user.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import { defineStore } from 'pinia';
  2. import { ref } from 'vue';
  3. import { CACHE_KEY } from '@/constants/index';
  4. // @ts-ignore 因为 utils 可能还没做完整的 ts 设置
  5. import { Local, Session } from '@/utils/storage';
  6. import { useLoginApi } from '@/api/system/login';
  7. import { useSystemApi } from '@/api/system/index';
  8. import { useUserApi } from '@/api/user/index';
  9. import type { LoginParams, UserInfo } from '@/types/user';
  10. import { sm3 } from 'sm-crypto';
  11. import to from 'await-to-js';
  12. const loginApi = useLoginApi();
  13. const systemApi = useSystemApi();
  14. const userApi = useUserApi();
  15. export const useUserStore = defineStore('user', () => {
  16. // ==================== State ====================
  17. const token = ref<string>(Local.get(CACHE_KEY.TOKEN) || '');
  18. const userInfo = ref<UserInfo>(Local.get(CACHE_KEY.USER_INFO) || ({} as UserInfo));
  19. const perms = ref<string[]>([]);
  20. const roles = ref<string[]>([]);
  21. const configSetting = ref<any>({});
  22. // 页面请求加载状态
  23. const loadings = {
  24. loginLoading: ref<boolean>(false),
  25. fetchUserInfoLoading: ref<boolean>(false),
  26. logoutLoading: ref<boolean>(false),
  27. } as const;
  28. // ==================== Actions ====================
  29. /**
  30. * 设置请求加载状态
  31. */
  32. function setRequestLoading(field: keyof typeof loadings, value: boolean) {
  33. loadings[field].value = value;
  34. }
  35. /**
  36. * 检查验证码配置
  37. */
  38. async function checkCaptcha() {
  39. const [err, res] = await to(systemApi.getEntityMapByKeys({ configKeys: ['isCaptcha'] }));
  40. if (err) return;
  41. if (res?.data) {
  42. configSetting.value = res.data;
  43. }
  44. }
  45. /**
  46. * 清理用户状态和本地缓存
  47. */
  48. function clearUserStatus() {
  49. token.value = '';
  50. roles.value = [];
  51. perms.value = [];
  52. userInfo.value = {} as UserInfo;
  53. Local.remove(CACHE_KEY.TOKEN);
  54. Local.remove(CACHE_KEY.USER_INFO);
  55. Local.remove(CACHE_KEY.PERMS);
  56. Local.remove(CACHE_KEY.ROLES);
  57. Session.clear();
  58. }
  59. /**
  60. * 用户登录
  61. */
  62. async function login(loginParams: LoginParams) {
  63. setRequestLoading('loginLoading', true);
  64. // 使用 sm3 加密密码
  65. const encryptedPassword = loginParams.password ? sm3(loginParams.password) : '';
  66. const [err, res] = await to(
  67. loginApi.signIn({
  68. userName: loginParams.userName,
  69. password: encryptedPassword,
  70. idValueC: loginParams.idValueC,
  71. idKeyC: loginParams.idKeyC,
  72. saltValue: loginParams.saltValue,
  73. })
  74. );
  75. setRequestLoading('loginLoading', false);
  76. if (err) {
  77. return Promise.reject(err);
  78. }
  79. const resToken = res?.data?.token;
  80. if (resToken) {
  81. token.value = resToken;
  82. Local.set(CACHE_KEY.TOKEN, resToken);
  83. // 登录成功后主动获取用户信息
  84. await fetchUserInfo();
  85. }
  86. return res;
  87. }
  88. /**
  89. * 获取用户信息
  90. */
  91. async function fetchUserInfo() {
  92. setRequestLoading('fetchUserInfoLoading', true);
  93. const [err, res] = await to(userApi.getUserByUserName());
  94. setRequestLoading('fetchUserInfoLoading', false);
  95. if (err) {
  96. return Promise.reject(err);
  97. }
  98. // 解决解构变量和 ref 变量重名问题
  99. const {
  100. userInfo: resUserInfo,
  101. perms: resPerms,
  102. roles: resRoles,
  103. } = res?.data || {};
  104. userInfo.value = resUserInfo || ({} as UserInfo);
  105. perms.value = resPerms || [];
  106. roles.value = resRoles || [];
  107. Local.set(CACHE_KEY.USER_INFO, userInfo.value);
  108. Local.set(CACHE_KEY.PERMS, perms.value);
  109. Local.set(CACHE_KEY.ROLES, roles.value);
  110. }
  111. /**
  112. * 用户登出
  113. */
  114. async function logout() {
  115. setRequestLoading('logoutLoading', true);
  116. const [err] = await to(loginApi.signOut());
  117. setRequestLoading('logoutLoading', false);
  118. // 即便接口报错也要清空本地缓存和状态
  119. clearUserStatus();
  120. if (err) {
  121. console.warn('退出登录异常', err);
  122. }
  123. }
  124. return {
  125. ...loadings,
  126. token,
  127. userInfo,
  128. perms,
  129. roles,
  130. configSetting,
  131. login,
  132. fetchUserInfo,
  133. logout,
  134. clearUserStatus,
  135. setRequestLoading,
  136. checkCaptcha,
  137. };
  138. });