Files
2026-09-08 11:40:15 +08:00

38 KiB
Raw Permalink Blame History

admin 医生端源码审计

审计日期:2026-08-10
参考项目:D:\web\zyt\admin
审计方式:只读检查 Vue/TypeScript 源码、API 封装、路由守卫、Pinia store、业务组件和权限判断;未修改 admin 项目,也未把 README 当作结论来源。

1. 结论摘要

  1. admin 是 Vue 3 + TypeScript + Vite + Element Plus + Pinia 项目。医生端并不是一套独立的静态路由:除登录、H5 诊单和只读诊单外,页面路径、标题、组件和菜单权限都由登录后 GET /adminapi/auth.admin/mySelf 返回的 menu 动态注入。
  2. 医生相关页面的全局状态很少。Pinia 只持有认证用户、权限、动态菜单、全局站点配置、布局与多标签;接诊台、处方、患者、问诊列表的查询条件和业务状态均保留在各页面的 ref/reactive 中,分页统一使用 usePaging。
  3. “患者列表”有两个不同实现:
    • 医生/一诊工作台的“我的患者”:src/views/first_visit/my_patients/index.vue,带患者、订单、面诊进度三个工作区,服务端按当前角色和部门数据范围收窄。
    • 平台注册用户列表:src/views/consumer/lists/index.vue,仅展示头像、昵称、账号、手机号、渠道和注册时间,不是医生业务患者工作台。
  4. “问诊列表”也有两个相关实现:
    • 挂号/问诊执行列表:src/views/tcm/appointment/list.vue,默认“今天 + 待接诊”,支持通话、视频二维码、完成、开方、取消。
    • 诊单/患者业务列表:src/views/tcm/diagnosis/index.vue,围绕诊单、挂号、确认、开方、医助指派、二维码和视频旁观。 最终菜单叫什么、URL 是什么取决于后端 menu 配置,不应仅根据文件名硬编码。
  5. 实际视频问诊主链是 src/components/chat-dialog/index.vue:腾讯云 Chat UIKit 单聊 + TUICallKit 音视频;通话前后还串联后端通话记录、TRTC 房间绑定、云端混流录制、可选浏览器本地录制、截屏写医生备注。src/components/video-call/index.vue 是另一套旧/独立实现,目前源码中没有被任何页面引用。
  6. 处方领域要区分三类对象:
    • 处方库模板:tcm.prescriptionLibrary,供医生复用药材组合。
    • 已开处方:tcm.prescription,处方笺、患者、医师签名、主辅方、审核与作废。
    • 处方业务订单:tcm.prescriptionOrder,收货、费用、双审、支付单、药房和物流履约;它不是支付单 zyt_order。

2. 关键源码与路由

2.1 页面定位

业务 关键源文件(绝对路径) 路由结论
登录 D:\web\zyt\admin\src\views\account\login.vue 静态精确路由 /login
接诊台 D:\web\zyt\admin\src\views\patient\reception\index.vue 动态菜单组件键应指向 patient/reception/index;实际 URL 取 menu[].paths
我的处方库 D:\web\zyt\admin\src\views\consumer\prescription\list.vue 动态菜单组件键应指向 consumer/prescription/list;实际 URL 取 menu[].paths
药品库(不是处方库) D:\web\zyt\admin\src\views\doctor\medicine.vue 动态菜单组件键应指向 doctor/medicine
已开处方/处方管理 D:\web\zyt\admin\src\views\consumer\prescription\index.vue 动态菜单组件键应指向 consumer/prescription/index
处方业务订单 D:\web\zyt\admin\src\views\consumer\prescription\order_list.vue 动态菜单组件键应指向 consumer/prescription/order_list
我的患者 D:\web\zyt\admin\src\views\first_visit\my_patients\index.vue 动态菜单组件键应指向 first_visit/my_patients/index
平台用户列表 D:\web\zyt\admin\src\views\consumer\lists\index.vue 动态菜单组件键应指向 consumer/lists/index
问诊/挂号列表 D:\web\zyt\admin\src\views\tcm\appointment\list.vue 动态菜单组件键应指向 tcm/appointment/list
诊单列表 D:\web\zyt\admin\src\views\tcm\diagnosis\index.vue 动态菜单组件键应指向 tcm/diagnosis/index;另有静态 H5 路由 /tcm/diagnosis/h5
诊单编辑/只读抽屉 D:\web\zyt\admin\src\views\tcm\diagnosis\edit.vue 被多个页面异步复用,不一定是独立菜单
患者只读详情 D:\web\zyt\admin\src\views\tcm\diagnosis\readonly.vue 静态精确路由 /tcm/diagnosis-readonly?id=诊单ID
预约视频问诊 D:\web\zyt\admin\src\views\tcm\diagnosis\appointment.vue 抽屉组件,由诊单列表/我的患者调用
诊间开方 D:\web\zyt\admin\src\components\tcm-prescription\index.vue 复用组件,由问诊列表和诊单编辑调用
聊天与视频问诊 D:\web\zyt\admin\src\components\chat-dialog\index.vue 浮动组件,由接诊台及问诊列表调用
医助视频旁观 D:\web\zyt\admin\src\views\tcm\diagnosis\components\AssistantWatchCallDialog.vue 诊单列表内异步组件

2.2 动态路由机制

关键文件:

  • D:\web\zyt\admin\src\router\routes.ts
  • D:\web\zyt\admin\src\router\index.ts
  • D:\web\zyt\admin\src\permission.ts
  • D:\web\zyt\admin\src\stores\modules\user.ts

流程:

  1. 常量路由只注册 /login、/403、/change-password、/bind-work-wechat、/user/setting、/doctor/progress、/tcm/diagnosis/h5 和 /tcm/diagnosis-readonly 等少数页面。
  2. 登录成功后 GET /auth.admin/mySelf。
  3. user store 保存 data.user、data.permissions,并把 data.menu 交给 filterAsyncRoutes。
  4. 每个后端菜单项使用以下字段转为 Vue Router:
    • paths:路由路径;
    • componentsrc/views 下的组件键;
    • name:菜单标题;
    • perms:写入 route.meta.perms
    • is_show:控制 meta.hidden
    • is_cache:控制 keepAlive
    • params:默认 query
    • selectedactiveMenu
    • type:目录或菜单。
  5. permission.ts 把转换后的路由动态挂到根布局;第一个可见菜单成为 / 的重定向目标。

因此,本仓库源码能确定组件和静态路由,但不能单独确定接诊台、处方库、已开处方、我的患者、问诊列表的生产 URL 与菜单标题。要得到精确值,必须取得当前环境 /auth.admin/mySelf 的 menu 响应或检查服务端菜单表。

3. 登录、认证、权限和状态管理

3.1 登录链路

关键文件:

  • D:\web\zyt\admin\src\views\account\login.vue
  • D:\web\zyt\admin\src\api\user.ts
  • D:\web\zyt\admin\src\stores\modules\user.ts
  • D:\web\zyt\admin\src\utils\request\index.ts
  • D:\web\zyt\admin\src\utils\auth.ts

账号密码:

  • POST /login/account
  • 请求:account、password、terminal=1。
  • 响应被页面使用的字段:token、is_paw、need_bind_work_wechat。
  • token 写入本地缓存键 token,后续请求通过请求拦截器放到 HTTP 头 token。
  • “记住账号”只缓存 account,不缓存密码,缓存键为 account。

企业微信:

  • GET /login/workWechatConfig,使用 enabled、corp_id、agent_id。
  • 企业微信内置浏览器走 OAuthscope=snsapi_privateinfo、state=admin_login。
  • 普通浏览器动态加载 https://wwcdn.weixin.qq.com/node/wework/wwopen/js/wwLogin-1.2.7.js 显示扫码登录。
  • 回调 code 通过 POST /login/workWechatLogin,参数 code、terminal=1。
  • 另有 POST /auth.admin/bindWorkWechat、POST /auth.admin/unbindWorkWechat。

守卫:

  • is_paw=0 强制跳转 /change-password,并通过 POST /login/changeFirstPassword 修改。
  • need_bind_work_wechat=true 强制进入 /bind-work-wechat。
  • 没有 token 的非白名单路由跳 /login?redirect=原地址。
  • /auth.admin/mySelf 没有任何有效菜单时清认证并跳 /403。
  • 响应码约定:1 成功、0 失败、-1 登录失效、10 需要绑定企微、2 打开新页面、-2 未安装。

3.2 Pinia 与页面状态

Store/Hook 文件 职责
user D:\web\zyt\admin\src\stores\modules\user.ts token、userInfo、routes、perms、isPaw;登录、退出、企微登录、加载个人信息
app D:\web\zyt\admin\src\stores\modules\app.ts 网站配置、OSS 图片地址、移动端/侧栏状态、视图刷新
tabs D:\web\zyt\admin\src\stores\modules\multipleTabs.ts 多标签与 keep-alive 缓存
setting D:\web\zyt\admin\src\stores\modules\setting.ts 本地布局、主题配置
usePaging D:\web\zyt\admin\src\hooks\usePaging.ts 页码、page_size、loading、count、lists、extend;支持 silent 静默刷新

列表接口统一期待服务端 data 为:

  • lists:当前页数组;
  • count:总数;
  • extend:额外统计、日期、权限范围等扩展数据。

页面内筛选和弹窗状态不进入 Pinia。这一约定适合桌面端复用:认证/权限做全局 store,业务工作台保持页面级 store 或 view-model。

3.3 权限判断语义

关键文件:

  • D:\web\zyt\admin\src\install\directives\perms.ts
  • D:\web\zyt\admin\src\utils\perm.ts

需要特别注意两套语义不同:

  • v-perms 数组是“任一权限命中即可显示”(OR)。
  • hasPermission 数组是“数组内每个权限都必须存在”(AND)。
  • permissions 含星号时视为全部权限。

多数业务调用只传单个权限,因此差异暂时不明显;复用时不要把多权限数组在两处互换。

4. 业务页面审计

4.1 接诊台

源码:

  • D:\web\zyt\admin\src\views\patient\reception\index.vue
  • D:\web\zyt\admin\src\api\patient.ts
  • D:\web\zyt\admin\src\views\tcm\diagnosis\components\PatientInfoCard.vue
  • D:\web\zyt\admin\src\views\tcm\diagnosis\components\PatientCaseCard.vue
  • D:\web\zyt\admin\src\views\tcm\diagnosis\components\DailyMatrix.vue
  • D:\web\zyt\admin\src\views\patient\reception\components\NoteTimeline.vue

页面行为:

  • 默认显示当天 status=1 待接诊;可切到 status=4 已过号。
  • 搜索字段 patient_name;分页 page_no/page_size,固定每页 15。
  • 每 5 秒静默刷新队列和已选患者详情;页面隐藏时暂停,恢复可见后立即刷新。
  • 队列使用无限滚动,并按 id 去重。
  • 队列行主要字段:id、patient_id、patient_name、patient_phone、diagnosis_id、doctor_id/name、assistant_id/name、appointment_date/time、gender、age、status/status_desc、has_prescription、remark。
  • 详情结构按源码使用为:
    • appointment:挂号;
    • diagnosis:诊单/病例;
    • doctor_notes:医生备注、舌苔和报告。
  • 日常记录不依赖 reception 响应完整下发,而由 DailyMatrix 继续按 diagnosis_id 调 trackingWindow/trackingNotes。

操作:

  • 通知医助:POST /doctor.appointment/notifyAssistant,参数 id=挂号ID。
  • 发起通话:先 POST /tcm.diagnosis/getCallSignature,参数 patient_id、diagnosis_id,再打开 ChatDialog。
  • 备注:POST /doctor.appointment/addDoctorNote,参数 diagnosis_id、content,可追加 tongue_images、report_files。
  • 编辑病历:复用 tcm/diagnosis/edit.vue。
  • 完成接诊:POST /doctor.appointment/complete,参数 id=挂号ID;页面允许 status=1 或 4。

权限:

  • doctor.appointment/addDoctorNote
  • tcm.diagnosis/edit
  • doctor.appointment/complete

源码中的“通知医助”和“发起通话”按钮没有 v-perms;只能依赖页面菜单权限和后端接口鉴权,桌面端若拆成独立入口应补显式能力判断。

4.2 我的处方库

源码:

  • D:\web\zyt\admin\src\views\consumer\prescription\list.vue
  • D:\web\zyt\admin\src\api\tcm.ts
  • D:\web\zyt\admin\src\components\medicine-name-select\index.vue

模型与筛选:

  • 查询:prescription_name、formula_type(主方/辅方)、is_public(0 仅自己、1 所有人)。
  • 列表:id、prescription_name、formula_type、herbs、is_public、disable_edit、creator_id/name、create_time。
  • herbs 项:medicine_id(可选)、name、dosage。
  • 编辑:id、prescription_name、formula_type、herbs、is_public、disable_edit。
  • disable_edit=1 表示导入模板后锁定整张处方的药材,不可增删改,只能再次导入覆盖。

接口:

  • GET /tcm.prescriptionLibrary/lists
  • POST /tcm.prescriptionLibrary/add
  • POST /tcm.prescriptionLibrary/edit
  • POST /tcm.prescriptionLibrary/delete,参数 id
  • GET /tcm.prescriptionLibrary/detail,参数 id(API 已封装,但当前列表弹窗直接使用行数据)

权限:

  • wcf.prescription/add
  • wcf.prescription/read
  • wcf.prescription/edit
  • wcf.prescription/delete

所有权:

  • 普通用户只可编辑/删除 creator_id 等于当前 userInfo.id 的模板。
  • root=1 或 role_ids 包含 0、3 可管理全部模板。
  • 诊间/已开处方导入模板时会额外传 prescribing_creator_id,通常取处方 creator_id,新增时取当前登录用户 id。

4.3 药品库(容易和处方库混淆)

源码:D:\web\zyt\admin\src\views\doctor\medicine.vue

接口:

  • GET /doctor.medicine/lists
  • POST /doctor.medicine/add
  • POST /doctor.medicine/edit
  • POST /doctor.medicine/delete
  • GET /doctor.medicine/detail

模型:

  • id、name、supplier、unit、settlement_price、retail_price、stock、image、status、remark。
  • 图片上传直接 POST 到 VITE_APP_BASE_URL + /api/upload/image,并携带 token 头。

当前页面的增删改按钮没有 v-perms。它是药材主数据管理,不应直接当作“我的处方库”复刻。

4.4 已开处方/处方管理

源码:

  • D:\web\zyt\admin\src\views\consumer\prescription\index.vue
  • D:\web\zyt\admin\src\components\tcm-prescription\index.vue
  • D:\web\zyt\admin\src\api\tcm.ts

列表筛选:

  • sn:处方编号模糊查;
  • patient_name
  • creator_ids:开方医师多选;
  • audit_filterall、pending、passed、not_passed、rejected
  • source_filterall、manual、system
  • start_time、end_time(按创建时间)。

列表核心字段:

  • id、sn、prescription_type
  • is_system_auto0 手工、1 空白处方/系统代开;
  • patient_name、gender、age、phone
  • audit_status、audit_remark、business_prescription_audit_rejected、business_prescription_audit_remark
  • void_status、void_by_name、void_time
  • doctor_name、creator_id、assistant_name、prescription_date、create_time
  • has_prescription_order。

处方编辑/详情模型:

  • 关联:id、diagnosis_id、creator_id。
  • 患者: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_signaturePNG data URL,保存前必填)。
  • 可见性/审核:is_shared、visible_role_ids、audit_status、audit_time、audit_by_name、audit_remark。

状态规则:

  • audit_status0 待审核、1 已通过、2 已驳回。
  • 驳回处方会同时作废。
  • “已通过且未作废”的有效处方不能普通编辑/删除。
  • 新增时前端强制 audit_status=0;编辑保存后提示重新进入待审核。
  • 诊间开方组件会保存 case_record 病历快照,并在已有 appointment_id 处方时直接进入只读查看。
  • 已存在业务订单时,诊间组件禁止作废处方。

主要接口:

  • GET /tcm.prescription/lists
  • GET /tcm.prescription/detail,参数 id
  • POST /tcm.prescription/add
  • POST /tcm.prescription/edit
  • POST /tcm.prescription/delete,参数 id
  • POST /tcm.prescription/patchPatient,参数 id、patient_name、phone、gender
  • POST /tcm.prescription/audit,参数 id、action=approve|reject、remark
  • POST /tcm.prescription/void,参数 id
  • GET /tcm.prescription/listByDiagnosis,参数 diagnosis_id
  • GET /tcm.prescription/getByAppointment,参数 appointment_id

权限:

  • cf.prescription/add、read、edit、audit、del
  • tcm.prescription/patchPatient
  • tcm.prescriptionLibrary/lists
  • tcm.prescriptionOrder/create、lists、setShipMode
  • finance.account_log/lists
  • tcm.prescriptionOrder/editRemarkExtra

角色补充:消费者处方页将 root 或 role_ids 0、3 视为可审核角色;仍应以后端和 cf.prescription/audit 为最终判定。

4.5 处方业务订单

源码:

  • D:\web\zyt\admin\src\views\consumer\prescription\order_list.vue
  • D:\web\zyt\admin\src\views\consumer\prescription\components\PrescriptionOrderDetailDrawer.vue
  • D:\web\zyt\admin\src\views\consumer\prescription\components\prescription-order-utils.ts

此页面是已开处方的相邻履约域。核心字段:

  • id、order_no、prescription_id、diagnosis_id
  • recipient_name、recipient_phone、region、shipping_address
  • fee_type、amount、internal_cost
  • prescription_audit_status、payment_slip_audit_status
  • fulfillment_status
  • linked_pay_order_count、linked_pay_order_id、linked_pay_paid_total
  • medication_days、service_channel、service_package
  • express_company、tracking_number、ship_mode
  • doctor_name、creator_id/name、assistant_id
  • remark_extra、remark_assistant
  • 药房提交号和状态。

审核状态统一为 0 待审核、1 已通过、2 已驳回。履约状态:

  • 1 待双审通过
  • 2 待发货
  • 3 已完成
  • 4 已取消
  • 5 已发货
  • 6 已签收
  • 7 进行中
  • 8 暂不制药
  • 9 拒收
  • 10 退款
  • 11 保留药方
  • 12 制药缓发

核心接口:

  • GET /tcm.prescriptionOrder/lists、detail、paidPayOrders、logs、logisticsTrace、export
  • POST /tcm.prescriptionOrder/create、edit、withdraw、ddcode
  • POST /tcm.prescriptionOrder/auditPrescription、auditPayment、revokeRxAudit、revokePayAudit
  • POST /tcm.prescriptionOrder/ship、complete、refund、requestCompletion
  • POST /tcm.prescriptionOrder/addPayOrder、linkPayOrder
  • POST /tcm.prescriptionOrder/patchPrescriptionPatient、patchPrescriptionUsage、updateAmount
  • POST /tcm.prescriptionOrder/setShipMode、uploadToPharmacy
  • POST /tcm.prescriptionOrder/submitGancaoRecipel、previewGancaoRecipel、confirmGancaoSubmission
  • POST /tcm.prescriptionOrder/batchAssignAssistant、addLog

主要权限:

  • tcm.prescriptionOrder/detail、edit、export、ddcode、ship、addPayOrder、complete、refund、withdraw
  • tcm.prescriptionOrder/auditPrescription、auditPayment
  • tcm.prescriptionOrder/setShipMode、uploadToPharmacy、editRemarkExtra
  • finance.account_log/lists、prescription.order/finance

前端还存在角色级显示规则:

  • role 2:医助;
  • role 6:下单角色;
  • role 3、8:下单筛选豁免;
  • role 0、3、6:财务字段;
  • role 0、3:可绕过双审后的创建人编辑锁、可批量改派;
  • 业务订单处方审核角色在共享工具中为 0、3、6。

这些数字与服务端配置耦合,不宜在新客户端再次散落硬编码。

4.6 我的患者

首选医生端实现:

  • D:\web\zyt\admin\src\views\first_visit\my_patients\index.vue
  • D:\web\zyt\admin\src\api\first_visit.ts

页面结构:

  • “患者列表”“订单管理”“面诊进度”三个工作区。
  • 筛选 keyword、status_filter、start_date、end_date。
  • status_filterunbooked 未预约、pending_interview 待面诊、completed 已完成、missed 已过号。
  • 日期快捷:今天、明天、后天、近 7 天、近 30 天、自定义。
  • extend.summary 返回 today/tomorrow/day_after 计数。
  • extend.dates 返回对应日期。
  • extend.scope.label 直接展示后端判定的数据范围。

列表使用字段:

  • diagnosis_id 或 id、source_patient_id
  • patient_name、gender_desc、age、phone_masked、has_id_card
  • assistant_id/name
  • appointment_id、appointment_doctor_id/name、appointment_status、appointment_status_text、appointment_time_text
  • revisit_count、confirmed、confirmation_text、diagnosis_date_text。

操作与接口:

  • GET /firstvisit.myPatient/lists
  • GET /firstvisit.myPatient/assistants
  • POST /firstvisit.myPatient/assignid、assistant_id、is_inherit=0|1
  • POST /firstvisit.myPatient/fillIdCardid、id_card
  • POST /firstvisit.myPatient/createAppointment:预约完整参数
  • POST /firstvisit.myPatient/cancelAppointmentid=挂号ID
  • 订单工作区另使用 /firstvisit.myPatient/orders、orderDetail、orderEdit 及双审/发货/退款等受限代理接口。
  • 面诊进度使用 GET /firstvisit.myPatient/progress。

权限:

  • tcm.diagnosis/edit
  • tcm.diagnosis/readonlyDetail
  • tcm.diagnosis/guahao
  • tcm.diagnosis/assign

服务端按当前角色与部门范围裁剪数据;前端不自行拼接 doctor_id 或 department_id 来模拟数据权限。

平台用户列表 D:\web\zyt\admin\src\views\consumer\lists\index.vue 使用 GET /user.user/lists,字段是 avatar、nickname、account、mobile、channel、create_time,只适合账号管理,不适合医生患者列表。

4.7 问诊/挂号列表

源码:

  • D:\web\zyt\admin\src\views\tcm\appointment\list.vue
  • D:\web\zyt\admin\src\api\doctor.ts

默认条件:

  • status=1 待接诊;
  • start_date=end_date=今天;
  • date_preset=today
  • 20 秒静默轮询;
  • include_status_counts=1 时从 extend.status_count 一次返回各状态角标。

状态:

  • 1 待接诊/已预约
  • 2 已取消
  • 3 已完成
  • 4 已过号

筛选:

  • patient_name、doctor_name
  • status
  • start_date、end_date、date_preset
  • diagnosis_confirmed
  • assistant_dept_id(选父部门含子级)。

行字段:

  • id、patient_id、diagnosis_id
  • patient_name、patient_phone、gender、age、height、weight
  • doctor_id/name、assistant_name
  • appointment_date、appointment_time、period
  • diagnosis_confirmed
  • has_prescription、prescription_is_system_auto、prescription_audit_status、prescription_void_status
  • status/status_desc、remark。

操作:

  • 编辑患者:复用诊单编辑抽屉。
  • 视频二维码:生成小程序码。
  • 通话:获取签名并打开 ChatDialog。
  • 完成:POST /doctor.appointment/complete,可同时 POST addDoctorNote。
  • 开方/查看:复用 TcmPrescription;有效已审核处方显示“查看”。
  • 取消:POST /doctor.appointment/cancel。

权限:

  • tcm.diagnosis/edit
  • tcm.diagnosis/videoQr
  • doctor.appointment/prescription
  • doctor.appointment/complete
  • tcm.diagnosis/kaifang
  • doctor.appointment/cancel
  • doctor.appointment/addDoctorNote(完成时备注能力)

角色判断:role_id 为 1 医生、2 医助;两者之外才显示医生姓名筛选。此处同时兼容 role_id 单值或数组,但其他页面多使用 role_ids,说明 user 模型尚未完全统一。

4.8 诊单列表

源码:

  • D:\web\zyt\admin\src\views\tcm\diagnosis\index.vue
  • D:\web\zyt\admin\src\views\tcm\diagnosis\edit.vue
  • D:\web\zyt\admin\src\views\tcm\diagnosis\readonly.vue

列表筛选字段:

  • keyword、diagnosis_type、syndrome_type、assistant_id
  • diagnosis_confirmed、appointment_date、has_appointment
  • latest_appointment_start_date/end_date/channel_source
  • latest_assign_start_date/end_date
  • pending_booking、completed_appointment、pending_assign
  • pending_assign_order_month、pending_assign_keyword
  • sort_unserved_days。

列表使用字段:

  • id、patient_name、gender_desc、age
  • assistant_id/assistant、assign_read_at
  • appointments 或聚合的 appointment_doctor_name、appointment_time_text、appointment_status
  • has_appointment、diagnosis_confirmed
  • has_prescription、followup_time_text、followup_doctor_name、followup_rx_voided
  • unserved_days、last_blood_record_at
  • video_call_hint。

video_call_hint

  • statenone、pending_room、live 等;
  • label
  • start_time、end_time。

操作权限:

  • tcm.diagnosis/add、edit、delete、readonlyDetail
  • tcm.diagnosis/assign
  • tcm.diagnosis/kaifang
  • tcm.diagnosis/guahao、guahaoLogList
  • tcm.diagnosis/videoQr
  • tcm.diagnosis/order
  • tcm.diagnosis/watchCall

诊单编辑模型的核心字段:

  • 标识:id、patient_id。
  • 患者:patient_name、id_card、phone、gender、age、marital_status、height、weight、region。
  • 诊断:diagnosis_date、diagnosis_type、syndrome_type、diabetes_type、diabetes_discovery_year、local_hospital_diagnosis、local_hospital_name。
  • 指标:systolic_pressure、diastolic_pressure、fasting_blood_sugar。
  • 现病史多选:appetite、water_intake、diet_condition、weight_change、body_feeling、sleep_condition、eye_condition、head_feeling、sweat_condition、skin_condition、urine_condition、stool_condition、kidney_condition、fatty_liver_degree。
  • 既往史:past_history、trauma_history、surgery_history、allergy_history、family_history、pregnancy_history。
  • 医疗内容:symptoms、tongue_coating、pulse、treatment_principle、prescription、doctor_advice、remark、current_medications。
  • 归属与来源:assistant_id、status、create_source、show_card、external_userid。

详情响应还使用 patient_basic_locked、can_edit_patient_basic、latest_prescription_order。手机号/身份证是否显示明文由 tcm.diagnosis/phonePlain 控制;已有身份证通常只有明文权限才能修改。

诊单详情 Tab 权限:

  • tcm.diagnosis/chufang:处方
  • tcm.diagnosis/patientOrders:业务订单
  • tcm.diagnosis/huifang:视频回放
  • tcm.diagnosis/chat:聊天记录
  • tcm.diagnosis/assign 或 detail:指派记录
  • doctor.appointment/lists:挂号记录
  • tcm.diagnosis/dailyRecord:日常记录

5. 视频问诊完整链路

5.1 预约

源码:D:\web\zyt\admin\src\views\tcm\diagnosis\appointment.vue

目前预约类型只有 video。请求字段:

  • patient_id
  • doctor_id
  • appointment_date
  • period=all
  • appointment_time
  • appointment_type=video
  • remark
  • channel_source
  • channel_source_detail

普通入口 POST /doctor.appointment/create;“我的患者”入口 POST /firstvisit.myPatient/createAppointment。可用时段来自 GET /doctor.appointment/availableSlots,字段 doctor_id、appointment_date、period=all,响应使用 slots[].time、slots[].available。页面还读取医生排班并限制不能重复预约当天 status=1/4 的号。

5.2 医生发起通话

生产主组件D:\web\zyt\admin\src\components\chat-dialog\index.vue

  1. 页面调用 open({ patientId, patientName, diagnosisId })。
  2. POST /tcm.diagnosis/getCallSignature,请求 patient_id、diagnosis_id。
  3. 响应实际使用:
    • sdkAppId
    • userId(医生 IM/TRTC user ID
    • userSig
    • patientUserId,缺省回退 patient_加患者ID
    • assistant_id(群视频邀请)
    • isLochostVod(是否启用浏览器本地录制)
  4. Chat UIKit 登录并创建与 patientUserId 的 C2C 会话。
  5. TUICallKitServer.init 初始化通话能力;只有成功后才显示 AudioCallPicker、VideoCallPicker 和群视频按钮。
  6. beforeCalling 时 POST /tcm.diagnosis/startCall
    • diagnosis_id
    • patient_id
    • call_type=2(视频)
  7. 呼叫状态进入 calling/connected 后从 TUIStore 或 TUICallEngine 捕获 roomID/strRoomID,再 POST /tcm.diagnosis/bindCallRoom
    • diagnosis_id
    • room_id(字符串)
  8. bindCallRoom 的响应可带 cloud_recording.started、task_id、message;源码注释说明后端在这里触发腾讯云 CreateCloudRecording,混流模式由后端负责。
  9. 接通后,若 isLochostVod=true,前端从 TUICallKit 视频元素启动 MediaRecorder/Canvas 本地录制。
  10. 通话结束、挂断、IM 自定义挂断消息或用户关闭窗口时先 POST /tcm.diagnosis/endCall,再完成本地视频上传并 POST attachLocalCallRecording。

群视频调用 TUICallKitServer.callsuserIDList=[patientUserId, assistant_id]type=VIDEO_CALL。

5.3 截屏、录制与回放

关键文件:

  • D:\web\zyt\admin\src\utils\call-local-recorder.ts
  • D:\web\zyt\admin\src\utils\call-video-screenshot.ts
  • D:\web\zyt\admin\src\views\tcm\diagnosis\components\CallRecordPanel.vue
  • D:\web\zyt\admin\src\views\tcm\diagnosis\components\RecordingPlaybackBlock.vue

视频浮窗“截屏”会:

  1. 抓取当前 video frame
  2. 上传图片;
  3. POST /doctor.appointment/addDoctorNote,把路径追加到 tongue_images。

通话记录字段:

  • id、call_type(1 语音、其他视为视频)
  • room_id
  • status:1 进行中、2 已结束、3 未接听、4 已取消
  • recording_status_text
  • recording_urls_list
  • start_time_text、end_time_text、duration_text

接口:

  • GET /tcm.diagnosis/getCallRecordsdiagnosis_id
  • POST /tcm.diagnosis/attachLocalCallRecordingdiagnosis_id、file_url、可选 call_record_id
  • POST /tcm.diagnosis/createManualCallRecorddiagnosis_id
  • POST /tcm.diagnosis/startCloudRecordingdiagnosis_idAPI 有封装,主组件当前通过 bindCallRoom 的后端联动启动)

5.4 医助旁观

入口在诊单列表。只有同时满足:

  • 当前 userInfo.id 等于该诊单 assistant_id
  • 拥有 tcm.diagnosis/watchCall
  • video_call_hint.state=live

才可真正进入。

GET /tcm.diagnosis/watchCall,参数 diagnosis_id,响应使用:

  • sdkAppId
  • userId
  • userSig
  • roomId 或 strRoomId
  • patientName

旁观组件直接使用 trtc-sdk-v5 进入房间,只调用 startRemoteVideo,不开启本地摄像头或麦克风。pending_room 时显示入口提示但点击会阻止进入,等待房间号同步。

5.5 视频二维码

页面通过 POST /tcm.diagnosis/generateMiniProgramQrcode 生成 qrcode_url,常用字段:

  • diagnosis_id
  • patient_id
  • doctor_id(部分入口)
  • share_user_id
  • mini_program_path=pages/login/login(问诊列表入口)

调用前先 GET 小程序配置并校验 app_id。

6. API 总表

所有 URL 会被请求层加上 baseUrl 和 adminapi 前缀;下表写的是 API 封装中的业务路径。

6.1 认证

方法 路径 关键请求/响应
POST /login/account account、password、terminal;返回 token、is_paw、need_bind_work_wechat
POST /login/workWechatLogin code、terminal;返回同登录结果
GET /login/workWechatConfig enabled、corp_id、agent_id
GET /auth.admin/mySelf 返回 user、permissions、menu
POST /login/logout 退出
POST /login/changeFirstPassword password、password_confirm
POST /auth.admin/bindWorkWechat code

6.2 挂号与接诊

方法 路径 关键字段
GET /doctor.appointment/lists status、start_date、end_date、patient_name、doctor_name、diagnosis_confirmed、assistant_dept_id、page_no、page_size
GET /doctor.appointment/reception id=挂号ID;返回 appointment、diagnosis、doctor_notes
GET /doctor.appointment/detail id
GET /doctor.appointment/availableSlots doctor_id、appointment_date、period
POST /doctor.appointment/create patient_id、doctor_id、appointment_date/time、appointment_type、渠道等
POST /doctor.appointment/cancel id
POST /doctor.appointment/complete id
POST /doctor.appointment/notifyAssistant id
POST /doctor.appointment/addDoctorNote diagnosis_id、content、tongue_images、report_files
GET /doctor.appointment/doctorNotes diagnosis_id
POST /doctor.appointment/deleteDoctorNoteImage note_id、image_type、image_path

6.3 诊单

方法 路径 关键字段
GET /tcm.diagnosis/lists 诊单列表全部筛选 + page_no/page_size;返回 lists/count/extend
GET /tcm.diagnosis/detail id
GET /tcm.diagnosis/readonlyDetail id;返回 appointment、diagnosis、unserved_days、last_blood_record_at、doctor_notes
POST /tcm.diagnosis/add 完整诊单模型
POST /tcm.diagnosis/edit 完整诊单模型
POST /tcm.diagnosis/delete id
POST /tcm.diagnosis/assign id、assistant_id、可选 is_inherit;批量场景由前端逐条调用
GET /tcm.diagnosis/getAssistants 医助选项
GET /tcm.diagnosis/getDoctors 医生选项
POST /tcm.diagnosis/checkPhone phone 及排除 id
POST /tcm.diagnosis/checkIdCard id_card 及排除 id
POST /tcm.diagnosis/fillIdCard id、id_card
GET /tcm.diagnosis/trackingWindow id、start_date、end_date
GET /tcm.diagnosis/trackingNotes diagnosis_id
POST /tcm.diagnosis/addTrackingNote diagnosis_id、tracking_content

6.4 处方与业务订单

处方、处方库、业务订单接口已在 4.2、4.4、4.5 分节完整列出。实现时必须保留三个资源命名空间,不要把 prescription、prescriptionLibrary、prescriptionOrder 合并成一个“处方”接口。

6.5 视频

方法 路径 关键字段
POST /tcm.diagnosis/getCallSignature patient_id、diagnosis_id;返回 sdkAppId、userId、userSig、patientUserId、assistant_id、isLochostVod
POST /tcm.diagnosis/startCall diagnosis_id、patient_id、call_type
POST /tcm.diagnosis/bindCallRoom diagnosis_id、room_id
POST /tcm.diagnosis/startCloudRecording diagnosis_id
POST /tcm.diagnosis/endCall diagnosis_id
GET /tcm.diagnosis/getCallRecords diagnosis_id
POST /tcm.diagnosis/attachLocalCallRecording diagnosis_id、file_url、可选 call_record_id
POST /tcm.diagnosis/createManualCallRecord diagnosis_id
GET /tcm.diagnosis/watchCall diagnosis_id
POST /tcm.diagnosis/generateMiniProgramQrcode diagnosis_id、patient_id、doctor_id、share_user_id 等

7. 可复用约定

  1. 请求协议

    • baseURL 来自 VITE_APP_BASE_URL,统一 URL 前缀 adminapi。
    • token 放在名为 token 的请求头,不是 Bearer Authorization。
    • POST 默认把 params 转为 bodyGET 使用 params。
    • 标准成功响应是 code=1,业务数据自动解包为 data。
    • GET 网络失败默认最多重试 2 次,POST 不自动重试。
  2. 列表协议

    • 请求 page_no、page_size。
    • 响应 lists、count、extend。
    • 定时刷新使用 getLists({ silent: true }),避免表格白屏闪烁。
  3. 标识约定

    • diagnosis_id 是诊单主键。
    • appointment.id 是挂号主键。
    • prescription.id 是处方主键。
    • prescriptionOrder.id 是处方业务订单主键。
    • patientUserId 是腾讯云 IM/TRTC 用户名,通常 patient_加患者标识。
  4. 隐私

    • 默认手机号 3-4-4 脱敏,身份证保留前 6 后 4。
    • tcm.diagnosis/phonePlain 控制诊单编辑中的明文能力。
    • 数据范围由后端按角色、部门、归属医助裁剪,前端只做 UI 能力门控。
  5. 复用组件

    • 患者摘要/病例:PatientInfoCard、PatientCaseCard。
    • 日常记录:DailyMatrix。
    • 医生备注:NoteTimeline。
    • 诊单编辑和只读:tcm/diagnosis/edit.vue 的 open、openViewOnly。
    • 处方开立/查看:TcmPrescription 的 open、openById。
    • 视频通讯:ChatDialog 的 open。
    • 业务订单详情:PrescriptionOrderDetailDrawer。
  6. 状态文本

    • 不建议在新客户端重复定义状态映射。优先抽取 D:\web\zyt\admin\src\views\consumer\prescription\components\prescription-order-utils.ts 中的审核、履约、支付、供货和物流格式化逻辑为共享领域模块。

8. 未知点、歧义与风险

  1. 动态菜单缺口:admin 前端仓库没有生产环境 /auth.admin/mySelf 的 menu 数据,因此接诊台、处方库、患者、问诊列表的精确 URL、菜单标题和页面级 route.meta.perms 仍未知。
  2. API 类型不足:tcm.ts、doctor.ts 多数参数和返回值是 any;本文列出的响应字段来自实际页面读取,不等于完整服务端 schema。后续实现应抓取真实响应或检查服务端 DTO。
  3. patient_id 语义有重载:
    • 挂号行中 patient_id 常被当作诊单/患者标识;
    • 我的患者 openAppointment 又把 diagnosis_id 或 id 同时写进 id 和 patient_id
    • ChatDialog 则把它转换为 patient_前缀的腾讯云用户。 新客户端必须先确认数据库实体关系,不能只按字段名推断。
  4. 接诊台发起通话使用 diagnosis_id || row.idrow.id 本身是挂号 ID。若后端要求真正诊单 ID,这个回退可能只在特定历史数据下成立。
  5. 视频二维码参数疑点:tcm/appointment/list.vue 的一个入口把 diagnosis_id 赋为 row.doctor_id,而其他入口使用真正诊单 ID;这很可能是历史兼容或缺陷,应向后端核实后再复用。
  6. 权限命名不统一:
    • 处方库用 wcf.prescription/*
    • 已开处方用 cf.prescription/*
    • 新增能力又混用 tcm.prescription/* 与 tcm.prescriptionOrder/*。 不能按字符串前缀自动推导资源。
  7. 角色配置存在差异:
    • 消费者处方审核页面写死 0、3
    • 业务订单共享工具写死 0、3、6
    • 多处注释都声称与服务端配置一致。 最终角色应由服务端下发 capability,避免继续硬编码。
  8. 权限 UI 不是安全边界:部分接诊、药品和通话按钮没有 v-perms;所有写接口必须继续依赖服务端鉴权。
  9. 双 SDK 并存:
    • 实际 ChatDialog 使用 @tencentcloud/call-uikit-vue
    • 未引用的 video-call/index.vue 使用 @trtc/calls-uikit-vue
    • 医助旁观直接使用 trtc-sdk-v5。 新项目应明确只保留一套主叫/被叫 UI SDK,并将纯 TRTC 旁观作为独立只拉流能力。
  10. src/components/video-call/index.vue 当前没有被任何 Vue/TS 源码引用,不应误认为生产主链。
  11. PatientCaseCard 的 caseTypeLabel 无论 consultation_type 都返回“复诊”,属于明显展示逻辑疑点。
  12. 录制启动/停止部分依赖 TUICallKit 内部 store、引擎属性和方法包装,升级腾讯云 SDK 时风险较高,必须用真实双端通话、拒接、对端挂断、网络中断和房间号延迟场景回归。
  13. 处方业务订单大量前端角色规则与 server/config/project.php 注释耦合;当前审计范围只有 admin 前端,无法验证服务端配置是否已同步。

9. 面向新医生端的建议映射

若新项目要复刻医生工作流,建议按领域而不是按现有目录命名:

  • /login:复用认证协议和企业微信登录。
  • /reception:复用接诊台队列、详情、5 秒静默刷新与 ChatDialog。
  • /prescription-library:复用 prescriptionLibrary 模板及所有权规则。
  • /prescriptions:复用 tcm.prescription 列表、审核、作废、打印/下载。
  • /patients:优先复用 firstvisit.myPatient,而不是 user.user/lists。
  • /consultations:复用 doctor.appointment/lists 的今天待接诊视图。
  • /diagnoses:复用 tcm.diagnosis/lists 的完整诊单工作台。
  • /video-consultation:主叫链路复用 ChatDialog/TUICallKit;医助旁观保持独立 TRTC 只拉流组件。

这些建议 URL 是新端的信息架构建议,不是对 admin 当前动态 URL 的断言。