feat(edit): AI套图生成、图片切七牛

This commit is contained in:
2026-10-04 20:47:47 +08:00
parent 696112e74d
commit e20cd7547f
60 changed files with 6241 additions and 312 deletions
+68 -2
View File
@@ -1,12 +1,78 @@
# Web 前端交接:商品编辑器与 AI 填报
更新日期:2026-09-30
更新日期:2026-10-04
## 2026-10-04 SKU 主动重算使用最新默认方案
根因:`SkuPricing.calculate` 优先使用 SKU 已保存的 `pricing_draft`,「重新试算」和批量按钮只强制重发相同参数,旧零折扣因此使实际售价与划线价相同。当前集成会话仅调整 Web `SkuPricing`、补充定价引擎公式回归测试及 API/交接说明,不修改服务端业务、HTTP 字段、定价引擎或数据库。
两个主动入口重读目标店铺定价目录,使用最新默认方案的完整参数替换旧 SKU 参数,沿用当前成本与有效包装;无默认方案/费率不可用/读取失败时明确提示,不回退零折扣。自动试算、手工售价输入和试算详情继续使用当前参数。批量跳过已导入 SKU,试算结果仍需保存草稿确认。表单监听保留未注册字段,返回报价直接核对实时表单,避免参数回填的渲染时序误丢弃报价;建立同一计算上下文时不取消已经发出的匹配请求。
验证:ego-browser 隔离真实组件复现旧零折扣两价相同,确认单 SKU 与批量使用最新 50% 折扣、划线价为实际售价两倍,保留成本和包装继承,跳过已上架 SKU;页面打开后将默认方案改为 25% 再重算能读取新值;手工实际售价不覆盖当前折扣;无默认方案、费率不可用、目录失败均不生成回退报价。定价引擎 16 项(新增 CNY/RUB 的 50% 折扣)和定价保存 12 项通过;Web/API 源码与测试类型检查、构建及差异检查通过。临时页面已清理,无真实商品保存或平台发布,未手动启停原有服务。
## 2026-10-04 实际售价、划线价展示与首次发布价格
本轮由当前集成会话负责,范围为 Web `SkuPricing`、`PricingCalculator`、`ProductPublishActions`、SKU 样式,API 发布映射/校验、发布回归测试和相关文档。按维护者要求,首次上架的 Ozon `price` 改为已确认 `listing.list_price`,不发送 `old_price`;保持 HTTP 字段、定价公式、数据库和 Worker 冻结快照执行方式。实际售价继续用于目标利润计算,用户上线后在 Ozon 调整实际售价;已创建任务沿用原价格快照,已导入 SKU 不自动更新。
SKU 收起摘要和展开定价区显示采购价、实际售价、划线价、预估净利润;试算结果实际售价与划线价同行。非人民币报价按同一报价快照比例换算摘要,不读取当前汇率改写历史价格。确认上架表格同时显示两价,划线价标为「本次上报价」。服务端预检与创建要求划线价有效且不低于实际售价,缺失/零值返回 `LIST_PRICE_REQUIRED`,低于实际售价返回 `LIST_PRICE_INVALID`;零折扣两价相同可发布。
验证:发布 11 项、商品编辑 13 项、定价引擎 15 项、定价保存 12 项全部通过,覆盖十进制划线价冻结/实际模拟 Ozon 请求、实际售价保留、零折扣、缺失/零划线价阻断、幂等和租户隔离。API 源码/测试类型检查及构建、Web 类型检查及构建通过。ego-browser 隔离真实组件检查 721px/390px 下的两价同行与无页面横向溢出、展开区、上架确认和 RUB 报价的人民币摘要;未向真实 Ozon 发布,未修改真实商品,原有服务未手动启停。临时验证页面已清理。
## 2026-10-04 主题标签格式与 AI 输出校验
本轮由当前集成会话负责,范围为共享 `ozon-hashtags.ts` 规则、Web SPU/SKU 标签提示、API 发布预检/创建校验、Worker AI 全局及 SKU 文案提示词与输出整理,以及相关测试和文档;不修改 HTTP 请求结构、数据库或标签覆盖继承语义。标签逐项以单个 # 开头,正文只允许字母、数字和下划线,无内部空格;每项含 # 最多 30 字符,最多 30 项,发布继续拼为一个 Ozon 属性值。AI 补齐缺失 #,词间空白及连字符转下划线,过滤非法、超长及重复项,并保留同项中文对照。
历史与手工草稿仍允许保存,Web 给出具体格式提示;预检和任务创建按所选 SKU 实际使用的标签拦截,返回 `OZON_HASHTAG_INVALID`,合法 SKU 独立覆盖不受未使用的通用标签阻断。Web 支持以空格拆分多个输入标签,不自动改写已有内容。新规则及示例见商品编辑 API 文档。
验证:Worker 11 项、发布 HTTP/数据库/模拟 Ozon 10 项、商品编辑 13 项通过;contracts/API/Worker/Web 类型检查与构建通过。ego-browser 隔离真实组件验证缺少 #、内部空格、非法标点、合法标签清除提示、空格拆分及 SKU 覆盖独立提示;临时页面已清理。未调用收费 AI 或向真实 Ozon 店铺发布,API/Worker 仍沿用原有开发监听进程,无手动启停。
## 2026-10-04 上架 SKU 整行选择
「选择与校验上架 SKU」弹窗支持点击整行选中/取消 SKU;复选框保留原有行为,点击不会因冒泡重复切换。行点击与复选框共用状态判断,只有未上架或失败 SKU 可选,已导入、提交中及其他不可重复提交状态仍禁选。仅修改 Web `ProductPublishActions.tsx` 和本文档,无接口、契约或发布规则变更。
Web 类型检查和生产构建通过;ego-browser 隔离页面验证整行选中/取消、复选框无重复切换、失败 SKU 可选、已导入/提交中禁选与全选。未执行真实预检或发布,临时页面已删除,未启停维护者服务。
## 2026-10-04 商品编辑属性与 SKU 文案显示修复
本轮负责人为当前前端会话,修改范围为 `ProductEditPage.tsx`、`DynamicAttributeFields.tsx`、`SkuInfoPanel.tsx` 和本文档;复用商品编辑快照、类目 schema、草稿保存与 AI 任务接口,无 API、Worker、数据库或共享契约变更。
属性草稿补齐从 schema 请求回调拆为独立表单联动:同类目保存重载过滤掉空属性后,仍补齐商品级与已有 SKU 的属性控件;动态属性组件监听顶层 `attributes`,避免缓存 schema 下不重新渲染。schema 请求仅随 profile、平台、类目或刷新版本变化,避免请求自身写入的缓存状态清理其轮询回调。AI 任务前后比较归一化后的保存内容,补齐空属性控件不会误判为人工修改。
SKU 展开区始终显示标题、标签、描述和文案 AI/中文对照入口;通用模式只预览 SPU 文案,不写入 SKU 覆盖值,开启逐 SKU 编辑后沿用原有字段绑定和标题模式。全局 AI 仍只生成 SPU 文案;类目属性仍按 schema 手工填写。
验证:Web 类型检查、生产构建和 `git diff --check` 通过。ego-browser 隔离模拟商品验证了 AI 选定类目后必填/选填及 SKU 属性出现、空属性保存重载后控件恢复、商品/SKU 属性作用域与重读、通用预览不产生覆盖值、AI 前自动保存后正常回填、缺失 schema 自动轮询恢复、逐 SKU 标题/描述编辑保存后恢复。未调用真实模型或写入真实商品;临时验证页面已删除。沿用维护者原有 Web/API 服务,无手动启动、停止或重启。
## 2026-10-04 套图生成固定操作区
按维护者确认的「并列操作」方案实现。生图策略列拆为独立滚动内容和底部常驻操作区;待生成保留 48px 主按钮,排队/生成时左侧取消、右侧状态,生成数量进度显示在下方。规划期间显示「取消规划」与规划状态,取消前确认并保留当前方案;生成取消前提示已完成数量,取消请求有重复操作保护。失败/取消后的未完成图片可在底部重试,成功图片保留;原结果列重复的进度与重试入口移至操作区。执行和重试的摘要取任务快照,调整下一轮方案不改变任务摘要;另保留按当前方案创建新任务的入口。
本轮负责人为当前集成会话,修改范围为 Web 抽屉、操作区组件、样式和交接记录,复用既有套图取消/重试接口,无共享契约、API、Worker 或数据库变更。桌面三列保持独立滚动,880px 以下两列时策略区随抽屉保持可见,580px 以下上下排列;策略高度取抽屉正文容器高度,避免依赖固定标题高度。当前业务页停留在登录页,使用临时隔离页面挂载真实组件,以模拟任务验证 1280px、838px、320px 布局、滚动固定、取消确认/继续生成、取消后保留成功图片、只重试未完成项、取消规划保留方案及任务快照摘要。未提交真实模型请求或修改商品草稿,临时验证页面已删除;Web 类型检查、生产构建和差异格式检查通过,沿用维护者原有开发服务,无手动重启。
## 2026-10-03 AI 套图生成
智能规划失败诊断已补齐:真实 DeepSeek 诊断复现连续两次在四张图片的 `type` 字段收到枚举校验错误。Worker 提示词改用有效的 `white_background` 示例和完整英文类型枚举,第二次规划携带具体字段路径及校验规则;共享错误码区分字段、张数、首图、主题、尺寸与保存失败。每次校验及最终失败打印结构化日志,安全诊断保存在 operation.result.failure。历史失败没有原始诊断,仍保持原记录。本轮实际模型请求限用户授权的两次,未执行生图;修复后的真实模型结果需下次规划确认。Worker 规划及 DeepSeek 客户端 19 项测试通过,覆盖同类错误反馈与纠正;contracts/API/Worker/Web 类型检查与构建通过,API/Worker 原有 watch 进程运行,无手动重启。
参考底图弹窗改为左右两列,复用 `SkuImageCard`、`SkuImageSourceTabs` 和 SKU 弹窗基础样式。左侧用 3:4 缩略图和顺序编号展示已选底图,第一张标为主体图,可移除、设为主体和拖动排序;右侧保留五类来源,点击图片选中/取消,左上角显示勾选。移除重复来源名称标签,不对原图裁切或拉伸。共享图片卡片允许不传编辑菜单,主体标记文案可配置,键盘操作只响应卡片自身,避免操作子按钮时重复触发。顶部数量靠左、灰色提示靠右;左右区域独立滚动,580px 以下上下排列。已在页面核对框比例 0.75、选择两张、主体切换、拖动排序、键盘移除和预览返回;Web 类型检查和构建通过,验证后恢复原有未选状态,未保存商品或调用生图。
本轮验证:Worker 规划/DeepSeek 客户端相关 17 项、API/数据库套图相关 8 项通过;contracts/API/Worker/Web 类型检查与构建通过。页面核对总张数由 4 调整到 5 后预算提示同步,已恢复默认 4。模型响应使用模拟数据,未实际调用 DeepSeek 或收费生图;没有手动启动或重启维护者服务。
智能规划按当前方案总张数提交 `image_count`(1–20,默认 4),预算独立于商品文本。DeepSeek 基于当前 SKU 的文字资料分配用途,按必要性选择场景、尺寸、材质等;规划完成后显示主题、说明和依据,不自动生图。取消/失败保留当前方案,诊断区分配置、连接和无效方案;历史恢复剥离规划预算字段,避免将其传入生成接口。
四类图片数量控件的减号按钮、输入框外框和加号按钮统一由 24px 加高至 28.8px(20%),输入内容垂直居中,宽度保持现有规格。
生成策略移除默认/AI 两个选项,改为右对齐的「AI 智能规划」操作按钮。默认四张自动展示;点击按钮异步规划并更新当前方案,规划成功后可再次点击重新规划;失败保留当前方案,规划期间禁用重复提交。
三列布局在上次策略列加宽的基础上,生图策略收窄 5%、商品资料加宽 5%;标准及 1100px 以下的三列布局同步调整比例和最小宽度。
界面反馈已落实:实物尺寸拆为长/宽/高,默认 CM,切换 MM/M 时换算实际数值,仍沿用带单位尺寸字符串契约。长/宽/高和实物重量统一使用 Ant Design `InputNumber`,支持小数;重量默认 g,可切换 kg 并换算实际净重,历史带明确单位的重量以 g 回填,提交仍使用带单位字符串。文本域为「采集信息/描述」「核心卖点/要求」。风格折叠标题、文本域和恢复默认按钮与风格按钮对齐,生成按钮高 48px。四类图片数量采用减号/输入框/加号组合,支持直接输入 0–5,边界禁用对应按钮;点击数量控件不触发分类展开/收起。
底部「AI 套图生成」已接入 `ProductImageSuiteDrawer` 三列右侧抽屉。目标为已保存 SKU,底图库最多 8 张,来源顺序采集/AI/处理/上传/网络;默认 4 张(白底/场景/核心卖点/细节各 1),分类数量 1/1/2/0,四大类逐张计划可编辑,AI 规划走异步 DeepSeek。Pcore 使用现有单图 Worker 生成子任务,整套与子任务通过数据库汇总,可后台生成、取消、失败重试。成功图片加入目标 SKU 后只修改表单,仍需保存。新契约见 [套图 API](../../docs/api/product-image-suites.md),迁移为 056–059。联调验证不执行真实收费生图,实际图像质量需用业务商品验证。
本文记录 Web 编辑页的现行状态;跨领域总体进度以 [`../../docs/project/HANDOFF.md`](../../docs/project/HANDOFF.md) 的 1.39 为准。开始继续开发前请查看仓库根目录的 `git status --short`,保留目前 API、Worker、contracts、迁移及 Web 中未提交和未跟踪的改动。
## 当前状态(2026-09-30)
- 编辑页 `/products/:id/editor` 的 `ProductEditPage.tsx` 将底部操作条固定在视口底部,提供「AI 填报」和「保存草稿」;AI 套图生成仍是占位入口;首次上架已接入,见下方记录。全局 AI 填报会先保存未保存草稿,再创建异步任务并轮询;核对商品、profile、来源版本和本地表单未变化后,只把合格结果填进空字段,不直接持久化。用户仍须检查并保存。
- 编辑页 `/products/:id/editor` 的 `ProductEditPage.tsx` 将底部操作条固定在视口底部,提供「AI 填报」和「保存草稿」;AI 套图生成已接入三列右侧抽屉;首次上架已接入,见下方记录。全局 AI 填报会先保存未保存草稿,再创建异步任务并轮询;核对商品、profile、来源版本和本地表单未变化后,只把合格结果填进空字段,不直接持久化。用户仍须检查并保存。
- 全局 AI 只回填 SPU 发布标题、标签、描述和中文对照,以及合格的类目、型号、未导入 SKU 货号与有证据的包装建议。类目有多个候选时,「确认 AI 推荐类目」弹窗用单选卡片让用户选择;选择前不自动写入类目。类目一旦确定,页面按现有机制加载动态属性,但不调用 AI 填写 Ozon 类目属性。
- SPU 的「中文商品名」和「俄文标题」标示首次上架必填,草稿保存允许留空;俄文标题可在通用与按 SKU 设置间切换并保存模式,按 SKU 设置时清空、禁用 SPU 标题并在各 SKU 填写。标题、标签、描述各有中文对照入口;用户可在当前 SKU 弹窗中单独生成、预览并明确应用,不因全局 AI 填报而批量覆盖 SKU。
- SKU 的 Ozon `is_aspect` 字段现在直接放在展开卡片的「SKU 信息」中,不另显示「Ozon 变体属性」标题。产品类目 Cascader 的清除事件按空类目处理,避免读取 `undefined.at`。来源采集信息侧栏仍展示来源资料与差异处理。