登录页优化

This commit is contained in:
JenniferW 2026-01-09 17:35:52 +08:00
parent 7939a35ca1
commit d47a1b7cdb
5 changed files with 126 additions and 160 deletions

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

View File

@ -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>

View File

@ -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>