Prompt file imported from lxKylin/yucheng-mini (
.codex/prompts/M13.prompt.md). Copyright stays with the author.
M13 · 首页 / 列表页适配新数据层
任务概述
你是一名熟练的 Taro 4 + React 18 + TypeScript + Zustand + @taroify/core 专家。请按照以下规范,逐步完成 M13 首页 / 提醒列表适配新数据层的全部开发内容。完成每个子任务后自行验证,确认无误再进入下一个。
本模块承接 M10 / M10a / M11 / M12:项目已经从旧 Reminder 过渡到统一 Medicine 实体,并新增了 MedicineComposer 和药箱 Tab。M13 的目标不是重做首页或列表,而是做一次精准收口:确保首页风险中心和提醒列表只消费「提醒视角」数据,新增 / 编辑入口统一使用 MedicineComposer,组件字段引用全部切到 Medicine 新字段,并且 reminderEnabled=false 的药品不会混入首页或提醒列表。
参考资料
- 开发计划:
docs/3.开发计划.md的「V1.1 药箱模块开发计划」与「M13 · 首页 / 列表页适配新数据层」 - UI 参考:
ui7.0/index.htmlrenderHome():首页风险中心结构、今日待办、最近提醒renderList():提醒列表搜索、状态筛选、提醒卡片reminderList():提醒视角,只展示reminderEnabled=true的药品medicineCard():首页 / 列表风险卡片字段和操作参考- FAB 行为:首页 / 提醒列表点击新增时打开统一表单,默认开启开药提醒
- 前置模块:
- M10:已建立
Medicine/DerivedMedicine类型、提醒视角派生函数和药箱视角派生函数 - M10a:已完成旧字段兼容迁移,确认旧数据不回归
- M11:已完成
MedicineComposer统一新增 / 编辑 Sheet 和useReminderSheet的defaultReminderEnabled支持 - M12:已完成药箱 Tab 和
MedicineInventoryCard,药箱视角与提醒视角已经分离
- M10:已建立
当前项目状态
src/hooks/useReminders.ts应提供:useDerivedList():提醒视角,仅返回status !== deleted && reminderEnabled === true的派生药品useAllDerivedMedicines():药箱视角,返回所有未删除药品,本模块不应在首页 / 列表使用useReminderActions():包含markDone、togglePause、updateReminder等操作
src/hooks/useReminderSheet.ts应支持:openCreate(defaultReminderEnabled = true)openEdit(id)sheetTitleformKeydefaultReminderEnabled
src/components/MedicineComposer/已存在:- 支持
medicineId - 支持
defaultReminderEnabled onSuccess后由页面负责关闭 Sheet
- 支持
src/pages/home/index.tsx和src/pages/list/index.tsx可能已经部分接入MedicineComposer;请先检查现状,再做最小必要修改。src/components/MedicineCard/index.tsx和src/components/ReminderDetail/index.tsx仍是首页 / 列表 / 详情的提醒视角组件,必须继续展示风险状态、进度、下次开药日期和已开药闭环。
技术约束
- 保持函数式组件 + Hooks + TypeScript 类型安全
- 优先使用
@taroify/core组件;没有合适组件时再使用@tarojs/components - 不新增云数据库集合,不修改云函数扫描逻辑,不重写 M9 云开发认证和订阅消息
- 不重做药箱页,不修改
MedicineInventoryCard,不把药箱搜索 / 筛选逻辑复制到首页或列表 - 不使用
useAllDerivedMedicines()作为首页 / 列表数据源 - 首页 / 列表仍然只展示
reminderEnabled=true的药品 - 不引入库存估算,不读取或展示
stockPerPrescription、estimatedStock、stockDays等字段 - 不删除
ReminderForm文件,但首页 / 列表新增 / 编辑入口不应再依赖它 - 修改保持小步精准,不顺手重构我的页、药箱页、云服务或全局样式
本模块新增 / 修改文件
按检查结果最小修改,重点文件如下:
src/
├── pages/
│ ├── home/
│ │ ├── index.tsx ← 检查 / 修改:提醒视角数据源、MedicineComposer 新增入口、字段名
│ │ └── index.scss ← 仅在 UI 因新字段文案溢出时微调
│ └── list/
│ ├── index.tsx ← 检查 / 修改:提醒视角数据源、搜索字段、MedicineComposer 新增入口
│ └── index.scss ← 仅在 UI 因新字段文案溢出时微调
├── components/
│ ├── MedicineCard/
│ │ ├── index.tsx ← 检查 / 修改:字段名切到 Medicine 新字段
│ │ └── index.scss ← 尽量不改
│ └── ReminderDetail/
│ ├── index.tsx ← 检查 / 修改:编辑入口、字段名、关闭提醒语义
│ └── index.scss ← 尽量不改
└── hooks/
└── useReminderSheet.ts ← 仅在 defaultReminderEnabled 传递不完整时修改
如发现这些内容已经完成,不要为了“做改动”而重写;请改为补齐缺失的验证、字段引用或边界处理。
子任务 1:确认提醒视角数据源
检查:
src/pages/home/index.tsxsrc/pages/list/index.tsxsrc/components/ReminderDetail/index.tsx
要求:
- 首页和提醒列表必须使用
useDerivedList()或等价的提醒视角选择器 - 首页和提醒列表不得使用
useAllDerivedMedicines() - 首页统计、最近提醒、列表筛选数量、搜索结果都必须来自同一份提醒视角数据
reminderEnabled=false的药品不得进入:- 首页今日待办
- 首页最近提醒
- 提醒列表
- 提醒列表筛选数量
- 首页 / 提醒 Tab badge 相关统计(如当前项目有 badge 逻辑)
若发现页面层手动过滤 reminderEnabled,优先确认 deriveAll() / useDerivedList() 是否已经承担过滤职责。页面层可以保留防御性过滤,但不要把业务口径拆散到多个地方。
子任务 2:替换首页新增 / 编辑入口为 MedicineComposer
检查 src/pages/home/index.tsx。
2.1 新增入口
首页右下角新增按钮应调用:
openCreate(true);
打开 Sheet 后渲染:
<MedicineComposer
key={formKey}
medicineId={editReminderId}
defaultReminderEnabled={true}
onSuccess={handleFormSuccess}
onCancel={closeSheet}
/>
要求:
- 新增标题应为
新增开药提醒 - 新增时
reminderEnabled默认开启 - 提醒配置区默认展开
- 保存后新药品应进入首页和提醒列表
- 不再从首页渲染旧
ReminderForm
2.2 详情编辑入口
从首页卡片打开 ReminderDetail 后,点击编辑应复用 openEdit(id):
- 编辑标题应为
编辑药品 - 编辑模式由
medicineId={editReminderId}回填 - 不要强行覆盖已有药品的
reminderEnabled状态;编辑模式应以药品自身数据为准
子任务 3:替换提醒列表新增 / 编辑入口为 MedicineComposer
检查 src/pages/list/index.tsx。
3.1 新增入口
列表页右下角新增按钮应调用:
openCreate(true);
打开 Sheet 后渲染 MedicineComposer,并传入 defaultReminderEnabled={true}。
要求:
- 新增标题应为
新增开药提醒 - 新增时提醒区默认展开
- 保存后新药品应立即出现在列表中,并按提醒优先级排序
- 不再从列表页渲染旧
ReminderForm
3.2 搜索与筛选
提醒列表搜索仍只面向提醒视角数据,至少支持:
namespec
筛选仍保持:
- 全部
- 逾期·今日
- 7天内
- 正常
- 暂停
不要加入药箱页的「已开提醒 / 未开提醒」筛选,也不要搜索纯药箱药品。
子任务 4:字段名适配与组件回归
检查以下文件:
src/components/MedicineCard/index.tsxsrc/components/ReminderDetail/index.tsxsrc/pages/home/index.tsxsrc/pages/list/index.tsx
4.1 字段名必须使用 Medicine 新字段
组件应优先使用:
namespeccurrentPrescriptionDateintervalDaysremindAdvanceDaysremindTimeprescriptionHistorynextPrescriptionDatenextRemindDatescheduleLabel(如需要展示服药时机)
不得继续依赖旧字段:
medicineNamemedicineSpeclastDateintervalbeforetimehistory
如果某些旧字段只出现在 ReminderForm、迁移函数、兼容双写或注释中,可以保留;但首页 / 列表 / 风险卡片 / 详情展示逻辑不应读取它们。
4.2 卡片展示口径
MedicineCard 是提醒风险卡片,不是药箱资料卡片。应继续展示:
- 药品名称、规格
- 状态标签
levelLabel - 最近开药日期
currentPrescriptionDate - 周期
intervalDays - 下次开药日期
nextPrescriptionDate - 提醒时间
nextRemindDate + remindTime - 进度条
progress 已开药和查看详情操作
不要在 MedicineCard 中展示药箱专属信息,如过期时间、资料编辑提示、提醒启用状态文案等;这些属于 MedicineInventoryCard。
4.3 详情删除语义
如果当前 ReminderDetail 的删除按钮用于首页 / 列表提醒视角,优先采用「关闭 / 移出提醒列表」语义:
- 确认弹窗文案说明药品资料仍保留在药箱
- 确认后调用
updateReminder(id, { reminderEnabled: false, status: active })或项目中等价 API - 成功后关闭 Sheet,Toast 提示已移出提醒列表
不要在提醒详情里直接硬删除药品,除非前置模块已经明确采用删除药品语义。
子任务 5:已开药闭环回归
首页 / 列表 / 详情中的「已开药」动作必须继续可用。
检查:
- 首页卡片点击「已开药」
- 列表卡片点击「已开药」
- 详情 Sheet 点击「本次已开药」
- 逾期时是否打开实际开药日期确认 Sheet(如项目已有
DoneDateSheet)
要求:
- 非逾期提醒可直接确认并调用
markDone(id) - 逾期提醒应允许用户确认实际开药日期
- 成功后更新
currentPrescriptionDate prescriptionHistory增加记录- 首页和列表即时刷新
reminderEnabled=false的药品不会因为已开药流程重新出现在首页 / 列表,除非用户在编辑表单中重新开启提醒
子任务 6:样式与交互边界
本模块原则上不需要大改样式。仅在出现以下问题时微调:
MedicineComposer接入后 Sheet 内容在首页 / 列表中被遮挡- 新字段文案导致卡片溢出或按钮文字换行异常
- 空状态、FAB、BottomSheet 在小屏下重叠
样式要求:
- 首页 / 列表继续保持 ui7.0 的风险中心风格
- 不把首页 / 列表改成药箱资料页视觉
- 点击区域不小于 44px
- 搜索框、筛选 chip、卡片操作按钮在小屏下不溢出
- 不引入新的大色系,不使用大面积装饰渐变
子任务 7:回归检查
完成后至少运行以下检查。
7.1 静态扫描
运行:
rg -n "ReminderForm|medicineName|medicineSpec|lastDate|\\binterval\\b|\\bbefore\\b|\\btime\\b|\\bhistory\\b" src/pages/home src/pages/list src/components/MedicineCard src/components/ReminderDetail
期望:
- 首页 / 列表 /
MedicineCard/ReminderDetail不再读取旧字段 - 如出现
time等通用词,要确认不是旧提醒字段误用
运行:
rg -n "useAllDerivedMedicines|useDerivedList|MedicineComposer|openCreate\\(true\\)|defaultReminderEnabled" src/pages/home src/pages/list src/components src/hooks/useReminderSheet.ts
确认:
- 首页 / 列表使用
useDerivedList() - 首页 / 列表没有使用
useAllDerivedMedicines() - 首页 / 列表新增入口调用
openCreate(true) - 首页 / 列表渲染
MedicineComposer MedicineComposer收到defaultReminderEnabled={true}或从useReminderSheet等价传递
运行:
rg -n "estimatedStock|stockDays|stockPerPrescription" src/pages/home src/pages/list src/components/MedicineCard src/components/ReminderDetail
期望:
- 首页 / 列表 / 风险卡片 / 提醒详情不读取库存估算字段
7.2 TypeScript 检查
优先运行:
pnpm exec tsc --noEmit
如项目当前没有独立 tsc 配置或存在环境限制,运行项目等效检查,并在最终说明中写清楚。
7.3 启动检查
运行:
pnpm dev:weapp
看到编译成功或无 M13 新增错误后即可停止。
验收标准
首页
- 首页使用提醒视角数据源,只展示
reminderEnabled=true的药品 - 首页今日待办、已逾期、今日处理、药物数统计不包含纯药箱药品
- 首页最近提醒最多展示 3 条,并保持提醒优先级排序
- 首页点击「查看全部」仍跳转提醒列表
- 首页点击右下角新增按钮打开
MedicineComposer - 首页新增提醒时
defaultReminderEnabled=true,提醒区默认展开 - 首页卡片「已开药」和「查看详情」功能正常
提醒列表
- 列表页使用提醒视角数据源,只展示
reminderEnabled=true的药品 - 列表搜索药品名称和规格正常
- 全部 / 逾期·今日 / 7天内 / 正常 / 暂停筛选数量准确
- 搜索 + 筛选可同时生效
- 筛选无结果时显示空状态
- 列表点击右下角新增按钮打开
MedicineComposer - 列表新增提醒时
defaultReminderEnabled=true,提醒区默认展开
组件与数据
-
MedicineCard使用name/spec/currentPrescriptionDate/intervalDays/remindTime等新字段 -
ReminderDetail使用新字段并能正常编辑、暂停 / 启用、移出提醒列表 - 首页 / 列表不再渲染旧
ReminderForm -
reminderEnabled=false的药品不会出现在首页、提醒列表、筛选计数或最近提醒中 - 从首页 / 列表新增
reminderEnabled=true的药品后,会同时出现在首页 / 列表和药箱页 - 从药箱新增
reminderEnabled=false的药品后,只出现在药箱页,不出现在首页 / 列表
回归
- 已开药后
currentPrescriptionDate和prescriptionHistory正确更新 - 暂停 / 重新启用提醒后,首页和列表状态即时刷新
- 编辑时可开启或关闭提醒;关闭提醒后从首页 / 列表消失但保留在药箱
-
pnpm exec tsc --noEmit或等效 TypeScript 检查无 M13 新增错误 -
pnpm dev:weapp可启动,无 M13 引入的编译错误
开发提示
- 先做静态扫描确认现状,再决定是否需要修改。M13 是收口模块,很多代码可能已经在 M11 / M12 中提前完成。
- 首页 / 列表的核心边界是「风险提醒视角」,药箱页的核心边界是「资料管理视角」。不要让两个视角互相借用数据源。
Reminder/DerivedReminder可能仍作为兼容别名存在,但展示代码应逐步面向Medicine新字段。openCreate(true)和openCreate(false)是区分新增开药提醒与新增药品的关键,不要在首页 / 列表误传false。- 如需微调
useReminderSheet,保持它同时服务首页、列表、详情和药箱页,不要为 M13 单独写一套 Sheet 状态机。
