|
|
@@ -355,6 +355,263 @@ class ProductService extends AlibabaAgentBaseService
|
|
355
|
355
|
return round($price * 1.5, 2);
|
|
356
|
356
|
}
|
|
357
|
357
|
|
|
|
358
|
+ // ================================================================
|
|
|
359
|
+ // 商品入库到 store_product 表
|
|
|
360
|
+ // ================================================================
|
|
|
361
|
+
|
|
|
362
|
+ /**
|
|
|
363
|
+ * 将 alibaba_import_goods 表中的商品数据写入 store_product 系列表
|
|
|
364
|
+ *
|
|
|
365
|
+ * 业务场景:从 alibaba_import_goods 表中选择已入库的1688商品,正式写入到
|
|
|
366
|
+ * rrx_store_product、rrx_store_product_attr、rrx_store_product_attr_value 表中
|
|
|
367
|
+ *
|
|
|
368
|
+ * @param int $importGoodsId alibaba_import_goods 表的主键ID
|
|
|
369
|
+ * @param int $merId 商户ID(目前写死3447)
|
|
|
370
|
+ * @return array ['code' => 200|400, 'msg' => '...', 'product_id' => int]
|
|
|
371
|
+ */
|
|
|
372
|
+ public function importToStoreProduct(int $importGoodsId, int $merId): array
|
|
|
373
|
+ {
|
|
|
374
|
+ try {
|
|
|
375
|
+ // 1. 读取 alibaba_import_goods 记录
|
|
|
376
|
+ $importGoods = Db::name('alibaba_import_goods')
|
|
|
377
|
+ ->where('id', $importGoodsId)
|
|
|
378
|
+ ->where('status', 1)
|
|
|
379
|
+ ->find();
|
|
|
380
|
+
|
|
|
381
|
+ if (empty($importGoods)) {
|
|
|
382
|
+ return ['code' => 400, 'msg' => '商品不存在或已下架', 'product_id' => 0];
|
|
|
383
|
+ }
|
|
|
384
|
+
|
|
|
385
|
+ // 2. 检查是否已入库(按 product_id 去重)
|
|
|
386
|
+ $exists = Db::name('store_product')
|
|
|
387
|
+ ->where('mer_id', $merId)
|
|
|
388
|
+ ->where('spu_id', (string)$importGoods['product_id'])
|
|
|
389
|
+ ->where('is_del', 0)
|
|
|
390
|
+ ->value('product_id');
|
|
|
391
|
+
|
|
|
392
|
+ if ($exists) {
|
|
|
393
|
+ return ['code' => 400, 'msg' => '商品已入库,product_id=' . $exists, 'product_id' => $exists];
|
|
|
394
|
+ }
|
|
|
395
|
+
|
|
|
396
|
+ // 3. 解析 product_info JSON
|
|
|
397
|
+ $productInfo = json_decode($importGoods['product_info'], true) ?: [];
|
|
|
398
|
+ if (empty($productInfo)) {
|
|
|
399
|
+ return ['code' => 400, 'msg' => '商品数据解析失败', 'product_id' => 0];
|
|
|
400
|
+ }
|
|
|
401
|
+
|
|
|
402
|
+ $skuList = $productInfo['skuList'] ?? [];
|
|
|
403
|
+ $imageList = $productInfo['imageList'] ?? [];
|
|
|
404
|
+ $mainImage = $productInfo['mainImage'] ?? $importGoods['image'] ?? '';
|
|
|
405
|
+ $title = $productInfo['title'] ?? $importGoods['product_name'] ?? '';
|
|
|
406
|
+ $description = $productInfo['description'] ?? '';
|
|
|
407
|
+
|
|
|
408
|
+ // 4. 判断是否为多规格
|
|
|
409
|
+ $specType = count($skuList) > 1 ? 1 : 0;
|
|
|
410
|
+
|
|
|
411
|
+ // 5. 轮播图处理
|
|
|
412
|
+ $sliderImage = !empty($imageList) ? implode(',', $imageList) : $mainImage;
|
|
|
413
|
+
|
|
|
414
|
+ // 6. 取最低价和最高价作为 price 和 ot_price
|
|
|
415
|
+ $prices = array_column($skuList, 'price');
|
|
|
416
|
+ $minPrice = !empty($prices) ? (float)min($prices) : 0;
|
|
|
417
|
+ $maxPrice = !empty($prices) ? (float)max($prices) : 0;
|
|
|
418
|
+
|
|
|
419
|
+ // 成本价取第一个SKU的成本价
|
|
|
420
|
+ $costPrice = $skuList[0]['costPrice'] ?? 0;
|
|
|
421
|
+
|
|
|
422
|
+ // 7. 写入 store_product 表
|
|
|
423
|
+ $productData = [
|
|
|
424
|
+ 'mer_id' => $merId,
|
|
|
425
|
+ 'image' => $mainImage,
|
|
|
426
|
+ 'slider_image' => $sliderImage,
|
|
|
427
|
+ 'store_name' => $title,
|
|
|
428
|
+ 'store_info' => mb_substr($title, 0, 100),
|
|
|
429
|
+ 'keyword' => mb_substr($title, 0, 10),
|
|
|
430
|
+ 'is_show' => 1,
|
|
|
431
|
+ 'status' => 0,
|
|
|
432
|
+ 'cate_id' => 0,
|
|
|
433
|
+ 'unit_name' => $productInfo['unit'] ?? '件',
|
|
|
434
|
+ 'price' => $minPrice,
|
|
|
435
|
+ 'cost' => $costPrice,
|
|
|
436
|
+ 'ot_price' => $maxPrice,
|
|
|
437
|
+ 'stock' => 9999,
|
|
|
438
|
+ 'spec_type' => $specType,
|
|
|
439
|
+ 'extension_type' => 0,
|
|
|
440
|
+ 'mer_status' => 1,
|
|
|
441
|
+ 'is_used' => 1,
|
|
|
442
|
+ 'volunteer' => 0,
|
|
|
443
|
+ 'type' => 1,
|
|
|
444
|
+ 'pension' => '0.00',
|
|
|
445
|
+ 'commission' => '',
|
|
|
446
|
+ 'spu_id' => (string)$importGoods['product_id'],
|
|
|
447
|
+ 'temp_id' => 105,
|
|
|
448
|
+ 'concession_pri' => '0.00',
|
|
|
449
|
+ 'cost_price' => $costPrice,
|
|
|
450
|
+ ];
|
|
|
451
|
+ $productId = Db::name('store_product')->insertGetId($productData);
|
|
|
452
|
+
|
|
|
453
|
+ if (!$productId) {
|
|
|
454
|
+ return ['code' => 400, 'msg' => '写入store_product表失败', 'product_id' => 0];
|
|
|
455
|
+ }
|
|
|
456
|
+
|
|
|
457
|
+ // 8. 写入 store_product_content 表(商品详情)
|
|
|
458
|
+ $contentHtml = $description;
|
|
|
459
|
+ // Db::name('store_product_content')->insert([
|
|
|
460
|
+ // 'product_id' => $productId,
|
|
|
461
|
+ // 'content' => $contentHtml,
|
|
|
462
|
+ // 'type' => 0,
|
|
|
463
|
+ // ]);
|
|
|
464
|
+
|
|
|
465
|
+ // 9. 写入 store_product_attr 和 store_product_attr_value
|
|
|
466
|
+ $this->insertStoreSkus($productId, $skuList, $merId);
|
|
|
467
|
+
|
|
|
468
|
+ Log::channel('alibaba')->info("[1688正式入库1] 商品{$importGoods['product_id']}入库成功,product_id={$productId},mer_id={$merId}");
|
|
|
469
|
+
|
|
|
470
|
+ return [
|
|
|
471
|
+ 'code' => 200,
|
|
|
472
|
+ 'msg' => '入库成功',
|
|
|
473
|
+ 'product_id' => $productId,
|
|
|
474
|
+ ];
|
|
|
475
|
+ } catch (\Throwable $e) {
|
|
|
476
|
+ Log::channel('alibaba')->error("[1688正式入库2] 异常: " . $e->getMessage());
|
|
|
477
|
+ return ['code' => 400, 'msg' => '入库异常: ' . $e->getMessage(), 'product_id' => 0];
|
|
|
478
|
+ }
|
|
|
479
|
+ }
|
|
|
480
|
+
|
|
|
481
|
+ /**
|
|
|
482
|
+ * 写入 store_product_attr 和 store_product_attr_value
|
|
|
483
|
+ *
|
|
|
484
|
+ * @param int $productId
|
|
|
485
|
+ * @param array $skuList formatDetailResult 返回的 skuList
|
|
|
486
|
+ * @param int $merId
|
|
|
487
|
+ */
|
|
|
488
|
+ protected function insertStoreSkus(int $productId, array $skuList, int $merId): void
|
|
|
489
|
+ {
|
|
|
490
|
+ if (empty($skuList)) {
|
|
|
491
|
+ // 单规格:写入默认规格
|
|
|
492
|
+ Db::name('store_product_attr')->insert([
|
|
|
493
|
+ 'product_id' => $productId,
|
|
|
494
|
+ 'attr_name' => '规格',
|
|
|
495
|
+ 'attr_values' => '',
|
|
|
496
|
+ 'type' => 0,
|
|
|
497
|
+ ]);
|
|
|
498
|
+
|
|
|
499
|
+ $unique = $this->generateUnique($productId, 'default');
|
|
|
500
|
+ Db::name('store_product_attr_value')->insert([
|
|
|
501
|
+ 'product_id' => $productId,
|
|
|
502
|
+ 'detail' => json_encode(['规格' => '默认'], JSON_UNESCAPED_UNICODE),
|
|
|
503
|
+ 'sku' => '默认',
|
|
|
504
|
+ 'image' => '',
|
|
|
505
|
+ 'cost' => 0,
|
|
|
506
|
+ 'ot_price' => 0,
|
|
|
507
|
+ 'price' => 0,
|
|
|
508
|
+ 'unique' => $unique,
|
|
|
509
|
+ 'stock' => 9999,
|
|
|
510
|
+ 'cost_price' => 0,
|
|
|
511
|
+ 'extension_one' => 5,
|
|
|
512
|
+ 'gong_sku_id' => '',
|
|
|
513
|
+ 'gong_mer_profit' => 0,
|
|
|
514
|
+ 'gong_pension' => 0,
|
|
|
515
|
+ 'gong_market_price' => 0,
|
|
|
516
|
+ 'plate_mer_profit' => 0,
|
|
|
517
|
+ 'volume' => 0,
|
|
|
518
|
+ 'weight' => 0,
|
|
|
519
|
+ 'dacang_price' => 0
|
|
|
520
|
+ ]);
|
|
|
521
|
+ return;
|
|
|
522
|
+ }
|
|
|
523
|
+
|
|
|
524
|
+ // 多规格处理
|
|
|
525
|
+ // 收集所有规格名称和值
|
|
|
526
|
+ $attrNames = []; // ['颜色', '尺寸']
|
|
|
527
|
+ $attrValueMap = []; // ['颜色' => ['红', '蓝'], '尺寸' => ['S', 'M']]
|
|
|
528
|
+
|
|
|
529
|
+ foreach ($skuList as $sku) {
|
|
|
530
|
+ $skuAttrs = $sku['skuAttrs'] ?? [];
|
|
|
531
|
+ foreach ($skuAttrs as $attr) {
|
|
|
532
|
+ $name = $attr['name'] ?? '';
|
|
|
533
|
+ $value = $attr['value'] ?? '';
|
|
|
534
|
+ if ($name === '') continue;
|
|
|
535
|
+ if (!in_array($name, $attrNames)) {
|
|
|
536
|
+ $attrNames[] = $name;
|
|
|
537
|
+ }
|
|
|
538
|
+ if (!isset($attrValueMap[$name])) {
|
|
|
539
|
+ $attrValueMap[$name] = [];
|
|
|
540
|
+ }
|
|
|
541
|
+ if (!in_array($value, $attrValueMap[$name])) {
|
|
|
542
|
+ $attrValueMap[$name][] = $value;
|
|
|
543
|
+ }
|
|
|
544
|
+ }
|
|
|
545
|
+ }
|
|
|
546
|
+
|
|
|
547
|
+ // 写入 store_product_attr
|
|
|
548
|
+ foreach ($attrNames as $attrName) {
|
|
|
549
|
+ $attrValues = $attrValueMap[$attrName] ?? [];
|
|
|
550
|
+ Db::name('store_product_attr')->insert([
|
|
|
551
|
+ 'product_id' => $productId,
|
|
|
552
|
+ 'attr_name' => $attrName,
|
|
|
553
|
+ 'attr_values' => implode('-!-', $attrValues),
|
|
|
554
|
+ 'type' => 0,
|
|
|
555
|
+ ]);
|
|
|
556
|
+ }
|
|
|
557
|
+
|
|
|
558
|
+ // 写入 store_product_attr_value
|
|
|
559
|
+ foreach ($skuList as $sku) {
|
|
|
560
|
+ $skuAttrs = $sku['skuAttrs'] ?? [];
|
|
|
561
|
+ $detailArr = [];
|
|
|
562
|
+ $skuKey = '';
|
|
|
563
|
+ foreach ($skuAttrs as $attr) {
|
|
|
564
|
+ $name = $attr['name'] ?? '';
|
|
|
565
|
+ $value = $attr['value'] ?? '';
|
|
|
566
|
+ if ($name !== '') {
|
|
|
567
|
+ $detailArr[$name] = $value;
|
|
|
568
|
+ $skuKey .= $value;
|
|
|
569
|
+ }
|
|
|
570
|
+ }
|
|
|
571
|
+ if (empty($detailArr)) {
|
|
|
572
|
+ $detailArr = ['规格' => '默认'];
|
|
|
573
|
+ $skuKey = '默认';
|
|
|
574
|
+ }
|
|
|
575
|
+
|
|
|
576
|
+ $skuId = $sku['skuId'] ?? '';
|
|
|
577
|
+ $unique = $this->generateUnique($productId, $skuId ?: $skuKey);
|
|
|
578
|
+
|
|
|
579
|
+ Db::name('store_product_attr_value')->insert([
|
|
|
580
|
+ 'product_id' => $productId,
|
|
|
581
|
+ 'detail' => json_encode($detailArr, JSON_UNESCAPED_UNICODE),
|
|
|
582
|
+ 'sku' => $skuKey,
|
|
|
583
|
+ 'image' => $sku['image'] ?? '',
|
|
|
584
|
+ 'cost' => $sku['costPrice'] ?? 0,
|
|
|
585
|
+ 'ot_price' => $sku['consignPrice'] ?? 0,
|
|
|
586
|
+ 'price' => $sku['costPrice'] ?? 0,
|
|
|
587
|
+ 'unique' => $unique,
|
|
|
588
|
+ 'stock' => $sku['stock'] ?? 9999,
|
|
|
589
|
+ 'cost_price' => $sku['costPrice'] ?? 0,
|
|
|
590
|
+ 'extension_one' => 5,
|
|
|
591
|
+ 'gong_sku_id' => (string)$skuId,
|
|
|
592
|
+ 'gong_mer_profit' => 0,
|
|
|
593
|
+ 'gong_pension' => 0,
|
|
|
594
|
+ 'gong_market_price' => $sku['consignPrice'] ?? 0,
|
|
|
595
|
+ 'plate_mer_profit' => 0,
|
|
|
596
|
+ 'volume' => 0,
|
|
|
597
|
+ 'weight' => 0,
|
|
|
598
|
+ 'dacang_price' => 0
|
|
|
599
|
+ ]);
|
|
|
600
|
+ }
|
|
|
601
|
+ }
|
|
|
602
|
+
|
|
|
603
|
+ /**
|
|
|
604
|
+ * 生成唯一值 unique
|
|
|
605
|
+ *
|
|
|
606
|
+ * @param int $productId
|
|
|
607
|
+ * @param string $sku
|
|
|
608
|
+ * @return string
|
|
|
609
|
+ */
|
|
|
610
|
+ protected function generateUnique(int $productId, string $sku): string
|
|
|
611
|
+ {
|
|
|
612
|
+ return substr(md5($sku . $productId), 12, 11) . '0';
|
|
|
613
|
+ }
|
|
|
614
|
+
|
|
358
|
615
|
/**
|
|
359
|
616
|
* 批量导入1688商品到 alibaba_import_goods 表
|
|
360
|
617
|
*
|