Files
one-pipe-system/src/composables/useLogin.ts
luo 2c8524485b
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m24s
fix: 资产信息字段显示隐藏根据角色
2026-07-13 16:40:35 +08:00

189 lines
4.8 KiB
TypeScript

/**
* 登录逻辑 Composable
*/
import { ref, reactive, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { ElNotification, ElMessage } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import { useUserStore } from '@/store/modules/user'
import { RoutesAlias } from '@/router/routesAlias'
import AppConfig from '@/config'
import { AuthService } from '@/api/modules'
import { ApiStatus } from '@/utils/http/status'
import { saveCredentials, getRememberedCredentials } from '@/utils/auth/rememberPassword'
import { usernameRules, passwordRules } from '@/utils/auth/loginValidation'
/**
* 登录表单数据
*/
interface LoginForm {
username: string
password: string
rememberPassword: boolean
}
export function useLogin() {
const { t } = useI18n()
const router = useRouter()
const userStore = useUserStore()
// 表单引用
const formRef = ref<FormInstance>()
// 加载状态
const loading = ref(false)
// 表单数据
const formData = reactive<LoginForm>({
username: '',
password: '',
rememberPassword: true
})
// 验证规则
const rules = computed<FormRules>(() => ({
username: usernameRules(t),
password: passwordRules(t)
}))
// 初始化表单
const initForm = () => {
const remembered = getRememberedCredentials()
if (remembered) {
formData.username = remembered.username
formData.password = remembered.password
formData.rememberPassword = remembered.rememberPassword
} else {
if (import.meta.env.DEV) {
formData.username = 'admin'
formData.password = 'Admin@123456'
formData.rememberPassword = false
}
}
}
/**
* 执行登录
*/
const handleLogin = async () => {
if (!formRef.value) return
try {
// 验证表单
const valid = await formRef.value.validate()
if (!valid) return
loading.value = true
await handleRealLogin()
} catch (error: any) {
console.error('登录失败:', error)
} finally {
loading.value = false
}
}
/**
* 登录
*/
const handleRealLogin = async () => {
// 调用登录接口
const response = await AuthService.login({
username: formData.username,
password: formData.password
})
// 检查响应状态
if (response.code !== ApiStatus.success) {
console.log(response.msg || t('login.error.invalidCredentials'))
return
}
// 检查返回数据
if (!response.data || !response.data.access_token) {
console.log(t('login.error.loginFailed'))
return
}
if (!response.data.user) {
ElMessage.error(t('login.error.getUserInfoFailed'))
return
}
// 登录成功但没有后台菜单或权限时,仅提示并停止后续流程。
// 这里不保存登录态,也不触发后续跳转,避免进入路由守卫后再连续调用退出接口。
const hasPermissions =
Array.isArray(response.data.permissions) && response.data.permissions.length > 0
const hasMenus = Array.isArray(response.data.menus) && response.data.menus.length > 0
if (!hasPermissions || !hasMenus) {
ElMessage.warning({
message: '当前账号暂无任何权限,请联系管理员分配角色和权限',
duration: 4000,
showClose: true
})
saveCredentials(formData.username, formData.password, formData.rememberPassword)
return
}
// 保存 Token
userStore.setToken(response.data.access_token, response.data.refresh_token)
// 保存用户信息
userStore.setUserInfo(response.data.user)
userStore.setLoginStatus(true)
// 保存权限、菜单和按钮
if (response.data.permissions) {
userStore.setPermissions(response.data.permissions)
}
if (response.data.menus) {
userStore.setMenus(response.data.menus)
}
if (response.data.buttons) {
userStore.setButtons(response.data.buttons)
}
// 保存记住密码
saveCredentials(formData.username, formData.password, formData.rememberPassword)
// 显示登录成功提示
showLoginSuccessNotice()
// 等待数据持久化完成
await new Promise((resolve) => setTimeout(resolve, 100))
// 跳转到资产信息页面
await router.push(RoutesAlias.AssetInformation)
}
/**
* 显示登录成功通知
*/
const showLoginSuccessNotice = () => {
setTimeout(() => {
ElNotification({
title: t('login.success.title'),
type: 'success',
duration: 2500,
zIndex: 10000,
message: `${t('login.success.message')}, ${AppConfig.systemInfo.name}!`
})
}, 150)
}
// 组件挂载时初始化
onMounted(() => {
initForm()
})
return {
formRef,
formData,
rules,
loading,
handleLogin
}
}