analysisRefreshPrompt.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import type { RouteLocationNormalized } from 'vue-router';
  2. import { Modal } from 'ant-design-vue';
  3. import { createLocalStorage } from '@jeesite/core/utils/cache';
  4. import { useUserStoreWithOut } from '@jeesite/core/store/modules/case';
  5. interface AnalysisRefreshState {
  6. hasData: boolean;
  7. syncedVersion: number;
  8. promptedVersion: number;
  9. pendingRefreshVersion: number;
  10. refreshHandler?: () => Promise<void> | void;
  11. }
  12. const ANALYSIS_REFRESH_VERSION_KEY_PREFIX = 'analysis-refresh-version:';
  13. const ls = createLocalStorage({ timeout: null });
  14. const analysisRefreshStateMap = new Map<string, AnalysisRefreshState>();
  15. const normalizeCaseId = () => {
  16. const caseId = String(useUserStoreWithOut().getCaseInfo?.id || '').trim();
  17. return caseId || 'default';
  18. };
  19. const getVersionCacheKey = (caseId = normalizeCaseId()) => `${ANALYSIS_REFRESH_VERSION_KEY_PREFIX}${caseId}`;
  20. export const resolveAnalysisRefreshRouteKey = (route?: Partial<RouteLocationNormalized> | null) =>
  21. String(route?.path || '').trim();
  22. const getCurrentVersion = () => {
  23. const version = Number(ls.get(getVersionCacheKey(), 0));
  24. return Number.isFinite(version) ? version : 0;
  25. };
  26. const getOrCreateState = (routeKey: string) => {
  27. const normalizedRouteKey = String(routeKey || '').trim();
  28. if (!normalizedRouteKey) return null;
  29. let state = analysisRefreshStateMap.get(normalizedRouteKey);
  30. if (!state) {
  31. state = {
  32. hasData: false,
  33. syncedVersion: 0,
  34. promptedVersion: 0,
  35. pendingRefreshVersion: 0,
  36. };
  37. analysisRefreshStateMap.set(normalizedRouteKey, state);
  38. }
  39. return state;
  40. };
  41. export const registerAnalysisRefreshHandler = (routeKey: string, refreshHandler: () => Promise<void> | void) => {
  42. const state = getOrCreateState(routeKey);
  43. if (!state) return;
  44. state.refreshHandler = refreshHandler;
  45. };
  46. export const unregisterAnalysisRefreshHandler = (routeKey: string) => {
  47. const normalizedRouteKey = String(routeKey || '').trim();
  48. if (!normalizedRouteKey) return;
  49. analysisRefreshStateMap.delete(normalizedRouteKey);
  50. };
  51. export const syncAnalysisRefreshState = (routeKey: string, hasData: boolean) => {
  52. const state = getOrCreateState(routeKey);
  53. if (!state) return;
  54. const currentVersion = getCurrentVersion();
  55. state.hasData = hasData;
  56. state.syncedVersion = currentVersion;
  57. state.promptedVersion = currentVersion;
  58. state.pendingRefreshVersion = 0;
  59. };
  60. export const markAnalysisDataChanged = () => {
  61. const currentVersion = getCurrentVersion();
  62. const nextVersion = Math.max(Date.now(), currentVersion + 1);
  63. ls.set(getVersionCacheKey(), nextVersion, null);
  64. return nextVersion;
  65. };
  66. export const shouldPromptAnalysisRefresh = (routeKey: string) => {
  67. const normalizedRouteKey = String(routeKey || '').trim();
  68. if (!normalizedRouteKey) return false;
  69. const state = analysisRefreshStateMap.get(normalizedRouteKey);
  70. if (!state?.hasData) return false;
  71. const currentVersion = getCurrentVersion();
  72. return currentVersion > state.syncedVersion && state.promptedVersion < currentVersion;
  73. };
  74. export const markAnalysisRefreshPrompted = (routeKey: string) => {
  75. const state = getOrCreateState(routeKey);
  76. if (!state) return;
  77. state.promptedVersion = getCurrentVersion();
  78. };
  79. export const markAnalysisRefreshPending = (routeKey: string) => {
  80. const state = getOrCreateState(routeKey);
  81. if (!state) return;
  82. const currentVersion = getCurrentVersion();
  83. state.promptedVersion = currentVersion;
  84. state.pendingRefreshVersion = currentVersion;
  85. };
  86. export const consumePendingAnalysisRefresh = (routeKey: string) => {
  87. const normalizedRouteKey = String(routeKey || '').trim();
  88. if (!normalizedRouteKey) return null;
  89. const state = analysisRefreshStateMap.get(normalizedRouteKey);
  90. if (!state?.pendingRefreshVersion || !state.refreshHandler) return null;
  91. state.pendingRefreshVersion = 0;
  92. return state.refreshHandler;
  93. };
  94. export const createAnalysisRefreshConfirm = (routeKey: string) =>
  95. new Promise<boolean>((resolve) => {
  96. Modal.confirm({
  97. title: '数据更新提醒',
  98. content: '数据发生变化,是否更新?',
  99. centered: true,
  100. okText: '更新',
  101. cancelText: '暂不更新',
  102. onOk: async () => {
  103. markAnalysisRefreshPending(routeKey);
  104. resolve(true);
  105. },
  106. onCancel: () => {
  107. markAnalysisRefreshPrompted(routeKey);
  108. resolve(true);
  109. },
  110. });
  111. });