feat(个人中心): 优化会员横幅组件,支持深色模式与国际化;新增医疗记录卡片组件,完善健康档案功能
This commit is contained in:
@@ -1,6 +1,13 @@
|
||||
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import * as healthProfileApi from '@/services/healthProfile';
|
||||
import { AppDispatch, RootState } from './index';
|
||||
import {
|
||||
HistoryData,
|
||||
HistoryItemDetail,
|
||||
MedicalRecordItem,
|
||||
MedicalRecordsData,
|
||||
MedicalRecordType,
|
||||
} from '@/services/healthProfile';
|
||||
|
||||
// 健康数据类型定义
|
||||
export interface FitnessRingsData {
|
||||
@@ -45,6 +52,9 @@ export interface HealthState {
|
||||
// 健康史数据
|
||||
historyData: HistoryData;
|
||||
|
||||
// 就医资料数据
|
||||
medicalRecords: MedicalRecordsData;
|
||||
|
||||
// 加载状态
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
@@ -62,6 +72,10 @@ const initialState: HealthState = {
|
||||
surgery: { hasHistory: null, items: [] },
|
||||
familyDisease: { hasHistory: null, items: [] },
|
||||
},
|
||||
medicalRecords: {
|
||||
records: [],
|
||||
prescriptions: [],
|
||||
},
|
||||
loading: false,
|
||||
error: null,
|
||||
lastUpdateTime: null,
|
||||
@@ -136,6 +150,34 @@ const healthSlice = createSlice({
|
||||
familyDisease: { hasHistory: null, items: [] },
|
||||
};
|
||||
},
|
||||
|
||||
// 更新就医资料列表
|
||||
setMedicalRecords: (state, action: PayloadAction<MedicalRecordsData>) => {
|
||||
state.medicalRecords = action.payload;
|
||||
state.lastUpdateTime = new Date().toISOString();
|
||||
},
|
||||
|
||||
// 添加就医资料项
|
||||
addMedicalRecordItem: (state, action: PayloadAction<MedicalRecordItem>) => {
|
||||
const item = action.payload;
|
||||
if (item.type === 'medical_record') {
|
||||
state.medicalRecords.records.unshift(item);
|
||||
} else {
|
||||
state.medicalRecords.prescriptions.unshift(item);
|
||||
}
|
||||
state.lastUpdateTime = new Date().toISOString();
|
||||
},
|
||||
|
||||
// 删除就医资料项
|
||||
removeMedicalRecordItem: (state, action: PayloadAction<{ id: string; type: MedicalRecordType }>) => {
|
||||
const { id, type } = action.payload;
|
||||
if (type === 'medical_record') {
|
||||
state.medicalRecords.records = state.medicalRecords.records.filter(item => item.id !== id);
|
||||
} else {
|
||||
state.medicalRecords.prescriptions = state.medicalRecords.prescriptions.filter(item => item.id !== id);
|
||||
}
|
||||
state.lastUpdateTime = new Date().toISOString();
|
||||
},
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
builder
|
||||
@@ -196,6 +238,40 @@ const healthSlice = createSlice({
|
||||
// 获取健康史进度
|
||||
.addCase(fetchHealthHistoryProgress.rejected, (state, action) => {
|
||||
state.error = action.payload as string;
|
||||
})
|
||||
// 获取就医资料
|
||||
.addCase(fetchMedicalRecords.pending, (state) => {
|
||||
state.loading = true;
|
||||
state.error = null;
|
||||
})
|
||||
.addCase(fetchMedicalRecords.fulfilled, (state, action) => {
|
||||
state.loading = false;
|
||||
state.medicalRecords = action.payload;
|
||||
state.lastUpdateTime = new Date().toISOString();
|
||||
})
|
||||
.addCase(fetchMedicalRecords.rejected, (state, action) => {
|
||||
state.loading = false;
|
||||
state.error = action.payload as string;
|
||||
})
|
||||
// 添加就医资料
|
||||
.addCase(addNewMedicalRecord.fulfilled, (state, action) => {
|
||||
const item = action.payload;
|
||||
if (item.type === 'medical_record') {
|
||||
state.medicalRecords.records.unshift(item);
|
||||
} else {
|
||||
state.medicalRecords.prescriptions.unshift(item);
|
||||
}
|
||||
state.lastUpdateTime = new Date().toISOString();
|
||||
})
|
||||
// 删除就医资料
|
||||
.addCase(deleteMedicalRecordItem.fulfilled, (state, action) => {
|
||||
const { id, type } = action.payload;
|
||||
if (type === 'medical_record') {
|
||||
state.medicalRecords.records = state.medicalRecords.records.filter(item => item.id !== id);
|
||||
} else {
|
||||
state.medicalRecords.prescriptions = state.medicalRecords.prescriptions.filter(item => item.id !== id);
|
||||
}
|
||||
state.lastUpdateTime = new Date().toISOString();
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -210,6 +286,9 @@ export const {
|
||||
updateHistoryData,
|
||||
setHistoryData,
|
||||
clearHistoryData,
|
||||
setMedicalRecords,
|
||||
addMedicalRecordItem,
|
||||
removeMedicalRecordItem,
|
||||
} = healthSlice.actions;
|
||||
|
||||
// Thunk action to fetch and set health data for a specific date
|
||||
@@ -286,12 +365,60 @@ export const fetchHealthHistoryProgress = createAsyncThunk(
|
||||
}
|
||||
);
|
||||
|
||||
// ==================== 就医资料 API Thunks ====================
|
||||
|
||||
/**
|
||||
* 获取就医资料
|
||||
*/
|
||||
export const fetchMedicalRecords = createAsyncThunk(
|
||||
'health/fetchMedicalRecords',
|
||||
async (_, { rejectWithValue }) => {
|
||||
try {
|
||||
const data = await healthProfileApi.getMedicalRecords();
|
||||
return data;
|
||||
} catch (err: any) {
|
||||
return rejectWithValue(err?.message ?? '获取就医资料失败');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* 添加就医资料
|
||||
*/
|
||||
export const addNewMedicalRecord = createAsyncThunk(
|
||||
'health/addMedicalRecord',
|
||||
async (data: Omit<MedicalRecordItem, 'id'>, { rejectWithValue }) => {
|
||||
try {
|
||||
const result = await healthProfileApi.addMedicalRecord(data);
|
||||
return result;
|
||||
} catch (err: any) {
|
||||
return rejectWithValue(err?.message ?? '添加就医资料失败');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* 删除就医资料
|
||||
*/
|
||||
export const deleteMedicalRecordItem = createAsyncThunk(
|
||||
'health/deleteMedicalRecord',
|
||||
async ({ id, type }: { id: string; type: MedicalRecordType }, { rejectWithValue }) => {
|
||||
try {
|
||||
await healthProfileApi.deleteMedicalRecord(id);
|
||||
return { id, type };
|
||||
} catch (err: any) {
|
||||
return rejectWithValue(err?.message ?? '删除就医资料失败');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 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 const selectHistoryData = (state: RootState) => state.health.historyData;
|
||||
export const selectMedicalRecords = (state: RootState) => state.health.medicalRecords;
|
||||
|
||||
// 计算健康史完成度的 selector
|
||||
export const selectHealthHistoryProgress = (state: RootState) => {
|
||||
|
||||
Reference in New Issue
Block a user