diff --git a/apps/miniprogram/src/pages/health/trend/index.tsx b/apps/miniprogram/src/pages/health/trend/index.tsx index ddf151f..5ccb7da 100644 --- a/apps/miniprogram/src/pages/health/trend/index.tsx +++ b/apps/miniprogram/src/pages/health/trend/index.tsx @@ -1,7 +1,8 @@ import { useState, useEffect } from 'react'; import { View, Text } from '@tarojs/components'; import Taro, { useRouter } from '@tarojs/taro'; -import { useHealthStore } from '../../../stores/health'; +import { useHealthStore } from '@/stores/health'; +import TrendChart from '@/components/TrendChart'; import './index.scss'; const RANGE_OPTIONS = [ @@ -10,6 +11,15 @@ const RANGE_OPTIONS = [ { value: '90d', label: '90天' }, ]; +const INDICATOR_META: Record = { + blood_pressure_systolic: { label: '收缩压', unit: 'mmHg', refMin: 90, refMax: 140 }, + blood_pressure_diastolic: { label: '舒张压', unit: 'mmHg', refMin: 60, refMax: 90 }, + heart_rate: { label: '心率', unit: 'bpm', refMin: 60, refMax: 100 }, + blood_sugar_fasting: { label: '空腹血糖', unit: 'mmol/L', refMin: 3.9, refMax: 6.1 }, + blood_sugar_postprandial: { label: '餐后血糖', unit: 'mmol/L', refMin: 3.9, refMax: 7.8 }, + weight: { label: '体重', unit: 'kg' }, +}; + export default function Trend() { const router = useRouter(); const indicator = router.params.indicator || 'heart_rate'; @@ -21,12 +31,12 @@ export default function Trend() { getTrend(indicator, range).then(setPoints); }, [indicator, range]); - const maxVal = points.length ? Math.max(...points.map((p) => p.value)) : 1; + const meta = INDICATOR_META[indicator] || { label: indicator, unit: '' }; return ( - {indicator.replace(/_/g, ' ')} 趋势 + {meta.label} 趋势 {RANGE_OPTIONS.map((opt) => ( - {/* 简易柱状图 */} - - {points.length === 0 ? ( - 暂无数据 - ) : ( - - {points.slice(-14).map((p, i) => ( - - - {p.date.slice(5)} - - ))} - - )} + {/* ECharts 折线图 */} + + {/* 数据列表 */} - - {points.slice().reverse().map((p, i) => ( - - {p.date} - {p.value} - - ))} - + {points.length > 0 && ( + + {points.slice().reverse().map((p, i) => ( + + {p.date} + {p.value}{meta.unit ? ` ${meta.unit}` : ''} + + ))} + + )} ); } diff --git a/apps/miniprogram/src/stores/health.ts b/apps/miniprogram/src/stores/health.ts index 0184da9..7bc1971 100644 --- a/apps/miniprogram/src/stores/health.ts +++ b/apps/miniprogram/src/stores/health.ts @@ -1,14 +1,22 @@ import { create } from 'zustand'; import * as healthApi from '@/services/health'; +interface CachedTrend { + data: { date: string; value: number }[]; + cachedAt: number; +} + interface HealthState { todaySummary: healthApi.TodaySummary | null; - trendData: Record; + trendData: Record; loading: boolean; refreshToday: () => Promise; getTrend: (indicator: string, range: string) => Promise<{ date: string; value: number }[]>; + clearCache: () => void; } +const CACHE_TTL = 5 * 60 * 1000; // 5 分钟 + export const useHealthStore = create((set, get) => ({ todaySummary: null, trendData: {}, @@ -27,15 +35,19 @@ export const useHealthStore = create((set, get) => ({ getTrend: async (indicator: string, range: string) => { const cacheKey = `${indicator}_${range}`; const cached = get().trendData[cacheKey]; - if (cached) return cached; + 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) => ({ trendData: { ...s.trendData, [cacheKey]: points } })); + set((s) => ({ trendData: { ...s.trendData, [cacheKey]: { data: points, cachedAt: Date.now() } } })); return points; } catch { return []; } }, + + clearCache: () => set({ trendData: {}, todaySummary: null }), }));