|
|
@@ -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 时调用
|