山东大学软件学院创新实训(八)
2026/6/3 16:12:02 网站建设 项目流程

前言

阶段七把住院桥接与智能辅助 UI 收成可演示闭环。阶段八转向门诊侧数据可信度与档案治理:开放医疗数据导入后,医生/患者分布失衡、演示账号缺少实习 、 假期 、 停职等真实场景;删除医生档案时患者病历里的接诊医生会消失;列表默认排序把停职案例 but 案例挤到末页看不见;删除接口还因 Pydantic 字段别名报 ValidationError。

本阶段做四件事:演示数据管线与再平衡、在班状态与预约门控、档案列表体验与锁定规则、删除拦截 + 病历医生姓名快照。不新增菜单,核心是工具脚本、服务层校验、ORM/SQL 增量与前端表格/抽屉微调。下文按「问题—根因—改法—联调与踩坑」写,并标注建议配图位置。


目录(仅供提示)

  1. 背景与阶段八目标
  2. 开放数据导入与门诊再平衡
  3. 特殊医师种子:实习 / 假期 / 停职
  4. 在班状态与患者预约门控
  5. 档案列表默认排序与停职可见性
  6. 档案修改权限:谁可以改、谁只读
  7. 删除医生档案:ValidationError 与临床引用拦截
  8. 病历接诊医生追溯:姓名快照与多级回退
  9. 增量 SQL 与脚本清单
  10. 本地验证与踩坑
  11. 结语与下阶段排期

1. 背景与阶段八目标

业务上: 带教演示需要实习跟师、假期不可约、停职冻结档案、患者病历永远能查到接诊医生。若停职账号藏在列表最后一页、或删档案后病历医生列空白,演示说服力会大打折扣。

工程上:

模块关键路径

数据导入

scripts/clinical_import/pipeline.py

医生再平衡

scripts/rebalance_clinic_doctors.py

时间线美化

scripts/realistic_case_timeline.py

特殊医师种子

scripts/seed_intern_doctors.py

在班工具

module_clinic/utils/doctor_duty_util.py

列表排序

module_clinic/utils/list_sort_util.py

姓名解析

module_clinic/utils/doctor_display_util.py

删除拦截

med_clinic_doctor_service.py

病历快照

med_case_service.py+med_case_do.py

增量 SQL

upgrade_doctor_clinic_status.sqlupgrade_med_case_doctor_name_snapshot.sql

本阶段交付:

验收方式

开放数据导入

pipeline.py import-clinical可写入病历/知识库

医生患者均衡

再平衡脚本后各科室医生均有病例、患者

特殊账号

6 实习 + 2 假期 + 2 停职,密码admin123

在班门控

停职/假期/离院不可预约;实习默认可约

列表排序

医生:在班→状态→科室→专家→姓名;患者:最近就诊→更新时间

停职可见

末页自动滚动 +「仅看停用」快捷筛选

档案锁定

停用/离院/暂停执业只读;假期/实习可改

删除拦截

有病历/处方/预约则拒绝删除,提示改用停用

医生追溯

病历doctor_name快照 + 列表/导出/抽屉展示


2. 开放数据导入与门诊再平衡

2.1 现象

a. 导入开放数据集后,病历集中在少数账号(如doctor_wang),其他科室医生列表空荡。
b. 就诊时间扎堆同一天,现病史像模板填空,不像真实门诊节奏。
c. 演示时切换医生账号,候诊/我的患者对不上。

2.2 根因

CPMI / 天池等开放数据未与本地med_clinic_doctor映射;缺少分科室建号与病例再分配脚本;就诊日未打散。

2.3 改法

导入流水线(scripts/clinical_import/):

命令说明

pipeline.py verify

检查数据源与 DB 连通

import-kb

知识库 QA 入库

import-clinical --limit N

病历导入(支持 cpmi / tianchi / auto)

purge

清除带 SEED 标签的导入数据

再平衡(rebalance_clinic_doctors.py):

按科室批量创建doctor_{dept}{nn}账号

将病历、患者归属从 admin/legacy 账号迁出

支持--dry-run--max-per-doctor控制每医生病例上限

时间线(realistic_case_timeline.py):

  • 就诊日分散到近 4 个月工作日
  • 补全现病史问诊叙述(normalize.enrich_consultation_narrative

上图仅作部分展示。


3. 特殊医师种子:实习 / 假期 / 停职

3.1 现象

需要演示「实习跟师可接诊」「假期不可约」「停职档案冻结」,但不想改动原有 40 名正常医生。

3.2 改法

scripts/seed_intern_doctors.py独立新增 10 个账号,不改旧数据:

类型登录名示例status说明

实习

doctor_sx_nk01

2

6 人,多科室

假期

doctor_hj_fk01

3

2 人

停职

doctor_ty_wk01

1

2 人

  • 人事状态employment_status保持0(在职),仅用出诊状态区分场景
  • 脚本可 补建曾被误删的档案,并恢复误改为停用的旧账号(RESTORE_NORMAL_USER_IDS
  • 统一密码:admin123


4. 在班状态与患者预约门控

4.1 现象

a. 停职/假期医生仍出现在患者端可预约列表。
b. 患者选到「石停」医生后挂号成功,与业务规则矛盾。
c. 列表「在班」列含义不清。

4.2 根因

仅有med_clinic_doctor.status,未统一「当日是否在班」;预约/挂号入口未校验。

4.3 改法:doctor_duty_util.py

编码约定:

字段含义

onDutyStatus

0

在班(默认)

onDutyStatus

1

不在班

status

0/1/2/3

正常 / 停用 / 实习 / 假期

resolve_doctor_duty规则:

  1. 停用、离院、暂停执业、假期 →1不在班
  2. 实习 → 默认0在班(跟师;独立出诊以后续排班为准)
  3. 当日排班stop_flag=1→ 不在班
  4. 排班未完善时,正常在职默认在班

预约门控assert_doctor_bookable接入:

入口文件

患者选医生

patient_service.py

患者 DAO 列表过滤

patient_dao.pyis_doctor_permanently_unavailable长期不可约)

门诊预约

med_clinic_appointment_service.py

现场挂号

med_outpatient_registration_service.py

不在班时统一:ServiceException('该医生当前不可预约(假期中/档案已停用/…)')

图中可以看出来不在班和实习的不会被列为可被挂号的医生


5. 档案列表默认排序与停职可见性

5.1 现象

停职演示账号在默认排序下排在最后一页,表格max-height固定,不滚动以为「种子没生效」。

5.2 改法

后端list_sort_util.py

医生列表:

  1. 不在班靠后
  2. 正常 → 实习 → 停用 → 假期(停用排在假期前,便于演示)
  3. 科室 → 专家号 → sort_num → 姓名

SQL 粗排 +enrichsort_doctor_rowsonDutyStatus精排当前页。

患者列表:

  • 医生「我的患者」:最近就诊日 ↓ → 档案更新时间 ↓ → 姓名 ↑
  • 管理员全院:正常档案优先 → 同上

前端clinic/doctor/index.vue

元素行为

el-alert

提示停职在末页,需滚动

快捷链接

「仅看停用/停职」「仅看假期」「仅看实习」

el-scrollbar max-height="62vh"

表单区加高

scrollTableIfLastPage()

末页加载后scrollTop = scrollHeight


6. 档案修改权限:谁可以改、谁只读

6.1 现象

停职医生仍能提交档案变更申请;假期医生却被误锁,无法改联系电话。

6.2 改法

is_doctor_profile_locked仅在以下情况锁定:

条件锁定

status = 1停用

employment_status = 1离院

employment_status = 2暂停执业

status = 3假期

❌ 可改

status = 2实习

❌ 可改

前端:

  • myProfile.vueprofileLocked时隐藏「提交变更」、展示el-alert
  • doctor/index.vue管理端编辑:锁定档案表单项disabled,描述「停用/离院/暂停执业:不可修改档案…」

这个不好做展示,就不贴图了。


7. 删除医生档案:ValidationError 与临床引用拦截

7.1 现象

a. 批量删除医生报ValidationError: doctorProfileIds field required
b. 删除有 hundreds 条病历的医生后,患者档案抽屉「接诊医生」列空白。
c. 用户以为「删档案 = 离职」,实际应「停用」。

7.2 根因

  • DeleteMedClinicDoctorModel未开populate_by_name,前端 camelCase 无法反序列化
  • 病历存doctor_id(用户 ID),展示 joinmed_clinic_doctor取姓名,档案删则 join 失败
  • 删除前未统计临床引用

7.3 改法

VO 修复:

class DeleteMedClinicDoctorModel(BaseModel):

model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

doctor_profile_ids: str # 逗号分隔

删除前校验delete_services

统计 user_id 关联 → 病历 + 处方 + 预约

若 total > 0 → ServiceException:

「该医生存在临床业务记录(病历 N 条、…),不可删除…请改用停用或离院」

前端确认文案:

若该医生存在病历/处方/预约记录,系统将拒绝删除并提示改用「停用」。


8. 病历接诊医生追溯:姓名快照与多级回退

8.1 设计原则

层级策略

预防

有临床记录禁止物理删档案

落库

病历写入时冻结doctor_name

展示

快照 → 档案 → 用户 →历史医生(uid)

8.2 表结构与 ORM

med_case新增:

doctor_name VARCHAR(64) NULL COMMENT '接诊医生姓名快照(落库时冻结,档案删除后仍可追溯)'

ORM:med_case_do.pymed_case_vo.py同步字段。

回填脚本:

mysql ... < sql/patient/upgrade_med_case_doctor_name_snapshot.sql

# 或

python scripts/apply_med_case_doctor_name.py

本地验证:回填 280 条历史病历。

8.3 服务层

时机逻辑

新建/编辑病历

_apply_doctor_snapshot写当前医生姓名

列表/分页

_enrich_case_list_rows批量解析doctorName

详情

无快照时resolve_doctor_display_name回退

快照与档案不一致

附加doctorNameHint:「姓名以病历快照为准…」

doctor_display_util.py解析顺序:

  1. med_clinic_doctor.doctor_name
  2. sys_user.nick_name/user_name
  3. 历史医生({uid})

8.4 前端与导出

位置变更

PatientCaseHistory.vue

新增列「接诊医生」

med_case_export_service.py

Word/PDF 元数据增加「接诊医生」「接诊医生用户ID」


9. 增量 SQL 与脚本清单

cd ruoyi-fastapi-backend

# 出诊状态字段注释(0正常 1停用 2实习 3假期)

mysql -u root -p ry-fastapi < sql/patient/upgrade_doctor_clinic_status.sql

# 病历医生姓名快照 + 历史回填

mysql -u root -p ry-fastapi < sql/patient/upgrade_med_case_doctor_name_snapshot.sql

# 特殊医师(不改原医生)

python scripts/seed_intern_doctors.py

# 可选:数据再平衡与时间线

python scripts/rebalance_clinic_doctors.py

python scripts/realistic_case_timeline.py

脚本用途

clinical_import/pipeline.py

开放数据导入主入口

rebalance_clinic_doctors.py

分科建号 + 病例均衡

realistic_case_timeline.py

就诊日打散 + 叙述补全

seed_intern_doctors.py

实习/假期/停职种子

apply_med_case_doctor_name.py

幂等加列 + 回填

audit_clinic_data.py

导入后数据审计(可选)

演示账号速查(密码admin123):

账号场景

doctor_sx_*

实习,可预约

doctor_hj_*

假期,不可预约

doctor_ty_*

停职,档案锁定,不可预约


10. 本地验证与踩坑

10.1 推荐验证顺序

  1. upgrade_doctor_clinic_status.sql+upgrade_med_case_doctor_name_snapshot.sql
  2. seed_intern_doctors.py→ 医生列表应 ≥ 50 条
  3. 「仅看停用」→ 见 2 条停职账号
  4. 患者端预约:选正常医生成功;选停职/假期失败
  5. 患者档案抽屉 → 就诊记录有「接诊医生」
  6. 删除有病历医生 → 业务拦截;改 status=停用 → 成功
  7. 导出病历 → 含接诊医生字段
  8. 重启后端,使 ORM 新列doctor_name生效

10.2 踩坑

现象原因处理

删除报 ValidationError

VO 未populate_by_name

已修复;强刷前端

1054 Unknown columndoctor_name

未跑快照 SQL

跑迁移或apply_med_case_doctor_name.py

停职账号「找不到」

默认排序在末页

点「仅看停用」或滚到底

删档案后医生列空白

旧数据无快照

跑回填;新病历自动写快照

PowerShell 内联 Python 引号错

转义问题

用独立.py脚本执行 SQL

假期账号不能改档案

误用旧锁定逻辑

确认仅停用/离院/暂停执业锁定

列表在班与预约不一致

SQL 粗排不含当日排班

assert_doctor_bookable为准


11. 结语与下阶段规划

阶段八在不加菜单的前提下,把门诊演示数据和档案治理规则补全:导入与再平衡让.wh 让多科室有料可讲;实习/假期/停职种子 + 在班门控让预约规则可演示;列表排序与快捷筛选让特殊账号不再「隐身」;删除拦截 + 病历doctor_name快照让患者历史永远能追到接诊医生。

本篇未做: 处方表doctor_name快照、排班表驱动工作台候诊、全量ry_fastapi.sql合并新列、删除 sys_user 级联策略。

下阶段计划:

1.处方/预约展示层同样落姓名快照

2.排班写入工作台「按日候诊」Tab

3.智能辅助流式输出(阶段七遗留)

4.全量 SQL 与 ORM 扫描脚本纳入 CI

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询