user.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. import type { UserInfo } from '/#/store';
  2. import type { ErrorMessageMode } from '/#/axios';
  3. import { defineStore } from 'pinia';
  4. import { store } from '/@/store';
  5. import { RoleEnum } from '/@/enums/roleEnum';
  6. import { PageEnum } from '/@/enums/pageEnum';
  7. import { ROLES_KEY, TOKEN_KEY, USER_INFO_KEY } from '/@/enums/cacheEnum';
  8. import { getAuthCache, setAuthCache } from '/@/utils/auth';
  9. import { GetUserInfoModel, LoginParams } from '/@/api/sys/model/userModel';
  10. import { doLogout, getUserInfo, loginApi } from '/@/api/sys/user';
  11. import { useI18n } from '/@/hooks/web/useI18n';
  12. import { useMessage } from '/@/hooks/web/useMessage';
  13. import { router } from '/@/router';
  14. import { usePermissionStore } from '/@/store/modules/permission';
  15. import { RouteRecordRaw } from 'vue-router';
  16. import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic';
  17. import { isArray } from '/@/utils/is';
  18. import { h } from 'vue';
  19. interface UserState {
  20. userInfo: Nullable<UserInfo>;
  21. token?: string;
  22. roleList: RoleEnum[];
  23. sessionTimeout?: boolean;
  24. lastUpdateTime: number;
  25. }
  26. export const useUserStore = defineStore({
  27. id: 'app-user',
  28. state: (): UserState => ({
  29. // user info
  30. userInfo: null,
  31. // token
  32. token: undefined,
  33. // roleList
  34. roleList: [],
  35. // Whether the login expired
  36. sessionTimeout: false,
  37. // Last fetch time
  38. lastUpdateTime: 0,
  39. }),
  40. getters: {
  41. getUserInfo(): UserInfo {
  42. return this.userInfo || getAuthCache<UserInfo>(USER_INFO_KEY) || {};
  43. },
  44. getToken(): string {
  45. return this.token || getAuthCache<string>(TOKEN_KEY);
  46. },
  47. getRoleList(): RoleEnum[] {
  48. return this.roleList.length > 0 ? this.roleList : getAuthCache<RoleEnum[]>(ROLES_KEY);
  49. },
  50. getSessionTimeout(): boolean {
  51. return !!this.sessionTimeout;
  52. },
  53. getLastUpdateTime(): number {
  54. return this.lastUpdateTime;
  55. },
  56. },
  57. actions: {
  58. setToken(info: string | undefined) {
  59. this.token = info ? info : ''; // for null or undefined value
  60. setAuthCache(TOKEN_KEY, info);
  61. },
  62. setRoleList(roleList: RoleEnum[]) {
  63. this.roleList = roleList;
  64. setAuthCache(ROLES_KEY, roleList);
  65. },
  66. setUserInfo(info: UserInfo | null) {
  67. this.userInfo = info;
  68. this.lastUpdateTime = new Date().getTime();
  69. setAuthCache(USER_INFO_KEY, info);
  70. },
  71. setSessionTimeout(flag: boolean) {
  72. this.sessionTimeout = flag;
  73. },
  74. resetState() {
  75. this.userInfo = null;
  76. this.token = '';
  77. this.roleList = [];
  78. this.sessionTimeout = false;
  79. },
  80. /**
  81. * @description: login
  82. */
  83. async login(
  84. params: LoginParams & {
  85. goHome?: boolean;
  86. mode?: ErrorMessageMode;
  87. },
  88. ): Promise<GetUserInfoModel | null> {
  89. try {
  90. const { goHome = true, mode, ...loginParams } = params;
  91. const data = await loginApi(loginParams, mode);
  92. const { token, user } = data;
  93. console.log('user', user);
  94. // save token
  95. this.setToken(token);
  96. return this.afterLoginAction(goHome);
  97. } catch (error) {
  98. return Promise.reject(error);
  99. }
  100. },
  101. async afterLoginAction(goHome?: boolean): Promise<GetUserInfoModel | null> {
  102. if (!this.getToken) return null;
  103. // get user info
  104. const userInfo = await this.getUserInfoAction();
  105. const sessionTimeout = this.sessionTimeout;
  106. if (sessionTimeout) {
  107. this.setSessionTimeout(false);
  108. } else {
  109. const permissionStore = usePermissionStore();
  110. if (!permissionStore.isDynamicAddedRoute) {
  111. const routes = await permissionStore.buildRoutesAction();
  112. routes.forEach((route) => {
  113. router.addRoute(route as unknown as RouteRecordRaw);
  114. });
  115. router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw);
  116. permissionStore.setDynamicAddedRoute(true);
  117. }
  118. goHome && (await router.replace(userInfo?.homePath || PageEnum.BASE_HOME));
  119. }
  120. return userInfo;
  121. },
  122. async getUserInfoAction(): Promise<UserInfo | null> {
  123. if (!this.getToken) return null;
  124. const userInfo = await getUserInfo();
  125. const { roles = [] } = userInfo;
  126. if (isArray(roles)) {
  127. const roleList = roles.map((item) => item.value) as RoleEnum[];
  128. this.setRoleList(roleList);
  129. } else {
  130. userInfo.roles = [];
  131. this.setRoleList([]);
  132. }
  133. this.setUserInfo(userInfo);
  134. return userInfo;
  135. },
  136. /**
  137. * @description: logout
  138. */
  139. async logout(goLogin = false) {
  140. if (this.getToken) {
  141. try {
  142. await doLogout();
  143. } catch {
  144. console.log('注销Token失败');
  145. }
  146. }
  147. this.setToken(undefined);
  148. this.setSessionTimeout(false);
  149. this.setUserInfo(null);
  150. goLogin && router.push(PageEnum.BASE_LOGIN);
  151. },
  152. /**
  153. * @description: Confirm before logging out
  154. */
  155. confirmLoginOut() {
  156. const { createConfirm } = useMessage();
  157. const { t } = useI18n();
  158. createConfirm({
  159. iconType: 'warning',
  160. title: () => h('span', t('sys.app.logoutTip')),
  161. content: () => h('span', t('sys.app.logoutMessage')),
  162. onOk: async () => {
  163. await this.logout(true);
  164. },
  165. });
  166. },
  167. },
  168. });
  169. // Need to be used outside the setup
  170. export function useUserStoreWithOut() {
  171. return useUserStore(store);
  172. }