import { reactive, toRefs } from 'vue'; import type { FileInfo } from '@jeesite/types/api'; const IMPORT_PROGRESS_STORAGE_KEY = 'case_clean_import_progress'; export interface ImportProgressSnapshot { active: boolean; caseId?: string | number; progress: number; activeStep: number; currentFileName: string; currentCleanFiles: FileInfo[]; currentCleanBatchId: string; successCount: number; failCount: number; cleanStatsSnapshot: { success?: number; fail?: number }; cleanTaskStarted: boolean; cleanTaskFinished: boolean; calcTaskTriggered: boolean; governTaskStarted: boolean; governTaskFinished: boolean; shouldRunGovernAfterClean: boolean; updatedAt: number; } interface ImportProgressRuntimeState { progress: number; activeStep: number; currentFileName: string; currentCleanFiles: FileInfo[]; currentCleanBatchId: string; sseConnected: boolean; sseError: string | null; cleanTaskStarted: boolean; calcTaskTriggered: boolean; cleanTaskFinished: boolean; governTaskStarted: boolean; governTaskFinished: boolean; shouldRunGovernAfterClean: boolean; governCompleteNotified: boolean; successCount: number; failCount: number; cleanStatsSnapshot: { success?: number; fail?: number }; } const createImportProgressRuntimeState = (): ImportProgressRuntimeState => ({ progress: 0, activeStep: 0, currentFileName: '', currentCleanFiles: [], currentCleanBatchId: '', sseConnected: false, sseError: null, cleanTaskStarted: false, calcTaskTriggered: false, cleanTaskFinished: false, governTaskStarted: false, governTaskFinished: false, shouldRunGovernAfterClean: true, governCompleteNotified: false, successCount: 0, failCount: 0, cleanStatsSnapshot: {}, }); const importProgressRuntimeState = reactive(createImportProgressRuntimeState()); let activeImportProgressEventSource: EventSource | null = null; export const useImportProgressRuntimeState = () => toRefs(importProgressRuntimeState); export const resetImportProgressRuntimeState = () => { Object.assign(importProgressRuntimeState, createImportProgressRuntimeState()); }; export const getImportProgressEventSource = () => activeImportProgressEventSource; export const setImportProgressEventSource = (eventSource: EventSource | null) => { activeImportProgressEventSource = eventSource; }; const getStorage = () => (typeof window === 'undefined' ? null : window.sessionStorage); const normalizeCaseId = (caseId?: string | number) => (caseId === undefined || caseId === null ? '' : String(caseId)); export const getActiveImportProgress = (caseId?: string | number): ImportProgressSnapshot | null => { const raw = getStorage()?.getItem(IMPORT_PROGRESS_STORAGE_KEY); if (!raw) return null; try { const snapshot = JSON.parse(raw) as ImportProgressSnapshot; if (!snapshot?.active || !snapshot.cleanTaskStarted) return null; const currentCaseId = normalizeCaseId(caseId); const snapshotCaseId = normalizeCaseId(snapshot.caseId); if (currentCaseId && snapshotCaseId && currentCaseId !== snapshotCaseId) return null; return snapshot; } catch { getStorage()?.removeItem(IMPORT_PROGRESS_STORAGE_KEY); return null; } }; export const saveImportProgress = (snapshot: ImportProgressSnapshot) => { getStorage()?.setItem(IMPORT_PROGRESS_STORAGE_KEY, JSON.stringify(snapshot)); }; export const clearImportProgress = (caseId?: string | number) => { const storage = getStorage(); if (!storage) return; const snapshot = getActiveImportProgress(); const currentCaseId = normalizeCaseId(caseId); const snapshotCaseId = normalizeCaseId(snapshot?.caseId); if (!currentCaseId || !snapshotCaseId || currentCaseId === snapshotCaseId) { storage.removeItem(IMPORT_PROGRESS_STORAGE_KEY); } }; export const resetImportProgressSession = (caseId?: string | number) => { activeImportProgressEventSource?.close(); activeImportProgressEventSource = null; resetImportProgressRuntimeState(); clearImportProgress(caseId); };