From 636c214516fc67e6c566e9e983fb1d705f9840b2 Mon Sep 17 00:00:00 2001 From: weigang Date: Thu, 17 Sep 2020 17:57:30 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8B=E5=8D=95=E5=8E=8B=E5=BA=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Controller/v3/OrderOfflineController.php | 2 +- .../Implementations/GoodsActivityService.php | 8 ++- .../v3/Implementations/GoodsService.php | 11 +++- .../v3/Implementations/OrderOnlineService.php | 61 ++++++++++++++++++- 4 files changed, 75 insertions(+), 7 deletions(-) diff --git a/app/Controller/v3/OrderOfflineController.php b/app/Controller/v3/OrderOfflineController.php index e929c3b..52d1003 100644 --- a/app/Controller/v3/OrderOfflineController.php +++ b/app/Controller/v3/OrderOfflineController.php @@ -47,7 +47,7 @@ class OrderOfflineController extends BaseController $params = $validator->validated(); $store = $this->storeService->detail($params['store_id']); - return $this->success(['store' => $store, 'digit_length' => 8]); + return $this->success(['store' => $store, 'digit_length' => 7]); } /** diff --git a/app/Service/v3/Implementations/GoodsActivityService.php b/app/Service/v3/Implementations/GoodsActivityService.php index 1bbd217..5bb2122 100644 --- a/app/Service/v3/Implementations/GoodsActivityService.php +++ b/app/Service/v3/Implementations/GoodsActivityService.php @@ -12,6 +12,7 @@ use App\Constants\v3\Store; use App\Constants\v3\Goods; use App\Model\v3\GoodsActivity; use App\Model\v3\GoodsActivityBanner; +use Hyperf\Redis\Redis; use Hyperf\Utils\ApplicationContext; class GoodsActivityService implements GoodsActivityServiceInterface @@ -24,6 +25,9 @@ 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)) { return ErrorCode::GOODS_ACTIVITY_NOT_EXISTS; } @@ -44,7 +48,9 @@ class GoodsActivityService implements GoodsActivityServiceInterface } // 商品库存不足 - if($goods->is_infinite != 1 && $goods->inventory < $num){ + // 获取冻结的库存 + $inventoryFrozen = (int)$redis->get($inventoryKey); + if($goods->is_infinite != 1 && $goods->inventory < ($num+$inventoryFrozen)){ return ErrorCode::GOODS_ACTIVITY_INVENTORY_ERROR; } diff --git a/app/Service/v3/Implementations/GoodsService.php b/app/Service/v3/Implementations/GoodsService.php index bf240f3..57fb1c3 100644 --- a/app/Service/v3/Implementations/GoodsService.php +++ b/app/Service/v3/Implementations/GoodsService.php @@ -10,6 +10,9 @@ use App\Model\v3\Goods; use App\Model\v3\GoodsBanner; use App\Constants\v3\Store; use App\Constants\v3\goods as goodsConstants; +use Hyperf\Redis\Redis; +use Hyperf\Utils\ApplicationContext; + class GoodsService implements GoodsServiceInterface { public function do($goodsId) @@ -17,10 +20,12 @@ 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)) { return ErrorCode::GOODS_NOT_EXISTS; } @@ -34,7 +39,9 @@ class GoodsService implements GoodsServiceInterface return ErrorCode::GOODS_ON_SALE_NO; } // 商品库存不足 - if($goods->is_infinite != 1 && $goods->inventory < $num){ + // 获取冻结的库存 + $inventoryFrozen = (int)$redis->get($inventoryKey); + if($goods->is_infinite != 1 && $goods->inventory < ($num+$inventoryFrozen)){ return ErrorCode::GOODS_INVENTORY_ERROR; } diff --git a/app/Service/v3/Implementations/OrderOnlineService.php b/app/Service/v3/Implementations/OrderOnlineService.php index 50fd29c..caf974d 100644 --- a/app/Service/v3/Implementations/OrderOnlineService.php +++ b/app/Service/v3/Implementations/OrderOnlineService.php @@ -34,6 +34,7 @@ use Hyperf\Database\Model\Model; use Hyperf\DbConnection\Db; use Hyperf\Di\Annotation\Inject; use App\Service\v3\Interfaces\OrderOnlineServiceInterface; +use Hyperf\Redis\Redis; use Hyperf\Snowflake\IdGeneratorInterface; use Hyperf\Utils\ApplicationContext; @@ -115,6 +116,8 @@ class OrderOnlineService implements OrderOnlineServiceInterface */ public function do($marketId, $userId, $userAddrId, $storeList, $totalMoney, $deliveryTimeNote='尽快送达', $serviceMoney=0, $receiveCouponIds=null, $plat=''){ + $redis = ApplicationContext::getContainer()->get(Redis::class); + $carts = []; Db::beginTransaction(); try { @@ -335,6 +338,18 @@ class OrderOnlineService implements OrderOnlineServiceInterface Db::commit(); + // 压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, $cart->num); + } else { + $redis->incrBy($inventoryKey, $cart->num); + } + } + // 清除购物车 $this->shopCartUpdateService->doClear($userId, $marketId); @@ -345,6 +360,17 @@ class OrderOnlineService implements OrderOnlineServiceInterface return $this->paymentService->do($globalOrderId, $totalAmount, $userId, config('wechat.notify_url.online')); } catch (Exception $e) { Db::rollBack(); + // 释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, $cart->num); + } + } $this->log->event(LogLabel::ORDER_ONLINE_LOG, ['msg' => $e->getMessage()]); throw new ErrorCodeException(ErrorCode::ORDER_ONLINE_FAIL); } @@ -388,15 +414,31 @@ class OrderOnlineService implements OrderOnlineServiceInterface // 撤销活动商品购买记录 $orders = Order::query()->where(['order_main_id' => $globalOrderId])->get()->toArray(); $orderGoods = OrderGoods::query() - ->where('activity_type', 2) + // ->where('activity_type', 2) ->whereIn('order_id', array_values(array_column($orders, 'id'))) - ->get(); + ->get() + ->toArray(); foreach ($orderGoods as $key => &$goods) { - $this->goodsActivityService->clearCacheRecord($goods->goods_id, $goods->number, $orderMain->user_id); + if ($goods['activity_type'] == 2) { + $this->goodsActivityService->clearCacheRecord($goods['goods_id'], $goods['number'], $orderMain['user_id']); + } } Db::commit(); + // 释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, $goodsItem['number']); + } + } + // 记录badge $orderChildIds = array_values(array_column($orders, 'store_id')); $this->badgeService->doByOrder($orderMain->user_id, $orderChildIds, $orderMain->global_order_id, OrderState::CANCELED); @@ -479,6 +521,19 @@ class OrderOnlineService implements OrderOnlineServiceInterface Db::commit(); + // 释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, $goodsItem['number']); + } + } + // 月销流水 $statistics = []; foreach ($orders as $key => &$order) {