feat: 支持步数卡片; 优化数据分析各类卡片样式

This commit is contained in:
richarjiang
2025-08-30 17:07:04 +08:00
parent 465d5350f3
commit 741688065d
9 changed files with 462 additions and 103 deletions

136
utils/mockHealthData.ts Normal file
View File

@@ -0,0 +1,136 @@
import { HourlyStepData, TodayHealthData } from './health';
// Mock的每小时步数数据模拟真实的一天活动模式
export const mockHourlySteps: HourlyStepData[] = [
{ hour: 0, steps: 0 }, // 午夜
{ hour: 1, steps: 0 }, // 凌晨
{ hour: 2, steps: 0 },
{ hour: 3, steps: 0 },
{ hour: 4, steps: 0 },
{ hour: 5, steps: 0 },
{ hour: 6, steps: 120 }, // 早晨起床
{ hour: 7, steps: 450 }, // 晨练/上班准备
{ hour: 8, steps: 680 }, // 上班通勤
{ hour: 9, steps: 320 }, // 工作时间
{ hour: 10, steps: 180 }, // 办公室内活动
{ hour: 11, steps: 280 }, // 会议/活动
{ hour: 12, steps: 520 }, // 午餐时间
{ hour: 13, steps: 150 }, // 午休
{ hour: 14, steps: 240 }, // 下午工作
{ hour: 15, steps: 300 }, // 工作活动
{ hour: 16, steps: 380 }, // 会议/外出
{ hour: 17, steps: 480 }, // 下班通勤
{ hour: 18, steps: 620 }, // 晚餐/活动
{ hour: 19, steps: 350 }, // 晚间活动
{ hour: 20, steps: 280 }, // 散步
{ hour: 21, steps: 150 }, // 休闲时间
{ hour: 22, steps: 80 }, // 准备睡觉
{ hour: 23, steps: 30 }, // 睡前
];
// Mock的完整健康数据
export const mockHealthData: TodayHealthData = {
steps: 6140, // 总步数
hourlySteps: mockHourlySteps,
activeEnergyBurned: 420,
basalEnergyBurned: 1680,
sleepDuration: 480, // 8小时
hrv: 45,
activeCalories: 420,
activeCaloriesGoal: 350,
exerciseMinutes: 32,
exerciseMinutesGoal: 30,
standHours: 8,
standHoursGoal: 12,
oxygenSaturation: 98.2,
heartRate: 72,
};
// 生成随机的每小时步数数据(用于测试不同的数据模式)
export const generateRandomHourlySteps = (): HourlyStepData[] => {
return Array.from({ length: 24 }, (_, hour) => {
let steps = 0;
// 模拟真实的活动模式
if (hour >= 6 && hour <= 22) {
if (hour >= 7 && hour <= 9) {
// 早晨高峰期
steps = Math.floor(Math.random() * 600) + 200;
} else if (hour >= 12 && hour <= 13) {
// 午餐时间
steps = Math.floor(Math.random() * 400) + 300;
} else if (hour >= 17 && hour <= 19) {
// 晚间活跃期
steps = Math.floor(Math.random() * 500) + 250;
} else if (hour >= 6 && hour <= 22) {
// 白天正常活动
steps = Math.floor(Math.random() * 300) + 50;
}
} else {
// 夜间很少活动
steps = Math.floor(Math.random() * 50);
}
return { hour, steps };
});
};
// 不同活动模式的预设数据
export const activityPatterns = {
// 久坐办公族
sedentary: Array.from({ length: 24 }, (_, hour) => ({
hour,
steps: hour >= 7 && hour <= 18 ? Math.floor(Math.random() * 200) + 50 :
hour >= 19 && hour <= 21 ? Math.floor(Math.random() * 300) + 100 :
Math.floor(Math.random() * 20)
})),
// 活跃用户
active: Array.from({ length: 24 }, (_, hour) => ({
hour,
steps: hour >= 6 && hour <= 8 ? Math.floor(Math.random() * 800) + 400 :
hour >= 12 && hour <= 13 ? Math.floor(Math.random() * 600) + 300 :
hour >= 17 && hour <= 20 ? Math.floor(Math.random() * 900) + 500 :
hour >= 9 && hour <= 16 ? Math.floor(Math.random() * 400) + 100 :
Math.floor(Math.random() * 50)
})),
// 健身爱好者
fitness: Array.from({ length: 24 }, (_, hour) => ({
hour,
steps: hour === 6 ? Math.floor(Math.random() * 1200) + 800 : // 晨跑
hour === 18 ? Math.floor(Math.random() * 1000) + 600 : // 晚间锻炼
hour >= 7 && hour <= 17 ? Math.floor(Math.random() * 300) + 100 :
Math.floor(Math.random() * 50)
})),
};
// 用于快速切换测试数据的函数
export const getTestHealthData = (pattern: 'mock' | 'random' | 'sedentary' | 'active' | 'fitness' = 'mock'): TodayHealthData => {
let hourlySteps: HourlyStepData[];
switch (pattern) {
case 'random':
hourlySteps = generateRandomHourlySteps();
break;
case 'sedentary':
hourlySteps = activityPatterns.sedentary;
break;
case 'active':
hourlySteps = activityPatterns.active;
break;
case 'fitness':
hourlySteps = activityPatterns.fitness;
break;
default:
hourlySteps = mockHourlySteps;
}
const totalSteps = hourlySteps.reduce((sum, data) => sum + data.steps, 0);
return {
...mockHealthData,
steps: totalSteps,
hourlySteps,
};
};