info.ts 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. import { useClientRequest } from '@/utils/request';
  2. import { defineStore } from 'pinia';
  3. import { ref } from 'vue';
  4. import { UserInfoOptional, CompanyInfoData } from '../type/infoType';
  5. import type { StorageLike } from 'pinia-plugin-persistedstate';
  6. // 为 UniApp 创建适配的 storage(与 store/index.ts 保持一致)
  7. const uniStorage: StorageLike = {
  8. getItem: (key: string): string | null => {
  9. try {
  10. return uni.getStorageSync(key);
  11. } catch (error) {
  12. console.error('读取存储失败:', error);
  13. return null;
  14. }
  15. },
  16. setItem: (key: string, value: string): void => {
  17. try {
  18. uni.setStorageSync(key, value);
  19. } catch (error) {
  20. console.error('写入存储失败:', error);
  21. }
  22. },
  23. };
  24. //判断当前是测试版还是正式版
  25. const accountInfo = uni.getAccountInfoSync();
  26. const prefixMap = {
  27. release: 'prod_', // production的缩写
  28. trial: 'beta_', // beta测试版
  29. develop: 'dev_', // development的缩写
  30. };
  31. // Token存储键和默认过期时间(24小时)
  32. const TOKEN_STORAGE_KEY = `${prefixMap[accountInfo?.miniProgram?.envVersion]}_token`;
  33. const INFOSTORE_KEY = `${prefixMap[accountInfo?.miniProgram?.envVersion]}info_store`;
  34. const DEFAULT_TOKEN_EXPIRE = 24 * 60 * 60 * 1000; // 24小时(毫秒)
  35. export const useInfoStore = defineStore(
  36. 'infoStore',
  37. () => {
  38. // token
  39. const token = ref('');
  40. //从存储中读取token并检查是否过期
  41. const getTokenFromStorage = (): string => {
  42. try {
  43. const stored = uni.getStorageSync(TOKEN_STORAGE_KEY);
  44. console.log(stored, 'stored');
  45. if (!stored) return '';
  46. const tokenData = JSON.parse(stored);
  47. const { value, timestamp, expire } = tokenData;
  48. // 检查是否过期
  49. if (expire && Date.now() - timestamp > expire) {
  50. uni.removeStorageSync(TOKEN_STORAGE_KEY);
  51. return '';
  52. }
  53. return value;
  54. } catch (error) {
  55. console.error('读取token失败:', error);
  56. return '';
  57. }
  58. };
  59. /**
  60. * 设置token,可指定过期时间(毫秒)
  61. * @param value token值
  62. * @param expireMs 过期时间(毫秒),默认24小时
  63. */
  64. const setToken = (value: string, expireMs: number = DEFAULT_TOKEN_EXPIRE) => {
  65. token.value = value;
  66. // 存储带过期时间的token
  67. const tokenData = {
  68. value,
  69. timestamp: Date.now(),
  70. expire: expireMs,
  71. };
  72. uni.setStorageSync(TOKEN_STORAGE_KEY, JSON.stringify(tokenData));
  73. };
  74. //移除token
  75. const removeToken = () => {
  76. token.value = '';
  77. uni.removeStorageSync(TOKEN_STORAGE_KEY);
  78. // 移除token,并删除其他缓存数据
  79. uni.removeStorageSync(INFOSTORE_KEY);
  80. };
  81. // 检查token是否过期
  82. const isTokenExpired = (): boolean => {
  83. try {
  84. const stored = uni.getStorageSync(TOKEN_STORAGE_KEY);
  85. if (!stored) return true;
  86. const tokenData = JSON.parse(stored);
  87. const { timestamp, expire } = tokenData;
  88. // 如果没有设置过期时间,则永不过期
  89. if (!expire) return false;
  90. return Date.now() - timestamp > expire;
  91. } catch {
  92. return true;
  93. }
  94. };
  95. // 获取token剩余有效时间(毫秒)
  96. const getTokenRemainingTime = (): number => {
  97. try {
  98. const stored = uni.getStorageSync(TOKEN_STORAGE_KEY);
  99. if (!stored) return 0;
  100. const tokenData = JSON.parse(stored);
  101. const { timestamp, expire } = tokenData;
  102. if (!expire) return Infinity;
  103. const elapsed = Date.now() - timestamp;
  104. const remaining = expire - elapsed;
  105. return remaining > 0 ? remaining : 0;
  106. } catch {
  107. return 0;
  108. }
  109. };
  110. // 初始化时从存储读取token
  111. token.value = getTokenFromStorage();
  112. // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  113. // 用户信息
  114. const userInfo = ref<UserInfoOptional | null>(null);
  115. // 获取用户信息
  116. const getUserInfo = async (): Promise<UserInfoOptional | null> => {
  117. try {
  118. if (!token.value) return null;
  119. const { data } = await useClientRequest.get('/app/auth/getUserInfo');
  120. userInfo.value = data;
  121. return data;
  122. } catch (error) {
  123. console.error('获取用户信息失败:', error);
  124. return null;
  125. }
  126. };
  127. // 清除用户信息
  128. const clearUserInfo = (): void => {
  129. userInfo.value = null;
  130. };
  131. // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  132. //公司信息
  133. const companyInfo = ref<CompanyInfoData | null>(null);
  134. // 获取公司信息
  135. const getCompanyInfo = async (): Promise<CompanyInfoData | null> => {
  136. try {
  137. const { data } = await useClientRequest.get(`/app/company/currentCpyDetail`);
  138. companyInfo.value = data;
  139. return data;
  140. } catch (error) {
  141. console.error('获取公司信息失败:', error);
  142. return null;
  143. }
  144. };
  145. // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  146. // 微信小程序登录获取的code
  147. const wxLogin = async (data: unknown) => {
  148. const res = await useClientRequest.post(`/plt-api/auth/login`, data, false);
  149. setToken(res.data?.access_token);
  150. };
  151. return {
  152. token,
  153. setToken,
  154. removeToken,
  155. isTokenExpired,
  156. getTokenRemainingTime,
  157. userInfo,
  158. getUserInfo,
  159. clearUserInfo,
  160. companyInfo,
  161. getCompanyInfo,
  162. wxLogin,
  163. };
  164. },
  165. {
  166. // 启用持久化,但只持久化 userInfo,其中token使用自定义的带过期时间的存储逻辑
  167. persist: {
  168. key: INFOSTORE_KEY,
  169. storage: uniStorage,
  170. pick: ['userInfo', 'companyInfo'],
  171. },
  172. }
  173. );