|
@@ -3,9 +3,11 @@ import { useRouter, useRoute } from 'vue-router'
|
|
|
import ErrorTips from './components/ErrorTips.vue'
|
|
import ErrorTips from './components/ErrorTips.vue'
|
|
|
import { useUserStore } from '@/stores/modules/user'
|
|
import { useUserStore } from '@/stores/modules/user'
|
|
|
import ScoringSystem from '@/views/Dashboard/src/components/ScoringSystem.vue'
|
|
import ScoringSystem from '@/views/Dashboard/src/components/ScoringSystem.vue'
|
|
|
|
|
+import CryptoJS from 'crypto-js'
|
|
|
|
|
|
|
|
const router = useRouter()
|
|
const router = useRouter()
|
|
|
const route = useRoute()
|
|
const route = useRoute()
|
|
|
|
|
+
|
|
|
const loginForm = ref({
|
|
const loginForm = ref({
|
|
|
username: '',
|
|
username: '',
|
|
|
password: '',
|
|
password: '',
|
|
@@ -13,6 +15,45 @@ const loginForm = ref({
|
|
|
code: ''
|
|
code: ''
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+const isRememerPwd = ref(false)
|
|
|
|
|
+const secretKey = 'fT5!R1k$7Mv@4Q9X'
|
|
|
|
|
+// AES 加密函数
|
|
|
|
|
+const encryptPassword = (password) => {
|
|
|
|
|
+ return CryptoJS.AES.encrypt(password, secretKey).toString()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// AES 解密函数
|
|
|
|
|
+const decryptPassword = (encryptedPassword) => {
|
|
|
|
|
+ const bytes = CryptoJS.AES.decrypt(encryptedPassword, secretKey)
|
|
|
|
|
+ return bytes.toString(CryptoJS.enc.Utf8)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 存储账号和加密后的密码
|
|
|
|
|
+const saveCredentials = () => {
|
|
|
|
|
+ clearCredentials()
|
|
|
|
|
+ const encryptedPassword = encryptPassword(loginForm.value.password) // 加密密码
|
|
|
|
|
+ localStorage.setItem('account', loginForm.value.username)
|
|
|
|
|
+ localStorage.setItem('password', encryptedPassword)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 读取存储的账号和解密后的密码
|
|
|
|
|
+const getCredentials = () => {
|
|
|
|
|
+ const username = localStorage.getItem('account')
|
|
|
|
|
+ const encryptedPassword = localStorage.getItem('password')
|
|
|
|
|
+ if (username && encryptedPassword) {
|
|
|
|
|
+ const password = decryptPassword(encryptedPassword) // 解密密码
|
|
|
|
|
+ loginForm.value.username = username
|
|
|
|
|
+ loginForm.value.password = password
|
|
|
|
|
+ isRememerPwd.value = true
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 删除存储的账号和密码
|
|
|
|
|
+const clearCredentials = () => {
|
|
|
|
|
+ localStorage.removeItem('account')
|
|
|
|
|
+ localStorage.removeItem('password')
|
|
|
|
|
+}
|
|
|
|
|
+getCredentials()
|
|
|
const status = ref(route.query.status || 'login')
|
|
const status = ref(route.query.status || 'login')
|
|
|
watch(status, () => {
|
|
watch(status, () => {
|
|
|
loginForm.value = {
|
|
loginForm.value = {
|
|
@@ -41,6 +82,7 @@ const verificationCode = ref()
|
|
|
const loading = ref(false)
|
|
const loading = ref(false)
|
|
|
// 获取验证码
|
|
// 获取验证码
|
|
|
const getCode = () => {
|
|
const getCode = () => {
|
|
|
|
|
+ if (loading.value) return
|
|
|
loading.value = true
|
|
loading.value = true
|
|
|
$api
|
|
$api
|
|
|
.getVerifcationCode()
|
|
.getVerifcationCode()
|
|
@@ -91,6 +133,11 @@ const handleLogin = () => {
|
|
|
.then((res: any) => {
|
|
.then((res: any) => {
|
|
|
if (res.code === 200) {
|
|
if (res.code === 200) {
|
|
|
const { data } = res
|
|
const { data } = res
|
|
|
|
|
+ if (isRememerPwd.value) {
|
|
|
|
|
+ saveCredentials()
|
|
|
|
|
+ } else {
|
|
|
|
|
+ clearCredentials()
|
|
|
|
|
+ }
|
|
|
if (data.msg === 'today') {
|
|
if (data.msg === 'today') {
|
|
|
ElMessageBox.alert('Your password will expire today, please reset', 'Prompt', {
|
|
ElMessageBox.alert('Your password will expire today, please reset', 'Prompt', {
|
|
|
confirmButtonText: 'OK',
|
|
confirmButtonText: 'OK',
|
|
@@ -111,14 +158,34 @@ const handleLogin = () => {
|
|
|
userStore.setUsername(res.data.uname || '')
|
|
userStore.setUsername(res.data.uname || '')
|
|
|
router.push('/')
|
|
router.push('/')
|
|
|
} else if (res.code === 400) {
|
|
} else if (res.code === 400) {
|
|
|
|
|
+ const { data } = res
|
|
|
// 验证码错误
|
|
// 验证码错误
|
|
|
- if (res.data.msg === 'password_error') {
|
|
|
|
|
|
|
+ if (data.msg === 'password_error') {
|
|
|
loginError.value.password = true
|
|
loginError.value.password = true
|
|
|
- } else if (res.data.msg === 'verifcation_error') {
|
|
|
|
|
|
|
+ } else if (data.msg === 'verifcation_error') {
|
|
|
loginError.value.code = true
|
|
loginError.value.code = true
|
|
|
- } else if (res.data.msg === 'error_times') {
|
|
|
|
|
|
|
+ } else if (data.msg === 'error_times') {
|
|
|
errorTipsRef.value.openDialog()
|
|
errorTipsRef.value.openDialog()
|
|
|
}
|
|
}
|
|
|
|
|
+ } else if (res.code === 500) {
|
|
|
|
|
+ const { data } = res
|
|
|
|
|
+ if (data.msg === 'passwordExpires') {
|
|
|
|
|
+ ElMessageBox.alert('Password expired, please change your password', 'Prompt', {
|
|
|
|
|
+ confirmButtonText: 'OK',
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ confirmButtonClass: 'el-button--dark'
|
|
|
|
|
+ })
|
|
|
|
|
+ userStore.setUsername(res.data.uname || '')
|
|
|
|
|
+ router.push({
|
|
|
|
|
+ name: 'Reset Password'
|
|
|
|
|
+ })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessageBox.alert(data.desc, {
|
|
|
|
|
+ confirmButtonText: 'OK',
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ confirmButtonClass: 'el-button--dark'
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
.finally(() => {
|
|
.finally(() => {
|
|
@@ -219,10 +286,12 @@ const errorTipsRef = ref()
|
|
|
v-model="loginForm.code"
|
|
v-model="loginForm.code"
|
|
|
placeholder="Verification Code"
|
|
placeholder="Verification Code"
|
|
|
@focus="handleDeleteEmailTips('code')"
|
|
@focus="handleDeleteEmailTips('code')"
|
|
|
|
|
+ @keyup.enter="handleLogin"
|
|
|
>
|
|
>
|
|
|
<template #append>
|
|
<template #append>
|
|
|
<img
|
|
<img
|
|
|
v-vloading="loading"
|
|
v-vloading="loading"
|
|
|
|
|
+ @click="getCode"
|
|
|
class="verification-code-img"
|
|
class="verification-code-img"
|
|
|
:src="verificationCode"
|
|
:src="verificationCode"
|
|
|
alt=""
|
|
alt=""
|
|
@@ -230,6 +299,12 @@ const errorTipsRef = ref()
|
|
|
</template>
|
|
</template>
|
|
|
</el-input>
|
|
</el-input>
|
|
|
<div class="error" v-if="loginError.code">Incorrect verification code.</div>
|
|
<div class="error" v-if="loginError.code">Incorrect verification code.</div>
|
|
|
|
|
+ <el-checkbox
|
|
|
|
|
+ class="remember-password"
|
|
|
|
|
+ v-model="isRememerPwd"
|
|
|
|
|
+ label="Remember Password"
|
|
|
|
|
+ size="large"
|
|
|
|
|
+ />
|
|
|
<el-button @click="handleLogin" class="el-button--dark login-btn">Login</el-button>
|
|
<el-button @click="handleLogin" class="el-button--dark login-btn">Login</el-button>
|
|
|
</div>
|
|
</div>
|
|
|
<template #footer>
|
|
<template #footer>
|
|
@@ -286,8 +361,15 @@ const errorTipsRef = ref()
|
|
|
v-model="loginForm.code"
|
|
v-model="loginForm.code"
|
|
|
placeholder="Verification Code"
|
|
placeholder="Verification Code"
|
|
|
@focus="handleDeleteEmailTips('code')"
|
|
@focus="handleDeleteEmailTips('code')"
|
|
|
|
|
+ @keyup.enter="handleSendPassword"
|
|
|
><template #append>
|
|
><template #append>
|
|
|
- <img class="verification-code-img" :src="verificationCode" alt="" /> </template
|
|
|
|
|
|
|
+ <img
|
|
|
|
|
+ v-vloading="loading"
|
|
|
|
|
+ class="verification-code-img"
|
|
|
|
|
+ :src="verificationCode"
|
|
|
|
|
+ @click="getCode"
|
|
|
|
|
+ alt=""
|
|
|
|
|
+ /> </template
|
|
|
></el-input>
|
|
></el-input>
|
|
|
<div class="error" v-if="loginError.code">Incorrect verification code.</div>
|
|
<div class="error" v-if="loginError.code">Incorrect verification code.</div>
|
|
|
<el-button @click="handleSendPassword" class="el-button--dark login-btn"
|
|
<el-button @click="handleSendPassword" class="el-button--dark login-btn"
|
|
@@ -459,6 +541,10 @@ const errorTipsRef = ref()
|
|
|
color: var(--color-danger);
|
|
color: var(--color-danger);
|
|
|
line-height: 14px;
|
|
line-height: 14px;
|
|
|
}
|
|
}
|
|
|
|
|
+ .remember-password {
|
|
|
|
|
+ height: 24px;
|
|
|
|
|
+ margin-top: 16px;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
.back-text {
|
|
.back-text {
|
|
|
width: 100%;
|
|
width: 100%;
|
|
@@ -495,3 +581,11 @@ const errorTipsRef = ref()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|
|
|
|
|
+<style lang="scss">
|
|
|
|
|
+.login {
|
|
|
|
|
+ .el-checkbox__label {
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: var(--color-neutral-2);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|