Files
zyt/app/research/parity_prescriptions.md
2026-08-10 17:29:05 +08:00

358 lines
28 KiB
Markdown
Raw Permalink 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.
# “我的处方库 / 已开处方”桌面端对齐审计
审计日期:2026-08-10
## 1. 范围、基准与结论口径
本审计只读检查以下两套实现,没有修改业务源码:
- 管理端唯一功能基准:D:/web/zyt/admin/src/views
- Python 桌面端:D:/web/zyt/app/src/doctor_workstation
管理端 API 包装文件、通用组件和分页 hook 仅用于解析“页面已经发起的调用”的 URL、参数与直接子组件行为,不把相邻页面或未被页面调用的 API 当成处方页功能。
结论标签:
- EXACT:用户可见行为、状态语义和请求合同均与基准一致;不要求布局像素一致。
- PARTIAL:仅覆盖基准的子集,或字段/状态/校验语义有差异。
- MISSING:基准存在,而 Python 没有入口或没有可达实现。
- EXACT(负向):基准明确没有该能力,Python 也没有;不能把它列为待补功能。
## 2. 真实页面定位
| 业务名 | 管理端真实 view 组件 | Python 页面 | 结论 |
|---|---|---|---|
| 我的处方库 | D:/web/zyt/admin/src/views/consumer/prescription/list.vue:1-414script name 为 prescriptionLibrary234 | D:/web/zyt/app/src/doctor_workstation/ui/pages/prescription_library.py:251-545;固定导航见 D:/web/zyt/app/src/doctor_workstation/ui/shell.py:48-54 | EXACT(组件映射) |
| 已开处方 / 处方管理 | D:/web/zyt/admin/src/views/consumer/prescription/index.vue:1-4892script name 为 prescriptionList1697 | D:/web/zyt/app/src/doctor_workstation/ui/pages/prescriptions.py:72-436;固定导航见 D:/web/zyt/app/src/doctor_workstation/ui/shell.py:55-61 | EXACT(组件映射),功能不是 EXACT |
管理端采用动态菜单,单凭 src/views 只能确定组件键应分别落到 consumer/prescription/list 与 consumer/prescription/index,不能确定生产环境最终 URL、菜单标题或 route.meta.perms。Python 则固定注册为 prescription_library / prescriptions。审计不伪造管理端生产 URL。
## 3. 直接子组件与边界
### 3.1 MedicineNameSelect
处方库在 D:/web/zyt/admin/src/views/consumer/prescription/list.vue:158-165 使用;已开处方的主方、辅方行分别在 D:/web/zyt/admin/src/views/consumer/prescription/index.vue:695-726、736-767 使用。
真实合同:
- 远程、可过滤选择器,提示支持药材名或拼音首字母:D:/web/zyt/admin/src/components/medicine-name-select/index.vue:3-24。
- 展开或搜索时 GET /doctor.medicine/lists,参数 name、page_no=1、page_size=100、status=1:同文件 69-92URL 包装见 D:/web/zyt/admin/src/api/medicine.ts:6-8。
- 选择后同时回写 name 和 medicine_id;不能把任意自由文本当成一次有效选择:组件 95-110。
Python 处方库的 HerbRow 是两个自由文本 QLineEditmedicine_id 只会保留已有行上的值,新增行没有药材主数据选择:D:/web/zyt/app/src/doctor_workstation/ui/pages/prescription_library.py:76-110。结论:PARTIAL。
### 3.2 DaterangePicker
已开处方在 D:/web/zyt/admin/src/views/consumer/prescription/index.vue:19-23 使用。直接子组件默认 datetimerange,值格式 YYYY-MM-DD HH:mm:ss,并分别回写 start_time/end_timeD:/web/zyt/admin/src/components/daterange-picker/index.vue:1-48。
Python 没有日期范围控件:MISSING。
### 3.3 TcmDiagnosisEditView
已开处方异步加载 D:/web/zyt/admin/src/views/tcm/diagnosis/edit.vue,并在 diagnosis_id>0 时提供“查看患者诊单详情”:D:/web/zyt/admin/src/views/consumer/prescription/index.vue:566-574、1692-1693、1728、2910-2921。
直接调用 openViewOnly(id);子页面以同一套界面只读打开、加载 GET /tcm.diagnosis/detail {id},默认病历 tabD:/web/zyt/admin/src/views/tcm/diagnosis/edit.vue:1263-1264、1310-1322URL 见 D:/web/zyt/admin/src/api/tcm.ts:59-62。
该只读子页仍保留全套 tab 边界:
- 病历字段整体 disableddiagnosis/edit.vue:55-67。
- 医生备注 readonly、日常记录 read-only633-670。
- 处方 tab 受 tcm.diagnosis/chufang 控制且 read-only673-686。
- 业务订单受 tcm.diagnosis/patientOrders 控制:688-702。
- 视频回放、聊天、指派、挂号分别受 tcm.diagnosis/huifang、tcm.diagnosis/chat、tcm.diagnosis/assign 或 detail、doctor.appointment/lists 控制:704-758。
Python 已开处方没有 diagnosis_id 跳转或只读诊单子页:MISSING。
### 3.4 分页
两个管理端页面均通过 usePaging 自动发送 page_no/page_size,默认 page=1、size=15,并消费 count/lists/extendD:/web/zyt/admin/src/hooks/usePaging.ts:13-49。Python 两页均默认 page_size=20,使用 PageResult/Pager
- 处方库:D:/web/zyt/app/src/doctor_workstation/ui/pages/prescription_library.py:263-266、413-442。
- 已开处方:D:/web/zyt/app/src/doctor_workstation/ui/pages/prescriptions.py:84-89、284-316。
参数和总数分页机制 EXACT,默认每页条数 PARTIAL15 vs 20)。
## 4. 我的处方库:管理端真实合同
### 4.1 筛选、字段与状态
- 筛选:prescription_name、formula_type=主方|辅方、is_public=0|1,查询回第一页,重置为初始值:D:/web/zyt/admin/src/views/consumer/prescription/list.vue:5-31、247-252、281-284。
- 列表字段:id、prescription_name、formula_type、herbs.length、全部 herbs 的 name/dosage(g)、is_public、disable_edit、creator_name、create_timelist.vue:44-107。
- 公开范围:0=仅自己可见,1=所有人可见:list.vue:21-26、67-72、195-205。
- disable_edit:0=可修改,1=已禁用;真实语义是“导入到已开处方后锁定整张处方药材”,不是“禁止维护这条模板自身”:list.vue:74-79、208-220。
- 普通用户只管理本人 creator_idroot=1 或 role_ids 含 0、3 可管理任意模板:list.vue:276-301。
### 4.2 查看、创建、编辑、删除、复制
- 新增:独立按钮,表单字段为 prescription_namemaxlength=100)、formula_type、herbs、is_public、disable_editlist.vue:35-41、116-230、259-267。
- 查看:有单独 read 权限按钮,复用列表行数据打开完全禁用的表单;不调用 detaillist.vue:83-87、123-129、333-343。
- 编辑:仅 owner 或管理角色可见;仍可修改 disable_edit=1 模板本身的药材:list.vue:88-106、345-355。
- 删除:确认后 POST {id}list.vue:403-409。
- 复制:页面没有复制/克隆按钮、函数或端点。导入模板属于“已开处方”的复用流程,不是复制模板 CRUD。
- 导出/打印:本页面没有。
### 4.3 药材行和校验
- 药材 DTO{medicine_id?: number, name: string, dosage: number}list.vue:259-266。
- name 必须由 MedicineNameSelect 选取并同步 IDdosage 是 min=0、precision=1、step=0.5 的数字控件:list.vue:156-190。
- 提交要求:名称必填、至少一味药、每行 name 非空、dosage>0list.vue:269-274、357-379。
### 4.4 API DTO
页面调用来源见 list.vue:234-245URL 包装见 D:/web/zyt/admin/src/api/tcm.ts:591-615。
| 方法与端点 | 页面请求参数 / body | 页面使用情况 |
|---|---|---|
| GET /tcm.prescriptionLibrary/lists | page_no、page_size、prescription_name、formula_type、is_public | 列表与分页 |
| POST /tcm.prescriptionLibrary/add | prescription_name、formula_type、herbs、is_public、disable_edit;页面对象还带重置后的 id=0 | 新增 |
| POST /tcm.prescriptionLibrary/edit | id、prescription_name、formula_type、herbs、is_public、disable_edit | 编辑 |
| POST /tcm.prescriptionLibrary/delete | {id} | 删除 |
| GET /tcm.prescriptionLibrary/detail | {id} | API 已封装,但该 view 没有调用 |
权限码为 wcf.prescription/add、read、edit、deletelist.vue:36、85、93、102。
## 5. 我的处方库:Python 逐项对比
| 项目 | Python 证据 | 结论 |
|---|---|---|
| 页面入口 | shell.py:48-54 以 tcm.prescriptionLibrary/lists 注册;页面标题见 prescription_library.py:251-282 | EXACT |
| 筛选 | Python 有关键词、主/辅方、公开范围;repository 把 keyword 改成 prescription_name,把 main/aux 改为主方/辅方:prescription_library.py:284-315、413-429repository.py:279-298、586-588 | PARTIAL:请求合同基本一致,但“名称或药材”的占位文案(291)是假的,实际只查 prescription_name |
| 分页 | page/page_size 经 invoke 转 page_no/page_sizePager 消费总数:prescription_library.py:409-442widgets.py:221-223 | PARTIAL:默认 20,基准 15 |
| 列表字段 | Python 只显示名称、类型、最多 4 味摘要、公开范围、创建人、时间:prescription_library.py:357-384 | PARTIAL:缺 id、药材数量、完整药材、disable_edit;把 create_time 列标题写成“更新时间” |
| 单独查看 | 没有 read 按钮;双击只会走 _edit_selected,且需 edit 按钮可见及 owner/管理员:prescription_library.py:330-350、385-386、479-485 | MISSING |
| 新增 | _new_template -> save -> repository addprescription_library.py:474-501repository.py:309-323 | PARTIAL:端点可用,但药材和 disable_edit 语义不完整 |
| 编辑 | 使用列表行直接打开,与基准一样不请求 detail;保存到 editprescription_library.py:479-501repository.py:325-347 | PARTIAL |
| 删除 | owner/管理员检查、确认、POST {id}prescription_library.py:454-472、507-537repository.py:349-352 | EXACT |
| 公开范围 | 复选框产生 boolrepository 规范为 0/1prescription_library.py:157-159、218-228repository.py:572-575 | EXACT |
| disable_edit | Python 把它解释成“当前模板药材不可编辑”,隐藏增删并禁用输入;而管理端只在导入已开处方后锁药材。Python 也没有切换开关,只能原样回传:prescription_library.py:117-140、167-170、218-224 | PARTIAL(语义错误) |
| 药材选择 | 自由文本 name/dosage;新行无 medicine_id,已有行才保留:prescription_library.py:76-110 | PARTIAL |
| 药材校验 | 只检查至少一行、有名称时 dosage 非空:prescription_library.py:230-248 | PARTIAL:不校验数字和 >0,且允许“10g”字符串,与基准 number DTO 不同 |
| 所有权 | user id 相同、root、role 0/3prescription_library.py:460-472 | EXACT |
| API CRUD | list/detail/add/edit/delete 均存在且 URL、id 合同正确:repository.py:279-352 | EXACT(仓储层) |
| 模型 | PrescriptionTemplate 保留 id/name/formula/herbs/public/disable/creator/time/rawto_api_dict 正规化中文方型和 0/1core/models.py:426-477 | EXACT(字段合同) |
| 权限 | add/edit/delete 接受基准 wcf.*,同时接受 tcm.prescriptionLibrary/* 别名:prescription_library.py:274-279、332-347 | PARTIAL:动作基本受控,但缺 wcf.prescription/read 的可达只读查看;额外别名不是 view 基准 |
| 复制 | 两边都没有 | EXACT(负向) |
| 导出/打印 | 两边都没有 | EXACT(负向) |
## 6. 已开处方:管理端真实合同
### 6.1 筛选与分页 DTO
页面筛选控件见 D:/web/zyt/admin/src/views/consumer/prescription/index.vue:4-99;状态对象见 1874-1887
- sn:处方编号模糊查询。
- patient_name。
- creator_ids:医生 ID 多选;有值才发数组。
- audit_filterall、pending、passed、not_passed、rejectedall 被正规化为空字符串。
- source_filterall、manual、systemall 被正规化为空字符串。
- start_time/end_time:创建时间,格式 YYYY-MM-DD HH:mm:ss。
- 快捷日期:全部、今日、昨日、前天,切换后立即回第一页查询:index.vue:3013-3048。
最终 GET /tcm.prescription/lists 参数是 page_no、page_size 与上述字段;creator_ids 空数组会被省略:index.vue:2990-3007。默认 page_size=15。
### 6.2 列表字段、状态与可达动作
列表与按钮位于 index.vue:102-270
- 列:sn、id、订单一致性警告、prescription_type、is_system_auto1=空白处方,其他=手工)、patient_name/gender/age、综合审核状态和驳回意见、void_status、doctor_name/prescription_date、assistant_name、create_time。
- audit_status0 待审核、1 已通过、2 已驳回:index.vue:3113-3123。
- business_prescription_audit_rejected=1 时,列表主状态覆盖为“已驳回”,并分别展示业务订单与消费者处方的驳回意见:index.vue:3125-3151。
- void_status=1 单独显示“作废”。
- 已有关联业务订单时,药材为空或重名会在编号下给出警告:index.vue:3192-3216。
动作门槛:
- 查看:cf.prescription/read。
- 修正姓名/性别/手机:未作废且 tcm.prescription/patchPatient。
- 创建订单:has_prescription_order=0、未作废且 tcm.prescriptionOrder/create。
- 编辑、删除:只有“非 audit_status=1 且未作废”才出现,分别需 cf.prescription/edit、cf.prescription/del。
- 审核:audit_status=0、未作废且 cf.prescription/audit。
- 业务订单列表:tcm.prescriptionOrder/lists。
精确条件和权限见 index.vue:214-264;“已通过且未作废”判定见 3154-3157。
### 6.3 查看详情、打印与 PDF
查看先用列表行渲染,再 GET /tcm.prescription/detail {id} 覆盖:index.vue:3796-3817。
A4 处方笺显示:
- 来源、作废、消费者审核、业务订单审核及意见:index.vue:284-343。
- 日期/编号;患者姓名、性别、年龄、电话、收件信息、临床诊断:345-390。
- 主方/辅方药材,单剂 dosage 与 dose_count 计算后的总量:392-433。
- 主辅方用法、医嘱、忌口、备注、药房备注、出丸:435-448。
- 医师手写签名、医生、类型、天数/剂数、单剂量:450-481。
- 审核人、审核时间、审核意见:484-496。
打印调用 window.printindex.vue:2741-2751。PDF 用 html2canvas(scale=2) 渲染 A4,再由 jsPDF 分页并下载:index.vue:2753-2813。页面没有“列表导出 Excel”;tcm.ts:384-387 的业务订单导出 API 没有被此 view 导入或调用。
### 6.4 新增/编辑字段与药材规则
表单位于 index.vue:499-1153reactive DTO 在 2815-2862
- 关联/系统:id、diagnosis_id、creator_id、is_system_auto。
- 患者:patient_name、gender、age、visit_no、prescription_date。
- 四诊/诊断:tongue、tongue_image、pulse、pulse_condition、clinical_diagnosis。
- 药材:herbs[{medicine_id?, name, dosage, formula_type=主方|辅方, locked?}]。
- 剂型:prescription_type(浓缩水丸、饮片、颗粒、丸剂、散剂、膏方、汤剂)、dosage_amount、dosage_unit、dosage_bag_count、need_decoction、bags_per_dose、dose_count、dose_unit。
- 主方用法:usage_days、times_per_day、usage_instruction、usage_time、usage_way、dietary_taboo[]、usage_notes。
- 辅方用法 aux_usagedosage_amount、dosage_bag_count、need_decoction、bags_per_dose、times_per_day、usage_days、prescription_name。
- 医师:doctor_name、doctor_signature(手写 canvas 生成 PNG data URL,必填)。
- 隐藏状态:is_shared、visible_role_ids、audit_status/time/by/remark、业务订单审核字段。
主辅方各自使用 MedicineNameSelect 和数字 dosage;导入 disable_edit=1 模板时给行加 locked 并锁定整张处方药材:index.vue:667-813、3489-3515、3712-3732。
新增/编辑校验:
- patient_name、gender、prescription_date、clinical_diagnosis、dose_count、doctor_name、doctor_signature 必填:index.vue:2955-2988。
- 至少一味药,每行 name 非空、dosage>03920-3947。
- 新增提交前强制 audit_status=0add/edit 都把完整 editForm 展开为 body3951-3961。
- 编辑提示保存后重新进入待审核;已作废/已驳回可经编辑恢复,业务订单侧审核会重置:index.vue:514-565。
公开/共享范围的特殊事实:is_shared、visible_role_ids 虽存在于 editForm、详情回填和展开 payload2846-2847、3889-3890、3952),但模板区没有任何 v-model 控件;formatVisibleRoleNames 也未被模板调用(3348-3364)。因此该真实 view 不允许用户设置共享范围。桌面端不应凭字段存在擅自新增 UI。
### 6.5 处方库导入、粘贴导入与“复制”
- 从处方库导入对话框支持处方名称、主/辅方筛选、replace/append、10/15/20/50 分页,展示公开范围和创建人:index.vue:1539-1633。
- 请求 GET /tcm.prescriptionLibrary/lists,参数 page_no、page_size、prescription_name、formula_type、prescribing_creator_idindex.vue:3444-3468。
- prescribing_creator_id 取当前开方医生;语义是“该医生自己的模板 + 公共模板”。
- 粘贴导入解析 name/dosage,只接受 GET /doctor.medicine/lists 中 name 完全相同且唯一的药材;请求 name、page_no=1、page_size=200、status=1index.vue:3538-3709。
- replace 只替换同方型药材,append 追加;重复名仅警告。
该页面没有“复制某张已开处方”动作或端点。处方库导入与文本导入是新增/编辑中的填充方式,不等于复制已开处方。Python 也没有复制:EXACT(负向)。
### 6.6 审核联动
- POST /tcm.prescription/audit body={id, action:'approve'|'reject', remark}D:/web/zyt/admin/src/api/tcm.ts:365-372;调用见 index.vue:3367-3395。
- reject 必填 remark,成功语义为“驳回并作废处方”:index.vue:1669-1689、3373-3385。
- 返回 wecom_notify_ok=false 且有 wecom_notify_hint 时额外警告:3384-3388。
- 页面定义 root/role_ids 0、3 的审核角色辅助函数,但该函数没有被模板使用;真实按钮门槛仍是 v-perms cf.prescription/audit 加行状态:index.vue:1854-1855、247-253、3104-3110。
### 6.7 患者修正与订单联动
患者修正:
- 对话框只改 patient_name、gender、phone,明确不改审核状态,并记录到业务订单日志:index.vue:1155-1195。
- POST /tcm.prescription/patchPatient body={id,patient_name,phone,gender}index.vue:1948-1973API 类型见 tcm.ts:330-338。
订单读取与一致性:
- 编辑处方时 GET /tcm.prescriptionOrder/lists,参数 page_no=1、page_size=5、prescription_id,显示最近订单的 order_no、medication_days、remark_assistantindex.vue:769-811、2879-2907。
- 业务订单审核驳回可以覆盖处方列表状态和处方笺状态,但保留消费者处方本身的 audit_statusindex.vue:165-190、295-343、3125-3151。
从处方创建业务订单:
- 三步表单:诊单患者与收件信息;服务/发货/支付单;费用与备注:index.vue:1197-1537。
- 诊单患者远程搜索意图为 GET /tcm.diagnosis/searchPatient,参数 keyword、page_no=1、page_size=10index.vue:2384-2401API 定义在 D:/web/zyt/admin/src/api/order.ts:88-91。
- GET /tcm.prescriptionOrder/paidPayOrders {diagnosis_id} 返回可关联支付单和 deposit_min_amountindex.vue:2307-2329API 见 tcm.ts:389-398。
- POST /tcm.prescriptionOrder/create 的 body
prescription_id、diagnosis_id、recipient_name、recipient_phone、shipping_address、is_follow_up、prev_staff、service_channel、service_package(逗号拼接)、express_company、tracking_number、ship_mode、fee_type、amount、remark_extra、remark_assistant;可选 shipping_province/city/district、medication_days、internal_cost、pay_order_ids。证据:index.vue:2435-2485URL 见 tcm.ts:374-382。
- ship_mode 选择需 tcm.prescriptionOrder/setShipModeinternal_cost 需 finance.account_log/listsremark_extra 需 tcm.prescriptionOrder/editRemarkExtraindex.vue:1307-1314、1466-1488、2041-2043。
- 服务套餐来自 GET /config/dict {type:'server_order'}index.vue:2180-2187URL 见 D:/web/zyt/admin/src/api/app.ts:13-16。
## 7. 已开处方:Python 逐项对比
D:/web/zyt/app/src/doctor_workstation/ui/pages/prescriptions.py:1 已明确把本页定义为 “Read-only list and detail view for issued prescriptions”。这不是完整管理端主链。
| 项目 | Python 证据 | 结论 |
|---|---|---|
| 页面入口 | shell.py:55-61,以 tcm.prescription/lists 控制 | EXACT |
| 筛选 | 只有一个“编号/患者”关键词和 audit 0/1/2prescriptions.py:101-125、284-303 | PARTIAL |
| 请求映射 | repository 根据 RX/CF/纯数字猜 sn,否则 patient_namestatus 转 pending/passed/rejectedrepository.py:354-387 | PARTIAL:已有控件映射正确;缺 creator_ids、日期、source、not_passed;同一关键词不能同时查编号与患者 |
| 分页 | PageResult/Pager 完整 | PARTIAL:默认 20,基准 15 |
| 列表字段 | sn、patient、audit、source、doctor、prescription_dateprescriptions.py:139-180 | PARTIAL:缺 id、prescription_type、gender/age、业务/消费者驳回意见、void 独立列、assistant、create_time、订单警告 |
| 来源 | is_system_auto -> “系统代开/医生开具”:prescriptions.py:67-70 | PARTIAL:基准语义/文案是“空白处方/手工” |
| 状态 | 先作废,再业务订单驳回/消费者驳回,再通过/待审;raw fallback 可读模型未声明字段:prescriptions.py:46-60widgets.py:48-66 | PARTIAL:主标签逻辑接近,但不能分别显示两类驳回意见、审核人/时间和独立作废信息 |
| 详情请求 | 选中后 GET /tcm.prescription/detail {id}prescriptions.py:326-357repository.py:389-396 | EXACT(端点) |
| 详情字段 | 患者/性别/年龄、医生、日期、类型、剂数、药材/剂量/方型、频次/天数/方式/时间/忌口/说明和一条审核备注:prescriptions.py:360-420 | PARTIAL |
| A4 处方笺 | 无 A4 版式;缺电话/收件、临床诊断、签名、单味总量、药房备注/出丸、审核轨迹等 | MISSING |
| 新增 | 页面无按钮、无表单;RemoteRepository 无 prescription add 方法 | MISSING |
| 编辑 | 页面无按钮、无表单;缺主/辅方药材、剂型用法、签名、重新待审完整流程 | MISSING |
| 删除 | 无按钮;RemoteRepository 无 delete | MISSING |
| 患者修正 | 无 patchPatient UI/仓储方法 | MISSING |
| 审核 | 无 approve/reject UI/仓储方法;无驳回必填、作废联动、企微提示 | MISSING |
| 订单联动 | 无订单列表入口、创建订单、支付单关联、处方一致性警告、最近订单提示 | MISSING |
| 处方库导入 | 无新增/编辑,自然也没有 replace/append、锁药材、prescribing_creator_id | MISSING |
| 文本导入 | 无解析及药材完全同名验证 | MISSING |
| 药材编辑行 | 详情表只读;无 medicine_id 选择与 dosage 校验 | MISSING |
| 打印 | 无 window/Qt 打印等价能力 | MISSING |
| PDF | 无处方笺 PDF 导出 | MISSING |
| 列表 Excel | 基准页也没有 | EXACT(负向) |
| 复制已开处方 | 基准页也没有 | EXACT(负向) |
| 共享范围 UI | Python 不展示 is_shared/visible_role_ids;基准 view 也没有可见控件 | EXACT(只读 UI 的负向行为) |
| 共享字段模型 | Prescription 存 is_shared、visible_role_ids,但没有 mutationcore/models.py:519-521、574-576 | PARTIAL(数据保留) |
| 诊单详情联动 | 没有 diagnosis_id “查看诊单详情”和全 tab 只读子页 | MISSING |
| 动作权限 | 构造器保存 permissions 但页面没有任何 has_permission 动作判断:prescriptions.py:72-99 | MISSING(动作本身也缺) |
### 7.1 Python Prescription DTO 覆盖度
Prescription 模型保留绝大多数列表/详情核心字段:id、diagnosis、sn、患者、四诊、药材、剂型/主方用法、aux_usage、签名、creator/assistant、source/share/audit/void/order/create_time,并保留 rawD:/web/zyt/app/src/doctor_workstation/core/models.py:480-587。
结论:PARTIAL。
原因:
- 模型层比 UI 完整,但 UI 只消费很小子集。
- business_prescription_audit_rejected、business_prescription_audit_remark、收件/药房/出丸等不设显式 dataclass 字段,只能从 raw 兜底;get_value 确实支持 raw fallbackwidgets.py:48-66。
- RemoteRepository 只实现 GET lists/detailrepository.py:354-396;没有 add/edit/delete/patch/audit/order 的请求合同。
## 8. 权限码总表
### 8.1 我的处方库
| 能力 | 管理端真实码 | Python |
|---|---|---|
| 页面/列表 | 动态菜单实际值不能由 view 单独确定;接口是 tcm.prescriptionLibrary/lists | shell 固定 tcm.prescriptionLibrary/lists |
| 新增 | wcf.prescription/add | 接受 wcf.prescription/add 或 tcm.prescriptionLibrary/add |
| 查看 | wcf.prescription/read | MISSING |
| 编辑 | wcf.prescription/edit + owner/root/role 0,3 | 同时接受 wcf 或 tcm 别名 + 同一所有权规则 |
| 删除 | wcf.prescription/delete + owner/root/role 0,3 | 同时接受 wcf 或 tcm 别名 + 同一所有权规则 |
### 8.2 已开处方
管理端真实页面使用:
- cf.prescription/add、read、edit、audit、del。
- tcm.prescription/patchPatient。
- tcm.prescriptionLibrary/lists。
- tcm.prescriptionOrder/create、lists、setShipMode、editRemarkExtra。
- finance.account_log/lists。
- 诊单子页另用 tcm.diagnosis/chufang、patientOrders、huifang、chat、assign/detail 和 doctor.appointment/lists。
证据集中在 index.vue:102-117、214-264、667-680、1307-1314、1466-1488、1692-1728。
Python 只有页面入口 tcm.prescription/listsshell.py:55-61);PrescriptionsPage 没有上述动作,也没有动作权限判断。结论:MISSING。
## 9. 基准 view 自身的边界/风险(不计作 Python 差异)
1. 订单患者搜索在 index.vue:2391 调用 searchPatientsAPI,但 index.vue:1698-1714 的显式 import 没有该符号;真正 export 位于 api/order.ts:88-91。若工程没有为这个本地 API 符号做自动导入,远程患者搜索会失败。仅以 views 不能证明是否存在额外自动导入,故结论是“高风险未确认”,不是把不存在的合同补到 Python。
2. is_shared、visible_role_ids、roleAll、formatVisibleRoleNames 存在,但没有表单绑定;不要把死状态误判成可见“公开范围”功能。
3. userCanAudit() 定义了 root/role 0,3,但没有被模板调用;真实前端门槛是 cf.prescription/audit 和行状态,后端仍是最终边界。
4. prescriptionVoid API 虽在 tcm.ts:360-363 存在,但此 route 没有导入/直接调用;该页的可达作废路径是 audit reject 的服务端联动。
5. prescriptionOrderExport API 存在,但“已开处方” route 不调用;不能据此声称本页有 Excel 导出。
6. 两个基准页面均无“复制”能力。
## 10. P0 / P1 缺口
### P0
1. 已开处方主链整体缺失:新增、编辑、删除及其 RemoteRepository POST 合同均不存在。当前 Python 实现是明确的只读页,无法替代管理端真实路由。
2. 医疗安全关键编辑合同缺失:药材必须来自 MedicineNameSelect、主辅方和 locked 模板规则、dosage>0、剂型/用法、临床诊断、手写医生签名、编辑后重入待审,Python 全部不可达。
3. 审核/作废闭环缺失:approve/reject、驳回意见必填、reject 同时作废、两类审核意见、企微通知提示均不存在。
4. 订单联动缺失:患者修正、订单创建、支付单关联/定金门槛、发货模式权限、订单审核驳回覆盖状态、处方/订单药材一致性提示全部不存在。
5. 权限闭环缺失:已开处方除了列表入口没有任何 cf.prescription/*、patchPatient、prescriptionOrder/* 动作校验;在补动作前必须按基准精确落码,不能以 lists 权限兜底。
### P1
1. 已开处方列表筛选不完整:缺医生多选、创建时间/快捷日期、来源、not_passed;关键词还通过内容猜测 sn 或 patient_name。
2. 已开处方列表/详情展示不完整:缺业务订单警告、两类驳回意见、独立作废/审核轨迹、收件/电话、临床诊断、医生签名、药房备注/出丸及 A4 处方笺。
3. 已开处方缺打印和 A4 PDF 下载。
4. 已开处方缺 diagnosis_id 只读诊单子页及其权限化 tabs。
5. 处方库缺真正的 wcf.prescription/read 查看路径;只有有编辑权且可管理该行的用户能通过编辑对话框看完整内容。
6. 处方库药材行应改为药材远程选择与数字 dosage;当前自由文本允许合同无效值。
7. 处方库 disable_edit 语义错误且无切换开关:它应控制“导入后的已开处方药材锁定”,不应锁死模板自身编辑。
8. 处方库表格缺 id、药材数、完整明细、disable_edit,且时间列标题与数据不一致。
9. 两页默认 page_size 与基准不同(20 vs 15);属于低风险但可见的分页差异。
“复制”不是缺口:两个管理端基准页面均没有复制动作,Python 也没有。