chore: record session journal - 握力环训练趣味化

This commit is contained in:
2026-05-27 16:53:33 +08:00
parent 261f8315de
commit b9d2541b32
946 changed files with 107438 additions and 0 deletions
@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}
@@ -0,0 +1 @@
{"_example": "Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. Put spec/research files only — no code paths. Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. Delete this line once real entries are added."}
@@ -0,0 +1,113 @@
# 诊单编辑对话框:新增「患者业务订单」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 条跨诊单)
@@ -0,0 +1,26 @@
{
"id": "tcm-diagnosis-patient-orders-tab",
"name": "tcm-diagnosis-patient-orders-tab",
"title": "诊单编辑对话框:新增患者历史订单 tab",
"description": "",
"status": "completed",
"dev_type": null,
"scope": null,
"package": null,
"priority": "P2",
"creator": "codex-agent",
"assignee": "codex-agent",
"createdAt": "2026-05-05",
"completedAt": "2026-05-11",
"branch": null,
"base_branch": "history-order",
"worktree_path": null,
"commit": null,
"pr_url": null,
"subtasks": [],
"children": [],
"parent": null,
"relatedFiles": [],
"notes": "",
"meta": {}
}