import { create } from 'zustand'; import * as healthApi from '@/services/health'; import { getCachedPatientId } from '@/services/request'; import { useAuthStore } from './auth'; interface CachedTrend { data: { date: string; value: number }[]; cachedAt: number; } interface HealthState { todaySummary: healthApi.TodaySummary | null; todaySummaryFetchedAt: number; trendData: Record; loading: boolean; _refreshingToday: boolean; refreshToday: (force?: boolean) => Promise; getTrend: (indicator: string, range: string) => Promise<{ date: string; value: number }[]>; clearCache: () => void; } const CACHE_TTL = 5 * 60 * 1000; const TODAY_SUMMARY_TTL = 60_000; const MAX_TREND_KEYS = 20; export const useHealthStore = create((set, get) => ({ todaySummary: null, todaySummaryFetchedAt: 0, trendData: {}, loading: false, _refreshingToday: false, refreshToday: async (force = false) => { if (get()._refreshingToday) return; const state = get(); if (!force && state.todaySummary && Date.now() - state.todaySummaryFetchedAt < TODAY_SUMMARY_TTL) { return; } set({ _refreshingToday: true, loading: true }); try { const patientId = getCachedPatientId() || useAuthStore.getState().currentPatient?.id || undefined; const data = await healthApi.getTodaySummary(patientId); set({ todaySummary: data, todaySummaryFetchedAt: Date.now(), loading: false, _refreshingToday: false }); } catch (err) { console.warn('[health] 刷新今日摘要失败:', err); set({ loading: false, _refreshingToday: false }); } }, getTrend: async (indicator: string, range: string) => { const cacheKey = `${indicator}_${range}`; const cached = get().trendData[cacheKey]; if (cached && Date.now() - cached.cachedAt < CACHE_TTL) { return cached.data; } try { const resp = await healthApi.getTrend(indicator, range); const points = resp.data_points || []; set((s) => { const updated = { ...s.trendData, [cacheKey]: { data: points, cachedAt: Date.now() } }; // 超过上限时淘汰最早的缓存 const keys = Object.keys(updated); if (keys.length > MAX_TREND_KEYS) { const oldest = keys.reduce((a, b) => updated[a].cachedAt < updated[b].cachedAt ? a : b); delete updated[oldest]; } return { trendData: updated }; }); return points; } catch (err) { console.warn('[health] 获取趋势数据失败:', err); return []; } }, clearCache: () => set({ trendData: {}, todaySummary: null, todaySummaryFetchedAt: 0, _refreshingToday: false }), }));