Files
chis_osi/docs/07-本项目HTTP接口.md
T

243 lines
9.8 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.
# 07 · 本项目 HTTP 接口
`chis_osi` **server 模式**对外提供的 HTTP 查询与健康档案 upsert 接口——供前端/运维/PHIS 侧调用。
> 这是本项目**自己**对外的接口的单一事实来源;调用**上游厂家 OSI** 的接口契约看 `docs/01`、`docs/04`。
> 新增/修改端点后同步本文(与 `handler/`、`server.go` 保持一致)。
> 机器可读 OpenAPI 文档见 [`openapi.yaml`](openapi.yaml)。
---
## 启动
```bash
go run . -mode server # 默认监听 127.0.0.1:8080
go run . -mode server -addr 127.0.0.1:9000 # 指定地址
```
凭据从 `config.yaml`(嵌套 `osi:` 段)读取;服务经 SOCKS5 代理访问内网 OSI 主机。
⚠ **默认仅绑 `127.0.0.1`**:所有端点回写真实居民档案/体检或平台主数据。后续内网部署可用 `-addr <内网IP>:<端口>` 监听内网地址,但本服务当前不内置鉴权;上线前必须通过内网访问控制/API 网关补鉴权、日志脱敏和限流。
---
## 通用约定
| 项 | 说明 |
| --- | --- |
| 查询方法 | `GET`,查询条件走 query string |
| Upsert 方法 | `POST`,请求体为 PHIS 健康档案响应信封,最大 1 MiB |
| 查询成功响应 | **直接回写平台完整 JSON**(`{code,message,data}`,不裁字段),`Content-Type: application/json` |
| 平台成功码 | `code="01"`(字符串,见 docs/01 §1)——本服务不改写,原样透传 |
| 参数错误 | `400`,体为 `{"error":"..."}`(如缺必填标识符) |
| 上游失败/网络错误 | `502`,体为 `{"error":"..."}` |
| 方法不对 | `405` |
> 设计取舍:端点**原样回写平台响应**(同 `Result.Raw`),不做字段裁剪/转换——保证平台未建模字段也能拿到,便于查看完整档案/体检。
健康档案 upsert 不透传 OSI 原文,只返回脱敏的结构化结果。其运行时先做无网络字段/码表预校验,再按档案 `manaUnitId` 查询责任医生和机构主数据,最后调用 T-213 的 query-first 应用服务。当前 HTTP 模式只使用**进程内并发租约**:可防同进程同时投递,成功后立即释放,后续版本仍会重新查询并更新;它不提供跨重启完成记录,持久化幂等仍属于路线图阶段 3。
---
## 端点清单
### 1. 查询个人健康档案
```
GET /api/health-record/find
```
| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `idCard` / `phrid` / `personName` / `empiId` | **四选一** | 查询标识符,只能给一个 |
- 上游:`JKDA00002` `/auto/jkda/find`
- 返回:`data` 为**数组**(档案聚合,含 healthRecord/pastHistory/既往史等,见 docs/04 §8)
### 2. 查询人群分类/子档案标记
```
GET /api/health-record/crowd
```
| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `idCard` / `phrid` | **二选一** | 查询标识符,只能给一个 |
- 上游:`JKDA00005` `/auto/jkda/findrqbj`
- 返回:`data` 为对象,含 `personSign`、`idCard`、`phrId`(见 docs/04 §12)
- `personSign` 是人群分类码,可能为逗号分隔多值;码表见 docs/04 §3
### 3. 最近一次体检
```
GET /api/health-check/last
```
| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `idCard` / `phrid` / `empiId` | **三选一** | |
- 上游:`JKTJLSJL00002` `/auto/jktjlscx/query`
- 返回:`data` 为**单个对象**(最近一次完整体检,约 260 字段,见 docs/04 §11.3)
### 4. 某人全部体检
```
GET /api/health-check/all
```
| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `idCard` / `phrid` / `empiId` | **三选一** | |
- 上游:`JKTJ00002` `/auto/jktj/query`
- 返回:`data` 为**数组**(该人全部体检历史,每条完整)
- 注意:历史记录 `checkId` 可能为 `null`(仅近年有),历史体检按 `checkDate` 区分(docs/04 §11.1)
### 5. 年度已检/未检人员名单
```
GET /api/health-check/list
```
| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `checkYear` | **是** | 检查年度,如 `2025` |
| `idCard` | 否 | 过滤到某人 |
| `checkType` | 否 | `0`已检 / `1`未检 / `2`全部 |
| `page` `rows` | 否 | 分页,默认 `1` / `10` |
- 上游:`JKTJLIST00002` `/auto/jktjlist/query`
- 返回:`data` 为**数组**(人员名单 + `checkType` 状态,**非体检明细**,见 docs/04 §11.4)
### 6. 查询网格地址
```
GET /api/dictionaries/grid-addresses
```
| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `parentCode` | 否 | 上级区划/网格编码 |
| `pageNo` | 否 | 页码,整数 |
| `operateUser` | 否 | 平台操作人编码 |
- 上游:`WGDZ00001` `/auto/wgdzcx/query`
- 返回:`data` 为**数组**(网格地址主数据,含 `regionCode`、`regionName`、`isFamily` 等)
### 7. 查询责任医生
```
GET /api/dictionaries/doctors
```
| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `manaUnitId` | 否 | 9 位管理机构码 |
| `operateUser` | 否 | 平台操作人编码 |
- 上游:`ZRYS00001` `/auto/zryscx/query`
- 返回:`data` 为**数组**(责任医生主数据,含 `personId`、`personName` 等)
### 8. 查询药品目录
```
GET /api/dictionaries/drugs
```
| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `pageNo` | **是** | 页码,整数——药品目录是**分页查询**,必填 |
| `pageSize` | 否 | 每页数量,整数 |
| `ypmc` | 否 | 药品名称关键字 |
| `pym` | 否 | 拼音码 |
- 上游:`YPML00001` `/auto/ypmlcx/query`(**分页目录查询**,非按名单条)
- 返回:`data` 为**数组**(一页药品),每条含 `ypxh`(序号)/`ypmc`/`ypdw`/`ypgg`/`ypjl`(剂量)/`ycjl`(一次剂量)/`jldw` 等
- ⚠ 依 docx 契约,**YPML00001 尚未真实联调**:`pageNo` 是否真必填、`pageSize` 字段名、响应字段均以联调实测为准
### 9. 查询机构
```
GET /api/dictionaries/orgs
```
| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `organizCode` | 否 | 机构编码;HTTP 未传时仍会向 OSI 显式上送空字符串 |
| `parentId` | 否 | 上级机构 ID/编码;HTTP 未传时仍会向 OSI 显式上送空字符串 |
- 上游:`CXJG00002` `/auto/cxjg/query`
- 返回:`data` 为**数组**(机构主数据,含 `organizCode`、`organizName`、`organizType`、`parentId`、`regionCode` 等);`regionCode` 可能为 null
- OSI 要求 `organizCode` 和 `parentId` 两个 `baseInfo` key 都存在,值可为空;本服务已保证该行为
### 10. 查询老年人生活自理能力评估
```
GET /api/elderly/self-care
```
| 参数 | 必填 | 说明 |
| --- | --- | --- |
| `idCard` | **是** | 身份证件号 |
| `phrId` | 否 | 健康档案编号(注意驼峰 `phrId`) |
| `checkId` | 否 | 第三方检查主键 |
- 上游:`LNRZLPG00002` `/auto/lnr/query`(厂家文档契约,待真实联调确认)
- 返回:`data` 为**数组**,每条含进餐/梳洗/穿衣/如厕/活动及总评的原始值、等级和评分;完整字段原样回写
### 11. 创建或更新个人健康档案
```
POST /api/health-record/upsert
Content-Type: application/json
```
请求体使用 PHIS 健康档案响应信封:顶层 `code` 必须为 `200`,`data.archId` 必填;`data.doctor` 和 `data.record` 字段结构见 `source.HealthRecordTask`。医生账号、密码即使出现在原始 JSON 中也会被解码器忽略,不进入领域模型和 OSI 请求。
处理规则:按身份证查询 CHIS,明确 0 条时创建,1 条且身份证、状态、机构、责任医生和 `phrId` 均安全时更新;多条或不安全目标转人工处理。查询失败绝不降级创建。
| HTTP 状态 | pipeline 状态 | 说明 |
| --- | --- | --- |
| `200` | `done` | 创建、更新或幂等跳过完成 |
| `409` | `manual_review` | 多档案、跨机构、跨医生、状态不可更新等,禁止自动写入 |
| `422` | `failed` | PHIS 字段、必填、格式、码表或主数据校验失败 |
| `502` | `failed` 或内部错误 | CHIS/字典上游失败,或写入成功后的本地收尾失败 |
| `503` | `retry` | 查询/写入暂时失败或同一档案正在处理 |
正常响应示例:
```json
{"status":"done","action":"update","serviceId":"JKDA00003","responseCode":"01","phrIdHint":"****1234"}
```
内部错误响应包含 `retrySafe`。若 CHIS 已明确写入成功但幂等完成或通知失败,会保留 `outcome.status="done"` 且返回 `retrySafe=false`,调用方不得重放整个 upsert,只能按错误补偿后置动作。
> 当前未完成 T-215 真实写入验收。没有安全测试档案和明确写入授权时,不得用真实居民调用此端点。
---
## 调用示例
```bash
curl "http://127.0.0.1:8080/api/health-record/find?idCard=<身份证>"
curl "http://127.0.0.1:8080/api/health-record/crowd?idCard=<身份证>"
curl "http://127.0.0.1:8080/api/health-check/last?idCard=<身份证>"
curl "http://127.0.0.1:8080/api/health-check/all?idCard=<身份证>"
curl "http://127.0.0.1:8080/api/health-check/list?checkYear=2025&idCard=<身份证>"
curl "http://127.0.0.1:8080/api/dictionaries/grid-addresses?parentCode=<区划码>&pageNo=1"
curl "http://127.0.0.1:8080/api/dictionaries/doctors?manaUnitId=<机构码>&operateUser=<操作人>"
curl "http://127.0.0.1:8080/api/dictionaries/drugs?pageNo=1&pageSize=10&ypmc=<药品名>&pym=<拼音码>" # pageNo 必填
curl "http://127.0.0.1:8080/api/dictionaries/orgs?organizCode=<机构码>&parentId=<上级机构ID>"
curl "http://127.0.0.1:8080/api/elderly/self-care?idCard=<身份证>&phrId=<档案号>&checkId=<检查主键>"
curl -X POST "http://127.0.0.1:8080/api/health-record/upsert" -H "Content-Type: application/json" --data-binary "@<phis-health-record.json>"
```
---
## 尚未提供(后续)
- 体检等其他业务写入端点:待对应 PHIS 转换、upsert 编排及厂家写入授权。
- 老年人中医体质辨识、中医指导查询端点:待对应 OSI serviceId/字段契约(docs/06 B4)。
- 鉴权、访问日志、限流:当前是本机联调工具形态,对外前必须补齐。