mirror of
https://github.com/zclzone/vue-naive-admin.git
synced 2025-04-30 22:29:01 +08:00
133 lines
3.5 KiB
Vue
133 lines
3.5 KiB
Vue
<template>
|
|
<AppPage :show-footer="true" bg-cover :style="{ backgroundImage: `url(${bgImg})` }">
|
|
<div
|
|
style="transform: translateY(25px)"
|
|
class="m-auto max-w-700 min-w-345 f-c-c rounded-10 bg-white bg-opacity-60 p-15 card-shadow"
|
|
dark:bg-dark
|
|
>
|
|
<div hidden w-380 px-20 py-35 md:block>
|
|
<img src="@/assets/images/login_banner.webp" w-full alt="login_banner" />
|
|
</div>
|
|
|
|
<div w-320 flex-col px-20 py-35>
|
|
<h5 f-c-c text-24 font-normal color="#6a6a6a">
|
|
<img src="@/assets/images/logo.png" height="50" class="mr-10" />
|
|
{{ title }}
|
|
</h5>
|
|
<div mt-32>
|
|
<n-input
|
|
v-model:value="loginInfo.name"
|
|
autofocus
|
|
class="h-48 items-center text-16"
|
|
placeholder="name"
|
|
:maxlength="20"
|
|
>
|
|
<template #prefix>
|
|
<icon-material-symbols:account-circle-outline class="mr-8 text-20 opacity-40" />
|
|
</template>
|
|
</n-input>
|
|
</div>
|
|
<div mt-32>
|
|
<n-input
|
|
v-model:value="loginInfo.password"
|
|
class="h-48 items-center text-16"
|
|
type="password"
|
|
show-password-on="mousedown"
|
|
placeholder="password"
|
|
:maxlength="20"
|
|
@keydown.enter="handleLogin"
|
|
>
|
|
<template #prefix>
|
|
<icon-ri:lock-password-line class="mr-8 text-20 opacity-40" />
|
|
</template>
|
|
</n-input>
|
|
</div>
|
|
|
|
<div mt-20>
|
|
<n-checkbox
|
|
:checked="isRemember"
|
|
label="记住我"
|
|
:on-update:checked="(val) => (isRemember = val)"
|
|
/>
|
|
</div>
|
|
|
|
<div mt-20>
|
|
<n-button
|
|
h-50
|
|
w-full
|
|
rounded-5
|
|
text-16
|
|
type="primary"
|
|
:loading="loading"
|
|
@click="handleLogin"
|
|
>
|
|
登录
|
|
</n-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</AppPage>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { lStorage, setToken } from '@/utils'
|
|
import { useStorage } from '@vueuse/core'
|
|
import bgImg from '@/assets/images/login_bg.webp'
|
|
import api from './api'
|
|
import { addDynamicRoutes } from '@/router'
|
|
|
|
const title = import.meta.env.VITE_TITLE
|
|
|
|
const router = useRouter()
|
|
const { query } = useRoute()
|
|
|
|
const loginInfo = ref({
|
|
name: '',
|
|
password: '',
|
|
})
|
|
|
|
initLoginInfo()
|
|
|
|
function initLoginInfo() {
|
|
const localLoginInfo = lStorage.get('loginInfo')
|
|
if (localLoginInfo) {
|
|
loginInfo.value.name = localLoginInfo.name || ''
|
|
loginInfo.value.password = localLoginInfo.password || ''
|
|
}
|
|
}
|
|
|
|
const isRemember = useStorage('isRemember', false)
|
|
const loading = ref(false)
|
|
async function handleLogin() {
|
|
const { name, password } = loginInfo.value
|
|
if (!name || !password) {
|
|
$message.warning('请输入用户名和密码')
|
|
return
|
|
}
|
|
try {
|
|
loading.value = true
|
|
$message.loading('正在验证...')
|
|
const res = await api.login({ name, password: password.toString() })
|
|
$message.success('登录成功')
|
|
setToken(res.data.token)
|
|
if (isRemember.value) {
|
|
lStorage.set('loginInfo', { name, password })
|
|
} else {
|
|
lStorage.remove('loginInfo')
|
|
}
|
|
await addDynamicRoutes()
|
|
if (query.redirect) {
|
|
const path = query.redirect
|
|
Reflect.deleteProperty(query, 'redirect')
|
|
router.push({ path, query })
|
|
} else {
|
|
router.push('/')
|
|
}
|
|
} catch (error) {
|
|
console.error(error)
|
|
$message.removeMessage()
|
|
}
|
|
loading.value = false
|
|
}
|
|
</script>
|