feat(health): 趋势图升级为 ECharts 折线图 + 缓存 TTL 5分钟

This commit is contained in:
iven
2026-04-24 12:38:07 +08:00
parent 7b5b00fbac
commit a9861a0cde
2 changed files with 46 additions and 31 deletions

View File

@@ -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<string, { label: string; unit: string; refMin?: number; refMax?: number }> = {
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 (
<View className='trend-page'>
<View className='trend-header'>
<Text className='trend-title'>{indicator.replace(/_/g, ' ')} </Text>
<Text className='trend-title'>{meta.label} </Text>
<View className='trend-tabs'>
{RANGE_OPTIONS.map((opt) => (
<View
@@ -40,34 +50,27 @@ export default function Trend() {
</View>
</View>
{/* 简易柱状图 */}
<View className='trend-chart'>
{points.length === 0 ? (
<Text className='trend-empty'></Text>
) : (
<View className='chart-bars'>
{points.slice(-14).map((p, i) => (
<View className='chart-bar-wrap' key={i}>
<View
className='chart-bar'
style={{ height: `${(p.value / maxVal) * 100}%` }}
/>
<Text className='chart-bar-date'>{p.date.slice(5)}</Text>
</View>
))}
</View>
)}
{/* ECharts 折线图 */}
<View className='trend-chart-container'>
<TrendChart
data={points}
referenceMin={meta.refMin}
referenceMax={meta.refMax}
unit={meta.unit}
/>
</View>
{/* 数据列表 */}
<View className='trend-list'>
{points.slice().reverse().map((p, i) => (
<View className='trend-item' key={i}>
<Text className='trend-item-date'>{p.date}</Text>
<Text className='trend-item-value'>{p.value}</Text>
</View>
))}
</View>
{points.length > 0 && (
<View className='trend-list'>
{points.slice().reverse().map((p, i) => (
<View className='trend-item' key={i}>
<Text className='trend-item-date'>{p.date}</Text>
<Text className='trend-item-value'>{p.value}{meta.unit ? ` ${meta.unit}` : ''}</Text>
</View>
))}
</View>
)}
</View>
);
}