Files
douba_shop/商城商品推送到聚水潭分析.md
Karlcarlo c7f85ffbda feat: 添加阿里云短信服务支持并优化验证码逻辑
- 引入 alibabacloud/dysmsapi-20170525 依赖,集成阿里云短信服务
- 将短信验证码从6位改为4位,优化用户体验
- 添加聚水潭商品按时间范围同步功能,支持分页拉取
- 增强Cron任务异常处理,添加错误日志记录
- 修复系统附件服务中图片路径处理逻辑
- 更新阿里云SDK相关组件至最新版本
- 添加think-trace调试扩展,便于问题排查
- 优化跨域中间件,使用str_contains替代strpos
2026-04-30 15:19:40 +08:00

13 KiB
Raw Blame History

商城商品推送到聚水潭分析

一、答案

❌ 当前状态:推送功能已禁用

在 CreateSuccess.php#L80-99 中,推送到ERP的代码被注释掉了:

//ERP功能开启
//        if (sys_config('erp_open') && $data['product_type'] == 0) {
//            //上传商品至ERP平台
//            ProductSyncErp::dispatchDo('upProductToErp', [$id]);
//            ...
//        }

二、推送功能架构

2.1 推送流程图

商城商品创建成功
      ↓
触发 CreateSuccess 事件监听器
      ↓
检查 ERP 功能是否开启 (erp_open = 1)
      ↓
      ├─ 未开启 → 不推送
      │
      └─ 开启 → ProductSyncErp::dispatchDo('upProductToErp', [$id])
                 ↓
            ┌──────────────┐
            │ 商品数据转换  │
            │              │
            │ 商品主数据   │
            │ SPU编码     │
            │ 商品名称     │
            │ SKU规格    │
            │ 价格信息    │
            └──────┬───────┘
                   ↓
            调用聚水潭API
            /open/jushuitan/itemsku/upload
                   ↓
            推送商品到聚水潭平台

2.2 核心文件

文件 职责
CreateSuccess.php 商品创建事件监听器
ProductSyncErp.php 推送任务(upProductToErp方法)
Product.php 聚水潭API调用封装

三、推送逻辑详解

3.1 商品创建监听器

文件: CreateSuccess.php#L79-99

//ERP功能开启
if (sys_config('erp_open') && $data['product_type'] == 0) {
    // 1. 上传商品至ERP平台
    ProductSyncErp::dispatchDo('upProductToErp', [$id]);

    // 2. 上传商品至ERP默认门店
    ProductSyncErp::dispatchDo('upBranchProductToErp', [
        $id, 
        ['erp_shop_id' => sys_config('jst_default_shopid')]
    ]);

    // 3. 给所有绑定了ERP店铺的门店增加该商品
    $systemStoreServices = app()->make(SystemStoreServices::class);
    $erpStoreList = $systemStoreServices->getStoreList([
        ['erp_shop_id', '>', 0]
    ]);
    foreach ($erpStoreList['list'] as $item) {
        if ($item['erp_shop_id'] < 1) continue;
        ProductSyncErp::dispatchDo('upBranchProductToErp', [$id, $item]);
    }

    // 4. 如果是新商品,同步库存
    if ($is_new) {
        ProductSyncErp::dispatchDo('stockFromErp', [[$id]]);
    }
}

触发条件:

  • ✅ erp_open 配置已开启
  • ✅ 商品类型为 product_type == 0(普通商品,非虚拟商品等)
  • ✅ 商品创建成功事件被触发

3.2 数据转换逻辑

文件: ProductSyncErp.php#L31-61

public function upProductToErp($id)
{
    try {
        // 1. 获取商品信息
        $productServices = app()->make(StoreProductServices::class);
        $productInfo = $productServices->getInfo($id)['productInfo'];
        
        // 2. 准备数据
        $data = [];
        $attrs = $productInfo['attrs'] ?? [$productInfo['attr']];
        
        foreach ($attrs as $item) {
            // 处理图片URL
            if ($item['pic'] && strstr($item['pic'], 'http') === false) {
                $siteUrl = sys_config('site_url');
                $item['pic'] = $siteUrl . $item['pic'];
            }
            
            // 3. 构建推送数据
            $data[] = [
                'i_id' => $productInfo['code'],           // SPU编码
                'sku_id' => $item['code'],                // SKU编码
                'name' => $productInfo['store_name'],     // 商品名称
                'properties_value' => str_replace(',', ' ', $item['values']), // 规格属性
                's_price' => $item['price'],               // 售价
                'pic' => $item['pic'],                     // 图片URL
                'c_price' => $item['cost'],                // 成本价
                'market_price' => $item['ot_price'],       // 划线价
            ];
        }
        
        // 4. 调用聚水潭API
        (new erpServices())->serviceDriver('product')->updateProduct($data);
        
    } catch (\Exception $e) {
        response_log_write([
            'message' => '上传商品到ERP失败, 原因: ' . $e->getMessage(),
            'file' => $e->getFile(),
            'line' => $e->getLine()
        ]);
    }
}

3.3 API调用

文件: Product.php#L36-54

public function updateProduct($data)
{
    $url = $this->accessToken->getApiUrl("/open/jushuitan/itemsku/upload");
    
    // 业务参数
    $biz['items'] = $data;
    
    // 拼装请求参数
    $params = $this->getParams($biz);
    
    // 请求平台接口
    $request = $this->postRequest($url, $params);
    
    if ($request['code'] == 0) {
        return true;
    } else {
        return false;
    }
}

调用API: POST /open/jushuitan/itemsku/upload


四、数据映射关系

4.1 推送数据格式

{
  "items": [
    {
      "i_id": "4651127369",           // SPU编码(来自CRMEB的code字段)
      "sku_id": "1N55001102",          // SKU编码(来自CRMEB的attrs.code字段)
      "name": "贝肽斯夏季儿童防晒帽",  // 商品名称
      "properties_value": "卡其布黄;M码:头围50-54cm",  // 规格属性
      "s_price": 35.9,                 // 售价
      "pic": "https://img.yzcdn.cn/...", // 图片URL
      "c_price": 0,                     // 成本价
      "market_price": 0                 // 划线价
    }
  ]
}

4.2 字段对应关系

聚水潭字段 CRMEB字段 说明
i_id productInfo.code SPU编码(商品唯一标识)
sku_id attrs[].code SKU编码
name productInfo.store_name 商品名称
properties_value attrs[].values 规格属性(逗号替换为空格)
s_price attrs[].price 售价
pic attrs[].pic SKU图片
c_price attrs[].cost 成本价
market_price attrs[].ot_price 划线价

五、推送触发场景

5.1 自动推送(已禁用)

触发时机: 商品创建成功

// 在 CreateSuccess.php 中被注释
if (sys_config('erp_open') && $data['product_type'] == 0) {
    ProductSyncErp::dispatchDo('upProductToErp', [$id]);
}

5.2 手动推送

触发方式: 后台手动操作

可以通过后台页面触发,调用接口:

POST /adminapi/product/sync_jst_product
{
    "spu_str": "商品SPU编码"
}

5.3 门店商品推送

除了主商品库,还会推送到绑定了ERP店铺的门店:

// 上传到ERP默认门店
ProductSyncErp::dispatchDo('upBranchProductToErp', [
    $id, 
    ['erp_shop_id' => sys_config('jst_default_shopid')]
]);

// 上传到所有绑定ERP店铺的门店
foreach ($erpStoreList['list'] as $item) {
    ProductSyncErp::dispatchDo('upBranchProductToErp', [$id, $item]);
}

六、当前状态分析

6.1 为什么推送功能被禁用?

查看代码注释,ERP推送功能是被有意注释掉的,可能原因:

  1. 测试阶段 - 功能尚未完善,避免生产环境误操作
  2. 数据同步策略 - 可能改为只从聚水潭拉取,不推送到聚水潭
  3. 业务调整 - 业务方向改变,暂不需要此功能
  4. 数据一致性 - 避免双向同步导致的数据冲突

6.2 如何启用推送功能?

步骤1: 取消注释推送代码

编辑 CreateSuccess.php#L80-99,取消注释:

//ERP功能开启
if (sys_config('erp_open') && $data['product_type'] == 0) {
    //上传商品至ERP平台
    ProductSyncErp::dispatchDo('upProductToErp', [$id]);

    //上传商品至ERP默认门店
    ProductSyncErp::dispatchDo('upBranchProductToErp', [
        $id, 
        ['erp_shop_id' => sys_config('jst_default_shopid')]
    ]);

    //给所有绑定了ERP店铺的门店增加该商品
    $systemStoreServices = app()->make(SystemStoreServices::class);
    $erpStoreList = $systemStoreServices->getStoreList([['erp_shop_id', '>', 0]]);
    foreach ($erpStoreList['list'] as $item) {
        if ($item['erp_shop_id'] < 1) continue;
        ProductSyncErp::dispatchDo('upBranchProductToErp', [$id, $item]);
    }

    if ($is_new) {
        ProductSyncErp::dispatchDo('stockFromErp', [[$id]]);
    }
}

步骤2: 确保ERP配置正确

在后台配置:

  • ✅ 开启ERP功能
  • ✅ 配置聚水潭AppKey和Secret
  • ✅ 配置默认门店ID

步骤3: 测试推送功能

# 创建测试商品
POST /adminapi/product/save
{
    "store_name": "测试商品",
    "price": 99.00
}

# 检查日志
tail -f runtime/log/xxx.log | grep "upProductToErp"

七、推送 vs 拉取

7.1 对比表

特性 拉取(已有) 推送(已禁用)
触发方式 手动/定时任务 商品创建时自动
数据流向 聚水潭 → CRMEB CRMEB → 聚水潭
代码状态 ✅ 正常 ❌ 被注释
使用场景 从ERP同步商品 上传新品到ERP
功能完整性 ✅ 完善 ⚠️ 需启用

7.2 推荐策略

方案A: 仅拉取(当前)

适用场景:

  • 聚水潭是主数据源
  • CRMEB作为销售前端
  • 商品信息在聚水潭维护

优点:

  • ✅ 数据单一来源,避免冲突
  • ✅ 商品信息统一管理
  • ✅ 降低系统复杂度

方案B: 仅推送

适用场景:

  • CRMEB是主数据源
  • 聚水潭仅用于库存/订单管理
  • 商品信息在CRMEB维护

优点:

  • ✅ 快速响应商品变化
  • ✅ 统一商品发布渠道
  • ✅ 便于营销活动管理

方案C: 双向同步

适用场景:

  • 两边都需要管理商品
  • 有专业团队分别维护
  • 需要数据一致性保障机制

挑战:

  • ⚠️ 数据冲突解决策略
  • ⚠️ 同步延迟处理
  • ⚠️ 异常情况处理

八、启用推送的注意事项

8.1 数据一致性

// 推送时,确保商品编码唯一
$productInfo['code'] 必须在聚水潭中是唯一的

// 如果推送失败,需要记录日志并重试
if (!(new erpServices())->serviceDriver('product')->updateProduct($data)) {
    // 记录失败日志
    Log::error('商品推送失败', ['product_id' => $id]);
    // 可以加入重试队列
}

8.2 性能考虑

// 当前是异步队列推送,无需担心性能
ProductSyncErp::dispatchDo('upProductToErp', [$id]);

// 但需要注意:
// 1. 批量创建商品时,可能产生大量队列任务
// 2. 建议限制推送频率
// 3. 添加推送限流机制

8.3 错误处理

try {
    (new erpServices())->serviceDriver('product')->updateProduct($data);
} catch (\Exception $e) {
    // 1. 记录错误日志
    Log::error('推送商品到聚水潭失败', [
        'product_id' => $id,
        'error' => $e->getMessage()
    ]);
    
    // 2. 可以加入失败重试队列
    ProductSyncErp::dispatchDo('upProductToErp', [$id]);
    
    // 3. 通知管理员
    // sendNotify('商品推送失败,需要人工处理');
}

九、总结

❌ 当前状态

商城创建的商品推送到聚水潭的功能已被禁用

✅ 推送功能已实现

代码逻辑完整,包括:

  • ✅ 商品数据转换
  • ✅ SKU规格处理
  • ✅ 聚水潭API调用
  • ✅ 门店商品推送
  • ✅ 库存同步

🔧 如何启用

  1. 取消 CreateSuccess.php 中的注释
  2. 配置ERP功能
  3. 测试推送流程

💡 建议

根据业务需求选择合适的数据同步策略:

  • 推荐仅拉取:单数据源,避免冲突
  • 慎用双向同步:需要完善冲突处理机制

十、相关文件清单

文件路径 说明 状态
CreateSuccess.php 商品创建监听器 ⚠️ 推送代码被注释
ProductSyncErp.php 推送任务 ✅ 已实现
Product.php API调用 ✅ 已实现
Jushuitan.php 聚水潭SDK ✅ 已实现
HaichaoJstServices.php 业务封装 ✅ 已实现