|
@@ -0,0 +1,1174 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace app\common\Service\Lottery;
|
|
|
+
|
|
|
+use app\common\model\lottery\LotteryActivity;
|
|
|
+use app\common\model\lottery\LotteryCondition;
|
|
|
+use app\common\model\lottery\LotteryUserChance;
|
|
|
+use app\common\model\lottery\LotteryUserChanceRecord;
|
|
|
+use app\common\model\User;
|
|
|
+use app\common\model\Order;
|
|
|
+use app\common\Enum\LotteryEnum;
|
|
|
+use think\Exception;
|
|
|
+use think\Db;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 抽奖机会服务类
|
|
|
+ * 处理用户获得抽奖机会的逻辑
|
|
|
+ *
|
|
|
+ * 主要功能:
|
|
|
+ * - 订单/充值后自动分发抽奖机会
|
|
|
+ * - 条件验证和机会计算
|
|
|
+ * - 用户机会管理
|
|
|
+ * - 批量操作和统计
|
|
|
+ */
|
|
|
+class LotteryChanceService
|
|
|
+{
|
|
|
+ // ============ 常量定义 ============
|
|
|
+
|
|
|
+ /** @var int 默认批量处理数量 */
|
|
|
+ const DEFAULT_BATCH_SIZE = 100;
|
|
|
+
|
|
|
+ /** @var int 最大批量处理数量 */
|
|
|
+ const MAX_BATCH_SIZE = 1000;
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 订单完成后检查并分发抽奖机会
|
|
|
+ *
|
|
|
+ * @param array $orderInfo 订单信息 ['id', 'total_amount', 'goods' => [['goods_id']]]
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return array 获得的抽奖机会信息
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static function checkAndGrantChanceForOrder($orderInfo, $userId)
|
|
|
+ {
|
|
|
+ if (empty($orderInfo) || empty($userId)) {
|
|
|
+ throw new Exception('订单信息或用户ID不能为空');
|
|
|
+ }
|
|
|
+
|
|
|
+ $grantedChances = [];
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 获取所有正在进行的抽奖活动
|
|
|
+ $activities = LotteryService::getRunningActivities();
|
|
|
+
|
|
|
+ foreach ($activities as $activity) {
|
|
|
+ try {
|
|
|
+ $chances = static::processActivityForOrder($activity, $orderInfo, $userId);
|
|
|
+ if ($chances > 0) {
|
|
|
+ $grantedChances[] = [
|
|
|
+ 'activity_id' => $activity->id,
|
|
|
+ 'activity_name' => $activity->name,
|
|
|
+ 'chances' => $chances,
|
|
|
+ 'granted_time' => time()
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ } catch (Exception $e) {
|
|
|
+ // 记录错误但不影响其他活动的处理
|
|
|
+ trace("抽奖机会分发失败 - 活动ID: {$activity->id}, 用户ID: {$userId}, 错误: " . $e->getMessage(), 'error');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception $e) {
|
|
|
+ trace("订单抽奖机会分发失败 - 用户ID: {$userId}, 错误: " . $e->getMessage(), 'error');
|
|
|
+ throw $e;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $grantedChances;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 充值完成后检查并分发抽奖机会
|
|
|
+ *
|
|
|
+ * @param array $rechargeInfo 充值信息 ['amount', 'type' => 'recharge']
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return array 获得的抽奖机会信息
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static function checkAndGrantChanceForRecharge($rechargeInfo, $userId)
|
|
|
+ {
|
|
|
+ if (empty($rechargeInfo) || empty($userId)) {
|
|
|
+ throw new Exception('充值信息或用户ID不能为空');
|
|
|
+ }
|
|
|
+
|
|
|
+ $grantedChances = [];
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 获取所有正在进行的抽奖活动
|
|
|
+ $activities = LotteryService::getRunningActivities();
|
|
|
+
|
|
|
+ foreach ($activities as $activity) {
|
|
|
+ try {
|
|
|
+ $chances = static::processActivityForRecharge($activity, $rechargeInfo, $userId);
|
|
|
+ if ($chances > 0) {
|
|
|
+ $grantedChances[] = [
|
|
|
+ 'activity_id' => $activity->id,
|
|
|
+ 'activity_name' => $activity->name,
|
|
|
+ 'chances' => $chances,
|
|
|
+ 'granted_time' => time()
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ } catch (Exception $e) {
|
|
|
+ // 记录错误但不影响其他活动的处理
|
|
|
+ trace("充值抽奖机会分发失败 - 活动ID: {$activity->id}, 用户ID: {$userId}, 错误: " . $e->getMessage(), 'error');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception $e) {
|
|
|
+ trace("充值抽奖机会分发失败 - 用户ID: {$userId}, 错误: " . $e->getMessage(), 'error');
|
|
|
+ throw $e;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $grantedChances;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 手动给用户增加抽奖机会(管理员操作) *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @param int $chances 机会次数
|
|
|
+ * @param string $reason 原因
|
|
|
+ * @param int $adminId 管理员ID
|
|
|
+ * @return bool
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static function manualGrantChance($activityId, $userId, $chances, $reason = '', $adminId = 0)
|
|
|
+ {
|
|
|
+ if ($chances <= 0) {
|
|
|
+ throw new Exception('抽奖机会数量必须大于0');
|
|
|
+ }
|
|
|
+
|
|
|
+ $activity = LotteryActivity::find($activityId);
|
|
|
+ if (!$activity) {
|
|
|
+ throw new Exception('活动不存在');
|
|
|
+ }
|
|
|
+
|
|
|
+ $user = User::find($userId);
|
|
|
+ if (!$user) {
|
|
|
+ throw new Exception('用户不存在');
|
|
|
+ }
|
|
|
+
|
|
|
+ $detail = [
|
|
|
+ 'reason' => $reason,
|
|
|
+ 'admin_id' => $adminId,
|
|
|
+ 'granted_time' => time()
|
|
|
+ ];
|
|
|
+
|
|
|
+ return static::grantChanceToUser($activityId, $userId, $chances, $detail);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量初始化用户抽奖机会(活动开始时)
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @param array $userIds 用户ID数组
|
|
|
+ * @param int $initChances 初始机会数
|
|
|
+ * @param int $batchSize 批量处理大小
|
|
|
+ * @return array 处理结果
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static function batchInitChances($activityId, $userIds, $initChances = 1, $batchSize = null)
|
|
|
+ {
|
|
|
+ if (empty($userIds)) {
|
|
|
+ throw new Exception('用户ID列表不能为空');
|
|
|
+ }
|
|
|
+
|
|
|
+ $activity = LotteryActivity::find($activityId);
|
|
|
+ if (!$activity) {
|
|
|
+ throw new Exception('活动不存在');
|
|
|
+ }
|
|
|
+
|
|
|
+ $batchSize = $batchSize ?: static::DEFAULT_BATCH_SIZE;
|
|
|
+ $batchSize = min($batchSize, static::MAX_BATCH_SIZE);
|
|
|
+
|
|
|
+ $result = [
|
|
|
+ 'total_users' => count($userIds),
|
|
|
+ 'success_count' => 0,
|
|
|
+ 'failed_count' => 0,
|
|
|
+ 'errors' => []
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 分批处理
|
|
|
+ $batches = array_chunk($userIds, $batchSize);
|
|
|
+
|
|
|
+ foreach ($batches as $batch) {
|
|
|
+ try {
|
|
|
+ $success = static::batchCreateChances($activityId, $batch, $initChances);
|
|
|
+ if ($success) {
|
|
|
+ $result['success_count'] += count($batch);
|
|
|
+ } else {
|
|
|
+ $result['failed_count'] += count($batch);
|
|
|
+ $result['errors'][] = "批次处理失败: " . implode(',', $batch);
|
|
|
+ }
|
|
|
+ } catch (Exception $e) {
|
|
|
+ $result['failed_count'] += count($batch);
|
|
|
+ $result['errors'][] = "批次处理异常: " . $e->getMessage();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // ============ 私有处理方法 ============
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理订单相关的活动
|
|
|
+ *
|
|
|
+ * @param LotteryActivity $activity 活动对象
|
|
|
+ * @param array $orderInfo 订单信息
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return int 获得的抽奖机会数量
|
|
|
+ */
|
|
|
+ private static function processActivityForOrder($activity, $orderInfo, $userId)
|
|
|
+ {
|
|
|
+ // 检查用户是否符合活动参与资格
|
|
|
+ if (!static::checkUserQualification($activity, $userId)) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取活动的参与条件
|
|
|
+ $conditions = static::getValidConditions($activity->id);
|
|
|
+ $totalChances = 0;
|
|
|
+ $chanceDetails = [];
|
|
|
+
|
|
|
+ foreach ($conditions as $condition) {
|
|
|
+ // 跳过充值条件
|
|
|
+ if ($condition->type == LotteryEnum::CONDITION_TYPE_RECHARGE_AMOUNT) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ $result = static::processConditionForOrder($condition, $orderInfo, $userId);
|
|
|
+ if ($result['chances'] > 0) {
|
|
|
+ $totalChances += $result['chances'];
|
|
|
+ $result['detail']['chances'] = $result['chances'];
|
|
|
+ $chanceDetails[] = $result['detail'];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果获得了抽奖机会,记录到数据库
|
|
|
+ if ($totalChances > 0) {
|
|
|
+ // 为每个条件分别记录
|
|
|
+ foreach ($chanceDetails as $detail) {
|
|
|
+ static::grantChanceToUser($activity->id, $userId, $detail['chances'] ?? 1, [
|
|
|
+ 'condition_id' => $detail['condition_id'],
|
|
|
+ 'condition_type' => $detail['condition_type'],
|
|
|
+ 'condition_value' => $detail['condition_value'],
|
|
|
+ 'order_id' => $orderInfo['id'] ?? 0,
|
|
|
+ 'granted_time' => time()
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $totalChances;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理充值相关的活动
|
|
|
+ *
|
|
|
+ * @param LotteryActivity $activity 活动对象
|
|
|
+ * @param array $rechargeInfo 充值信息
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return int 获得的抽奖机会数量
|
|
|
+ */
|
|
|
+ private static function processActivityForRecharge($activity, $rechargeInfo, $userId)
|
|
|
+ {
|
|
|
+ // 检查用户是否符合活动参与资格
|
|
|
+ if (!static::checkUserQualification($activity, $userId)) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取活动的参与条件
|
|
|
+ $conditions = static::getValidConditions($activity->id);
|
|
|
+ $totalChances = 0;
|
|
|
+ $chanceDetails = [];
|
|
|
+
|
|
|
+ foreach ($conditions as $condition) {
|
|
|
+ // 只处理充值条件
|
|
|
+ if ($condition->type != LotteryEnum::CONDITION_TYPE_RECHARGE_AMOUNT) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ $result = static::processConditionForRecharge($condition, $rechargeInfo, $userId);
|
|
|
+ if ($result['chances'] > 0) {
|
|
|
+ $totalChances += $result['chances'];
|
|
|
+ $result['detail']['chances'] = $result['chances'];
|
|
|
+ $chanceDetails[] = $result['detail'];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果获得了抽奖机会,记录到数据库
|
|
|
+ if ($totalChances > 0) {
|
|
|
+ // 为每个条件分别记录
|
|
|
+ foreach ($chanceDetails as $detail) {
|
|
|
+ static::grantChanceToUser($activity->id, $userId, $detail['chances'] ?? 1, [
|
|
|
+ 'condition_id' => $detail['condition_id'],
|
|
|
+ 'condition_type' => $detail['condition_type'],
|
|
|
+ 'condition_value' => $detail['condition_value'],
|
|
|
+ 'recharge_amount' => $rechargeInfo['amount'] ?? 0,
|
|
|
+ 'granted_time' => time()
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $totalChances;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理订单条件
|
|
|
+ *
|
|
|
+ * @param LotteryCondition $condition 条件对象
|
|
|
+ * @param array $orderInfo 订单信息
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return array 获得的抽奖机会信息 ['chances' => int, 'detail' => array]
|
|
|
+ */
|
|
|
+ private static function processConditionForOrder($condition, $orderInfo, $userId)
|
|
|
+ {
|
|
|
+ $chances = 0;
|
|
|
+ $detail = [
|
|
|
+ 'condition_id' => $condition->id,
|
|
|
+ 'condition_type' => $condition->type,
|
|
|
+ 'condition_value' => $condition->condition_value,
|
|
|
+ ];
|
|
|
+
|
|
|
+ switch ($condition->type) {
|
|
|
+ case LotteryEnum::CONDITION_TYPE_BUY_GOODS:
|
|
|
+ if (static::validateGoodsCondition($condition, $orderInfo)) {
|
|
|
+ $chances = static::getRewardTimes($condition);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case LotteryEnum::CONDITION_TYPE_ORDER_AMOUNT:
|
|
|
+ if (static::validateOrderAmountCondition($condition, $orderInfo)) {
|
|
|
+ $chances = static::getRewardTimes($condition);
|
|
|
+
|
|
|
+ // 如果可重复获得,根据金额倍数计算次数
|
|
|
+ if (static::canRepeat($condition)) {
|
|
|
+ $multiple = floor($orderInfo['total_amount'] / $condition->condition_value);
|
|
|
+ $chances *= $multiple;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case LotteryEnum::CONDITION_TYPE_TOTAL_AMOUNT:
|
|
|
+ if (static::validateAccumulateCondition($condition, $userId, $condition->activity_id)) {
|
|
|
+ // 检查是否已经因为累计消费获得过机会
|
|
|
+ if (!static::hasGrantedForAccumulate($condition->activity_id, $userId)) {
|
|
|
+ $chances = static::getRewardTimes($condition);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'chances' => $chances,
|
|
|
+ 'detail' => $detail
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理充值条件
|
|
|
+ *
|
|
|
+ * @param LotteryCondition $condition 条件对象
|
|
|
+ * @param array $rechargeInfo 充值信息
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return array 获得的抽奖机会信息 ['chances' => int, 'detail' => array]
|
|
|
+ */
|
|
|
+ private static function processConditionForRecharge($condition, $rechargeInfo, $userId)
|
|
|
+ {
|
|
|
+ $chances = 0;
|
|
|
+ $detail = [
|
|
|
+ 'condition_id' => $condition->id,
|
|
|
+ 'condition_type' => $condition->type,
|
|
|
+ 'condition_value' => $condition->condition_value,
|
|
|
+ ];
|
|
|
+
|
|
|
+ if (static::validateRechargeCondition($condition, ['type' => 'recharge', 'amount' => $rechargeInfo['amount']])) {
|
|
|
+ $chances = static::getRewardTimes($condition);
|
|
|
+
|
|
|
+ // 如果可重复获得,根据金额倍数计算次数
|
|
|
+ if (static::canRepeat($condition)) {
|
|
|
+ $multiple = floor($rechargeInfo['amount'] / $condition->condition_value);
|
|
|
+ $chances *= $multiple;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'chances' => $chances,
|
|
|
+ 'detail' => $detail
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // ============ 用户资格检查方法 ============
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查用户资格
|
|
|
+ *
|
|
|
+ * @param LotteryActivity $activity 活动对象
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ private static function checkUserQualification($activity, $userId)
|
|
|
+ {
|
|
|
+ // 检查用户群体限制
|
|
|
+ switch ($activity->user_limit_type) {
|
|
|
+ case LotteryEnum::USER_LIMIT_ALL:
|
|
|
+ return true;
|
|
|
+ case LotteryEnum::USER_LIMIT_LEVEL:
|
|
|
+ return static::checkUserLevel($userId, $activity->user_limit_value);
|
|
|
+ case LotteryEnum::USER_LIMIT_TAG:
|
|
|
+ return static::checkUserTag($userId, $activity->user_limit_value);
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查用户等级
|
|
|
+ *
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @param mixed $limitValue 限制值
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ private static function checkUserLevel($userId, $limitValue)
|
|
|
+ {
|
|
|
+ if (empty($limitValue)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ $user = User::find($userId);
|
|
|
+ if (!$user) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $limitLevels = is_array($limitValue) ? $limitValue : [$limitValue];
|
|
|
+ return in_array($user->level, $limitLevels);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查用户标签
|
|
|
+ *
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @param mixed $limitValue 限制值
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ private static function checkUserTag($userId, $limitValue)
|
|
|
+ {
|
|
|
+ if (empty($limitValue)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO: 根据实际的用户标签系统实现
|
|
|
+ // 这里需要根据具体的用户标签表结构来实现
|
|
|
+ // 暂时返回true,避免影响现有功能
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查是否已因累计消费获得过机会
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ private static function hasGrantedForAccumulate($activityId, $userId)
|
|
|
+ {
|
|
|
+ $record = LotteryUserChanceRecord::where('activity_id', $activityId)
|
|
|
+ ->where('user_id', $userId)
|
|
|
+ ->where('get_type', LotteryEnum::CHANCE_GET_TYPE_TOTAL_AMOUNT)
|
|
|
+ ->find();
|
|
|
+
|
|
|
+ return $record ? true : false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // ============ 条件验证方法 ============
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证订单是否满足条件
|
|
|
+ *
|
|
|
+ * @param LotteryCondition $condition 条件对象
|
|
|
+ * @param array $orderInfo 订单信息
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function validateOrder(LotteryCondition $condition, $orderInfo)
|
|
|
+ {
|
|
|
+ switch ($condition->type) {
|
|
|
+ case LotteryEnum::CONDITION_TYPE_BUY_GOODS:
|
|
|
+ return static::validateGoodsCondition($condition, $orderInfo);
|
|
|
+ case LotteryEnum::CONDITION_TYPE_ORDER_AMOUNT:
|
|
|
+ return static::validateOrderAmountCondition($condition, $orderInfo);
|
|
|
+ case LotteryEnum::CONDITION_TYPE_RECHARGE_AMOUNT:
|
|
|
+ return static::validateRechargeCondition($condition, $orderInfo);
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证商品条件
|
|
|
+ *
|
|
|
+ * @param LotteryCondition $condition 条件对象
|
|
|
+ * @param array $orderInfo 订单信息
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function validateGoodsCondition(LotteryCondition $condition, $orderInfo)
|
|
|
+ {
|
|
|
+ if (empty($orderInfo['goods']) || empty($condition->goods_ids_list)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $orderGoodsIds = array_column($orderInfo['goods'], 'goods_id');
|
|
|
+ $conditionGoodsIds = $condition->goods_ids_list;
|
|
|
+ $intersection = array_intersect($orderGoodsIds, $conditionGoodsIds);
|
|
|
+
|
|
|
+ if ($condition->goods_rule == LotteryEnum::GOODS_RULE_INCLUDE) {
|
|
|
+ // 指定商品参与:订单中必须包含指定商品
|
|
|
+ return !empty($intersection);
|
|
|
+ } else {
|
|
|
+ // 指定商品不可参与:订单中不能包含指定商品
|
|
|
+ return empty($intersection);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证订单金额条件
|
|
|
+ *
|
|
|
+ * @param LotteryCondition $condition 条件对象
|
|
|
+ * @param array $orderInfo 订单信息
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function validateOrderAmountCondition(LotteryCondition $condition, $orderInfo)
|
|
|
+ {
|
|
|
+ $orderAmount = $orderInfo['total_amount'] ?? 0;
|
|
|
+ return $orderAmount >= $condition->condition_value;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证充值条件
|
|
|
+ *
|
|
|
+ * @param LotteryCondition $condition 条件对象
|
|
|
+ * @param array $orderInfo 订单信息
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function validateRechargeCondition(LotteryCondition $condition, $orderInfo)
|
|
|
+ {
|
|
|
+ if (($orderInfo['type'] ?? '') !== 'recharge') {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $rechargeAmount = $orderInfo['amount'] ?? 0;
|
|
|
+ return $rechargeAmount >= $condition->condition_value;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证累计消费条件
|
|
|
+ *
|
|
|
+ * @param LotteryCondition $condition 条件对象
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function validateAccumulateCondition(LotteryCondition $condition, $userId, $activityId)
|
|
|
+ {
|
|
|
+ $activity = LotteryActivity::find($activityId);
|
|
|
+ if (!$activity) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算活动期间用户累计消费
|
|
|
+ $totalAmount = Order::where('user_id', $userId)
|
|
|
+ ->where('status', 'paid')
|
|
|
+ ->where('createtime', '>=', $activity->start_time)
|
|
|
+ ->where('createtime', '<=', $activity->end_time)
|
|
|
+ ->sum('total_amount');
|
|
|
+
|
|
|
+ return $totalAmount >= $condition->condition_value;
|
|
|
+ }
|
|
|
+
|
|
|
+ // ============ 条件管理方法 ============
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取活动的有效条件
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function getValidConditions($activityId)
|
|
|
+ {
|
|
|
+ return LotteryCondition::where('activity_id', $activityId)
|
|
|
+ ->where('status', 1)
|
|
|
+ ->order('id', 'asc')
|
|
|
+ ->select();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查条件是否可重复获得奖励
|
|
|
+ *
|
|
|
+ * @param LotteryCondition $condition 条件对象
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function canRepeat(LotteryCondition $condition)
|
|
|
+ {
|
|
|
+ return $condition->is_repeatable == 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取奖励次数
|
|
|
+ *
|
|
|
+ * @param LotteryCondition $condition 条件对象
|
|
|
+ * @return int
|
|
|
+ */
|
|
|
+ public static function getRewardTimes(LotteryCondition $condition)
|
|
|
+ {
|
|
|
+ return $condition->reward_times ?: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量验证订单条件
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @param array $orderInfo 订单信息
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return array 满足的条件列表
|
|
|
+ */
|
|
|
+ public static function batchValidateConditions($activityId, $orderInfo, $userId)
|
|
|
+ {
|
|
|
+ $conditions = static::getValidConditions($activityId);
|
|
|
+ $validConditions = [];
|
|
|
+
|
|
|
+ foreach ($conditions as $condition) {
|
|
|
+ if (static::validateOrder($condition, $orderInfo)) {
|
|
|
+ $validConditions[] = [
|
|
|
+ 'condition_id' => $condition->id,
|
|
|
+ 'condition_name' => $condition->name,
|
|
|
+ 'condition_type' => $condition->type,
|
|
|
+ 'condition_type_text' => $condition->type_text,
|
|
|
+ 'reward_times' => static::getRewardTimes($condition),
|
|
|
+ 'can_repeat' => static::canRepeat($condition)
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $validConditions;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取条件统计信息
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function getConditionStatistics($activityId)
|
|
|
+ {
|
|
|
+ $conditions = static::getValidConditions($activityId);
|
|
|
+ $statistics = [
|
|
|
+ 'total_conditions' => count($conditions),
|
|
|
+ 'goods_conditions' => 0,
|
|
|
+ 'amount_conditions' => 0,
|
|
|
+ 'recharge_conditions' => 0,
|
|
|
+ 'accumulate_conditions' => 0
|
|
|
+ ];
|
|
|
+
|
|
|
+ foreach ($conditions as $condition) {
|
|
|
+ switch ($condition->type) {
|
|
|
+ case LotteryEnum::CONDITION_TYPE_BUY_GOODS:
|
|
|
+ $statistics['goods_conditions']++;
|
|
|
+ break;
|
|
|
+ case LotteryEnum::CONDITION_TYPE_ORDER_AMOUNT:
|
|
|
+ $statistics['amount_conditions']++;
|
|
|
+ break;
|
|
|
+ case LotteryEnum::CONDITION_TYPE_RECHARGE_AMOUNT:
|
|
|
+ $statistics['recharge_conditions']++;
|
|
|
+ break;
|
|
|
+ case LotteryEnum::CONDITION_TYPE_TOTAL_AMOUNT:
|
|
|
+ $statistics['accumulate_conditions']++;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $statistics;
|
|
|
+ }
|
|
|
+
|
|
|
+ // ============ 用户机会管理方法 ============
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户抽奖机会
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return LotteryUserChance|null
|
|
|
+ */
|
|
|
+ public static function getUserChance($activityId, $userId)
|
|
|
+ {
|
|
|
+ return LotteryUserChance::where('activity_id', $activityId)
|
|
|
+ ->where('user_id', $userId)
|
|
|
+ ->find();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据详情确定机会获取类型
|
|
|
+ *
|
|
|
+ * @param array $detail 获得详情
|
|
|
+ * @return int 获取类型
|
|
|
+ */
|
|
|
+ private static function getChanceGetTypeFromDetail($detail)
|
|
|
+ {
|
|
|
+ // 如果有条件类型,直接使用条件类型对应的获取类型
|
|
|
+ if (isset($detail['condition_type'])) {
|
|
|
+ switch ($detail['condition_type']) {
|
|
|
+ case LotteryEnum::CONDITION_TYPE_BUY_GOODS:
|
|
|
+ return LotteryEnum::CHANCE_GET_TYPE_BUY_GOODS;
|
|
|
+ case LotteryEnum::CONDITION_TYPE_ORDER_AMOUNT:
|
|
|
+ return LotteryEnum::CHANCE_GET_TYPE_ORDER_AMOUNT;
|
|
|
+ case LotteryEnum::CONDITION_TYPE_RECHARGE_AMOUNT:
|
|
|
+ return LotteryEnum::CHANCE_GET_TYPE_RECHARGE;
|
|
|
+ case LotteryEnum::CONDITION_TYPE_TOTAL_AMOUNT:
|
|
|
+ return LotteryEnum::CHANCE_GET_TYPE_TOTAL_AMOUNT;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果没有条件类型,检查是否是管理员赠送
|
|
|
+ if (isset($detail['admin_id']) && $detail['admin_id'] > 0) {
|
|
|
+ return LotteryEnum::CHANCE_GET_TYPE_ADMIN_GRANT;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 默认返回管理员赠送
|
|
|
+ return LotteryEnum::CHANCE_GET_TYPE_ADMIN_GRANT;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户在指定活动中的抽奖机会详情
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function getUserChanceDetail($activityId, $userId)
|
|
|
+ {
|
|
|
+ $userChance = static::getUserChance($activityId, $userId);
|
|
|
+
|
|
|
+ if (!$userChance) {
|
|
|
+ return [
|
|
|
+ 'total_chances' => 0,
|
|
|
+ 'used_chances' => 0,
|
|
|
+ 'remain_chances' => 0,
|
|
|
+ 'get_records' => []
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取机会获得记录
|
|
|
+ $getRecords = LotteryUserChanceRecord::getUserChanceRecords($activityId, $userId);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'total_chances' => $userChance->total_chances,
|
|
|
+ 'used_chances' => $userChance->used_chances,
|
|
|
+ 'remain_chances' => $userChance->remain_chances,
|
|
|
+ 'last_get_time' => $userChance->last_get_time,
|
|
|
+ 'last_use_time' => $userChance->last_use_time,
|
|
|
+ 'get_records' => $getRecords
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 给用户分发抽奖机会
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @param int $chances 机会次数
|
|
|
+ * @param array $detail 获得详情
|
|
|
+ * @return LotteryUserChance|bool
|
|
|
+ */
|
|
|
+ private static function grantChanceToUser($activityId, $userId, $chances, $detail)
|
|
|
+ {
|
|
|
+ return static::addChance($activityId, $userId, $chances, $detail);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 增加抽奖机会
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @param int $times 机会次数
|
|
|
+ * @param array $detail 获得详情
|
|
|
+ * @return LotteryUserChance|bool
|
|
|
+ */
|
|
|
+ public static function addChance($activityId, $userId, $times = 1, $detail = [])
|
|
|
+ {
|
|
|
+ if ($times <= 0) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ Db::startTrans();
|
|
|
+
|
|
|
+ $chance = static::getUserChance($activityId, $userId);
|
|
|
+
|
|
|
+ if (!$chance) {
|
|
|
+ // 创建新记录
|
|
|
+ $data = [
|
|
|
+ 'activity_id' => $activityId,
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'total_chances' => $times,
|
|
|
+ 'used_chances' => 0,
|
|
|
+ 'remain_chances' => $times,
|
|
|
+ 'last_get_time' => time(),
|
|
|
+ 'get_detail' => json_encode([]) // 保留字段但不使用
|
|
|
+ ];
|
|
|
+ $chance = LotteryUserChance::create($data);
|
|
|
+ } else {
|
|
|
+ // 更新现有记录
|
|
|
+ $chance->total_chances += $times;
|
|
|
+ $chance->remain_chances += $times;
|
|
|
+ $chance->last_get_time = time();
|
|
|
+ $chance->save();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建获得记录
|
|
|
+ $recordData = [
|
|
|
+ 'activity_id' => $activityId,
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'get_type' => static::getChanceGetTypeFromDetail($detail),
|
|
|
+ 'chances' => $times,
|
|
|
+ 'condition_id' => $detail['condition_id'] ?? null,
|
|
|
+ 'condition_value' => $detail['condition_value'] ?? null,
|
|
|
+ 'order_id' => $detail['order_id'] ?? null,
|
|
|
+ 'recharge_amount' => $detail['recharge_amount'] ?? null,
|
|
|
+ 'admin_id' => $detail['admin_id'] ?? null,
|
|
|
+ 'reason' => $detail['reason'] ?? null,
|
|
|
+ 'remark' => $detail['remark'] ?? null,
|
|
|
+ 'get_time' => time()
|
|
|
+ ];
|
|
|
+
|
|
|
+ $validation = LotteryUserChanceRecord::validateRecord($recordData);
|
|
|
+ if ($validation !== true) {
|
|
|
+ throw new Exception($validation);
|
|
|
+ }
|
|
|
+
|
|
|
+ LotteryUserChanceRecord::create($recordData);
|
|
|
+
|
|
|
+ Db::commit();
|
|
|
+ return $chance;
|
|
|
+
|
|
|
+ } catch (Exception $e) {
|
|
|
+ Db::rollback();
|
|
|
+ throw $e;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 使用抽奖机会
|
|
|
+ *
|
|
|
+ * @param LotteryUserChance $userChance 用户机会对象
|
|
|
+ * @param int $times 使用次数
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function useChance(LotteryUserChance $userChance, $times = 1)
|
|
|
+ {
|
|
|
+ if ($userChance->remain_chances < $times) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $userChance->used_chances += $times;
|
|
|
+ $userChance->remain_chances -= $times;
|
|
|
+ $userChance->last_use_time = time();
|
|
|
+
|
|
|
+ return $userChance->save();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查是否有剩余机会
|
|
|
+ *
|
|
|
+ * @param LotteryUserChance $userChance 用户机会对象
|
|
|
+ * @param int $times 需要的机会次数
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function hasChance(LotteryUserChance $userChance, $times = 1)
|
|
|
+ {
|
|
|
+ return $userChance->remain_chances >= $times;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重置抽奖机会(用于测试或特殊情况)
|
|
|
+ *
|
|
|
+ * @param LotteryUserChance $userChance 用户机会对象
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function resetChance(LotteryUserChance $userChance)
|
|
|
+ {
|
|
|
+ $userChance->used_chances = 0;
|
|
|
+ $userChance->remain_chances = $userChance->total_chances;
|
|
|
+ return $userChance->save();
|
|
|
+ }
|
|
|
+
|
|
|
+ // ============ 统计和查询方法 ============
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取活动总参与人数
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @return int
|
|
|
+ */
|
|
|
+ public static function getActivityParticipants($activityId)
|
|
|
+ {
|
|
|
+ return LotteryUserChance::where('activity_id', $activityId)->count();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户在多个活动中的机会统计
|
|
|
+ *
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @param array $activityIds 活动ID数组
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function getUserChancesStats($userId, $activityIds = [])
|
|
|
+ {
|
|
|
+ $query = LotteryUserChance::where('user_id', $userId);
|
|
|
+
|
|
|
+ if (!empty($activityIds)) {
|
|
|
+ $query->where('activity_id', 'in', $activityIds);
|
|
|
+ }
|
|
|
+
|
|
|
+ return $query->field([
|
|
|
+ 'activity_id',
|
|
|
+ 'total_chances',
|
|
|
+ 'used_chances',
|
|
|
+ 'remain_chances'
|
|
|
+ ])
|
|
|
+ ->select();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户在所有活动中的机会概览
|
|
|
+ *
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function getUserAllChancesOverview($userId)
|
|
|
+ {
|
|
|
+ $chances = LotteryUserChance::where('user_id', $userId)
|
|
|
+ ->with(['activity'])
|
|
|
+ ->select();
|
|
|
+
|
|
|
+ $overview = [
|
|
|
+ 'total_activities' => count($chances),
|
|
|
+ 'total_chances' => 0,
|
|
|
+ 'total_used' => 0,
|
|
|
+ 'total_remain' => 0,
|
|
|
+ 'activities' => []
|
|
|
+ ];
|
|
|
+
|
|
|
+ foreach ($chances as $chance) {
|
|
|
+ $overview['total_chances'] += $chance->total_chances;
|
|
|
+ $overview['total_used'] += $chance->used_chances;
|
|
|
+ $overview['total_remain'] += $chance->remain_chances;
|
|
|
+
|
|
|
+ $overview['activities'][] = [
|
|
|
+ 'activity_id' => $chance->activity_id,
|
|
|
+ 'activity_name' => $chance->activity->name ?? '',
|
|
|
+ 'total_chances' => $chance->total_chances,
|
|
|
+ 'used_chances' => $chance->used_chances,
|
|
|
+ 'remain_chances' => $chance->remain_chances,
|
|
|
+ 'last_get_time' => $chance->last_get_time,
|
|
|
+ 'last_use_time' => $chance->last_use_time
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ return $overview;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查用户是否可以参与活动
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function canUserParticipate($activityId, $userId)
|
|
|
+ {
|
|
|
+ $userChance = static::getUserChance($activityId, $userId);
|
|
|
+ return $userChance && static::hasChance($userChance, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取活动参与用户列表
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @param int $page 页码
|
|
|
+ * @param int $limit 每页数量
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function getActivityParticipantsList($activityId, $page = 1, $limit = 20)
|
|
|
+ {
|
|
|
+ return LotteryUserChance::where('activity_id', $activityId)
|
|
|
+ ->with(['user'])
|
|
|
+ ->order('createtime', 'desc')
|
|
|
+ ->page($page, $limit)
|
|
|
+ ->select();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取活动参与统计
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function getActivityParticipationStats($activityId)
|
|
|
+ {
|
|
|
+ $stats = LotteryUserChance::where('activity_id', $activityId)
|
|
|
+ ->field([
|
|
|
+ 'COUNT(*) as total_participants',
|
|
|
+ 'SUM(total_chances) as total_chances_granted',
|
|
|
+ 'SUM(used_chances) as total_chances_used',
|
|
|
+ 'SUM(remain_chances) as total_chances_remain'
|
|
|
+ ])
|
|
|
+ ->find();
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'total_participants' => $stats['total_participants'] ?? 0,
|
|
|
+ 'total_chances_granted' => $stats['total_chances_granted'] ?? 0,
|
|
|
+ 'total_chances_used' => $stats['total_chances_used'] ?? 0,
|
|
|
+ 'total_chances_remain' => $stats['total_chances_remain'] ?? 0,
|
|
|
+ 'usage_rate' => $stats['total_chances_granted'] > 0 ?
|
|
|
+ round(($stats['total_chances_used'] / $stats['total_chances_granted']) * 100, 2) : 0
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // ============ 批量操作方法 ============
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量创建用户机会(用于活动启动时)
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @param array $userIds 用户ID数组
|
|
|
+ * @param int $times 机会次数
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function batchCreateChances($activityId, $userIds, $times = 1)
|
|
|
+ {
|
|
|
+ if (empty($userIds)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $data = [];
|
|
|
+ $now = time();
|
|
|
+
|
|
|
+ foreach ($userIds as $userId) {
|
|
|
+ $data[] = [
|
|
|
+ 'activity_id' => $activityId,
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'total_chances' => $times,
|
|
|
+ 'used_chances' => 0,
|
|
|
+ 'remain_chances' => $times,
|
|
|
+ 'last_get_time' => $now,
|
|
|
+ 'createtime' => $now,
|
|
|
+ 'updatetime' => $now
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ return LotteryUserChance::insertAll($data);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量检查用户资格
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @param array $userIds 用户ID数组
|
|
|
+ * @return array 符合条件的用户ID数组
|
|
|
+ */
|
|
|
+ public static function batchCheckUserQualification($activityId, $userIds)
|
|
|
+ {
|
|
|
+ $activity = LotteryActivity::find($activityId);
|
|
|
+ if (!$activity) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ $qualifiedUsers = [];
|
|
|
+
|
|
|
+ foreach ($userIds as $userId) {
|
|
|
+ if (static::checkUserQualification($activity, $userId)) {
|
|
|
+ $qualifiedUsers[] = $userId;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $qualifiedUsers;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量验证条件
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @param array $orderInfo 订单信息
|
|
|
+ * @param array $userIds 用户ID数组
|
|
|
+ * @return array 每个用户满足的条件
|
|
|
+ */
|
|
|
+ public static function batchValidateConditionsForUsers($activityId, $orderInfo, $userIds)
|
|
|
+ {
|
|
|
+ $results = [];
|
|
|
+
|
|
|
+ foreach ($userIds as $userId) {
|
|
|
+ $results[$userId] = static::batchValidateConditions($activityId, $orderInfo, $userId);
|
|
|
+ }
|
|
|
+
|
|
|
+ return $results;
|
|
|
+ }
|
|
|
+
|
|
|
+ // ============ 机会获取记录管理方法 ============
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户机会获取记录
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @param int $page 页码
|
|
|
+ * @param int $limit 每页数量
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function getUserChanceRecords($activityId, $userId, $page = 1, $limit = 20)
|
|
|
+ {
|
|
|
+ return LotteryUserChanceRecord::getUserChanceRecords($activityId, $userId, $page, $limit);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取活动机会获取统计
|
|
|
+ *
|
|
|
+ * @param int $activityId 活动ID
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function getActivityChanceRecordStats($activityId)
|
|
|
+ {
|
|
|
+ return LotteryUserChanceRecord::getActivityChanceStats($activityId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户机会获取统计
|
|
|
+ *
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @param int $activityId 活动ID(可选)
|
|
|
+ * @return array
|
|
|
+ */
|
|
|
+ public static function getUserChanceRecordStats($userId, $activityId = null)
|
|
|
+ {
|
|
|
+ return LotteryUserChanceRecord::getUserChanceStats($userId, $activityId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量创建机会获取记录
|
|
|
+ *
|
|
|
+ * @param array $records 记录数组
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function batchCreateChanceRecords($records)
|
|
|
+ {
|
|
|
+ return LotteryUserChanceRecord::batchCreateRecords($records);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 验证机会获取记录数据
|
|
|
+ *
|
|
|
+ * @param array $data 记录数据
|
|
|
+ * @return bool|string
|
|
|
+ */
|
|
|
+ public static function validateChanceRecord($data)
|
|
|
+ {
|
|
|
+ return LotteryUserChanceRecord::validateRecord($data);
|
|
|
+ }
|
|
|
+}
|