feat(ai-edit): 开发 AI 填报功能
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# 商品 AI 编辑页
|
||||
|
||||
> 状态:商品编辑主流程和 Ozon 动态属性 P0 已实施,平台类目/属性/字典读取及首次发布预检已迁移完成;定价确认、AI 任务和真正调用 Ozon 的发布 job 仍有未实施部分。准确接口状态以 [`../api/product-editor-and-publishing.md`](../api/product-editor-and-publishing.md) 和 [`../project/HANDOFF.md`](../project/HANDOFF.md) 为准。
|
||||
> 状态(2026-09-23):商品编辑主流程、Ozon 动态属性 P0、平台级目录读取、首次发布预检及商品 AI 填报/单 SKU 文案任务已有实现;Ozon 动态属性由用户填写,当前不由 AI 自动填报。定价确认、AI 生图、真正调用 Ozon 的发布 job 与在线商品同步尚未完成。实际验收边界以 [`../api/product-editor-and-publishing.md`](../api/product-editor-and-publishing.md) 和 [`../project/HANDOFF.md`](../project/HANDOFF.md) 为准。
|
||||
|
||||
## 目标
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
## 分册
|
||||
|
||||
- [页面与交互](./product-ai-editor.md)
|
||||
- [AI 一键填报开发与设计方案](./ai-autofill-plan.md)
|
||||
- [Ozon 动态属性与 SKU 填报改造方案](./ozon-dynamic-attributes-and-sku-form-plan.md)
|
||||
- [数据库领域模型](./data-model.md)
|
||||
- [服务端 API 契约](./api.md)
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
# 商品 AI 填报:设计与开发方案
|
||||
|
||||
> 状态:2026-09-23 已实现。目标平台首期为 Ozon;采集来源覆盖 Ozon、1688、淘宝、天猫。全局 AI 填报和 SKU 文案通过异步任务回填未保存表单;动态类目属性不在当前范围。
|
||||
|
||||
## 1. 目标与边界
|
||||
|
||||
用户采集商品、进入编辑页并点击底部唯一的「AI 填报」按钮后,系统依据已经保存的采集资料、当前草稿和 Atlas 平台参考目录,生成类目、型号、每个未导入 SKU 的货号、证据充分的包装规格,以及 **SPU 的** Ozon 俄文标题、主题标签和产品描述。任务完成后,页面**直接将合格结果写入当前表单**,标记为未保存修改;用户可以继续改动,并通过现有「保存」操作统一持久化。生成任务本身不修改商品草稿、店铺或 Ozon 商品。SKU 三项文案默认继承 SPU;用户展开 SKU 字段后可针对当前 SKU 单独触发 AI 生成。
|
||||
|
||||
AI 不生成售价、采购价、品牌、条形码、图片、富内容、动态类目属性或已导入 SKU 的货号。类目改变后仍由现有机制加载属性 schema,并由用户按既有控件填写。输入资料不足时允许部分填报,不能为了填满表单编造重量、尺寸或商品事实。
|
||||
|
||||
该能力的内部入口是「已规范化商品资料 + 目标平台 + 可售 SKU + 草稿版本」,而不是 React 页面。未来从商品详情链接直接采集后,先进入现有采集规范化链路,再调用同一 AI 填报服务。
|
||||
|
||||
## 2. 现状与可行性
|
||||
|
||||
- Atlas 已有 `source_material`、`source_material_state.latest`、`ai_input`、平台级类目树、商品/SKU 草稿、版本号及 `editor-draft` 原子保存接口。底部现有类目和文案两个占位按钮,可合并为一个入口。
|
||||
- Atlas 现有 AI API 是尚未实施的任务契约:先保存草稿,再创建异步任务,结果由用户应用。此次保持「先保存」和「任务不写草稿」,但把结果应用动作改为任务完成后直接写入浏览器表单;页面现有保存按钮仍是数据库写入边界。
|
||||
- 旧版 `ozon-seller-kit` 的 `server/services/prompts/copy_ru.py` 已定义中俄成对的标题、描述和标签及事实边界;`server/services/deepseek.py` 实现 JSON 请求、解析和一次纠错重试。可复用规则和测试样本,不直接复制旧版 FastAPI、无工作空间隔离的调用路径或试算页「生成后立即保存简介」行为。
|
||||
- DeepSeek 官方 JSON 输出文档支持 `response_format: {"type":"json_object"}`,同时提示空内容和输出截断的可能性。因此 JSON 模式只保证可解析性的目标,**不替代 Atlas 的字段 schema、事实引用、类目 ID、长度和唯一性校验**。具体模型名和参数应作为服务端配置,经上线时再次确认。
|
||||
- 当前迁移尚无 `product_ai_tasks` 实表;`docs/architecture/sql/002_product-domain.sql` 仅有设计草案。落地任务状态、结果和中文对照需要新迁移。
|
||||
|
||||
## 3. 一次点击的页面流程
|
||||
|
||||
1. 用户点击「AI 填报」。若表单有未保存修改,页面先调用现有保存流程;保存失败时不创建任务。当前 `source_snapshot_revision`、商品/profile revision、SKU ID、目标店铺和平台由服务端固化为任务输入快照。
|
||||
2. 页面将底部按钮改为「填报中…」,显示步骤:分析采集资料 → 推荐类目 → 生成文案与编号 → 校验结果。用户可继续浏览页面。重复点击沿用同一输入版本的进行中任务,避免重复计费。任务以字段组为独立产出单元:类目、编号、包装和文案可以分别成功或失败;只有完全没有合格结果才记为整体失败。
|
||||
3. Worker 完成后,服务端返回已校验结果、警告及中俄文案。页面核对任务快照与当前编辑版本;若复采或草稿有新版本,提示结果已过期,不自动回填。
|
||||
4. 在同一版本下,页面直接写入符合规则的表单字段并显示「已填报 N 项,M 项待处理/证据不足」。任务部分成功时,合格字段照常回填,失败字段保留原值并按原因列出。类目写入表单后触发已有动态 schema 加载;旧类目属性草稿按现有切换规则处理。本期不让 AI 接续填写新 schema。
|
||||
5. 已导入 SKU 的货号不变;全局结果只填空字段,原本由用户填写的非空字段保留。异步等待期间若草稿版本变化,本次结果不回填。
|
||||
6. 回填只改变浏览器表单并触发页面 `dirty` 状态。关闭页面前继续使用现有未保存提示;保存后与其他草稿字段一同持久化。
|
||||
|
||||
不增加逐字段确认弹窗。字段建议、被跳过项目和原因可在一个简短的填报结果面板查看;用户最终通过编辑页原有的保存动作提交。生成失败或部分字段失败时,已校验合格的其他字段仍可应用。
|
||||
|
||||
## 4. 字段规则
|
||||
|
||||
### 4.1 类目
|
||||
|
||||
- Ozon 来源先使用现有「一级面包屑 + `Type_0` 商品类型」匹配;已经有用户选择的类目不因 AI 填报改变。确定性匹配唯一时沿用它,不再为该字段消耗模型调用。
|
||||
- 1688、淘宝、天猫来源无 Ozon 类目 ID。服务端向模型分层提供 Atlas **活动、可发布目录**:先给顶层选项,再按选定分支给子节点,直到叶子;每一步只允许返回给定 UUID,并记录候选路径和理由。不得让模型自造类目名或把来源平台类目 ID 当成 Ozon ID。
|
||||
- 最终叶子由服务端复核所属平台、活动状态、可发布 `description_category_id + type_id` 以及祖先链。证据明确时把 Atlas 叶子 UUID 填入未保存表单,`category_source=ai_suggestion`;歧义或证据不足时不填,并显示至多三个候选供用户通过现有类目控件选择。
|
||||
- 不用模型自报的置信度单独决定是否回填;自动回填阈值应基于四来源样本评测校准。已保存的用户类目优先级高于新建议。
|
||||
- 类目目录若缺失、未同步完整、已失效或目标叶子缺少有效 `description_category_id + type_id`,先复用现有目录同步机制;在有界等待后仍不可用时,类目结果标为 `catalog_unavailable`,不向 AI 提供不完整候选,也不自造类目 ID。已有已确认类目可继续作为其他字段的上下文;否则依赖类目码的型号与货号暂不生成。文案和有独立证据的包装建议照常处理。
|
||||
- 这里的类目目录与 Ozon **动态属性字典**不同。类目确认并保存后,页面只加载 schema,动态属性由用户通过既有下拉搜索和输入控件填写;当前 AI 填报不处理属性及字典值。
|
||||
|
||||
### 4.2 型号与 SKU 货号
|
||||
|
||||
- **同一 SPU 只有一个 `model`**,不随 SKU 的作品、角色、颜色变化。AI 先归纳所有 SKU 真实共有的商品类型与形态;只有全部 SKU 确实属于同一系列时,系列语义才允许进入型号。死亡笔记、海贼王、火影忍者等作品混在一个手办 SPU 时,公共型号使用中性的类别/形态码,如 `FIG-MIX-8K4F`,绝不取首个 SKU 的作品名当整组型号。若 SKU 连基本商品形态都不同,提示先拆分 SPU,不强行生成共同型号。
|
||||
- 格式由服务端固定:`model = 类目短码-共通形态或 MIX-商品稳定码`,例如 `FIG-MIX-8K4F`;只用大写英文字母、数字和 `-`,最多 **32 个 ASCII 字符、2 个连接符**。短码来自 Atlas 维护的跨平台商品形态码表,由目标类目映射而来,不直接使用 Ozon 专有 ID;AI 只建议共有语义,不能直接输出最终编号。模型不可用但类目明确时,可保守回退 `MIX`;无可用类目时不生成编号。类目名称或 SKU 排序变化后,不自动重编已经保存的型号。
|
||||
- 每个未导入 SKU 的 `offer_id = model-变体识别码`,识别码可由作品、角色和必要规格组成。例如 `FIG-MIX-8K4F-DN-L`、`FIG-MIX-8K4F-OP-LUFFY`、`FIG-MIX-8K4F-NAR-SASUKE`。整串最多 **48 个 ASCII 字符、4 个连接符**,通常为 3~4 个连接符;额外的颜色/尺寸须压入已有变体段,不能不断追加 `-`。只有来源明确提供作品/角色时才使用其缩写,不能凭图片猜测 IP;语义不可靠时改用基于稳定 SKU 身份的 `V` 码。变体识别码在本 SPU 内必须唯一,不依据显示顺序生成 `V01/V02`。
|
||||
- 服务端维护短码、缩写、稳定商品码及 SKU 身份的映射;AI 不负责计数或唯一性。生成后对本次所有 SKU、目标店铺已有草稿和在线镜像检查冲突;冲突时仅调整尚未保存的新码并保持上述长度/连接符上限,仍冲突则跳过该货号并报告。保存时仍由数据库唯一索引和现有服务端校验兜底。
|
||||
- 当前通用保存契约仅有较宽的 `model ≤ 300`、`offer_id ≤ 500` 字符上限。上述 32/48 及连接符规则是**AI 生成值的强校验**,不应悄悄拒绝已有或手填的较长编号;如要统一收紧所有编号,需要先盘点历史值并单独迁移、通知用户。
|
||||
- `model` 是跨平台商品字段,也会映射到 Ozon「型号名称」属性。本期按用户希望使用可识别编码;后续若需要单独的内部编码与对外型号,应新增独立字段,不能在生成逻辑里偷偷分叉。
|
||||
- 已导入 SKU 的货号是历史事实;AI 结果绝不填入或改动。手填非空型号/货号按页面覆盖规则保留。
|
||||
|
||||
### 4.3 包装重量与尺寸
|
||||
|
||||
- 只从明确的「包装/外箱/包裹」事实提出建议,区分商品本体的尺寸、净重和物流包装规格。模型为每个建议返回原文证据片段、来源字段、原单位和换算后的 `g/mm` 数值。
|
||||
- 服务端检查证据存在、单位可识别、值为正数且数量级合理。若只有商品尺寸或重量、只看图片推测、三维缺项或存在多种包装版本,相关字段保持空值或现有值,不生成“确切数值”。
|
||||
- 商品级包装建议填 SPU 默认值;仅当某 SKU 有专属包装证据时填该 SKU 覆盖值。有明确证据的结果字段状态为 `suggested`,允许直接回填;回填后的包装**确认状态**先标为 `ambiguous`,用户核对后改为 `confirmed`。证据本身有歧义的结果字段状态为 `ambiguous`,不自动回填。因此 AI 可减少录入,但不能绕过定价和发布所需的包装确认。
|
||||
|
||||
### 4.4 SPU 默认文案、SKU 按需文案与中文对照
|
||||
|
||||
- 三项指**发布标题、主题标签、产品描述**。底部「AI 填报」只生成 SPU 三项及逐项中文对照,不生成、不写入 SKU 三项覆盖值。SPU 文案只能陈述所有 SKU 都成立的共有事实;不同作品混在一组手办 SKU 时,不把其中一个作品写成 SPU 通用事实。
|
||||
- SPU 各字段旁的 `+` 只开启对应 SKU 字段编辑入口,**不批量复制 SPU 文案、不隐藏 SPU 字段**。各 SKU 的标题、标签和描述逐字段默认继承 SPU;表单显示有效值和「继承 SPU」状态,只有用户手动输入或主动应用该 SKU 的生成结果才保存覆盖。
|
||||
- SKU 三项字段旁的 AI 图标打开同一个当前 SKU 生成弹窗。左侧展示中文来源描述、SKU 名称、规格和可证的作品/角色资料;点击「AI 生成」仅为该 SKU 生成俄文标题、标签、描述及中文配对,右侧预览,点击「应用到当前 SKU」才把合格结果写入该 SKU 的未保存表单。已有手工覆盖不得被静默替换。某项证据不足时可单独保持继承,其他合格项仍可应用。
|
||||
- 参考旧版提示词,每次文案生成可返回两组标题候选及逐项中文,默认采用第一组;标签逐项中俄配对,描述按段落对应。俄文是发布表单值,中文只是对照资料,不进入 Ozon 发布 payload。不得编造材料、认证、配件、安全性、产地、适用年龄、包装或功效;也不得把 A SKU 的角色、颜色或规格写到 B SKU。
|
||||
- SPU 和每个 SKU 的三个字段旁另有「中文对照」图标。统一弹窗左列展示当前有效俄文,右列展示对应中文,标题标明 SPU 或 SKU;继承项显示 SPU 对照与「继承 SPU」。中文对照按 `profile_id + scope(SPU/SKU) + variant_id + field` 保存配对版本;继承项只引用 SPU 对照,不复制记录。手工改俄文后若不再与中文配对,标记「中文对照待更新」,不得把 SPU 中文错配给 SKU 俄文覆盖。
|
||||
|
||||
## 5. 可复用服务与当前接口
|
||||
|
||||
全局入口使用 `POST /api/product-platform-profiles/{profile_id}/ai/autofills`;当前 SKU 的独立文案入口使用 `POST /api/product-platform-profiles/{profile_id}/variants/{variant_id}/ai/copy`。两者均要求 `Idempotency-Key` 和平台头,body 可带 `hint`;返回 `202 { ai_task_id, status }`。`GET /api/product-ai-tasks/{ai_task_id}` 返回任务状态、输入版本与已校验结果,不返回提示词、密钥或原始模型响应。Worker 从服务端 `.env` 读取 `DEEPSEEK_API_KEY` 与 `DEEPSEEK_MODEL_NAME`。
|
||||
|
||||
全局结果包含 `category` 或 `category_candidates`、`model`、`offers`、可选 `package_spec`、`spu_copy`、`warnings`。单 SKU 结果只包含 `variant_id`、`copy`、`warnings`。任务输入固化商品、profile、来源快照版本和 SKU ID;前端在回填前再次比对版本。
|
||||
|
||||
接口结构示意(实际契约见 `@atlas/contracts`):
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "task-uuid",
|
||||
"kind": "autofill",
|
||||
"status": "partial",
|
||||
"input_revision": { "product": 12, "profile": 7, "source_snapshot": 4 },
|
||||
"result": {
|
||||
"category": { "category_id": "atlas-category-uuid", "path": "目录路径" },
|
||||
"model": "FIG-MIX-8K4F",
|
||||
"offers": [{ "variant_id": "variant-uuid", "offer_id": "FIG-MIX-8K4F-V123456" }],
|
||||
"spu_copy": {
|
||||
"title": { "ru": "…", "zh": "…" },
|
||||
"tags": [{ "ru": "…", "zh": "…" }],
|
||||
"description": { "ru": "…", "zh": "…" }
|
||||
},
|
||||
"warnings": ["未找到可核对的包装重量和尺寸"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
任务状态区分 `succeeded`、`partial`、`failed`;部分失败通过 `warnings` 表达。候选类目不自动回填,由用户点击候选确认。包装缺少可核对证据时不返回包装建议。
|
||||
|
||||
内部拆为四个与页面无关的组件:
|
||||
|
||||
1. `SourceFactAssembler`:把采集快照和已保存的用户整理稿转为带证据的、长度受限的规范化商品事实;未来 URL 入口复用此层。
|
||||
2. `CategoryResolver`:已有类目优先沿用;否则分层查询平台目录并向模型提供封闭候选,返回经数据库验证的叶子 UUID 或需用户确认的多个候选。
|
||||
3. `AutofillGenerator`:Worker 调用 DeepSeek 生成中俄文案与有证据的包装建议;稳定型号/货号由服务端规则生成。API Key 只在 Worker 环境读取,不进入浏览器、任务输入、outbox 或日志。
|
||||
4. `AutofillValidator`:校验中俄配对、包装证据与正数、类目 UUID、编号长度和货号冲突,丢弃不合格字段。
|
||||
|
||||
NestJS 负责鉴权、工作空间事务、快照和任务创建;任务与 outbox 在同一事务入库;Worker 调用模型和写回结果。调用超时、限流、空响应、截断和非法 JSON 使用有界重试,重复任务以任务 ID 幂等。失败只更新任务状态,不触碰草稿。记录模型、提示词版本、耗时和 token 用量以便成本分析;日志及对外错误只输出脱敏摘要。
|
||||
|
||||
迁移 `029_product_ai_autofill.sql` 建立任务和中俄对照表,并给 SKU listing 增加可空 `title`;`null` 表示继承 SPU 发布标题。SKU `tags=[]`、`description=null` 继续表示继承。中文对照随草稿事务保存、随编辑快照读取;表单俄文若与对照时的俄文不一致,页面显示「待更新」。
|
||||
|
||||
页面只回填空白的全局字段和 SPU 文案,不覆盖已有手填值;SKU 文案必须由当前 SKU 弹窗单独生成,并经用户点「应用到当前 SKU」才覆盖其标题、标签、描述。中文只进入对应作用域的对照记录。回填只改变未保存的表单状态,不独立写入草稿。
|
||||
|
||||
## 6. 版本、冲突与失败处理
|
||||
|
||||
| 情况 | 页面行为 |
|
||||
|---|---|
|
||||
| 任务期间用户改了部分字段 | 页面保存前先固化草稿;任务完成时若版本已变化,拒绝整次自动回填并提示重新生成。 |
|
||||
| 任务期间商品被复采、平台或 SKU 集合改变 | 结果标为过期,不自动回填;用户可重新点击生成。 |
|
||||
| AI 找不到可确定的目标类目 | 类目留空,展示候选;文案和有独立证据的包装仍可回填。若已有已确认类目,可继续生成型号与货号;否则编号留空。 |
|
||||
| 类目目录不完整或同步失败 | 无已确认类目时,型号与货号跳过;其他独立字段仍可回填。 |
|
||||
| Ozon 动态属性字典缺失 | 本期不由 AI 填报该属性,不影响其他字段;页面显示字典加载状态,保存草稿允许缺失,发布预检继续阻止无效字典值。 |
|
||||
| 包装数据没有明确证据 | 包装项留空,说明缺失,不将商品尺寸当包装尺寸。 |
|
||||
| 目标店铺货号冲突 | 服务端重算稳定后缀;仍冲突则仅跳过该 SKU 货号并提示。 |
|
||||
| DeepSeek 超时、限流、空响应或截断 | 按错误类别执行有界退避重试;仍失败则模型依赖组标为失败,确定性类目/编号组若已合格可形成 `partial`,否则任务为 `failed`;已填值不回滚,未填值保留原样。 |
|
||||
| 结构不合法或事实/字段规则不合格 | JSON 请求有限次重试;仍失败则拒绝模型依赖组。可解析时逐字段校验,中俄不成对或数值无证据的字段单独丢弃。 |
|
||||
| 当前 SKU 文案失败 | 弹窗显示错误;原 SKU 文案不变,不影响已生成的 SPU 文案或其他 SKU。 |
|
||||
| 用户修改俄文后查看中文对照 | 标记「对照待更新」,不把旧中文当作当前俄文的翻译。 |
|
||||
|
||||
## 7. 实施顺序与验收
|
||||
|
||||
1. **契约与迁移**:修订 `docs/api/`、`@atlas/contracts`;落地 AI 任务、SKU 发布标题和分作用域中文对照表、工作空间 RLS、outbox 事件与幂等键。测试跨工作空间不可读取任务/对照及 SKU 标题继承。
|
||||
2. **服务端核心**:事实组装、平台目录分层候选、DeepSeek JSON 输出校验、稳定型号/货号规则、包装证据校验。全局只生成 SPU 文案;当前 SKU 文案由独立任务按需生成。不使用真实密钥跑自动化测试。
|
||||
3. **编辑页**:合并底部按钮、任务轮询、表单直接回填和保存前版本保护;类目回填触发现有 schema 请求,AI 不碰动态属性。SKU 展开区补独立标题编辑,标签/描述改为逐字段继承 SPU,留空即继承。
|
||||
4. **中文对照**:SPU 和每个 SKU 的三个字段旁入口、统一双栏弹窗、继承来源标记、随草稿保存与重新加载、各作用域俄文编辑后的过期提示。
|
||||
5. **端到端验收**:维护者启动 API/Worker 并完成迁移后,用 Ozon、1688、淘宝、天猫样本回归;覆盖跨作品 SKU、单 SKU 按需生成、中文对照刷新后读取、已导入 SKU 货号保护、无包装证据、歧义类目、模型异常及复采并发。
|
||||
|
||||
完成标准:点击一次「AI 填报」后,页面出现合格的类目、型号、未导入 SKU 货号及 SPU 俄文文案;证据不足的包装项保持空白。用户可以再对指定 SKU 单独生成并确认文案;中文对照保存后仍可查看。动态 Ozon 类目属性由后续单独设计。
|
||||
|
||||
## 8. 已知取舍
|
||||
|
||||
- 一键入口可以在内部多次调用模型,特别是非 Ozon 来源的分层类目选择;页面应显示异步进度,不能假设一个同步 HTTP 请求必定快速完成。
|
||||
- 直接回填提高速度,也要求可撤销、保留手填值、版本检查和完整任务记录。当前页面不增加逐项确认步骤。
|
||||
- 目前 `model` 是跨平台商品字段并会成为 Ozon 型号名称。若将来需要「内部编码」与「消费者可见型号」分离,应再增字段和迁移;本期不为此增加隐藏的第二套型号。
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# 商品编辑 API 契约
|
||||
|
||||
> 本文是早期产品级接口草案,部分路径和状态已经被实现契约取代,不应直接作为联调依据。当前端点、平台目录缓存和发布预检以 [`../api/product-editor-and-publishing.md`](../api/product-editor-and-publishing.md) 为准;所有请求仍须按当前用户、工作空间和平台/门店上下文授权,客户端不能跨租户指定 ID。浏览器插件采集入口以 [`../requirements/collector-browser-extension.md`](../requirements/collector-browser-extension.md) 为准。
|
||||
> 本文是早期产品级接口草案,部分路径和状态已经被实现契约取代,不应直接作为联调依据。尤其下文的独立 AI 类目/文案接口与逐项人工应用流程已由[统一 AI 填报方案](./ai-autofill-plan.md)取代。当前端点、平台目录缓存和发布预检以 [`../api/product-editor-and-publishing.md`](../api/product-editor-and-publishing.md) 为准;所有请求仍须按当前用户、工作空间和平台/门店上下文授权,客户端不能跨租户指定 ID。浏览器插件采集入口以 [`../requirements/collector-browser-extension.md`](../requirements/collector-browser-extension.md) 为准。
|
||||
|
||||
## 1. 采集与读取
|
||||
|
||||
|
||||
@@ -22,11 +22,11 @@ workspaces 1 ── N collection_items ── 0..1 products (SPU) 1 ── N pro
|
||||
(平台发布配置) (平台 SKU 首次发布映射)
|
||||
```
|
||||
|
||||
`collection_items` 是工作空间级采集箱记录,保存来源平台、来源商品键、原始证据、规范化结果、素材任务和可空的草稿商品关联;它在采集阶段没有 `target_platform_id` 或 `target_store_id`。每个父商品至少有一条 SKU。`products` 仅是**采集箱商品**的跨平台可复用资料:来源标题、用户填写的型号、条形码、采买地址、货源备注、默认规格和来源证据;采集阶段型号允许为空,不能从来源数据猜测生成。首次上架前型号必须已由用户确认填写;不把任何一个平台的类目、价格、属性或上架状态直接写到该表。
|
||||
`collection_items` 是工作空间级采集箱记录,保存来源平台、来源商品键、原始证据、规范化结果、素材任务和可空的草稿商品关联;它在采集阶段没有 `target_platform_id` 或 `target_store_id`。每个父商品至少有一条 SKU。`products` 仅是**采集箱商品**的跨平台可复用资料:来源标题、用户手填或主动 AI 填报的型号、条形码、采买地址、货源备注、默认规格和来源证据;采集入箱时型号允许为空,不直接从来源数据猜测填入。首次上架前型号必须非空并通过现有校验;不把任何一个平台的类目、价格、属性或上架状态直接写到该表。
|
||||
|
||||
`product_platform_profiles` 是 `product_id + platform_id` 唯一的平台发布配置。用户在页头选中平台并进入编辑时才创建或读取它;它保存当前目标门店、该平台的标题/简介/标签、类目和类型、平台通用属性及本平台草稿版本。A 平台与 B 平台独立配置、独立状态;A 已上架不会让 B 显示已上架。门店只是配置中可改的当前发布目标,实际每次发布仍会在 SKU 映射中固化当时的 `store_id`。
|
||||
|
||||
`product_variants` 保存:稳定来源键、展示名、删除状态、排序、采购价、SKU 规格、包装物流规格、实物规格和时间戳。`product_variant_platform_listings` 保存平台 SKU 维度的数据:`profile_id`、`variant_id`、用户填写的本平台 `offer_id`(货号)、售价、划线价、币种、平台变体属性、首次导入状态/失败原因、首次导入任务和当时 `store_id`、Ozon `product_id`。采集时不得根据 `source_sku` 自动填入 `offer_id`;用户填写后,它对同一门店/平台连接必须唯一,并且是首次上架的必填项。成功导入的 SKU 映射不可再次创建导入任务;删除 Atlas SKU 只软删 Atlas 关联,不删除平台商品和审计记录。
|
||||
`product_variants` 保存:稳定来源键、展示名、删除状态、排序、采购价、SKU 规格、包装物流规格、实物规格和时间戳。`product_variant_platform_listings` 保存平台 SKU 维度的数据:`profile_id`、`variant_id`、用户填写或主动 AI 填报生成的本平台 `offer_id`(货号)、售价、划线价、币种、平台变体属性、首次导入状态/失败原因、首次导入任务和当时 `store_id`、Ozon `product_id`。AI 填报落地时新增可空的 SKU 发布标题 `title`;`title=null`、`description=null`、`tags=[]` 分别继承 SPU 当前平台发布配置的标题、描述、标签,非空/非空数组则按 SKU 覆盖。`product_variants.display_name` 只是内部展示名,不能充当发布标题。中俄文案对照按 SPU/SKU 作用域保存,继承时读取 SPU 对照而不复制。采集入箱时不填入 `offer_id`;编辑页主动生成或手填后,它对同一门店/平台连接必须唯一,并且是首次上架的必填项。成功导入的 SKU 映射不可再次创建导入任务;删除 Atlas SKU 只软删 Atlas 关联,不删除平台商品和审计记录。
|
||||
|
||||
`platform_listings`(实际建表名待定)保存店铺级在线商品 SKU 镜像,一条记录对应 Ozon 的一个 `product_id` / `offer_id`,而非采集箱 SPU:`store_id`、平台 `product_id`、`offer_id`、平台 SKU、名称、价格、可见性、审核/错误、库存、图片摘要、完整同步快照、最近同步时间和来源(`atlas_published` / `external_sync`)。它是**平台 + 门店独有**的外部事实记录,绝不跨平台、跨门店复用,也不因关联了采集箱 SKU 就变成采集箱商品。它由异步同步任务更新,包含非 Atlas 发布的商品;通过 `store_id + offer_id/product_id` 可选关联 Atlas SKU。采集箱不因成功上架而删除,其当前平台状态由首次导入映射汇总;在线商品的 `visible` 只用于在线商品实际可见性展示。
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ Ozon 商品的必填属性由 `description_category_id` 与 `type_id` 对应的
|
||||
|
||||
### 2.3 SKU 设置
|
||||
|
||||
Ozon schema 中 `is_aspect=true` 的属性放入每个 SKU 卡片的「Ozon 变体属性」区域,不再按 SKU 名称集中堆放在产品属性区。每张 SKU 卡片包含:
|
||||
Ozon schema 中 `is_aspect=true` 的属性放入每个 SKU 卡片展开后的「SKU 信息」区域,与包装和文案字段共用布局,不单独显示「Ozon 变体属性」标题。每张 SKU 卡片包含:
|
||||
|
||||
- SKU 名称与当前平台上架状态;
|
||||
- 卖家货号 `offer_id`;
|
||||
@@ -195,7 +195,7 @@ POST /api/product-platform-profiles/{profile_id}/publish-preflights
|
||||
- 保存草稿允许不完整,发布校验阻断缺失项。
|
||||
- 服务端补齐通用和逐 SKU 必填属性检查。
|
||||
|
||||
实现状态:已完成。编辑器会在选定类目后立即加载 schema,商品级必填属性始终显示在「产品属性」,SKU 级必填属性始终显示在对应 SKU 卡片;保存草稿不因缺少必填值失败,`validation` 接口按商品与 SKU 返回结构化缺失项。
|
||||
实现状态:已完成。编辑器会在选定类目后立即加载 schema,商品级必填属性始终显示在「产品属性」,SKU 级变体属性在对应 SKU 展开后的「SKU 信息」中显示;保存草稿不因缺少必填值失败,`validation` 接口按商品与 SKU 返回结构化缺失项。
|
||||
|
||||
类目 schema 中由编辑器已有控件承载的字段通过 `editor_field` 显式绑定,不在动态属性区重复展示,也不重复加载其字典。绑定只允许按 Ozon 属性 ID:品牌 `85`、型号名称 `9048`、类型 `8229`、主题标签 `23171`、JSON 富内容 `11254`、简介/产品描述 `4191`;禁止使用名称或翻译文本猜测。后续发布适配器必须据此生成 Ozon 所需字段,不能要求用户重复填写。
|
||||
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
```text
|
||||
页头:返回 · 商品标题 · 当前平台 · 目标门店 · 当前平台上架状态 · 来源
|
||||
├─ 主要信息
|
||||
│ ├─ 类目、标题、型号、品牌
|
||||
│ ├─ 类目、中文商品名、俄文发布标题、型号、品牌
|
||||
│ └─ 默认包装重量与默认包装尺寸
|
||||
├─ 产品属性
|
||||
│ ├─ 主题标签、简介、采买地址与货源备注
|
||||
│ └─ 当前平台/市场的商品级动态属性
|
||||
├─ SKU 商品:卡片(默认)/ 紧凑列表
|
||||
│ └─ N 个 SKU;维护货号、条形码、图片、价格、变体属性及可选包装覆盖
|
||||
│ └─ N 个 SKU;维护货号、条形码、图片、价格、变体属性、三项 SKU 文案及可选包装覆盖
|
||||
└─ 固定操作栏
|
||||
├─ 左:AI 类目 · AI 标题/标签/描述 · AI 套图生成
|
||||
├─ 左:AI 填报 · AI 套图生成
|
||||
└─ 右:取消并关闭 · 保存草稿 · 选择未上架 SKU 并首次上架
|
||||
```
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
|
||||
页面以编辑草稿工作,不采用字段失焦即写库。保存草稿需原子提交父商品、SKU、属性和媒体顺序;存在未保存修改时关闭页面须二次确认。SKU 定价确认是例外:它会即时持久化该 SKU 的价格与定价快照。
|
||||
|
||||
采集进入采集箱时,商品**型号**和各 SKU 的目标平台**货号(Ozon `offer_id`)**默认都为空,不从来源标题、来源 SKU 或规格名称猜测生成。用户在编辑页填写:型号属于商品通用资料;货号属于当前平台下的每个 SKU。两者允许随草稿保存而暂时为空,但首次上架校验必须全部通过:商品型号非空,且每个待上架 SKU 的货号非空并在目标店铺内唯一。
|
||||
主要信息中的“中文商品名”用于 Atlas 内部识别;“俄文发布标题”是 SPU 共用发布标题,页面保存时必须填写。AI 填报仍可从俄文标题为空的采集草稿启动;发布前服务端会再次检查该字段。
|
||||
|
||||
采集进入采集箱时,商品**型号**和各 SKU 的目标平台**货号(Ozon `offer_id`)**默认都为空。进入编辑页后,用户可手动填写或点击“AI 填报”生成并直接填入表单;生成货号不直接照搬来源 SKU。型号属于商品通用资料,货号属于当前平台下的每个 SKU。两者允许随草稿保存而暂时为空,但首次上架校验必须全部通过:商品型号非空,且每个待上架 SKU 的货号非空并在目标店铺内唯一。详见[AI 填报方案](./ai-autofill-plan.md)。
|
||||
|
||||
上架状态是“当前平台 + SKU”维度:`未上架`、`处理中`、`上架失败`、`已上架`。SPU 在当前平台的状态由未删除 SKU 汇总为 `未上架`、`已部分上架`、`已上架`。用户可勾选任意未上架 SKU 执行首次上架;已上架 SKU 不显示上架选择,也不发送更新请求。编辑已上架 SKU 时,保存按钮旁必须提示“仅保存 Atlas 草稿,不会更新 Ozon 商品”。
|
||||
|
||||
@@ -39,9 +41,9 @@
|
||||
|
||||
## 3. SKU 卡片和列表
|
||||
|
||||
卡片默认展示:序号、SKU 名称、当前平台上架状态、最多 3 张图片缩略图(可切换为 5)、货号、条形码、采购价、售价、划线价、定价按钮、按 schema 展示的商品规格与 Ozon 变体属性。列表仅是紧凑视图,字段和数据完全相同。货号由用户填写,不自动复用来源 SKU;缺少货号的 SKU 可保存但不能被选择首次上架。SKU 包装规格为空时继承主要信息中的默认包装规格;只有该 SKU 包装不同才填写覆盖值。商品净重和商品尺寸不是 Ozon 固定物流字段,只在当前 schema 的对应属性为 SKU 级(`is_aspect=true`)时展示;商品级属性继续在 SPU 展示。首期不支持视频上传、编辑或发布;视频能力待 Ozon 对应接口和审核规则确定后再开启。
|
||||
卡片默认展示:序号、SKU 名称、当前平台上架状态、最多 3 张图片缩略图(可切换为 5)、货号、条形码、采购价、售价、划线价、定价按钮、按 schema 展示的商品规格与 Ozon 变体属性。列表仅是紧凑视图,字段和数据完全相同。货号可由用户填写或“AI 填报”生成,不直接复用来源 SKU;缺少货号的 SKU 可保存但不能被选择首次上架。SKU 包装规格为空时继承主要信息中的默认包装规格;只有该 SKU 包装不同才填写覆盖值。商品净重和商品尺寸不是 Ozon 固定物流字段,只在当前 schema 的对应属性为 SKU 级(`is_aspect=true`)时展示;商品级属性继续在 SPU 展示。首期不支持视频上传、编辑或发布;视频能力待 Ozon 对应接口和审核规则确定后再开启。
|
||||
|
||||
SKU 名称只用于展示;采集 SKU 用稳定 `source_variant_key` 关联,手工 SKU 用本地 UUID。规格字段 `null` 仅表示没有覆盖父商品默认值,绝不能据此判断是否单规格或缺少 SKU。
|
||||
SKU 名称只用于展示,不是发布标题;采集 SKU 用稳定 `source_variant_key` 关联,手工 SKU 用本地 UUID。SKU 展开区提供发布标题、主题标签、产品描述;留空逐字段继承 SPU,手工输入或应用当前 SKU 的 AI 结果才覆盖该项。SPU 三项旁的加号只显示对应 SKU 输入框,不复制共用文案。规格字段 `null` 仅表示没有覆盖父商品默认值,绝不能据此判断是否单规格或缺少 SKU。
|
||||
|
||||
无论 SPU 或 SKU 在当前平台是否已上架,用户都可以新增 SKU 变体、复制任一既有 SKU 作为新变体、删除 SKU。复制出的 SKU 没有平台发布映射,始终从 `未上架` 开始。删除已上架 SKU 只从 Atlas 商品结构和当前平台的可发布 SKU 集合移除,**不会删除、下架或修改 Ozon 已创建的商品**;删除未上架 SKU 后若当前平台只剩已上架 SKU,SPU 状态变为 `已上架`。
|
||||
|
||||
@@ -65,6 +67,6 @@ SKU 图片编辑弹窗左侧是该 SKU 的已选图片(排序/移除),右
|
||||
|
||||
首期素材规则:发布图片仅接受 JPG、PNG、WebP;单文件最大 20 MB,最短边低于 700 px 给出警告且不得作为主图,超过 10,000 px 的边长在上传时拒绝;建议 1:1 或 3:4,允许其他比例但在预览中提示裁切风险。采集候选素材可保留原始文件供编辑选择,实际发布时始终按目标平台的图片数、格式和可访问性校验。Ozon 发布图片必须是可由 Ozon 拉取的 HTTPS 地址。
|
||||
|
||||
AI 文案针对当前平台的商品信息生成候选标题、标签与简介,用户选择后写入草稿;首期不生成或编辑富内容。AI 套图由左侧抽屉承载,必须显式选择目标 SKU;尺寸图一 SKU 一任务,并保存实物规格快照。
|
||||
“AI 填报”针对当前平台一次生成类目、型号、SKU 货号、证据充分的包装规格以及 **SPU 共用的**标题、标签与简介,并在任务完成后直接填入当前页面表单,等待用户保存。SKU 文案默认继承 SPU;用户可从当前 SKU 的 AI 图标单独生成并在弹窗明确应用。SPU 和每个 SKU 的三项字段旁均有「中文对照」图标,打开同一个弹窗查看当前作用域左俄右中的三项对照;继承字段标明来源,俄文被手改后该字段对照标为待更新。首期不生成或编辑富内容。AI 套图由左侧抽屉承载,必须显式选择目标 SKU;尺寸图一 SKU 一任务,并保存实物规格快照。
|
||||
|
||||
AI 类目由用户主动触发:系统将采集标题、规格、参数、图片摘要等证据与当前平台可发布的类目树交给 AI,返回候选类目、置信度和简短依据,用户必须选择确认后才写入当前平台发布配置。来源为 Ozon 的商品优先保留采集到的 Ozon 类目,默认不自动调用 AI,但始终允许用户主动重新推荐;1688、淘宝、天猫等其他来源默认提供“AI 推荐类目”以提升上品速度。AI 不得直接自动落类目或跳过类目属性校验。
|
||||
类目推荐由“AI 填报”主动触发:系统将采集证据与当前平台可发布的类目候选交给 AI。Ozon 来源优先沿用现有确定性匹配;1688、淘宝、天猫等来源由 AI 评估目标类目。服务端验证候选 UUID 后可将明确结果填入**未保存的页面表单**;用户点击保存后才写入平台发布配置。歧义结果留给用户选择。AI 不得跳过类目属性校验;本期 AI 填报不处理动态类目属性。
|
||||
|
||||
Reference in New Issue
Block a user