Files
chis_osi/docs/01-OSI接口规范分析.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

200 lines
10 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.
# 01 · OSI 接口规范分析
来源:《广东省基层医疗机构管理系统 统一对外服务接口 API 规范文档 V1.5.7》(2023-02-02,和宇健康科技)
配套:《广东省基层医疗机构管理系统服务接口对接回复后需要的接口.xlsx》(本期需对接的 25 个接口清单)
---
## 1. 总体约定
| 项 | 约定 |
| --- | --- |
| 协议 | HTTP,方法统一 `POST` |
| 通用 URL | `http://${hostname}/osi/api/...`(各接口在此基础上拼子路径) |
| 报文格式 | 请求/响应均为 JSON 字符串 |
| 字符集 | UTF-8 |
| 返回码 | `code == "1"` 成功;其它值失败;`405` = 服务调用超时 |
> 注意:返回码 `code` 是**字符串** `"1"`,不是数字 `1`;判定成功务必按字符串比较或归一化处理。
### 1.1 响应统一结构
```json
{ "code": "1", "message": "操作成功", "data": { ... } }
```
- `data` 在创建类接口是对象(如 `{ "phrId": "...", "createUnit": "..." }`);
- 在查询/列表类接口可能是对象或数组,需按接口分别建模。
---
## 2. 鉴权:请求头 MD5 签名(无状态)
所有接口通过 **HTTP 请求头**鉴权,**没有登录、没有 Cookie、没有 Session**:
| 请求头 | 说明 |
| --- | --- |
| `Content-Type` | `application/json` |
| `orgCode` | 机构编码(机构的社会统一信用代码,约 18~20 位)。接入方先把组织/机构信息提供给平台,由平台生成 |
| `deviceSN` | 设备序列号(创建/更新/查询类接口均要求必填) |
| `ts` | 13 位毫秒级时间戳 |
| `userName` | 平台分配的用户名(对应一个 `ask` 密钥;同时也是报文里的第三方接入公司名称编码 `DSFMC`) |
| `password` | `md5("ts=<时间戳>&ask=<密钥>")`,取 **32 位小写** |
签名要点:
- `password` 的明文是字符串 `ts=<ts>&ask=<ask>`,其中 `<ts>` 必须与请求头里发送的 `ts` 完全一致;
- `ask` 为平台下发的密钥,**只参与签名,绝不放进请求头或报文**;
- 每个请求现算 `ts`/`password`,天然防重放(平台侧通常校验 `ts` 时效)。
> 对比旧项目:这里**不需要** SM2 公钥加密、不需要 `lw_d`/`d`/查询 `d` 加密参数、不需要按年份变化的动态字段名。
> 一个标准库 `crypto/md5` 即可完成全部鉴权。
---
## 3. 请求报文信封
请求体(HTTP body)统一为:
```json
{
"serviceId": "<固定服务码>",
"uploadinfo": { ... } // 创建/更新类:写入数据
}
```
或查询类:
```json
{
"serviceId": "<固定服务码>",
"baseInfo": { ... } // 查询条件
}
```
- `serviceId` 是每个接口的**固定常量**(见第 5 节映射表),平台据此路由业务。
- 创建/更新类信封内含 `manageInfo`(管理节点)+ 业务数据节点:
- `manageInfo.DSFMC` = 第三方接入公司名称编码(与请求头 `userName` 一致)
- `manageInfo.operateUnit` = 操作机构编码(与请求头 `orgCode` 一致)
- `manageInfo.operateUser` = 责任医生 ID
- 文档中创建样例外层出现的 `"headers": {...}` 仅用于演示 HTTP 头,**不是 body 的一部分**;实际 POST body 只发 `serviceId`+数据节点。
---
## 4. 本期需对接接口清单(来自 xlsx,25 项)
| # | 模块 | 接口名称 |
| --- | --- | --- |
| 1 | 档案 | 个人健康档案信息列表查询 |
| 2 | 档案 | 个人健康档案信息创建 |
| 3 | 档案 | 个人健康档案信息更新 |
| 4 | 档案 | 个人健康档案信息查询 |
| 5 | 档案 | 居民人群标记与子档案标记查询 |
| 6 | 体检 | 健康体检已检/待检人员列表查询 |
| 7 | 体检 | 最近一次健康体检查询 |
| 8 | 体检 | 健康体检创建 |
| 9 | 体检 | 健康体检更新 |
| 10 | 体检 | 健康体检查询 |
| 11 | 老年人·中医体质辨识 | 列表查询 |
| 12 | 老年人·中医体质辨识 | 创建 |
| 13 | 老年人·中医体质辨识 | 更新 |
| 14 | 老年人·生活自理能力评估 | 列表查询 |
| 15 | 老年人·生活自理能力评估 | 创建 |
| 16 | 老年人·生活自理能力评估 | 更新 |
| 17 | 老年人·生活自理能力评估 | 查询 |
| 18 | 老年人·中医健康指导 | 列表查询 |
| 19 | 老年人·中医健康指导 | 保存 |
| 20 | 老年人·中医健康指导 | 更新 |
| 21 | 老年人·中医健康指导 | 查询 |
| 22 | 公共服务 | 查询网格地址 |
| 23 | 公共服务 | 责任医生查询 |
| 24 | 公共服务 | 药品目录查询 |
| 25 | 公共服务 | 机构查询 |
---
## 5. 接口 → 路径 → serviceId 映射表
> 以文档正文为准整理。文档中部分 serviceId 因复制粘贴存在错误(见第 7 节),下表为校正后的推断值,**联调时需逐一回填确认**。
### 5.1 健康档案(JKDA)
| 业务 | 路径 | serviceId | 主数据节点 |
| --- | --- | --- | --- |
| 创建 | `/osi/api/jkda/create` | `JKDA00001` | `uploadinfo.healthRecord` + `pastHistory`/`jwsjb`/`jwsss`/`jwsws`/`jwssx`/`familyMiddle` |
| 查询 | `/osi/api/auto/jkda/find` | `JKDA00002` ⚠ 文档样例误写 `TNB00004` | `baseInfo`(idCard/phrid/personName 三选一) |
| 更新 | `/osi/api/jkda/update` | `JKDA00003` | 同创建 |
| 人群/子档案标记查询 | `/osi/api/jkda/findrqbj` | `JKDA00005` | `baseInfo`(phrid/idCard 二选一) → `data.personSign` |
| 列表查询 | (清单第 1 项,文档正文未见独立路径,疑与 `find` 合并或缺漏) | 待确认 | — |
`findrqbj` 返回的 `personSign` 取值:`PU` 普通 / `GRQY` 已签约 / `LAO` 老年人 / `GAO` 高血压 / `TANG` 糖尿病 / `FU` 孕产妇 / `ER` 儿童 / `FEI` 肺结核 / `JING` 精神障碍 / `CAN` 残疾人,多个以逗号分隔。
### 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` |
> 体检报文体量大(hcData/lsData/exaData/aeData 等数十~上百字段),是字段映射工作量最大的一块。
### 5.3 老年人(LNR)
| 业务 | 路径 | serviceId |
| --- | --- | --- |
| 生活自理能力评估·创建 | `/osi/api/lnrzlpg/create` | `LNRZLPG00001` |
| 生活自理能力评估·更新 | `/osi/api/lnrzlpg/update` | `LNRZLPG00003` |
| 生活自理能力评估·查询/列表 | (清单第 14/17 项) | 待确认(推断 `LNRZLPG00002`) |
| 中医体质辨识·创建 | `/osi/api/lnrzyygl/create` | `LNRZYTZ00001` |
| 中医体质辨识·更新 | `/osi/api/lnrzyygl/update` | `LNRZYTZ00003` |
| 中医体质辨识·查询/列表 | (清单第 11 项) | 待确认(推断 `LNRZYTZ00002`) |
> 注意路径与 serviceId 的命名不一致:中医体质辨识的**路径**用 `lnrzyygl`,而 **serviceId** 用 `LNRZYTZ`。对接时以文档逐条为准,不要据路径猜 serviceId。
### 5.4 中医健康指导(ZYJKZD)
| 业务 | 路径 | serviceId |
| --- | --- | --- |
| 保存 | `/osi/api/auto/zyjkzd/create` | 待确认 |
| 更新 | `/osi/api/auto/zyjkzd/update` | 待确认 |
| 查询/列表 | (清单第 18/21 项) | 待确认 |
### 5.5 公共服务(查询类,请求体 `baseInfo`)
| 业务 | 路径 | serviceId | 关键入参 | 关键出参 |
| --- | --- | --- | --- | --- |
| 查询网格地址 | `/osi/api/auto/wgdzcx/query` | `WGDZ00001` | `parentCode`,`pageNo`,`operateUser` | `regionCode`,`regionName`,`isFamily`(层级) |
| 责任医生查询 | `/osi/api/auto/zryscx/query` | `ZRYS00001` | `manaUnitId`,`operateUser` | `personId`,`personName` |
| 药品目录查询 | `/osi/api/auto/ypmlcx/query` | `YPML00001` | `pageNo`,`ypmc`,`pym` | `ypmc`,`ypdw`,`ypgg`,`jldw` |
| 机构查询 | `/osi/api/auto/cxjg/query` | `CXJG00002` | `organizCode`,`parentId` | `organizCode`,`organizName`,`organizType`,`parentId` |
> 公共服务接口是**基础字典服务**:网格地址→`regionCode`、责任医生→`personId`、机构→`organizCode`。
> 它们正是创建类接口所需主数据(`regionCode`/`manaDoctorId`/`manaUnitId` 等)的来源,建议优先打通并本地缓存为字典。
---
## 6. 关键字段语义(创建健康档案为例)
- `checkId`:**第三方系统业务唯一识别码(流水码)**。这是接入方自己生成、用于和平台对账与去重的关键键,是新项目幂等设计的基石(见 04 文档)。
- `idCard` + `personName` + `sexCode` + `birthday`:人口学主键四要素,必填。
- `regionCode`:12 位行政区划/网格代码,来自「网格地址查询」。
- `manaDoctorId` / `manaUnitId` / `operateUser`:责任医生与管辖机构,来自「责任医生查询」「机构查询」。
- 大量字段是**带码表的枚举**(民族 56 项、职业、文化程度、婚姻、血型、医保支付方式、既往史/家族史多选用逗号拼接等),是映射层的主要工作量。
- `isFillShhj`(y/n)显式标记是否填写生活环境(`familyMiddle`)。
- 推断:完整度(旧项目里的 `completeLevel`/`perfection`)很可能由**平台服务端自行计算**,接入方只需如实上送文档字段;这与旧项目"客户端重算完整度"形成对比,需在联调中确认(见 03 文档"开放问题")。
---
## 7. 文档坑点(务必在联调中校验)
官方 docx 存在明显的复制粘贴/排版错误,建模前需逐一核对:
1. **serviceId 串台**:`jkda/find` 的请求样例里 serviceId 写成 `TNB00004`(糖尿病接口的码),实际应为 `JKDA00002`。
2. **字段名不一致**:创建档案家族史父亲在字段定义里叫 `jzsfqn`,在请求样例里叫 `jzsfq`;现住址门牌号在创建里 `addressNumber`、在查询里 `adressNumber`(少一个 d)。
3. **类型不一致**:`familyMiddle` 在创建接口标 `object`,在查询接口标 `list`;`pastHistory` 同样在不同接口标注不同。
4. **样例 JSON 非法**:多处查询样例花括号不配对(如 `{ "baseInfo": {...} }, "serviceId": "..." }`),应理解为 `{ "serviceId": "...", "baseInfo": {...} }`。
5. **列表查询路径缺漏**:xlsx 要求"档案列表查询""自理/体质/中医指导列表查询""自理查询"等,但 docx 正文未给出全部独立路径与 serviceId,需向厂家索要补充。
> 结论:**不能直接照搬 docx 字段表生成契约**。落地前应整理一份「校验后的接口契约」(见 03 文档 `contract/` 包),
> 并以厂家沙箱环境的真实请求/响应样本做回归校准。