- 成功码实测为字符串 "01"(docx 误写 "1"),判定按去前导零 - 查询类同走 uploadinfo 信封(baseInfo+manageInfo),非裸 baseInfo - 三种机构码分层:18位统信码 / 9位机构码 / 12位区划码 - docs/04 新增 §8 JKDA00002 实测契约(请求信封+响应结构,已脱敏) - docs/06 回填 A1~A9/B3/B6/C3/D2/D3 联调状态 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
12 KiB
04 · 字段与接口映射
本文是 mapping/ 与 contract/ 两层的落地指引:接口能力映射、PHIS→OSI 字段映射策略、码表清单、checkId 幂等键设计。
1. 接口能力 → 内部方法映射
| OSI serviceId | 路径 | 内部方法(osi 包) |
dataType(pipeline 分流) |
|---|---|---|---|
| JKDA00001 | /jkda/create |
CreateHealthRecord |
health_record |
| JKDA00003 | /jkda/update |
UpdateHealthRecord |
health_record |
| JKDA00002 | /auto/jkda/find |
FindHealthRecord |
(查询) |
| JKDA00005 | /jkda/findrqbj |
FindPersonSign |
(查询) |
| JKTJ00001 | /jktj/create |
CreateHealthCheck |
health_check |
| JKTJ00003 | /jktj/update |
UpdateHealthCheck |
health_check |
| JKTJ00002 | /auto/jktj/query |
QueryHealthCheck |
(查询) |
| JKTJLIST00002 | /auto/jktjlist/query |
ListHealthCheckPeople |
(查询) |
| JKTJLSJL00002 | /auto/jktjlscx/query |
LastHealthCheck |
(查询) |
| LNRZLPG00001 | /lnrzlpg/create |
CreateElderlySelfCare |
elderly_self_care |
| LNRZLPG00003 | /lnrzlpg/update |
UpdateElderlySelfCare |
elderly_self_care |
| LNRZYTZ00001 | /lnrzyygl/create |
CreateTCMConstitution |
tcm |
| LNRZYTZ00003 | /lnrzyygl/update |
UpdateTCMConstitution |
tcm |
| (待确认) | /auto/zyjkzd/create |
SaveTCMGuidance |
tcm_guidance |
| (待确认) | /auto/zyjkzd/update |
UpdateTCMGuidance |
tcm_guidance |
| WGDZ00001 | /auto/wgdzcx/query |
QueryGridAddress |
(字典) |
| ZRYS00001 | /auto/zryscx/query |
QueryDoctors |
(字典) |
| YPML00001 | /auto/ypmlcx/query |
QueryDrugs |
(字典) |
| CXJG00002 | /auto/cxjg/query |
QueryOrgs |
(字典) |
⚠ "(待确认)"项以 01 文档第 7 节为准,联调回填后更新
osi/codes.go的 serviceId 常量与pathOf路由表。
2. 字段映射策略
2.1 三类字段,三种处理
- 直传字段:PHIS 与 OSI 同义且同形(如姓名、出生日期
yyyy-MM-dd)。直接拷贝,做必填/长度校验。 - 码表字段:枚举值需经字典转换(性别、民族、血型、职业…)。统一走
dict.go双向查表,未命中报ValidationError,绝不静默置空。 - 结构/多选字段:嵌套节点(既往史/家族史/手术/外伤/输血/生活环境)、逗号拼接多选。集中在各业务域映射函数里组装。
2.2 映射函数约定
// 返回结构化校验错误,pipeline 在投递前据此拦截,避免把脏数据打到平台。
func MapHealthRecord(src phis.HealthRecord, ctx MapContext) (contract.HealthRecordCreate, []ValidationError)
MapContext携带机构级常量:orgCode/userName/operateUser/regionCode默认值与字典快照。- 校验项:必填(idCard/personName/sexCode/birthday/mobileNumber/regionCode/manaDoctorId/manaUnitId…)、长度上限、码表合法性、日期格式。
- 映射是纯函数,便于用 01 文档样例 + 联调真实样本做单测(对齐旧项目"可测试改动补最小必要测试")。
3. 码表清单(dict.go 初始内容)
取值来自 docx 字段说明,建模时全部落为常量表,并加注释标"来源:OSI 文档 §字段名"。
| 维度 | 取值(节选) |
|---|---|
| 性别 sexCode | 0 未知 / 1 男 / 2 女 / 9 未说明 |
| 户籍 registeredPermanent | 1 户籍 / 2 非户籍 |
| 血型 bloodTypeCode | 1 A / 2 B / 3 O / 4 AB / 5 不详 |
| RH rhBloodCode | 1 阳性 / 2 阴性 / 3 不详 |
| 文化程度 educationCode | 10 研究生 / 20 本科 / 31 大专 / 41 中专 / 47 技校 / 60 高中 / 70 初中 / 80 小学 / 90 文盲 / 91 不详 |
| 职业 workCode | 0 负责人 / 1·2 专技 / 3 办事 / 4 商业服务 / 5 农林牧渔 / 9-9 生产运输 / X 军人 / Y 其他 / 8 无职业 |
| 婚姻 maritalStatusCode | 10 未婚 / 20 已婚 / 30 丧偶 / 40 离婚 / 90 未说明 |
| 医保 insuranceCode(多选) | 01 城镇职工 / 02 城乡居民 / 04 贫困救助 / 05 商业 / 06 全公费 / 07 全自费 / 99 其他 |
| 民族 nationCode | 01 汉 … 56 基诺 / 99 其他(56 项全表) |
| 人群标记 personSign | PU 普通 / GRQY 已签约 / LAO 老年 / GAO 高血压 / TANG 糖尿病 / FU 孕产妇 / ER 儿童 / FEI 肺结核 / JING 精神 / CAN 残疾 |
| 药物过敏 ywgms(多选) | 0101 无 / 0102 青霉素 / 0103 磺胺 / 0104 链霉素 / 0109 其他 |
| 既往疾病 jwsjbcode | 0201 无 / 0202 高血压 / 0203 糖尿病 / … / 0299 其他 |
| 残疾 cjqk(多选) | 1101 无 / 1102 视力 / 1103 听力 / 1104 言语 / 1105 肢体 / 1106 智力 / 1107 精神 / 1108 孤独症 / 1109 脑瘫 / 1199 其他 |
| 厨房排风 cookAirTool | 1 无 / 2 油烟机 / 3 换气扇 / 4 烟囱 / 9 其他 |
| 燃料 fuelType | 1 液化气 / 2 煤 / 3 天然气 / 4 沼气 / 5 柴火 / 9 其他 |
| 饮水 waterSourceCode | 1 自来水 / 2 净化水 / 3 井水 / 4 河湖水 / 5 塘水 / 9 其他 |
| 厕所 washroom | 1 卫生厕所 / 2 粪池式 / 3 马桶 / 4 露天粪坑 / 5 简易棚厕 / 6 其他 |
| 机构类型 organizType | A 医院 / B 社区中心(站) / C 卫生院 / D 门诊诊所村室 / D6 村卫生室 / R 市卫生局 |
多选字段统一用英文逗号拼接(文档示例如
"0102,0103")。注意 docx 个别返回样例用了中文逗号,解析时两者都要兼容。
4. 主数据依赖:字典服务先行
创建类接口的若干必填字段依赖公共服务查询结果,建议在投递前用字典缓存解析:
regionCode ← QueryGridAddress(parentCode) // 网格地址
manaDoctorId/operateUser ← QueryDoctors(manaUnitId) // 责任医生
manaUnitId/organizCode ← QueryOrgs(...) // 机构
策略:启动或定时拉取这些字典,缓存到本地(redis 可选 + 内存),映射时按 PHIS 的地址/医生/机构名称反查 OSI 码。命中失败计入校验错误,不投递。
5. checkId 与幂等键设计
checkId(第三方业务唯一识别码,长度 20)是新项目幂等的核心。
5.1 生成规则(mapping/checkid.go)
要求确定性:同一源记录无论重试多少次,都得到同一 checkId。
checkId = 截断20位( 编码( 源系统标识 | dataType | 源记录主键 [ | 版本/更新时间] ) )
- 同一条源记录的"创建"应使用稳定 checkId → 平台据此识别为同一档案,避免重复建档。
- "更新"沿用原 checkId(走 update 接口)。
- 若源记录内容变更需视为新版本上送,可把"更新时间/版本号"纳入 checkId 计算——取决于平台是否以 checkId 去重(见 03 文档开放问题 5)。
5.2 幂等存储
- 键:
checkId(替代旧项目account|idCard|dataType|sha1(saveBody))。 - 值:
{status: success|failed, phrId, lastTs, attempts}。 - 命中
success:跳过,不重复投递。 failed:允许后续重试。- 存储:redis 优先、本地 JSON 降级(沿用旧项目
idempotency_store思路)。
用 checkId 做幂等键的好处:与平台对账口径一致(平台也认 checkId),且不受报文字段微调影响。
6. 校验与错误分类(与 pipeline 配合)
成功码以 docs/01 §1 为准:实测为字符串
"01"(非"1"),判定按去前导零后 =="1"。
| 错误来源 | 分类 | 处理 |
|---|---|---|
| 映射缺必填/码表未命中/格式非法 | 不可重试(数据错) | 直接 failed,回写 PHIS,附 ValidationError 明细 |
| 网络错误 / SOCKS / EOF / 超时 | 可重试 | 退避重试,计熔断 |
OSI code == "405"(服务超时) |
可重试 | 退避重试 |
OSI code 非成功码非 405(业务/权限拒绝) |
不可重试 | failed,记 message 供排查 |
| HTTP 5xx / 429 | 可重试 | 退避重试 |
7. 待补字段表
以下接口的完整字段表 docx 未充分给出或存在坑点,建模时以联调样本为准并在此登记:
- 体检
jktj/create全量字段(hcData/lsData/exaData/aeData,体量最大) - 老年人自理评估
lnrzlpg字段 - 中医体质辨识
lnrzyygl字段 - 中医健康指导
zyjkzd字段 + serviceId - 个人档案查询 JKDA00002 的请求信封与返回结构 —— 已联调实测,见 §8
- 其余列表/查询接口的分页与返回数组结构(体检/老年人/中医指导)
8. JKDA00002 个人档案查询 · 联调实测契约
来源:2026-07 沙箱一次成功查询(
code="01"操作成功)。下方均为脱敏结构,真实身份证/姓名/联系方式等 PII 只在本地样本,不入库。 这是contract/里FindHealthRecord请求/响应结构体与osi.FindHealthRecord的事实基线。
8.1 请求(POST /osi/api/auto/jkda/find)
{
"serviceId": "JKDA00002",
"uploadinfo": {
"baseInfo": { "idCard": "<idCard>" },
"manageInfo": { "DSFMC": "<userName>", "operateUser": "<operateUser>", "operateUnit": "<orgCode-18位>" }
}
}
baseInfo三选一:idCard/phrid/personName。manageInfo三字段来自机构级常量(见 docs/01 §3 三种机构码区分)。- 请求头另带
orgCode(=operateUnit) /deviceSN(查询可空) /ts/userName(=DSFMC) /password,签名规则见 docs/01 §2。
8.2 响应(code="01",data 为数组,每元素 = 一份档案聚合)
| 节点 | 类型 | 说明 |
|---|---|---|
healthRecord |
object | 档案主体(人口学 + 管理字段),见 8.3 |
pastHistory |
object | 既往史标志位:ywgms(药物过敏)/jwsjb标志/bls/ycbs(遗传病)/cjqk(残疾)/jzsfqn/jzsmq/jzszn/jzsxdjm(家族史·父/母/子女/兄弟姐妹) 等 code |
jwsjb |
array | 既往疾病:{ jwsjbcode, jwsjbmc, jwsjbqzsj(确诊时间) } |
jwsss |
array | 既往手术:{ jwssscode, jwsssmc, jwsssqzsj } |
jwsws |
array | 既往外伤:{ jwswscode, jwswsmc } |
jwssx |
array | 既往输血:{ jwssxcode, jwssxyy(原因) } |
familyMiddle |
object | 生活环境:waterSourceCode/fuelType/cookAirTool/washroom/livestockColumn/isFillShhj |
pastHistory/familyMiddle实测是 object(非 docx 查询侧标的 list);多选标志仍以码值出现。
8.3 healthRecord 关键字段(实测字段名,注意坑点拼写)
| 字段 | 语义 | 备注 |
|---|---|---|
idCard personName sexCode birthday |
人口学主键四要素 | 直传+校验 |
phrId |
健康档案号 | 注意驼峰 phrId(查询入参用小写 phrid) |
empiId |
EMPI 主索引 | 32 位十六进制串 |
checkId |
第三方业务唯一码 | 本样本为 null(存量档案无 checkId)→ 佐证幂等键需我方生成,见 §5 |
manaUnitId createUnit |
管辖/建档机构 | 9 位机构码,≠ 请求头 orgCode(18位) |
manaDoctorId createUser |
责任医生/建档人 | 机构内人员 ID |
regionCode addressCode homePlaceCode |
行政区划/网格码 | 12 位 |
address adressNumber |
现住址/门牌号 | ⚠门牌号字段名少一个 d:adressNumber |
homePlace homePlaceNumber |
户籍地/门牌 | |
nationCode educationCode workCode maritalStatusCode bloodTypeCode rhBloodCode insuranceCode |
码表字段 | 走 dict.go 双向查表(§3) |
personGroup otherPersonGroup |
人群标记 | 与 JKDA00005 personSign 联动 |
isFillShhj |
是否填生活环境 | y/n |
contact contactPhone mobileNumber phoneNumber |
联系人/电话 | PII |
status createDate |
档案状态/建档日期 |
建模提示:
data用数组承接(可能多档案/多版本);insuranceType、otherPersonGroup、checkId等实测可为null,结构体用指针或omitempty,映射层不得因 null 报错。