unis_sip/oms_web/oms_vue/src/views/login.vue

396 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="login">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
<h3 class="title">{{title}}</h3>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
type="text"
auto-complete="off"
placeholder="账号"
>
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
type="password"
auto-complete="off"
placeholder="密码"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaEnabled">
<el-input
v-model="loginForm.code"
auto-complete="off"
placeholder="验证码"
style="width: 63%"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
</div>
</el-form-item>
<div class="login-options">
<el-checkbox v-model="loginForm.rememberMe">记住密码</el-checkbox>
<span class="link-type forgot-password" @click="openResetPwdDialog">忘记密码?</span>
</div>
<el-form-item style="width:100%;">
<el-button
:loading="loading"
size="medium"
type="primary"
style="width:100%;"
@click.native.prevent="handleLogin"
>
<span v-if="!loading">登 录</span>
<span v-else>登 录 中...</span>
</el-button>
<div style="float: right;" v-if="register">
<router-link class="link-type" :to="'/register'">立即注册</router-link>
</div>
</el-form-item>
</el-form>
<el-dialog
title="修改密码"
:visible.sync="resetPwdOpen"
width="420px"
:close-on-click-modal="false"
:close-on-press-escape="false"
append-to-body
>
<el-form ref="resetPwdForm" :model="resetPwdForm" :rules="resetPwdRules" label-width="100px">
<el-form-item label="账号" prop="username">
<el-input v-model="resetPwdForm.username" placeholder="请输入账号" />
</el-form-item>
<el-form-item label="新密码" prop="newPassword">
<el-input v-model="resetPwdForm.newPassword" type="password" placeholder="请输入新密码" show-password />
</el-form-item>
<el-form-item label="确认新密码" prop="confirmPassword">
<el-input v-model="resetPwdForm.confirmPassword" type="password" placeholder="请确认新密码" show-password />
</el-form-item>
<el-form-item label="邮箱验证码" prop="emailCode">
<el-input v-model="resetPwdForm.emailCode" placeholder="请输入邮箱验证码" maxlength="6" style="width: 190px" />
<el-button :loading="emailCodeLoading" :disabled="emailCodeCountdown > 0" @click="sendEmailCode">
{{ emailCodeCountdown > 0 ? emailCodeCountdown + '秒后重发' : '发送验证码' }}
</el-button>
</el-form-item>
<div class="password-tip">
<div>密码长度8-20位以下规则中至少满足 3 种:</div>
<ul>
<li>大写字母</li>
<li>小写字母</li>
<li>数字</li>
<li>特殊字符</li>
</ul>
</div>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" :loading="resetPwdLoading" @click="submitResetPwd">提 交</el-button>
</div>
</el-dialog>
<!-- 底部 -->
<div class="el-login-footer">
<span>Copyright © 2018-2025 unissense All Rights Reserved.</span>
</div>
</div>
</template>
<script>
import Cookies from "js-cookie"
import { encrypt, decrypt } from '@/utils/jsencrypt'
import { resetLoginPwd, sendResetPwdEmailCode } from '@/api/login'
export default {
name: "Login",
data() {
return {
title: process.env.VUE_APP_TITLE,
codeUrl: "",
loginForm: {
username: "",
password: "",
rememberMe: false,
code: ""
},
resetPwdForm: {
username: "",
newPassword: "",
confirmPassword: "",
emailCode: ""
},
resetPwdOpen: false,
resetPwdLoading: false,
emailCodeLoading: false,
emailCodeCountdown: 0,
emailCodeTimer: null,
resetPwdRules: {
username: [
{ required: true, trigger: "blur", message: "请输入账号" }
],
newPassword: [
{ required: true, trigger: "blur", message: "请输入新密码" },
{ min: 8, max: 20, trigger: "blur", message: "密码长度为8到20个字符" },
{ pattern: /^(?=.{8,20}$)(?:(?=.*[a-z])(?=.*[A-Z])(?=.*\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*[^A-Za-z0-9])|(?=.*[a-z])(?=.*\d)(?=.*[^A-Za-z0-9])|(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9])).*$/, trigger: "blur", message: "不符合密码规则" }
],
confirmPassword: [
{ required: true, trigger: "blur", message: "请确认新密码" },
{ validator: (rule, value, callback) => this.equalToNewPassword(rule, value, callback), trigger: "blur" }
],
emailCode: [
{ required: true, trigger: "blur", message: "请输入邮箱验证码" },
{ pattern: /^\d{6}$/, trigger: "blur", message: "邮箱验证码为6位数字" }
]
},
loginRules: {
username: [
{ required: true, trigger: "blur", message: "请输入您的账号" }
],
password: [
{ required: true, trigger: "blur", message: "请输入您的密码" }
],
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
},
loading: false,
// 验证码开关
captchaEnabled: false,
// 注册开关
register: false,
redirect: undefined
}
},
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect
},
immediate: true
}
},
created() {
this.getCode()
this.getCookie()
},
beforeDestroy() {
this.clearEmailCodeTimer()
},
methods: {
getCode() {
// 基于 Session 认证,直接使用图片 URL添加时间戳防止缓存
const timestamp = new Date().getTime()
this.codeUrl = `${process.env.VUE_APP_BASE_API}/captcha/captchaImage?type=math&s=${timestamp}`
this.captchaEnabled = true
},
getCookie() {
const username = Cookies.get("username")
const password = Cookies.get("password")
const rememberMe = Cookies.get('rememberMe')
this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
password: password === undefined ? this.loginForm.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
code: this.loginForm.code
}
},
equalToNewPassword(rule, value, callback) {
if (this.resetPwdForm.newPassword !== value) {
callback(new Error("两次输入的密码不一致"))
} else {
callback()
}
},
openResetPwdDialog() {
this.resetPwdOpen = true
this.clearEmailCodeTimer()
this.resetPwdForm = {
username: this.loginForm.username,
newPassword: "",
confirmPassword: "",
emailCode: ""
}
this.$nextTick(() => {
if (this.$refs.resetPwdForm) {
this.$refs.resetPwdForm.clearValidate()
}
})
},
sendEmailCode() {
this.$refs.resetPwdForm.validateField('username', (errorMessage) => {
if (errorMessage) {
return
}
this.emailCodeLoading = true
sendResetPwdEmailCode(this.resetPwdForm.username).then(() => {
this.$modal.msgSuccess("验证码已发送")
this.startEmailCodeCountdown()
}).finally(() => {
this.emailCodeLoading = false
})
})
},
startEmailCodeCountdown() {
this.clearEmailCodeTimer()
this.emailCodeCountdown = 60
this.emailCodeTimer = setInterval(() => {
if (this.emailCodeCountdown <= 1) {
this.clearEmailCodeTimer()
} else {
this.emailCodeCountdown--
}
}, 1000)
},
clearEmailCodeTimer() {
if (this.emailCodeTimer) {
clearInterval(this.emailCodeTimer)
this.emailCodeTimer = null
}
this.emailCodeCountdown = 0
},
submitResetPwd() {
this.$refs.resetPwdForm.validate(valid => {
if (!valid) {
return
}
this.resetPwdLoading = true
resetLoginPwd(this.resetPwdForm).then(() => {
this.$modal.msgSuccess("密码修改成功,请重新登录")
this.resetPwdOpen = false
this.$refs.loginForm.resetFields()
this.loginForm.password = ""
this.$nextTick(() => {
window.location.reload()
})
}).catch(() => {
}).finally(() => {
this.resetPwdLoading = false
})
})
},
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 })
Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 })
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 })
} else {
Cookies.remove("username")
Cookies.remove("password")
Cookies.remove('rememberMe')
}
this.$store.dispatch("Login", this.loginForm).then((res) => {
if (res && res.code === 301) {
this.resetPwdForm.username = this.loginForm.username
this.resetPwdForm.newPassword = ""
this.resetPwdForm.confirmPassword = ""
this.resetPwdForm.emailCode = ""
this.clearEmailCodeTimer()
this.resetPwdOpen = true
this.loading = false
return
}
this.$router.push({ path: this.redirect || "/" }).catch(()=>{})
}).catch(() => {
this.loading = false
if (this.captchaEnabled) {
this.getCode()
}
})
}
})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss">
.login {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
background-image: url("../assets/images/login-background.jpg");
background-size: cover;
}
.password-tip {
margin-top: -5px;
margin-bottom: 15px;
color: #f56c6c;
font-size: 12px;
line-height: 18px;
}
.title {
margin: 0px auto 30px auto;
text-align: center;
color: #707070;
}
.login-form {
border-radius: 6px;
background: #ffffff;
width: 400px;
padding: 25px 25px 5px 25px;
z-index: 1;
.el-input {
height: 38px;
input {
height: 38px;
}
}
.input-icon {
height: 39px;
width: 14px;
margin-left: 2px;
}
}
.login-options {
display: flex;
align-items: center;
justify-content: space-between;
margin: 0px 0px 25px 0px;
}
.forgot-password {
cursor: pointer;
font-size: 14px;
}
.forgot-password:hover {
text-decoration: underline;
}
.login-tip {
font-size: 13px;
text-align: center;
color: #bfbfbf;
}
.login-code {
width: 33%;
height: 38px;
float: right;
img {
cursor: pointer;
vertical-align: middle;
}
}
.el-login-footer {
height: 40px;
line-height: 40px;
position: fixed;
bottom: 0;
width: 100%;
text-align: center;
color: #fff;
font-family: Arial;
font-size: 12px;
letter-spacing: 1px;
}
.login-code-img {
height: 38px;
}
</style>