Files
digital-pilates/store/healthSlice.ts
richarjiang 9bcea25a2f feat(auth): 为未登录用户添加登录引导界面
为目标页面、营养记录、食物添加等功能添加登录状态检查和引导界面,确保用户在未登录状态下能够获得清晰的登录提示和指引。

- 在目标页面添加精美的未登录引导界面,包含渐变背景和登录按钮
- 为食物记录相关组件添加登录状态检查,未登录时自动跳转登录页面
- 重构血氧饱和度卡片为独立数据获取,移除对外部数据依赖
- 移除个人页面的实验性SwiftUI组件,统一使用原生TouchableOpacity
- 清理统计页面和营养记录页面的冗余代码和未使用变量
2025-09-19 15:52:24 +08:00

123 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;
basalEnergyBurned: 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;