From 66bf37bcd3791210716d472f49c95f59ff3052a0 Mon Sep 17 00:00:00 2001 From: ila Date: Wed, 8 Jul 2026 00:45:47 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E7=99=BB=E8=AE=B0=20T-301=20=E4=BD=93?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E8=AF=A2=E5=A5=91=E7=BA=A6=E4=B8=8E=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E6=B8=85=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docs/04 §11 体检 ~260 字段清单(7 节点)供将来 create 用 - docs/01 §5.2 标注各体检接口联调状态(单查未部署) - tasks T-301 DONE;gitignore 收敛为 scripts/*.py Co-Authored-By: Claude Opus 4.8 --- .gitignore | 5 +++-- docs/01-OSI接口规范分析.md | 16 +++++++-------- docs/04-字段与接口映射.md | 41 ++++++++++++++++++++++++++++++++++++++ docs/current-state.md | 6 +++--- progress.md | 9 +++++++++ tasks.md | 2 +- 6 files changed, 65 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 563ca81..a8b980d 100644 --- a/.gitignore +++ b/.gitignore @@ -44,9 +44,10 @@ config.local.yaml scripts/*.json # 账号/凭据(userName/密码/主机/代理)——只本地留存 /docs/账号.txt -# 本地联调脚本(硬编码了 ask/orgCode/身份证等真实值)——只本地留存 -/scripts/query_health_record.py +# 本地联调探针脚本(硬编码了 ask/orgCode/身份证等真实值)——只本地留存 +/scripts/*.py /query_health_record.bat +/dev.bat # 本地工作区文件 /agent-session.txt /chis_osi.code-workspace diff --git a/docs/01-OSI接口规范分析.md b/docs/01-OSI接口规范分析.md index f9a88af..2dfcfa9 100644 --- a/docs/01-OSI接口规范分析.md +++ b/docs/01-OSI接口规范分析.md @@ -132,15 +132,15 @@ ### 5.2 健康体检(JKTJ) -| 业务 | 路径 | serviceId | -| --- | --- | --- | -| 创建 | `/osi/api/jktj/create` | `JKTJ00001` | -| 查询 | `/osi/api/auto/jktj/query` | `JKTJ00002` | -| 更新 | `/osi/api/jktj/update` | `JKTJ00003` | -| 已检/待检人员列表 | `/osi/api/auto/jktjlist/query` | `JKTJLIST00002` | -| 最近一次体检 | `/osi/api/auto/jktjlscx/query` | `JKTJLSJL00002` | +| 业务 | 路径 | serviceId | 联调状态 | +| --- | --- | --- | --- | +| 创建 | `/osi/api/jktj/create` | `JKTJ00001` | 待写入授权 | +| 查询(单条) | `/osi/api/auto/jktj/query` | `JKTJ00002` | ⚠ 实测"没有url的接口配置"(**未部署**);`auto/jktj/find` 待确认 | +| 更新 | `/osi/api/jktj/update` | `JKTJ00003` | 待写入授权 | +| 已检/待检人员列表 | `/osi/api/auto/jktjlist/query` | `JKTJLIST00002` | 路径登记;入参待确认 | +| 最近一次体检 | `/osi/api/auto/jktjlscx/query` | `JKTJLSJL00002` | ✅ 联调可用(T-301) | -> 体检报文体量大(hcData/lsData/exaData/aeData 等数十~上百字段),是字段映射工作量最大的一块。 +> 体检报文体量大(实测最近一次约 260 字段,分 4 object + 3 array 子节点),是字段映射工作量最大的一块。响应结构与字段清单见 `docs/04 §11`。 ### 5.3 老年人(LNR) diff --git a/docs/04-字段与接口映射.md b/docs/04-字段与接口映射.md index b27aaaa..6b5bd76 100644 --- a/docs/04-字段与接口映射.md +++ b/docs/04-字段与接口映射.md @@ -250,3 +250,44 @@ T-206 已建立本地契约与客户端方法,真实写入验收暂未执行 - `mapping.BuildHealthRecordCreate` 负责把 `MappedHealthRecord` 组装成 `contract.HealthRecordCreate`,保留确定性 `checkId`,并由 `manaDoctorId/manaUnitId` 派生 `createUser/createUnit`。 真实 create/update 联调完成后,需要在本节补回平台返回样本、`phrId` 字段确认、同一 `checkId` 重复 create 的幂等语义。 + +--- + +## 11. JKTJ 健康体检查询 · 联调实测契约(T-301) + +> 来源:2026-07 沙箱"最近一次体检"一次成功查询(`code="01"`)。**脱敏结构**,真实值只在本地样本、不入库。 +> 这是体检查询的事实基线,也是将来体检 **create 映射**的字段清单来源。 + +### 11.1 接口与状态 + +| 业务 | serviceId | 路径 | 状态 | +| --- | --- | --- | --- | +| 最近一次体检 | `JKTJLSJL00002` | `/auto/jktjlscx/query` | ✅ 实测可用(`osi.LastHealthCheck`) | +| 已检/待检列表 | `JKTJLIST00002` | `/auto/jktjlist/query` | 路径已登记;入参(机构/日期/分页)待厂家确认 | +| 单条按体检 id 查 | `JKTJ00002` | docx 标 `/auto/jktj/query` | ⚠ 实测返回"没有url的接口配置"(**未部署**);`/auto/jktj/find` 待确认,见 docs/06 B5 | + +- 请求信封同档案(`serviceId` + `uploadinfo{baseInfo, manageInfo}`);查询按 `idCard`/`phrid`/`empiId` 之一。 +- **两处与档案不同的坑**:① 最近一次的 `data` 是**单个对象**(档案 find 是数组);② 体检身份证字段是小写 **`idcard`**(档案是 `idCard`)。 + +### 11.2 记录结构与主键 + +- 体检记录主键 = **`checkId`**(体检自身流水,**注意**与档案 §5 我方生成的幂等 `checkId` 同名不同义)。 +- 各子节点用 **`healthCheck`** 外键指向主键(值 = checkId);子节点各有自己的 id:`healthAssessment.assessmentId`、`accessoryExamination.recordId`、`inhospitalSituations[].situationId`。 + +### 11.3 字段清单(实测约 260 项,供体检 create 建模用) + +> 查询侧只强类型化定位字段(`contract.HealthCheckSummary`:checkId/healthCheck/idcard/personName/checkDate),完整内容由 `osi.Result.Raw` 保留。 +> 全量字段的强类型建模留到体检 create 任务——写入映射才需要逐字段建模,届时以本清单 + 联调 create 样本为准,不照 docx 猜类型(本样本大量字段为 null,类型不可判)。 + +| 节点 | 类型 | 字段数 | 说明 | +| --- | --- | --- | --- | +| (顶层标量) | - | 39 | 体征与主诉:身高体重 `height/weight/bmi`(float)、血压 `constriction/diastolic(_l)`、`temperature/pulse/breathe/waistline`、`symptom/healthstatus/selfcare/cognitive/emotion` 及各类疾病标志 | +| `healthAssessment` | object | 24 | 健康评价:`abnormality1..8`、`riskfactorsControl`、`assessmentId` + create/lastModify 审计字段 | +| `examination` | object | 52 | 一般查体:皮肤/淋巴结/心肺/腹部/肝脾/乳腺/妇科等 `*` + `*Desc` 描述对 | +| `lifestySituation` | object | 43 | 生活方式:吸烟 `wehtherSmoke/beginSmokeTime`、饮酒 `drinkingFrequency`、运动、职业暴露 `occupational/dust/ray/chemicals` | +| `accessoryExamination` | object | 84 | 辅助检查(最大):血常规 `wbc/hgb/platelet`、生化 `alt/ast/glu/fbs/hba1c/tc/tg/hdl/ldl/cr/bun/tbil`、尿常规、心电 `ecg`、胸片 `x`、视力听力 `recordId` | +| `inhospitalSituations` | array | 19/项 | 住院/家庭病床:`type`、`inhospitalDate/outhospitalDate`、`situationId`,多含 `*_text` 中文回显 | +| `nonimmuneInoculations` | array | - | 非免疫规划预防接种(本样本空,结构待样本) | +| `medicineSituations` | array | - | 用药情况(本样本空,结构待样本) | + +> 命名坑点:`constriction`=收缩压、`diastolic`=舒张压(`_l` 疑为左侧);辅助检查用大量医学缩写。建 create 映射时逐字段加中文注释。 diff --git a/docs/current-state.md b/docs/current-state.md index bdce836..fd55344 100644 --- a/docs/current-state.md +++ b/docs/current-state.md @@ -88,9 +88,9 @@ python3 scripts/query_health_record.py > 读先行调整(2026-07-08):写入(T-206/T-204)被厂家授权锁死,先推其余业务线查询。 -1. **T-301 体检查询打通**(`contract/jktj.go` + `osi/jktj.go`,JKTJ00002 / JKTJLSJL00002),响应字段记入 docs/04 —— 当前可领。 -2. T-302 体检 HTTP 查询端点(复用 T-208 handler 模式)。 -3. 并行催厂家(docs/06 ★ 优先催办):写入授权+测试档案、缺失列表 serviceId、checkId/完整度规则。 +1. ✅ T-301 体检查询打通(`osi.LastHealthCheck` JKTJLSJL00002;字段清单 docs/04 §11)——待 `go test ./...` 复验。 +2. **T-302 体检 HTTP 查询端点**(复用 T-208 handler 模式)——当前可领。 +3. 并行催厂家(docs/06 ★ 优先催办):写入授权+测试档案、缺失列表/单查 serviceId、checkId/完整度规则。 4. 授权到位后回到 T-206 真实 create 验收 → T-204。 ## 维护规则 diff --git a/progress.md b/progress.md index 266fada..388d180 100644 --- a/progress.md +++ b/progress.md @@ -200,3 +200,12 @@ - 变更:`tasks.md` 新增 Phase Q2(其余业务线查询:T-301 体检查询 / T-302 体检端点 / T-303 老年人查询 / T-304 列表查询),把写入 T-206(BLOCKED)/T-204 明确降到 Q2 之后;里程碑加 M4=体检查询、M5=创建闭环。`docs/06` 顶部加"★ 当前批次优先催办",把写入授权(D3)+缺失 serviceId(B1/B2/B4)+写入规则(C1/C2) 归拢成一封邮件一起催。`docs/current-state.md` 下一步改为 T-301 起。 - 决策(全栈分析):真实 create 被厂家写入授权外部锁死,垂直切片走不通;改按读/写横切、读先行——读路径不被授权阻塞、只读零风险、且各查询响应是将来写入映射的事实侦察。T-206 创建代码保留不作废,授权到位再验收。 - 下一步:T-301 体检查询打通。 + +## 2026-07-08 T-301 体检查询打通(最近一次) + +- 状态:DONE +- 变更:新增 `contract/jktj.go`(HealthCheckSummary 定位字段)、`osi/jktj.go`(`LastHealthCheck` JKTJLSJL00002)、`osi/jktj_test.go`(脱敏假数据测路径/解码/Raw/idcard 小写映射/单键校验);`osi/codes.go` 登记 JKTJLSJL00002 + JKTJLIST00002 路由;`docs/04` 新增 §11 体检字段清单(~260 项/7 节点),`docs/01 §5.2` 标注各体检接口联调状态。 +- 验证:真实"最近一次体检"查询已通(用户侧 Python 脚本 code=01,返回单个体检对象)。Go 侧因本环境离线无工具链未复跑,需用户 `go test ./...` 确认编译与单测。 +- 发现:① 单条 JKTJ00002 `auto/jktj/query` 平台实测"没有url的接口配置"(未部署),`auto/jktj/find` 待确认 → docs/06 B5。② 体检 data 为单对象(档案 find 是数组)。③ 体检身份证字段小写 `idcard`(档案 `idCard`)。④ 体检主键 `checkId`(与档案幂等 checkId 同名不同义),子节点 `healthCheck` 外键指向它。 +- 决策:查询只强类型化定位字段,完整内容留 `Result.Raw`;~260 全量字段建模留到体检 create(写入才需逐字段,避免照单样本猜 null 类型)。 +- 下一步:T-302 体检 HTTP 查询端点(复用 T-208 handler 模式);或按 docs/06 催厂家确认单查/列表接口。 diff --git a/tasks.md b/tasks.md index 1f25a2f..24124c6 100644 --- a/tasks.md +++ b/tasks.md @@ -73,7 +73,7 @@ | ID | 任务 | 依赖 | 验收要点 | 状态 | | --- | --- | --- | --- | --- | -| T-301 | 体检查询打通:`contract/jktj.go` + `osi/jktj.go`(单条 JKTJ00002 / 最近一次 JKTJLSJL00002) | T-004 | 真实请求拿到 `code="01"` 与体检数据;响应字段(hcData/lsData/exaData/aeData…)记入 docs/04 | TODO | +| T-301 | 体检查询打通:`contract/jktj.go` + `osi/jktj.go`(最近一次 JKTJLSJL00002) | T-004 | 真实请求拿到 `code="01"` 与体检数据;响应字段(~260 项/7 节点)记入 docs/04 §11 | DONE(单条 JKTJ00002 平台未部署,见 §11) | | T-302 | 体检 HTTP 查询端点(复用 T-208 handler 模式) | T-301 | server 模式 curl 返回体检完整 JSON;默认仅绑本机 | TODO | | T-303 | 老年人查询打通:自理 LNRZLPG / 体质 LNRZYTZ(查询 serviceId 部分待确认) | T-004 | 真实请求打通;缺失 serviceId 先向厂家确认(docs/06 B4) | TODO(部分待 B4) | | T-304 | 列表类查询(档案/体检/老年人/中医指导列表) | T-004 | 各列表路径+serviceId 到位后返回分页数组 | BLOCKED(待 docs/06 B1/B2 厂家回填) |