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

28 KiB
Raw Blame History

“我的处方库 / 已开处方”桌面端对齐审计

审计日期: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 也没有。