user.ts 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. import { defineStore } from 'pinia';
  2. import { ref, computed } from 'vue';
  3. import { getUserInfo, login, getCompanyStatus } from '@/apis/user';
  4. import tokenInfo from '@/stores/modules/token';
  5. import client from '@/stores/modules/client';
  6. import { ElMessage } from 'element-plus';
  7. export const useUserInfo = defineStore('userInfo', () => {
  8. // 状态(State)
  9. const tokenInfoStore = new tokenInfo()
  10. const loginShow = ref(false); // 控制登录弹窗的显示状态
  11. const userInfo = ref({}); // 用户的详细信息
  12. const isExpired = ref(false); // 企业账户是否过期
  13. const expiredMessage = ref(''); // 过期提示消息
  14. const supportCameraCounts = ref(1); // 支持的相机数量
  15. // 多相机模式判断
  16. // support_camera_counts > 1 则为多相机模式
  17. const isMultiCameraMode = computed(() => {
  18. return supportCameraCounts.value > 1
  19. })
  20. const cameraMode = computed(() => {
  21. return supportCameraCounts.value > 1 ? 'multi' : 'single'
  22. })
  23. // HLM用户判断
  24. const isHLM = computed(() => {
  25. return userInfo.value?.brand_company_code === '1300'
  26. })
  27. // 定时检查相关
  28. let checkInterval: NodeJS.Timeout | null = null; // 定时器
  29. const CHECK_INTERVAL = 10 * 60 * 1000; // 10分钟检查一次
  30. // Actions(操作)
  31. /**
  32. * 更新用户信息。
  33. *
  34. * @param {any} data - 新的用户信息数据。
  35. */
  36. const updateUserInfo = (data: any) => {
  37. userInfo.value = data;
  38. };
  39. /**
  40. * 更新用户的登录令牌。
  41. *
  42. * @param {string} data - 新的登录令牌。
  43. */
  44. const updateToken = (data: string) => {
  45. tokenInfoStore.updateToken(data)
  46. };
  47. /**
  48. * 更新登录弹窗的显示状态。
  49. *
  50. * @param {boolean} data - 是否显示登录弹窗。
  51. */
  52. const updateLoginShow = (data: boolean) => {
  53. loginShow.value = data;
  54. };
  55. /**
  56. * 执行用户登录操作。
  57. *
  58. * @param {any} data - 登录所需的用户凭据。
  59. * @returns {Promise<any>} 登录接口返回的结果。
  60. * @throws {Error} 如果登录失败,抛出错误。
  61. */
  62. const loginAction = async (data: any) => {
  63. try {
  64. const res = await login(data); // 调用登录接口
  65. await updateToken(res.data.token); // 更新登录令牌
  66. // await getInfo(); // 获取用户信息
  67. return res;
  68. } catch (error) {
  69. console.error('登录失败:', error);
  70. throw error;
  71. }
  72. };
  73. /**
  74. * 执行用户退出登录操作。
  75. *
  76. * @param {any} data - 退出登录所需的参数。
  77. * @returns {Promise<any>} 退出登录的结果。
  78. * @throws {Error} 如果退出登录失败,抛出错误。
  79. */
  80. const loginOut = async (data: any) => {
  81. try {
  82. // 关闭所有子窗口
  83. try {
  84. const clientStore = client();
  85. await clientStore.ipc.invoke('controller.utils.closeAllWindows');
  86. console.log('所有子窗口已关闭');
  87. } catch (error) {
  88. console.error('关闭子窗口失败:', error);
  89. // 关闭窗口失败不影响退出登录流程
  90. }
  91. // 停止定期检查
  92. stopPeriodicCheck();
  93. // 清空用户信息
  94. try {
  95. tokenInfoStore.clearToken()
  96. } catch (e) {
  97. await updateToken('')
  98. }
  99. await updateUserInfo({});
  100. // 跳转到首页
  101. try {
  102. // 在Electron环境中使用正确的协议
  103. if (window.location.protocol === 'file:') {
  104. window.location.href = window.location.href.split('#')[0] + '#/';
  105. window.location.reload()
  106. } else {
  107. window.location.href = '/';
  108. }
  109. console.log('已跳转到首页');
  110. } catch (error) {
  111. console.error('跳转到首页失败:', error);
  112. // 跳转失败不影响退出登录流程
  113. }
  114. } catch (error) {
  115. console.error('退出登录失败:', error);
  116. throw error;
  117. }
  118. };
  119. /**
  120. * 检查企业状态并处理跳转
  121. * @returns {Promise<boolean>} 是否过期
  122. */
  123. const checkCompanyStatus = async (): Promise<boolean> => {
  124. try {
  125. const statusRes = await getCompanyStatus({});
  126. const statusData = statusRes.data;
  127. if (statusData && statusData.status === 0) {
  128. // 已过期,设置过期状态
  129. isExpired.value = true;
  130. expiredMessage.value = statusData.message || '企业账户已过期,请联系管理员';
  131. // 触发自定义事件,通知组件进行跳转
  132. if (typeof window !== 'undefined') {
  133. window.dispatchEvent(new CustomEvent('companyExpired', {
  134. detail: { message: expiredMessage.value }
  135. }));
  136. }
  137. return true;
  138. } else {
  139. // 未过期,重置状态
  140. isExpired.value = false;
  141. expiredMessage.value = '';
  142. // 保存支持的相机数量
  143. if (statusData?.support_camera_counts) {
  144. supportCameraCounts.value = statusData.support_camera_counts;
  145. }
  146. return false;
  147. }
  148. } catch (statusError) {
  149. console.error('获取企业状态失败:', statusError);
  150. // 企业状态获取失败不影响正常使用,只记录错误
  151. isExpired.value = false;
  152. expiredMessage.value = '';
  153. return false;
  154. }
  155. };
  156. /**
  157. * 启动定期检查企业状态
  158. */
  159. const startPeriodicCheck = () => {
  160. // 清除已有的定时器
  161. if (checkInterval) {
  162. clearInterval(checkInterval);
  163. }
  164. // 设置新的定时器,每5分钟检查一次
  165. checkInterval = setInterval(async () => {
  166. await checkCompanyStatus();
  167. }, CHECK_INTERVAL);
  168. console.log('企业状态定期检查已启动');
  169. };
  170. /**
  171. * 停止定期检查企业状态
  172. */
  173. const stopPeriodicCheck = () => {
  174. if (checkInterval) {
  175. clearInterval(checkInterval);
  176. checkInterval = null;
  177. console.log('企业状态定期检查已停止');
  178. }
  179. };
  180. /**
  181. * 获取用户信息并更新状态。
  182. *
  183. * @returns {Promise<any>} 用户信息数据。
  184. * @throws {Error} 如果获取用户信息失败,抛出错误。
  185. */
  186. const getInfo = async () => {
  187. try {
  188. const res = await getUserInfo({
  189. device:'aigc',
  190. }); // 调用获取用户信息接口
  191. const { data } = res;
  192. if (!data) {
  193. try {
  194. tokenInfoStore.clearToken()
  195. } catch (e) {
  196. updateToken('')
  197. }
  198. throw new Error('请重新登录!');
  199. }
  200. updateUserInfo(data); // 更新用户信息
  201. // 获取企业状态,检查是否过期
  202. await checkCompanyStatus();
  203. // 启动定期检查
  204. startPeriodicCheck();
  205. return data;
  206. } catch (error) {
  207. console.error('获取用户信息失败:', error);
  208. throw error;
  209. }
  210. };
  211. return {
  212. loginShow,
  213. userInfo,
  214. isExpired,
  215. expiredMessage,
  216. supportCameraCounts,
  217. isMultiCameraMode,
  218. cameraMode,
  219. isHLM,
  220. updateUserInfo,
  221. updateLoginShow,
  222. loginAction,
  223. loginOut,
  224. getInfo,
  225. checkCompanyStatus,
  226. startPeriodicCheck,
  227. stopPeriodicCheck,
  228. };
  229. });
  230. export default useUserInfo;