141 lines
5.2 KiB
Vue
141 lines
5.2 KiB
Vue
<template>
|
||
<div class="user-container">
|
||
<div class="card">
|
||
<!-- 头部标题 -->
|
||
<div class="header">
|
||
<h1>登录 👋</h1>
|
||
</div>
|
||
|
||
<el-form :model="LoginForm" :rules="formRules" ref="loginFormRef" class="login-form" size="default">
|
||
<!-- 用户名输入 -->
|
||
<el-form-item label="用户名" prop="username" :label-position="labelPosition" label-width="65px">
|
||
<el-input v-model="LoginForm.email" placeholder="请输入用户名" :prefix-icon="User" />
|
||
</el-form-item>
|
||
|
||
<!-- 密码输入 -->
|
||
<el-form-item label="密码" prop="password" :label-position="labelPosition" label-width="65px">
|
||
<el-input v-model="LoginForm.password" type="password" placeholder="请输入密码" :prefix-icon="Lock"
|
||
show-password />
|
||
</el-form-item>
|
||
|
||
<!-- 记住账号 & 忘记密码 -->
|
||
<el-form-item class="form-footer">
|
||
<div class="form-footer-content">
|
||
<el-checkbox v-model="LoginForm.remember" class="remember-checkbox">记住账号</el-checkbox>
|
||
<router-link to="/reset-password" class="forgot-password">忘记密码?</router-link>
|
||
</div>
|
||
</el-form-item>
|
||
|
||
<!-- 登录按钮(Element Plus 主按钮规范) -->
|
||
<el-form-item width="100%">
|
||
<el-button type="primary" class="login-btn" size="large" @click="handleLogin" style="width: 100%"
|
||
:loading="userStore.loading" :disabled="userStore.loading">
|
||
{{ userStore.loading ? '登录中...' : '登录' }}
|
||
</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
// element 导入
|
||
import type { FormInstance, FormRules, FormProps } from 'element-plus'
|
||
import { User, Lock } from '@element-plus/icons-vue'
|
||
// type导入
|
||
import type { LoginForm as LoginFormType } from '@/type/user'
|
||
// 业务导入
|
||
import { useUserStore } from '@/stores/user'
|
||
import { useLocalStorage, useSessionStorage } from '@/utils/storage'
|
||
|
||
// 加密导入
|
||
import { encryptPassword } from '@/utils/encrypt'
|
||
|
||
const router = useRouter()
|
||
const error = ref('')
|
||
const userStore = useUserStore()
|
||
// 表单 Ref(符合 Element Plus 规范)
|
||
const loginFormRef = ref<FormInstance>()
|
||
const labelPosition = ref<FormProps['labelPosition']>('left')
|
||
// 表单数据
|
||
const LoginForm = reactive<LoginFormType>({
|
||
email: '1241208486@qq.com',
|
||
password: encryptPassword('888888'),
|
||
login_type: 1,
|
||
})
|
||
// 表单校验规则(Element Plus 标准校验)
|
||
const formRules = reactive<FormRules>({
|
||
email: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
||
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
|
||
})
|
||
|
||
// 登录
|
||
const handleLogin = async () => {
|
||
if (!loginFormRef.value) return
|
||
loginFormRef.value.validate(async (valid) => {
|
||
if (valid) {
|
||
try {
|
||
error.value = ''
|
||
await userStore.login(LoginForm)
|
||
saveRememberedUsername()
|
||
// 如果是登录或者退出登录重新登录,都是跳转首页,如果是从修改密码操作返回登录页,就跳转回修改密码操作前的页面
|
||
const isChangePassword = useSessionStorage.get('changePassword');
|
||
const backPath = useSessionStorage.get('backPath') || '/';
|
||
|
||
// 2. 先清理 sessionStorage(避免残留,执行顺序关键)
|
||
useSessionStorage.remove('changePassword');
|
||
useSessionStorage.remove('backPath');
|
||
|
||
// 3. 重置菜单折叠状态(提前执行,避免跳转中断)
|
||
useLocalStorage.set('isCollapse', false);
|
||
const targetPath = isChangePassword ? backPath : '/';
|
||
|
||
router.push(typeof targetPath === 'string' ? targetPath : targetPath.value || '/');
|
||
} catch (err) {
|
||
error.value = err instanceof Error ? err.message : '登录失败'
|
||
}
|
||
} else {
|
||
console.log('登录表单验证失败')
|
||
}
|
||
})
|
||
}
|
||
// 记住账号
|
||
const saveRememberedUsername = () => {
|
||
if (LoginForm.remember) {
|
||
useLocalStorage.set('rememberedUsername', LoginForm.email)
|
||
} else {
|
||
useLocalStorage.remove('rememberedUsername')
|
||
}
|
||
}
|
||
// 从本地存储加载记住的用户名
|
||
const loadRememberedUsername = () => {
|
||
const rememberedUsername = useLocalStorage.get('rememberedUsername')
|
||
if (rememberedUsername.value) {
|
||
LoginForm.email = rememberedUsername.value
|
||
LoginForm.remember = true
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
// 组件挂载时加载记住的用户名
|
||
loadRememberedUsername()
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.login-form {
|
||
.form-footer {
|
||
.form-footer-content {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
width: 100%;
|
||
|
||
.forgot-password {
|
||
color: #409eff;
|
||
text-decoration: none;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style> |