Files
atlas-seller-kit/apps/web/HANDOFF.md
T

21 KiB
Raw Blame History

Web 前端交接:商品编辑器与 AI 填报

更新日期: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,迁移为 056–059。联调验证不执行真实收费生图,实际图像质量需用业务商品验证。

本文记录 Web 编辑页的现行状态;跨领域总体进度以 ../../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、来源版本和本地表单未变化后,只把合格结果填进空字段,不直接持久化。用户仍须检查并保存。
  • 全局 AI 只回填 SPU 发布标题、标签、描述和中文对照,以及合格的类目、型号、未导入 SKU 货号与有证据的包装建议。类目有多个候选时,「确认 AI 推荐类目」弹窗用单选卡片让用户选择;选择前不自动写入类目。类目一旦确定,页面按现有机制加载动态属性,但不调用 AI 填写 Ozon 类目属性。
  • SPU 的「中文商品名」和「俄文标题」标示首次上架必填,草稿保存允许留空;俄文标题可在通用与按 SKU 设置间切换并保存模式,按 SKU 设置时清空、禁用 SPU 标题并在各 SKU 填写。标题、标签、描述各有中文对照入口;用户可在当前 SKU 弹窗中单独生成、预览并明确应用,不因全局 AI 填报而批量覆盖 SKU。
  • SKU 的 Ozon is_aspect 字段现在直接放在展开卡片的「SKU 信息」中,不另显示「Ozon 变体属性」标题。产品类目 Cascader 的清除事件按空类目处理,避免读取 undefined.at。来源采集信息侧栏仍展示来源资料与差异处理。
  • 关键组件:ProductMainInfoSection.tsx(名称、类目、SPU 标题等)、ProductAttributeSection.tsx(SPU 属性、标签与描述)、ProductVariantSection.tsx(SKU 信息及动态变体字段)、ProductCopyAiDialogs.tsx(SKU AI 生成与中俄对照)。商品编辑流程编排仍主要在 ProductEditPage.tsx。

下一轮前端回归应覆盖固定 footer 在不同视口/侧栏状态下不遮挡内容、类目清除和候选确认、AI 任务失败/部分成功/版本过期、SPU/SKU 文案继承与中文对照保存后重读。俄文禁汉字的最终拦截在 Worker,旧文案不会由前端自动清洗。本次更新只修改交接文档,未重新运行浏览器回归。

2026-09-30 首次上架

  • ProductPublishActions.tsx 提供「上架至 OZON」「部分上架」,沿用父页面草稿保存与版本锁,按指定 SKU 调用预检;超过 50 个需分批选择,任一待提交项失败不创建任务。
  • 选择表禁选已导入/进行中 SKU,并显示原因;确认摘要列出店铺、货号、售价和图片数量。任务列表恢复最近任务,轮询后仅合并 listing 状态,保留未保存表单。
  • 发布标题最多 500、货号最多 50、SKU 图片最多 30;中文来源商品名仍为 1000。已导入或进行中锁定型号,进行中锁定换店;其他草稿资料可以编辑。
  • Web 类型检查及构建通过。隔离数据库页面验证了禁选、全部/部分预检、缺货号阻断、确认提交和刷新恢复;没有向真实 Ozon 店铺导入。
  • VAT 首期省略且生产发布默认关闭;真实店铺与七牛图片交付待验收。后端契约见 docs/api/product-editor-and-publishing.md 第 7 节。

2026-09-11 历史前端记录(以下内容仅供追溯)

商品编辑器

  • 编辑页为 /products/:id/editor,主文件为 src/pages/products/ProductEditPage.tsx。
  • 已接入门店级类目 Cascader:保存时只提交末级类目 ID;父级节点可展开,只有叶子节点可选。类目下拉菜单高度为 324px(相对 Ant Design 默认菜单高度提高 80%)。
  • “更多特征”位于 02 产品属性 Card 内,不再单独使用 Card;展开后按当前选定类目加载 schema,折叠再展开且类目未变时复用已加载的 schema。加载、空 schema、同步类目属性、字典值搜索、清除字段和旧属性告警均在该区处理。
  • 动态属性字段按 schema 渲染:普通值为输入框、布尔值为选择框、字典值为可搜索下拉、多值为多选/标签输入;保存时会过滤空的可选属性值,避免提交无效空数组。
  • “主题标签”和“JSON 富内容”属于产品属性的普通字段,不属于“更多特征”。
  • 编辑页表单已去除页面级的字号、控件高度覆盖,恢复 Ant Design 主题默认规格。仍保留业务性宽度:型号/品牌/条码 170px,包装重量 150px,包装尺寸各 130px。
  • 包装重量通过 package-weight-field 单独约束输入组宽度,避免 addonAfter="g" 与输入框分离;父表单的标签列为 190px、控件区域为可收缩 680px,避免控件被换到标签下一行。

组件拆分现状

已拆出的组件:

  • src/pages/products/components/ProductMainInfoSection.tsx:主要信息、目标门店、类目、标题、品牌、型号、父商品包装规格。
  • src/pages/products/components/ProductOtherSection.tsx:货源链接和备注。
  • src/pages/products/components/CollectedProductInfoPanel.tsx:右侧“采集的商品信息”侧栏。

仍在 ProductEditPage.tsx 中的视图:产品属性/更多特征,以及变体设置。后续若继续组件化,应将它们分别迁为展示组件;父页面只保留快照读取、草稿保存、类目/schema/字典同步和状态编排。迁移时不要改变 Form.List 字段路径、乐观锁保存流程或动态属性的按需加载缓存条件。

门店与类目调试入口

  • 店铺列表的“刷新门店类目”按钮在 src/pages/shops/ShopsPage.tsx;前端会等待请求完成才结束 loading,并展示成功或失败反馈。
  • 左侧菜单新增“调试 → Ozon 类目树调试”,路由为 /shops/category-tree-debug。
  • 调试页文件:src/pages/shops/CategoryTreeDebugPage.tsx、CategoryTreeDebugPage.css;服务封装为 src/services/categoryTreeDebug.ts。该页只负责调用已存在的前端 API 封装并以 Ant Design 树展示响应,不能在前端处理或持久化 API Key。

关键前端行为

  1. 选定目标门店后才读取该门店的类目缓存;加载期间 Cascader 显示“正在读取该店铺的类目缓存”。
  2. 切换类目会清空草稿属性;展开“更多特征”后才读取新类目的 schema。
  3. 动态属性的字典搜索输入至少两个字符后,用户可显式选择“从 Ozon 搜索”;前端不传递或记录 API Key。
  4. 页面 API、错误码和返回结构以 docs/api/ 与 @atlas/contracts 为准。前端不要自行扩展接口字段或模拟同步完成状态。

已执行验证

本次前端改动已执行:

cd apps/web
../../node_modules/.bin/tsc -p tsconfig.json --noEmit
git diff --check

两项均通过。后续对交互或样式作变更时,应在已启动的 Web 环境中回归:类目选择、更多特征展开/收起与加载状态、字典查询、包装重量同一行展示、SKU 展开编辑、货源链接按钮对齐,以及调试页的树形渲染。

当前工作约定

  • 当前任务可按仓库 AGENTS.md 修改相关项目代码;跨领域改动需遵守 ../../docs/project/development-collaboration-contract.md 并说明影响范围。
  • 验证需要时可在确认目标进程和端口后启动、停止或重启 API/Worker;完成后说明实际操作与状态。上方 2026-09-11 的验证记录不能替代新改动的检查。
  • 不在浏览器持久化、日志或页面状态中保存 Ozon API Key。