# 手术室监控服务 — 客户端 HTTP API 对接说明 本文档面向**集成我方 FastAPI 后端的客户系统**(HIS、手麻、护理工作站、自研终端等),说明如何通过 HTTP 调用完成「手术开始 / 结束」「耗材结果查询」「低置信度耗材语音确认」等能力。 > **说明**:仓库内 `scripts/demo_client/` 等演示页面仅用于**内部联调与测试**,不代表生产对接规范;生产环境请按本文档与 OpenAPI 契约自行实现客户端。 --- ## 1. 服务与发现 | 项目 | 说明 | | ------- | ------------------------------------------------------------- | | 默认监听 | 应用默认 `0.0.0.0:38080`(以实际部署为准,可能经反向代理改写路径或端口) | | 基础路径 | 路由**无全局前缀**;下文路径均为相对服务根路径 | | OpenAPI | 服务启动后可访问 `**/docs`(Swagger UI)**、`**/redoc`** 获取实时 Schema 与试调 | | 健康检查 | `GET /health`:探活与数据库连通性(降级时可能返回 503) | | 跨域 CORS | 仅当服务端开启演示用 CORS 配置时对浏览器页面生效;**服务端对接通常不受 CORS 限制** | 认证方式以部署约定为准;当前公开路由未在文档层强制 API Key,若贵方环境增加了网关鉴权,请在请求头中按网关要求携带。 --- ## 2. 客户端 API 一览(`/client/...`) 所有「客户集成」接口均位于 `**/client`** 命名空间下。 | 方法 | 路径 | 摘要 | | ------ | ------------------------------------------------------------------------------- | ------------------------- | | `POST` | `/client/surgeries/start` | 开始手术:确认摄像头开录成功后返回 | | `POST` | `/client/surgeries/end` | 结束手术:确认停录成功后返回 | | `GET` | `/client/surgeries/{surgery_id}/result` | 查询该台手术的耗材明细与汇总 | | `GET` | `/client/surgeries/{surgery_id}/pending-confirmation` | 拉取一条待确认项(含 TTS 音频 Base64) | | `POST` | `/client/surgeries/{surgery_id}/pending-confirmation/{confirmation_id}/resolve` | 上传医生语音 WAV,完成确认或否认 | 路径参数 `**surgery_id`**:固定 **6 位数字**(正则 `^\d{6}$`)。 --- ## 3. 端到端业务流程(推荐时序) 以下为客户系统与手术室监控服务之间的**推荐调用顺序**与并行关系。 ```mermaid sequenceDiagram participant Client as 客户系统 participant API as 监控服务 API Client->>API: POST /client/surgeries/start Note over Client,API: body: surgery_id, camera_ids, candidate_consumables API-->>Client: 200 accepted(开录已确认) par 术中轮询 loop 按需轮询 Client->>API: GET .../result API-->>Client: 200 明细+汇总 或 503 RESULT_NOT_READY end loop 语音确认闭环(若启用) Client->>API: GET .../pending-confirmation API-->>Client: 200 待确认+MP3 或 404 无待确认 opt 有待确认 Client->>Client: 播放 prompt_audio_mp3_base64 Client->>API: POST .../resolve(multipart audio) API-->>Client: 200 accepted end end end Client->>API: POST /client/surgeries/end API-->>Client: 200 accepted(停录已确认) Client->>API: GET .../result API-->>Client: 200 归档后持久化结果(若可查) ``` ### 3.1 手术生命周期(状态视角) ```mermaid flowchart LR A[未开始] -->|POST start 成功| B[录制中 / 推理中] B -->|GET result 可 200| C[可查消耗] B -->|GET pending 可 200| D[有待确认] D -->|POST resolve| B B -->|POST end 成功| E[已结束] E -->|GET result| C ``` --- ## 4. 接口说明与请求/响应要点 ### 4.1 `POST /client/surgeries/start` **Content-Type**:`application/json` **请求体(摘要)** | 字段 | 类型 | 说明 | | ----------------------- | -------- | ------------------------------------------------------------- | | `surgery_id` | string | 6 位数字手术号 | | `camera_ids` | string[] | 至少 1 个;需与贵方 RTSP/SDK 映射中的 **摄像头 ID** 一致 | | `candidate_consumables` | string[] | 可选;**本台手术可能用到的耗材名称清单**。服务端仅对该清单内耗材做自动记账与待确认追问;为空则只做拉流推理、不写入消耗 | **成功(200)**:`SurgeryApiResponse` — `status` 一般为 `accepted`,表示**服务端已确认开录完成**。 **失败**:常见 `**503 Service Unavailable`**,`detail` 内含业务 `code`(如录制子系统未就绪、开录未确认等)。开录/停录类错误会按服务端配置**自动重试**;仍失败则返回最后一次错误信息。 ### 4.2 `POST /client/surgeries/end` **Content-Type**:`application/json` **请求体**:`{ "surgery_id": "123456" }` **成功(200)**:停录已确认。 **失败**:`503` 同 start,表示未能在确认摄像头全部停录后完成请求。 ### 4.3 `GET /client/surgeries/{surgery_id}/result` **幂等只读**。术中返回当前内存已记账结果;结束后返回数据库持久化结果(以服务端实现为准)。 **成功(200)**:`SurgeryResultResponse` - `details`:多行消耗明细,字段顺序为 `**item_id` → `item_name` → `qty` → `doctor_id` → `timestamp`** - `summary`:按 `item_id` 汇总的 `total_quantity` `**503`**:`detail.code === "RESULT_NOT_READY"` — 尚无该手术可查询结果(未开始、未成功开录或暂无可返回数据)。 ### 4.4 `GET /client/surgeries/{surgery_id}/pending-confirmation` 用于**低置信度识别**的人工确认闭环(需服务端启用语音确认及相关配置)。 **成功(200)**:包含 `confirmation_id`、`prompt_text`、候选项 `options`、`prompt_audio_mp3_base64`(与话术一致的 **MP3 标准 Base64**,无换行)、模型 Top1 等。 `**404`**:当前无待确认或手术未在进行(`NO_PENDING_CONFIRMATION`)。 `**422` / `503`**:话术为空、音频无效、ASR/TTS/MinIO/百度语音等异常时返回,详见响应 `detail.code`。 ### 4.5 `POST /client/surgeries/{surgery_id}/pending-confirmation/{confirmation_id}/resolve` **Content-Type**:`multipart/form-data` **表单字段** | 字段 | 说明 | | ------- | -------------------------------------------------------- | | `audio` | 单个 `**.wav`** 文件;建议 16 kHz 单声道 PCM;其他格式服务端可能尝试 ffmpeg 转码 | **成功(200)**:`SurgeryPendingConfirmationResolveResponse` — 含 `resolved_label`、`rejected`、`asr_text`、`audio_object_key` 等。 **常见 HTTP 状态**:`404`(确认项不存在或已失效)、`409`(已处理)、`422`(音频/解析问题)、`503`(外部依赖故障)。 --- ## 5. 错误约定 FastAPI 对 `HTTPException` 的 JSON 外形一般为: ```json { "detail": { "code": "业务错误码", "message": "人类可读说明", "surgery_id": "123456" } } ``` 部分错误可能在 `detail` 中附带额外字段(如重试剩余次数),请以实际响应与 OpenAPI 为准。 **校验错误(422)**:请求体或路径不符合 Pydantic 校验时,FastAPI 可能返回标准 `422` 验证错误结构(与上表「对象型 detail」不同),请客户端分别解析。 --- ## 6. 与内部演示能力的关系(非客户必选) 以下路由用于**内部一键联调**,客户生产系统**无需依赖**: | 路径 | 说明 | | ------------------------------------------- | -------------------------------------------------- | | `GET /internal/demo/orchestrator-status` | 探测演示编排是否开启、RTSP 配置文件是否设置等 | | `POST /internal/demo/orchestrate-and-start` | 仅在服务端开启 `DEMO_ORCHESTRATOR_ENABLED` 时注册;用于演示环境串联开录 | 客户正式对接应直接调用 `**/client/...`**,并在贵方环境中配置真实的 `camera_ids` 与视频后端映射。 --- ## 7. 联调建议 1. 先调用 `**GET /health`** 确认服务与数据库可用。 2. 用 `**POST /client/surgeries/start`** 验证 `camera_ids` 与现场 RTSP/SDK 配置一致,避免 503。 3. `**candidate_consumables**` 与实际手术耗材名称尽量与院内目录或模型标签对齐,减少待确认次数。 4. 结果查询 `**503**` 时建议**退避重试**(术中数据尚未就绪属正常现象)。 5. 以 `**/docs`** 导出或对照契约测试,与贵方 CI 中的契约测试对齐。 --- ## 8. 文档修订 接口行为以部署实例的 **OpenAPI(`/docs`)** 与代码为准;字段含义补充见仓库内 `app/schemas.py` 中各模型的 `description`。