- docs/: OSI 接口规范分析、旧项目架构评估、目标架构设计、字段与接口映射、实施路线图 - CLAUDE.md: 协作规则(项目认知、osi/mapping/pipeline 三层技术约束、安全/验证、提交规范) - .gitignore: 补充项目特定忽略(config.yaml/logs/样本等) - 随项目留存厂家 OSI 规范源材料(docx/xlsx,内部保密,仅限本私有仓库) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
10 KiB
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 响应统一结构
{ "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)统一为:
{
"serviceId": "<固定服务码>",
"uploadinfo": { ... } // 创建/更新类:写入数据
}
或查询类:
{
"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 存在明显的复制粘贴/排版错误,建模前需逐一核对:
- serviceId 串台:
jkda/find的请求样例里 serviceId 写成TNB00004(糖尿病接口的码),实际应为JKDA00002。 - 字段名不一致:创建档案家族史父亲在字段定义里叫
jzsfqn,在请求样例里叫jzsfq;现住址门牌号在创建里addressNumber、在查询里adressNumber(少一个 d)。 - 类型不一致:
familyMiddle在创建接口标object,在查询接口标list;pastHistory同样在不同接口标注不同。 - 样例 JSON 非法:多处查询样例花括号不配对(如
{ "baseInfo": {...} }, "serviceId": "..." }),应理解为{ "serviceId": "...", "baseInfo": {...} }。 - 列表查询路径缺漏:xlsx 要求"档案列表查询""自理/体质/中医指导列表查询""自理查询"等,但 docx 正文未给出全部独立路径与 serviceId,需向厂家索要补充。
结论:不能直接照搬 docx 字段表生成契约。落地前应整理一份「校验后的接口契约」(见 03 文档
contract/包), 并以厂家沙箱环境的真实请求/响应样本做回归校准。