user.ts 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. import type { UserInfo, LoginInfo } 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, LOGIN_INFO_KEY, DB_DICT_DATA_KEY, TENANT_ID } from '/@/enums/cacheEnum';
  8. import { getAuthCache, setAuthCache, removeAuthCache } from '/@/utils/auth';
  9. import { GetUserInfoModel, LoginParams, ThirdLoginParams } from '/@/api/sys/model/userModel';
  10. import { doLogout, getUserInfo, loginApi, phoneLoginApi, thirdLogin } 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, QIANKUN_ROUTE } from '/@/router/routes/basic';
  17. import { isArray } from '/@/utils/is';
  18. import { useGlobSetting } from '/@/hooks/setting';
  19. import { JDragConfigEnum } from '/@/enums/jeecgEnum';
  20. import { useSso } from '/@/hooks/web/useSso';
  21. import { getActions } from '/@/qiankun/state';
  22. interface UserState {
  23. userInfo: Nullable<UserInfo>;
  24. token?: string;
  25. roleList: RoleEnum[];
  26. dictItems?: [];
  27. sessionTimeout?: boolean;
  28. lastUpdateTime: number;
  29. tenantid?: string | number;
  30. loginInfo?: Nullable<LoginInfo>;
  31. }
  32. export const useUserStore = defineStore({
  33. id: 'app-user',
  34. state: (): UserState => ({
  35. // 用户信息
  36. userInfo: null,
  37. // token
  38. token: undefined,
  39. // 角色列表
  40. roleList: [],
  41. // 字典
  42. dictItems: [],
  43. // session过期时间
  44. sessionTimeout: false,
  45. // Last fetch time
  46. lastUpdateTime: 0,
  47. //租户id
  48. tenantid: '',
  49. //登录返回信息
  50. loginInfo: null,
  51. }),
  52. getters: {
  53. getUserInfo(): UserInfo {
  54. return this.userInfo || getAuthCache<UserInfo>(USER_INFO_KEY) || {};
  55. },
  56. getLoginInfo(): LoginInfo {
  57. return this.loginInfo || getAuthCache<LoginInfo>(LOGIN_INFO_KEY) || {};
  58. },
  59. getToken(): string {
  60. return this.token || getAuthCache<string>(TOKEN_KEY);
  61. },
  62. getAllDictItems(): [] {
  63. return this.dictItems || getAuthCache(DB_DICT_DATA_KEY);
  64. },
  65. getRoleList(): RoleEnum[] {
  66. return this.roleList.length > 0 ? this.roleList : getAuthCache<RoleEnum[]>(ROLES_KEY);
  67. },
  68. getSessionTimeout(): boolean {
  69. return !!this.sessionTimeout;
  70. },
  71. getLastUpdateTime(): number {
  72. return this.lastUpdateTime;
  73. },
  74. getTenant(): string | number {
  75. return this.tenantid || getAuthCache<string | number>(TENANT_ID);
  76. },
  77. },
  78. actions: {
  79. setToken(info: string | undefined) {
  80. this.token = info ? info : ''; // for null or undefined value
  81. setAuthCache(TOKEN_KEY, info);
  82. },
  83. setRoleList(roleList: RoleEnum[]) {
  84. this.roleList = roleList;
  85. setAuthCache(ROLES_KEY, roleList);
  86. },
  87. setUserInfo(info: UserInfo | null) {
  88. this.userInfo = info;
  89. this.lastUpdateTime = new Date().getTime();
  90. setAuthCache(USER_INFO_KEY, info);
  91. },
  92. setLoginInfo(info: LoginInfo | null) {
  93. this.loginInfo = info;
  94. setAuthCache(LOGIN_INFO_KEY, info);
  95. },
  96. setAllDictItems(dictItems) {
  97. this.dictItems = dictItems;
  98. setAuthCache(DB_DICT_DATA_KEY, dictItems);
  99. },
  100. setTenant(id) {
  101. this.tenantid = id;
  102. setAuthCache(TENANT_ID, id);
  103. },
  104. setSessionTimeout(flag: boolean) {
  105. this.sessionTimeout = flag;
  106. },
  107. resetState() {
  108. this.userInfo = null;
  109. this.dictItems = [];
  110. this.token = '';
  111. this.roleList = [];
  112. this.sessionTimeout = false;
  113. },
  114. /**
  115. * 登录事件
  116. */
  117. async login(
  118. params: LoginParams & {
  119. goHome?: boolean;
  120. mode?: ErrorMessageMode;
  121. }
  122. ): Promise<GetUserInfoModel | null> {
  123. try {
  124. const { goHome = true, mode, ...loginParams } = params;
  125. const data = await loginApi(loginParams, mode);
  126. const { token } = data;
  127. // save token
  128. this.setToken(token);
  129. return this.afterLoginAction(goHome, data);
  130. } catch (error) {
  131. return Promise.reject(error);
  132. }
  133. },
  134. /**
  135. * 扫码登录事件
  136. */
  137. async qrCodeLogin(token): Promise<GetUserInfoModel | null> {
  138. try {
  139. // save token
  140. this.setToken(token);
  141. return this.afterLoginAction(true, {});
  142. } catch (error) {
  143. return Promise.reject(error);
  144. }
  145. },
  146. /**
  147. * 登录完成处理
  148. * @param goHome
  149. */
  150. async afterLoginAction(goHome?: boolean, data?: any): Promise<any | null> {
  151. if (!this.getToken) return null;
  152. //获取用户信息
  153. const userInfo = await this.getUserInfoAction();
  154. const sessionTimeout = this.sessionTimeout;
  155. if (sessionTimeout) {
  156. this.setSessionTimeout(false);
  157. } else {
  158. const permissionStore = usePermissionStore();
  159. if (!permissionStore.isDynamicAddedRoute) {
  160. const routes = await permissionStore.buildRoutesAction();
  161. routes.forEach((route) => {
  162. router.addRoute(route as unknown as RouteRecordRaw);
  163. });
  164. router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw);
  165. router.addRoute(QIANKUN_ROUTE as unknown as RouteRecordRaw);
  166. permissionStore.setDynamicAddedRoute(true);
  167. }
  168. await this.setLoginInfo({ ...data, isLogin: true });
  169. //update-begin-author:liusq date:2022-5-5 for:登录成功后缓存拖拽模块的接口前缀
  170. localStorage.setItem(JDragConfigEnum.DRAG_BASE_URL, useGlobSetting().domainUrl);
  171. //update-end-author:liusq date:2022-5-5 for: 登录成功后缓存拖拽模块的接口前缀
  172. goHome && (await router.replace((userInfo && userInfo.homePath) || PageEnum.BASE_HOME));
  173. }
  174. if (useGlobSetting().openQianKun) {
  175. const actions = getActions();
  176. actions.setGlobalState({ token: this.getToken, userInfo: userInfo, isMounted: false });
  177. }
  178. return data;
  179. },
  180. /**
  181. * 手机号登录
  182. * @param params
  183. */
  184. async phoneLogin(
  185. params: LoginParams & {
  186. goHome?: boolean;
  187. mode?: ErrorMessageMode;
  188. }
  189. ): Promise<GetUserInfoModel | null> {
  190. try {
  191. const { goHome = true, mode, ...loginParams } = params;
  192. const data = await phoneLoginApi(loginParams, mode);
  193. const { token } = data;
  194. // save token
  195. this.setToken(token);
  196. return this.afterLoginAction(goHome, data);
  197. } catch (error) {
  198. return Promise.reject(error);
  199. }
  200. },
  201. /**
  202. * 获取用户信息
  203. */
  204. async getUserInfoAction(): Promise<UserInfo | null> {
  205. if (!this.getToken) {
  206. return null;
  207. }
  208. const { userInfo, sysAllDictItems } = await getUserInfo();
  209. if (userInfo) {
  210. const { roles = [] } = userInfo;
  211. if (isArray(roles)) {
  212. const roleList = roles.map((item) => item.value) as RoleEnum[];
  213. this.setRoleList(roleList);
  214. } else {
  215. userInfo.roles = [];
  216. this.setRoleList([]);
  217. }
  218. this.setUserInfo(userInfo);
  219. }
  220. /**
  221. * 添加字典信息到缓存
  222. * @updateBy:lsq
  223. * @updateDate:2021-09-08
  224. */
  225. if (sysAllDictItems) {
  226. this.setAllDictItems(sysAllDictItems);
  227. }
  228. return userInfo;
  229. },
  230. /**
  231. * 退出登录
  232. */
  233. async logout(goLogin = false) {
  234. if (this.getToken) {
  235. try {
  236. await doLogout();
  237. } catch {
  238. console.log('注销Token失败');
  239. }
  240. }
  241. // //update-begin-author:taoyan date:2022-5-5 for: src/layouts/default/header/index.vue showLoginSelect方法 获取tenantId 退出登录后再次登录依然能获取到值,没有清空
  242. // let username:any = this.userInfo && this.userInfo.username;
  243. // if(username){
  244. // removeAuthCache(username)
  245. // }
  246. // //update-end-author:taoyan date:2022-5-5 for: src/layouts/default/header/index.vue showLoginSelect方法 获取tenantId 退出登录后再次登录依然能获取到值,没有清空
  247. this.setToken('');
  248. setAuthCache(TOKEN_KEY, null);
  249. this.setSessionTimeout(false);
  250. this.setUserInfo(null);
  251. this.setLoginInfo(null);
  252. //update-begin-author:liusq date:2022-5-5 for:退出登录后清除拖拽模块的接口前缀
  253. localStorage.removeItem(JDragConfigEnum.DRAG_BASE_URL);
  254. //update-end-author:liusq date:2022-5-5 for: 退出登录后清除拖拽模块的接口前缀
  255. //如果开启单点登录,则跳转到单点统一登录中心
  256. const openSso = useGlobSetting().openSso;
  257. if (openSso == 'true') {
  258. await useSso().ssoLoginOut();
  259. }
  260. goLogin && (await router.push(PageEnum.BASE_LOGIN));
  261. },
  262. /**
  263. * 登录事件
  264. */
  265. async ThirdLogin(
  266. params: ThirdLoginParams & {
  267. goHome?: boolean;
  268. mode?: ErrorMessageMode;
  269. }
  270. ): Promise<any | null> {
  271. try {
  272. const { goHome = true, mode, ...ThirdLoginParams } = params;
  273. const data = await thirdLogin(ThirdLoginParams, mode);
  274. const { token } = data;
  275. // save token
  276. this.setToken(token);
  277. return this.afterLoginAction(goHome, data);
  278. } catch (error) {
  279. return Promise.reject(error);
  280. }
  281. },
  282. /**
  283. * 退出询问
  284. */
  285. confirmLoginOut() {
  286. // debugger;
  287. const { createConfirm } = useMessage();
  288. const { t } = useI18n();
  289. createConfirm({
  290. iconType: 'warning',
  291. title: t('sys.app.logoutTip'),
  292. content: t('sys.app.logoutMessage'),
  293. onOk: async () => {
  294. await this.logout(true);
  295. },
  296. });
  297. },
  298. },
  299. });
  300. // Need to be used outside the setup
  301. export function useUserStoreWithOut() {
  302. return useUserStore(store);
  303. }