# 患者首页 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 继续补规则。