|
|
@@ -23,9 +23,9 @@ use bizGhs\order\classes\CheckOrderItemClass;
|
|
|
use bizGhs\order\traits\OrderTrait;
|
|
|
use bizGhs\shop\classes\ShopAdminClass;
|
|
|
use bizGhs\stock\classes\StockRecordClass;
|
|
|
-use bizHd\notify\classes\NotifyClass;
|
|
|
use common\components\dict;
|
|
|
use common\components\imgUtil;
|
|
|
+use common\components\noticeUtil;
|
|
|
use common\components\orderSn;
|
|
|
use common\components\stringUtil;
|
|
|
use common\components\util;
|
|
|
@@ -38,6 +38,7 @@ class ProductClass extends BaseClass
|
|
|
use OrderTrait;
|
|
|
|
|
|
public static $baseFile = '\bizGhs\product\models\Product';
|
|
|
+ const LIMIT_BUY_ROLLBACK_SNAPSHOT_KEY = 'limitBuyRollbackSnapshot'; //记录限购旧值快照缓存键
|
|
|
const PRICE_LABEL_AUTO = 1; //自动调价
|
|
|
const PRICE_LABEL_CHANGE = 2; //改价
|
|
|
const LOCK_STOCK = 'lock_stock';//修改库存锁
|
|
|
@@ -1408,22 +1409,21 @@ class ProductClass extends BaseClass
|
|
|
$itemInfo = self::mergeItemInfo($itemInfo);
|
|
|
|
|
|
$productIds = array_column($itemInfo, 'productId');
|
|
|
- $ghsProductData = ProductClass::getProductByIds($productIds);
|
|
|
+ $ghsProductData = self::getProductByIds($productIds);
|
|
|
$ghsProductData = array_column($ghsProductData, NULL, 'id');
|
|
|
- if ($live == 1) {
|
|
|
- $hdProductData = [];
|
|
|
- } else {
|
|
|
- $hdIds = array_column($itemInfo, 'hdProductId');
|
|
|
- $hdProductData = ProductClass::getByIds($hdIds, null, 'id');
|
|
|
- }
|
|
|
-
|
|
|
- $book = $moreParams['book'] ?? 0;
|
|
|
- $customShopAdminId = $moreParams['customShopAdminId'] ?? 0;
|
|
|
+// if ($live == 1) {
|
|
|
+// $hdProductData = [];
|
|
|
+// } else {
|
|
|
+// $hdIds = array_column($itemInfo, 'hdProductId');
|
|
|
+// $hdProductData = self::getByIds($hdIds, null, 'id');
|
|
|
+// }
|
|
|
|
|
|
$totalPrice = 0;
|
|
|
$totalBigNum = 0;
|
|
|
$totalSmallNum = 0;
|
|
|
|
|
|
+ $book = $moreParams['book'] ?? 0;
|
|
|
+ $customShopAdminId = $moreParams['customShopAdminId'] ?? 0;
|
|
|
$custom = $moreParams['custom'] ?? [];
|
|
|
//不同等级对应 price addPrice
|
|
|
$priceMap = CustomClass::$levelPriceKeyMap;
|
|
|
@@ -1439,12 +1439,15 @@ class ProductClass extends BaseClass
|
|
|
$totalCost = 0;
|
|
|
foreach ($itemInfo as $v) {
|
|
|
$ghsProductId = $v['productId'];
|
|
|
-
|
|
|
$currentGhsProduct = $ghsProductData[$ghsProductId] ?? [];
|
|
|
- $itemId = $currentGhsProduct['itemId'] ?? 0;
|
|
|
- $ratio = $currentGhsProduct['ratio'] ?? 0;
|
|
|
- $cost = $currentGhsProduct['avCost'] ?? 0;
|
|
|
- $classId = $currentGhsProduct['classId'] ?? 0;
|
|
|
+ if (empty($currentGhsProduct)) {
|
|
|
+ noticeUtil::push("ghsProductId={$ghsProductId} 在 ghsProductData 中为空");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $itemId = $currentGhsProduct['itemId'];
|
|
|
+ $ratio = $currentGhsProduct['ratio'];
|
|
|
+ $cost = $currentGhsProduct['avCost'];
|
|
|
+ $classId = $currentGhsProduct['classId'];
|
|
|
|
|
|
$bigNum = $v['bigNum'] ?? 0;
|
|
|
$smallNum = $v['smallNum'] ?? 0;
|
|
|
@@ -1514,10 +1517,13 @@ class ProductClass extends BaseClass
|
|
|
$tmp['sjId'] = $currentGhsProduct['sjId'] ?? 0;
|
|
|
$tmp['shopId'] = $currentGhsProduct['shopId'] ?? 0;
|
|
|
$tmp['mainId'] = $currentGhsProduct['mainId'] ?? 0;
|
|
|
- $tmp['limitBuy'] = $currentGhsProduct['limitBuy'] ?? 0;
|
|
|
+ $tmp['limitBuy'] = $currentGhsProduct['limitBuy'];
|
|
|
$tmp['smallUnitPrice'] = $itemPrice;
|
|
|
$tmp['classId'] = $classId;
|
|
|
$tmp['belongCost'] = $currentGhsProduct['belongCost'] ?? 0;
|
|
|
+ $tmp['hjDiscountPrice'] = $currentGhsProduct['hjDiscountPrice'];
|
|
|
+ $tmp['discountPrice'] = $currentGhsProduct['discountPrice'];
|
|
|
+ $tmp['skDiscountPrice'] = $currentGhsProduct['skDiscountPrice'];
|
|
|
|
|
|
$totalBigNum += $bigNum;
|
|
|
$totalSmallNum += $smallNum;
|
|
|
@@ -1533,16 +1539,10 @@ class ProductClass extends BaseClass
|
|
|
|
|
|
$smallCost = bcdiv($cost, $ratio, 2);
|
|
|
$cost = $smallCost;
|
|
|
-
|
|
|
}
|
|
|
|
|
|
- $tmp['cost'] = $cost;
|
|
|
-
|
|
|
$xhPrice = bcmul($xhNum, $itemPrice, 2);
|
|
|
-
|
|
|
- $currentCost = bcmul($xhNum, $cost, 2);
|
|
|
- $totalCost = bcadd($totalCost, $currentCost, 2);
|
|
|
-
|
|
|
+ $tmp['cost'] = $cost;
|
|
|
$tmp['xhNum'] = $xhNum;
|
|
|
$tmp['xhUnitName'] = $xhUnitName;
|
|
|
$tmp['xhUnitType'] = $xhUnitType;
|
|
|
@@ -1553,8 +1553,10 @@ class ProductClass extends BaseClass
|
|
|
$tmp['xhPreUnitType'] = $xhUnitType;
|
|
|
$tmp['xhPreUnitPrice'] = $itemPrice;
|
|
|
$tmp['xhPrePrice'] = $xhPrice;
|
|
|
-
|
|
|
$data[] = $tmp;
|
|
|
+
|
|
|
+ $currentCost = bcmul($xhNum, $cost, 2);
|
|
|
+ $totalCost = bcadd($totalCost, $currentCost, 2); // TODO 根据限购与特价进行价格计算的关键参数
|
|
|
}
|
|
|
|
|
|
return ['product' => $data, 'totalReachDiscount' => $totalReachDiscount, 'smallNum' => $totalSmallNum,
|
|
|
@@ -2689,26 +2691,111 @@ class ProductClass extends BaseClass
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 设置限购缓存
|
|
|
- public static function setLimitBuyCache($productId, $customId, $limitBuy, $num)
|
|
|
+ /**
|
|
|
+ * 记录限购缓存写入前快照(同一次请求内同商品同客户只记录一次)
|
|
|
+ *
|
|
|
+ * @param int $productId
|
|
|
+ * @param int $customId
|
|
|
+ * @param bool $hasOldValue
|
|
|
+ * @param string|int|float $oldValue
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public static function recordLimitBuyRollbackSnapshot($productId, $customId, $hasOldValue, $oldValue = 0)
|
|
|
+ {
|
|
|
+ $productId = intval($productId);
|
|
|
+ $customId = intval($customId);
|
|
|
+ if ($productId <= 0 || $customId <= 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ $snapshotKey = $productId . '_' . $customId;
|
|
|
+ if (!isset(Yii::$app->params[self::LIMIT_BUY_ROLLBACK_SNAPSHOT_KEY]) || !is_array(Yii::$app->params[self::LIMIT_BUY_ROLLBACK_SNAPSHOT_KEY])) {
|
|
|
+ Yii::$app->params[self::LIMIT_BUY_ROLLBACK_SNAPSHOT_KEY] = [];
|
|
|
+ }
|
|
|
+ if (isset(Yii::$app->params[self::LIMIT_BUY_ROLLBACK_SNAPSHOT_KEY][$snapshotKey])) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Yii::$app->params[self::LIMIT_BUY_ROLLBACK_SNAPSHOT_KEY][$snapshotKey] = [
|
|
|
+ 'productId' => $productId,
|
|
|
+ 'customId' => $customId,
|
|
|
+ 'hasOldValue' => $hasOldValue ? 1 : 0,
|
|
|
+ 'oldValue' => strval($oldValue),
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 清理当前请求中记录的限购回滚快照
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public static function clearLimitBuyRollbackSnapshot()
|
|
|
+ {
|
|
|
+ unset(Yii::$app->params[self::LIMIT_BUY_ROLLBACK_SNAPSHOT_KEY]);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 回滚当前请求中已记录的限购缓存变更
|
|
|
+ *
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function rollbackLimitBuySnapshot()
|
|
|
+ {
|
|
|
+ $snapshotList = Yii::$app->params[self::LIMIT_BUY_ROLLBACK_SNAPSHOT_KEY] ?? [];
|
|
|
+ if (empty($snapshotList) || !is_array($snapshotList)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ foreach ($snapshotList as $snapshot) {
|
|
|
+ $productId = intval($snapshot['productId'] ?? 0);
|
|
|
+ $customId = intval($snapshot['customId'] ?? 0);
|
|
|
+ if ($productId <= 0 || $customId <= 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $limitKey = 'limit_buy_' . $productId;
|
|
|
+ $hasOldValue = intval($snapshot['hasOldValue'] ?? 0);
|
|
|
+ if ($hasOldValue == 1) {
|
|
|
+ $oldValue = $snapshot['oldValue'] ?? '0';
|
|
|
+ Yii::$app->redis->executeCommand('HSET', [$limitKey, $customId, $oldValue]);
|
|
|
+ } else {
|
|
|
+ Yii::$app->redis->executeCommand('HDEL', [$limitKey, $customId]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ self::clearLimitBuyRollbackSnapshot();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 限购处理
|
|
|
+ public static function handleLimitBuy($product, $customId, $num)
|
|
|
{
|
|
|
+ $limitBuy = $product['limitBuy'];
|
|
|
if ($limitBuy <= 0) {
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ $productId = $product['productId'];
|
|
|
$limitKey = 'limit_buy_' . $productId;
|
|
|
$has = Yii::$app->redis->executeCommand('HEXISTS', [$limitKey, $customId]);
|
|
|
if (!empty($has)) {
|
|
|
$hasNum = Yii::$app->redis->executeCommand('HGET', [$limitKey, $customId]);
|
|
|
$lastNum = bcadd($hasNum, $num);
|
|
|
if ($lastNum > $limitBuy) {
|
|
|
- util::fail('超出限购数');
|
|
|
+ // 如果有特价,则超过的数量按原价卖;否则中断
|
|
|
+ if ($product['hjDiscountPrice'] > 0 && $product['discountPrice'] > 0 && $product['skDiscountPrice'] > 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ util::error(-1, '累计已超出限购数', ['productId'=>$productId, 'limitBuy'=>$limitBuy, 'exceed'=>$lastNum - $limitBuy]);
|
|
|
}
|
|
|
+ self::recordLimitBuyRollbackSnapshot($productId, $customId, true, $hasNum);
|
|
|
Yii::$app->redis->executeCommand('HSET', [$limitKey, $customId, $lastNum]);
|
|
|
} else {
|
|
|
if ($num > $limitBuy) {
|
|
|
- util::fail('超出限购数');
|
|
|
+ // 如果有特价,则超过的数量按原价卖;否则中断
|
|
|
+ if ($product['hjDiscountPrice'] > 0 && $product['discountPrice'] > 0 && $product['skDiscountPrice'] > 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ util::error(-1, '超出限购数', ['productId'=>$productId, 'limitBuy'=>$limitBuy, 'exceed'=>$num - $limitBuy]);
|
|
|
}
|
|
|
+ self::recordLimitBuyRollbackSnapshot($productId, $customId, false, 0);
|
|
|
Yii::$app->redis->executeCommand('HSET', [$limitKey, $customId, $num]);
|
|
|
}
|
|
|
}
|