Просмотр исходного кода

Merge branch 'redesign‌-260706' into dev

shizhongqi 1 день назад
Родитель
Сommit
1587cf2ada

+ 2 - 6
app-mall/controllers/GroupBuyController.php

@@ -187,9 +187,7 @@ class GroupBuyController extends BaseController
         if (empty($row)) {
             util::fail('团购活动已结束或商品已下架');
         }
-        if ($goodsNum > intval($row['limit'])) {
-            util::fail('超出单人限购数量');
-        }
+        GroupBuyClass::assertPurchaseLimit($mainId, $customId, $row, $goodsNum);
 
         $connection = Yii::$app->db;
         $transaction = $connection->beginTransaction();
@@ -274,9 +272,7 @@ class GroupBuyController extends BaseController
                     'virtualMinutes' => 0,
                 ];
             }
-            if ($goodsNum > intval($row['limit'] ?? 1)) {
-                util::fail('超出单人限购数量');
-            }
+            GroupBuyClass::assertPurchaseLimit($mainId, $customId, $row, $goodsNum);
             $order = $this->createGroupBuyOrder($form, $row, $groupBuyId, $goodsNum, $custom);
             GroupBuyMemberClass::bindOrderMember(
                 $groupBuyId,

+ 112 - 0
biz-hd/groupBuy/classes/GroupBuyClass.php

@@ -134,6 +134,118 @@ class GroupBuyClass extends BaseClass
         return $group;
     }
 
+    /**
+     * 单人限购校验:本次购买数量不得超限,且加上历史有效购买数量后也不得超限
+     *
+     * @param int $mainId
+     * @param int $customId
+     * @param array $activityGoodsRow getActiveGoodsRowById 或团快照
+     * @param int $goodsNum 本次购买数量
+     * @return bool
+     */
+    public static function assertPurchaseLimit($mainId, $customId, $activityGoodsRow, $goodsNum)
+    {
+        $limit = intval($activityGoodsRow['limit'] ?? 0);
+        $goodsNum = intval($goodsNum);
+        if ($goodsNum > $limit) {
+            util::fail('超出单人限购数量');
+        }
+        $boughtNum = self::getCustomBoughtNum(
+            $mainId,
+            $customId,
+            intval($activityGoodsRow['activityId'] ?? 0),
+            intval($activityGoodsRow['goodsId'] ?? 0),
+            intval($activityGoodsRow['activityGoodsId'] ?? ($activityGoodsRow['id'] ?? 0))
+        );
+        if (($goodsNum + $boughtNum) > $limit) {
+            util::fail('超出单人限购数量');
+        }
+        return true;
+    }
+
+    /**
+     * 客户在同一活动商品上的历史有效购买数量(待支付占用 + 已支付未退款)
+     * 拼团失败/取消、订单已取消或已退款不计入
+     *
+     * @param int $mainId
+     * @param int $customId
+     * @param int $activityId
+     * @param int $goodsId
+     * @param int $activityGoodsId 无 activityId/goodsId 时的兜底
+     * @return int
+     */
+    public static function getCustomBoughtNum($mainId, $customId, $activityId, $goodsId, $activityGoodsId = 0)
+    {
+        $mainId = intval($mainId);
+        $customId = intval($customId);
+        $activityId = intval($activityId);
+        $goodsId = intval($goodsId);
+        $activityGoodsId = intval($activityGoodsId);
+        if ($mainId <= 0 || $customId <= 0) {
+            return 0;
+        }
+
+        $groupCondition = [
+            'mainId' => $mainId,
+            'status' => ['in', [self::STATUS_ONGOING, self::STATUS_SUCCESS]],
+        ];
+        if ($activityId > 0 && $goodsId > 0) {
+            $groupCondition['activityId'] = $activityId;
+            $groupCondition['goodsId'] = $goodsId;
+        } elseif ($activityGoodsId > 0) {
+            $groupCondition['activityGoodsId'] = $activityGoodsId;
+        } else {
+            return 0;
+        }
+        $groups = self::getAllByCondition($groupCondition, null, 'id', null);
+        if (empty($groups)) {
+            return 0;
+        }
+        $groupBuyIds = array_values(array_filter(array_map('intval', array_column($groups, 'id'))));
+        if (empty($groupBuyIds)) {
+            return 0;
+        }
+
+        $members = GroupBuyMemberClass::getAllByCondition([
+            'mainId' => $mainId,
+            'customId' => $customId,
+            'groupBuyId' => ['in', $groupBuyIds],
+            'status' => ['in', [
+                GroupBuyMemberClass::STATUS_WAIT_PAY,
+                GroupBuyMemberClass::STATUS_PAID,
+            ]],
+        ], null, 'orderSn', null);
+        if (empty($members)) {
+            return 0;
+        }
+        $orderSns = array_values(array_filter(array_unique(array_map('strval', array_column($members, 'orderSn')))));
+        if (empty($orderSns)) {
+            return 0;
+        }
+
+        $orders = OrderClass::getAllByCondition([
+            'orderSn' => ['in', $orderSns],
+            'customId' => $customId,
+            'status' => ['not in', [OrderClass::ORDER_STATUS_CANCEL]],
+            'refund' => OrderClass::REFUND_NO,
+        ], null, 'orderSn', null);
+        if (empty($orders)) {
+            return 0;
+        }
+        $validSns = array_values(array_filter(array_map('strval', array_column($orders, 'orderSn'))));
+        if (empty($validSns)) {
+            return 0;
+        }
+
+        $sumCondition = [
+            'orderSn' => ['in', $validSns],
+        ];
+        if ($goodsId > 0) {
+            $sumCondition['goodsId'] = $goodsId;
+        }
+        return intval(OrderGoodsClass::sum($sumCondition, 'num'));
+    }
+
     /**
      * 支付成功钩子:成员置已支付、currentNum+1、判定满团
      * 由 OrderClass::payAfter 在 groupBuyId>0 时调用