feat: 建立全局店铺跨渠道管理 (#208 #209 #210 #211)

This commit is contained in:
chengma
2026-08-13 11:15:54 +08:00
parent 901b37a8cb
commit 8f707722ba
28 changed files with 1160 additions and 500 deletions
+20 -8
View File
@@ -121,6 +121,10 @@ v15(#203)把历史 `syb_orders` 中每个蝦皮商品最新的非空店铺
“颜色,尺码【建议】”格式,并为历史数据补建无真实外部 ID 的低优先级蝦皮 SKU;
不明确格式只保留原文。v17(#205)为蝦皮商品增加 `deleted_at`、
`deleted_by_user_id` 和删除状态索引,删除改为可恢复的软删除。
v18(#208)新增 `shops` 业务店铺和 `shop_channel_aliases` 渠道名称表,并为
`syb_orders`、`shopee_products` 增加可空 `shop_id`。迁移把 v14 旧准入项一对一
转成业务店铺,同时保留 `syb_allowed_shops` 作为回退依据;历史数据只按渠道原始
名称精确回填,无法确认的记录保持未关联。
**v3 为什么丢弃旧 `sku_mappings` 数据(见 #20):** 新主键需要 `pdd_option_key`,
这是 Go 的 `service.OptionKey()` 用 `json.Marshal` 算出来的规范化键,SQL 语句
@@ -543,16 +547,24 @@ v14 起,`stock_count` 继续表示通过完整性校验的**原始货运单数
`shop_filter_hash` 保存同步开始时启用店铺排序后计算的 SHA-256,只用于判断两次同步
是否使用同一份快照,不保存 Cookie、密码或原始响应。
### 5.3 `syb_allowed_shops` 同步店铺准入(MySQL v14)
### 5.3 全局店铺与渠道名称(MySQL v18)
每个店铺只保留一条全局记录。`normalized_name` 是去除首尾空白后的名称并使用
`utf8mb4_bin` 唯一约束;匹配不做模糊、正则或大小写折叠。日常退出同步使用停用,
只有已停用项允许管理员永久删除;条件删除必须再次带 `enabled=0`,避免并发重新启用
后被误删。删除配置不级联历史货运单或同步记录。同步开始时一次读取所有
`enabled=1` 的名称作为不可变快照。
`shops` 是 Admin 内部统一展示的业务店铺;`shop_channel_aliases` 保存同一业务店铺
在 `syb`、`shopee` 渠道中的原始名称。首版每个业务店铺每个渠道维护一个主名称,
渠道和去除首尾空白后的原始名称组成唯一约束。匹配使用 `utf8mb4_bin` 精确比较,
不做模糊、正则、大小写折叠或 AI 猜测。
`[必须]` 没有任何启用店铺时同步关闭失败,不请求顺运宝、不推进游标。该表只控制
后续同步是否入库,不自动删除历史 `syb_orders`。
全局 `shops.enabled` 和 SYB 渠道名称的 `enabled` 是两个不同开关:前者停用整个业务
店铺,后者只停止该店铺进入后续 SYB 同步。蝦皮导入和 SYB 写入都保留上游原始店铺
名称,并把精确解析出的 `shop_id` 作为派生关联;未解析成功时 `shop_id` 保持 `NULL`,
由“待关联”筛选暴露给管理员处理。
`[必须]` 没有任何“业务店铺启用且 SYB 渠道启用”的名称时,同步关闭失败,不请求
顺运宝、不推进游标。编辑渠道名称会在一个事务里重建该业务店铺的历史精确关联。
永久删除只允许全局停用且没有任何货运单或蝦皮商品引用的店铺。
v14 的 `syb_allowed_shops` 在 v18 后不再作为运行时配置源,但为迁移回退保留,不能
在 v18 中直接改名或删除。
## 6. `spec_mappings` 顺运宝规格映射
+9 -5
View File
@@ -472,16 +472,16 @@ Go 的 map 是无序的,不靠它定顺序的话,同一个商品每次刷新
### 6.1 工具条
```text
开始日期 [2026-08-08] 结束日期 [2026-08-09] [同步] [同步记录] [同步店铺(N)·管理员]
开始日期 [2026-08-08] 结束日期 [2026-08-09] [同步] [同步记录] [店铺管理(同步 N)·管理员]
[创建 PDD 采集任务] [创建采购任务] 处理阶段 [全部] 店铺 [___] 订单号 [___] [搜索] [删除]
```
日期始终显示在主工具条,按 UTC+8 解释且两端都包含。首次打开页面固定默认昨天
到今天,不因覆盖游标位置自动扩大范围;需要补历史缺口时由采购员明确选择日期。
所有账号都能看到当前启用同步店铺数量;只有管理员显示“同步店铺”管理入口。
管理页使用可见的“店铺名称”标签,支持新增、停用、重新启用,以及永久删除已停用
店铺。启用店铺不显示删除入口,服务端仍必须按停用状态条件删除;确认文案显示店铺
名称,并说明历史货运单和同步记录不会删除。
所有账号都能看到当前启用 SYB 同步店铺数量;只有管理员显示独立“店铺管理”入口。
管理页一行一个业务店铺,同时展示和编辑 SYB、蝦皮原始名称;全局启停与 SYB 同步
启停使用不同按钮和明确文字。启用店铺不显示删除入口,服务端还要拒绝删除有关联
货运单或蝦皮商品的停用店铺。
空状态必须明确提示先新增并启用至少一个店铺,否则同步会安全停止。
`[必须]` 「同步」是唯一同步入口:
@@ -913,3 +913,7 @@ placeholder 写「任务编号 / 订单号 / 商品 ID」,**不要写全「PDD
150px并省略,完整值放在 `title` 和详情中。商品标题继续使用 `.col-title` 的 18%,
不得因新增列再次缩窄;1366×768 下通过表格横向滚动保留可读性。详情同时显示图片、
店铺、各自来源和观测时间,顺运宝观测图仍只出现在观测区域。
蝦皮列表同时显示“业务店铺”列,并提供具体业务店铺和“待关联”筛选。蝦皮店铺列
始终显示导入或同步得到的渠道原始值,用于追溯;业务店铺列显示 `shop_id` 对应的统一
名称。两列不能互相替代,未精确关联时必须显示文字“待关联”。