diff --git a/src/components/exam/ExamSignPanel.tsx b/src/components/exam/ExamSignPanel.tsx index b781ebc..781a882 100644 --- a/src/components/exam/ExamSignPanel.tsx +++ b/src/components/exam/ExamSignPanel.tsx @@ -39,7 +39,7 @@ export const ExamSignPanel = ({ examId, onBusyChange }: ExamSignPanelProps) => { return () => onBusyChange?.(false); }, [busy, onBusyChange]); - const SIGN_STORAGE_KEY = 'yh_signed_consents'; + const SIGN_STORAGE_KEY = `yh_signed_consents_${new Date().toISOString().slice(0, 10)}`; const handlePickFile = () => { fileInputRef.current?.click(); diff --git a/src/components/home/HomeSection.tsx b/src/components/home/HomeSection.tsx index 8297819..0a40303 100644 --- a/src/components/home/HomeSection.tsx +++ b/src/components/home/HomeSection.tsx @@ -2,6 +2,7 @@ import { useEffect, useMemo, useState } from 'react'; import { getRevenueStatistics, getTodayExamStatistics, getUserOwnedMenus, getB1ServiceBoard, getNorth3ServiceBoard } from '../../api'; import type { B1ServiceInfo, OutputNorth3ServiceBoard } from '../../api/types'; import { Card, CardContent, CardHeader, InfoCard } from '../ui'; +import { cleanLocalStorageIfNeeded } from '../../utils/clean'; const APP_ID = 'b2b49e91d21446aeb14579930f732985'; @@ -38,6 +39,10 @@ export const HomeSection = () => { }), []); useEffect(() => { + + // 清理本地存储 + cleanLocalStorageIfNeeded(); + getTodayExamStatistics({}) .then((res) => { const d = res.Data; diff --git a/src/utils/clean.ts b/src/utils/clean.ts new file mode 100644 index 0000000..4305a5d --- /dev/null +++ b/src/utils/clean.ts @@ -0,0 +1,79 @@ +import { getTodayString } from './examActions'; + +/** + * 本地存储清理 - 上次清理日期 key + */ +const CLEAN_LAST_TIME_KEY = 'yh_local_clean_last_time'; + +/** + * 按日期清理本地存储中的体检相关缓存数据 + * + * 规则: + * - 仅在「从未清理过」或「上次清理日期早于今天」时执行清理 + * - 删除所有日期不是今天的 key,匹配示例: + * - yh_tongyishu_pdf_list_2025-12-24_100057962 + * - yh_exam_actions_2025-12-24_100057962 + * - yh_signed_consents_2025-12-24 + */ +export const cleanLocalStorageIfNeeded = (): void => { + if (typeof window === 'undefined' || !window.localStorage) return; + + const today = getTodayString(); // YYYY-MM-DD + const lastCleanDate = window.localStorage.getItem(CLEAN_LAST_TIME_KEY); + + // 如果已经在今天清理过,则直接返回 + if (lastCleanDate === today) { + return; + } + + const { localStorage } = window; + const keysToRemove: string[] = []; + + for (let i = 0; i < localStorage.length; i++) { + const key = localStorage.key(i); + if (!key) continue; + + // 匹配 yh_tongyishu_pdf_list_YYYY-MM-DD_xxx + const matchTongyishu = key.match(/^yh_tongyishu_pdf_list_(\d{4}-\d{2}-\d{2})_/); + if (matchTongyishu) { + const date = matchTongyishu[1]; + if (date !== today) { + keysToRemove.push(key); + } + continue; + } + + // 匹配 yh_exam_actions_YYYY-MM-DD_xxx + const matchExamActions = key.match(/^yh_exam_actions_(\d{4}-\d{2}-\d{2})_/); + if (matchExamActions) { + const date = matchExamActions[1]; + if (date !== today) { + keysToRemove.push(key); + } + continue; + } + + // 匹配 yh_signed_consents_YYYY-MM-DD + const matchSignedConsents = key.match(/^yh_signed_consents_(\d{4}-\d{2}-\d{2})$/); + if (matchSignedConsents) { + const date = matchSignedConsents[1]; + if (date !== today) { + keysToRemove.push(key); + } + continue; + } + } + + // 执行删除 + keysToRemove.forEach((key) => { + try { + localStorage.removeItem(key); + } catch { + // 删除失败忽略 + } + }); + + // 更新最后清理时间为今天 + window.localStorage.setItem(CLEAN_LAST_TIME_KEY, today); +}; +