diff --git a/docs/系统架构-网关与高性能后端.md b/docs/系统架构-网关与高性能后端.md index 064655e..0704efe 100644 --- a/docs/系统架构-网关与高性能后端.md +++ b/docs/系统架构-网关与高性能后端.md @@ -184,9 +184,15 @@ - 删除该 base64 字段,新增对应的 `*_url` 字段,值为 `https://hair.xiangsilian.com/static/annotations/{uuid}.png`; 3. 客户端最终看到的字段名/URL **与接口文档完全一致**(如 `annotated_image_url`)。 -> 网关持有一份「接口 → 图片字段」映射表(接口1: `annotated_image` ↔ 接口5: `hairline_image` 等),按表把内部 `*_base64` 转成对外 `*_url`。映射表以接口文档为准。 +> **完整字段映射表见 [`网关-开发任务书.md`](网关-开发任务书.md) §6**(接口1/2/3/5 全部 `*_base64`→`*_url`,以 `接口文档.md` 为准)。 +> ⚠️ 两个易漏点: +> 1. **数组里的图片字段**:接口2 `results[].image_base64`/`results[].grown_image_base64`、接口5 +> `hairline_images[].image_base64` 在数组元素内——改写逻辑要**递归进数组**(建议「凡 key 以 `_base64` +> 结尾就改写」的通用递归,自动覆盖嵌套与未来新增字段)。 +> 2. **可空字段**:接口2/3 的生发图(ComfyUI 未起/失败时)`*_base64` 为 **null** → 保留 null,不落盘。 > > 代价:内部 HTTP 多传一份 base64(图片放大约 1.33×)。worker↔网关若跨网络,单图 ~100KB–1MB 量级,可接受。 +> ⚠️ 生发接口(2/3)经 ComfyUI 同步出图较慢(接口2 ~18s、接口3 ~6s),网关转发**超时要调大(≥120s)**。 > > 静态文件清理:网关 `static/annotations/` 会持续增长,需加定期清理(按时间或容量,定时任务),与拆分前同样的问题,由网关侧负责。 diff --git a/docs/网关-开发任务书.md b/docs/网关-开发任务书.md index 7f27e53..fb07f08 100644 --- a/docs/网关-开发任务书.md +++ b/docs/网关-开发任务书.md @@ -122,7 +122,24 @@ curl -s http://127.0.0.1:8080/gateway-health # 200 2. **base64 → URL 改写**:拿到 worker 的 JSON 响应后,对约定的图片字段: - worker 用 `*_base64` 承载 PNG(如接口1 `annotated_image_base64`)。 - 网关:解码 → 存 `static/annotations/{uuid}.png` → **删除 `*_base64`,新增 `*_url`** = `{public_base_url}/static/annotations/{uuid}.png`。 - - 维护一张「接口路径 → 图片字段名」映射表(接口1:`annotated_image`;接口3/5 待其实现后补;**以接口文档字段名为准**)。 + - **推荐通用实现**:递归遍历 `data`,凡 key 以 `_base64` 结尾 → 落盘 → 改成同前缀 `_url`, + **包括数组元素内部的字段**(接口2/5 的图片字段在数组里)。这样新增字段自动覆盖、无需逐一硬编码。 + - `*_base64` 值可能为 **null**(如接口2/3 的生发图,ComfyUI 未起/失败时)→ 该项**保留 null、不落盘、不生成 url**。 + + **完整字段映射表**(worker 内部 `*_base64` → 对外 `*_url`,以 `docs/接口文档.md` 为准): + + | 接口 | 路径 | worker 字段(内部) | 对外字段 | 位置 | + |------|------|--------------------|----------|------| + | 1 | `/api/v1/face/measure` | `annotated_image_base64` | `annotated_image_url` | data 顶层 | + | 2 | `/api/v1/hair/grow` | `results[].image_base64` | `results[].image_url` | **数组元素** | + | 2 | 〃 | `results[].grown_image_base64` | `results[].grown_image_url` | **数组元素**(可空) | + | 3 | `/api/v1/hair/grow-b` | `best_hairline_image_base64` | `best_hairline_image_url` | data 顶层 | + | 3 | 〃 | `hair_growth_image_base64` | `hair_growth_image_url` | data 顶层(可空) | + | 4 | `/api/v1/face/features` | —(无图片字段,原样透传)| — | — | + | 5 | `/api/v1/hairline/generate` | `hairline_images[].image_base64` | `hairline_images[].image_url` | **数组元素** | + + > 接口2/5 **新增了必填 `gender` 入参**、接口3 用 `marked_image_*`+`original_image_*`——这些都是 + > **请求 multipart 参数**,网关原样透传即可,无需改造(网关对入参透明)。 3. 5 个接口路由统一走「选 worker → 转发 → 改写 → 返回」一条链路。 **验证(端到端,最终冒烟)** @@ -190,7 +207,8 @@ sudo systemctl restart hair-gateway && sudo systemctl status hair-gateway 1. **联调依赖 worker**:阶段四之前可用**本地 stub worker**(返回 `/health` 200 + 假的 base64 图)独立开发;worker 真机就绪后再换真实地址端到端联调。 2. **接口文档是字段唯一权威**:图片字段映射表、对外字段名都以 `docs/接口文档.md` 为准,冲突时以文档为准并在 PR 说明指出。 3. **安全(先跑通后处理,已知项)**:`:28187` 当前 HTTP 明文 + 公网可达,密码明文传输;后续建议加 TLS / 内网 / IP 白名单(见架构文档 §13/§14)。本阶段不阻塞。 -4. **图片字段未实现的接口**:接口 2/4/5 worker 暂为 mock,网关先按"无图片字段或透传"处理,待 worker 实现对应图片后再补映射。 +4. **接口实现进度**:接口 **1/2/3/5 worker 已真实实现**(图片字段见上方映射表);**接口 4(用户特征)仍为 mock**(无图片字段,原样透传)。 +5. **生发图耗时**:接口 2(一次 N 张 Flux,~18s)、接口 3(~6s)经 ComfyUI 同步出图,**`request_timeout_seconds` 要调大**(建议 ≥120s),否则网关会先超时换 worker 重试。 ---