You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 
 
 
 

188 lines
5.7 KiB

import type { ErrorMessageMode } from '@/types/axios'
import { h } from 'vue'
import { defineStore } from 'pinia'
import { store } from '@/store'
import { router } from '@/router'
import { RoleEnum } from '@/enums/roleEnum'
import { PageEnum } from '@/enums/pageEnum'
import { ROLES_KEY, ACCESS_TOKEN_KEY, REFRESH_TOKEN_KEY, USER_INFO_KEY } from '@/enums/cacheEnum'
import { RouteRecordRaw } from 'vue-router'
import { PAGE_NOT_FOUND_ROUTE } from '@/router/routes/basic'
import { usePermissionStore } from '@/store/modules/permission'
import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { getAuthCache, setAuthCache } from '@/utils/auth'
import { doLogout, getUserInfo, loginApi } from '@/api/base/user'
import { GetUserInfoModel, LoginParams } from '@/api/base/model/userModel'
import { isArray } from '@/utils/is'
interface UserState {
userInfo: Nullable<GetUserInfoModel>
accessToken?: string
refreshToken?: string
roleList: RoleEnum[]
sessionTimeout?: boolean
lastUpdateTime: number
}
export const useUserStore = defineStore('app-user', {
state: (): UserState => ({
// user info
userInfo: null,
// token
accessToken: undefined,
refreshToken: undefined,
// roleList
roleList: [],
// Whether the login expired
sessionTimeout: false,
// Last fetch time
lastUpdateTime: 0
}),
getters: {
getUserInfo(): GetUserInfoModel {
return this.userInfo || getAuthCache<GetUserInfoModel>(USER_INFO_KEY) || {}
},
getAccessToken(): string {
return this.accessToken || getAuthCache<string>(ACCESS_TOKEN_KEY)
},
getRefreshToken(): string {
return this.refreshToken || getAuthCache<string>(REFRESH_TOKEN_KEY)
},
getRoleList(): RoleEnum[] {
return this.roleList.length > 0 ? this.roleList : getAuthCache<RoleEnum[]>(ROLES_KEY)
},
getSessionTimeout(): boolean {
return !!this.sessionTimeout
},
getLastUpdateTime(): number {
return this.lastUpdateTime
}
},
actions: {
setAccessToken(info: string | undefined) {
this.accessToken = info ? info : '' // for null or undefined value
setAuthCache(ACCESS_TOKEN_KEY, info)
},
setRefreshToken(info: string | undefined) {
this.refreshToken = info ? info : '' // for null or undefined value
setAuthCache(REFRESH_TOKEN_KEY, info)
},
setRoleList(roleList: RoleEnum[]) {
this.roleList = roleList
setAuthCache(ROLES_KEY, roleList)
},
setUserInfo(info: GetUserInfoModel | null) {
this.userInfo = info
this.lastUpdateTime = new Date().getTime()
setAuthCache(USER_INFO_KEY, info)
},
setSessionTimeout(flag: boolean) {
this.sessionTimeout = flag
},
resetState() {
this.userInfo = null
this.accessToken = ''
this.roleList = []
this.sessionTimeout = false
},
/**
* @description: login
*/
async login(
params: LoginParams & {
goHome?: boolean
mode?: ErrorMessageMode
}
): Promise<GetUserInfoModel | null> {
try {
const { goHome = true, mode, ...loginParams } = params
const data = await loginApi(loginParams, mode)
const { accessToken, refreshToken } = data
// save token
this.setAccessToken(accessToken)
this.setRefreshToken(refreshToken)
return this.afterLoginAction(goHome)
} catch (error) {
return Promise.reject(error)
}
},
async afterLoginAction(goHome?: boolean): Promise<GetUserInfoModel | null> {
if (!this.getAccessToken) return null
// get user info
const userInfo = await this.getUserInfoAction()
const sessionTimeout = this.sessionTimeout
if (sessionTimeout) {
this.setSessionTimeout(false)
} else {
const permissionStore = usePermissionStore()
if (!permissionStore.isDynamicAddedRoute) {
const routes = await permissionStore.buildRoutesAction()
routes.forEach((route) => {
router.addRoute(route as unknown as RouteRecordRaw)
})
router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw)
permissionStore.setDynamicAddedRoute(true)
}
console.info(router.replace(PageEnum.BASE_HOME))
goHome && (await router.replace(PageEnum.BASE_HOME))
}
return userInfo
},
async getUserInfoAction(): Promise<GetUserInfoModel | null> {
if (!this.getAccessToken) return null
const userInfo = await getUserInfo()
const { roles = [] } = userInfo
if (isArray(roles)) {
const roleList = roles.map((item) => item) as RoleEnum[]
this.setRoleList(roleList)
} else {
userInfo.roles = []
this.setRoleList([])
}
this.setUserInfo(userInfo)
return userInfo
},
/**
* @description: logout
*/
async logout(goLogin = false) {
if (this.getAccessToken) {
try {
await doLogout()
} catch {
console.log('注销Token失败')
}
}
this.setAccessToken(undefined)
this.setSessionTimeout(false)
this.setUserInfo(null)
goLogin && router.push(PageEnum.BASE_LOGIN)
},
/**
* @description: Confirm before logging out
*/
confirmLoginOut() {
const { createConfirm } = useMessage()
const { t } = useI18n()
createConfirm({
iconType: 'warning',
title: () => h('span', t('sys.app.logoutTip')),
content: () => h('span', t('sys.app.logoutMessage')),
onOk: async () => {
await this.logout(true)
}
})
}
}
})
// Need to be used outside the setup
export function useUserStoreWithOut() {
return useUserStore(store)
}