Files
HIS/患者首页处理/README.md
2026-05-27 00:21:16 +08:00

261 lines
13 KiB
Markdown
Raw 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.
# 患者首页 PDF 本地处理工作流
这个目录用于批量处理“患者首页 PDF”把每份 PDF 抽取成结构化记录,并输出到 `数据处理结果区/`
## 目录约定
- `待处理-患者首页PDF/`:放入等待处理的 PDF文件名建议保留首页病案号或住院号。
- `数据处理工作区/`:存放处理脚本和后续工作流工具。
- `数据处理结果区/`:脚本输出 CSV、JSONL、单份 JSON、抽取文本、PDF 图片对照页和复核清单。
- `数据可视化网页端/`Docker 化复核网页端,包含概览、复核、抽查、抽查一览、设置;设置内统一管理用户与权限、数据库状态和目录信息。
- `已处理-患者首页PDF/`:人工确认后,可把已处理 PDF 移到这里归档。
## 工作区文件
- `数据处理工作区/01_配置规则/01_科室分类规则.json`:子科室到大科室的分类规则。
- `数据处理工作区/02_解析入库/02_患者首页PDF解析与入库.py`:解析 PDF生成 CSV/JSON并可写入 PostgreSQL。
- `数据处理工作区/03_人工复核/03_人工复核导出与回写.py`:从 PostgreSQL 导出人工复核表,并把人工修正结果回写。
- `数据处理工作区/04_质量体检/04_字段核验与数据库体检.py`:检查字段注释、关键字段空值和疑似错位记录。
- `数据处理工作区/05_备用读取/05_备用PDF转Markdown_Mineru.py`:备用 PDF 转 Markdown 工具,用于扫描件或 `pdftotext` 读取异常时兜底。
- `数据处理工作区/06_图片对照核验/06_PDF转图片与对照核验.py`:把 PDF 转为图片,生成图片-字段对照 HTML 和缺项核验索引。
- `数据处理工作区/07_Kimi视觉兜底/07_Kimi图片识别辅助.py`:可选的 Kimi 视觉识别兜底,仅在文本/Markdown 解析仍不稳定时人工触发。
## 环境文件
本地 `.env` 保存 PostgreSQL 连接信息和网页端目录映射,已被 `.gitignore` 忽略,不会提交到 Gitea。网页端模板见
```text
数据可视化网页端/.env.example
```
`.env` 也可配置 `MOONSHOT_API_KEY``KIMI_MODEL`。网页端 AI 核验默认按按钮开启隐私模式如需核验基本信息或地址联系人可在设置页分别关闭“AI当前项”“AI后5项”“AI后全部”的隐私模式。
## 快速运行
在当前项目根目录执行:
```bash
python3 数据处理工作区/02_解析入库/02_患者首页PDF解析与入库.py
```
默认 `--text-source auto`:先用 `pdftotext`,如果抽取文本过短或缺少首页关键标记,再调用 Mineru 转 Markdown。
强制使用 Mineru
```bash
python3 数据处理工作区/02_解析入库/02_患者首页PDF解析与入库.py \
--text-source mineru \
--mineru-url "$MINERU_URL"
```
单独运行 PDF 转 Markdown
```bash
python3 数据处理工作区/05_备用读取/05_备用PDF转Markdown_Mineru.py \
-s 待处理-患者首页PDF \
-t 数据处理结果区/06_Mineru_MD \
-u "$MINERU_URL"
```
正式流程建议同时写入 PostgreSQL
```bash
export PGPASSWORD='从安全渠道获取数据库密码'
python3 数据处理工作区/02_解析入库/02_患者首页PDF解析与入库.py \
--write-postgres \
--pg-host "$PGHOST" \
--pg-port 5432 \
--pg-database "$PGDATABASE" \
--pg-user "$PGUSER" \
--pg-table "$PGTABLE"
unset PGPASSWORD
```
也可以指定输入和输出目录:
```bash
python3 数据处理工作区/02_解析入库/02_患者首页PDF解析与入库.py \
--input-dir 待处理-患者首页PDF \
--output-dir 数据处理结果区
```
生成 PDF 图片对照页:
```bash
python3 数据处理工作区/06_图片对照核验/06_PDF转图片与对照核验.py --force
```
该步骤会读取 `02_单份JSON/` 的结构化结果,把每份 PDF 转为 PNG并生成
- `数据处理结果区/06_PDF图片对照/图片/`:每份 PDF 一个图片目录。
- `数据处理结果区/06_PDF图片对照/患者首页_PDF图片对照.html`:浏览器打开后可左侧看原图、右侧看结构化字段和缺项提示。
- `数据处理结果区/06_PDF图片对照/患者首页_PDF图片对照索引.csv`:按 PDF 汇总页数、复核状态、核心缺项、建议核对缺项。
启动可视化网页端:
```bash
docker compose -f 数据可视化网页端/docker-compose.yml up -d --build
```
打开:
```text
http://localhost:8501
```
首次进入会显示登录界面;默认管理员为 `admin`,默认密码请在本地 `.env` 中通过 `REVIEW_ADMIN_PASSWORD` 设置。设置页创建的本地用户会同步作为登录账号,并按权限控制各页面。
网页端会显示数据库连接情况、记录数、需复核数、PDF 数量;人工修改右侧字段并点击“复核并保存”后,会同步更新 PostgreSQL并把 `manual_corrected` 标记为 `true`
网页端说明:
- PDF 以 `inline` 方式在页面内打开,不再作为附件触发保存;浏览器内核无法彻底禁止用户保存已展示内容。
- “复核并保存”后,复核状态由后端自动标记为 `reviewed`,复核状态和质控状态只读显示在 PDF 下方。
- 诊断、手术、费用等 JSON 字段在右侧以表格方式编辑,保存时再写回 JSONB。
- 手术操作按编码、日期、级别、名称、术者、I助、II助、切口愈合等级、麻醉方式、麻醉医师拆分展示。
- 设置页的 AI 核验按钮可分别设置模型/Thinking 和隐私模式;隐私模式默认开启,关闭后对应按钮会允许上传基本信息、地址联系人等相关局部内容用于核验和修正。
可选 Kimi 视觉兜底:
```bash
python3 数据处理工作区/07_Kimi视觉兜底/07_Kimi图片识别辅助.py \
--case ZY010001672803_ori \
--page page-001.png
```
输出位于 `数据处理结果区/07_Kimi视觉识别/`,默认不直接覆盖 PostgreSQL需要人工确认后再回写。
## 人工复核流程
从 PostgreSQL 导出待复核表:
```bash
export PGPASSWORD='从安全渠道获取数据库密码'
python3 数据处理工作区/03_人工复核/03_人工复核导出与回写.py export \
--pg-host "$PGHOST" \
--pg-port 5432 \
--pg-database "$PGDATABASE" \
--pg-user "$PGUSER" \
--pg-table "$PGTABLE"
unset PGPASSWORD
```
人工在 `数据处理结果区/04_复核与人工校正/患者首页_人工复核表.csv` 中填写:
- `manual_review_notes`:人工复核说明。
- `corrected_medical_record_no`:修正后的病案号。
- `corrected_patient_name`:修正后的姓名。
- `corrected_major_department`:修正后的大科室。
- `corrected_primary_diagnosis``corrected_primary_diagnosis_code`:修正后的主要诊断。
- `corrected_total_cost``corrected_self_pay_amount`:修正后的费用。
- `mark_review_status`:建议填 `reviewed`;确实仍有问题可填 `needs_review`
回写 PostgreSQL
```bash
export PGPASSWORD='从安全渠道获取数据库密码'
python3 数据处理工作区/03_人工复核/03_人工复核导出与回写.py import \
--pg-host "$PGHOST" \
--pg-port 5432 \
--pg-database "$PGDATABASE" \
--pg-user "$PGUSER" \
--pg-table "$PGTABLE"
unset PGPASSWORD
```
回写后建议做数据库体检:
```bash
export PGPASSWORD='从安全渠道获取数据库密码'
python3 数据处理工作区/04_质量体检/04_字段核验与数据库体检.py \
--pg-host "$PGHOST" \
--pg-port 5432 \
--pg-database "$PGDATABASE" \
--pg-user "$PGUSER" \
--pg-table "$PGTABLE"
unset PGPASSWORD
```
体检会生成:
- `数据处理结果区/05_质量体检/患者首页_数据库体检报告.txt`
- `数据处理结果区/05_质量体检/患者首页_字段空值统计.csv`
- `数据处理结果区/05_质量体检/患者首页_疑似异常记录.csv`
## 输出文件
运行后会生成:
- `数据处理结果区/01_结构化结果/患者首页_结构化结果.csv`:适合 Excel/WPS 查看的一行一病例总表。
- `数据处理结果区/01_结构化结果/患者首页_结构化结果.jsonl`:每行一个完整 JSON适合后续程序继续处理。
- `数据处理结果区/02_单份JSON/*.json`:每份 PDF 一个完整 JSON保留嵌套诊断、手术、费用明细和原始文本。
- `数据处理结果区/03_提取文本/*.txt``pdftotext` 抽出的原始文本,用于人工核查。
- `数据处理结果区/04_复核与人工校正/患者首页_复核清单.csv`:脚本认为需要人工复核的病例。
- `数据处理结果区/04_复核与人工校正/患者首页_处理失败.csv`:只有处理失败时才会生成。
- `数据处理结果区/06_PDF图片对照/患者首页_PDF图片对照.html`PDF 图片与结构化字段的对照复核页。
- `数据处理结果区/06_PDF图片对照/患者首页_PDF图片对照索引.csv`:图片对照与字段缺项索引。
## PostgreSQL 表结构
`--write-postgres` 会写入本地 `PGTABLE` 指向的宽表,不再使用 `payload` 总 JSON 字段,也不写入 `parsed_at/created_at/updated_at`
入库时会同步写入表注释和字段注释,便于在数据库客户端中查看每列含义。
网页端会按需把人工复核和抽查记录写入主表 JSONB 列:`review_logs` 记录人工保存时间、修改字段和备注;`audit_logs` 记录抽查来源、结论和备注。历史辅助日志表会自动迁移并删除,数据库最终只保留 `PGTABLE` 指向的一张业务表。
患者号/住院号 `inpatient_no` 是首页与患者列表联动唯一键,也是本程序唯一强制校验条件:不能为空。程序不校验编号格式,同一非空 `inpatient_no` 只保留一条首页记录;迁移时会删除历史重复住院号并保留最新记录,后续重复入库或网页写入会按 `inpatient_no` 覆盖旧首页。若 PDF 文件名和首页病案号可推导,程序仍会自动生成类似 `ZY020001447443` 的默认住院号,后续格式问题交由患者目录核验网页端处理。
病案号和首页病案号都按 10 位文本保存,保留前导 0。若 PDF 首页病案号缺前导 0但文件名可还原例如 `01447443` -> `0001447443`,脚本会自动修正,并写入:
- `inpatient_no`
- `front_page_medical_record_no`
- `major_department`
- `text_extraction_method`
- `mineru_markdown_dir`
- `review_status`
- `review_notes`
- `auto_corrections`
- `manual_corrected`
`Patient_Lists` 会同步增加 `has_front_page``front_page_id``front_page_source_file`:凡是患者号非空的首页记录,都会通过 PostgreSQL 触发器自动和 `Patient_Lists.inpatient_no` 关联;如果患者列表没有对应患者号,会由首页表自动补建一条列表记录并标记 `has_front_page = true`同时写入主要诊断、入院时间和出院时间。空患者号记录会在迁移和入库时被删除PGSQL 会阻止再次写入空患者号。当首页记录删除,或 `inpatient_no` 改为其他患者号时,触发器会把旧患者号对应的 `has_front_page` 置回 `false` 并清空首页引用。若同一患者号的姓名不一致,以首页表中的非空姓名覆盖 `Patient_Lists.patient_name`,保证患者号、姓名对齐;已有列表记录的诊断和入出院时间不被首页联动覆盖。
## 环境要求
脚本使用 Python 标准库,不需要安装 pandas/pdfplumber。
系统需要有 `pdftotext``pdftoppm` 命令。Linux 上通常都来自 `poppler-utils`
```bash
sudo apt-get install poppler-utils
```
`05_备用PDF转Markdown_Mineru.py` 需要 `requests`;只在单独使用 Mineru 客户端时安装即可:
```bash
python3 -m pip install requests
```
Docker 网页端依赖已写入 `数据可视化网页端/Dockerfile`,不再单独维护 `requirements.txt`
## 当前解析范围
脚本会抽取:
- 基本信息:住院号、病案号、首页病案号、姓名、性别、出生日期、年龄、身份证号、付费方式等。
- 入出院信息:入院/出院时间、科别、病房、实际住院天数、门急诊诊断。
- 科室分类:根据 `数据处理工作区/01_配置规则/01_科室分类规则.json` 生成 CSV 的 `大科室` 和 PostgreSQL 的 `major_department`
- 诊断信息:`discharge_diagnoses` 出院诊断 JSONB 数组,包含主要诊断、其他诊断、疾病编码、入院病情。
- 手术操作:编码、日期、名称、原始行内容。
- 首页质控信息:病理、药物过敏、尸检、血型/Rh、医师、护士、编码员、病案质量、质控日期、离院方式、再住院计划等。
- 费用信息:总费用、自付金额、各费用明细;若 PDF 首页未填写费用,不强制判为失败。
## 建议审核
每次运行后先看:
```bash
sed -n '1,20p' 数据处理结果区/04_复核与人工校正/患者首页_复核清单.csv
```
随后打开 `数据处理结果区/06_PDF图片对照/患者首页_PDF图片对照.html`,用 PDF 图片逐项对照病案号、姓名、入出院信息、诊断、手术、质控和费用。遇到新医院、新模板、扫描件或字段错位时,把 PDF、对应 TXT、图片对照索引中的缺项提示留在目录中再让 Codex 继续补规则。