diff --git a/app/Service/v3/Implementations/GoodsActivityService.php b/app/Service/v3/Implementations/GoodsActivityService.php index f2c9595..77ea89b 100644 --- a/app/Service/v3/Implementations/GoodsActivityService.php +++ b/app/Service/v3/Implementations/GoodsActivityService.php @@ -8,6 +8,7 @@ use App\Constants\v3\ErrorCode; use App\Constants\v3\LogLabel; use App\Constants\v3\SsdbKeys; use App\Service\v3\Interfaces\GoodsActivityServiceInterface; +use App\Service\v3\Interfaces\GoodsInventoryServiceInterface; use App\TaskWorker\SSDBTask; use App\Model\v3\GoodsActivity; use App\Model\v3\GoodsActivityBanner; @@ -24,6 +25,12 @@ class GoodsActivityService implements GoodsActivityServiceInterface */ protected $log; + /** + * @Inject + * @var GoodsInventoryServiceInterface + */ + protected $goodsInventoryService; + public function do($goodsId) { @@ -32,9 +39,6 @@ class GoodsActivityService implements GoodsActivityServiceInterface public function check(GoodsActivity $goods, $num, $userId) { - $redis = ApplicationContext::getContainer()->get(Redis::class); - $inventoryKey = 'goods_inventory_sold_2_'.$goods->id; // 拼接activity_type和goods_id - if (empty($goods)) { $message = ErrorCode::getMessage(ErrorCode::GOODS_ACTIVITY_NOT_EXISTS); $this->log->event(LogLabel::ERROR_CODE_EXCEPTION_LOG_DATA, ['message' => $message, 'buy_num' => $num, 'user_id' => $userId, 'logData' => json_encode($goods)]); @@ -64,11 +68,11 @@ class GoodsActivityService implements GoodsActivityServiceInterface // 商品库存不足 // 获取冻结的库存 - $inventoryFrozen = (int)$redis->get($inventoryKey); + $inventoryFrozen = $this->goodsInventoryService->getSold(2, $goods->id); // $inventoryFrozen = 0; if($goods->is_infinite != 1 && $goods->inventory < ($num+$inventoryFrozen)){ $message = ErrorCode::getMessage(ErrorCode::GOODS_ACTIVITY_INVENTORY_ERROR); - $this->log->event(LogLabel::ERROR_CODE_EXCEPTION_LOG_DATA, ['message' => $message, 'buy_num' => $num, 'inventoryKey' => $inventoryKey, 'inventoryFrozen' => $inventoryFrozen, 'user_id' => $userId, 'logData' => json_encode($goods)]); + $this->log->event(LogLabel::ERROR_CODE_EXCEPTION_LOG_DATA, ['message' => $message, 'buy_num' => $num, 'activity_type' => 2, 'inventoryFrozen' => $inventoryFrozen, 'user_id' => $userId, 'logData' => json_encode($goods)]); return ErrorCode::GOODS_ACTIVITY_INVENTORY_ERROR; } diff --git a/app/Service/v3/Implementations/GoodsInventoryService.php b/app/Service/v3/Implementations/GoodsInventoryService.php new file mode 100644 index 0000000..b8be428 --- /dev/null +++ b/app/Service/v3/Implementations/GoodsInventoryService.php @@ -0,0 +1,47 @@ +get(Redis::class); + $hName = 'goods_inventory_sold_' . $activityType; + $hKey = 'goods_id_' . $goodsId; + + $redis->hIncrBy($hName, $hKey, $num); + } + + /** + * @inheritDoc + */ + public function undoSold($activityType, $goodsId, $num) + { + $redis = ApplicationContext::getContainer()->get(Redis::class); + $hName = 'goods_inventory_sold_' . $activityType; + $hKey = 'goods_id_' . $goodsId; + + $redis->hIncrBy($hName, $hKey, -1*$num); + } + + /** + * @inheritDoc + */ + public function getSold($activityType, $goodsId) + { + $redis = ApplicationContext::getContainer()->get(Redis::class); + $hName = 'goods_inventory_sold_' . $activityType; + $hKey = 'goods_id_' . $goodsId; + + return $redis->hGet($hName, $hKey); + } +} \ No newline at end of file diff --git a/app/Service/v3/Implementations/GoodsService.php b/app/Service/v3/Implementations/GoodsService.php index 2848be5..0ed9a5e 100644 --- a/app/Service/v3/Implementations/GoodsService.php +++ b/app/Service/v3/Implementations/GoodsService.php @@ -6,6 +6,7 @@ use App\Commons\Log; use App\Constants\v3\ErrorCode; use App\Constants\v3\LogLabel; use App\Exception\ErrorCodeException; +use App\Service\v3\Interfaces\GoodsInventoryServiceInterface; use App\Service\v3\Interfaces\GoodsServiceInterface; use App\Model\v3\Goods; use App\Model\v3\GoodsBanner; @@ -22,6 +23,12 @@ class GoodsService implements GoodsServiceInterface */ protected $log; + /** + * @Inject + * @var GoodsInventoryServiceInterface + */ + protected $goodsInventoryService; + public function do($goodsId) { @@ -30,9 +37,6 @@ class GoodsService implements GoodsServiceInterface public function check(Goods $goods,$num = 1) { - $redis = ApplicationContext::getContainer()->get(Redis::class); - $inventoryKey = 'goods_inventory_sold_1_'.$goods->id; // 拼接activity_type和goods_id - if (empty($goods)) { $message = ErrorCode::getMessage(ErrorCode::GOODS_NOT_EXISTS); $this->log->event(LogLabel::ERROR_CODE_EXCEPTION_LOG_DATA, ['message' => $message, 'buy_num' => $num, 'logData' => json_encode($goods)]); @@ -53,7 +57,7 @@ class GoodsService implements GoodsServiceInterface } // 商品库存不足 // 获取冻结的库存 - //$inventoryFrozen = (int)$redis->get($inventoryKey); + // $inventoryFrozen = $this->goodsInventoryService->getSold(1, $goods->id); $inventoryFrozen = 0; if($goods->is_infinite != 1 && $goods->inventory < ($num+$inventoryFrozen)){ $message = ErrorCode::getMessage(ErrorCode::GOODS_INVENTORY_ERROR); diff --git a/app/Service/v3/Implementations/OrderOnlineService.php b/app/Service/v3/Implementations/OrderOnlineService.php index dd7cdec..3cb38eb 100644 --- a/app/Service/v3/Implementations/OrderOnlineService.php +++ b/app/Service/v3/Implementations/OrderOnlineService.php @@ -24,6 +24,7 @@ use App\Service\v3\Interfaces\BadgeServiceInterface; use App\Service\v3\Interfaces\CouponRecServiceInterface; use App\Service\v3\Interfaces\CouponServiceInterface; use App\Service\v3\Interfaces\GoodsActivityServiceInterface; +use App\Service\v3\Interfaces\GoodsInventoryServiceInterface; use App\Service\v3\Interfaces\GoodsServiceInterface; use App\Service\v3\Interfaces\InitialDeliveryServiceInterface; use App\Service\v3\Interfaces\PaymentServiceInterface; @@ -102,6 +103,12 @@ class OrderOnlineService implements OrderOnlineServiceInterface */ protected $initialDeliveryService; + /** + * @Inject + * @var GoodsInventoryServiceInterface + */ + protected $goodsInventoryService; + /** * 下单 * @param $marketId @@ -224,12 +231,13 @@ class OrderOnlineService implements OrderOnlineServiceInterface // 压redis库存 // redis记录当前商品的购买数量,压库存,下单失败、下单成功扣库存成功、订单取消的时候释放 - $inventoryKey = 'goods_inventory_sold_'.$cart->activity_type.'_'.$cart->goods_id; // 拼接activity_type和goods_id - if (!$redis->exists($inventoryKey)) { - $redis->set($inventoryKey, $cart->num); - } else { - $redis->incrBy($inventoryKey, intval($cart->num)); - } + // $inventoryKey = 'goods_inventory_sold_'.$cart->activity_type.'_'.$cart->goods_id; // 拼接activity_type和goods_id + // if (!$redis->exists($inventoryKey)) { + // $redis->set($inventoryKey, $cart->num); + // } else { + // $redis->incrBy($inventoryKey, intval($cart->num)); + // } + $this->goodsInventoryService->doSold($cart->activity_type, $cart->goods_id, $cart->num); $isCacheInventory = true; if ($cart->activity_type == 2) { @@ -404,14 +412,15 @@ class OrderOnlineService implements OrderOnlineServiceInterface if ($isCacheInventory) { // 释redis库存 foreach ($carts as $k => &$cart) { - // 拼接activity_type和goods_id - $inventoryKey = 'goods_inventory_sold_'.$cart->activity_type.'_'.$cart->goods_id; - // redis记录当前商品的购买数量,压库存,下单失败、下单成功扣库存成功、订单取消的时候释放 - if (!$redis->exists($inventoryKey)) { - $redis->set($inventoryKey, 0); - } else { - $redis->decrBy($inventoryKey, intval($cart->num)); - } + // // 拼接activity_type和goods_id + // $inventoryKey = 'goods_inventory_sold_'.$cart->activity_type.'_'.$cart->goods_id; + // // redis记录当前商品的购买数量,压库存,下单失败、下单成功扣库存成功、订单取消的时候释放 + // if (!$redis->exists($inventoryKey)) { + // $redis->set($inventoryKey, 0); + // } else { + // $redis->decrBy($inventoryKey, intval($cart->num)); + // } + $this->goodsInventoryService->undoSold($cart->activity_type, $cart->goods_id, $cart->num); } } $this->log->event(LogLabel::ORDER_ONLINE_LOG, ['msg' => $e->getMessage()]); @@ -477,14 +486,15 @@ class OrderOnlineService implements OrderOnlineServiceInterface // 释redis库存 $redis = ApplicationContext::getContainer()->get(Redis::class); foreach ($orderGoods as $k => &$goodsItem) { - // 拼接activity_type和goods_id - $inventoryKey = 'goods_inventory_sold_'.$goodsItem['activity_type'].'_'.$goodsItem['goods_id']; - // redis记录当前商品的购买数量,压库存,下单失败、下单成功扣库存成功、订单取消的时候释放 - if (!$redis->exists($inventoryKey)) { - $redis->set($inventoryKey, 0); - } else { - $redis->decrBy($inventoryKey, intval($goodsItem['number'])); - } + // // 拼接activity_type和goods_id + // $inventoryKey = 'goods_inventory_sold_'.$goodsItem['activity_type'].'_'.$goodsItem['goods_id']; + // // redis记录当前商品的购买数量,压库存,下单失败、下单成功扣库存成功、订单取消的时候释放 + // if (!$redis->exists($inventoryKey)) { + // $redis->set($inventoryKey, 0); + // } else { + // $redis->decrBy($inventoryKey, intval($goodsItem['number'])); + // } + $this->goodsInventoryService->undoSold($goodsItem['activity_type'], $goodsItem['goods_id'], $goodsItem['number']); } // 记录badge @@ -572,14 +582,15 @@ class OrderOnlineService implements OrderOnlineServiceInterface // 释redis库存 $redis = ApplicationContext::getContainer()->get(Redis::class); foreach ($orderGoods as $k => &$goodsItem) { - // 拼接activity_type和goods_id - $inventoryKey = 'goods_inventory_sold_'.$goodsItem['activity_type'].'_'.$goodsItem['goods_id']; - // redis记录当前商品的购买数量,压库存,下单失败、下单成功扣库存成功、订单取消的时候释放 - if (!$redis->exists($inventoryKey)) { - $redis->set($inventoryKey, 0); - } else { - $redis->decrBy($inventoryKey, intval($goodsItem['number'])); - } + // // 拼接activity_type和goods_id + // $inventoryKey = 'goods_inventory_sold_'.$goodsItem['activity_type'].'_'.$goodsItem['goods_id']; + // // redis记录当前商品的购买数量,压库存,下单失败、下单成功扣库存成功、订单取消的时候释放 + // if (!$redis->exists($inventoryKey)) { + // $redis->set($inventoryKey, 0); + // } else { + // $redis->decrBy($inventoryKey, intval($goodsItem['number'])); + // } + $this->goodsInventoryService->undoSold($goodsItem['activity_type'], $goodsItem['goods_id'], $goodsItem['number']); } // 月销流水 @@ -691,19 +702,6 @@ class OrderOnlineService implements OrderOnlineServiceInterface $orderIds = Order::query()->where(['order_main_id' => $orderMain->global_order_id])->pluck('id'); $orderGoods = OrderGoods::query()->whereIn('order_id', $orderIds)->get()->toArray(); - // // 释redis库存 - // $redis = ApplicationContext::getContainer()->get(Redis::class); - // foreach ($orderGoods as $k => &$goodsItem) { - // // 拼接activity_type和goods_id - // $inventoryKey = 'goods_inventory_sold_'.$goodsItem['activity_type'].'_'.$goodsItem['goods_id']; - // // redis记录当前商品的购买数量,压库存,下单失败、下单成功扣库存成功、订单取消的时候释放 - // if (!$redis->exists($inventoryKey)) { - // $redis->set($inventoryKey, 0); - // } else { - // $redis->decrBy($inventoryKey, intval($goodsItem['number'])); - // } - // } - // 微信退款 if ($orderMain->pay_type == Payment::WECHAT) { return $this->paymentService->undo($orderMain->global_order_id, $userId); @@ -745,14 +743,15 @@ class OrderOnlineService implements OrderOnlineServiceInterface // 释redis库存 $redis = ApplicationContext::getContainer()->get(Redis::class); foreach ($orderGoods as $k => &$goodsItem) { - // 拼接activity_type和goods_id - $inventoryKey = 'goods_inventory_sold_'.$goodsItem['activity_type'].'_'.$goodsItem['goods_id']; - // redis记录当前商品的购买数量,压库存,下单失败、下单成功扣库存成功、订单取消的时候释放 - if (!$redis->exists($inventoryKey)) { - $redis->set($inventoryKey, 0); - } else { - $redis->decrBy($inventoryKey, intval($goodsItem['number'])); - } + // // 拼接activity_type和goods_id + // $inventoryKey = 'goods_inventory_sold_'.$goodsItem['activity_type'].'_'.$goodsItem['goods_id']; + // // redis记录当前商品的购买数量,压库存,下单失败、下单成功扣库存成功、订单取消的时候释放 + // if (!$redis->exists($inventoryKey)) { + // $redis->set($inventoryKey, 0); + // } else { + // $redis->decrBy($inventoryKey, intval($goodsItem['number'])); + // } + $this->goodsInventoryService->undoSold($goodsItem['activity_type'], $goodsItem['goods_id'], $goodsItem['number']); } // 记录badge diff --git a/app/Service/v3/Interfaces/GoodsInventoryServiceInterface.php b/app/Service/v3/Interfaces/GoodsInventoryServiceInterface.php new file mode 100644 index 0000000..c60deb2 --- /dev/null +++ b/app/Service/v3/Interfaces/GoodsInventoryServiceInterface.php @@ -0,0 +1,33 @@ + \App\Service\v3\Implementations\InitialDeliveryService::class, \App\Service\v3\Interfaces\ServiceEvaluateServiceInterface::class => \App\Service\v3\Implementations\ServiceEvaluateService::class, \App\Service\v3\Interfaces\ParamsTokenServiceInterface::class => \App\Service\v3\Implementations\ParamsTokenSsdbService::class, + \App\Service\v3\Interfaces\GoodsInventoryServiceInterface::class => \App\Service\v3\Implementations\GoodsInventoryService::class, ];