Files
ozon-seller-kit/docs/v2.1/api.md
T

122 lines
7.1 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.
# V2.1 API 契约(新增 + 复用)
> 状态:前端服务层已按本文开发(Phase A);服务端 Phase B 按 本文实现。
> 通用:鉴权 `Authorization: Bearer <JWT>`(studio 走 axios 拦截器自动附带);错误统一 FastAPI `detail`。
---
## 1. 复用的现有接口(Phase A 即可用)
| 接口 | 用途(试算页) |
|---|---|
| `GET /api/products/{id}`、`PATCH /api/products/{id}` | 商品详情 / 试算页自动保存(raw/pricing/copy/price/weight/... 全字段) |
| `GET /api/products/{id}/assets` | 素材列表(分组/规格/状态/current `stored_url`、`original_url`、水印状态) |
| `GET /api/products?stage&q&page&page_size` | 批量 CSV / 组合码导出的数据源 |
| `POST /api/materials/bytes` | 试算页「上传图片」(FormData:`product_id, group_key=upload, file`)→ `{asset_id, status}` |
| `GET /api/fx` | 汇率 `{rate, source, ts}` |
| `GET /api/ai/models`、`POST /api/ai/copy` | 俄文文案(模型白名单 / 生成) |
| `POST /api/image/edit` | 智能修图页保留,不在试算页主链路 |
## 2. 套图规划 `POST /api/suite/plan`(Phase B)
**Req**
```jsonc
{
"product_id": "uuid", // 可选:便于日志与上下文缓存
"texts": [ { "kind": "title|price|params|selling_point|desc|brand|sales|shop",
"content": "…", "pairs": [ { "key": "…", "value": "…" } ] } ],
"sku_variants": ["粉色", "蓝色"],
"image_stats": { "main": 8, "sku": 6, "detail": 12 },
"platform": "ozon",
"requirements": "…|null" // 用户强制要求,最高优先级
}
```
**Res** `{ "summary": "一句话方案说明", "items": [ { "kind": "white_bg", "title": "白底主图", "detail": "…", "prompt_hint": "…", "count": 2, "variant_name": "粉色|null" } ] }`
实现要点:DeepSeek 单行紧凑 JSON;kind 白名单清洗;count 钳 0-3;幻觉 variant 丢弃绑定;总张数 AI 自主(建议 8 张左右;安全上限:默认 15,生图要求指定「N 张」时按 N、最大 24)。同步接口(数秒级)。
## 3. 一键生成 `POST /api/suite/generate`(Phase B)
**Req**
```jsonc
{
"product_id": "uuid",
"texts": [ …同上… ],
"images": [ { "url": "…", "group_key": "main|sku|detail|upload", "variant_name": "粉色|null" } ], // 勾选参考底图
"style_set": 1,
"style_prompt": "…|null", // 用户改写的风格提示词,覆盖后端模板
"requirements": "…|null",
"plan": [ …PlanItem(count>0)… ],
"platform": "ozon",
"model": "gpt-image-2-vip",
"watermark": { "enabled": true, "type": "image|text", "text": "xiongmaoyx", "opacity": 30 } // 关闭时缺省
}
```
**Res** `{ "suite_id": "…" }`
实现要点:方案按 count 展开为持久化逐图子任务;独立 Worker 领取子项并在完成后回写进度。Pcore、RightAPI 与通义万相的第三方任务 ID 会先写入数据库,重启后继续轮询同一个模型任务;完成后再水印、落 storage、追加 `product_assets(group_key='generated')`。
## 4. 任务查询 `GET /api/suites/{id}`(Phase B)
**Res**
```jsonc
{
"id": "…", "status": "queued|running|done|partial|failed|cancelled",
"style_set": 1, "platform": "ozon", "lang": "俄文", "ratio": "3:4", "provider": "rightapi",
"total": 8, "completed": 3, "failed": 1,
"images": [ { "type_id": "white_bg", "name": "白底主图-01.png", "url": "/media/suites/…png",
"status": "queued|waiting_provider|running|done|failed|cancelled", "error": null } ],
"error": null
}
```
前端采用“本次请求结束后再延迟下一次”的递归轮询(正常 3s、请求失败指数退避),并在切换任务、组件卸载时取消在途请求;`done/partial/failed/cancelled` 为终态。每条 `images` 项另含 `item_id`,用于按图重试。浏览器会暂存当前任务 ID,并从服务端查询商品的活动任务;Web 服务或 Worker 重启后仍可恢复任务状态。
辅助接口:`GET /api/products/{product_id}/suites?active_only=true` 恢复活动任务;`POST /api/suites/{id}/cancel` 取消任务;`POST /api/suites/{id}/retry` 重试全部失败子项;`POST /api/suites/{id}/items/{item_id}/retry` 只重试指定失败项。
## 5. 结果导出 `GET /api/suites/{id}/zip`(Phase B)
→ `application/zip` blob(按方案标题命名内部文件)。404/失败返回 `detail` JSON。
## 6. 单张 AI 生图 `POST /api/suite/image-edit`(Phase B)
**Req**
```jsonc
{
"product_id": "uuid",
"image_url": "…", // stored_url 或 source_url(服务端代下绕防盗链)
"prompt": "把背景换成纯白色摄影棚", // 必填
"model": "nano-banana-2",
"append": true // true:结果追加 product_assets(generated)
}
```
**Res** `{ "suite_id": "…" }`
接口仅创建并提交统一图片任务,立即返回;前端通过 `GET /api/suites/{suite_id}` 查询状态和 `images[0].url`。完成后若 `append=true`,结果会回写为 `product_assets(group_key='generated')`。单张编辑优先级高于套图,提交模型后同样持久化第三方任务 ID;参考图 = 传入单图;Ozon 规格(俄文 3:4)。
## 7. 素材水印 `POST /api/assets/watermark` / `POST /api/assets/watermark/remove`
`POST /api/assets/watermark` 的请求体为 `{ "asset_ids": ["uuid"], "watermark": { "enabled": true, "type": "text|image", "text": "…", "opacity": 30 } }`,立即返回 `{ "job_id": "uuid", "total": n }`。Worker 对选中的采集图或生成图逐张应用水印,前端经 `GET /api/suites/{job_id}` 查看逐图进度和错误;`GET /api/products/{product_id}/watermark-jobs?active_only=true` 用于页面刷新后恢复。
`POST /api/assets/watermark/remove` 的请求体为 `{ "asset_ids": ["uuid"] }`,将选中图片恢复为无水印原图。
`POST /api/assets/watermark/remove` 当前仍为短时同步操作,返回 `{ "updated_ids": [], "failed": [] }`。两接口均只保留原图和当前展示版本:重新加水印会在数据库提交后删除旧水印文件;前端展示、单张下载与导出均使用 `stored_url`。
## 8. 导出与代理(Phase B / D)
| 接口 | 方法 | Req | Res |
|---|---|---|---|
| `/api/export/images` | POST | `{ "title": "…", "images": [{ "url", "groupName", "variantName", "key" }] }` | zip blob(分组建文件夹) |
| `/api/proxy-image?url=` | GET | 源站图片 URL | 图片字节(带站点 Referer 代下,绕防盗链) |
| `/api/export/trial-csv` | GET | query:`stage?` | csv blob(16 列,见 trial-page.md §7;Phase D 服务端化,替代前端拼装) |
图片资源上限:默认单张上传/远程下载 20 MB;一次导出最多 50 张,ZIP 内源图片总量与成品 ZIP 均最多 200 MB。超过限制返回 HTTP `413` 及可读错误提示;ZIP 超过 2 MB 自动写入临时磁盘,并以分块响应下载。
## 9. 采集相关(Phase C 使用,均已实现)
- `POST /api/materials`:插件上传采集结果;**响应含 `product_id`**(插件用于打开 `/trial/{id}`)。
- `GET /api/collected?platform=&itemId=`:采集前查重。
## 10. 冻结接口(不投入,保留代码)
`/api/publish/*`、`/api/shops/*`、`/api/categories/*`——Ozon API 直传链路(D1)。