Files
chis_osi/docs/02-旧项目架构评估.md
T
ilaandClaude Opus 4.8 3498542b07 docs: 初始化 chis_osi 设计文档与协作规范
- docs/: OSI 接口规范分析、旧项目架构评估、目标架构设计、字段与接口映射、实施路线图
- CLAUDE.md: 协作规则(项目认知、osi/mapping/pipeline 三层技术约束、安全/验证、提交规范)
- .gitignore: 补充项目特定忽略(config.yaml/logs/样本等)
- 随项目留存厂家 OSI 规范源材料(docx/xlsx,内部保密,仅限本私有仓库)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 13:10:17 +08:00

83 lines
6.3 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.
# 02 · 旧项目(chis_upload)架构评估
`chis_upload` 是通过**逆向 Chrome F12 网页接口**实现的 PHIS→CHIS 上传工具(Go 1.24)。
本文梳理它的分层与组件,区分「哪些复杂度是被网页逆向逼出来的、新项目应删除」与「哪些工程经验值得保留」。
---
## 1. 整体定位与数据流
旧项目本质是一个**数据搬运管道**:
```
PHIS(上游公卫系统) --拉取任务--> chis_upload --(模拟网页登录态)--> CHIS 网页后端
```
它对外暴露一组 HTTP API(`/api/health-record/save` 等),内部再以网页同款报文调用 CHIS。
另有 worker 模式:轮询 PHIS 拉任务、按 `dataType` 分流、调用自身 save API 完成投递。
---
## 2. 分层与目录职责(摘自其 AGENTS.md 与源码)
| 目录 | 职责 |
| --- | --- |
| `config/` | viper 读取 `config.yaml` |
| `util/` | SM2 加密、Redis、报告日志(reportlog)、apitrace、日志 |
| `chis/` | CHIS 调用核心:client/transport/auth/login + 各业务域 save/query + 归一化器/补齐器/身份链/完整度计算 |
| `model/` | 请求/响应结构体 |
| `handler/` | 对外 HTTP API 处理函数 |
| `middleware/` | Cookie 中间件(登录态注入) |
| `router/` | 路由注册(每个 save/query 都套 `authMW`) |
| `worker/` | phis_poll_worker、mock_task_worker、幂等存储、批次报告 |
`chis/` 目录尤其庞大(30+ 文件),是复杂度集中地。
---
## 3. 复杂度来源分析
### 3.1 由「网页逆向」逼出来的复杂度 —— 新项目应整体删除
| 旧项目机制 | 为什么存在 | OSI 下的命运 |
| --- | --- | --- |
| **SM2 加密**(`util/encrypt.go`:`EncryptSM2`/`GenerateLwD`/`GenerateQueryD`/`YearLlxKey`) | 网页登录与查询参数 `lw_d`/`d` 用 SM2 公钥加密,按年份还有动态字段名 `2026llx` | ❌ 删除。OSI 用 MD5 头签名 |
| **登录流程**(`chis/login.go`、`LoginWithRoleHint`、`identity_chain.go`) | 网页要先登录拿 Cookie,且要处理多角色选择 | ❌ 删除。OSI 无登录 |
| **Cookie/会话**(`middleware/cookie.go`、`chis/auth.go` `RedisCookieAuth`、`validate_cookie.go`、`util/redis.go` cookie 缓存、`cookie_ttl` 配置) | 维持网页登录态、跨请求复用、过期重登 | ❌ 删除。OSI 每请求现签,无状态 |
| **身份链反查**(`chis/identity_chain.go`:`idCard → empiId/phrId/...`) | 网页保存需要先把身份证换成内部主键链路 | ❌ 删除/大幅简化。OSI 直接用 `idCard`+`checkId`,`phrId` 由创建接口回传 |
| **Chrome 报文对齐**(`chrome_payload_compat_enable`、各 `*_payload_normalizer.go`、`health_check_enricher.go`) | 必须把字段补齐成 Chrome F12 抓到的同款形态,否则后端拒绝 | ⚠ 转化。不再"对齐网页",而改为"映射到文档契约"——见下 |
| **完整度服务端重算**(`health_record_complete_level.go` 37/33 项、`health_check_perfection.go` 70 项) | 逆向得知网页会算 completeLevel/perfection,客户端不可信任传入值,需本地重算 | ⚠ 待定。OSI 有显式 `isFillShhj`,完整度很可能由平台算;需联调确认后决定保留与否 |
| **网页拟态请求头**(`buildCHISCallHeaders`:`Origin`/`Referer`/`X-Requested-With`/`Host`) | 让请求看起来像浏览器发的 | ❌ 删除。OSI 是正式服务接口,无需伪装 |
| **apitrace + 多套快照**(`util/apitrace.go`、`phis_snapshot_*`,且注释标"兼容保留") | 逆向期排障留下的多套追踪 | 🔁 收敛为一套 report log |
> 量级判断:`chis/` 目录约 70%~80% 的代码是为「骗过网页 + 复刻网页隐藏算法」服务的。
> OSI 接口让这部分**整体失去存在意义**。
### 3.2 值得保留的工程经验 —— 新项目应继承
| 旧项目机制 | 价值 | 新项目去向 |
| --- | --- | --- |
| **分层清晰 + 面向初级维护者**(AGENTS.md:可读、不过度抽象、必要中文注释) | 团队约定,降低接手成本 | ✅ 继承这套协作规范 |
| **统一调用入口**(`chis/client.go` `Call(ctx, account, path, req, out)`:拼地址→注入头→传输→反序列化→记日志) | 单点收敛传输与可观测 | ✅ 演化为 OSI `client.Call(ctx, serviceId, body, out)` |
| **传输层与代理**(`transport.go`/`http_client.go`,SOCKS5 支持、超时控制、避免 typed-nil jar panic) | 内网穿透/超时是真实运维需求 | ✅ 几乎原样保留(去掉 cookiejar) |
| **投递流水线**(`worker/`:任务校验分流、**重试分类**、**幂等去重**、**熔断**、**批次报告**、跑完自动退出) | 这是搬运管道的可靠性核心,与接口形态无关 | ✅ 重点保留并升级 |
| **重试错误分类**(网络/5xx/429/网络型 401 可重试;参数/权限不可重试;退避 `2s*attempt`) | 来之不易的运维经验 | ✅ 保留,适配 OSI 返回码(`405` 超时可重试) |
| **report log + 降级**(Redis 优先、不可用降级写本地 JSONL;带 trace_id) | 可观测 + 不强依赖 Redis | ✅ 保留,Redis 改为完全可选 |
| **统一错误体**(`APIError{error_code,error_message,trace_id}`) | 上游稳定解析 | ✅ 保留 |
| **配置驱动 + Redis 启动失败不阻断** | 联调友好 | ✅ 保留 |
### 3.3 旧项目的待改进点(新项目顺手修正)
- **幂等键弱**:旧键 `account|idCard|dataType|sha1(saveBody)`,依赖报文哈希,报文微调即视为新任务。OSI 有天然的 `checkId`,应作为幂等主键。
- **任务源是 mock 文件**:`mock_task_worker` 读本地 JSON,真实 PHIS 拉取/状态回写一直 TODO(见其 `phase9_todo_open_items.md`)。新项目应直接把 PHIS 接入做实。
- **多套追踪并存**:apitrace / reportlog / snapshot 三套,注释里自承"兼容保留",应收敛为一套。
- **handler 里大量"从原始 JSON 多路径兜底提取字段"**(`fillEMPIAndPHRFromContext` 等),是历史请求体不规范的补丁。新项目以明确契约杜绝。
- **server 与 worker 杂糅在 `main.go`**(flag 极多)。新项目用子命令拆分。
---
## 4. 给新项目的迁移启示(一句话)
> 把 `chis/` 里"对付网页"的 70% 删掉,保留并强化 `worker/` 那套"可靠投递"的 30%,
> 再把删掉的部分替换成一个**薄 OSI 客户端**和一个**厚字段映射层**。