Files
zyt/.trellis/tasks/archive/2026-05/05-05-tcm-diagnosis-patient-orders-tab/prd.md
T

114 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 诊单编辑对话框:新增「患者业务订单」Tab
## Goal
在「编辑诊单」抽屉对话框(`admin/src/views/tcm/diagnosis/edit.vue`)中新增一个 tab,一站式查看该患者的**处方业务订单**(含订单编号、金额、医生、医助、创建人、时间)。直接复用 `admin/src/views/consumer/prescription/order_list.vue` 所用接口 `/tcm.prescriptionOrder/lists`,仅以患者维度过滤。tab 受 `tcm.diagnosis/chufang` 权限控制。
## Decision Log
- **D1(数据源)**:处方业务订单 `tcm_prescription_order`(不是支付单 `zyt_order`)。用户明确:「订单信息可以参考这个页面,这个页面接口获取的是所有订单 关联到患者就好了」
- **D2(订单范围 / Q1)**:默认跨诊单聚合 + tab 顶部放切换开关,可一键切到"仅本诊单"
- **D3(接口)**:复用 `prescriptionOrderLists` (`@/api/tcm.ts:346`),不另起新接口
- **D4(列映射 / Q2)**:5 列:订单编号 / 金额 / 医生(`doctor_name`) / 创建人·医助(`creator_name`) / 创建时间。**不**单独显示 `assistant_name`,与创建人合并 → 后端无需新增字段注入
- **D5(行操作 / Q3)**:纯只读,不点击跳转、不弹详情、不挂任何按钮
## What I already know(已查证的事实)
### 前端
- 「编辑诊单」对话框:`admin/src/views/tcm/diagnosis/edit.vue:55` `<el-tabs>`,已含 12 个 tab,规范统一为 `:disabled="!formData.id" lazy` + `v-if="hasPermission([...])"`,子组件用 props 接 `diagnosisId / patientId`
- 处方 tab 现用 `tcm.diagnosis/chufang` 权限:`edit.vue:627`
- 参考页面:`admin/src/views/consumer/prescription/order_list.vue`5890 行)
- 现有 API`prescriptionOrderLists``/tcm.prescriptionOrder/lists``admin/src/api/tcm.ts:346`),已支持 `patient_keyword / order_no / prescription_id / fulfillment_status / prescription_audit_status / payment_slip_audit_status / start_time / end_time / doctor_id / assistant_id / express_keyword`
- 列表字段(前端列):订单号、处方ID、诊单ID、收货人、费用类别、金额、内部成本、处方审核、支付审核、履约、关联支付单、创建时间、**开方人 `doctor_name`**、**创建人 `creator_name`**
### 后端 `server/app/adminapi/lists/tcm/PrescriptionOrderLists.php`
- `setSearch()`line 29-36):当前 `=` 等值过滤仅含 `prescription_id / fulfillment_status / prescription_audit_status / payment_slip_audit_status`**未含 `diagnosis_id`**
- `applyPatientKeywordFilter()`line 768-785):用 `whereExists` 关联 `tcm_diagnosis`,按 `patient_name LIKE '%kw%' OR phone LIKE '%kw%'` 模糊聚合,**天然跨诊单**,正符合 D2 默认模式
- 响应注入字段(line 436-461):`creator_name``doctor_name``prescription_phone` 已写入;`assistant_id` 已查出(`$assistantByDiag` line 432-434)但**未写入 item**,需要补
- 返回 `assistant_name` 还需要再 `Admin::whereIn('id', assistant_ids)->column('name','id')` 一次
## Assumptions(待确认)
1. **「患者」匹配键**:用 `phone`(手机号)作 `patient_keyword`。如手机号脱敏不可用,回退用 `patient_name`。需要避免空 phone 误匹配
2. **「仅本诊单」开关 = 传 diagnosis_id**:后端补 `setSearch` `'=' => ['diagnosis_id']` 即可
3. **三列字段映射**
- 订单编号 → `order_no`
- 金额 → `amount`
- 医生 → `doctor_name`(开方人,已存在)
- 医助 → `assistant_name`(需后端新增注入)
- 创建人 → `creator_name`(已存在)
- 时间 → `create_time`
4. **只读**:tab 内只展示,不嵌业务操作(详情/取消/审核 等都不放)
## Open Questions
(已无阻塞问题,三个 Decision 已落定 D2 / D4 / D5
## Requirements
- [ ] **后端** `server/app/adminapi/lists/tcm/PrescriptionOrderLists.php`
- `setSearch()``'='` 数组里追加 `'diagnosis_id'`,使前端可传 `diagnosis_id` 做精确等值过滤
- 不动其他过滤、不动响应字段
- [ ] **前端 子组件** `admin/src/views/tcm/diagnosis/components/PatientOrderList.vue`
- props`diagnosisId: number``patientPhone?: string``patientName?: string`
- 顶部 `el-radio-group`/`el-segmented``全部历史(默认) | 仅本诊单` 二选一
- 全部历史 → 调 `prescriptionOrderLists({ patient_keyword: phone || patient_name, page_no, page_size })`
- 仅本诊单 → 调 `prescriptionOrderLists({ diagnosis_id, page_no, page_size })`
- 5 列:订单编号(`order_no`) / 金额(`amount`) / 医生(`doctor_name`) / 创建人(`creator_name`) / 创建时间(`create_time`)
- 分页:默认 size=10,可切 10/20/50
- 空态:`<el-empty>`
- [ ] **前端 入口** `admin/src/views/tcm/diagnosis/edit.vue`
-`<el-tabs>` 内追加 `<el-tab-pane label="业务订单" name="patientOrders" :disabled="!formData.id" lazy v-if="hasPermission(['tcm.diagnosis/chufang'])">`
- 内部嵌 `<PatientOrderList v-if="formData.id" :diagnosisId="Number(formData.id)" :patientPhone="originalPhone || formData.phone" :patientName="formData.patient_name" />`,否则 `<el-empty>`
## Acceptance Criteria
- [ ]`tcm.diagnosis/chufang` 权限的角色打开任一已保存诊单 → 看到"业务订单"tab
- [ ] 默认聚合该患者所有诊单的处方业务订单(按 phone 优先,回退 patient_name 模糊匹配)
- [ ] 顶部切换到"仅本诊单"后,列表使用新加的 `diagnosis_id` 等值过滤,仅展示当前诊单的订单
- [ ] 5 列正确:`order_no` / `amount` / `doctor_name` / `creator_name` / `create_time`
- [ ] 无该权限的用户看不见此 tab
- [ ] 新建(未保存)诊单 → tab 不可点
- [ ] 既有「处方业务订单」列表页(`consumer/prescription/order_list.vue`)行为完全不变(只新增过滤参数,不改既有过滤)
- [ ] 行无任何点击/操作行为
## Implementation Plan
**PR1(小步合并,约 30 行后端 + 200 行前端)**
1. 后端:`PrescriptionOrderLists.php:32` `setSearch()``'='` 数组追加 `'diagnosis_id'`
2. 前端:新增 `admin/src/views/tcm/diagnosis/components/PatientOrderList.vue`
3. 前端:`edit.vue` 注册 tab + import + 占位
**手动验证(无单测框架)**
- 角色:医生(有 chufang/ 医助(无 chufang/ 超管 — 看 tab 显隐与数据范围
- 数据:跨诊单同患者、单诊单单订单、无订单 三种场景
- 过滤:聚合开关切换两次响应应不同
- 回归:旧的 `consumer/prescription/order_list.vue` 列表所有过滤项均正常工作
## Definition of Done
- ESLint / vue-tsc 通过;新增字段 TS 类型完整
- 后端无 SQL 注入风险(`diagnosis_id``setSearch` 自动转 int
- 不引入 `console.log`
- 既有 `consumer/prescription/order_list.vue` 视觉/交互无回归
## Out of Scope
- 不展示支付单(`zyt_order`),不在该 tab 内做收款关联
- 不在 tab 内做任何写操作(无审核、改价、取消、退款、发货)
- 不为本 tab 单独建菜单/权限位(沿用 `tcm.diagnosis/chufang`
## Technical Notes
- 关键文件:
- `admin/src/views/tcm/diagnosis/edit.vue:55-697`el-tabs 区)
- `admin/src/views/consumer/prescription/order_list.vue`(参考)
- `admin/src/api/tcm.ts:346` `prescriptionOrderLists`
- `server/app/adminapi/lists/tcm/PrescriptionOrderLists.php:29-36, 430-465, 768-785`
- 风险:
- `patient_keyword` 是 LIKE 模糊匹配,对短手机号 / 同名同号场景可能误聚合 → 建议优先用完整 11 位手机号
- `assistant_name` 注入需要再发一次 `Admin` 查询(很轻量,已有 admin id 集合)
- 测试:手动验证四种角色(医生/医助/超管/无权限)+ 三种诊单(无订单/有 1 条/有 N 条跨诊单)