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.
205 lines
6.7 KiB
205 lines
6.7 KiB
/** |
|
* @program: kicc-ui |
|
* @description: 当前用户信息存储中心 |
|
* @author: wangxiang4 |
|
* @create: 2022/4/9 |
|
*/ |
|
|
|
import { defineStore } from 'pinia'; |
|
import { store } from '/@/store'; |
|
import { PageEnum } from '/@/enums/pageEnum'; |
|
import { ACCESS_TOKEN_KEY, PERMISSIONS_KEY, REFRESH_TOKEN_KEY, ROLE_IDS_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum'; |
|
import { getAuthCache, setAuthCache } from '/@/utils/auth'; |
|
import { KiccUser } from '/@/api/common/base/entity'; |
|
import { LoginParams } from '/@/api/platform/core/entity/user'; |
|
import { logout, getUserInfo, login } from '/@/api/platform/core/controller/user'; |
|
import { useI18n } from '/@/hooks/web/useI18n'; |
|
import { useMessage } from '/@/hooks/web/useMessage'; |
|
import { router } from '/@/router'; |
|
import { usePermissionStore } from '/@/store/modules/permission'; |
|
import { RouteRecordRaw } from 'vue-router'; |
|
import defaultAvatar from '/@/assets/images/defaultAvatar.svg'; |
|
import { urlToBase64 } from '/@/utils/file/base64Conver'; |
|
import { useGlobSetting } from '/@/hooks/setting'; |
|
import { isUrl, isEmpty } from '/@/utils/is'; |
|
import { h } from 'vue'; |
|
import { getAuthClient } from '/@/utils'; |
|
import { merge } from 'lodash-es'; |
|
import { RequestOptions } from '/#/axios'; |
|
|
|
interface UserState { |
|
userInfo: KiccUser; |
|
sessionTimeout?: boolean; |
|
lastUpdateTime: number; |
|
roleIds: string[]; |
|
permissions: string[]; |
|
access_token?: string; |
|
refresh_token?: string; |
|
} |
|
|
|
export const useUserStore = defineStore({ |
|
id: 'app-user', |
|
state: (): UserState => ({ |
|
// 用户信息 |
|
userInfo: getAuthCache<KiccUser>(USER_INFO_KEY), |
|
// 登录是否过期记录(确保下次登陆不刷新路由直接还原) |
|
sessionTimeout: false, |
|
// 最后一次性更新用户信息时间(用于页面刷新更新用户数据) |
|
lastUpdateTime: 0, |
|
// 角色ID用于权限校验 |
|
roleIds: getAuthCache<string[]>(ROLE_IDS_KEY), |
|
// 按钮权限标识用于权限校验 |
|
permissions: getAuthCache<string[]>(PERMISSIONS_KEY), |
|
// 访问令牌 |
|
access_token: getAuthCache<string>(ACCESS_TOKEN_KEY), |
|
// 刷新令牌 |
|
refresh_token: getAuthCache<string>(REFRESH_TOKEN_KEY), |
|
}), |
|
getters: { |
|
getUserInfo(): KiccUser { |
|
return this.userInfo || {}; |
|
}, |
|
getAccessToken(): string { |
|
return this.access_token; |
|
}, |
|
getRefreshToken(): string { |
|
return this.refresh_token; |
|
}, |
|
getRoleIds(): string[] { |
|
return this.roleIds; |
|
}, |
|
getPermissions(): string[] { |
|
return this.permissions; |
|
}, |
|
getSessionTimeout(): boolean { |
|
return !!this.sessionTimeout; |
|
}, |
|
getLastUpdateTime(): number { |
|
return this.lastUpdateTime; |
|
}, |
|
}, |
|
actions: { |
|
setRoleIds(roleIds: string[]) { |
|
this.roleIds = roleIds; |
|
setAuthCache(ROLE_IDS_KEY, roleIds); |
|
}, |
|
setPermissions(permissions: string[]) { |
|
this.permissions = permissions; |
|
setAuthCache(PERMISSIONS_KEY, permissions); |
|
}, |
|
setAccessToken(accessToken: string) { |
|
this.access_token = accessToken; |
|
setAuthCache(ACCESS_TOKEN_KEY, accessToken); |
|
}, |
|
setRefreshToken(refreshToken: string) { |
|
this.refresh_token = refreshToken; |
|
setAuthCache(REFRESH_TOKEN_KEY, refreshToken); |
|
}, |
|
setUserInfo(userInfo: Partial<KiccUser>) { |
|
this.userInfo = userInfo; |
|
this.lastUpdateTime = new Date().getTime(); |
|
setAuthCache(USER_INFO_KEY, userInfo); |
|
}, |
|
setSessionTimeout(flag: boolean) { |
|
this.sessionTimeout = flag; |
|
}, |
|
resetState(): void { |
|
this.setSessionTimeout(false); |
|
this.setUserInfo({}); |
|
this.setRoleIds([]); |
|
this.setPermissions([]); |
|
}, |
|
/** 登录 */ |
|
async login(params: LoginParams): Promise<KiccUser | null> { |
|
try { |
|
const { goHome = true, clientId = '', ...loginParams } = params; |
|
// 处理自定义授权客户端 |
|
if (clientId) { |
|
const client = getAuthClient(clientId); |
|
!isEmpty(client) && merge(loginParams, { |
|
options: { |
|
clientId: client[0], |
|
clientSecret: client[1] |
|
} as RequestOptions |
|
}); |
|
} |
|
const data = await login(loginParams); |
|
const { access_token, refresh_token } = data; |
|
this.setUserInfo(data.user_info); |
|
this.setAccessToken(access_token); |
|
this.setRefreshToken(refresh_token); |
|
return this.afterLoginAction(goHome); |
|
} catch (error) { |
|
return Promise.reject(error); |
|
} |
|
}, |
|
/** 登录成功后动作 */ |
|
async afterLoginAction(goHome?: boolean): Promise<KiccUser | null> { |
|
if (!this.getAccessToken) return null; |
|
// 获取用户信息 |
|
const userInfo = await this.getUserInfoAction(); |
|
const sessionTimeout = this.sessionTimeout; |
|
if (sessionTimeout) { |
|
this.setSessionTimeout(false); |
|
} else { |
|
// 处理路由与菜单的构建,并且进行缓存 |
|
const permissionStore = usePermissionStore(); |
|
// 使用isDynamicAddedRoute字段做菜单路由缓存功能 |
|
if (!permissionStore.isDynamicAddedRoute) { |
|
const routes = await permissionStore.buildRoutesAction(); |
|
routes.forEach((route) => { |
|
router.addRoute(route as unknown as RouteRecordRaw); |
|
}); |
|
permissionStore.setDynamicAddedRoute(true); |
|
} |
|
goHome && await router.replace(userInfo?.homePath || PageEnum.BASE_HOME); |
|
} |
|
return userInfo; |
|
}, |
|
/** 获取用户信息 */ |
|
async getUserInfoAction(): Promise<KiccUser> { |
|
const { apiUrl } = useGlobSetting(); |
|
const { t } = useI18n(); |
|
try { |
|
const userInfo = await getUserInfo(); |
|
userInfo.avatar = userInfo.avatar |
|
? isUrl(userInfo.avatar) |
|
? userInfo.avatar |
|
: apiUrl + userInfo.avatar |
|
: await urlToBase64(defaultAvatar); |
|
// 存储用户扩展信息,便于鉴权 |
|
this.setUserInfo(userInfo); |
|
this.setRoleIds(userInfo.roleIds); |
|
this.setPermissions(userInfo.permissions); |
|
return userInfo; |
|
} catch (error) { console.error(error); } |
|
return Promise.resolve({} as KiccUser); |
|
}, |
|
/** 登出 */ |
|
async logout(goLogin = false) { |
|
await logout(); |
|
this.resetState(); |
|
this.setAccessToken(''); |
|
this.setRefreshToken(''); |
|
goLogin && await router.push(PageEnum.BASE_LOGIN); |
|
}, |
|
/** 退出前确认 */ |
|
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); |
|
} |
|
}); |
|
} |
|
} |
|
}); |
|
|
|
// 需要在设置之外使用 |
|
export function useUserStoreWithOut() { |
|
return useUserStore(store); |
|
}
|
|
|