Files
makemd/docs/08_Analysis/07_Product_Center_Analysis.md
wurenzhi a037843851 refactor: 重构代码结构和类型定义,优化类型安全性和代码可维护性
- 添加类型定义文件和类型引用
- 删除废弃的页面模块和导出文件
- 新增聚合管理模块和插件系统
- 修复类型错误和潜在运行时问题
- 更新API基础URL和配置
- 优化组件类型定义和事件处理
- 重构数据源接口和实现
- 完善文档和开发进度记录
2026-03-22 11:25:28 +08:00

37 KiB
Raw Blame History

商品中心与价格系统深度分析报告

文档目的: 基于ChatGPT对话内容结合项目现有文档和代码实现系统梳理商品管理、价格策略、组织权限的核心架构识别差距并提出最优解决方案。

创建日期: 2026-03-22

参考来源: chatgpt-vs-2026-03-22T03-06-04-110Z.md


目录

  1. 核心概念梳理
  2. 现有架构分析
  3. 差距识别与问题诊断
  4. 最优解决方案
  5. 实施步骤
  6. 风险评估与应对
  7. 附录

1. 核心概念梳理

1.1 商品映射 vs 商品刊登

维度 商品映射Mapping 商品刊登Listing/Publish
本质 关系绑定 创建商品 + 发布到平台
动作 不创建新商品 创建新Listing
方向 双向绑定 单向(系统→平台)
触发时机 已有商品需要统一管理 新品上架、批量铺货
结果 系统知道"平台SKU = 主SKU" 平台新增商品
用途 统一库存、利润分析、AI调价 上新、自动铺货、跨平台分发

核心判断公式

这个动作有没有在平台创建新商品?

  • 有 → 刊登
  • 没有 → 映射

业务流程对比

场景1已有店铺商品 → 用「映射」
平台已有商品 → 抓取 → 绑定到系统SKU → 完成映射
用途统一管理库存、做利润分析、AI调价

场景2要卖新产品 → 用「刊登」
选品 → AI生成内容 → 发布到平台 → 创建Listing
用途:上新、自动铺货、跨平台分发

1.2 价格归属问题

核心结论

价格绝对不属于商品SKU本身 价格属于:"渠道 + 场景 + Listing"

价格多场景示例

场景1跨平台价格不同
同一个SKU
- Amazon$19.99
- TikTok$17.99
- Shopify$21.99
原因:手续费不同、流量成本不同、用户价格敏感度不同

场景2同平台同店铺价格不同AB测试/不同引流)
同一个SKU在同一个TikTok店铺
- Listing A$19.99(自然流量)
- Listing B$15.99(广告引流)
- Listing C$12.99(清库存)
原因AB测试、不同标题/人群、不同投放策略、不同活动入口

1.3 三层价格体系

┌─────────────────────────────────────────┐
│ 1⃣ 基准价层Base Price Layer         │
│    SKU.base_price = 99                  │
│    SKU.cost_price = 40                  │
│    用途:统一锚点、人工理解               │
└──────────────┬──────────────────────────┘
               │
               ↓
┌─────────────────────────────────────────┐
│ 2⃣ 策略层Strategy Layer             │
│    PriceStrategy:                        │
│    - scope: 平台/店铺/Listing            │
│    - type: multiplier/fixed/dynamic     │
│    - value: 1.1                          │
│    用途:规则定义、批量控制               │
└──────────────┬──────────────────────────┘
               │
               ↓
┌─────────────────────────────────────────┐
│ 3⃣ Listing层Final Price Layer       │
│    PlatformListing:                      │
│    - price最终成交价                  │
│    - strategy_id                         │
│    - override_price手动覆盖           │
│    用途:真正赚钱的地方                   │
└─────────────────────────────────────────┘

最终价格计算公式

最终价格 = override_price || strategy计算结果 || AI计算结果

三层价格体系示例

主SKU: SKU-001蓝牙耳机
├── TikTok主店东南亚 → 基准价 $99 → 策略: × 1.0 = $99
├── TikTok美国店美国 → 基准价 $99 → 策略: × 1.1 = $109
├── Shopee旗舰店马来 → 基准价 $99 → 策略: × 0.9 = $89
├── Shopify独立站全球 → 基准价 $99 → 策略: × 1.15 = $114
└── B2B批发国内 → 基准价 $99 → 策略: × 0.5 = $50

1.4 组织权限模型

核心原则

权限 = 能做什么Permission 数据范围 = 能操作谁的数据Scope 👉 两者必须同时存在

多租户层级结构

平台Platform
    ↓
商户/公司Tenant/Organization
    ↓
组织结构Org Tree
    ├── 部门A主管
    │     ├── 组A1组长
    │     │     ├── 员工1
    │     │     └── 员工2
    │     └── 组A2组长
    │           └── 员工3
    └── 部门B主管
          └── ...

Scope数据范围定义

type DataScope = 
  | 'SELF'     // 只看自己
  | 'TEAM'     // 看自己组
  | 'DEPT'     // 看自己部门
  | 'ORG'      // 看整个公司
  | 'ALL';     // 全平台(超管)

角色权限设计

角色 描述 权限范围
owner 拥有者 删除店铺、管理授权、管理成员、所有权限
admin 管理员 管理商品、管理价格、管理订单、不可删除店铺
operator 运营 刊登、改价、查看数据
viewer 只读 查看数据、不可操作

1.5 授权模型

核心原则

授权属于店铺,不属于用户 店铺属于主体Owner用户只是被授权使用

店铺授权结构

Organization公司
    ↓
Shop店铺
    ↓
Auth授权
    ↑
User使用者

授权类型

类型 适用平台 存储内容
API授权 Shopify、Amazon access_token, refresh_token, expire_time
Agent授权 TikTok、Shopee cookies, proxy, device_id, user_agent

授权状态机

INIT → AUTHORIZED → EXPIRED → INVALID → ERROR

1.6 商品三层模型

SPU产品层
  ↓
SKU库存单元层
  ↓
Listing平台商品层

SPU产品层

Product (SPU) {
  id: string;
  name: string;           // 蓝牙耳机
  brand: string;
  category_id: string;
  attributes: JSON;       // 通用属性
}

SKU库存单元

ProductSKU {
  id: string;
  spu_id: string;
  sku_code: string;
  attributes: JSON;       // {"color": "red", "size": "XL"}
  cost_price: number;     // 成本价
  base_price: number;     // 基准价(参考用)
  weight: number;
}

PlatformListing平台商品层

PlatformListing {
  id: string;
  sku_id: string;
  shop_id: string;
  platform: string;
  platform_listing_id: string;
  title: string;
  price: number;          // 最终销售价
  stock: number;
  status: string;
}

2. 现有架构分析

2.1 项目现有数据模型

基于 docs/01_Architecture/03_Domain_Model.md

实体 现有字段 缺失关键点
Product id, merchant_id, store_id, name, sku, price, stock 无SPU/SKU分层、 价格不应在SKU层
Store id, merchant_id, name, platform, platform_shop_id 基本完整,⚠️ 缺少org_id归属
User id, merchant_id, role, status 无Team归属、 无Scope
Order id, user_id, merchant_id, total_amount, status ⚠️ 缺少shop_id关联
Inventory id, product_id, merchant_id, warehouse_id, quantity ⚠️ 缺少SKU级别库存

2.2 项目现有权限设计

基于 docs/02_Backend/07_RBAC_Design.md

维度 现有实现 评估
角色定义 ADMIN/MANAGER/OPERATOR/FINANCE/SOURCING/LOGISTICS/ANALYST 完整
权限定义 CREATE/READ/UPDATE/DELETE/APPROVE/EXPORT/IMPORT 完整
租户隔离 tenantId字段过滤 已实现
店铺隔离 shopId字段过滤 ⚠️ 部分实现
组织层级 无Team/Department结构 🔴 缺失
数据范围 无Scope概念 🔴 缺失
层级继承 无parent_id树结构 🔴 缺失

2.3 项目现有商品闭环

基于 docs/00_Business/Business_ClosedLoops/01_Product.md

闭环 状态 缺失点
数据采集与清洗 已定义 -
商品刊登 已定义 ⚠️ 缺少Listing实体
SKU变体与结构 已定义 ⚠️ 缺少映射表
多平台商品管理 已定义 ⚠️ 缺少价格策略层
商品主数据 已定义 ⚠️ 缺少属性标准化

2.4 项目现有服务编排

基于 docs/01_Architecture/04_Service_Map.md

服务闭环 状态 评估
权限校验闭环 已定义 ⚠️ 缺少Scope校验
商户管理闭环 已定义 完整
店铺管理闭环 已定义 ⚠️ 缺少授权管理
多租户数据隔离 已定义 ⚠️ 缺少组织层级

2.5 项目现有状态机

基于 docs/01_Architecture/06_State_Machine.md

实体 状态定义 评估
Product DRAFT → PENDING_APPROVAL → ACTIVE → INACTIVE → DISCONTINUED ⚠️ 缺少Listing状态
Store PENDING → ACTIVE → INACTIVE → SUSPENDED 完整
Order PENDING → PAID → SPLIT → PROCESSING → SHIPPED → COMPLETED → REFUNDED → CANCELLED 完整

3. 差距识别与问题诊断

3.1 🔴 严重问题(必须修复)

问题1价格存储在SKU层

现状

Product.price = 99  // ❌ 错误设计

后果

  • 一改价格 → 全平台全乱
  • 无法做AB测试
  • 无法做利润分析
  • AI无法决策

影响范围商品管理、价格策略、利润计算、AI调价

问题2缺少SPU/SKU分层

现状

// 只有Product无SPU/SKU区分
Product { id, name, sku, price }

后果

  • 无法管理变体(颜色/尺寸)
  • 跨平台SKU映射困难
  • 库存管理混乱

影响范围:商品管理、库存管理、订单归集

问题3缺少Listing实体

现状无PlatformListing表

后果

  • 无法支持"一个SKU → 多个Listing"
  • 无法实现同店铺多价格
  • 无法做AB测试

影响范围:多平台管理、价格策略、刊登系统

问题4缺少组织层级

现状

User { merchant_id, role }  // 无team_id

后果

  • 组长看不到下属数据
  • 无法实现部门管理
  • 无法支持代运营场景

影响范围:权限系统、数据隔离、团队协作

3.2 🟡 中等问题(建议修复)

问题5缺少价格策略表

现状前端有UI后端无表

后果

  • 策略无法持久化
  • 无法批量调价
  • AI调价无基础

影响范围价格管理、AI调价

问题6缺少SKU映射表

现状前端有UI后端无表

后果

  • 映射关系无法存储
  • 订单无法归集
  • 库存无法统一

影响范围:多平台管理、库存同步

问题7缺少操作归因

现状有OperationLog但无target_user_id

后果

  • 无法追踪"谁帮谁操作"
  • 无法做绩效分析
  • 审计不完整

影响范围:审计系统、绩效分析

问题8缺少属性标准化体系

现状无Attribute表

后果

  • 不同平台类目不同
  • AI生成依赖结构化数据
  • 映射会失败

影响范围商品管理、AI生成、跨平台刊登

3.3 🟢 轻微问题(可后续优化)

  • 缺少类目映射系统
  • 缺少单位/货币统一管理
  • 缺少数据快照/回滚能力
  • 缺少并发控制机制
  • 缺少幂等性保证

4. 最优解决方案

4.1 数据模型重构方案

4.1.1 商品三层模型

-- SPU产品层
CREATE TABLE cf_spu (
  id VARCHAR(36) PRIMARY KEY,
  tenant_id VARCHAR(36) NOT NULL,
  name VARCHAR(255) NOT NULL,
  brand VARCHAR(100),
  category_id VARCHAR(36),
  description TEXT,
  main_image VARCHAR(500),
  status ENUM('draft', 'active', 'inactive', 'archived') DEFAULT 'draft',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  
  INDEX idx_tenant (tenant_id),
  INDEX idx_category (category_id)
);

-- SKU库存单元层
CREATE TABLE cf_sku (
  id VARCHAR(36) PRIMARY KEY,
  tenant_id VARCHAR(36) NOT NULL,
  spu_id VARCHAR(36) NOT NULL,
  sku_code VARCHAR(100) NOT NULL,
  name VARCHAR(255),
  attributes JSON,  -- {"color": "red", "size": "XL"}
  cost_price DECIMAL(10,2) NOT NULL,  -- 成本价
  base_price DECIMAL(10,2),            -- 基准价(参考用)
  weight DECIMAL(10,3),
  status ENUM('draft', 'active', 'inactive', 'archived') DEFAULT 'draft',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  
  UNIQUE KEY uk_tenant_sku (tenant_id, sku_code),
  INDEX idx_spu (spu_id),
  INDEX idx_tenant (tenant_id)
);

-- PlatformListing平台商品层
CREATE TABLE cf_platform_listing (
  id VARCHAR(36) PRIMARY KEY,
  tenant_id VARCHAR(36) NOT NULL,
  sku_id VARCHAR(36) NOT NULL,
  shop_id VARCHAR(36) NOT NULL,
  platform ENUM('tiktok', 'shopee', 'lazada', 'shopify', 'woocommerce', 'b2b', 'custom') NOT NULL,
  platform_listing_id VARCHAR(100),    -- 平台商品ID
  platform_sku VARCHAR(100),           -- 平台SKU
  title VARCHAR(500),
  price DECIMAL(10,2) NOT NULL,        -- 最终销售价
  original_price DECIMAL(10,2),
  currency VARCHAR(10) DEFAULT 'USD',
  stock INT DEFAULT 0,
  status ENUM('draft', 'pending', 'active', 'inactive', 'error') DEFAULT 'draft',
  sync_status ENUM('synced', 'syncing', 'error', 'never') DEFAULT 'never',
  last_sync_at TIMESTAMP,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  
  INDEX idx_sku (sku_id),
  INDEX idx_shop (shop_id),
  INDEX idx_platform_listing (platform, platform_listing_id),
  INDEX idx_tenant (tenant_id)
);

4.1.2 价格策略模型

-- 价格策略表
CREATE TABLE cf_price_strategy (
  id VARCHAR(36) PRIMARY KEY,
  tenant_id VARCHAR(36) NOT NULL,
  name VARCHAR(100) NOT NULL,
  scope ENUM('global', 'platform', 'shop', 'listing') NOT NULL,
  target_id VARCHAR(36),               -- 平台ID/店铺ID/ListingID
  strategy_type ENUM('multiplier', 'fixed', 'dynamic', 'range') NOT NULL,
  strategy_value DECIMAL(10,4),        -- 倍率或固定值
  min_price DECIMAL(10,2),
  max_price DECIMAL(10,2),
  profit_rate_min DECIMAL(5,4),        -- 最低利润率
  is_active BOOLEAN DEFAULT TRUE,
  priority INT DEFAULT 0,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  
  INDEX idx_tenant (tenant_id),
  INDEX idx_scope_target (scope, target_id)
);

-- 价格变更日志
CREATE TABLE cf_price_change_log (
  id VARCHAR(36) PRIMARY KEY,
  tenant_id VARCHAR(36) NOT NULL,
  listing_id VARCHAR(36) NOT NULL,
  old_price DECIMAL(10,2),
  new_price DECIMAL(10,2),
  change_type ENUM('manual', 'strategy', 'ai', 'sync') NOT NULL,
  strategy_id VARCHAR(36),
  reason VARCHAR(500),
  operator_id VARCHAR(36),
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  
  INDEX idx_listing (listing_id),
  INDEX idx_tenant (tenant_id),
  INDEX idx_created (created_at)
);

4.1.3 SKU映射模型

-- SKU映射表
CREATE TABLE cf_sku_mapping (
  id VARCHAR(36) PRIMARY KEY,
  tenant_id VARCHAR(36) NOT NULL,
  master_sku_id VARCHAR(36) NOT NULL,  -- 主SKU
  listing_id VARCHAR(36) NOT NULL,     -- 平台Listing
  mapping_type ENUM('auto', 'manual') DEFAULT 'manual',
  confidence DECIMAL(5,4),             -- 自动映射置信度
  status ENUM('active', 'inactive') DEFAULT 'active',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  
  UNIQUE KEY uk_sku_listing (master_sku_id, listing_id),
  INDEX idx_tenant (tenant_id)
);

4.1.4 组织层级模型

-- 组织/公司表
CREATE TABLE cf_organization (
  id VARCHAR(36) PRIMARY KEY,
  tenant_id VARCHAR(36) NOT NULL,
  name VARCHAR(255) NOT NULL,
  type ENUM('company', 'department', 'team') NOT NULL,
  parent_id VARCHAR(36),               -- 支持层级
  level INT DEFAULT 0,                 -- 层级深度
  path VARCHAR(500),                   -- 路径:/org1/org2/org3
  manager_id VARCHAR(36),              -- 负责人
  status ENUM('active', 'inactive') DEFAULT 'active',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  
  INDEX idx_tenant (tenant_id),
  INDEX idx_parent (parent_id),
  INDEX idx_path (path)
);

-- 用户组织关系
CREATE TABLE cf_user_organization (
  id VARCHAR(36) PRIMARY KEY,
  tenant_id VARCHAR(36) NOT NULL,
  user_id VARCHAR(36) NOT NULL,
  org_id VARCHAR(36) NOT NULL,
  role ENUM('manager', 'member') DEFAULT 'member',
  data_scope ENUM('self', 'team', 'dept', 'org', 'all') DEFAULT 'self',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  
  UNIQUE KEY uk_user_org (user_id, org_id),
  INDEX idx_tenant (tenant_id),
  INDEX idx_org (org_id)
);

-- 店铺归属(挂到组织)
ALTER TABLE cf_store ADD COLUMN org_id VARCHAR(36);
ALTER TABLE cf_store ADD INDEX idx_org (org_id);

4.1.5 授权模型

-- 店铺授权表
CREATE TABLE cf_shop_auth (
  id VARCHAR(36) PRIMARY KEY,
  tenant_id VARCHAR(36) NOT NULL,
  shop_id VARCHAR(36) NOT NULL,
  auth_type ENUM('api', 'agent') NOT NULL,
  
  -- API类
  access_token TEXT,
  refresh_token TEXT,
  expire_time TIMESTAMP,
  
  -- Agent类
  cookies JSON,
  proxy VARCHAR(255),
  device_id VARCHAR(100),
  user_agent VARCHAR(500),
  
  -- 通用
  status ENUM('init', 'authorized', 'expired', 'invalid', 'error') DEFAULT 'init',
  last_refresh_at TIMESTAMP,
  raw_data JSON,                       -- 原始返回(兼容)
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  
  INDEX idx_shop (shop_id),
  INDEX idx_tenant (tenant_id)
);

-- 用户店铺关系
CREATE TABLE cf_user_shop (
  id VARCHAR(36) PRIMARY KEY,
  tenant_id VARCHAR(36) NOT NULL,
  user_id VARCHAR(36) NOT NULL,
  shop_id VARCHAR(36) NOT NULL,
  role ENUM('owner', 'admin', 'operator', 'viewer') DEFAULT 'operator',
  permissions JSON,                    -- 细粒度权限
  status ENUM('active', 'inactive') DEFAULT 'active',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  
  UNIQUE KEY uk_user_shop (user_id, shop_id),
  INDEX idx_tenant (tenant_id),
  INDEX idx_shop (shop_id)
);

4.1.6 属性标准化模型

-- 属性定义表
CREATE TABLE cf_attribute (
  id VARCHAR(36) PRIMARY KEY,
  tenant_id VARCHAR(36) NOT NULL,
  name VARCHAR(100) NOT NULL,          -- 颜色 / 尺寸 / 材质
  code VARCHAR(50) NOT NULL,           -- color / size
  type ENUM('enum', 'string', 'number') NOT NULL,
  is_required BOOLEAN DEFAULT FALSE,
  sort_order INT DEFAULT 0,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  
  UNIQUE KEY uk_tenant_code (tenant_id, code),
  INDEX idx_tenant (tenant_id)
);

-- 属性值表
CREATE TABLE cf_attribute_value (
  id VARCHAR(36) PRIMARY KEY,
  attribute_id VARCHAR(36) NOT NULL,
  value VARCHAR(100) NOT NULL,         -- 红 / 蓝 / XL
  sort_order INT DEFAULT 0,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  
  INDEX idx_attribute (attribute_id)
);

-- SKU属性绑定
CREATE TABLE cf_sku_attribute (
  id VARCHAR(36) PRIMARY KEY,
  sku_id VARCHAR(36) NOT NULL,
  attribute_id VARCHAR(36) NOT NULL,
  value VARCHAR(100) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  
  UNIQUE KEY uk_sku_attr (sku_id, attribute_id),
  INDEX idx_sku (sku_id)
);

-- 类目映射表
CREATE TABLE cf_category_mapping (
  id VARCHAR(36) PRIMARY KEY,
  tenant_id VARCHAR(36) NOT NULL,
  platform ENUM('tiktok', 'shopee', 'lazada', 'shopify', 'woocommerce', 'amazon') NOT NULL,
  platform_category_id VARCHAR(100) NOT NULL,
  platform_category_name VARCHAR(255),
  internal_category_id VARCHAR(36) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  
  UNIQUE KEY uk_platform_category (platform, platform_category_id),
  INDEX idx_tenant (tenant_id)
);

4.2 服务层设计

4.2.1 价格服务PricingService

/**
 * 价格服务 - 所有价格计算必须通过此服务
 * 禁止在Controller或前端直接计算价格
 */
interface PricingService {
  calculatePrice(skuId: string, shopId: string): Promise<number>;
  applyStrategy(listingId: string, strategyId: string): Promise<void>;
  overridePrice(listingId: string, price: number, reason: string): Promise<void>;
  getPriceHistory(listingId: string, period: DateRange): Promise<PriceChangeLog[]>;
  suggestPrice(skuId: string, platform: Platform): Promise<PriceSuggestion>;
  batchApplyStrategy(skuIds: string[], strategyId: string): Promise<BatchResult>;
}

interface PriceSuggestion {
  suggestedPrice: number;
  confidence: number;
  factors: {
    cost: number;
    competitorPrice?: number;
    demandLevel: 'low' | 'medium' | 'high';
    profitRate: number;
  };
}

interface BatchResult {
  success: number;
  failed: number;
  errors: Array<{ id: string; reason: string }>;
}

4.2.2 映射服务MappingService

/**
 * SKU映射服务 - 管理主SKU与平台Listing的映射关系
 */
interface MappingService {
  createMapping(masterSkuId: string, listingId: string, type: 'auto' | 'manual'): Promise<SkuMapping>;
  autoMap(skuId: string, platform: Platform): Promise<SkuMapping[]>;
  validateMapping(mappingId: string): Promise<boolean>;
  getMappingByListing(listingId: string): Promise<SkuMapping | null>;
  getMappingsBySku(skuId: string): Promise<SkuMapping[]>;
  batchMap(mappings: Array<{ skuId: string; listingId: string }>): Promise<BatchResult>;
}

4.2.3 数据范围服务DataScopeService

/**
 * 数据范围服务 - 所有数据访问必须通过此服务校验
 */
interface DataScopeService {
  getUserScope(userId: string): Promise<DataScope>;
  getAccessibleShopIds(userId: string): Promise<string[]>;
  getAccessibleUserIds(userId: string): Promise<string[]>;
  checkDataAccess(userId: string, targetShopId: string): Promise<boolean>;
  getOrgTree(orgId: string): Promise<OrganizationNode[]>;
  buildScopeQuery(userId: string, baseQuery: QueryBuilder): Promise<QueryBuilder>;
}

interface DataScope {
  scope: 'self' | 'team' | 'dept' | 'org' | 'all';
  orgIds: string[];
  shopIds: string[];
  userIds: string[];
}

4.2.4 刊登服务ListingService

/**
 * 刊登服务 - 管理商品到平台的刊登流程
 */
interface ListingService {
  createDraft(skuId: string, shopId: string, data: ListingDraftData): Promise<PlatformListing>;
  publishDraft(draftId: string): Promise<PublishResult>;
  syncToListing(listingId: string): Promise<SyncResult>;
  batchPublish(draftIds: string[]): Promise<BatchResult>;
  getListingStatus(listingId: string): Promise<ListingStatus>;
}

interface PublishResult {
  success: boolean;
  platformListingId?: string;
  error?: string;
}

4.3 API设计

4.3.1 商品API

# SPU管理
GET    /api/v1/spu                    # SPU列表
POST   /api/v1/spu                    # 创建SPU
GET    /api/v1/spu/:id                # SPU详情
PUT    /api/v1/spu/:id                # 更新SPU
DELETE /api/v1/spu/:id                # 删除SPU

# SKU管理
GET    /api/v1/spu/:spuId/sku         # SKU列表
POST   /api/v1/spu/:spuId/sku         # 创建SKU
GET    /api/v1/sku/:id                # SKU详情
PUT    /api/v1/sku/:id                # 更新SKU
DELETE /api/v1/sku/:id                # 删除SKU

# Listing管理
GET    /api/v1/listing                # Listing列表支持多筛选
POST   /api/v1/listing                # 创建Listing刊登
GET    /api/v1/listing/:id            # Listing详情
PUT    /api/v1/listing/:id            # 更新Listing
DELETE /api/v1/listing/:id            # 删除Listing
POST   /api/v1/listing/:id/sync       # 同步到平台
POST   /api/v1/listing/batch          # 批量操作

4.3.2 价格API

# 价格策略
GET    /api/v1/price-strategy         # 策略列表
POST   /api/v1/price-strategy         # 创建策略
PUT    /api/v1/price-strategy/:id     # 更新策略
DELETE /api/v1/price-strategy/:id     # 删除策略
POST   /api/v1/price-strategy/:id/apply # 应用策略

# 价格操作
GET    /api/v1/listing/:id/price      # 获取价格
PUT    /api/v1/listing/:id/price      # 修改价格
GET    /api/v1/listing/:id/price/history # 价格历史
POST   /api/v1/listing/:id/price/suggest # AI建议价

4.3.3 映射API

GET    /api/v1/sku-mapping            # 映射列表
POST   /api/v1/sku-mapping            # 创建映射
DELETE /api/v1/sku-mapping/:id        # 删除映射
POST   /api/v1/sku-mapping/auto       # 自动映射
POST   /api/v1/sku-mapping/validate   # 验证映射

4.3.4 组织API

# 组织管理
GET    /api/v1/organization           # 组织列表
POST   /api/v1/organization           # 创建组织
GET    /api/v1/organization/:id       # 组织详情
PUT    /api/v1/organization/:id       # 更新组织
DELETE /api/v1/organization/:id       # 删除组织
GET    /api/v1/organization/:id/tree  # 组织树

# 用户组织关系
GET    /api/v1/user-organization      # 用户组织关系
POST   /api/v1/user-organization      # 分配用户到组织
PUT    /api/v1/user-organization/:id  # 更新关系
DELETE /api/v1/user-organization/:id  # 移除关系

# 数据范围
GET    /api/v1/data-scope             # 获取当前用户数据范围
GET    /api/v1/data-scope/shops       # 可访问店铺
GET    /api/v1/data-scope/users       # 可管理用户

4.3.5 授权API

# 店铺授权
GET    /api/v1/shop-auth              # 授权列表
POST   /api/v1/shop-auth              # 创建授权
GET    /api/v1/shop-auth/:id          # 授权详情
DELETE /api/v1/shop-auth/:id          # 删除授权
POST   /api/v1/shop-auth/:id/refresh  # 刷新授权

# OAuth流程
GET    /api/v1/auth/:platform/start   # 开始OAuth
GET    /api/v1/auth/:platform/callback # OAuth回调

# Agent授权
POST   /api/v1/auth/agent/login       # Agent登录
POST   /api/v1/auth/agent/cookie      # 上传Cookie

4.4 前端改造方案

4.4.1 页面结构调整

商品中心(新一级菜单)
├── 商品管理SPU/SKU
│   ├── SPU列表
│   ├── SKU列表
│   └── 商品详情
├── 平台商品Listing
│   ├── Listing列表
│   ├── 刊登管理
│   └── 同步状态
├── 价格策略
│   ├── 策略列表
│   ├── 策略配置
│   └── 价格历史
└── SKU映射
    ├── 映射列表
    └── 自动映射

组织管理(新一级菜单)
├── 组织架构
│   ├── 组织树
│   └── 成员管理
├── 店铺管理
│   ├── 店铺列表
│   └── 授权管理
└── 权限配置
    ├── 角色管理
    └── 数据范围

4.4.2 关键组件设计

interface ProductListPage {
  filters: {
    platform?: Platform[];
    shopIds?: string[];
    status?: ProductStatus;
    category?: string;
    search?: string;
  };
  view: 'spu' | 'sku' | 'listing';
  actions: {
    batchEdit: () => void;
    batchSync: () => void;
    export: () => void;
  };
}

interface PriceStrategyEditor {
  basePrice: number;
  strategies: PriceStrategy[];
  calculatedPrices: Map<string, number>;
  onStrategyChange: (strategy: PriceStrategy) => void;
  onApply: () => void;
}

interface DataScopeSelector {
  currentScope: DataScope;
  orgTree: OrganizationNode[];
  onScopeChange: (scope: DataScope) => void;
}

interface ListingPriceEditor {
  listingId: string;
  currentPrice: number;
  basePrice: number;
  strategyPrice: number;
  onPriceChange: (price: number, reason: string) => void;
}

4.4.3 操作日志增强

interface OperationLog {
  id: string;
  tenant_id: string;
  user_id: string;
  shop_id: string;
  action: string;
  target_id: string;
  target_user_id?: string;           // 新增:操作归属用户
  before: JSON;
  after: JSON;
  ip: string;
  device: string;
  created_at: Timestamp;
}

5. 实施步骤

5.1 阶段一数据模型迁移预计3天

任务清单

任务ID 任务描述 优先级 预计时间
DB-001 创建cf_spu表 P0 0.5天
DB-002 创建cf_sku表 P0 0.5天
DB-003 创建cf_platform_listing表 P0 0.5天
DB-004 创建cf_price_strategy表 P0 0.5天
DB-005 创建cf_sku_mapping表 P1 0.5天
DB-006 创建cf_organization表 P1 0.5天
DB-007 创建cf_user_organization表 P1 0.5天
DB-008 创建cf_shop_auth表 P1 0.5天
DB-009 创建cf_user_shop表 P1 0.5天
DB-010 创建cf_attribute表 P2 0.5天
DB-011 创建cf_attribute_value表 P2 0.5天
DB-012 创建cf_sku_attribute表 P2 0.5天
DB-013 创建cf_category_mapping表 P2 0.5天
DB-014 数据迁移脚本Product→SPU/SKU/Listing P0 1天

数据迁移策略

-- Step 1: 迁移现有Product到SPU
INSERT INTO cf_spu (id, tenant_id, name, status, created_at)
SELECT id, merchant_id, name, status, created_at
FROM cf_product;

-- Step 2: 创建默认SKU每个SPU一个
INSERT INTO cf_sku (id, tenant_id, spu_id, sku_code, name, cost_price, base_price, status, created_at)
SELECT 
  UUID() as id,
  merchant_id as tenant_id,
  id as spu_id,
  sku as sku_code,
  name,
  price * 0.4 as cost_price,  -- 假设成本为售价40%
  price as base_price,
  status,
  created_at
FROM cf_product;

-- Step 3: 创建默认Listing关联到店铺
INSERT INTO cf_platform_listing (id, tenant_id, sku_id, shop_id, platform, price, stock, status, created_at)
SELECT 
  UUID() as id,
  p.merchant_id as tenant_id,
  s.id as sku_id,
  p.store_id as shop_id,
  st.platform,
  p.price,
  p.stock,
  p.status,
  p.created_at
FROM cf_product p
JOIN cf_sku s ON s.spu_id = p.id
JOIN cf_store st ON st.id = p.store_id;

-- Step 4: 创建默认价格策略
INSERT INTO cf_price_strategy (id, tenant_id, name, scope, strategy_type, strategy_value, is_active)
SELECT 
  UUID() as id,
  merchant_id as tenant_id,
  '默认策略' as name,
  'global' as scope,
  'multiplier' as strategy_type,
  1.0 as strategy_value,
  TRUE as is_active
FROM cf_merchant;

5.2 阶段二服务层实现预计5天

任务清单

任务ID 任务描述 优先级 预计时间
SVC-001 PricingService实现 P0 1天
SVC-002 MappingService实现 P0 1天
SVC-003 DataScopeService实现 P0 1天
SVC-004 ListingService实现 P1 1天
SVC-005 OrganizationService实现 P1 0.5天
SVC-006 AuthService实现 P1 0.5天

服务层实现原则

  1. 所有业务逻辑必须在Service层
  2. Controller只负责请求/响应和权限校验
  3. 禁止跨Domain直接操作数据库
  4. 所有状态变更必须通过STATE_MACHINE

5.3 阶段三API层实现预计3天

任务清单

任务ID 任务描述 优先级 预计时间
API-001 商品API实现 P0 1天
API-002 价格API实现 P0 1天
API-003 映射API实现 P1 0.5天
API-004 组织API实现 P1 0.5天

5.4 阶段四前端改造预计5天

任务清单

任务ID 任务描述 优先级 预计时间
FE-001 商品管理页面重构 P0 1天
FE-002 Listing管理页面 P0 1天
FE-003 价格策略页面 P0 1天
FE-004 组织架构页面 P1 1天
FE-005 授权管理页面 P1 0.5天
FE-006 数据范围选择器组件 P1 0.5天

5.5 阶段五测试与验证预计2天

任务清单

任务ID 任务描述 优先级 预计时间
TEST-001 单元测试编写 P0 0.5天
TEST-002 集成测试编写 P0 0.5天
TEST-003 数据迁移验证 P0 0.5天
TEST-004 权限系统验证 P0 0.5天

5.6 总体进度安排

阶段一:数据模型迁移     ████████░░░░░░░░░░░░  Day 1-3
阶段二:服务层实现       ░░░░░░░░████████░░░░  Day 4-8
阶段三API层实现        ░░░░░░░░░░░░░░██████  Day 9-11
阶段四:前端改造         ░░░░████████░░░░░░░░  Day 12-16
阶段五:测试与验证       ░░░░░░░░░░░░░░░░████  Day 17-18

预计总工期18天可并行压缩至12天


6. 风险评估与应对

6.1 技术风险

风险1数据迁移数据丢失

风险等级🔴

影响:历史商品数据丢失,影响业务连续性

应对措施

  1. 迁移前完整备份现有数据
  2. 编写迁移验证脚本,对比迁移前后数据量
  3. 保留原Product表6个月设置只读
  4. 分批迁移,每批验证后再进行下一批

回滚方案

-- 回滚脚本示例
DROP TABLE IF EXISTS cf_spu, cf_sku, cf_platform_listing;
RESTORE TABLE cf_product FROM backup;

风险2权限系统重构影响现有用户

风险等级🟡

影响:现有用户权限丢失或混乱

应对措施

  1. 为现有用户自动创建默认组织关系
  2. 保留原有role字段作为fallback
  3. 灰度发布,先在测试环境验证
  4. 提供权限迁移工具,支持手动调整

风险3价格计算逻辑变更导致价格错误

风险等级🔴

影响:商品价格错误,影响销售和利润

应对措施

  1. 所有价格变更记录日志
  2. 价格计算服务增加单元测试覆盖
  3. 上线前进行价格对比验证
  4. 提供价格回滚功能

6.2 业务风险

风险4用户不适应新操作流程

风险等级🟡

影响:用户投诉,使用效率下降

应对措施

  1. 提供详细的操作文档和视频教程
  2. 保留旧版入口1个月过渡期
  3. 收集用户反馈,快速迭代优化
  4. 提供在线客服支持

风险5多平台同步延迟

风险等级🟡

影响:数据不一致,影响运营决策

应对措施

  1. 增加同步状态监控和告警
  2. 提供手动同步入口
  3. 记录同步日志,便于排查
  4. 设置合理的同步频率和重试机制

6.3 性能风险

风险6组织层级查询性能问题

风险等级🟡

影响:权限校验慢,影响系统响应

应对措施

  1. 使用path字段优化层级查询
  2. 缓存用户Scope信息
  3. 定期更新层级缓存
  4. 限制组织层级深度建议不超过5层
// Scope缓存示例
const userScopeCache = new Map<string, DataScope>();

async function getUserScope(userId: string): Promise<DataScope> {
  if (userScopeCache.has(userId)) {
    return userScopeCache.get(userId)!;
  }
  const scope = await calculateUserScope(userId);
  userScopeCache.set(userId, scope);
  return scope;
}

6.4 风险矩阵

风险 等级 概率 影响 应对优先级
数据迁移丢失 🔴 极高 P0
价格计算错误 🔴 极高 P0
权限系统混乱 🟡 P1
用户不适应 🟡 P2
同步延迟 🟡 P2
性能问题 🟡 P3

7. 附录

7.1 术语对照表

术语 英文 说明
商品映射 Product Mapping 绑定系统SKU与平台商品的关系
商品刊登 Product Listing 创建新商品并发布到平台
基准价 Base Price SKU层的参考价格锚点
策略层 Strategy Layer 价格规则定义层
Listing层 Listing Layer 最终销售价格层
数据范围 Data Scope 用户可访问的数据边界
组织层级 Organization Hierarchy 公司/部门/团队的树形结构

7.2 参考文档

7.3 变更记录

日期 版本 变更内容 作者
2026-03-22 1.0 初始版本,完整分析报告 AI

本报告基于ChatGPT对话内容和项目现有文档综合分析生成如有疑问请参考原始文档。