import { defineStore } from 'pinia' import { computed, reactive, ref } from 'vue' import { resetRouter } from '@/router' import { type AccountLoginReq, AuthTypeConstants, type EmailLoginReq, type PhoneLoginReq, type UserDetail, type DeptDetail, type RoleDetail, type UserInfo, accountLogin as accountLoginApi, emailLogin as emailLoginApi, getUserInfo as getUserInfoApi, logout as logoutApi, phoneLogin as phoneLoginApi, socialLogin as socialLoginApi, } from '@/apis' import { clearToken, getToken, setToken } from '@/utils/auth' import { resetHasRouteFlag } from '@/router/guard' interface NewUserInfoData { user: UserDetail; dept: DeptDetail; roles: RoleDetail[]; posts: any[]; } const storeSetup = () => { // 更新用户信息结构以匹配新API const userInfo = reactive({ userId: '', account: '', name: '', status: 0, userCode: '', userStatus: '', userType: '', mobile: '', createTime: '', deptId: '', deptName: '', avatar: '', roles: [] as string[], permissions: [] as string[] }) const nickname = computed(() => userInfo.name) const username = computed(() => userInfo.account) const avatar = computed(() => userInfo.avatar) const token = ref(getToken() || '') const pwdExpiredShow = ref(true) const roles = ref([]) // 当前用户角色 const permissions = ref([]) // 当前角色权限标识集合 // 重置token const resetToken = () => { token.value = '' clearToken() resetHasRouteFlag() } // 登录 const accountLogin = async (req: AccountLoginReq) => { const res = await accountLoginApi({ ...req }) setToken(res.data.tokenValue) token.value = res.data.tokenValue } // 邮箱登录 const emailLogin = async (req: EmailLoginReq) => { const res = await emailLoginApi({ ...req, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeConstants.EMAIL }) setToken(res.data.token) token.value = res.data.token } // 手机号登录 const phoneLogin = async (req: PhoneLoginReq) => { const res = await phoneLoginApi({ ...req, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeConstants.PHONE }) setToken(res.data.token) token.value = res.data.token } // 三方账号登录 const socialLogin = async (source: string, req: any) => { const res = await socialLoginApi({ ...req, source, clientId: import.meta.env.VITE_CLIENT_ID, authType: AuthTypeConstants.SOCIAL }) setToken(res.data.token) token.value = res.data.token } // 退出登录回调 const logoutCallBack = async () => { roles.value = [] permissions.value = [] pwdExpiredShow.value = true resetToken() resetRouter() } // 退出登录 const logout = async () => { try { await logoutApi() await logoutCallBack() return true } catch (error) { return false } } // 获取用户信息 const getInfo = async () => { const res = await getUserInfoApi() // 检查返回数据格式,适配新旧API if (res.data && 'user' in res.data) { // 新API结构 const { user, dept, roles: userRoles } = res.data as unknown as NewUserInfoData // 更新用户基本信息 userInfo.userId = user.userId userInfo.account = user.account userInfo.name = user.name userInfo.status = user.status userInfo.userCode = user.userCode userInfo.userStatus = user.userStatus userInfo.userType = user.userType userInfo.mobile = user.mobile userInfo.createTime = user.createTime // 更新部门信息 if (dept) { userInfo.deptId = dept.deptId userInfo.deptName = dept.deptName } // 处理角色信息 if (userRoles && userRoles.length) { // 提取角色键作为权限标识 const roleKeys = userRoles.map(role => role.roleKey).filter(Boolean) as string[] roles.value = roleKeys // 由于新API没有直接提供permissions,这里默认给管理员全部权限 permissions.value = roleKeys.includes('admin') ? ['*:*:*'] : [] } } else if (res.data) { // 旧API结构,保留兼容 const oldData = res.data as unknown as UserInfo // 映射旧结构到新结构 userInfo.userId = oldData.id userInfo.account = oldData.username userInfo.name = oldData.nickname userInfo.avatar = oldData.avatar userInfo.deptName = oldData.deptName if (oldData.roles && oldData.roles.length) { roles.value = oldData.roles permissions.value = oldData.permissions } } } return { userInfo, nickname, username, avatar, token, roles, permissions, pwdExpiredShow, accountLogin, emailLogin, phoneLogin, socialLogin, logout, logoutCallBack, getInfo, resetToken, } } export const useUserStore = defineStore('user', storeSetup, { persist: { paths: ['token', 'roles', 'permissions', 'pwdExpiredShow'], storage: localStorage }, })