70 lines
2.6 KiB
TypeScript
70 lines
2.6 KiB
TypeScript
/** 时间范围 */
|
|
export type TimeRange = '7d' | '30d' | '3m'
|
|
|
|
/** 单条测量记录 */
|
|
export interface RecordItem {
|
|
id: string
|
|
/** 格式 YYYY.MM.DD HH:mm */
|
|
time: string
|
|
weight: number
|
|
bmi: number
|
|
/** 体脂率(%) */
|
|
bodyFat: number
|
|
}
|
|
|
|
/** 统计指标 */
|
|
export interface StatsData {
|
|
maxWeight: number
|
|
minWeight: number
|
|
avgWeight: number
|
|
/** 体重变化(kg,正=增重,负=减轻) */
|
|
weightDiff: number
|
|
}
|
|
|
|
/** 全量 mock 记录(最近 3 个月数据,按时间倒序) */
|
|
const ALL_RECORDS: RecordItem[] = [
|
|
{ id: 'r-001', time: '2026.05.12 08:12', weight: 68.2, bmi: 22.0, bodyFat: 18.5 },
|
|
{ id: 'r-002', time: '2026.05.11 21:30', weight: 68.5, bmi: 22.1, bodyFat: 18.7 },
|
|
{ id: 'r-003', time: '2026.05.10 08:05', weight: 68.8, bmi: 22.3, bodyFat: 18.9 },
|
|
{ id: 'r-004', time: '2026.05.09 07:58', weight: 69.0, bmi: 22.4, bodyFat: 19.0 },
|
|
{ id: 'r-005', time: '2026.05.08 22:10', weight: 69.3, bmi: 22.5, bodyFat: 19.2 },
|
|
{ id: 'r-006', time: '2026.05.07 08:20', weight: 69.5, bmi: 22.6, bodyFat: 19.3 },
|
|
{ id: 'r-007', time: '2026.05.06 08:00', weight: 70.0, bmi: 22.7, bodyFat: 19.5 },
|
|
{ id: 'r-008', time: '2026.04.30 08:10', weight: 70.3, bmi: 22.8, bodyFat: 19.7 },
|
|
{ id: 'r-009', time: '2026.04.20 07:45', weight: 71.0, bmi: 23.0, bodyFat: 20.0 },
|
|
{ id: 'r-010', time: '2026.04.10 08:30', weight: 71.8, bmi: 23.2, bodyFat: 20.3 },
|
|
{ id: 'r-011', time: '2026.03.28 08:15', weight: 72.5, bmi: 23.5, bodyFat: 20.7 },
|
|
{ id: 'r-012', time: '2026.03.15 09:00', weight: 73.2, bmi: 23.7, bodyFat: 21.0 },
|
|
{ id: 'r-013', time: '2026.03.01 08:05', weight: 73.8, bmi: 23.9, bodyFat: 21.3 },
|
|
]
|
|
|
|
/** 各时间范围截取数量 */
|
|
const RANGE_COUNTS: Record<TimeRange, number> = {
|
|
'7d': 7,
|
|
'30d': 10,
|
|
'3m': 13,
|
|
}
|
|
|
|
/**
|
|
* 按时间范围获取 mock 记录列表
|
|
*/
|
|
export function getMockRecords(range: TimeRange): RecordItem[] {
|
|
return ALL_RECORDS.slice(0, RANGE_COUNTS[range])
|
|
}
|
|
|
|
/**
|
|
* 根据记录列表计算统计指标
|
|
*/
|
|
export function calcStats(records: RecordItem[]): StatsData {
|
|
if (!records.length) {
|
|
return { maxWeight: 0, minWeight: 0, avgWeight: 0, weightDiff: 0 }
|
|
}
|
|
const weights = records.map(r => r.weight)
|
|
const maxWeight = Math.max(...weights)
|
|
const minWeight = Math.min(...weights)
|
|
const avgWeight = parseFloat((weights.reduce((a, b) => a + b, 0) / weights.length).toFixed(1))
|
|
// 最新 - 最旧
|
|
const weightDiff = parseFloat((weights[0] - weights[weights.length - 1]).toFixed(1))
|
|
return { maxWeight, minWeight, avgWeight, weightDiff }
|
|
}
|