问题说明:门店新建时同步商品,商品关联门店联系问题
修改文件:app/services/product/branch/StoreBranchProductServices.php
修改方法:syncProduct()
/**
* 同步门店商品
* @param int $product_id
* @param int $store_id
* @param int $card_product_id
* @param int $is_sync_stock 库存同步到门店1:同步0:门店库存为0
* @param int $is_sync_show 状态同步到门店1:同平台商品状态0:同步至门店为下架状态
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function syncProduct(int $product_id, int $store_id, int $card_product_id = 0, int $is_sync_stock = 1, int $is_sync_show = 1)
{
if (!$product_id || !$store_id) {
return true;
}
/** @var StoreProductServices $productServices */
$productServices = app()->make(StoreProductServices::class);
//同步正常普通商品、次卡商品、卡项商品、预约商品
$productInfo = $productServices->get(['type' => [0, 2], 'product_type' => [0, 4, 5, 6], 'id' => $product_id]);
if (!$productInfo) {
return true;
}
$productInfo = $productInfo->toArray();
if ($productInfo['applicable_type'] == 2) {
$applicable_store_id = $productInfo['applicable_store_id'];
if (!is_array($applicable_store_id)) {
$applicable_store_id = explode(',', $applicable_store_id);
}
$applicable_store_id[] = $store_id;
$applicableStoreId = array_unique($applicable_store_id);
$this->dao->update($product_id, ['applicable_store_id' => $applicableStoreId]);
$productInfo['applicable_store_id'] = $applicableStoreId;
}
$productInfo['pid'] = $productInfo['id'];
$productInfo['slider_image'] = json_encode($productInfo['slider_image']);
$productInfo['custom_form'] = json_encode($productInfo['custom_form']);
$productInfo['specs'] = is_array($productInfo['specs']) ? json_encode($productInfo['specs']) : $productInfo['specs'];
$deliveryType = is_string($productInfo['delivery_type']) ? explode(',', $productInfo['delivery_type']) : $productInfo['delivery_type'];
$productInfo['delivery_type'] = array_diff($deliveryType, [1]);
unset($productInfo['id'], $productInfo['sales']);
/** @var StoreProductCategoryServices $productCategoryServices */
$productCategoryServices = app()->make(StoreProductCategoryServices::class);
$productInfo['store_cate_id'] = $productCategoryServices->getStoreCate($store_id, $productInfo['cate_id']);
//关联补充信息
$relationData = [];
$relationData['cate_id'] = ($productInfo['cate_id'] ?? []) && is_string($productInfo['cate_id']) ? explode(',', $productInfo['cate_id']) : ($productInfo['cate_id'] ?? []);
$relationData['store_cate_id'] = ($productInfo['store_cate_id'] ?? []) && is_string($productInfo['store_cate_id']) ? explode(',', $productInfo['store_cate_id']) : ($productInfo['store_cate_id'] ?? []);
$relationData['brand_id'] = ($productInfo['brand_id'] ?? []) && is_string($productInfo['brand_id']) ? explode(',', $productInfo['brand_id']) : ($productInfo['brand_id'] ?? []);
$relationData['store_label_id'] = ($productInfo['store_label_id'] ?? []) && is_string($productInfo['store_label_id']) ? explode(',', $productInfo['store_label_id']) : ($productInfo['store_label_id'] ?? []);
$relationData['label_id'] = ($productInfo['label_id'] ?? []) && is_string($productInfo['label_id']) ? explode(',', $productInfo['label_id']) : ($productInfo['label_id'] ?? []);
$relationData['ensure_id'] = ($productInfo['ensure_id'] ?? []) && is_string($productInfo['ensure_id']) ? explode(',', $productInfo['ensure_id']) : ($productInfo['ensure_id'] ?? []);
$relationData['specs_id'] = ($productInfo['specs_id'] ?? []) && is_string($productInfo['specs_id']) ? explode(',', $productInfo['specs_id']) : ($productInfo['specs_id'] ?? []);
$relationData['coupon_ids'] = ($productInfo['coupon_ids'] ?? []) && is_string($productInfo['coupon_ids']) ? explode(',', $productInfo['coupon_ids']) : ($productInfo['coupon_ids'] ?? []);
if (isset($productInfo['store_cate_id'])) {
$productInfo['store_cate_id'] = implode(',', $productInfo['store_cate_id']);
}
$where = ['product_id' => $product_id, 'type' => 0];
/** @var StoreProductAttrServices $productAttrServices */
$productAttrServices = app()->make(StoreProductAttrServices::class);
$attrInfo = $productAttrServices->getProductAttr($where);
/** @var StoreProductAttrResultServices $productAttrResultServices */
$productAttrResultServices = app()->make(StoreProductAttrResultServices::class);
$attrResult = $productAttrResultServices->getResult($where);
/** @var StoreProductAttrValueServices $productAttrValueServices */
$productAttrValueServices = app()->make(StoreProductAttrValueServices::class);
$attrValue = $productAttrValueServices->getList($where);
/** @var StoreDescriptionServices $productDescriptionServices */
$productDescriptionServices = app()->make(StoreDescriptionServices::class);
$description = $productDescriptionServices->getDescription($where);
$description = $description ?: '';
/** @var StoreProductReservationTimeServices $productReservationTimeServices */
$productReservationTimeServices = app()->make(StoreProductReservationTimeServices::class);
/** @var SystemStoreServices $systemStoreServices */
$systemStoreServices = app()->make(SystemStoreServices::class);
$storeInfo = $systemStoreServices->get($store_id, ['id', 'product_change_price_status']);
$branchProductInfo = $this->dao->get(['pid' => $product_id, 'type' => 1, 'relation_id' => $store_id]);
//存在修改
if ($branchProductInfo) {
$productInfo['store_cate_id'] = $branchProductInfo['store_cate_id'];
$relationData['store_cate_id'] = $branchProductInfo['store_cate_id'];
}
[$id, $is_new] = $productServices->transaction(function () use (
$product_id, $branchProductInfo, $productInfo, $store_id, $storeInfo, $attrInfo, $attrResult, $attrValue, $description,
$productServices, $productAttrServices, $productAttrResultServices, $productAttrValueServices, $productDescriptionServices, $productReservationTimeServices, $card_product_id, $is_sync_stock, $is_sync_show
) {
$productInfo['is_del'] = 0;
$productInfo['type'] = 1;
$productInfo['relation_id'] = $store_id;
$reservationTime = [];
if ($branchProductInfo) {//二次同步,编辑
$id = $branchProductInfo['id'];
unset($productInfo['stock'], $productInfo['is_show']);
$res = $this->dao->update($id, $productInfo);
if (!$res) throw new ValidateException('商品添加失败');
$updateSuks = array_column($attrValue, 'suk');
$oldSuks = [];
//门店商品sku
$oldAttrValue = $productAttrValueServices->getSkuArray(['product_id' => $id, 'type' => 0], '*', 'suk');
if ($oldAttrValue) $oldSuks = array_column($oldAttrValue, 'suk');
$delSuks = array_merge(array_diff($oldSuks, $updateSuks));
$dataAll = [];
$res1 = $res2 = $res3 = true;
foreach ($attrValue as $item) {
unset($item['id'], $item['stock'], $item['sales']);
$item['product_id'] = $id;
$oldUnique = $item['unique'];
if ($oldSuks && in_array($item['suk'], $oldSuks) && isset($oldAttrValue[$item['suk']])) {
//默认平台商品售价
$price = $oldPrice = (float)$item['price'];
if (isset($item['price_range_min']) && isset($item['price_range_max']) && $storeInfo && $storeInfo['product_change_price_status']) {//v3.3改价区间 门店有改价权限
$oldAttrValueOne = $oldAttrValue[$item['suk']];
//门店商品改价后售价
$price = (float)$oldAttrValueOne['price'];
$min = (float)$item['price_range_min'];
$max = (float)$item['price_range_max'];
if ($oldPrice == $min && $oldPrice == $max) {//不允许改价
$price = $oldPrice;
} elseif ($min && $max) {//限制区间
if ($price < $min || $price > $max) {
$price = $oldPrice;
}
} elseif (!$min && $max) {//限制最大值
if ($price > $max) {
$price = $oldPrice;
}
} elseif ($min && !$max) {//限制最小值
if ($price < $min) {
$price = $oldPrice;
}
} else {//不限制改价
}
}
//重新赋值售价
$item['price'] = $price;
$attrId = $oldAttrValue[$item['suk']]['id'];
$unique = $oldAttrValue[$item['suk']]['unique'];
unset($item['suk'], $item['unique']);
$res1 = $res1 && $productAttrValueServices->update($attrId, $item);
} else {
$unique = $productAttrServices->createAttrUnique($id, $item['suk']);
$item['unique'] = $unique;
$dataAll[] = $item;
}
if ($productInfo['product_type'] == 6) {//预约商品
$times = $productReservationTimeServices->getProductReservationTimes($oldUnique, $product_id, 'sku_unique,show_time,start,end,stock');
foreach ($times as &$time) {
$time['sku_unique'] = $unique;
}
$reservationTime = array_merge($reservationTime, $times);
unset($times, $time);
}
}
if ($delSuks) {
$res2 = $productAttrValueServices->del($id, 0, $delSuks);
}
if ($dataAll) {
$res3 = $productAttrValueServices->saveAll($dataAll);
}
if (!$res1 || !$res2 || !$res3) {
throw new AdminException('商品规格信息保存失败');
}
$is_new = 0;
} else {//新增
if (!$is_sync_stock) {//不同步库存
unset($productInfo['stock']);
}
if (!$is_sync_show) {//同步过去到门店为下架状态
$productInfo['is_show'] = 0;
}
$res = $this->dao->save($productInfo);
if (!$res) throw new ValidateException('商品添加失败');
$id = (int)$res->id;
if ($attrValue) {
foreach ($attrValue as &$value) {
unset($value['id'], $value['sales']);
if (!$is_sync_stock) {//不同步库存
unset($value['stock']);
}
$value['product_id'] = $id;
$unique = $productAttrServices->createAttrUnique($id, $value['suk']);
if ($productInfo['product_type'] == 6) {//预约商品
$times = $productReservationTimeServices->getProductReservationTimes($value['unique'], $product_id, 'sku_unique,show_time,start,end,stock');
foreach ($times as &$time) {
$time['sku_unique'] = $unique;
}
$reservationTime = array_merge($reservationTime, $times);
unset($times, $time);
}
$value['unique'] = $unique;
}
$productAttrValueServices->saveAll($attrValue);
}
$is_new = 1;
}
if ($attrInfo) {//规则数据
foreach ($attrInfo as &$attr) {
unset($attr['id']);
$attr['product_id'] = $id;
}
$productAttrServices->delete(['product_id' => $id]);
$productAttrServices->saveAll($attrInfo);
}
if ($reservationTime) {//预约商品时段库存
foreach ($reservationTime as &$time) {
$time['product_id'] = $id;
}
$productReservationTimeServices->delete(['product_id' => $id]);
$productReservationTimeServices->saveAll($reservationTime);
}
/** @var StoreCardRelatedServices $cardRelatedServices */
$cardRelatedServices = app()->make(StoreCardRelatedServices::class);
if ($productInfo['product_type'] == 5) {//卡项商品
/** @var StoreCardRelatedServices $relatedService */
$relatedService = app()->make(StoreCardRelatedServices::class);
$related = $relatedService->getCardRelatedProduct($product_id);
$res = $cardRelatedServices->handleCardRelated($id, $related);
if ($res) {
ProductSyncStoreJob::dispatchDo('syncCardRelatedProducts', [$store_id, $product_id, $related, $id]);
}
}
//处理卡项关联商品
if (in_array($productInfo['product_type'], [0, 6]) && $card_product_id) {
$cardRelatedServices->updateCardProduct($productInfo['pid'], $card_product_id, $id);
}
if ($attrResult) $productAttrResultServices->setResult($attrResult, $id, 0);
$productDescriptionServices->saveDescription($id, $description, 0);
return [$id, $is_new];
});
//商品创建事件
event('product.create', [$id, $productInfo, [], $is_new, [], $description, 1, $relationData]);
$this->dao->cacheTag()->clear();
$productAttrServices->cacheTag()->clear();
return true;
}
