diff --git a/docs/sku-mapping-business-guide.md b/docs/sku-mapping-business-guide.md new file mode 100644 index 0000000..e93509a --- /dev/null +++ b/docs/sku-mapping-business-guide.md @@ -0,0 +1,194 @@ +# SKU Mapping 业务场景说明 + +> 创建日期:2026-04-16 +> 适用模块:`skus_mapping`、`skus_origin` + +--- + +## 一、业务模型概述 + +SKU Mapping 是 Datahub 系统中连接客户内部 SKU 体系与电商平台 SKU 体系的桥梁。由于不同平台对 SKU 编码有格式限制(如不能以 `0` 开头、不能包含特殊字符等),系统需要维护一套映射关系,将客户的原始 SKU(`origin_sku`)转换为符合各平台规范的平台 SKU(`platform_outer_sku`)。 + +**核心实体**: + +| 实体 | 表 | 说明 | +|------|------|------| +| Origin SKU | `skus_origin` | 客户内部 SKU 编码,公司级唯一 | +| SKU Mapping | `skus_mapping` | origin_sku → platform_outer_sku 的映射记录 | +| Platform | `platforms` | 电商平台(Shopee、Tmall 等)| +| Store | `stores` | 平台下的具体店铺 | + +**映射粒度**:店铺级别 — 同一平台下不同店铺可使用不同的 `platform_outer_sku`。 + +--- + +## 二、核心业务场景 + +### 场景 1:普通映射(1:1) + +最基础的场景。一个 `origin_sku` 在一个平台下映射到一个 `platform_outer_sku`。 + +``` +origin_sku: "0032" → platform_outer_sku: "C03_0032" (Shopee) +``` + +**数据示例**: + +| origin_sku_id | platform_id | platform_outer_sku | bundled | +|---------------|-------------|-------------------|---------| +| 1 | 1 (Shopee) | C03_0032 | false | + +### 场景 2:多平台映射(1:N) + +同一个 `origin_sku` 在多个平台分别生成不同的 `platform_outer_sku`。 + +``` +origin_sku: "0032" + → Shopee: "C03_0032" + → Tmall: "TM_0032" + → Lazada: "LZ_0032" +``` + +**数据示例**: + +| origin_sku_id | platform_id | platform_outer_sku | bundled | +|---------------|-------------|-------------------|---------| +| 1 | 1 (Shopee) | C03_0032 | false | +| 1 | 2 (Tmall) | TM_0032 | false | +| 1 | 3 (Lazada) | LZ_0032 | false | + +### 场景 3:同平台多规则映射 + +同一个 `origin_sku` 在同一个平台下有多个不同的 `platform_outer_sku`(例如不同店铺使用不同编码)。 + +``` +origin_sku: "0032" + → Shopee 店铺A: "C03_0032" + → Shopee 店铺B: "SP_CUSTOM_0032" +``` + +**数据示例**: + +| origin_sku_id | platform_id | store_id | platform_outer_sku | bundled | +|---------------|-------------|----------|-------------------|---------| +| 1 | 1 (Shopee) | 101 | C03_0032 | false | +| 1 | 1 (Shopee) | 102 | SP_CUSTOM_0032 | false | + +> 唯一索引 `(origin_sku_id, platform_id, platform_outer_sku)` 允许此场景,但防止同一组合产生重复记录。 + +### 场景 4:组合商品(Bundle) + +一个 `platform_outer_sku` 实际对应多个 `origin_sku`,标记 `bundled = true`。典型场景:平台上的"套装"由多个单品组成。 + +``` +platform_outer_sku: "BUNDLE_SUMMER" + → origin_sku: "SHIRT_001"(上衣) + → origin_sku: "PANTS_002"(裤子) + → origin_sku: "HAT_003"(帽子) +``` + +**数据示例**: + +| origin_sku_id | platform_id | platform_outer_sku | bundled | +|---------------|-------------|-------------------|---------| +| 10 (SHIRT) | 1 (Shopee) | BUNDLE_SUMMER | true | +| 11 (PANTS) | 1 (Shopee) | BUNDLE_SUMMER | true | +| 12 (HAT) | 1 (Shopee) | BUNDLE_SUMMER | true | + +> 唯一索引允许不同 `origin_sku_id` 共享同一 `platform_outer_sku`,因为三元组 `(origin_sku_id, platform_id, platform_outer_sku)` 各不相同。 + +--- + +## 三、使用流程指南 + +### 3.1 创建映射 + +1. **选择公司** → 加载该公司下的 Origin SKU 列表 +2. **选择 Origin SKU** → 系统自动填充 `origin_sku` 快照字段 +3. **选择平台** → 选择目标店铺(可选) +4. **生成 platform_outer_sku**: + - **前缀模式**:`{prefix}_{origin_sku}`,如 `C03_0032` + - **前缀+随机模式**:`{prefix}_{random}`,如 `C03_A7K2` + - **手动模式**:用户直接输入 +5. **唯一性预检** → 系统检查 `(origin_sku_id, platform_id, platform_outer_sku)` 是否已存在 +6. **重复提示** → 如果同一 origin_sku 在该平台已有映射,提示用户可复用 +7. **提交创建** + +### 3.2 自动生成逻辑 + +调用 `POST /api/v1/sku-mappings/generate-sku` 接口时: +- 根据策略参数生成 `platform_outer_sku` +- 同时执行重复检测,返回该 origin_sku 在目标平台下的已有映射 +- 前端展示生成结果和重复提示,由用户确认后提交 + +### 3.3 组合商品处理 + +创建组合商品映射时: +1. 开启 `bundled` 开关 +2. 输入统一的 `platform_outer_sku`(如 `BUNDLE_SUMMER`) +3. 为套装中的每个 origin_sku 分别创建一条映射记录,均使用相同的 `platform_outer_sku` 和 `bundled = true` +4. 查询时可通过 `bundled` 筛选快速定位组合商品映射 + +--- + +## 四、实体关系图 + +``` +┌──────────┐ 1:N ┌──────────────┐ +│ Company │─────────────▶│ SkuOrigin │ +│ │ │ (skus_origin)│ +└──────────┘ └──────┬───────┘ + │ │ + │ origin_sku_id (FK, NOT NULL) + │ │ + │ 1:N ┌────────────────▼────────────────┐ + ├─────────▶│ SkuMapping │ + │ │ (skus_mapping) │ + │ │ │ + │ │ UK: (origin_sku_id, platform_id, │ + │ │ platform_outer_sku) │ + │ └──────┬──────────┬────────────────┘ + │ │ │ + │ platform_id store_id (nullable) + │ │ │ + │ ┌──────▼──┐ ┌───▼─────┐ + └─────────▶│Platform │ │ Store │ + └─────────┘ └─────────┘ + +组合商品关系: + SkuOrigin A ──┐ + SkuOrigin B ──┼──▶ 同一 platform_outer_sku (bundled=true) + SkuOrigin C ──┘ +``` + +--- + +## 五、注意事项与约束 + +### 5.1 唯一性约束 + +- **数据库级**:唯一索引 `uk_origin_platform_sku (origin_sku_id, platform_id, platform_outer_sku)` 确保数据一致性 +- **应用级**:Controller 层在 store/update 时执行唯一性预检,返回友好的 422 错误而非数据库异常 + +### 5.2 必填字段 + +V2 改进后,以下字段为必填: +- `origin_sku_id`:必须关联有效的 Origin SKU 记录 +- `platform_outer_sku`:映射记录必须包含平台编码 + +### 5.3 数据隔离 + +- 所有查询通过 `DataScope` 中间件按 `company_id` 隔离 +- 跨公司数据不可见 + +### 5.4 组合商品限制 + +- 组合商品映射的 `bundled` 字段应统一为 `true` +- 创建组合商品映射时,前端应引导用户为每个组成 SKU 分别创建记录 +- 删除组合商品映射时,建议提示用户是否一并删除同组的其他映射 + +### 5.5 Origin SKU 快照 + +`skus_mapping.origin_sku` 字段存储的是创建映射时从 `skus_origin.sku` 复制的快照值,用于: +- 即使 Origin SKU 被修改,历史映射记录仍保留原始编码 +- 订单匹配时使用快照值进行比对