From da09df1e9d8c7c3aa7b26fac4c2fecee700f80ea Mon Sep 17 00:00:00 2001 From: richarjiang Date: Wed, 19 Nov 2025 16:12:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(medications):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=8D=AF=E7=89=A9=E6=98=BE=E7=A4=BA=E9=80=BB=E8=BE=91=EF=BC=8C?= =?UTF-8?q?=E6=9C=AA=E6=9C=8D=E7=94=A8=E8=8D=AF=E5=93=81=E4=BC=98=E5=85=88?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E5=B9=B6=E6=9B=B4=E6=96=B0=E8=AE=A1=E6=95=B0?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/(tabs)/medications.tsx | 14 +++++++++++++- store/medicationsSlice.ts | 26 +++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/app/(tabs)/medications.tsx b/app/(tabs)/medications.tsx index d74d4ff..7420d16 100644 --- a/app/(tabs)/medications.tsx +++ b/app/(tabs)/medications.tsx @@ -177,12 +177,24 @@ export default function MedicationsScreen() { if (activeFilter === 'all') { return medicationsWithImages; } + + // "未服用" tab 包含 missed(已错过)和 upcoming(待服用)两种状态 + if (activeFilter === 'missed') { + return medicationsWithImages.filter((item: any) => + item.status === 'missed' || item.status === 'upcoming' + ); + } + + // 其他状态按原逻辑过滤 return medicationsWithImages.filter((item: any) => item.status === activeFilter); }, [activeFilter, medicationsWithImages]); const counts = useMemo(() => { const taken = medicationsWithImages.filter((item: any) => item.status === 'taken').length; - const missed = medicationsWithImages.filter((item: any) => item.status === 'missed').length; + // "未服用"计数包含 missed(已错过)和 upcoming(待服用) + const missed = medicationsWithImages.filter((item: any) => + item.status === 'missed' || item.status === 'upcoming' + ).length; return { all: medicationsWithImages.length, taken, diff --git a/store/medicationsSlice.ts b/store/medicationsSlice.ts index 7f883d9..628b481 100644 --- a/store/medicationsSlice.ts +++ b/store/medicationsSlice.ts @@ -729,6 +729,7 @@ export const selectSelectedDateStats = (state: RootState) => { /** * 获取指定日期的展示项列表(用于UI渲染) * 将药物记录和药物信息合并为展示项 + * 排序规则:优先显示未服用的药品(upcoming、missed),然后是已服用的药品(taken、skipped) */ export const selectMedicationDisplayItemsByDate = (date: string) => (state: RootState) => { const records = state.medications.medicationRecords[date] || []; @@ -739,7 +740,7 @@ export const selectMedicationDisplayItemsByDate = (date: string) => (state: Root medications.forEach((med) => medicationMap.set(med.id, med)); // 转换为展示项 - return records + const displayItems = records .map((record) => { const medication = medicationMap.get(record.medicationId); if (!medication) return null; @@ -768,6 +769,29 @@ export const selectMedicationDisplayItemsByDate = (date: string) => (state: Root } as import('@/types/medication').MedicationDisplayItem; }) .filter((item): item is import('@/types/medication').MedicationDisplayItem => item !== null); + + // 排序:未服用的药品(upcoming、missed)优先,已服用的药品(taken、skipped)其次 + // 在同一组内,按计划时间升序排列 + return displayItems.sort((a, b) => { + // 定义状态优先级:数值越小优先级越高 + const statusPriority: Record = { + 'missed': 1, // 已错过 - 最高优先级 + 'upcoming': 2, // 待服用 + 'taken': 3, // 已服用 + 'skipped': 4, // 已跳过 + }; + + const priorityA = statusPriority[a.status]; + const priorityB = statusPriority[b.status]; + + // 首先按状态优先级排序 + if (priorityA !== priorityB) { + return priorityA - priorityB; + } + + // 状态相同时,按计划时间升序排列 + return a.scheduledTime.localeCompare(b.scheduledTime); + }); }; // ==================== Export ====================