소스 검색

命令行-修复拉取微唯宝商品逻辑

sunxbiao 6 달 전
부모
커밋
175bbbb96a
1개의 변경된 파일244개의 추가작업 그리고 31개의 파일을 삭제
  1. 244 31
      app/command/WiwibaoProductSync.php

+ 244 - 31
app/command/WiwibaoProductSync.php

@@ -3,8 +3,10 @@ declare (strict_types=1);
3 3
 
4 4
 namespace app\command;
5 5
 
6
+use app\common\enum\CommonEnum;
6 7
 use app\common\enum\douhuomall\DouhuomallEnum;
7 8
 use app\common\enum\store\ProductEnum;
9
+use app\common\repositories\store\product\ProductRepository;
8 10
 use app\traits\GongApiRequest;
9 11
 use think\console\Command;
10 12
 use think\console\Input;
@@ -25,6 +27,7 @@ class WiwibaoProductSync extends Command
25 27
         'page_size' => 100,      // 每页拉取数量
26 28
         'max_pages' => 0,       // 最大页数限制
27 29
         'price_change_rate' => 0.0, // 价格变动比率阈值(10%)
30
+        'mer_id' => CommonEnum::DESIGN_MERCHANT_ID['WonderfulLiving']['code']
28 31
     ];
29 32
 
30 33
     protected function configure()
@@ -60,13 +63,22 @@ class WiwibaoProductSync extends Command
60 63
             }
61 64
 
62 65
             // 2. 获取本地所有SPU ID
63
-            $localSpuIds = Db::name('douhuomall')->column('spu_id');
66
+            $douhuomallDataMap = [];
67
+            $localSpuIds = [];
68
+            $douhuomallDataList = Db::name('douhuomall')
69
+                ->select()
70
+                ->toArray();
71
+            if (!empty($douhuomallDataList)) {
72
+                $douhuomallDataMap = array_column($douhuomallDataList, null, 'spu_id');
73
+                $localSpuIds = array_keys($douhuomallDataMap);
74
+            }
75
+
64 76
             $syncedSpuIds = [];
65 77
 
66 78
             // 3. 批量处理商品数据
67 79
             foreach ($allProducts as $product) {
68 80
                 try {
69
-                    $spuId = $this->processSingleProduct($product);
81
+                    $spuId = $this->processSingleProduct($product, $douhuomallDataMap[$product['goods_id']] ?? []);
70 82
                     if ($spuId) {
71 83
                         $syncedSpuIds[] = $spuId;
72 84
                     }
@@ -120,7 +132,7 @@ class WiwibaoProductSync extends Command
120 132
     /**
121 133
      * 处理单个商品
122 134
      */
123
-    protected function processSingleProduct($productData)
135
+    protected function processSingleProduct($productData, $douhuomallData)
124 136
     {
125 137
         $goodsId = $productData['goods_id'];
126 138
 
@@ -140,7 +152,7 @@ class WiwibaoProductSync extends Command
140 152
         $saveData = $this->buildSaveData($goodsInfo, $skuInfo, $imageData);
141 153
 
142 154
         // 5. 保存到本地(使用原有的add方法逻辑)
143
-        $spuId = $this->addToDouhuomall($saveData);
155
+        $spuId = $this->addToDouhuomall($saveData, $douhuomallData);
144 156
 
145 157
         // 6. 检查并处理已上架商品的价格变动
146 158
         $this->checkAndProcessOnlineProduct($spuId, $saveData);
@@ -244,13 +256,14 @@ class WiwibaoProductSync extends Command
244 256
     }
245 257
 
246 258
     /**
247
-     * 保存到douhuomall表(基于原有add方法)
259
+     * @param $data
260
+     * @param $findData
261
+     * @return mixed
262
+     * @throws DbException
248 263
      */
249
-    protected function addToDouhuomall($data)
264
+    protected function addToDouhuomall($data, $findData)
250 265
     {
251 266
         try {
252
-            $findData = Db::name('douhuomall')->where('spu_id', $data['spu_id'])->find();
253
-
254 267
             // 对SKU按成本价排序,获取最低成本价的SKU
255 268
             $skuInfo = $this->arrSort($data['skuId_info'], 'cost_price', SORT_ASC);
256 269
 
@@ -291,11 +304,11 @@ class WiwibaoProductSync extends Command
291 304
                 Db::name('douhuomall')->insert($insertData);
292 305
             } else {
293 306
                 // 更新
294
-                // 检查是否需要恢复已删除商品的上架状态
295
-                $shouldRestore = $this->shouldRestoreProduct($findData, $data);
296
-                if ($shouldRestore) {
297
-                    $this->restoreProduct($data['spu_id']);
298
-                }
307
+                //  无意义 // 检查是否需要恢复已删除商品的上架状态
308
+                // $shouldRestore = $this->shouldRestoreProduct($findData, $data);
309
+                // if ($shouldRestore) {
310
+                //     $this->restoreProduct($data['spu_id']);
311
+                // }
299 312
                 $updateData = [
300 313
                     'status' => $data['status'],
301 314
                     'update_time' => $now,
@@ -359,7 +372,7 @@ class WiwibaoProductSync extends Command
359 372
         Db::name('store_product')
360 373
             ->where('spu_id', $spuId)
361 374
             ->update([
362
-                'is_show' => ProductEnum::IS_SHOW['No']['code'],
375
+                'is_show' => ProductEnum::IS_SHOW['Yes']['code'],
363 376
                 'status' => ProductEnum::STATUS['Approved']['code']
364 377
             ]);
365 378
 
@@ -374,12 +387,14 @@ class WiwibaoProductSync extends Command
374 387
         // 检查商品是否已上架
375 388
         try {
376 389
             $productList = Db::name('store_product')
377
-                ->where('is_show', ProductEnum::IS_SHOW['Yes']['code'])
390
+                // ->where('is_show', ProductEnum::IS_SHOW['Yes']['code'])
378 391
                 ->where('spu_id', $spuId)
379 392
                 ->select()
380 393
                 ->toArray();
381 394
 
382 395
             if (empty($productList)) {
396
+                // 如果没有该商品则自动上架
397
+                $this->insert_product($spuId, $this->config['mer_id']);
383 398
                 return;
384 399
             }
385 400
 
@@ -395,6 +410,12 @@ class WiwibaoProductSync extends Command
395 410
             }
396 411
 
397 412
             foreach ($productList as $product) {
413
+
414
+                if ($product['is_show'] == ProductEnum::IS_SHOW['No']['code'] && $product['is_status'] == ProductEnum::IS_STATUS['Triggered']['code']) {
415
+                    // 如果商品 属于未上架商品(或是被员工下架了) 则不做任何处理
416
+                    continue;
417
+                }
418
+
398 419
                 // 获取本地商品价格信息
399 420
                 // 获取SKU价格
400 421
                 $skus = Db::name('store_product_attr_value')
@@ -412,9 +433,30 @@ class WiwibaoProductSync extends Command
412 433
                 // 比较价格,判断是否需要下架
413 434
                 $priceChanged = $this->checkPriceChange($localPrices, $syncPrices);
414 435
 
415
-                if ($priceChanged) {
436
+                if ($priceChanged['result'] ?? false) {
416 437
                     // 价格变动超过阈值,下架商品并记录
417
-                    $this->offlineProductWithRecord($product, $syncData, $localPrices, $syncPrices);
438
+                    // $this->offlineProductWithRecord($product, $syncData, $localPrices, $syncPrices);
439
+
440
+                    $changeSkuAttrDataList = [];
441
+                    foreach ($skus as $sku) {
442
+                        $changeSkuAttrDataList[] = [
443
+                            'sku_id' => $sku['gong_sku_id'],
444
+                            'edit_price' => bcadd(
445
+                                $sku['price'],
446
+                                $priceChanged['sku_difference_map'][$sku['gong_sku_id']] ?? ($priceChanged['spu_difference'] ?? '0.00'),
447
+                                2
448
+                            )
449
+                        ];
450
+                    }
451
+                    // 新规则 根据价格变动 增减商品售价
452
+                    /** @var ProductRepository $productRepository */
453
+                    $productRepository = app()->make(ProductRepository::class);
454
+                    $productRepository->editPrice($product['product_id'], $changeSkuAttrDataList);
455
+
456
+                    // 如果是系统下架的商品 则对商品重新上架
457
+                    if ($product['is_show'] == ProductEnum::IS_SHOW['No']['code'] && $product['is_status'] == ProductEnum::IS_STATUS['Automatic']['code']) {
458
+                        $this->restoreProduct($product['spu_id']);
459
+                    }
418 460
                 } else {
419 461
                     // 价格未变动或变动很小,只更新图片
420 462
                     $this->updateProductImages($spuId);
@@ -430,16 +472,23 @@ class WiwibaoProductSync extends Command
430 472
      */
431 473
     protected function checkPriceChange($localPrices, $syncPrices)
432 474
     {
475
+        $res = [
476
+            'result' => false,
477
+            'spu_difference' => 0.00,
478
+            'sku_difference_map' => []
479
+        ];
480
+        // 如果成本价不变 则没有必要更新商品信息
433 481
         // 如果没有SKU,比较商品主价格
434 482
         if (empty($localPrices['skus'])) {
435
-            $localPrice = $localPrices['product_price'];
436
-            $syncPrice = $syncPrices[0]['market_price'] ?? 0;
483
+            $localPrice = $localPrices['product_cost'];
484
+            $syncPrice = $syncPrices[0]['cost_price'] ?? 0;
437 485
 
438 486
             if ($localPrice > 0 && $syncPrice > 0) {
439 487
                 $changeRate = abs(($syncPrice - $localPrice) / $localPrice);
440
-                return $changeRate > $this->config['price_change_rate'];
488
+                $res['result'] = $changeRate > $this->config['price_change_rate'];
489
+                $res['spu_difference'] = bcsub((string)$syncPrice, $localPrice, 2);
441 490
             }
442
-            return false;
491
+            return $res;
443 492
         }
444 493
 
445 494
         // 如果有SKU,匹配SKU进行比较
@@ -447,20 +496,19 @@ class WiwibaoProductSync extends Command
447 496
             foreach ($syncPrices as $syncSku) {
448 497
                 // 尝试匹配SKU
449 498
                 if ($this->matchSku($localSku, $syncSku)) {
450
-                    $localPrice = $localSku['price'] ?? 0;
451
-                    $syncPrice = $syncSku['market_price'] ?? 0;
499
+                    $localPrice = $localSku['cost'] ?? 0;
500
+                    $syncPrice = $syncSku['cost_price'] ?? 0;
452 501
 
453 502
                     if ($localPrice > 0 && $syncPrice > 0) {
454 503
                         $changeRate = abs(($syncPrice - $localPrice) / $localPrice);
455
-                        if ($changeRate > $this->config['price_change_rate']) {
456
-                            return true;
457
-                        }
504
+                        $res['result'] = $changeRate > $this->config['price_change_rate'];
505
+                        $res['sku_difference_map'][$localSku['gong_sku_id']] = bcsub((string)$syncPrice, $localPrice, 2);
458 506
                     }
459 507
                 }
460 508
             }
461 509
         }
462 510
 
463
-        return false;
511
+        return $res;
464 512
     }
465 513
 
466 514
     /**
@@ -623,11 +671,9 @@ class WiwibaoProductSync extends Command
623 671
         $products = Db::name('store_product')
624 672
             ->where('spu_id', $spuId)
625 673
             ->select();
674
+        $douhuomallData = Db::name('douhuomall')->where('spu_id', $spuId)->select()->toArray();
626 675
 
627 676
         foreach ($products as $product) {
628
-            // 记录下架前数据
629
-            $beforeData = $product;
630
-
631 677
             // 下架商品
632 678
             Db::name('store_product')
633 679
                 ->where('product_id', $product['product_id'])
@@ -643,7 +689,7 @@ class WiwibaoProductSync extends Command
643 689
                 $spuId,
644 690
                 'third_party_offline',
645 691
                 $reason,
646
-                $beforeData,
692
+                ['product' => $product, 'douhuomallData' => $douhuomallData],
647 693
                 []
648 694
             );
649 695
         }
@@ -740,4 +786,171 @@ class WiwibaoProductSync extends Command
740 786
             'time' => date('Y-m-d H:i:s')
741 787
         ]);
742 788
     }
789
+
790
+    // 借用 app\controller\merchant\gong\Goods.php 控制器内方法
791
+
792
+    /**
793
+     * 将 微唯宝商品 选品(加入) 到系统内部商户商品表
794
+     * @param $spu_id
795
+     * @param $mer_id
796
+     * @return bool
797
+     */
798
+    public function insert_product($spu_id, $mer_id)
799
+    {
800
+        try {
801
+            // 1、获取商品信息
802
+            $data = Db::name('douhuomall')->where('spu_id', $spu_id)->find();
803
+
804
+            // 2、是否为多规格
805
+            $sku_data = json_decode($data['skuId_info'], true);
806
+            $spec_type = count($sku_data);
807
+            if ($spec_type > 1) {
808
+                $spec_type = 1;
809
+            } else {
810
+                $spec_type = 0;
811
+            }
812
+
813
+            // 3、商品主图
814
+            $spuId_info = json_decode($data['spuId_info'], true);
815
+            $slider_image = $spuId_info['detail_img_list'] ?? '';
816
+            $image = $spuId_info['cover_url'] ?? '';
817
+            if (empty($slider_image)) {
818
+                $slider_image = $image;
819
+            } else if (is_string($slider_image)) {
820
+                $slider_image = implode(',', json_decode($slider_image, true));
821
+            } else if (is_array($slider_image)) {
822
+                $slider_image = implode(',', $slider_image);
823
+            }
824
+            $yanglaojin_scale = (!empty($data['pension']) && !empty($data['market_price'])) ? bcdiv($data['pension'], $data['market_price'], 2) : 0;
825
+
826
+            // 4、商品入库数据
827
+            $product_insert_data = [
828
+                'mer_id' => $mer_id,
829
+                'image' => $image,
830
+                'slider_image' => $slider_image,
831
+                'store_name' => $data['title'],
832
+                'store_info' => 1,
833
+                'keyword' => mb_substr($data['title'], 0, 3),
834
+                'is_show' => 1,
835
+                'status' => 1,
836
+                'cate_id' => $data['cate_ids'],
837
+                'unit_name' => '个',
838
+                'price' => $data['market_price'],
839
+                'cost' => $data['cost_price'],
840
+                'ot_price' => $data['ot_price'],
841
+                'stock' => '1000',
842
+                'spec_type' => $spec_type,
843
+                'extension_type' => 1,
844
+                'mer_status' => 1,
845
+                'is_used' => 1,
846
+                'old_product_id' => $data['id'],
847
+                'volunteer' => 0,
848
+                'type' => 1,
849
+                'pension' => '0.00',
850
+                'commission' => 5,
851
+                'spu_id' => $data['spu_id'],
852
+                'temp_id' => 105,
853
+                'plate_mer_profit' => $data['mer_profit'],
854
+                'concession_pri' => $data['mer_profit'],
855
+                'yanglaojin_scale' => $yanglaojin_scale
856
+            ];
857
+            $insert_id = Db::name('store_product')->insertGetId($product_insert_data);
858
+
859
+            // 5、更新商品详情表
860
+            $detail = $spuId_info['detail'];
861
+            if (!is_null(json_decode($detail))) {
862
+                $detail_list = json_decode($detail);
863
+                $detail = '';
864
+                foreach ($detail_list as $value) {
865
+                    $detail .= '<img src="' . $value . '"></img>';
866
+                }
867
+            }
868
+            Db::name('store_product_content')->insert(['content' => $detail, 'product_id' => $insert_id]);
869
+
870
+            // 6、
871
+            $this->insert_sku($insert_id, $sku_data);
872
+            return true;
873
+        } catch (\Exception $e) {
874
+            Log::error($spu_id . "加入选品失败:" . $e->getMessage());
875
+            return false;
876
+        }
877
+    }
878
+
879
+    // 借用 app\controller\merchant\gong\Goods.php 控制器内方法
880
+    public function insert_sku($id, $data)
881
+    {
882
+        // 1、获取 所有SKU的 规格属性值
883
+        $sku_attr_data = array_column($data, 'attribute_json');
884
+        $name = '';
885
+
886
+        // 2、写入 商品属性表
887
+        /** @var ProductRepository $ProductRepository */
888
+        $ProductRepository = app()->make(ProductRepository::class);
889
+        if (empty($sku_attr_data[0][0])) {
890
+            // 写入商品属性表
891
+            Db::name('store_product_attr')->insert(['product_id' => $id, 'attr_name' => '规格', 'attr_values' => $name]);
892
+            $key = '';
893
+            $num = 1;
894
+            // 写入 SKU 商品属性值表
895
+            foreach ($data as $k => $v) {
896
+                Db::name('store_product_attr_value')->insert([
897
+                    'product_id' => $id,
898
+                    'detail' => json_encode(['规格' => $key]),
899
+                    'sku' => $key,
900
+                    'image' => $v['img_url'],
901
+                    'cost' => $v['cost_price'],
902
+                    'ot_price' => $v['retail_price'],
903
+                    'price' => $v['market_price'],
904
+                    'unique' => $ProductRepository->setUnique($id, $v['sku_id'], 0),
905
+                    'stock' => 100,
906
+                    'cost_price' => $v['cost_price'],
907
+                    'extension_one' => 5,
908
+                    'gong_sku_id' => $v['sku_id'],
909
+                    'gong_mer_profit' => $v['mer_profit'],
910
+                    'gong_pension' => $v['yanglaojin'],
911
+                    'gong_market_price' => $v['market_price'],
912
+                    'plate_mer_profit' => $v['mer_profit']
913
+                ]);
914
+                $key = '';
915
+                $num++;
916
+            }
917
+        } else {
918
+            foreach ($sku_attr_data as $kk => $vv) {
919
+                foreach ($vv as $k1 => $v1) {
920
+                    $name .= $v1['val'];
921
+                }
922
+                $name .= '-!-';
923
+            }
924
+            $name = rtrim($name, '-!-');
925
+            Db::name('store_product_attr')->insert(['product_id' => $id, 'attr_name' => '规格', 'attr_values' => $name]);
926
+            $key = '';
927
+            $num = 1;
928
+            foreach ($data as $k => $v) {
929
+                foreach ($v['attribute_json'] as $k2 => $v2) {
930
+                    $key .= $v2['val'];
931
+                }
932
+
933
+                Db::name('store_product_attr_value')->insert([
934
+                    'product_id' => $id,
935
+                    'detail' => json_encode(['规格' => $key]),
936
+                    'sku' => $key,
937
+                    'image' => $v['img_url'],
938
+                    'cost' => $v['cost_price'],
939
+                    'ot_price' => $v['retail_price'],
940
+                    'price' => $v['market_price'],
941
+                    'unique' => $ProductRepository->setUnique($id, $v['sku_id'], 0),
942
+                    'stock' => 100,
943
+                    'cost_price' => $v['cost_price'],
944
+                    'extension_one' => 5,
945
+                    'gong_sku_id' => $v['sku_id'],
946
+                    'gong_mer_profit' => $v['mer_profit'],
947
+                    'gong_pension' => $v['yanglaojin'],
948
+                    'gong_market_price' => $v['market_price'],
949
+                    'plate_mer_profit' => $v['mer_profit']
950
+                ]);
951
+                $key = '';
952
+                $num++;
953
+            }
954
+        }
955
+    }
743 956
 }