康来智慧冷链系统 - 前端
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.
 
 
 
 
 

211 lines
6.9 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: Nullable<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: Nullable<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(null);
this.setAccessToken('');
this.setRefreshToken('');
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.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 (e) {
// 防止 system-biz 微服务挂掉后导致token授权成功重新登陆覆盖授权客户端密钥
this.resetState();
throw Error(t('sys.api.errMsg503'));
}
},
/** 登出 */
async logout(goLogin = false) {
try {
await logout();
} catch {
console.log('注销Token失败');
}
this.resetState();
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);
}