- docs/: OSI 接口规范分析、旧项目架构评估、目标架构设计、字段与接口映射、实施路线图 - CLAUDE.md: 协作规则(项目认知、osi/mapping/pipeline 三层技术约束、安全/验证、提交规范) - .gitignore: 补充项目特定忽略(config.yaml/logs/样本等) - 随项目留存厂家 OSI 规范源材料(docx/xlsx,内部保密,仅限本私有仓库) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.3 KiB
6.3 KiB
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 客户端和一个厚字段映射层。