1
0
mirror of https://github.com/zclzone/vue-naive-admin.git synced 2025-05-01 06:39:01 +08:00
2024-03-31 18:33:58 +08:00

183 lines
5.1 KiB
Vue

<!--------------------------------
- @Author: Ronnie Zhang
- @LastEditor: Ronnie Zhang
- @LastEditTime: 2023/12/05 21:28:36
- @Email: zclzone@outlook.com
- Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
--------------------------------->
<template>
<div class="wh-full flex-col bg-[url(@/assets/images/login_bg.webp)] bg-cover">
<div
class="m-auto max-w-700 min-w-345 f-c-c rounded-8 bg-opacity-20 bg-cover p-12 card-shadow auto-bg"
>
<div class="hidden w-380 px-20 py-35 md:block">
<img src="@/assets/images/login_banner.webp" class="w-full" alt="login_banner" />
</div>
<div class="w-320 flex-col px-20 py-32">
<h2 class="f-c-c text-24 text-#6a6a6a font-normal">
<img src="@/assets/images/logo.png" class="mr-12 h-50" />
{{ title }}
</h2>
<n-input
v-model:value="loginInfo.username"
autofocus
class="mt-32 h-40 items-center"
placeholder="请输入用户名"
:maxlength="20"
>
<template #prefix>
<i class="i-fe:user mr-12 opacity-20" />
</template>
</n-input>
<n-input
v-model:value="loginInfo.password"
class="mt-20 h-40 items-center"
type="password"
show-password-on="mousedown"
placeholder="请输入密码"
:maxlength="20"
@keydown.enter="handleLogin()"
>
<template #prefix>
<i class="i-fe:lock mr-12 opacity-20" />
</template>
</n-input>
<div class="mt-20 flex items-center">
<n-input
v-model:value="loginInfo.captcha"
class="h-40 items-center"
palceholder="请输入验证码"
:maxlength="4"
@keydown.enter="handleLogin()"
>
<template #prefix>
<i class="i-fe:key mr-12 opacity-20" />
</template>
</n-input>
<img
v-if="captchaUrl"
:src="captchaUrl"
alt="验证码"
height="40"
class="ml-12 w-80 cursor-pointer"
@click="initCaptcha"
/>
</div>
<n-checkbox
class="mt-20"
:checked="isRemember"
label="记住我"
:on-update:checked="(val) => (isRemember = val)"
/>
<div class="mt-20 flex items-center">
<n-button
class="h-40 flex-1 rounded-5 text-16"
type="primary"
ghost
@click="quickLogin()"
>
一键体验
</n-button>
<n-button
class="ml-32 h-40 flex-1 rounded-5 text-16"
type="primary"
:loading="loading"
@click="handleLogin()"
>
登录
</n-button>
</div>
</div>
</div>
<TheFooter class="py-12" />
</div>
</template>
<script setup>
import { throttle, lStorage } from '@/utils'
import { useStorage } from '@vueuse/core'
import api from './api'
import { useAuthStore } from '@/store'
const authStore = useAuthStore()
const router = useRouter()
const route = useRoute()
const title = import.meta.env.VITE_TITLE
const loginInfo = ref({
username: '',
password: '',
})
const captchaUrl = ref('')
const initCaptcha = throttle(() => {
captchaUrl.value = '/api/auth/captcha?' + Date.now()
}, 500)
const localLoginInfo = lStorage.get('loginInfo')
if (localLoginInfo) {
loginInfo.value.username = localLoginInfo.username || ''
loginInfo.value.password = localLoginInfo.password || ''
}
initCaptcha()
function quickLogin() {
loginInfo.value.username = 'admin'
loginInfo.value.password = '123456'
handleLogin(true)
}
const isRemember = useStorage('isRemember', true)
const loading = ref(false)
async function handleLogin(isQuick) {
const { username, password, captcha } = loginInfo.value
if (!username || !password) return $message.warning('请输入用户名和密码')
if (!isQuick && !captcha) return $message.warning('请输入验证码')
try {
loading.value = true
$message.loading('正在验证,请稍后...', { key: 'login' })
const { data } = await api.login({ username, password: password.toString(), captcha, isQuick })
if (isRemember.value) {
lStorage.set('loginInfo', { username, password })
} else {
lStorage.remove('loginInfo')
}
onLoginSuccess(data)
} catch (error) {
// 10003为验证码错误专属业务码
if (error?.code === 10003) {
// 为防止爆破,验证码错误则刷新验证码
initCaptcha()
}
$message.destroy('login')
console.error(error)
}
loading.value = false
}
async function onLoginSuccess(data = {}) {
authStore.setToken(data)
$message.loading('登录中...', { key: 'login' })
try {
$message.success('登录成功', { key: 'login' })
if (route.query.redirect) {
const path = route.query.redirect
delete route.query.redirect
router.push({ path, query: route.query })
} else {
router.push('/')
}
} catch (error) {
console.error(error)
$message.destroy('login')
}
}
</script>