Files
wms-ui/src/views/login/components/account/index.vue

211 lines
5.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<a-form
ref="formRef"
:model="form"
:rules="rules"
:label-col-style="{ display: 'none' }"
:wrapper-col-style="{ flex: 1 }"
size="large"
@submit="handleLogin"
>
<a-form-item field="username" hide-label>
<a-input v-model="form.username" placeholder="请输入用户名" allow-clear autocomplete="off" />
</a-form-item>
<a-form-item field="password" hide-label>
<a-input-password v-model="form.password" placeholder="请输入密码" autocomplete="new-password" />
</a-form-item>
<a-form-item v-if="isCaptchaEnabled" field="captcha" hide-label>
<a-input v-model="form.captcha" placeholder="请输入验证码" :max-length="4" allow-clear style="flex: 1 1" />
<div class="captcha-container" @click="getCaptcha">
<img :src="captchaImgBase64" alt="验证码" class="captcha" />
<div v-if="form.expired" class="overlay">
<p>已过期请刷新</p>
</div>
</div>
</a-form-item>
<a-form-item>
<a-row justify="space-between" align="center" class="w-full">
<a-checkbox v-model="loginConfig.rememberMe">记住我</a-checkbox>
<a-link>忘记密码</a-link>
</a-row>
</a-form-item>
<a-form-item>
<a-space direction="vertical" fill class="w-full">
<a-button class="btn" type="primary" :loading="loading" html-type="submit" size="large" long>立即登录</a-button>
</a-space>
</a-form-item>
</a-form>
</template>
<script setup lang="ts">
import { type FormInstance, Message } from '@arco-design/web-vue'
import { useStorage } from '@vueuse/core'
import { getImageCaptcha } from '@/apis/common'
import { useAppStore, useTabsStore, useUserStore } from '@/stores'
import { encryptByRsa } from '@/utils/encrypt'
const loginConfig = useStorage('login-config', {
// rememberMe: true,
// username: 'admin', // 演示默认值
// password: 'admin123', // 演示默认值
rememberMe: false,
username: '',
password: '',
})
// 是否启用验证码
const isCaptchaEnabled = ref(true)
// 验证码图片
const captchaImgBase64 = ref()
const formRef = ref<FormInstance>()
const form = reactive({
username: loginConfig.value.username,
password: loginConfig.value.password,
captcha: '',
uuid: '',
expired: false,
})
const rules: FormInstance['rules'] = {
username: [{ required: true, message: '请输入用户名' }],
password: [{ required: true, message: '请输入密码' }],
captcha: [{ required: isCaptchaEnabled.value, message: '请输入验证码' }],
}
// 验证码过期定时器
let timer
const startTimer = (expireTime: number, curTime = Date.now()) => {
if (timer) {
clearTimeout(timer)
}
const remainingTime = expireTime - curTime
if (remainingTime <= 0) {
form.expired = true
return
}
timer = setTimeout(() => {
form.expired = true
}, remainingTime)
}
// 组件销毁时清理定时器
onBeforeUnmount(() => {
if (timer) {
clearTimeout(timer)
}
})
// 获取验证码
const getCaptcha = () => {
getImageCaptcha().then((res) => {
const { uuid, img, expireTime, isEnabled } = res.data
isCaptchaEnabled.value = isEnabled
captchaImgBase64.value = img
form.uuid = uuid
form.expired = false
startTimer(expireTime, Number(res.timestamp))
})
}
const userStore = useUserStore()
const tabsStore = useTabsStore()
const appStore = useAppStore()
const router = useRouter()
const loading = ref(false)
// 登录
const handleLogin = async () => {
try {
const isInvalid = await formRef.value?.validate()
if (isInvalid) return
loading.value = true
await userStore.accountLogin({
username: form.username,
password: encryptByRsa(form.password) || '',
captcha: form.captcha,
uuid: form.uuid,
})
// 登录成功后获取系统配置(根据登录账号显示不同的系统名称)
await appStore.initSiteConfig()
tabsStore.reset()
const { redirect, ...othersQuery } = router.currentRoute.value.query
const { rememberMe } = loginConfig.value
loginConfig.value.username = rememberMe ? form.username : ''
await router.push({
path: (redirect as string) || '/',
query: {
...othersQuery,
},
})
Message.success('欢迎使用')
} catch (error) {
console.error(error)
getCaptcha()
form.captcha = ''
} finally {
loading.value = false
}
}
onMounted(() => {
getCaptcha()
})
</script>
<style scoped lang="scss">
.arco-input-wrapper,
:deep(.arco-select-view-single) {
height: 40px;
border-radius: 4px;
font-size: 13px;
}
.arco-input-wrapper.arco-input-error {
background-color: rgb(var(--danger-1));
border-color: rgb(var(--danger-3));
}
.arco-input-wrapper.arco-input-error:hover {
background-color: rgb(var(--danger-1));
border-color: rgb(var(--danger-6));
}
.arco-input-wrapper :deep(.arco-input) {
font-size: 13px;
color: var(--color-text-1);
}
.arco-input-wrapper:hover {
border-color: rgb(var(--arcoblue-6));
}
.captcha {
width: 111px;
height: 36px;
margin: 0 0 0 5px;
}
.btn {
height: 40px;
}
.captcha-container {
position: relative;
display: inline-block;
cursor: pointer;
}
.overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(51, 51, 51, 0.8);
display: flex;
justify-content: center;
align-items: center;
}
.overlay p {
font-size: 12px;
color: white;
}
</style>