feat(edit): 定价试算开发、SKU 样式功能修改

This commit is contained in:
R524809
2026-09-29 17:50:19 +08:00
parent 84b230e69a
commit 0a303414d8
52 changed files with 4278 additions and 1393 deletions
@@ -0,0 +1,72 @@
# 类目佣金 JSON 导入与定价接入方案
> 2026-09-29:维护者已批准实施。目标是通过「系统管理 → 类目佣金」导入、核对并启用分档规则,让商品编辑页和即时试算自动读取佣金。
## 1. 范围与责任
本任务由当前会话负责跨领域集成,涉及 `apps/web`、`apps/api`、`packages/contracts`、`packages/database` 和文档。原因是导入页面、管理员鉴权、数据库原子启用和报价规则读取必须形成一个可验收能力。新增接口采用独立契约,不破坏现有报价请求。
本次只支持 Ozon、RU、rFBS、RUB 阶梯佣金。数据是平台共享参考数据,沿用平台目录的系统管理员权限;普通用户仅通过已授权门店查询有效规则。导入来源为 `competitor_capture`,保留来源信息与版本。
## 2. 已核对的数据
用户附件包含 26 个一级类目、542 个二级类目、1,626 条规则。每个二级类目都是三档:`0 < 售价 ≤ 1500₽`、`1500₽ < 售价 ≤ 5000₽`、`售价 > 5000₽`。84 个二级类目的三档费率相同。标签百分比与 `value` 一致。
2026-09-29 只读核对本地 Ozon 平台目录:542 个二级 `cate_id` 全部匹配,一级父类目 ID 全部一致,覆盖 7,365 个有效商品类型。目录最近同步于 2026-09-28。该结果证明本次可建立映射,不代表任意未来附件的 ID 都正确。
来源 `id` 是树节点编号,不能用作平台 ID。`cate_id` 保存为来源键,并与 Ozon `external_category_id` 核对;同名类目不能合并。第三层是价格档,不是商品类型。
`200001728`(管材、桩材、型材)和 `17028768`(Ozon Fresh 新鲜及冷冻肉类、家禽和鱼类)的三档都是 0%。维护者明确指出 0% 可能是平台的真实优惠费率;导入按有效佣金处理并保留原值,不由系统推断为占位值。
## 3. 页面与流程
系统管理增加「类目佣金」列表,展示平台规则版本、来源、启用时间及覆盖数量,选中版本查看各类目的三档费率。
导入弹窗:
1. 上传 JSON(也可粘贴文本),填写来源说明、采集日期、版本名称。
2. 服务端校验格式、ID 唯一性、档位、百分比一致性;与当前平台目录匹配,生成预览。
3. 预览列出新增、变更、未变类目和目录异常(未匹配、父子关系不符、无有效商品类型);显示成功类目及商品类型覆盖数量。异常类目不进入可启用集合。
4. 管理员确认来源适用于 RU/rFBS;预览明确展示无法映射数与上一版本被移除的覆盖数,但不要求额外勾选排除确认。
5. 点击「确认并启用」,后端重算预览指纹,若目录、当前版本或输入变化则返回冲突并要求重新预览。成功后立即生效。
首版只支持立即启用,不做定时发布、逐条在线编辑、后台抓取或自动猜测缺失费率。0% 佣金直接按来源导入。无法映射的类目保留在导入版本及预览中,但无法建立定价映射;只要存在可映射类目,就可启用其余规则。
## 4. 存储与原子启用
复用 `commission_categories`、`commission_category_rules`、`platform_product_category_commission_mappings`;增加导入版本表保存原始 JSON、内容指纹、来源、采集日期、操作者、统计和启用时间。规则及映射关联导入版本。
费率按比例字符串存储,例如 12% 为 `0.120000`,20.50% 为 `0.205000`。金额边界为精确十进制,第三档上界为 null。一级类目仅用于分组,规则挂在二级佣金类目下;商品类型叶子通过显式映射共享规则。
启用在单个数据库事务内完成:检查系统管理员权限、锁定平台、检查预览指纹、保存版本、写入类目与规则、建立有效商品类型映射、结束被替代规则/映射的有效期。失败整体回滚。所有关键写操作要求 Idempotency-Key;重复提交同一批次不产生重复版本。
同平台、市场、履约模式只保留一个当前导入版本。使用新的规则行保留历史引用,禁止修改已启用的费率、区间和来源。报价保存时仍重新读取规则并检查指纹,旧预览在换版后不能确认;已确认报价保留历史快照。
## 5. 规则查询与算价
增加卖家查询接口:按 `store_id` 和 Atlas 商品类目 UUID,或者按已核对的 Ozon `description_category_id` 查询,二者只能指定一个;返回匹配类目、币种、全部价格档、来源、版本、生效日期。门店必须属于当前工作空间。
查询接口与报价共用正式规则解析逻辑;报价仍由后端选择规则,前端不能用传入佣金替换有效正式规则。现有定价引擎已经逐档反算售价、舍入并检查区间,继续复用。规则的区间币种为 RUB,CNY 门店按当前预览锁定的汇率换算判断。
现有试算结果增加佣金类目、档位、百分比、来源版本展示;有正式规则时无需填写临时佣金。未覆盖类目继续给出缺失规则提示。前端展示缺失状态不能把它误写成 0%。
## 6. 验收
- 原始附件可预览 542 类、1,626 档,包括两个全档 0% 类目,均可映射。
- 错误 JSON、重复 ID、缺失档位、标签和值不一致的费率被拒绝。
- 同名不同 ID 保持独立;父类目不符和未匹配项不会自动发布。
- 普通用户不能预览或启用管理员导入;跨租户门店查询失败。
- 启用重放、并发换版、陈旧预览、完整回滚及历史规则保护有数据库/API 测试。
- `1500`、`1500.01`、`5000`、`5000.01` 正确命中档位,CNY/RUB 试算和目标利润反算使用正式规则。
- 新版启用后旧试算预览失效,已有确认报价保持原快照。
- 受影响工作区通过类型检查、构建和相关测试;浏览器验证上传、预览、异常提示与启用条件。
## 7. 实施顺序
先补充 API 契约与共享 DTO,再实现导入解析器、数据库迁移和原子启用,随后实现管理页面与菜单、查询及试算展示,最后完成测试与交接记录。开发验证使用测试数据,不自动把用户附件启用为正式业务费率;正式启用需由管理员在页面确认其来源与适用范围。
## 8. 实施结果(2026-09-29)
已实现以上主流程,迁移为 `052_category_commission_imports.sql`。最初附件预览为 540 类 / 7,358 类型;维护者纠正 0% 处理后,新版浏览器实测 542 类 / 7,365 类型均可映射。修正后 38 项相关测试、API/Web 类型检查与构建、contracts/database 构建通过;浏览器曾核对上传、预览、异常筛选、确认条件和预览失效;0% 处理修改后已重新验证全部 542 类均可用,且不需要额外排除确认。数据库启用/历史查询/失败回滚使用事务测试验证,未启用用户附件,未做多连接并发压力测试。
首版映射为发布时快照,不自动补齐后续同步新增类型;同内容重复导入被拒绝,映射单独刷新能力留待后续。正式使用前需管理员在页面确认数据适用范围。