Files

6.8 KiB

API / 模块合约

本文定义第三方 API、统一响应和内部模块合约的目标形状。实现前可细化,但不要在代码里另起一套不兼容接口。

通用约定

  • 传输:HTTPS JSON。
  • 编码:UTF-8 JSON。
  • 时间格式:YYYY-MM-DD 用于业务日期,时间戳使用 ISO 8601。
  • 第三方鉴权:待定,推荐 Authorization: Bearer <token> 或 X-App-Key + X-Signature。
  • 每个响应包含 trace_id。
  • 每个 API 请求都生成一个 archive 文件,保存 API 和 CHIS 请求 / 响应,详见 架构设计 的请求归档文件章节。

成功响应:

{
  "ok": true,
  "trace_id": "TRACE_ID",
  "data": {}
}

错误响应:

{
  "ok": false,
  "trace_id": "TRACE_ID",
  "error": {
    "code": "bad_request",
    "message": "请求参数不正确"
  }
}

第三方 API

POST /api/v1/health-checks/query-detail

用途:查询 CHIS 中某次体检详情。第一版用于验证 CHIS 登录、Redis 会话、通用请求和查询链路。

第一版请求要求调用方传全参数:

{
  "account_ref": "chis-account-alias",
  "healthCheck": "0000000000481718",
  "phrId": "44162511100102877",
  "idCard": "440000********1234",
  "checkDate": "2014-06-05"
}

说明:

  • healthCheck + phrId + idCard 用于调用 CHIS getHMNIListOfHTML。
  • idCard + checkDate 用于调用 CHIS getCheckInfoDetail。
  • 当前资料不能证明只传 healthCheck 就能查完整详情;后续任务会验证反查链路。

成功响应:

{
  "ok": true,
  "trace_id": "TRACE_ID",
  "data": {
    "healthCheck": "0000000000481718",
    "detail": {},
    "check_info": {}
  }
}

POST /api/v1/health-checks/submit

用途:提交单条体检数据到 CHIS。

请求示例(字段待后续业务样例细化):

{
  "request_id": "third-party-unique-id",
  "source": "third-party-system",
  "account_ref": "chis-account-alias",
  "person": {
    "id_card": "440000********1234",
    "name": "张三"
  },
  "check_date": "2026-07-04",
  "health_check": {
    "height": 170,
    "weight": 65
  }
}

成功响应:

{
  "ok": true,
  "trace_id": "TRACE_ID",
  "data": {
    "request_id": "third-party-unique-id",
    "idempotent": false,
    "chis_result": {
      "code": 200,
      "message": "success"
    }
  }
}

重复提交响应:

{
  "ok": true,
  "trace_id": "TRACE_ID",
  "data": {
    "request_id": "third-party-unique-id",
    "idempotent": true,
    "chis_result": {
      "code": 200,
      "message": "success"
    }
  }
}

错误码

code HTTP 说明
unauthorized 401 第三方鉴权失败
forbidden 403 第三方无权限使用该账号或机构
bad_request 400 请求体格式错误或必填字段缺失
invalid_health_check_data 400 体检字段校验失败
missing_health_check_query_params 400 查询体检详情缺少 healthCheck、phrId、idCard 或 checkDate
chis_login_failed 502 CHIS 登录失败
chis_session_invalid 502 CHIS 会话无效且重登失败
chis_request_failed 502 CHIS 业务接口失败
chis_timeout 504 CHIS 请求超时
idempotency_conflict 409 相同幂等键对应不同请求体

内部模块合约

ChisLoginClient.from_config(config).login(username, password)

输入:

username: str
password: str

输出:

ChisLoginSession(
    cookie=str,
    jsessionid=str,
    role_id=str,
    role_name=str,
    user_name=str,
    roles_result=dict,
    apps_result=dict,
)

职责:

  • 从 CHIS_BASE_URL、CHIS_PUBLIC_KEY、CHIS_PROXY 创建登录客户端。
  • 调用 logon/myRoles,使用 SM2 加密密码和时间戳 d。
  • 优先选择 责任医生助理 或 责任医生 角色。
  • 调用 logon/myApps 获取应用上下文。
  • 从 Set-Cookie 提取 JSESSIONID,组装 CHIS cookie。
  • 登录失败、缺少允许角色、缺少 cookie 时抛出 ChisLoginError,错误对象包含稳定 code。

ChisLoginClient.get_lander_info(cookie)

输入:

cookie: str

输出:CHIS chis.myPageService / getLanderInfo 原始字典响应。

职责:

  • 使用已有 CHIS cookie 调用 *.jsonRequest?。
  • 请求体固定为 serviceId=chis.myPageService、serviceAction=getLanderInfo、method=execute。
  • 成功时返回当前账号信息响应。
  • CHIS 返回非 200 业务码时抛出 ChisLoginError(code="chis_session_invalid"),用于判断会话无效。

RedisChisSessionStore

职责:

  • 使用 Redis key chis:session:{account_ref} 保存 CHIS 会话对象。
  • save(account_ref, session) 按 expires_at 计算 TTL 并调用 Redis setex。
  • get(account_ref) 只返回未过期会话;发现过期会话时删除缓存并返回 None。
  • delete(account_ref) 清理指定账号引用的缓存。
  • 会话 JSON 包含 base_url、uid、role_id、manage_unit、cookies、login_at、expires_at、last_validated_at,不得包含明文密码。

ChisSessionManager.ensure_session(account_ref)

输入:

account_ref: str

输出:

ChisSession(
    cookies=dict,
    uid=str,
    role_id=str | None,
    manage_unit=str | None,
    expires_at=datetime,
)

职责:

  • 优先读取 Redis 有效会话。
  • 会话不存在或验证失败时登录 CHIS。
  • 登录成功后缓存会话。
  • 不返回明文密码。

ChisCrypto.sm2_encrypt(public_key, raw_text)

职责:

  • 使用配置中的 CHIS public key 加密密码和时间戳 d。
  • 兼容已有 hans_chis.sm2.sm2_encrypt 行为:gmssl.sm2.CryptSM2(mode=0),返回带 04 前缀的十六进制密文。
  • 不记录明文和密文到普通业务日志。

HealthCheckQueryClient.get_detail(session, health_check, phr_id, id_card)

输出:CHIS getHMNIListOfHTML 的标准化结果。

职责:

  • 组装 chis.healthCheckService / getHMNIListOfHTML 请求。
  • 不做第三方鉴权。
  • 不保存数据。

HealthCheckQueryClient.get_check_info(session, id_card, check_date)

输出:CHIS getCheckInfoDetail 的标准化结果。

职责:

  • 组装 chis.healthCheckService / getCheckInfoDetail 请求。
  • 身份证号日志脱敏。

HealthCheckMapper.to_chis_payload(input_model, session_context)

输入:内部体检标准模型和 CHIS 会话上下文。

输出:CHIS *.jsonRequest 请求体。

职责:

  • 字段映射。
  • 字典值转换。
  • 默认值和空值处理。
  • 不访问网络,不访问 Redis。

ChisClient.json_request(session, payload)

职责:

  • 发送 CHIS *.jsonRequest。
  • 携带 cookie 和 header。
  • 根据配置处理出站代理:CHIS_PROXY 为空直连;有值时为 CHIS HTTP 请求设置同一个 SOCKS5 代理。
  • 处理 timeout、CHIS 错误、未登录。
  • 返回标准化 CHIS 响应对象。