Files
digital-pilates/store/healthSlice.ts
richarjiang fb85a5f30c refactor(health): remove basalEnergyBurned from global state and move to local component
Remove basalEnergyBurned from global health data structure and refactor BasalMetabolismCard to fetch its own data locally. This decouples the component from global state and improves data locality.

- Remove basalEnergyBurned from HealthData interface and health utilities
- Update BasalMetabolismCard to use selectedDate prop and fetch data locally
- Simplify statistics screen by removing unused basalMetabolism variable
- Update nutrition radar card to use activeCalories only for burned calories calculation
2025-09-19 17:01:45 +08:00

122 lines
3.1 KiB
TypeScript

import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { AppDispatch, RootState } from './index';
// 健康数据类型定义
export interface FitnessRingsData {
activeCalories: number;
activeCaloriesGoal: number;
exerciseMinutes: number;
exerciseMinutesGoal: number;
standHours: number;
standHoursGoal: number;
}
export interface HealthData {
activeCalories: number | null;
hrv: number | null;
heartRate: number | null;
activeEnergyBurned: number;
activeCaloriesGoal: number;
exerciseMinutes: number;
exerciseMinutesGoal: number;
standHours: number;
standHoursGoal: number;
}
export interface HealthState {
// 按日期存储的历史数据
dataByDate: Record<string, HealthData>;
// 加载状态
loading: boolean;
error: string | null;
// 最后更新时间
lastUpdateTime: string | null;
}
// 初始状态
const initialState: HealthState = {
dataByDate: {},
loading: false,
error: null,
lastUpdateTime: null,
};
const healthSlice = createSlice({
name: 'health',
initialState,
reducers: {
// 设置加载状态
setLoading: (state, action: PayloadAction<boolean>) => {
state.loading = action.payload;
},
// 设置错误信息
setError: (state, action: PayloadAction<string | null>) => {
state.error = action.payload;
},
// 设置完整的健康数据
setHealthData: (state, action: PayloadAction<{
date: string;
data: HealthData;
}>) => {
const { date, data } = action.payload;
// 存储到历史数据
state.dataByDate[date] = data;
state.lastUpdateTime = new Date().toISOString();
},
// 清除特定日期的数据
clearHealthDataForDate: (state, action: PayloadAction<string>) => {
const date = action.payload;
delete state.dataByDate[date];
},
// 清除所有健康数据
clearAllHealthData: (state) => {
state.dataByDate = {};
state.error = null;
state.lastUpdateTime = null;
},
},
});
// Action creators
export const {
setLoading,
setError,
setHealthData,
clearHealthDataForDate,
clearAllHealthData,
} = healthSlice.actions;
// Thunk action to fetch and set health data for a specific date
export const fetchHealthDataForDate = (date: Date) => {
return async (dispatch: AppDispatch, getState: () => RootState) => {
try {
dispatch(setLoading(true));
dispatch(setError(null));
// 这里可以添加实际的 API 调用逻辑
// 目前我们假设数据已经通过其他方式获取
dispatch(setLoading(false));
} catch (error) {
dispatch(setError(error instanceof Error ? error.message : '获取健康数据失败'));
dispatch(setLoading(false));
}
};
};
// Selectors
export const selectHealthDataByDate = (date: string) => (state: RootState) => state.health.dataByDate[date];
export const selectHealthLoading = (state: RootState) => state.health.loading;
export const selectHealthError = (state: RootState) => state.health.error;
export const selectLastUpdateTime = (state: RootState) => state.health.lastUpdateTime;
export default healthSlice.reducer;