# 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:路由路径; - component:src/views 下的组件键; - name:菜单标题; - perms:写入 route.meta.perms; - is_show:控制 meta.hidden; - is_cache:控制 keepAlive; - params:默认 query; - selected:activeMenu; - 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。 - 企业微信内置浏览器走 OAuth,scope=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_filter:all、pending、passed、not_passed、rejected; - source_filter:all、manual、system; - start_time、end_time(按创建时间)。 列表核心字段: - id、sn、prescription_type; - is_system_auto:0 手工、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_usage:dosage_amount、dosage_bag_count、need_decoction、bags_per_dose、times_per_day、usage_days、prescription_name(部分页面保留模板名)。 - 医师:doctor_name、doctor_signature(PNG data URL,保存前必填)。 - 可见性/审核:is_shared、visible_role_ids、audit_status、audit_time、audit_by_name、audit_remark。 状态规则: - audit_status:0 待审核、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_filter:unbooked 未预约、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/assign:id、assistant_id、is_inherit=0|1 - POST /firstvisit.myPatient/fillIdCard:id、id_card - POST /firstvisit.myPatient/createAppointment:预约完整参数 - POST /firstvisit.myPatient/cancelAppointment:id=挂号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: - state:none、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.calls,userIDList=[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/getCallRecords,diagnosis_id - POST /tcm.diagnosis/attachLocalCallRecording,diagnosis_id、file_url、可选 call_record_id - POST /tcm.diagnosis/createManualCallRecord,diagnosis_id - POST /tcm.diagnosis/startCloudRecording,diagnosis_id(API 有封装,主组件当前通过 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 转为 body;GET 使用 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.id;row.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 的断言。