131 lines
3.8 KiB
TypeScript
131 lines
3.8 KiB
TypeScript
import { router } from '@/router'
|
||
import { fetchLogin, fetchLoginUserInfo, fetchLogout } from '@/service/api/auth'
|
||
import { local } from '@/utils'
|
||
import { useRouteStore } from './router'
|
||
import { useTabStore } from './tab'
|
||
|
||
interface AuthStatus {
|
||
userInfo: Api.Login.Info | null
|
||
token: string
|
||
}
|
||
export const useAuthStore = defineStore('auth-store', {
|
||
state: (): AuthStatus => {
|
||
return {
|
||
userInfo: local.get('userInfo'),
|
||
token: local.get('accessToken') || '',
|
||
}
|
||
},
|
||
getters: {
|
||
/** 是否登录 */
|
||
isLogin(state) {
|
||
return Boolean(state.token)
|
||
},
|
||
},
|
||
actions: {
|
||
/* 登录退出,重置用户信息等 */
|
||
async logout() {
|
||
const route = unref(router.currentRoute)
|
||
|
||
// 先清除本地缓存,立即使token失效
|
||
this.clearAuthStorage()
|
||
// 重置当前存储库
|
||
this.$reset()
|
||
// 清空路由、菜单等数据
|
||
const routeStore = useRouteStore()
|
||
routeStore.resetRouteStore()
|
||
// 清空标签栏数据
|
||
const tabStore = useTabStore()
|
||
tabStore.clearAllTabs()
|
||
|
||
// 最后调用后端退出登录接口
|
||
try {
|
||
await fetchLogout()
|
||
}
|
||
catch (error) {
|
||
// 后端接口调用失败不影响前端清理
|
||
console.warn('后端退出登录接口调用失败:', error)
|
||
}
|
||
|
||
// 重定向到登录页
|
||
if (route.meta.requiresAuth) {
|
||
router.push({
|
||
name: 'login',
|
||
query: {
|
||
redirect: route.fullPath,
|
||
},
|
||
})
|
||
}
|
||
},
|
||
clearAuthStorage() {
|
||
local.remove('accessToken')
|
||
local.remove('refreshToken')
|
||
local.remove('userInfo')
|
||
},
|
||
|
||
/* 用户登录 */
|
||
async login(loginName: string, password: string, codeKey: string, securityCode: string, rememberMe = false) {
|
||
try {
|
||
const { isSuccess, data } = await fetchLogin({ loginName, password, codeKey, securityCode, rememberMe })
|
||
if (!isSuccess)
|
||
return
|
||
|
||
// 保存Token
|
||
local.set('accessToken', data.tokenValue)
|
||
this.token = data.tokenValue
|
||
|
||
// 获取用户信息
|
||
const userInfoResult = await fetchLoginUserInfo()
|
||
if (!userInfoResult.isSuccess)
|
||
return
|
||
|
||
// 处理登录信息 - 转换后端返回的数据结构
|
||
const userInfo = {
|
||
id: userInfoResult.data.loginUser.userId,
|
||
userId: userInfoResult.data.loginUser.userId,
|
||
userName: userInfoResult.data.loginUser.userName,
|
||
avatar: userInfoResult.data.loginUser.avatar,
|
||
role: userInfoResult.data.roles,
|
||
buttons: userInfoResult.data.buttons, // 用户权限按钮列表
|
||
accessToken: data.tokenValue,
|
||
refreshToken: data.tokenValue, // 没有单独的refreshToken,暂时使用相同值
|
||
}
|
||
await this.handleLoginInfo(userInfo as Api.Login.Info)
|
||
}
|
||
catch (e) {
|
||
console.warn('[Login Error]:', e)
|
||
}
|
||
},
|
||
|
||
/* 处理登录返回的数据 */
|
||
async handleLoginInfo(data: Api.Login.Info) {
|
||
// 将token和userInfo保存下来
|
||
local.set('userInfo', data)
|
||
local.set('accessToken', data.accessToken)
|
||
local.set('refreshToken', data.refreshToken)
|
||
this.token = data.accessToken
|
||
this.userInfo = data
|
||
|
||
// 添加路由和菜单
|
||
const routeStore = useRouteStore()
|
||
await routeStore.initAuthRoute()
|
||
|
||
// 进行重定向跳转
|
||
const route = unref(router.currentRoute)
|
||
const query = route.query as { redirect: string }
|
||
router.push({
|
||
path: query.redirect || '/',
|
||
})
|
||
},
|
||
|
||
/* 更新用户信息 */
|
||
updateUserInfo(updates: Partial<Api.Login.Info>) {
|
||
if (this.userInfo) {
|
||
// 更新内存中的用户信息
|
||
this.userInfo = { ...this.userInfo, ...updates }
|
||
// 更新本地存储
|
||
local.set('userInfo', this.userInfo)
|
||
}
|
||
},
|
||
},
|
||
})
|