# 01 · OSI 接口规范分析 来源:《广东省基层医疗机构管理系统 统一对外服务接口 API 规范文档 V1.5.7》(2023-02-02,和宇健康科技) 配套:《广东省基层医疗机构管理系统服务接口对接回复后需要的接口.xlsx》(本期需对接的 25 个接口清单) --- ## 1. 总体约定 | 项 | 约定 | | --- | --- | | 协议 | HTTP,方法统一 `POST` | | 通用 URL | `http://${hostname}/osi/api/...`(各接口在此基础上拼子路径) | | 报文格式 | 请求/响应均为 JSON 字符串 | | 字符集 | UTF-8 | | 返回码 | 成功码 `code`(字符串);其它值失败;`405` = 服务调用超时 | > **联调实测(2026-07,JKDA00002)**:成功返回 `code="01"`、`message="操作成功"`,而非早期依 docx 整理的 `"1"`。 > `code` 是**字符串**,落地判定成功建议按「去前导零后 == `"1"`」或落入集合 `{"1","01"}`,不要用数字比较;`405` 仍为服务调用超时(可重试)。其余失败码字典待厂家给全(见 docs/06 C3)。 ### 1.1 响应统一结构 ```json { "code": "01", "message": "操作成功", "data": [ ... ] } ``` - `data` 在创建类接口是对象(如 `{ "phrId": "...", "createUnit": "..." }`); - 在查询/列表类接口可能是对象或数组,需按接口分别建模。 --- ## 2. 鉴权:请求头 MD5 签名(无状态) 所有接口通过 **HTTP 请求头**鉴权,**没有登录、没有 Cookie、没有 Session**: | 请求头 | 说明 | | --- | --- | | `Content-Type` | `application/json` | | `orgCode` | 机构编码(机构的社会统一信用代码,约 18~20 位)。接入方先把组织/机构信息提供给平台,由平台生成 | | `deviceSN` | 设备序列号。docx 标各类接口必填,但**联调实测** JKDA00002 查询 `deviceSN` 为空仍成功——查询类可空;创建/更新是否必填待联调(docs/06 A6) | | `ts` | 13 位毫秒级时间戳 | | `userName` | 平台分配的用户名(对应一个 `ask` 密钥;同时也是报文里的第三方接入公司名称编码 `DSFMC`) | | `password` | `md5("ts=<时间戳>&ask=<密钥>")`,取 **32 位小写** | 签名要点: - `password` 的明文是字符串 `ts=&ask=`,其中 `` 必须与请求头里发送的 `ts` 完全一致; - `ask` 为平台下发的密钥,**只参与签名,绝不放进请求头或报文**; - 每个请求现算 `ts`/`password`,天然防重放(平台侧通常校验 `ts` 时效)。 > 对比旧项目:这里**不需要** SM2 公钥加密、不需要 `lw_d`/`d`/查询 `d` 加密参数、不需要按年份变化的动态字段名。 > 一个标准库 `crypto/md5` 即可完成全部鉴权。 --- ## 3. 请求报文信封 **联调实测**:请求体统一为 `serviceId` + `uploadinfo` 两段,**查询类同样走 `uploadinfo` 信封**(早期依 docx 猜测查询发裸 `baseInfo`,实测不成立): ```json { "serviceId": "<固定服务码>", "uploadinfo": { "baseInfo": { ... }, // 查询:查询条件;创建:人口学主键等 "manageInfo": { ... }, // 管理节点,查询与创建都要带 "...": { ... } // 创建/更新再加 healthRecord / pastHistory / jwsjb … 业务节点 } } ``` - `serviceId` 是每个接口的**固定常量**(见第 5 节映射表),平台据此路由业务。 - `manageInfo` 三字段(JKDA00002 查询实测携带即成功,是否可省未验证): - `DSFMC` = 第三方接入公司名称编码(= 请求头 `userName`) - `operateUnit` = 操作机构编码(= 请求头 `orgCode`) - `operateUser` = 操作用户 / 责任医生 ID - 文档中创建样例外层出现的 `"headers": {...}` 仅用于演示 HTTP 头,**不是 body 的一部分**。 > **三种机构相关编码分属不同层级,切勿混用**(实测确认): > - 请求头 `orgCode` / `manageInfo.operateUnit`:**18 位统一社会信用代码**(如 `12…G`),是接入机构的鉴权身份。 > - 记录内 `manaUnitId` / `createUnit`:**9 位机构编码**,落在档案数据上。 > - `regionCode` / `addressCode`:**12 位行政区划/网格码**。 > 注意:`config.yaml` 里的 `org_code`(9 位)其实是 `manaUnitId`,**不是**请求头 `orgCode`;请求头 orgCode 需用 18 位码,两者不要填反。 --- ## 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` ✅联调确认(docx 样例误写 `TNB00004`) | `uploadinfo.baseInfo`(idCard/phrid/personName 三选一) + `manageInfo`;响应见 docs/04 §8 | | 更新 | `/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` | ✅ 联调可用(按 idCard/phrid 查,返回全部体检数组)| | 更新 | `/osi/api/jktj/update` | `JKTJ00003` | 待写入授权 | | 已检/待检人员列表 | `/osi/api/auto/jktjlist/query` | `JKTJLIST00002` | ✅ 联调可用(T-305,入参 checkYear+分页)| | 最近一次体检 | `/osi/api/auto/jktjlscx/query` | `JKTJLSJL00002` | ✅ 联调可用(T-301) | > 体检报文体量大(实测最近一次约 260 字段,分 4 object + 3 array 子节点),是字段映射工作量最大的一块。响应结构与字段清单见 `docs/04 §11`。 ### 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` —— ✅**联调已确认为 `JKDA00002`**。 2. **字段名不一致**:创建档案家族史父亲在字段定义里叫 `jzsfqn`,在请求样例里叫 `jzsfq`;现住址门牌号在创建里 `addressNumber`、在查询里 `adressNumber`(少一个 d)—— ✅JKDA00002 **响应实测确实返回 `adressNumber`(缺 d)**,响应侧以错拼写为准;创建侧入参拼写仍待联调核对。 3. **类型不一致**:`familyMiddle` 在创建接口标 `object`,在查询接口标 `list`;`pastHistory` 同样在不同接口标注不同 —— ✅JKDA00002 **响应实测 `pastHistory`/`familyMiddle` 均为 object**,`jwsjb`/`jwssx`/`jwsss`/`jwsws` 为 array(见 docs/04 §8)。 4. **样例 JSON 非法**:多处查询样例花括号不配对(如 `{ "baseInfo": {...} }, "serviceId": "..." }`)。⚠实测请求信封为 `{ "serviceId": "...", "uploadinfo": { "baseInfo": {...}, "manageInfo": {...} } }`,查询条件包在 `uploadinfo.baseInfo` 内,**不是**外层裸 `baseInfo`。 5. **成功码不是 `"1"`**:docx/早期整理写成功 `code="1"`,✅**联调实测为 `code="01"`**(见第 1 节),成功判定需兼容前导零。 6. **列表查询路径缺漏**:xlsx 要求"档案列表查询""自理/体质/中医指导列表查询""自理查询"等,但 docx 正文未给出全部独立路径与 serviceId,需向厂家索要补充。 > 结论:**不能直接照搬 docx 字段表生成契约**。落地前应整理一份「校验后的接口契约」(见 03 文档 `contract/` 包), > 并以厂家沙箱环境的真实请求/响应样本做回归校准。