refactor(login): 重构登录页面,适配国际化并简化功能

1.  将页面文本替换为国际化翻译
2.  移除验证码、快速登录等冗余功能
3.  更新logo资源路径与表单校验逻辑
4.  优化页面样式与代码结构
This commit is contained in:
sheng
2026-05-27 16:42:19 +08:00
parent 000b87eb92
commit 0f3b5d4371

View File

@@ -8,7 +8,7 @@
<div
class="page-login--layer page-login--layer-time"
flex="main:center cross:center">
{{time}}
{{ time }}
</div>
<div class="page-login--layer">
<div
@@ -16,15 +16,13 @@
flex="dir:top main:justify cross:stretch box:justify">
<div class="page-login--content-header">
<p class="page-login--content-header-motto">
时间是一切财富中最宝贵的财富
{{ $t(key('time_is_most_precious')) }}
</p>
</div>
<div
class="page-login--content-main"
flex="dir:top main:center cross:center">
<!-- logo -->
<img class="page-login--logo" src="./image/logo@2x.png">
<!-- form -->
<img class="page-login--logo" :src="`${$baseUrl}image/logo/sc_logo.png`">
<div class="page-login--form">
<el-card shadow="never">
<el-form
@@ -37,7 +35,8 @@
<el-input
type="text"
v-model="formLogin.username"
placeholder="用户名">
@keyup.enter.native="submit"
:placeholder="$t(key('username'))">
<i slot="prepend" class="fa fa-user-circle-o"></i>
</el-input>
</el-form-item>
@@ -45,139 +44,65 @@
<el-input
type="password"
v-model="formLogin.password"
placeholder="密码">
@keyup.enter.native="submit"
:placeholder="$t(key('password'))">
<i slot="prepend" class="fa fa-keyboard-o"></i>
</el-input>
</el-form-item>
<el-form-item prop="code">
<el-input
type="text"
v-model="formLogin.code"
placeholder="验证码">
<template slot="append">
<img class="login-code" src="./image/login-code.png">
</template>
</el-input>
</el-form-item>
<el-button
size="default"
@click="submit"
type="primary"
class="button-login">
登录
{{ $t(key('login')) }}
</el-button>
</el-form>
</el-card>
<p
class="page-login--options"
flex="main:justify cross:center">
<span><d2-icon name="question-circle"/> 忘记密码</span>
<span>注册用户</span>
</p>
<!-- quick login -->
<el-button class="page-login--quick" size="default" type="info" @click="dialogVisible = true">
快速选择用户测试功能
</el-button>
</div>
</div>
<div class="page-login--content-footer">
<p class="page-login--content-footer-locales">
<a
v-for="language in $languages"
:key="language.value"
@click="onChangeLocale(language.value)">
{{ language.label }}
</a>
</p>
<p class="page-login--content-footer-copyright">
Copyright
<d2-icon name="copyright"/>
2018 D2 Projects 开源组织出品
<a href="https://github.com/FairyEver">
@FairyEver
</a>
</p>
<p class="page-login--content-footer-options">
<a href="#">帮助</a>
<a href="#">隐私</a>
<a href="#">条款</a>
</p>
</div>
<div class="page-login--content-footer" />
</div>
</div>
<el-dialog
title="快速选择用户"
:visible.sync="dialogVisible"
width="400px">
<el-row :gutter="10" style="margin: -20px 0px -10px 0px;">
<el-col v-for="(user, index) in users" :key="index" :span="8">
<div class="page-login--quick-user" @click="handleUserBtnClick(user)">
<d2-icon name="user-circle-o"/>
<span>{{user.name}}</span>
</div>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<script>
import dayjs from 'dayjs'
import { mapActions } from 'vuex'
import util from '@/libs/util'
import localeMixin from '@/locales/mixin.js'
import { i18nMixin } from '@/composables/useI18n'
import '@/components/d2-icon/font-awesome-4.7.0/css/font-awesome.min.css'
export default {
mixins: [
localeMixin
localeMixin,
i18nMixin('page.system.login')
],
data () {
return {
// 实时时钟定时器
timeInterval: null,
// 当前时间显示
time: dayjs().format('HH:mm:ss'),
// 快速选择用户
dialogVisible: false,
users: [
{
name: 'Admin',
username: 'admin',
password: 'admin'
},
{
name: 'Editor',
username: 'editor',
password: 'editor'
},
{
name: 'User1',
username: 'user1',
password: 'user1'
}
],
// 表单
// 登录表单数据
formLogin: {
username: 'admin',
password: 'admin',
code: 'v9am'
username: '',
password: ''
},
// 表单校验
// 表单校验规则
rules: {
username: [
{
required: true,
message: '请输入用户名',
message: this.$t(this.key('please_enter_username')),
trigger: 'blur'
}
],
password: [
{
required: true,
message: '请输入密码',
trigger: 'blur'
}
],
code: [
{
required: true,
message: '请输入验证码',
message: this.$t(this.key('please_enter_password')),
trigger: 'blur'
}
]
@@ -185,50 +110,45 @@ export default {
}
},
mounted () {
util.cookies.set('block', 'false')
// 启动实时时钟
this.timeInterval = setInterval(() => {
this.refreshTime()
}, 1000)
},
beforeDestroy () {
// 销毁时清除时钟定时器
clearInterval(this.timeInterval)
},
methods: {
...mapActions('d2admin/account', [
'login'
]),
// 刷新时间显示
refreshTime () {
this.time = dayjs().format('HH:mm:ss')
},
/**
* @description 接收选择一个用户快速登录的事件
* @param {Object} user 用户信息
*/
handleUserBtnClick (user) {
this.formLogin.username = user.username
this.formLogin.password = user.password
this.submit()
},
/**
* @description 提交表单
*/
// 提交登录信息
// 提交登录表单
submit () {
this.$refs.loginForm.validate((valid) => {
if (valid) {
// 登录
// 注意 这里的演示没有传验证码
// 具体需要传递的数据请自行修改代码
// 调用 Vuex login action 进行登录
this.login({
username: this.formLogin.username,
password: this.formLogin.password
})
.then(() => {
// 重定向对象不存在则返回顶层路径
// 登录成功后跳转到目标页或首页
this.$router.replace(this.$route.query.redirect || '/')
})
.catch((error) => {
// 登录失败时清除残留的 cookie 并提示错误信息
util.cookies.remove('token')
util.cookies.remove('uuid')
this.$message.error(error.message || this.$t(this.key('form_validation_failed')))
})
} else {
// 登录表单校验失败
this.$message.error('表单校验失败,请检查')
this.$message.error(this.$t(this.key('form_validation_failed')))
}
})
}
@@ -240,33 +160,34 @@ export default {
.page-login {
@extend %unable-select;
$backgroundColor: #F0F2F5;
// ---
background-color: $backgroundColor;
height: 100%;
position: relative;
// 层
.page-login--layer {
@extend %full;
overflow: auto;
}
.page-login--layer-area {
overflow: hidden;
}
// 时间
.page-login--layer-time {
font-size: 24em;
font-weight: bold;
color: rgba(0, 0, 0, 0.03);
overflow: hidden;
}
// 登陆页面控件的容器
.page-login--content {
height: 100%;
min-height: 500px;
}
// header
.page-login--content-header {
padding: 1em 0;
.page-login--content-header-motto {
margin: 0px;
padding: 0px;
@@ -275,115 +196,33 @@ export default {
font-size: 12px;
}
}
// main
.page-login--logo {
width: 240px;
margin-bottom: 2em;
margin-top: -2em;
}
// 登录表单
.page-login--form {
width: 280px;
// 卡片
.el-card {
margin-bottom: 15px;
}
// 登录按钮
.button-login {
width: 100%;
}
// 输入框左边的图表区域缩窄
.el-input-group__prepend {
padding: 0px 14px;
}
.login-code {
height: 40px - 2px;
display: block;
margin: 0px -20px;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
}
// 登陆选项
.page-login--options {
margin: 0px;
padding: 0px;
font-size: 14px;
color: $color-primary;
margin-bottom: 15px;
font-weight: bold;
}
.page-login--quick {
width: 100%;
}
}
// 快速选择用户面板
.page-login--quick-user {
@extend %flex-center-col;
padding: 10px 0px;
border-radius: 4px;
&:hover {
background-color: $color-bg;
i {
color: $color-text-normal;
}
span {
color: $color-text-normal;
}
}
i {
font-size: 36px;
color: $color-text-sub;
}
span {
font-size: 12px;
margin-top: 10px;
color: $color-text-sub;
}
}
// footer
.page-login--content-footer {
padding: 1em 0;
.page-login--content-footer-locales {
padding: 0px;
margin: 0px;
margin-bottom: 15px;
font-size: 12px;
line-height: 12px;
text-align: center;
color: $color-text-normal;
a {
color: $color-text-normal;
margin: 0 .5em;
&:hover {
color: $color-text-main;
}
}
}
.page-login--content-footer-copyright {
padding: 0px;
margin: 0px;
margin-bottom: 10px;
font-size: 12px;
line-height: 12px;
text-align: center;
color: $color-text-normal;
a {
color: $color-text-normal;
}
}
.page-login--content-footer-options {
padding: 0px;
margin: 0px;
font-size: 12px;
line-height: 12px;
text-align: center;
a {
color: $color-text-normal;
margin: 0 1em;
}
}
}
// 背景
.circles {
position: absolute;
top: 0;
@@ -393,6 +232,7 @@ export default {
overflow: hidden;
margin: 0px;
padding: 0px;
li {
position: absolute;
display: block;
@@ -402,24 +242,27 @@ export default {
background: #FFF;
animation: animate 25s linear infinite;
bottom: -200px;
@keyframes animate {
0%{
0% {
transform: translateY(0) rotate(0deg);
opacity: 1;
border-radius: 0;
}
100%{
100% {
transform: translateY(-1000px) rotate(720deg);
opacity: 0;
border-radius: 50%;
}
}
&:nth-child(1) {
left: 15%;
width: 80px;
height: 80px;
animation-delay: 0s;
}
&:nth-child(2) {
left: 5%;
width: 20px;
@@ -427,12 +270,14 @@ export default {
animation-delay: 2s;
animation-duration: 12s;
}
&:nth-child(3) {
left: 70%;
width: 20px;
height: 20px;
animation-delay: 4s;
}
&:nth-child(4) {
left: 40%;
width: 60px;
@@ -440,24 +285,28 @@ export default {
animation-delay: 0s;
animation-duration: 18s;
}
&:nth-child(5) {
left: 65%;
width: 20px;
height: 20px;
animation-delay: 0s;
}
&:nth-child(6) {
left: 75%;
width: 150px;
height: 150px;
animation-delay: 3s;
}
&:nth-child(7) {
left: 35%;
width: 200px;
height: 200px;
animation-delay: 7s;
}
&:nth-child(8) {
left: 50%;
width: 25px;
@@ -465,6 +314,7 @@ export default {
animation-delay: 15s;
animation-duration: 45s;
}
&:nth-child(9) {
left: 20%;
width: 15px;
@@ -472,6 +322,7 @@ export default {
animation-delay: 2s;
animation-duration: 35s;
}
&:nth-child(10) {
left: 85%;
width: 150px;