user(); if ($user) { $locale = GlobalUserInfo::getLocaleByUserID($user->UserID, 'en'); App::setLocale($locale); } } // 充值记录 public function orderList(Request $request) { $user_id = (int)$request->globalUser->UserID;//$request->get('user_id', 1); $page = $request->get('page', 1); $pageSize = $request->get('pageSize', 20); $redisKey = 'PayRecharge_orderList_'.$user_id; if (!SetNXLock::getExclusiveLock($redisKey)) { return apiReturnFail(['web.withdraw.try_again_later','Tente novamente mais tarde']); } $where[] = ['user_id', $user_id]; $where[] = ['pay_status', 1]; $cacheTime = 60 * rand(1, 2); // $list = cache()->remember($user_id . '_order_list', $cacheTime, function () use ($where, $pageSize) { // // return Order::where($where) // ->orderBy('finished_at', 'desc') // ->selectRaw('amount,payment_code,order_sn as payment_sn,finished_at,created_at,pay_status') // ->paginate(15,['*'],'page',1); // }); $list = Order::query()->where($where) ->orderBy('finished_at', 'desc') ->where('finished_at', '>=', date('Y-m-d', strtotime('-7 day'))) ->selectRaw('amount,payment_code,order_sn as payment_sn,finished_at,created_at,pay_status,type') ->paginate($pageSize); // ->paginate(15,['*'],'page',1); foreach ($list as &$val) { $val->amount = number_format($val->amount, 2, '.', ''); } SetNXLock::release($redisKey); return apiReturnSuc($list); } // 首充 public function firstPay(Request $request) { $user = $request->user(); $user_recharge = DB::table(TableName::QPAccountsDB() . 'YN_VIPAccount') ->where('UserID', $user->UserID) ->value('Recharge') ?: 0; if($user_recharge)return apiReturnSuc(); $firstPayGift = DB::table('agent.dbo.recharge_gift') ->where('gift_id', 301)->first(); if(!$firstPayGift) return apiReturnFail(); $names = DB::table('agent.dbo.admin_configs') ->where([ 'type' => 'pay_method', 'status' => 1, ]) ->selectRaw('id, name, status, new_pay_type as type') ->orderByDesc('sort')->get()->toArray(); $list = DB::table('agent.dbo.recharge_gear') ->select('id','money','favorable_price','give') ->orderBy('money', 'asc')->where('status', 1)->get(); $gear = Util::filterGearByDevice(\GuzzleHttp\json_encode($names)); foreach ($list as &$val) { $val->favorable_price = $val->favorable_price + $val->give; $val->gear = $gear; $val->recommend = 0; if($val->money == $firstPayGift->recommend){ $val->recommend = 1; } } return apiReturnSuc(compact('list', 'firstPayGift')); } // 首充礼包(带倒计时逻辑) public function firstPayGift(Request $request) { $user = $request->user(); $this->setUserLocale($request); // 获取礼包配置 $giftConfig = DB::table('agent.dbo.recharge_gift') ->where('gift_id', 301) ->first(); if (!$giftConfig) { return apiReturnFail(['web.gift.config_not_exists', __('web.gift.config_not_exists')]); } // 检查用户是否购买了首充礼包 $giftRecord = DB::table('agent.dbo.first_pay_gift_records') ->where('user_id', $user->UserID) ->first(); // ========== 未购买礼包:返回充值列表 + 礼包配置 + 倒计时 ========== if (!$giftRecord) { // 获取充值档位列表 $list = DB::table('agent.dbo.recharge_gear') ->select('money', 'favorable_price', 'give', 'gear') ->orderBy('money', 'asc') ->where('status', 1) ->where('in_shop', 1) ->get(); foreach ($list as &$val) { $val->favorable_price = $val->favorable_price + $val->give; $val->recommend = 0; if ($val->money == $giftConfig->recommend) { $val->recommend = 1; } if (!empty($val->gear)) { $val->gear = Util::filterGearByDevice($val->gear,GlobalUserInfo::toWebData($user)); } } // ========== 处理倒计时逻辑(仅未购买时) ========== $redisKey = "first_pay_gift_timer_{$user->UserID}"; $currentTime = time(); $timeLeft = 0; $timerData = Redis::get($redisKey); if ($timerData) { $timerData = json_decode($timerData, true); $firstRequestTime = $timerData['first_request_time']; $phase = $timerData['phase']; // 阶段1:valid_h倒计时 if ($phase === 'first') { $expireTime = $firstRequestTime + ($giftConfig->valid_h * 3600); if ($currentTime >= $expireTime) { $expireDate = date('Y-m-d', $expireTime); $currentDate = date('Y-m-d', $currentTime); if ($expireDate !== $currentDate) { // 进入阶段2 $nextDayStart = time(); $newExpireTime = $nextDayStart + ($giftConfig->valid_h_2 * 3600); $newTimerData = [ 'first_request_time' => $firstRequestTime, 'phase' => 'daily', 'current_cycle_start' => $nextDayStart, 'last_expire_time' => $newExpireTime ]; Redis::set($redisKey, json_encode($newTimerData)); $timeLeft = max(0, $newExpireTime - $currentTime); } } else { $timeLeft = $expireTime - $currentTime; } } // 阶段2:每日循环 elseif ($phase === 'daily') { $currentCycleStart = $timerData['current_cycle_start']; $expireTime = $currentCycleStart + ($giftConfig->valid_h_2 * 3600); if ($currentTime >= $expireTime) { $expireDate = date('Y-m-d', $expireTime); $currentDate = date('Y-m-d', $currentTime); if ($expireDate !== $currentDate) { $todayStart = time(); $newExpireTime = $todayStart + ($giftConfig->valid_h_2 * 3600); $newTimerData = [ 'first_request_time' => $firstRequestTime, 'phase' => 'daily', 'current_cycle_start' => $todayStart, 'last_expire_time' => $newExpireTime ]; Redis::set($redisKey, json_encode($newTimerData)); $timeLeft = max(0, $newExpireTime - $currentTime); } } else { $timeLeft = $expireTime - $currentTime; } } } else { // 首次请求,初始化倒计时 $expireTime = $currentTime + ($giftConfig->valid_h * 3600); $timerData = [ 'first_request_time' => $currentTime, 'phase' => 'first', 'last_expire_time' => $expireTime ]; Redis::set($redisKey, json_encode($timerData)); $timeLeft = $giftConfig->valid_h * 3600; } return apiReturnSuc([ 'has_purchased' => false, // 未购买标记 'list' => $list, // 充值档位列表 'gift_info' => [ 'gift_id' => $giftConfig->gift_id, 'gift_name' => $giftConfig->gift_name, 'total_bonus' => $giftConfig->total_bonus, 'bonus_instantly' => $giftConfig->bonus_instantly, 'day_rewards' => $giftConfig->day_rewards ? json_decode($giftConfig->day_rewards) : null, 'betting_bonus' => $giftConfig->betting_bonus ? json_decode($giftConfig->betting_bonus) : null, 'betting_task' => $giftConfig->betting_task ? json_decode($giftConfig->betting_task) : null, ], 'time_left' => $timeLeft, // ✅ 倒计时(未购买时展示) 'expire_at' => time() + $timeLeft // ✅ 过期时间戳 ]); } // ========== 已购买礼包:返回任务进度(无倒计时) ========== // 获取用户当前累计下注次数(从RecordUserGameCount表) $currentTotalBetCount = DB::table(TableName::QPRecordDB() . 'RecordUserGameCount') ->where('UserID', $user->UserID) ->sum('Cnt') ?? 0; // 获取用户当前累计下注金额(从统计表,用于下注任务) $userStats = DB::table('QPRecordDB.dbo.RecordUserTotalStatistics') ->where('UserID', $user->UserID) ->first(); $currentTotalBetAmount = $userStats->TotalBet ?? 0; // 更新下注进度到礼包记录(betting_current_bet存储下注次数,用于下注奖励) DB::table('agent.dbo.first_pay_gift_records') ->where('user_id', $user->UserID) ->update([ 'betting_current_bet' => $currentTotalBetCount, 'updated_at' => date('Y-m-d H:i:s') ]); // 重新获取最新记录 $giftRecord = DB::table('agent.dbo.first_pay_gift_records') ->where('user_id', $user->UserID) ->first(); // 解析任务数据 $dayRewardsData = $giftRecord->day_rewards_data ? json_decode($giftRecord->day_rewards_data, true) : null; $bettingBonusData = $giftRecord->betting_bonus_data ? json_decode($giftRecord->betting_bonus_data, true) : null; $bettingTaskData = $giftRecord->betting_task_data ? json_decode($giftRecord->betting_task_data, true) : null; // 计算当前是购买后的第几天(所有任务都需要用到) $purchaseDate = date('Y-m-d', strtotime($giftRecord->created_at)); $today = date('Y-m-d'); $daysPassed = floor((strtotime($today) - strtotime($purchaseDate)) / 86400); // 构建返回数据 $giftInfo = [ 'gift_id' => $giftRecord->gift_id, 'gift_name' => $giftRecord->gift_name, 'total_bonus' => (float)$giftRecord->total_bonus, 'bonus_instantly' => (float)$giftRecord->bonus_instantly, 'pay_amount' => (float)$giftRecord->pay_amount, ]; // 每日奖励进度 if ($dayRewardsData) { $startDay = $dayRewardsData['start_day'] ?? 1; $bonusDay = $dayRewardsData['bonus_day'] ?? 0; $claimedDays = $giftRecord->day_rewards_claimed; // $startDay = $startDay-1; // 判断每日奖励状态 // 0=不可领取, 1=可领取, 2=已领取, 3=过期 $dayRewardStatus = 0; // 默认不可领取 // 检查是否过期(购买后7天) if ($daysPassed >= 7) { $dayRewardStatus = 3; // 过期 } elseif ($daysPassed >= $startDay-1) { // 计算今天是第几个奖励日(从起始天数开始) $rewardIndex = $daysPassed - ($startDay-1); if ($rewardIndex < $bonusDay) { // 在奖励期内 if ($claimedDays > $rewardIndex) { $dayRewardStatus = 2; // 已领取 } else { // 即便前几天漏领,后续奖励仍可继续领取(漏掉的视为作废) $dayRewardStatus = 1; // 可领取 } } else { // 超过奖励天数 $dayRewardStatus = 2; // 已领取完 } } $giftInfo['day_rewards'] = [ 'total_bonus' => (float)$giftRecord->day_rewards_total, 'bonus_day' => $bonusDay, 'start_day' => $startDay, 'bonus' => $dayRewardsData['bonus'] ?? [], 'daysPassed' => $daysPassed, 'claimed_days' => $claimedDays, 'progress' => $claimedDays . '/' . $bonusDay, 'status' => $dayRewardStatus, // 0=不可领取, 1=可领取, 2=已领取, 3=过期 'status_text' => [ __('web.gift.status_cannot_claim'), __('web.gift.status_can_claim'), __('web.gift.status_claimed'), __('web.gift.status_expired') ][$dayRewardStatus] ?? __('web.gift.status_unknown') ]; } // 下注奖励进度(使用下注次数) if ($bettingBonusData) { $perBet = $bettingBonusData['per_bet'] ?? 100; // 每次下注次数要求 $perBetBonus = $bettingBonusData['per_bet_bonus'] ?? 2; // 每次奖励金额(不是百分比) $currentBetCount = $giftRecord->betting_current_bet; // 当前累计下注次数 $totalBonusLimit = $giftRecord->betting_bonus_total; // 总奖励上限 $claimedAmount = $giftRecord->betting_bonus_claimed; // 已领取金额 $remainingBonus = $totalBonusLimit - $claimedAmount; // 剩余可领取金额 // 每次可领取的金额(直接使用配置的值,不是百分比计算) $perReward = (float)$perBetBonus; // 根据当前下注次数计算已达成的次数 $completedTimes = floor($currentBetCount / $perBet); // 已领取的次数 $claimedTimes = $claimedAmount > 0 ? floor($claimedAmount / $perReward) : 0; // 当前可领取次数(但不能超过剩余总额) $canClaimTimes = $completedTimes - $claimedTimes; $maxCanClaimTimes = floor($remainingBonus / $perReward); // 剩余总额最多可领次数 $canClaimTimes = min($canClaimTimes, $maxCanClaimTimes); // 当前可领取金额 $canClaimAmount = min($canClaimTimes * $perReward, $remainingBonus); // 计算下次领取需要的下注次数 $nextClaimBet = 0; if ($remainingBonus > 0 && $canClaimTimes == 0) { // 还有剩余奖励但当前不能领取,计算还需下注多少次 $nextClaimBet = ($claimedTimes + 1) * $perBet - $currentBetCount; } // 判断下注奖励状态 // 0=不可领取(可领取金额为0), 1=可领取, 2=已领取(所有奖励都领完), 3=过期 $bettingBonusStatus = 0; // 默认不可领取 // 检查是否过期(购买后7天) if ($daysPassed >= 7) { $bettingBonusStatus = 3; // 过期 } elseif ($remainingBonus <= 0) { $bettingBonusStatus = 2; // 已领取完 } elseif ($canClaimAmount > 0) { $bettingBonusStatus = 1; // 可领取 } else { $bettingBonusStatus = 0; // 不可领取(下注次数不足) } $giftInfo['betting_bonus'] = [ 'total_bonus' => (float)$totalBonusLimit, // 总奖励上限 'per_bet' => $perBet, // 每次下注次数要求 'per_bet_bonus' => $perReward, // 每次奖励金额(实际金额) // 'per_reward' => $perReward, // 每次奖励金额(保持兼容) 'current_bet' => (float)$currentBetCount, // 当前累计下注次数 'claimed_amount' => (float)$claimedAmount, // 已领取金额 'remaining_bonus' => (float)$remainingBonus, // 剩余可领金额 'can_claim_amount' => (float)$canClaimAmount, // 当前可领取金额 'can_claim_times' => max(0, $canClaimTimes), // 当前可领取次数 'next_claim_bet' => max(0, $nextClaimBet), // 下次领取还需下注次数 'progress' => round($currentBetCount, 0) . '/' . round($claimedTimes * $perBet + $perBet, 0), // 当前进度/下次领取目标(次数) 'status' => $bettingBonusStatus, // 0=不可领取, 1=可领取, 2=已领取, 3=过期 'status_text' => [ __('web.gift.status_cannot_claim'), __('web.gift.status_can_claim'), __('web.gift.status_claimed'), __('web.gift.status_expired') ][$bettingBonusStatus] ?? __('web.gift.status_unknown') ]; } // 下注任务进度(使用下注金额) if ($bettingTaskData) { $betPayTimes = $bettingTaskData['bet_pay_times'] ?? 60; $requiredBet = $giftRecord->pay_amount * $betPayTimes; $currentProgress = $currentTotalBetAmount / NumConfig::NUM_VALUE; // 使用下注金额,不是次数 $taskCompleted = $currentProgress >= $requiredBet; $isClaimed = $giftRecord->betting_task_claimed == 1; // 判断下注任务状态 // 0=不可领取, 1=可领取, 2=已领取, 3=过期 $bettingTaskStatus = 0; // 默认不可领取 // 检查是否过期(购买后7天) if ($daysPassed >= 7) { $bettingTaskStatus = 3; // 过期 } elseif ($isClaimed) { $bettingTaskStatus = 2; // 已领取 } elseif ($taskCompleted) { $bettingTaskStatus = 1; // 可领取(任务完成且未领取) } else { $bettingTaskStatus = 0; // 不可领取(任务未完成) } $giftInfo['betting_task'] = [ 'total_bonus' => (float)$giftRecord->betting_task_total, 'bet_pay_times' => $betPayTimes, 'required_bet' => $requiredBet, // 需要下注的金额 'current_bet' => (float)$currentProgress, // 当前累计下注 'progress' => round($currentProgress, 2) . '/' . $requiredBet, 'status' => $bettingTaskStatus, // 0=不可领取, 1=可领取, 2=已领取, 3=过期 'status_text' => [ __('web.gift.status_cannot_claim'), __('web.gift.status_can_claim'), __('web.gift.status_claimed'), __('web.gift.status_expired') ][$bettingTaskStatus] ?? __('web.gift.status_unknown') ]; } $giftInfo['expired'] = strtotime(date('Y-m-d',strtotime($giftRecord->created_at)))+86400*7; return apiReturnSuc([ 'has_purchased' => true, // 已购买标记 'gift_info' => $giftInfo // ✅ 已购买用户不返回倒计时 ]); } /** * 领取首充礼包奖励 */ public function claimFirstPayGiftReward(Request $request) { $user = $request->user(); $userId = $user->UserID; $rewardType = $request->input('reward_type'); // 'day_reward', 'betting_bonus', 'betting_task' $this->setUserLocale($request); // 获取礼包记录 $giftRecord = DB::table('agent.dbo.first_pay_gift_records') ->where('user_id', $userId) ->first(); if (!$giftRecord) { return apiReturnFail(['web.gift.not_purchased', __('web.gift.not_purchased')]); } $rewardAmount = 0; try { // 每日奖励领取 if ($rewardType === 'day_reward') { $dayRewardsData = json_decode($giftRecord->day_rewards_data, true); if (!$dayRewardsData) { return apiReturnFail(['web.gift.no_day_rewards_config', __('web.gift.no_day_rewards_config')]); } $bonusDay = $dayRewardsData['bonus_day'] ?? 0; $startDay = $dayRewardsData['start_day'] ?? 1; $bonusArray = $dayRewardsData['bonus'] ?? []; $claimedDays = $giftRecord->day_rewards_claimed; // 检查是否还有可领取的天数 if ($claimedDays >= $bonusDay) { return apiReturnFail(['web.gift.day_rewards_all_claimed', __('web.gift.day_rewards_all_claimed')]); } // 计算当前是购买后的第几天 $purchaseDate = date('Y-m-d', strtotime($giftRecord->created_at)); $currentDate = date('Y-m-d'); $daysPassed = floor((strtotime($currentDate) - strtotime($purchaseDate)) / 86400); // 检查是否到了可以领取的天数(从第start_day天开始) if ($daysPassed < $startDay-1) { return apiReturnFail(['web.gift.day_rewards_not_time', str_replace(':day', $startDay, __('web.gift.day_rewards_not_time'))]); } // 计算今天应该领取第几天的奖励 // 例如:start_day=2,今天是第3天,应该领取第1个奖励(索引0) $todayRewardIndex = $daysPassed - ($startDay-1); // 检查是否超过奖励天数 if ($todayRewardIndex >= $bonusDay) { return apiReturnFail(['web.gift.day_rewards_expired', __('web.gift.day_rewards_expired')]); } // 检查今天是否已领取 $lastClaimDate = $giftRecord->day_last_claim_date; if ($lastClaimDate && $lastClaimDate === $currentDate) { return apiReturnFail(['web.gift.day_rewards_claimed_today', __('web.gift.day_rewards_claimed_today')]); } // 检查是否跳过了某些天(过期不补领) // 如果今天应该领第5天的奖励,但用户只领了3天,那就直接领第5天的 if ($todayRewardIndex > $claimedDays) { // 跳过了一些天,更新已领取天数为今天的索引 $claimedDays = $todayRewardIndex; } // 计算今天可领取的奖励(使用todayRewardIndex作为索引) $todayBonusPercent = $bonusArray[$todayRewardIndex] ?? 0; $rewardAmount = round($giftRecord->pay_amount * $todayBonusPercent / 100, 2); // 更新记录 DB::table('agent.dbo.first_pay_gift_records') ->where('user_id', $userId) ->update([ 'day_rewards_claimed' => $todayRewardIndex + 1, // 已领取到第几天(索引+1) 'day_last_claim_date' => $currentDate, 'updated_at' => date('Y-m-d H:i:s') ]); } // 下注奖励领取(使用下注次数) elseif ($rewardType === 'betting_bonus') { $bettingBonusData = json_decode($giftRecord->betting_bonus_data, true); if (!$bettingBonusData) { return apiReturnFail(['web.gift.no_betting_bonus_config', __('web.gift.no_betting_bonus_config')]); } // 检查是否过期(购买后7天) $purchaseDate = date('Y-m-d', strtotime($giftRecord->created_at)); $currentDate = date('Y-m-d'); $daysPassed = floor((strtotime($currentDate) - strtotime($purchaseDate)) / 86400); if ($daysPassed >= 7) { return apiReturnFail(['web.gift.betting_bonus_expired', __('web.gift.betting_bonus_expired')]); } // 获取最新的下注次数 $currentBetCount = DB::table(TableName::QPRecordDB() . 'RecordUserGameCount') ->where('UserID', $userId) ->sum('Cnt') ?? 0; $perBet = $bettingBonusData['per_bet'] ?? 100; // 每次下注次数要求 $perBetBonus = $bettingBonusData['per_bet_bonus'] ?? 2; // 每次奖励金额(不是百分比) $totalBonusLimit = $giftRecord->betting_bonus_total; // 总奖励上限 $claimedAmount = $giftRecord->betting_bonus_claimed; // 已领取金额 $remainingBonus = $totalBonusLimit - $claimedAmount; // 剩余可领金额 // 检查是否还有剩余奖励 if ($remainingBonus <= 0) { return apiReturnFail(['web.gift.betting_bonus_all_claimed', __('web.gift.betting_bonus_all_claimed')]); } // 每次可领取的金额(直接使用配置的值,不是百分比计算) $perReward = (float)$perBetBonus; // 根据当前下注次数计算已达成的次数 $completedTimes = floor($currentBetCount / $perBet); // 已领取的次数 $claimedTimes = $claimedAmount > 0 ? floor($claimedAmount / $perReward) : 0; // 可领取次数(下注达成的次数 - 已领取次数) $canClaimTimes = $completedTimes - $claimedTimes; // 检查是否可以领取 if ($canClaimTimes <= 0) { $neededBets = (($claimedTimes + 1) * $perBet - $currentBetCount); return apiReturnFail(['web.gift.betting_bonus_insufficient', str_replace(':times', $neededBets, __('web.gift.betting_bonus_insufficient'))]); } // ✅ 一次性领取所有已达成的奖励(但不能超过剩余总额) $totalCanClaimAmount = $canClaimTimes * $perReward; // 理论可领取总额 $rewardAmount = min($totalCanClaimAmount, $remainingBonus); // 实际领取金额(不超过剩余总额) $actualClaimTimes = floor($rewardAmount / $perReward); // 实际领取次数 // 更新记录(同时更新下注次数) DB::table('agent.dbo.first_pay_gift_records') ->where('user_id', $userId) ->update([ 'betting_bonus_claimed' => $giftRecord->betting_bonus_claimed + $rewardAmount, 'betting_current_bet' => $currentBetCount, // 更新最新下注次数 'updated_at' => date('Y-m-d H:i:s') ]); \Log::info('下注奖励领取', [ 'user_id' => $userId, 'can_claim_times' => $canClaimTimes, 'actual_claim_times' => $actualClaimTimes, 'reward_amount' => $rewardAmount ]); } // 下注任务领取(使用下注金额) elseif ($rewardType === 'betting_task') { if ($giftRecord->betting_task_claimed == 1) { return apiReturnFail(['web.gift.betting_task_claimed', __('web.gift.betting_task_claimed')]); } $bettingTaskData = json_decode($giftRecord->betting_task_data, true); if (!$bettingTaskData) { return apiReturnFail(['web.gift.no_betting_task_config', __('web.gift.no_betting_task_config')]); } // 检查是否过期(购买后7天) $purchaseDate = date('Y-m-d', strtotime($giftRecord->created_at)); $currentDate = date('Y-m-d'); $daysPassed = floor((strtotime($currentDate) - strtotime($purchaseDate)) / 86400); if ($daysPassed >= 7) { return apiReturnFail(['web.gift.betting_task_expired', __('web.gift.betting_task_expired')]); } // 获取最新的下注金额 $userStats = DB::table('QPRecordDB.dbo.RecordUserTotalStatistics') ->where('UserID', $userId) ->first(); $currentBetAmount = ($userStats->TotalBet ?? 0) / NumConfig::NUM_VALUE; $betPayTimes = $bettingTaskData['bet_pay_times'] ?? 60; $requiredBet = $giftRecord->pay_amount * $betPayTimes; if ($currentBetAmount < $requiredBet) { return apiReturnFail(['web.gift.betting_task_insufficient', str_replace(':amount', $requiredBet, __('web.gift.betting_task_insufficient'))]); } $rewardAmount = $giftRecord->betting_task_total; // 更新记录 DB::table('agent.dbo.first_pay_gift_records') ->where('user_id', $userId) ->update([ 'betting_task_claimed' => 1, 'updated_at' => date('Y-m-d H:i:s') ]); } else { return apiReturnFail(['web.gift.invalid_reward_type', __('web.gift.invalid_reward_type')]); } // 添加奖励到用户账户 if ($rewardAmount > 0) { OuroGameService::AddScore($userId, $rewardAmount * NumConfig::NUM_VALUE, 52, true); // 52=首充礼包奖励 app(PaidRewardStatisticsService::class) ->incrementRecordByDateIDAndType(date('Ymd'), 'first_recharge_claim', $rewardAmount * NumConfig::NUM_VALUE); \Log::info('首充礼包奖励领取', [ 'user_id' => $userId, 'reward_type' => $rewardType, 'amount' => $rewardAmount ]); } return apiReturnSuc([ 'amount' => $rewardAmount, 'message' => str_replace(':amount', $rewardAmount, __('web.gift.claim_success')) ]); } catch (\Exception $e) { \Log::error('首充礼包奖励领取失败', [ 'user_id' => $userId, 'error' => $e->getMessage() ]); return apiReturnFail(['web.gift.claim_failed', str_replace(':error', $e->getMessage(), __('web.gift.claim_failed'))]); } } /** * 获取首充礼包数据(包含充值档位列表) * @param $firstPayGift 礼包配置 * @param $timeLeft 剩余秒数(已经是用户实际剩余时间) */ private function getFirstPayGiftData($firstPayGift, $timeLeft) { // 获取支付方式 // $names = DB::table('agent.dbo.admin_configs') // ->where([ // 'type' => 'pay_method', // 'status' => 1, // ]) // ->selectRaw('id, name, status, new_pay_type as type') // ->orderByDesc('sort') // ->get() // ->toArray(); // 获取充值档位 $list = DB::table('agent.dbo.recharge_gear') ->select('money', 'favorable_price', 'give','gear') ->orderBy('money', 'asc') ->where('status', 1) ->where('in_shop', 1) ->get(); // $gear = \GuzzleHttp\json_encode($names); foreach ($list as &$val) { $val->favorable_price = $val->favorable_price + $val->give; // $val->gear = $gear; $val->recommend = 0; if ($val->money == $firstPayGift->recommend) { $val->recommend = 1; } if (!empty($val->gear)) { $val->gear = Util::filterGearByDevice($val->gear); } } return apiReturnSuc([ 'list' => $list, 'gift_info' => [ 'gift_id' => $firstPayGift->gift_id, 'gift_name' => $firstPayGift->gift_name, 'total_bonus' => $firstPayGift->total_bonus, 'bonus_instantly' => $firstPayGift->bonus_instantly, 'day_rewards' => $firstPayGift->day_rewards?json_decode($firstPayGift->day_rewards):'', 'betting_bonus' => $firstPayGift->betting_bonus?json_decode($firstPayGift->betting_bonus):'', 'betting_task' => $firstPayGift->betting_task?json_decode($firstPayGift->betting_task):'', ], 'time_left' => $timeLeft, // 剩余秒数 'expire_at' => time() + $timeLeft // 过期时间戳 ]); } public function firstPayMulti(Request $request) { $user = LoginController::checkLogin($request); if($user){ if(env('CONFIG_24680_NFTD_99',0)==0)if($user->Channel==99)return apiReturnFail(); $fpkey='Firstpay_'.$user->UserID; if(Redis::exists($fpkey)){ $data=Redis::get($fpkey); $data=json_decode($data,true); $data['timeleft']=86400-(time()-$data['buytime']); return apiReturnSuc(['leftitem'=>$data]); } $user_recharge = DB::table(TableName::QPAccountsDB() . 'YN_VIPAccount') ->where('UserID', $user->UserID) ->value('Recharge') ?: 0; if($user_recharge)return apiReturnFail(); } $items=DB::table('agent.dbo.recharge_gear') ->where('status',1) ->where('second_give','>',0) ->where('first_pay','>=', 1) ->select('gift_id','money','give','favorable_price','second_give')->get()->each(function($item){ $item->id=28; })->toArray(); $default=count($items)-1; return apiReturnSuc(compact('items','default')); } // 破产礼包 public function bankruptcyGift(Request $request) { $user = $request->user(); $this->setUserLocale($request); // 判断用户是否充值 $user_recharge = DB::table(TableName::QPAccountsDB() . 'YN_VIPAccount') ->where('UserID', $user->UserID) ->value('Recharge') ?: 0; if ($user_recharge <= 0) { return apiReturnFail(['web.gift.user_not_recharged', __('web.gift.user_not_recharged')]); } // 获取所有破产礼包配置 (gift_id=302) $bankruptcyGifts = DB::table('agent.dbo.recharge_gift') ->where('gift_id', 302) ->get(); if ($bankruptcyGifts->isEmpty()) { return apiReturnFail(['web.gift.bankruptcy_gift_not_exists', __('web.gift.bankruptcy_gift_not_exists')]); } $moneys = $bankruptcyGifts->pluck('recommend')->toArray(); foreach ($moneys as $k => $v) { $moneys[$k]=round($v, 2); } $paidAmounts = DB::table('agent.dbo.order') ->where(['user_id' => $user->UserID, 'pay_status' => 1, 'GiftsID' => 302]) ->whereDate('created_at', date('Y-m-d')) ->get()->pluck('amount')->toArray(); $result = []; // 遍历每条礼包配置,根据 recommend 关联 recharge_gear foreach ($bankruptcyGifts as $gift) { $gear = DB::table('agent.dbo.recharge_gear') ->select('money', 'favorable_price', 'gear') ->where('money', $gift->recommend) ->where('status', 1) ->first(); if ($gear) { $gear->gift_id = $gift->gift_id; $gear->total_bonus = $gift->total_bonus; $gear->bonus = $gift->total_bonus - 100; $gear->paidToday = in_array(round($gear->money*NumConfig::NUM_VALUE, 2), $paidAmounts); if (!empty($gear->gear)) { $gear->gear = Util::filterGearByDevice($gear->gear,GlobalUserInfo::toWebData($user)); } $result[] = $gear; } } // 按 money 排序 usort($result, function($a, $b) { return $a->money <=> $b->money; }); return apiReturnSuc($result); } // 每日首充礼包 public function dailyFirstRechargeGift(Request $request) { $user = $request->user(); $this->setUserLocale($request); // 检查用户今日是否已充值(完成任意档位充值后入口消失) $todayStart = date('Y-m-d') . ' 00:00:00'; $todayEnd = date('Y-m-d') . ' 23:59:59'; $todayRecharge = DB::table('agent.dbo.order') ->where('user_id', $user->UserID) ->where('pay_status', 1) ->where('GiftsID', 303) ->where('pay_at', '>=', $todayStart) ->where('pay_at', '<=', $todayEnd) ->first(); // 如果今日已充值,返回入口消失标记 if ($todayRecharge) { return apiReturnSuc([ 'has_recharged_today' => true, 'message' => __('web.gift.recharged_today') ]); } // 获取每日首充礼包配置 (gift_id=303) $dailyGifts = DB::table('agent.dbo.recharge_gift') ->where('gift_id', 303) ->get(); if ($dailyGifts->isEmpty()) { return apiReturnFail(['web.gift.daily_first_recharge_not_exists', __('web.gift.daily_first_recharge_not_exists')]); } $result = []; // 遍历每条礼包配置,根据 recommend 关联 recharge_gear foreach ($dailyGifts as $gift) { $gear = DB::table('agent.dbo.recharge_gear') ->select('money', 'favorable_price', 'gear', 'give') ->where('money', $gift->recommend) ->where('status', 1) ->first(); if ($gear) { $gear->gift_id = $gift->gift_id; $gear->total_bonus = $gift->total_bonus; $gear->bonus = $gift->total_bonus - 100; $gear->recommend = $gift->first_pay?1:0; if (!empty($gear->gear)) { $gear->gear = Util::filterGearByDevice($gear->gear,GlobalUserInfo::toWebData($user)); } $result[] = $gear; } } // 按 money 排序 usort($result, function($a, $b) { return $a->money <=> $b->money; }); return apiReturnSuc([ 'has_recharged_today' => false, 'list' => $result ]); } // 每日礼包(三档充值) public function dailyGift(Request $request) { $user = $request->user(); $this->setUserLocale($request); // 获取每日礼包配置 (gift_id=304),应该有3档 $dailyGifts = DB::table('agent.dbo.recharge_gift') ->where('gift_id', 304) ->orderBy('recommend', 'asc') ->get(); if ($dailyGifts->isEmpty()) { return apiReturnFail(['web.gift.daily_gift_not_exists', __('web.gift.daily_gift_not_exists')]); } if ($dailyGifts->count() > 3) { // 如果配置超过3档,只取前3档 $dailyGifts = $dailyGifts->take(3); } // 检查用户今日每档的充值状态 $todayStart = date('Y-m-d') . ' 00:00:00'; $todayEnd = date('Y-m-d') . ' 23:59:59'; $todayRecharges = DB::table('agent.dbo.order') ->where('user_id', $user->UserID) ->where('GiftsID', 304) ->where('pay_status', 1) ->where('pay_at', '>=', $todayStart) ->where('pay_at', '<=', $todayEnd) ->pluck('amount') ->toArray(); $result = []; $completedCount = 0; // 遍历每档配置 foreach ($dailyGifts as $index => $gift) { $gear = DB::table('agent.dbo.recharge_gear') ->select('money', 'favorable_price', 'gear', 'give') ->where('money', $gift->recommend) ->where('status', 1) ->first(); if ($gear) { // 检查该档位今日是否已充值(使用浮点数比较,允许小数点精度差异) $isCompleted = false; foreach ($todayRecharges as $rechargeAmount) { if (abs($rechargeAmount/100 - $gift->recommend) < 0.01) { $isCompleted = true; break; } } if ($isCompleted) { $completedCount++; } $gear->gift_id = $gift->gift_id; $gear->total_bonus = $gift->total_bonus; $gear->bonus = $gift->total_bonus - 100; $gear->is_completed = $isCompleted; // 是否已完成 $gear->gear_index = $index + 1; // 档位序号(1,2,3) $gear->recommend = $gift->first_pay?1:0; if (!empty($gear->gear)) { $gear->gear = Util::filterGearByDevice($gear->gear,GlobalUserInfo::toWebData($user)); } $result[] = $gear; } } // 获取额外奖励金额(从任意一档的 task_bonus 字段获取,task_bonus 是数字字段) $taskBonus = null; $firstGift = $dailyGifts->first(); if ($firstGift && $firstGift->task_bonus !== null) { $taskBonus = round((float)$firstGift->task_bonus, 2); } // 检查是否可以领取额外奖励(三档都完成) $canClaimBonus = ($completedCount >= 3 && $taskBonus > 0); // 检查是否已领取过额外奖励 $hasClaimedBonus = false; if ($canClaimBonus) { $redisKey = "daily_gift_bonus_claimed_{$user->UserID}_" . date('Y-m-d'); $hasClaimedBonus = Redis::exists($redisKey); } return apiReturnSuc([ 'list' => $result, 'completed_count' => $completedCount, 'total_count' => count($result), 'can_claim_bonus' => $canClaimBonus && !$hasClaimedBonus, 'has_claimed_bonus' => $hasClaimedBonus, 'task_bonus' => $taskBonus ]); } // 领取每日礼包三档完成后的额外奖励 public function claimDailyGiftBonus(Request $request) { $user = $request->user(); $userId = $user->UserID; $this->setUserLocale($request); // 检查三档是否都已完成 $todayStart = date('Y-m-d') . ' 00:00:00'; $todayEnd = date('Y-m-d') . ' 23:59:59'; // 获取每日礼包配置 $dailyGifts = DB::table('agent.dbo.recharge_gift') ->where('gift_id', 304) ->orderBy('recommend', 'asc') ->get() ->take(3); if ($dailyGifts->isEmpty()) { return apiReturnFail(['web.gift.daily_gift_not_exists', __('web.gift.daily_gift_not_exists')]); } // 检查每档今日是否都已充值 $todayRecharges = DB::table('agent.dbo.order') ->where('user_id', $userId) ->where('GiftsID', 304) ->where('pay_status', 1) ->where('pay_at', '>=', $todayStart) ->where('pay_at', '<=', $todayEnd) ->pluck('amount') ->toArray(); $completedCount = 0; foreach ($dailyGifts as $gift) { // 检查该档位是否已充值(使用浮点数比较) $isCompleted = false; foreach ($todayRecharges as $rechargeAmount) { if (abs($rechargeAmount/100 - $gift->recommend) < 0.01) { $isCompleted = true; break; } } if ($isCompleted) { $completedCount++; } } if ($completedCount < 3) { return apiReturnFail(['web.gift.three_tiers_not_completed', __('web.gift.three_tiers_not_completed')]); } // 检查是否已领取过 $redisKey = "daily_gift_bonus_claimed_{$userId}_" . date('Y-m-d'); if (Redis::exists($redisKey)) { return apiReturnFail(['web.gift.bonus_already_claimed_today', __('web.gift.bonus_already_claimed_today')]); } // 获取奖励金额(从任意一档的 task_bonus 获取,task_bonus 是数字字段) $firstGift = $dailyGifts->first(); $rewardAmount = 0; if ($firstGift && $firstGift->task_bonus !== null) { $rewardAmount = round((float)$firstGift->task_bonus, 2); } if ($rewardAmount <= 0) { return apiReturnFail(['web.gift.bonus_config_not_exists', __('web.gift.bonus_config_not_exists')]); } try { // 发放奖励 OuroGameService::AddScore($userId, $rewardAmount * NumConfig::NUM_VALUE, 52, true); // 52=礼包奖励 app(PaidRewardStatisticsService::class) ->incrementRecordByDateIDAndType(date('Ymd'), 'daily_gift_claim', $rewardAmount * NumConfig::NUM_VALUE); // 标记已领取 Redis::setex($redisKey, 86400, 1); // 24小时过期 \Log::info('每日礼包额外奖励领取成功', [ 'user_id' => $userId, 'reward_amount' => $rewardAmount ]); return apiReturnSuc([ 'amount' => $rewardAmount, 'message' => str_replace(':amount', $rewardAmount, __('web.gift.claim_success')) ]); } catch (\Exception $e) { \Log::error('每日礼包额外奖励领取失败', [ 'user_id' => $userId, 'error' => $e->getMessage() ]); return apiReturnFail(['web.gift.claim_failed', str_replace(':error', $e->getMessage(), __('web.gift.claim_failed'))]); } } public function getSecondGive(Request $request) { $user = $request->user(); $fpkey='Firstpay_'.$user->UserID; if(Redis::exists($fpkey)){ $data=Redis::get($fpkey); $data=json_decode($data,true); $data['timeleft']=86400-(time()-$data['buytime']); if($data['timeleft']<=0) { Redis::del($fpkey); //加钱 if($data['second_give']){ $czReason=$data['czReason']; $cjReason=$data['cjReason']; [$OrgScore,$NowScore]=OuroGameService::AddScore($user->UserID,$data['second_give']*NumConfig::NUM_VALUE,$cjReason); //更新二次领钱记录 DB::table(TableName::agent() . 'guide_payment')->where('UserID',$user->UserID)->update([ 'GetSecondTime' => now(), 'SecondScoreNum'=>$data['second_give']*NumConfig::NUM_VALUE ]); return apiReturnSuc(compact('OrgScore','NowScore')); } return apiReturnSuc(); } } return apiReturnFail(['web.withdraw.try_again_later','Tente novamente mais tarde']); } /** * 获取召回礼包(gift_id=305)三档金额及对应奖励百分比 * 可用档位:9, 19, 29, 39, 49, 59, 79, 99 * 初档 70% 加成,后续每档增加 15% * @param float $avgRecharge 用户平均充值金额 * @return array [['amount'=>float, 'bonus_percent'=>int], ...] 三档信息 */ private function getRecallGiftTiers($avgRecharge) { $amounts = [9.99, 19.99, 29.99, 39.99, 49.99, 59.99, 79.99, 99.99]; $bonusPercents = [70, 85, 100]; // 初档70%,中档85%,高档100% // 找到初档索引:第一个 >= avgRecharge 的档位 $index = count($amounts); // 默认未找到,后面会 cap foreach ($amounts as $i => $amt) { if ($avgRecharge <= $amt) { $index = $i; break; } } // 如果 avgRecharge 大于所有档位,取最后三位 if ($index > count($amounts) - 3) { $index = count($amounts) - 3; } $tiers = []; for ($i = 0; $i < 3; $i++) { $tiers[] = [ 'amount' => $amounts[$index + $i], 'bonus_percent' => $bonusPercents[$i], ]; } return $tiers; } /** * 召回礼包(gift_id=305)—— 检查条件和返回三档信息 * * 新规则: * - 连续 7 天未充值后弹出(原为 3 天) * - 根据平均充值金额确定初档,显示三档(初/中/高) * - 初档 70% 加成,中档 85%,高档 100%,通过 7 天签到领取 * - 签到从充值次日开始,按比例分配(7%/9%/11%/13%/14%/21%/25%) * - 第 4-7 天需要当天流水 >= 100 */ public function vipInactiveGift(Request $request) { $user = $request->user(); $this->setUserLocale($request); $userId = $user->UserID; // 1. VIP 判断:是否有过充值 $userRecharge = DB::table(TableName::QPAccountsDB() . 'YN_VIPAccount') ->where('UserID', $userId) ->value('Recharge') ?: 0; if ($userRecharge <= 0) { return apiReturnSuc([ 'status' => 0, 'message' => __('web.gift.vip_inactive_not_vip') ]); } // 2. 计算连续未充值天数(排除 305 礼包自身) $lastOrder = DB::table('agent.dbo.order') ->where('user_id', $userId) ->where('pay_status', 1) ->where('GiftsID', '<>', 305) ->orderBy('pay_at', 'desc') ->first(); if (!$lastOrder) { return apiReturnSuc([ 'status' => 0, 'message' => __('web.gift.vip_inactive_not_vip') ]); } $lastDate = date('Y-m-d', strtotime($lastOrder->pay_at)); $today = date('Y-m-d'); $diffDays = (strtotime($today) - strtotime($lastDate)) / 86400; $inactiveDays = max(0, (int)$diffDays - 1); // 3. 查询最近一条礼包记录 $record = DB::table('agent.dbo.inactive_vip_gift_records') ->where('user_id', $userId) ->where('gift_id', 305) ->orderBy('id', 'desc') ->first(); // 连续 7 天未充值才弹出(原为 3 天) $requiredInactiveDays = 7; if ($inactiveDays < $requiredInactiveDays && !$record) { return apiReturnSuc([ 'status' => 0, 'message' => __('web.gift.vip_inactive_days_insufficient'), 'inactive_days' => $inactiveDays ]); } // 4. 计算总充值 & 平均单笔 $stat = DB::table(TableName::QPRecordDB() . 'RecordUserTotalStatistics') ->where('UserID', $userId) ->select('Recharge', 'RechargeTimes') ->first(); $totalRecharge = (float)($stat->Recharge ?? 0); $rechargeTimes = (int)($stat->RechargeTimes ?? 0); if ($totalRecharge <= 0 || $rechargeTimes <= 0) { return apiReturnSuc([ 'status' => 0, 'message' => __('web.gift.vip_inactive_not_vip') ]); } $avgRecharge = $totalRecharge / $rechargeTimes; // 5. 根据平均充值获取三档信息 $tiers = $this->getRecallGiftTiers($avgRecharge); /* * status 定义: * 0 不满足条件 * 1 满足条件未充值 * 2 满足条件已充值,奖励未全部领取 * 3 满足条件已充值,奖励全部领取 */ $status = 1; $timeLeft = 0; if ($record) { // 有记录:根据是否领满7天判断状态 $allClaimedMask = (1 << 7) - 1; $allClaimed = (($record->claimed_days_mask & $allClaimedMask) == $allClaimedMask); if ($allClaimed) { $status = 3; // 全部领取(视为过期) } else { $status = 2; // 部分领取,进行中 } } else { // 无记录:24 小时倒计时逻辑 $today = date('Y-m-d'); $timerKey = "vip_inactive_gift_timer_{$userId}_{$today}"; $timerData = Redis::get($timerKey); if ($timerData) { $timerData = json_decode($timerData, true); $expireTime = $timerData['expire_time'] ?? 0; $timeLeft = max(0, $expireTime - time()); if ($timeLeft <= 0) { $status = 0; } } else { $expireTime = time() + 86400; $ttl = 86400 + 3600; Redis::setex($timerKey, $ttl, json_encode([ 'expire_time' => $expireTime, 'created_at' => time(), 'date' => $today ])); $timeLeft = 86400; } } // 构建返回的三档列表 $list = []; if ($status == 1) { foreach ($tiers as $i => $tier) { $amount = $tier['amount']; $bonusPercent = $tier['bonus_percent']; $gear = DB::table('agent.dbo.recharge_gear') ->select('money', 'favorable_price', 'gear', 'give') ->where('money', $amount) ->first(); $rechargeGearAmt = $amount; // favorable_price = 本金(无立即奖励,全部通过签到领取) $favorablePrice = $rechargeGearAmt; $give = 0; $item = $gear ? (clone $gear) : new \stdClass(); if ($gear) { $item->money = $amount; $item->favorable_price = $favorablePrice; $item->give = $give; } else { $item->money = $amount; $item->favorable_price = $favorablePrice; $item->give = $give; $item->gear = null; } $item->gift_id = 305; $item->total_bonus = $bonusPercent; $item->bonus = $bonusPercent; $item->total_reward_percent = $bonusPercent; $item->tier_index = $i; // 0=初档, 1=中档, 2=高档 $item->recommend = ($i == 1) ? 1 : 0; // 默认中档 if (!empty($item->gear)) { $item->gear = Util::filterGearByDevice($item->gear, GlobalUserInfo::toWebData($user)); } // 额外奖励信息 $item->extra_reward = round($amount * $bonusPercent / 100, 2); $item->total_reward = round($amount * $bonusPercent / 100 + $amount, 2); $list[] = $item; } } $payload = [ 'status' => $status, 'inactive_days' => $inactiveDays, 'time_left' => $timeLeft, 'expire_at' => $timeLeft > 0 ? (time() + $timeLeft) : null, 'message' => $status == 1 ? __('web.gift.vip_inactive_can_recharge') : ($status == 2 ? __('web.gift.vip_inactive_claimed_partial') : ($status == 3 ? __('web.gift.vip_inactive_claimed_all') : __('web.gift.vip_inactive_seven_days_expired'))), 'list' => $status == 1 ? $list : [], 'tiers' => $status == 1 ? $tiers : [], 'distribution' => [7, 9, 11, 13, 14, 21, 25], // 7 天签到分配比例(%) ]; if ($status != 1 && $record) { $payload['total_reward_percent'] = $record->total_percent - 100; } // 2025-05-15 暂停7天 到 2025-05-22 $payload['list'] = []; if ($payload['status'] == 1) { $payload['status'] = 0; // 暂时调整为不可充值状态 $payload['message'] = __('web.gift.vip_inactive_can_recharge_seven_days_paused'); } return apiReturnSuc($payload); } /** * 连续未充值 VIP 礼包(gift_id=305)—— 获取 7 日礼包信息 * 签到从充值次日开始,按比例分配(7%/9%/11%/13%/14%/21%/25%) * 第 4-7 天需要当天流水 >= 100 */ public function vipInactiveGiftSevenDays(Request $request) { $user = $request->user(); $this->setUserLocale($request); $userId = $user->UserID; // 获取 7 日礼包记录 $record = DB::table('agent.dbo.inactive_vip_gift_records') ->where('user_id', $userId) ->where('gift_id', 305) ->orderBy('id', 'desc') ->first(); if (!$record) { return apiReturnFail(['web.gift.vip_inactive_no_record', __('web.gift.vip_inactive_no_record')]); } // 计算从充值完成后的第几天(充值当天=0,次日=1) $createdDate = date('Y-m-d', strtotime($record->created_at)); $today = date('Y-m-d'); $daysPassed = floor((strtotime($today) - strtotime($createdDate)) / 86400); // 检查是否已领满7天(视为过期) $allClaimedMask = (1 << 7) - 1; $claimedMask = (int)$record->claimed_days_mask; $isExpired = ($claimedMask & $allClaimedMask) == $allClaimedMask; $expiredAt = $isExpired ? strtotime($record->expired_at) : null; $totalBonus = (float)$record->per_day_amount; // 存储的是总奖励金额 // 计算已签到次数 $claimedDaysCount = 0; for ($i = 0; $i < 7; $i++) { if ($claimedMask & (1 << $i)) { $claimedDaysCount++; } } // 上次签到日期(用于判断今天是否已签) $lastClaimDate = $record->updated_at ? date('Y-m-d', strtotime($record->updated_at)) : null; $todayDate = date('Y-m-d'); $alreadyClaimedToday = ($lastClaimDate === $todayDate); // 7 天签到分配比例 $distribution = [7, 9, 11, 13, 14, 21, 25]; // 构建每一天的状态 $days = []; for ($day = 1; $day <= 7; $day++) { $dayIndex = $day - 1; // 位索引:day1对应bit0 $isClaimed = ($claimedMask & (1 << $dayIndex)) > 0; // 当天可领取金额 $dayAmount = round($totalBonus * $distribution[$dayIndex] / 100, 2); // 判断状态:0=不可领取, 1=可领取, 2=已领取, 3=过期 $dayStatus = 0; $betAmount = 0; if ($isClaimed) { $dayStatus = 2; // 已领取 } elseif ($isExpired) { // 整体过期(所有天数已领完) $dayStatus = 3; } elseif ($day == $claimedDaysCount + 1) { // 下一个可签到的天数 if ($alreadyClaimedToday) { // 今天已签到过,不能再签 $dayStatus = 0; } else { $dayStatus = 1; // 可领取 } } else { // 已签过的(不在这里处理)或未来的天数 $dayStatus = 0; } $days[] = [ 'day' => $day, 'amount' => $dayAmount, 'percent' => $distribution[$dayIndex], 'status' => $dayStatus, 'status_text' => [ __('web.gift.status_cannot_claim'), __('web.gift.status_can_claim'), __('web.gift.status_claimed'), __('web.gift.status_expired') ][$dayStatus] ?? __('web.gift.status_unknown'), ]; } return apiReturnSuc([ 'record' => [ 'pay_amount' => (float)$record->pay_amount, 'total_percent' => (float)$record->total_percent - 100, 'seven_days_percent' => (float)$record->seven_days_percent, 'total_bonus' => $totalBonus, 'inactive_days' => (int)$record->inactive_days, 'last_sign_day' => $record ? (int)($record->claimed_days_mask ? floor(log($record->claimed_days_mask, 2)) + 1 : 0) : 0, 'created_at' => $record->created_at, 'expired_at' => $record->expired_at ], 'distribution' => $distribution, 'days' => $days, 'claimed_count' => $claimedDaysCount, // 已签到次数 'is_expired' => $isExpired, 'expire_at' => $expiredAt ]); } /** * 连续未充值 VIP 礼包(gift_id=305)—— 领取某日奖励 */ public function claimVipInactiveGiftDayReward(Request $request) { $user = $request->user(); $this->setUserLocale($request); $userId = $user->UserID; $day = (int)$request->input('day', 0); // if ($day < 1 || $day > 7) { // return apiReturnFail(['web.gift.invalid_reward_type', __('web.gift.invalid_reward_type')]); // } // 获取 7 日礼包记录 $record = DB::table('agent.dbo.inactive_vip_gift_records') ->where('user_id', $userId) ->where('gift_id', 305) ->orderBy('id', 'desc') ->first(); if (!$record) { return apiReturnFail(['web.gift.vip_inactive_no_record', __('web.gift.vip_inactive_no_record')]); } // 检查是否已领满7天(视为过期) $allClaimedMask = (1 << 7) - 1; $claimedMaskCheck = (int)$record->claimed_days_mask; if (($claimedMaskCheck & $allClaimedMask) == $allClaimedMask) { return apiReturnFail(['web.gift.vip_inactive_expired', __('web.gift.vip_inactive_expired')]); } // 计算已签到次数,确定下一次签到的天数 $claimedMask = (int)$record->claimed_days_mask; $claimedDaysCount = 0; for ($i = 0; $i < 7; $i++) { if ($claimedMask & (1 << $i)) { $claimedDaysCount++; } } $day = $claimedDaysCount + 1; if ($day < 1 || $day > 7) { return apiReturnFail(['web.gift.vip_inactive_day_not_time', __('web.gift.vip_inactive_day_not_time')]); } // 检查是否已领取 $dayIndex = $day - 1; if ($claimedMask & (1 << $dayIndex)) { return apiReturnFail(['web.gift.vip_inactive_day_claimed', str_replace(':day', $day, __('web.gift.vip_inactive_day_claimed'))]); } // 每天只能签到一次:检查上次签到日期是否今天 $lastClaimDate = $record->updated_at ? date('Y-m-d', strtotime($record->updated_at)) : null; $todayDate = date('Y-m-d'); if ($lastClaimDate === $todayDate) { return apiReturnFail(['web.gift.vip_inactive_day_claimed_today', __('web.gift.vip_inactive_day_claimed_today')]); } // 7 天签到分配比例 $distribution = [7, 9, 11, 13, 14, 21, 25]; $totalBonus = (float)$record->per_day_amount; // 存储的是总奖励金额 $dayIndex = (int)($day - 1); $amount = round($totalBonus * $distribution[$dayIndex] / 100, 2); try { // 发放奖励 OuroGameService::AddScore($userId, $amount * NumConfig::NUM_VALUE, 52, true); // 52=礼包奖励 app(PaidRewardStatisticsService::class) ->incrementRecordByDateIDAndType(date('Ymd'), 'vip_inactive_claim', $amount * NumConfig::NUM_VALUE); // 更新位标记 $newMask = $claimedMask | (1 << $dayIndex); $updateData = [ 'claimed_days_mask' => $newMask, 'updated_at' => date('Y-m-d H:i:s') ]; // 如果领满7天,在 expired_at 记录完成时间 $allClaimedMask = (1 << 7) - 1; if (($newMask & $allClaimedMask) == $allClaimedMask) { $updateData['expired_at'] = date('Y-m-d H:i:s'); } DB::connection('write')->table('agent.dbo.inactive_vip_gift_records') ->where('id', $record->id) ->update($updateData); \Log::info('连续未充值VIP礼包奖励领取成功', [ 'user_id' => $userId, 'day' => $day, 'amount' => $amount ]); return apiReturnSuc([ 'amount' => $amount, 'day' => $day, 'message' => str_replace(':amount', $amount, __('web.gift.claim_success')) ]); } catch (\Exception $e) { \Log::error('连续未充值VIP礼包奖励领取失败', [ 'user_id' => $userId, 'day' => $day, 'error' => $e->getMessage() ]); return apiReturnFail(['web.gift.claim_failed', str_replace(':error', $e->getMessage(), __('web.gift.claim_failed'))]); } } public function freeBonusGifts(Request $request) { $user = $request->user(); $this->setUserLocale($request); $gifts = DB::table('agent.dbo.recharge_gift') ->where('gift_id', 306) ->orderBy('recommend', 'asc') ->get(); $gifts = $gifts->keyBy('recommend'); $moneyList = []; foreach ($gifts as $gift) { $money = sprintf('%.2f', $gift->recommend); $moneyList[$money] = $gift; } $result = []; $gears = DB::table('agent.dbo.recharge_gear') ->select('money', 'favorable_price', 'gear') ->whereIn('money', array_keys($moneyList)) ->where('status', 1) ->get(); foreach ($gears as $gear) { if (empty($moneyList[$gear->money])) { continue; } $gear->amount = 0; $gear->gift_id = $moneyList[$gear->money]->gift_id; $gear->task_bonus = $moneyList[$gear->money]->task_bonus; $gear->recommend = sprintf('%.2f', $moneyList[$gear->money]->recommend); $gear->gear = Util::filterGearByDevice($gear->gear,GlobalUserInfo::toWebData($user)); $result[] = $gear; } return apiReturnSuc([ 'list' => $result, ]); } }