feat(health): 趋势图升级为 ECharts 折线图 + 缓存 TTL 5分钟
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user