feat(haichao): 新增聚水潭ERP集成功能
- 新增聚水潭回调接口及事件处理机制 - 添加聚水潭商品、订单、售后同步任务 - 实现聚水潭订单推送及售后状态同步 - 新增手动同步聚水潭商品功能 - 在各路由组添加聚水潭中间件支持
This commit is contained in:
90
app/jobs/haichao/JstAfterSalePushJob.php
Normal file
90
app/jobs/haichao/JstAfterSalePushJob.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: CRMEB Team <admin@crmeb.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\jobs\haichao;
|
||||
|
||||
use app\haichao\HaichaoJstServices;
|
||||
use crmeb\basic\BaseJobs;
|
||||
use crmeb\traits\QueueTrait;
|
||||
use think\facade\Log;
|
||||
|
||||
class JstAfterSalePushJob extends BaseJobs
|
||||
{
|
||||
use QueueTrait;
|
||||
|
||||
public static function queueName()
|
||||
{
|
||||
return (string)env('QUEUE_LISTEN_NAME', 'CRMEB_PRO');
|
||||
}
|
||||
|
||||
public function create(int $refundId, int $times = 0): bool
|
||||
{
|
||||
Log::info('jst.after_sale.create.job_start ' . json_encode([
|
||||
'refund_id' => $refundId,
|
||||
'times' => $times
|
||||
], JSON_UNESCAPED_UNICODE));
|
||||
try {
|
||||
HaichaoJstServices::getServices()->afterSaleCreatePush($refundId);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('jst.after_sale.create.job_error ' . json_encode([
|
||||
'refund_id' => $refundId,
|
||||
'times' => $times,
|
||||
'msg' => $e->getMessage(),
|
||||
], JSON_UNESCAPED_UNICODE));
|
||||
if ($times < 3) {
|
||||
self::dispatchSece(10 * ($times + 1), 'create', [$refundId, $times + 1]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function cancel(int $refundId, int $times = 0): bool
|
||||
{
|
||||
Log::info('jst.after_sale.cancel.job_start ' . json_encode([
|
||||
'refund_id' => $refundId,
|
||||
'times' => $times
|
||||
], JSON_UNESCAPED_UNICODE));
|
||||
try {
|
||||
HaichaoJstServices::getServices()->afterSaleCancelPush($refundId);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('jst.after_sale.cancel.job_error ' . json_encode([
|
||||
'refund_id' => $refundId,
|
||||
'times' => $times,
|
||||
'msg' => $e->getMessage(),
|
||||
], JSON_UNESCAPED_UNICODE));
|
||||
if ($times < 3) {
|
||||
self::dispatchSece(10 * ($times + 1), 'cancel', [$refundId, $times + 1]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function refunded(int $refundId, int $times = 0): bool
|
||||
{
|
||||
Log::info('jst.after_sale.refunded.job_start ' . json_encode([
|
||||
'refund_id' => $refundId,
|
||||
'times' => $times
|
||||
], JSON_UNESCAPED_UNICODE));
|
||||
try {
|
||||
HaichaoJstServices::getServices()->afterSaleRefundedPush($refundId);
|
||||
} catch (\Throwable $e) {
|
||||
Log::error('jst.after_sale.refunded.job_error ' . json_encode([
|
||||
'refund_id' => $refundId,
|
||||
'times' => $times,
|
||||
'msg' => $e->getMessage(),
|
||||
], JSON_UNESCAPED_UNICODE));
|
||||
if ($times < 3) {
|
||||
self::dispatchSece(10 * ($times + 1), 'refunded', [$refundId, $times + 1]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,11 @@ namespace app\jobs\product;
|
||||
use app\services\product\product\StoreProductServices;
|
||||
use app\services\product\sku\StoreProductAttrServices;
|
||||
use app\services\product\sku\StoreProductAttrValueServices;
|
||||
use app\haichao\HaichaoJstServices;
|
||||
use crmeb\basic\BaseJobs;
|
||||
use crmeb\exceptions\AdminException;
|
||||
use crmeb\services\erp\Erp as erpServices;
|
||||
use crmeb\traits\QueueTrait;
|
||||
use think\facade\Log;
|
||||
|
||||
class ProductSyncErp extends BaseJobs
|
||||
{
|
||||
@@ -118,55 +119,164 @@ class ProductSyncErp extends BaseJobs
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function productFromErp($spuArr)
|
||||
public function productFromErp($spuArr, int $supplierId = 0)
|
||||
{
|
||||
try {
|
||||
$result = (new erpServices())->serviceDriver('product')->syncProduct([$spuArr]);
|
||||
$productList = $result['datas'];
|
||||
Log::info('admin.manual.jst.product.sync.request', ['spu' => $spuArr]);
|
||||
$result = app()->make(HaichaoJstServices::class)->getProductListKuan($spuArr);
|
||||
$resultPreview = null;
|
||||
try {
|
||||
$resultPreview = mb_substr(json_encode($result, JSON_UNESCAPED_UNICODE), 0, 2000);
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
Log::info('admin.manual.jst.product.sync.api_result', [
|
||||
'spu' => $spuArr,
|
||||
'page_index' => $result['page_index'] ?? null,
|
||||
'page_count' => $result['page_count'] ?? null,
|
||||
'datas_count' => isset($result['datas']) && is_array($result['datas']) ? count($result['datas']) : 0,
|
||||
'result_preview' => $resultPreview,
|
||||
]);
|
||||
$productList = $result['datas'] ?? [];
|
||||
$productInfo = [];
|
||||
/** @var StoreProductServices $productServices */
|
||||
$productServices = app()->make(StoreProductServices::class);
|
||||
/** @var StoreProductAttrServices $productAttrServices */
|
||||
$productAttrServices = app()->make(StoreProductAttrServices::class);
|
||||
|
||||
Log::info('admin.manual.jst.product.sync.response', [
|
||||
'spu' => $spuArr,
|
||||
'datas_count' => is_array($productList) ? count($productList) : 0
|
||||
]);
|
||||
$relationSupplierId = $supplierId > 0 ? $supplierId : 0;
|
||||
foreach ($productList as $item) {
|
||||
Log::info('admin.manual.jst.product.sync.item', [
|
||||
'spu' => $spuArr,
|
||||
'i_id' => $item['i_id'] ?? '',
|
||||
'name' => $item['name'] ?? '',
|
||||
'sku_count' => isset($item['skus']) && is_array($item['skus']) ? count($item['skus']) : 0
|
||||
]);
|
||||
$skuRows = isset($item['skus']) && is_array($item['skus']) ? $item['skus'] : [];
|
||||
$salePrice = floatval($item['s_price'] ?? 0);
|
||||
if ($salePrice <= 0 && $skuRows) {
|
||||
$skuSalePrices = [];
|
||||
foreach ($skuRows as $skuRow) {
|
||||
if (isset($skuRow['sale_price']) && is_numeric($skuRow['sale_price'])) {
|
||||
$skuSalePrices[] = floatval($skuRow['sale_price']);
|
||||
}
|
||||
}
|
||||
if ($skuSalePrices) {
|
||||
$salePrice = min($skuSalePrices);
|
||||
}
|
||||
}
|
||||
$marketPrice = floatval($item['market_price'] ?? 0);
|
||||
if ($marketPrice <= 0 && $skuRows) {
|
||||
$skuMarketPrices = [];
|
||||
foreach ($skuRows as $skuRow) {
|
||||
if (isset($skuRow['market_price']) && is_numeric($skuRow['market_price'])) {
|
||||
$skuMarketPrices[] = floatval($skuRow['market_price']);
|
||||
}
|
||||
}
|
||||
if ($skuMarketPrices) {
|
||||
$marketPrice = max($skuMarketPrices);
|
||||
}
|
||||
}
|
||||
$costPrice = floatval($item['c_price'] ?? ($item['cost_price'] ?? 0));
|
||||
if ($costPrice <= 0 && $skuRows) {
|
||||
$skuCostPrices = [];
|
||||
foreach ($skuRows as $skuRow) {
|
||||
if (isset($skuRow['cost_price']) && is_numeric($skuRow['cost_price'])) {
|
||||
$skuCostPrices[] = floatval($skuRow['cost_price']);
|
||||
}
|
||||
}
|
||||
if ($skuCostPrices) {
|
||||
$costPrice = max($skuCostPrices);
|
||||
}
|
||||
}
|
||||
$pic = (string)($item['pic'] ?? ($skuRows[0]['pic'] ?? ''));
|
||||
$name = (string)($item['name'] ?? ($skuRows[0]['name'] ?? ''));
|
||||
$productInfo = [
|
||||
'image' => (string)$item['pic'],
|
||||
'slider_image' => json_encode([(string)$item['pic']]),
|
||||
'store_name' => $item['name'],
|
||||
'store_info' => $item['name'],
|
||||
'image' => $pic,
|
||||
'slider_image' => json_encode([$pic]),
|
||||
'store_name' => $name,
|
||||
'store_info' => $name,
|
||||
'cate_id' => 0,
|
||||
'price' => floatval($item['s_price']),
|
||||
'ot_price' => floatval($item['market_price']),
|
||||
'price' => $salePrice,
|
||||
'ot_price' => $marketPrice,
|
||||
'delivery_type' => '1,2,3',
|
||||
'freight' => 1,
|
||||
'is_show' => 0,
|
||||
'add_time' => time(),
|
||||
'cost' => floatval($item['c_price']),
|
||||
'cost' => $costPrice,
|
||||
'ficti' => 0,
|
||||
'spec_type' => 1,
|
||||
'code' => $item['i_id'],
|
||||
'type' => $relationSupplierId ? 2 : 0,
|
||||
'relation_id' => $relationSupplierId,
|
||||
];
|
||||
$detail = $details = $value = [];
|
||||
foreach ($item['skus'] as $items) {
|
||||
$detail[] = $items['properties_value'];
|
||||
$usedSpecValues = [];
|
||||
foreach ($skuRows as $skuIndex => $items) {
|
||||
$specValue = trim((string)($items['properties_value'] ?? ''));
|
||||
if ($specValue === '') {
|
||||
$specValue = trim((string)($items['name'] ?? ''));
|
||||
}
|
||||
if ($specValue === '') {
|
||||
$specValue = '规格' . ($skuIndex + 1);
|
||||
}
|
||||
if (isset($usedSpecValues[$specValue])) {
|
||||
$specValue = $specValue . '-' . ($skuIndex + 1);
|
||||
}
|
||||
$usedSpecValues[$specValue] = 1;
|
||||
$detail[] = $specValue;
|
||||
$details[] = [
|
||||
'name' => $items['properties_value'],
|
||||
'name' => $specValue,
|
||||
'select' => false
|
||||
];
|
||||
$skuCost = floatval($items['cost_price'] ?? $costPrice);
|
||||
$skuSettle = $relationSupplierId ? $skuCost : 0.0;
|
||||
$value[] = [
|
||||
'bar_code' => '',
|
||||
'brokerage' => 0,
|
||||
'brokerage_two' => 0,
|
||||
'code' => $items['sku_id'],
|
||||
'cost' => floatval($items['cost_price']),
|
||||
'detail' => ['规格' => $items['properties_value']],
|
||||
'ot_price' => floatval($items['market_price']),
|
||||
'code' => (string)($items['sku_id'] ?? ''),
|
||||
'settle_price' => $skuSettle,
|
||||
'cost' => $skuCost,
|
||||
'detail' => ['规格' => $specValue],
|
||||
'ot_price' => floatval($items['market_price'] ?? $marketPrice),
|
||||
'pic' => (string)$items['pic'],
|
||||
'price' => floatval($items['sale_price']),
|
||||
'price' => floatval($items['sale_price'] ?? $salePrice),
|
||||
'select' => true,
|
||||
'value1' => $items['properties_value'],
|
||||
'values' => $items['properties_value'],
|
||||
'value1' => $specValue,
|
||||
'values' => $specValue,
|
||||
'vip_price' => 0,
|
||||
'volume' => 0,
|
||||
'weight' => 0,
|
||||
'stock' => 0,
|
||||
];
|
||||
}
|
||||
if (!$value) {
|
||||
$specValue = '默认';
|
||||
$detail[] = $specValue;
|
||||
$details[] = [
|
||||
'name' => $specValue,
|
||||
'select' => false
|
||||
];
|
||||
$defCost = floatval($item['c_price'] ?? 0);
|
||||
$defSettle = $relationSupplierId ? $defCost : 0.0;
|
||||
$value[] = [
|
||||
'bar_code' => '',
|
||||
'brokerage' => 0,
|
||||
'brokerage_two' => 0,
|
||||
'code' => (string)($item['i_id'] ?? ''),
|
||||
'settle_price' => $defSettle,
|
||||
'cost' => $defCost,
|
||||
'detail' => ['规格' => $specValue],
|
||||
'ot_price' => floatval($item['market_price'] ?? 0),
|
||||
'pic' => (string)($item['pic'] ?? ''),
|
||||
'price' => floatval($item['s_price'] ?? 0),
|
||||
'select' => true,
|
||||
'value1' => $specValue,
|
||||
'values' => $specValue,
|
||||
'vip_price' => 0,
|
||||
'volume' => 0,
|
||||
'weight' => 0,
|
||||
@@ -174,6 +284,7 @@ class ProductSyncErp extends BaseJobs
|
||||
];
|
||||
}
|
||||
$pid = $productServices->value(['code' => $item['i_id']], 'id');
|
||||
$existed = !!$pid;
|
||||
if (!$pid) {
|
||||
$pid = $productServices->ErpProductSave($productInfo);
|
||||
}
|
||||
@@ -185,11 +296,18 @@ class ProductSyncErp extends BaseJobs
|
||||
|
||||
$skuList = $productAttrServices->validateProductAttr($attr, $value, $pid, 0, 0, 0);
|
||||
$productAttrServices->saveProductAttr($skuList, $pid);
|
||||
Log::info('admin.manual.jst.product.sync.save', [
|
||||
'spu' => $spuArr,
|
||||
'product_id' => $pid,
|
||||
'existed' => $existed,
|
||||
'sku_saved_count' => isset($skuList['value']) && is_array($skuList['value']) ? count($skuList['value']) : 0
|
||||
]);
|
||||
}
|
||||
|
||||
//清除数据缓存
|
||||
$productServices->cacheTag()->clear();
|
||||
$productAttrServices->cacheTag()->clear();
|
||||
Log::info('admin.manual.jst.product.sync.finish', ['spu' => $spuArr, 'count' => count($productList)]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
|
||||
@@ -198,6 +316,7 @@ class ProductSyncErp extends BaseJobs
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine()
|
||||
]);
|
||||
Log::error('admin.manual.jst.product.sync.error', ['spu' => $spuArr, 'message' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user