Browse Source

冻结和释放库存

master
weigang 5 years ago
parent
commit
5e0b2991b3
  1. 14
      app/Service/v3/Implementations/GoodsActivityService.php
  2. 47
      app/Service/v3/Implementations/GoodsInventoryService.php
  3. 12
      app/Service/v3/Implementations/GoodsService.php
  4. 101
      app/Service/v3/Implementations/OrderOnlineService.php
  5. 33
      app/Service/v3/Interfaces/GoodsInventoryServiceInterface.php
  6. 1
      config/autoload/dependencies.php

14
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;
}

47
app/Service/v3/Implementations/GoodsInventoryService.php

@ -0,0 +1,47 @@
<?php
namespace App\Service\v3\Implementations;
use App\Service\v3\Interfaces\GoodsInventoryServiceInterface;
use Hyperf\Redis\Redis;
use Hyperf\Utils\ApplicationContext;
class GoodsInventoryService implements GoodsInventoryServiceInterface
{
/**
* @inheritDoc
*/
public function doSold($activityType, $goodsId, $num)
{
$redis = ApplicationContext::getContainer()->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);
}
}

12
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);

101
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

33
app/Service/v3/Interfaces/GoodsInventoryServiceInterface.php

@ -0,0 +1,33 @@
<?php
namespace App\Service\v3\Interfaces;
interface GoodsInventoryServiceInterface
{
/**
* 压已售库存(冻结的)
* @param $activityType
* @param $goodsId
* @param $num
* @return mixed
*/
public function doSold($activityType, $goodsId, $num);
/**
* 释已售库存(冻结的)
* @param $activityType
* @param $goodsId
* @param $num
* @return mixed
*/
public function undoSold($activityType, $goodsId, $num);
/**
* 获取当前商品冻结库存
* @param $activityType
* @param $goodsId
* @return mixed
*/
public function getSold($activityType, $goodsId);
}

1
config/autoload/dependencies.php

@ -90,4 +90,5 @@ return [
\App\Service\v3\Interfaces\InitialDeliveryServiceInterface::class => \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,
];
Loading…
Cancel
Save