登录页优化
This commit is contained in:
parent
7939a35ca1
commit
d47a1b7cdb
Binary file not shown.
|
Before Width: | Height: | Size: 725 KiB After Width: | Height: | Size: 867 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 72 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 137 KiB |
|
|
@ -2,7 +2,11 @@
|
|||
<el-breadcrumb class="app-breadcrumb" separator="/">
|
||||
<transition-group name="breadcrumb">
|
||||
<el-breadcrumb-item v-for="(item, index) in levelList" :key="item.path">
|
||||
<span v-if="item.redirect === 'noRedirect' || index == levelList.length - 1" class="no-redirect">{{ item.meta.title }}</span>
|
||||
<span
|
||||
v-if="item.redirect === 'noRedirect' || index == levelList.length - 1"
|
||||
class="no-redirect"
|
||||
>{{ item.meta.title }}</span
|
||||
>
|
||||
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
|
||||
</el-breadcrumb-item>
|
||||
</transition-group>
|
||||
|
|
@ -10,77 +14,82 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import usePermissionStore from '@/store/modules/permission'
|
||||
import usePermissionStore from "@/store/modules/permission";
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const permissionStore = usePermissionStore()
|
||||
const levelList = ref([])
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const permissionStore = usePermissionStore();
|
||||
const levelList = ref([]);
|
||||
|
||||
function getBreadcrumb() {
|
||||
// only show routes with meta.title
|
||||
let matched = []
|
||||
const pathNum = findPathNum(route.path)
|
||||
let matched = [];
|
||||
const pathNum = findPathNum(route.path);
|
||||
// multi-level menu
|
||||
if (pathNum > 2) {
|
||||
const reg = /\/\w+/gi
|
||||
const reg = /\/\w+/gi;
|
||||
const pathList = route.path.match(reg).map((item, index) => {
|
||||
if (index !== 0) item = item.slice(1)
|
||||
return item
|
||||
})
|
||||
getMatched(pathList, permissionStore.defaultRoutes, matched)
|
||||
if (index !== 0) item = item.slice(1);
|
||||
return item;
|
||||
});
|
||||
getMatched(pathList, permissionStore.defaultRoutes, matched);
|
||||
} else {
|
||||
matched = route.matched.filter((item) => item.meta && item.meta.title)
|
||||
matched = route.matched.filter((item) => item.meta && item.meta.title);
|
||||
}
|
||||
// 判断是否为首页
|
||||
if (!isDashboard(matched[0])) {
|
||||
matched = [{ path: "/index", meta: { title: "首页" } }].concat(matched)
|
||||
}
|
||||
levelList.value = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
|
||||
// if (!isDashboard(matched[0])) {
|
||||
// matched = [{ path: "/index", meta: { title: "首页" } }].concat(matched)
|
||||
// }
|
||||
levelList.value = matched.filter(
|
||||
(item) => item.meta && item.meta.title && item.meta.breadcrumb !== false
|
||||
);
|
||||
}
|
||||
function findPathNum(str, char = "/") {
|
||||
let index = str.indexOf(char)
|
||||
let num = 0
|
||||
let index = str.indexOf(char);
|
||||
let num = 0;
|
||||
while (index !== -1) {
|
||||
num++
|
||||
index = str.indexOf(char, index + 1)
|
||||
num++;
|
||||
index = str.indexOf(char, index + 1);
|
||||
}
|
||||
return num
|
||||
return num;
|
||||
}
|
||||
function getMatched(pathList, routeList, matched) {
|
||||
let data = routeList.find(item => item.path == pathList[0] || (item.name += '').toLowerCase() == pathList[0])
|
||||
let data = routeList.find(
|
||||
(item) =>
|
||||
item.path == pathList[0] || (item.name += "").toLowerCase() == pathList[0]
|
||||
);
|
||||
if (data) {
|
||||
matched.push(data)
|
||||
matched.push(data);
|
||||
if (data.children && pathList.length) {
|
||||
pathList.shift()
|
||||
getMatched(pathList, data.children, matched)
|
||||
pathList.shift();
|
||||
getMatched(pathList, data.children, matched);
|
||||
}
|
||||
}
|
||||
}
|
||||
function isDashboard(route) {
|
||||
const name = route && route.name
|
||||
const name = route && route.name;
|
||||
if (!name) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
return name.trim() === 'Index'
|
||||
return name.trim() === "Index";
|
||||
}
|
||||
function handleLink(item) {
|
||||
const { redirect, path } = item
|
||||
const { redirect, path } = item;
|
||||
if (redirect) {
|
||||
router.push(redirect)
|
||||
return
|
||||
router.push(redirect);
|
||||
return;
|
||||
}
|
||||
router.push(path)
|
||||
router.push(path);
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
// if you go to the redirect page, do not update the breadcrumbs
|
||||
if (route.path.startsWith('/redirect/')) {
|
||||
return
|
||||
if (route.path.startsWith("/redirect/")) {
|
||||
return;
|
||||
}
|
||||
getBreadcrumb()
|
||||
})
|
||||
getBreadcrumb()
|
||||
getBreadcrumb();
|
||||
});
|
||||
getBreadcrumb();
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="login">
|
||||
<!-- <img src="../assets/images/444.png" class="logo" alt="logo" /> -->
|
||||
<img src="../assets/images/logo.png" class="logo" alt="logo" />
|
||||
<div class="login-container">
|
||||
<!-- 左侧插图区域 -->
|
||||
<!-- <div class="login-left">
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
type="text"
|
||||
size="large"
|
||||
auto-complete="off"
|
||||
placeholder="请输入账号"
|
||||
placeholder="请输入工号"
|
||||
>
|
||||
<template #prefix
|
||||
><svg-icon icon-class="user" class="el-input__icon input-icon"
|
||||
|
|
@ -123,8 +123,8 @@ const router = useRouter();
|
|||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const loginForm = ref({
|
||||
username: "admin",
|
||||
password: "admin123",
|
||||
username: "",
|
||||
password: "",
|
||||
rememberMe: false,
|
||||
code: "",
|
||||
uuid: "",
|
||||
|
|
@ -143,7 +143,7 @@ const showPassword = ref(false);
|
|||
// 动态验证规则
|
||||
const loginRules = computed(() => {
|
||||
const rules = {
|
||||
username: [{ required: true, trigger: "blur", message: "请输入您的账号" }],
|
||||
username: [{ required: true, trigger: "blur", message: "请输入您的工号" }],
|
||||
password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],
|
||||
};
|
||||
if (captchaEnabled.value) {
|
||||
|
|
@ -241,100 +241,45 @@ getCookie();
|
|||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
background-image: url("../assets/images/bg.jpg");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%; /* 使背景图片完全覆盖容器 */
|
||||
background-size: 100% 100%;
|
||||
background-clip: padding-box;
|
||||
overflow: visible;
|
||||
background-position: center;
|
||||
background-attachment: fixed; // 固定背景,滚动时不移动
|
||||
// background: linear-gradient(to bottom, #449ac6 0%, #5dbbe4 100%);
|
||||
// background: linear-gradient(135deg, #e3f2f5 0%, #d0e8eb 50%, #c5e3e6 100%);
|
||||
// position: relative;
|
||||
// padding: 0;
|
||||
// overflow: hidden;
|
||||
|
||||
// // 底部背景图片 - 左侧
|
||||
// &::before {
|
||||
// content: "";
|
||||
// position: absolute;
|
||||
// bottom: 0;
|
||||
// left: 0;
|
||||
// width: 45%;
|
||||
// height: 280px;
|
||||
// min-height: 220px;
|
||||
// background-image: url("../assets/images/logo_left.png");
|
||||
// background-repeat: no-repeat;
|
||||
// background-position: left bottom;
|
||||
// background-size: contain;
|
||||
// opacity: 0.5;
|
||||
// z-index: 0;
|
||||
// pointer-events: none;
|
||||
// filter: blur(0.5px);
|
||||
// }
|
||||
|
||||
// // 底部背景图片 - 右侧
|
||||
// &::after {
|
||||
// content: "";
|
||||
// position: absolute;
|
||||
// bottom: 0;
|
||||
// right: 0;
|
||||
// width: 45%;
|
||||
// height: 280px;
|
||||
// min-height: 220px;
|
||||
// background-image: url("../assets/images/logo_leftright.png");
|
||||
// background-repeat: no-repeat;
|
||||
// background-position: right bottom;
|
||||
// background-size: contain;
|
||||
// opacity: 0.5;
|
||||
// z-index: 0;
|
||||
// pointer-events: none;
|
||||
// filter: blur(0.5px);
|
||||
// }
|
||||
background-attachment: fixed;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.logo {
|
||||
position: absolute;
|
||||
top: 70px;
|
||||
left: 80px;
|
||||
width: 30%;
|
||||
}
|
||||
.login-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
max-width: 1400px;
|
||||
min-height: 100vh;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
box-sizing: border-box;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding: 40px 60px;
|
||||
}
|
||||
|
||||
// .logo {
|
||||
// position: absolute;
|
||||
// top: 35px;
|
||||
// left: 45px;
|
||||
// width: 18%;
|
||||
// }
|
||||
|
||||
// .login-container {
|
||||
// display: flex;
|
||||
// width: 100%;
|
||||
// max-width: 1400px;
|
||||
// height: 100vh;
|
||||
// position: relative;
|
||||
// z-index: 1;
|
||||
// }
|
||||
|
||||
// .login-left {
|
||||
// flex: 1;
|
||||
// display: flex;
|
||||
// justify-content: center;
|
||||
// align-items: center;
|
||||
// padding: 60px 40px;
|
||||
// position: relative;
|
||||
|
||||
// // .login-illustration {
|
||||
// // width: 100%;
|
||||
// // max-width: 650px;
|
||||
// // height: auto;
|
||||
// // object-fit: contain;
|
||||
// // filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.08));
|
||||
// // }
|
||||
// }
|
||||
|
||||
.login-right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: end;
|
||||
left: 70%;
|
||||
padding: 40px 60px;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
|
|
@ -346,18 +291,23 @@ getCookie();
|
|||
font-weight: 600;
|
||||
letter-spacing: 0.5px;
|
||||
line-height: 1.4;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
border-radius: 16px;
|
||||
background: #ffffff;
|
||||
width: 100%;
|
||||
width: 420px;
|
||||
min-width: 420px;
|
||||
max-width: 420px;
|
||||
padding: 50px 40px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
|
||||
box-sizing: border-box;
|
||||
flex-shrink: 0;
|
||||
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 10px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
|
|
@ -509,54 +459,61 @@ getCookie();
|
|||
// 响应式设计
|
||||
@media (max-width: 1024px) {
|
||||
.login-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.login-left {
|
||||
flex: 0 0 auto;
|
||||
padding: 30px 20px;
|
||||
max-height: 40vh;
|
||||
|
||||
.login-illustration {
|
||||
max-width: 400px;
|
||||
}
|
||||
justify-content: center;
|
||||
padding: 40px 40px;
|
||||
}
|
||||
|
||||
.login-right {
|
||||
flex: 1;
|
||||
padding: 30px 20px;
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login {
|
||||
&::before,
|
||||
&::after {
|
||||
height: 180px;
|
||||
opacity: 0.3;
|
||||
}
|
||||
.login-form {
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
min-width: 320px;
|
||||
padding: 45px 35px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.login-left {
|
||||
display: none;
|
||||
.login-container {
|
||||
padding: 30px 20px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.login-right {
|
||||
width: 100%;
|
||||
padding: 30px 20px;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
padding: 35px 28px 28px 28px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.login {
|
||||
&::before,
|
||||
&::after {
|
||||
height: 150px;
|
||||
opacity: 0.25;
|
||||
}
|
||||
.login-form {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-width: 280px;
|
||||
padding: 35px 28px;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
font-size: 28px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.login-container {
|
||||
padding: 20px 15px;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
padding: 30px 20px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
font-size: 24px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue