|
|
|
@ -1,5 +1,5 @@ |
|
|
|
<script setup> |
|
|
|
import {onMounted, ref} from 'vue' |
|
|
|
import {onMounted, ref,onUnmounted} from 'vue' |
|
|
|
import {ElMessage} from 'element-plus' |
|
|
|
import request from '@/util/http' |
|
|
|
import {useRouter} from 'vue-router' |
|
|
|
@ -34,20 +34,74 @@ function getMachineId() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const form = ref({account: null, password: '', token: '', machineId: machineId1.value, code: '', uuid: ''}) |
|
|
|
const form = ref({account: null, password: '', token: '', machineId: machineId1.value, captcha: '', uuid: ''}) |
|
|
|
const formRef = ref(null) |
|
|
|
const rules = { |
|
|
|
account: [ |
|
|
|
{ required: true, message: '请输入账号', trigger: 'blur' } |
|
|
|
], |
|
|
|
password: [ |
|
|
|
{ required: true, message: '请输入密码', trigger: 'blur' } |
|
|
|
], |
|
|
|
captcha: [ |
|
|
|
{ required: true, message: '请输入验证码', trigger: 'blur' } |
|
|
|
] |
|
|
|
} |
|
|
|
const captchaUrl = ref('') |
|
|
|
const isCaptchaCooldown = ref(false) |
|
|
|
let captchaCooldownTimer = null |
|
|
|
let cooldownStartTime = 0 // 冷却开始时间(时间戳) |
|
|
|
const COOLDOWN_TOTAL = 5 * 1000 // 总冷却时长:5 秒(转毫秒) |
|
|
|
|
|
|
|
// 启动验证码冷却定时器 |
|
|
|
const startCaptchaCooldown = () => { |
|
|
|
isCaptchaCooldown.value = true |
|
|
|
cooldownStartTime = Date.now() |
|
|
|
captchaCooldownTimer = setTimeout(() => { |
|
|
|
isCaptchaCooldown.value = false // 冷却结束 |
|
|
|
cooldownStartTime = 0 // 重置开始时间 |
|
|
|
}, COOLDOWN_TOTAL) |
|
|
|
} |
|
|
|
|
|
|
|
const getCaptchaRemainingSeconds = () => { |
|
|
|
if (!isCaptchaCooldown.value || cooldownStartTime === 0) { |
|
|
|
return 0 |
|
|
|
} |
|
|
|
const elapsed = Date.now() - cooldownStartTime |
|
|
|
const remainingMs = Math.max(COOLDOWN_TOTAL - elapsed, 0) |
|
|
|
const remainingSeconds = Math.ceil(remainingMs / 1000) |
|
|
|
return remainingSeconds |
|
|
|
} |
|
|
|
|
|
|
|
const clearCaptchaCooldown = () => { |
|
|
|
if (captchaCooldownTimer) { |
|
|
|
clearTimeout(captchaCooldownTimer) |
|
|
|
captchaCooldownTimer = null |
|
|
|
} |
|
|
|
isCaptchaCooldown.value = false |
|
|
|
cooldownStartTime = 0 |
|
|
|
} |
|
|
|
// 获取验证码 |
|
|
|
const getCaptcha = async () => { |
|
|
|
if (isCaptchaCooldown.value) { |
|
|
|
ElMessage.warning('验证码获取太频繁,请' + getCaptchaRemainingSeconds() + '秒后再试') |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
let uuid = Date.now() |
|
|
|
localStorage.setItem('uuid', uuid) |
|
|
|
const res = await request({ |
|
|
|
url: '/admin/captchaImage', |
|
|
|
method: 'get' |
|
|
|
url: '/captcha' + '?uuid=' + uuid, |
|
|
|
method: 'get', |
|
|
|
responseType: 'blob', |
|
|
|
}) |
|
|
|
if (res.code === 200) { |
|
|
|
captchaUrl.value = "data:image/gif;base64," + res.img |
|
|
|
form.value.uuid = res.uuid |
|
|
|
if (captchaUrl.value) { |
|
|
|
URL.revokeObjectURL(captchaUrl.value); |
|
|
|
} |
|
|
|
captchaUrl.value = URL.createObjectURL(res); |
|
|
|
|
|
|
|
startCaptchaCooldown() |
|
|
|
} catch (error) { |
|
|
|
console.error('获取验证码失败', error) |
|
|
|
} |
|
|
|
@ -59,6 +113,12 @@ const adminRoleId = ref(null) |
|
|
|
const adminStore = useAdminStore() |
|
|
|
//调用方法 |
|
|
|
const login = async function () { |
|
|
|
if (!formRef.value) return |
|
|
|
try { |
|
|
|
await formRef.value.validate() |
|
|
|
} catch (err) { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
if(loading.value) { |
|
|
|
console.log('正在登录,请稍后') |
|
|
|
@ -68,11 +128,15 @@ const login = async function () { |
|
|
|
loading.value = true |
|
|
|
|
|
|
|
try { |
|
|
|
let params = { |
|
|
|
...form.value, |
|
|
|
uuid: localStorage.getItem('uuid') |
|
|
|
} |
|
|
|
const result = await request({ |
|
|
|
url: '/admin/login', |
|
|
|
data: form.value |
|
|
|
data: params |
|
|
|
}) |
|
|
|
console.log('传给后端的参数', form.value) |
|
|
|
console.log('传给后端的参数', params) |
|
|
|
|
|
|
|
if (result.code === 200) { |
|
|
|
// 本地存储token |
|
|
|
@ -114,16 +178,14 @@ const login = async function () { |
|
|
|
} else { |
|
|
|
form.value.password = '' |
|
|
|
form.value.account = '' |
|
|
|
form.value.code = '' |
|
|
|
form.value.captcha = '' |
|
|
|
ElMessage.error(result.msg) |
|
|
|
loading.value = false //登录失败时重置loading状态 |
|
|
|
getCaptcha() |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.log('请求失败', error) |
|
|
|
ElMessage.error('登录失败,请检查账号密码') |
|
|
|
loading.value = false // 发生异常时重置loading状态 |
|
|
|
getCaptcha() |
|
|
|
} |
|
|
|
} |
|
|
|
//获取菜单树 |
|
|
|
@ -184,6 +246,10 @@ onMounted(() => { |
|
|
|
getCaptcha() |
|
|
|
}) |
|
|
|
|
|
|
|
onUnmounted(() => { |
|
|
|
clearCaptchaCooldown() |
|
|
|
}) |
|
|
|
|
|
|
|
</script> |
|
|
|
<template> |
|
|
|
<el-row class="login-page"> |
|
|
|
@ -192,7 +258,7 @@ onMounted(() => { |
|
|
|
</el-col> |
|
|
|
<el-col :span="6" :offset="3" class="form"> |
|
|
|
<!-- 登录表单 --> |
|
|
|
<el-form :model="form" size="large" autocomplete="off"> |
|
|
|
<el-form :model="form" :rules="rules" ref="formRef" size="large" autocomplete="off"> |
|
|
|
<el-form-item> |
|
|
|
<h1 style="color: #409eff">熵盾管理系统 V1.0</h1> |
|
|
|
</el-form-item> |
|
|
|
@ -207,15 +273,15 @@ onMounted(() => { |
|
|
|
required |
|
|
|
/> |
|
|
|
</el-form-item> |
|
|
|
<el-form-item prop="code" required> |
|
|
|
<el-form-item prop="captcha" required> |
|
|
|
<el-row :gutter="20" style="width: 100%"> |
|
|
|
<el-col :span="16"> |
|
|
|
<el-input v-model="form.code" placeholder="请输入验证码" @keyup.enter="login"></el-input> |
|
|
|
<el-input v-model="form.captcha" placeholder="请输入验证码" @keyup.enter="login"></el-input> |
|
|
|
</el-col> |
|
|
|
<el-col :span="8" style="display: flex; align-items: center; justify-content: center;"> |
|
|
|
<img v-if="captchaUrl" :src="captchaUrl" @click="getCaptcha" style="width: 100%; height: 40px; cursor: pointer; border-radius: 4px;" alt="验证码" title="点击刷新验证码" /> |
|
|
|
<div v-else class="failed"> |
|
|
|
<img src="@/assets/images/loadingFaild.png" @click="getCaptcha"> |
|
|
|
<div v-else @click="getCaptcha" class="failed"> |
|
|
|
<img src="@/assets/images/loadingFaild.png" > |
|
|
|
<text>点击刷新二维码</text> |
|
|
|
</div> |
|
|
|
</el-col> |
|
|
|
|