101 lines
6.7 KiB
Markdown
101 lines
6.7 KiB
Markdown
# V2.2 商品 AI 编辑 API
|
||
|
||
> 状态:契约设计,尚未实现。所有写接口由服务端验证所有权、单位、继承与状态;前端不可提交计算结果冒充服务端结果。
|
||
|
||
## 1. 采集入库与 SKU 归属
|
||
|
||
`POST /api/materials` 保持现有商品级采集契约,并新增可选 `variants`。服务端始终落一条父商品和至少一条 SKU:有 `variants` 时逐项创建/更新;没有时创建一条默认 SKU。单规格商品不会省略 SKU 表记录,使编辑页、定价和未来发布永远面对同一模型;字段 `null` 只表示该字段未覆盖默认值。
|
||
|
||
```jsonc
|
||
{
|
||
"source": { "platform": "1688", "itemId": "123", "url": "https://..." },
|
||
"texts": ["...现有采集文本..."],
|
||
"images": ["...现有商品级采集图..."],
|
||
"variants": [
|
||
{
|
||
"sourceVariantKey": "stable-source-sku-id",
|
||
"variantName": "白色 / 500 ml",
|
||
"specs": { "颜色": "白色", "容量": "500 ml" },
|
||
"sourcePrice": 28.5,
|
||
"physicalMeasurements": {
|
||
"lengthMm": null, "widthMm": null, "heightMm": null, "netWeightG": null,
|
||
"status": "missing"
|
||
},
|
||
"packageMeasurements": {
|
||
"lengthMm": null, "widthMm": null, "heightMm": null, "shippingWeightG": null,
|
||
"status": "missing"
|
||
},
|
||
"imageUrls": []
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
服务端按 `platform + itemId + sourceVariantKey` 幂等写入 SKU;改名只更新 `variant_name`,不会创建重复 SKU。只有来源给出可靠 SKU—图片对应关系时,`imageUrls` 才能绑定该 SKU。1688、淘宝、天猫当前没有这种可靠映射时,图片仍作为商品级 `collected_main` / `collected_detail` 候选素材,`imageUrls` 保持空数组。来源口径不明的重量和尺寸不得写入任一 measurements 对象,需保留原始文本并写 `ambiguous`。
|
||
|
||
## 2. 读取与草稿保存
|
||
|
||
| 接口 | 用途 |
|
||
|---|---|
|
||
| `GET /api/products/{product_id}/editor` | 返回父商品、动态属性 schema、SKU 摘要/详情、已选媒体和候选素材统计。 |
|
||
| `PUT /api/products/{product_id}/editor-draft` | 原子保存父商品、属性、SKU 新增/修改/排序/停用与媒体选择。响应返回规范化完整编辑数据。 |
|
||
| `GET /api/products/{product_id}/validation` | 返回父商品及逐 SKU 的本地上架校验结果。 |
|
||
|
||
`editor-draft` 使用版本号/ETag 防止两个页面静默互相覆盖;版本冲突返回 `409` 和当前版本摘要。复杂的单一操作也提供下列细粒度接口,供弹窗立即保存使用。
|
||
|
||
## 3. SKU 与属性
|
||
|
||
| 接口 | 用途 |
|
||
|---|---|
|
||
| `POST /api/products/{product_id}/variants` | 创建手工 SKU 或复制 SKU,返回新 ID。 |
|
||
| `PATCH /api/products/{product_id}/variants/{variant_id}` | 修改单个 SKU 字段或恢复继承(字段值传 `null`)。 |
|
||
| `DELETE /api/products/{product_id}/variants/{variant_id}` | 软删除未发布 SKU;已发布 SKU 改为停用并要求后续发布流程处理。 |
|
||
| `PUT /api/products/{product_id}/attributes` | 保存通用属性。 |
|
||
| `PUT /api/products/{product_id}/variants/{variant_id}/attributes` | 保存 SKU/变体属性。 |
|
||
| `GET /api/products/{product_id}/attribute-schema` | 按当前 `description_category_id + type_id` 返回 Ozon schema、字典选项和 `is_aspect` 标识。 |
|
||
|
||
服务端通过 Ozon `/v1/description-category/attribute` 获取 schema,并按 `type`、`is_required`、`is_collection`、`max_value_count` 和字典值校验结构化值。`is_aspect=true` 是默认的 `variant` scope;客户端可显式将业务上按 SKU 区分的非 aspect 属性保存为 `variant` scope。服务端不得因该业务覆盖而丢弃属性,但会在发布校验中按 Ozon 最终 schema 提示兼容性问题。来源采集接口以稳定 `source_variant_key` 做 SKU 幂等,而不按 `variant_name` 匹配。
|
||
|
||
## 4. 定价
|
||
|
||
| 接口 | 用途 |
|
||
|---|---|
|
||
| `POST /api/products/{product_id}/variants/{variant_id}/pricing/quote` | 以请求的编辑值和服务端合并后的包装规格计算预览,不写入售价。 |
|
||
| `POST /api/products/{product_id}/variants/{variant_id}/pricing/confirm` | 重新计算、校验并保存快照,同时写入 `selling_price`、`old_price`。 |
|
||
| `GET /api/products/{product_id}/variants/{variant_id}/pricing` | 读取最新确认快照和可解释的告警。 |
|
||
|
||
`confirm` 的请求只包含用户可编辑的定价输入;服务端自行读取 SKU 和父商品规格,写入计算结果、公式版本和有效包装规格快照。包装值缺失、`ambiguous`、小于等于零或不满足物流尺寸限制时返回 `422`,不更改原价格。
|
||
|
||
## 5. 媒体
|
||
|
||
| 接口 | 用途 |
|
||
|---|---|
|
||
| `GET /api/products/{product_id}/variants/{variant_id}/media/candidates?group=` | 返回 AI 记录、采集主图、采集 SKU 图、采集详情图;带稳定 SKU 归属的候选项只返回给对应 SKU。 |
|
||
| `PUT /api/products/{product_id}/variants/{variant_id}/media` | 原子保存该 SKU 图片/视频/封面选中项及顺序。 |
|
||
| `POST /api/products/{product_id}/assets` | 上传商品级或明确指定 SKU 的候选媒体。 |
|
||
| `DELETE /api/products/{product_id}/assets/{asset_id}` | 删除未被引用的候选资产;仍被 SKU 选中时返回引用信息并要求先解除选择。 |
|
||
|
||
资产引用必须使用 `asset_id` 和 `product_variant_id`,不使用图片 URL 或 SKU 名称作为关联键。
|
||
|
||
## 6. AI
|
||
|
||
| 接口 | 用途 |
|
||
|---|---|
|
||
| `POST /api/products/{product_id}/ai/copy` | 输入通用商品上下文,返回标题、标签、简介、富内容等候选草稿;不直接覆盖数据库。 |
|
||
| `POST /api/products/{product_id}/ai/model-and-offers` | 为父商品返回型号和每个 SKU 的货号候选;用户确认后通过草稿保存接口写入。 |
|
||
| `POST /api/products/{product_id}/ai/suite-plans` | 创建套图规划;请求必须显式给出目标 SKU 集合。 |
|
||
| `POST /api/products/{product_id}/variants/{variant_id}/ai/dimension-image` | 为单 SKU 创建尺寸图任务;服务端固化已确认实物规格快照。 |
|
||
|
||
AI 与生图任务沿用现有持久化后台任务模型。任何任务都要保存 `product_variant_id`,且尺寸图额外保存 `physical_measurements_snapshot`;SKU 改名不会丢失任务归属。
|
||
|
||
## 7. 后续 Ozon 发布契约
|
||
|
||
未来 `POST /api/products/{product_id}/publish` 的内部实现应把每个启用 SKU 转换成一个 `/v3/product/import.items[]`:
|
||
|
||
- 父商品标题、描述、类目、通用属性复制到每个 item;
|
||
- SKU 的 `offer_id`、价格、划线价、包装尺寸/重量、已选图片和变体属性写入对应 item;
|
||
- 每个 SKU 独立保存 Ozon task item 结果、`ozon_product_id` 和 Ozon SKU;
|
||
- 请求按最多 100 个 item 分批,单 SKU 失败不应抹掉其他 item 的状态。
|
||
|
||
本期不实现该接口;本文仅规定数据与错误归属,避免后续发布阶段重新拆分单商品记录。
|