Tree 2 месяцев назад
Родитель
Сommit
5d6c3f0fb0
2 измененных файлов с 608 добавлено и 0 удалено
  1. 605 0
      app/Http/Controllers/Game/ActivityController.php
  2. 3 0
      routes/game.php

+ 605 - 0
app/Http/Controllers/Game/ActivityController.php

@@ -735,4 +735,609 @@ class ActivityController extends Controller
         die;
     }
 
+    // ==================== VIP提现诱导功能 ====================
+
+    /**
+     * 获取用户VIP提现任务进度
+     */
+    public function getVipWithdrawTasks(Request $request)
+    {
+        $user = $request->user();
+        $userId = $user->UserID;
+
+        // 检查用户是否已充值
+        $user_recharge = DB::table(TableName::QPAccountsDB() . 'YN_VIPAccount')
+            ->where('UserID', $userId)
+            ->value('Recharge') ?: 0;
+
+        if ($user_recharge <= 0 &&!$request->input('is_test', 0)) {
+            return apiReturnFail('请先充值后再查看任务-'.$userId);
+        }
+
+        // 获取用户任务数据
+        $taskData = $this->getUserTaskData($userId);
+        
+        // 获取任务配置
+        $taskConfig = $this->getTaskConfig();
+
+        // 判断奖励状态:0-不能领取, 1-待领取, 2-已领取
+        $stage1_reward_status = 0; // 不能领取
+        if ($taskData['stage1_completed']) {
+            $stage1_reward_status = $taskData['stage1_withdrawn'] ? 2 : 1; // 已领取 : 待领取
+        }
+
+        $stage2_reward_status = 0; // 不能领取
+        if ($taskData['stage1_completed']) { // 阶段2需要阶段1完成才能解锁
+            if ($taskData['stage2_completed']) {
+                $stage2_reward_status = $taskData['stage2_withdrawn'] ? 2 : 1; // 已领取 : 待领取
+            }
+        }
+
+        $stage3_task1_status = 0; // 不能领取
+        $stage3_task2_status = 0; // 不能领取
+        if ($taskData['stage2_completed']) { // 阶段3需要阶段2完成才能解锁
+            // 循环任务:基于累计下注判断是否可领取(不使用已领取状态)
+            if (($taskData['stage3_current_bet'] ?? 0) >= 600) {
+                $stage3_task1_status = 1; // 待领取
+            }
+            if (($taskData['stage3_current_bet'] ?? 0) >= 1200) {
+                $stage3_task2_status = 1; // 待领取
+            }
+        }
+
+        // 构建阶段1任务列表
+        $stage1Tasks = [];
+        foreach ($taskConfig['stage1']['tasks'] as $taskCfg) {
+            $taskKey = $taskCfg['id'];
+            $progressKey = $taskCfg['progress_key'];
+            $completed = $taskData[$taskKey] ?? false;
+            
+            $stage1Tasks[] = [
+                'id' => $taskCfg['id'],
+                'title' => $taskCfg['title'],
+                'type' => $taskCfg['type'],
+                'completed' => $completed,
+                'status' => $completed ? 1 : 0,
+                'status_text' => $completed ? '已完成' : '未完成',
+                'progress' => $taskData[$progressKey] ?? 0,
+                'target' => $taskCfg['target']
+            ];
+        }
+
+        // 构建任务结构
+        $tasks = [
+            'stage1' => [
+                'stage' => 1,
+                'title' => '阶段任务1',
+                'reward' => $taskConfig['stage1']['reward'],
+                'completed' => $taskData['stage1_completed'],
+                'reward_status' => $stage1_reward_status,
+                'reward_status_text' => ['不能领取', '待领取', '已领取'][$stage1_reward_status],
+                'can_claim' => $stage1_reward_status === 1,
+                'tasks' => $stage1Tasks
+            ],
+            'stage2' => [
+                'stage' => 2,
+                'title' => '阶段任务2',
+                'reward' => $taskConfig['stage2']['reward'],
+                'unlocked' => $taskData['stage1_completed'],
+                'completed' => $taskData['stage2_completed'],
+                'reward_status' => $stage2_reward_status,
+                'reward_status_text' => ['不能领取', '待领取', '已领取'][$stage2_reward_status],
+                'can_claim' => $stage2_reward_status === 1,
+                'tasks' => array_map(function($taskCfg) use ($taskData) {
+                    $taskKey = $taskCfg['id'];
+                    $progressKey = $taskCfg['progress_key'];
+                    $completed = $taskData[$taskKey] ?? false;
+                    
+                    return [
+                        'id' => $taskCfg['id'],
+                        'title' => $taskCfg['title'],
+                        'type' => $taskCfg['type'],
+                        'completed' => $completed,
+                        'status' => $completed ? 1 : 0,
+                        'status_text' => $completed ? '已完成' : '未完成',
+                        'progress' => $taskData[$progressKey] ?? 0,
+                        'target' => $taskCfg['target']
+                    ];
+                }, $taskConfig['stage2']['tasks'])
+            ],
+            'stage3' => [
+                'stage' => 3,
+                'title' => '阶段任务3(循环任务)',
+                'unlocked' => $taskData['stage2_completed'],
+                'is_loop' => true,
+                'current_loop' => $taskData['stage3_loop_count'],
+                'tasks' => array_map(function($taskCfg) use ($taskData, $stage3_task1_status, $stage3_task2_status) {
+                    $taskKey = $taskCfg['id'];
+                    $progressKey = $taskCfg['progress_key'];
+                    $completed = $taskData[$taskKey] ?? false;
+                    $rewardStatus = $taskKey === 'stage3_task1' ? $stage3_task1_status : $stage3_task2_status;
+                    
+                    return [
+                        'id' => $taskCfg['id'],
+                        'title' => $taskCfg['title'],
+                        'type' => $taskCfg['type'],
+                        'reward' => $taskCfg['reward'],
+                        'completed' => $completed,
+                        'reward_status' => $rewardStatus,
+                        'reward_status_text' => ['不能领取', '待领取', '可重复领取'][$rewardStatus],
+                        'can_claim' => $rewardStatus === 1,
+                        'progress' => $taskData[$progressKey] ?? 0,
+                        'target' => $taskCfg['target']
+                    ];
+                }, $taskConfig['stage3']['tasks'])
+            ]
+        ];
+
+        return apiReturnSuc($tasks);
+    }
+
+    /**
+     * 领取任务奖励(提现)
+     */
+    public function claimVipWithdrawReward(Request $request)
+    {
+        $user = $request->user();
+        $userId = $user->UserID;
+        $stage = (int)$request->input('stage');
+        $taskId = $request->input('task_id', '');
+
+        $redisLockKey = "vip_withdraw_claim_{$userId}";
+        if (!Redis::set($redisLockKey, 1, 'EX', 10, 'NX')) {
+            return apiReturnFail('操作太频繁,请稍后再试');
+        }
+
+        try {
+            // 获取用户任务数据
+            $taskData = $this->getUserTaskData($userId);
+            $rewardAmount = 0;
+
+            // 阶段1
+            if ($stage === 1) {
+                if (!$taskData['stage1_completed']) {
+                    Redis::del($redisLockKey);
+                    return apiReturnFail('任务未完成');
+                }
+                if ($taskData['stage1_withdrawn']) {
+                    Redis::del($redisLockKey);
+                    return apiReturnFail('奖励已领取');
+                }
+                $rewardAmount = 10;
+                $this->updateTaskProgress($userId, 'stage1_withdrawn', 1);
+            }
+            // 阶段2
+            elseif ($stage === 2) {
+                if (!$taskData['stage2_completed']) {
+                    Redis::del($redisLockKey);
+                    return apiReturnFail('任务未完成');
+                }
+                if ($taskData['stage2_withdrawn']) {
+                    Redis::del($redisLockKey);
+                    return apiReturnFail('奖励已领取');
+                }
+                $rewardAmount = 10;
+                $this->updateTaskProgress($userId, 'stage2_withdrawn', 1);
+            }
+            // 阶段3
+            elseif ($stage === 3) {
+                if ($taskId === 'stage3_task1') {
+                    // 每满600可领取20,领取后扣除600下注进度
+                    if (($taskData['stage3_current_bet'] ?? 0) < 600) {
+                        Redis::del($redisLockKey);
+                        return apiReturnFail('任务未完成');
+                    }
+                    $rewardAmount = 20;
+                    $this->updateTaskProgress($userId, 'stage3_current_bet', max(0, ($taskData['stage3_current_bet'] - 600)));
+                } 
+                elseif ($taskId === 'stage3_task2') {
+                    // 每满1200可领取40,领取后扣除1200下注进度
+                    if (($taskData['stage3_current_bet'] ?? 0) < 1200) {
+                        Redis::del($redisLockKey);
+                        return apiReturnFail('任务未完成');
+                    }
+                    $rewardAmount = 40;
+                    $this->updateTaskProgress($userId, 'stage3_current_bet', max(0, ($taskData['stage3_current_bet'] - 1200)));
+                }
+            } else {
+                Redis::del($redisLockKey);
+                return apiReturnFail('无效的阶段');
+            }
+
+            // 添加提现额度到用户账户
+            if ($rewardAmount > 0) {
+                OuroGameService::AddScore($userId, $rewardAmount * NumConfig::NUM_VALUE, 91, true);
+                
+                // 记录日志
+                \Log::info('VIP提现任务奖励', [
+                    'user_id' => $userId,
+                    'stage' => $stage,
+                    'task_id' => $taskId,
+                    'amount' => $rewardAmount
+                ]);
+            }
+
+            Redis::del($redisLockKey);
+            return apiReturnSuc([
+                'amount' => $rewardAmount,
+                'message' => "成功领取 {$rewardAmount} 提现额度"
+            ]);
+
+        } catch (\Exception $e) {
+            Redis::del($redisLockKey);
+            \Log::error('VIP提现任务领取失败', [
+                'user_id' => $userId,
+                'error' => $e->getMessage()
+            ]);
+            return apiReturnFail('领取失败:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 获取用户任务数据(从Redis和数据库)
+     */
+    private function getUserTaskData($userId)
+    {
+        $redisKey = "vip_withdraw_task_{$userId}";
+        $data = Redis::get($redisKey);
+
+        if ($data) {
+            $taskData = json_decode($data, true);
+        } else {
+            // 从数据库初始化任务数据
+            $taskData = $this->initUserTaskData($userId);
+        }
+
+        // 实时更新统计数据
+        $this->updateRealTimeStats($userId, $taskData);
+
+        // 检查任务完成状态
+        $this->checkTaskCompletion($taskData);
+
+        // 保存到Redis(缓存1小时)
+        Redis::setex($redisKey, 3600, json_encode($taskData));
+
+        return $taskData;
+    }
+
+    /**
+     * 获取任务配置
+     */
+    private function getTaskConfig()
+    {
+        return [
+            'stage1' => [
+                'reward' => 10,
+                'tasks' => [
+                    [
+                        'id' => 'stage1_task1',
+                        'title' => '签到一次',
+                        'type' => 'sign_in',
+                        'target' => 1,
+                        'progress_key' => 'sign_in_count'
+                    ],
+                    [
+                        'id' => 'stage1_task2',
+                        'title' => '下注金额达到100',
+                        'type' => 'bet_amount',
+                        'target' => 100,
+                        'progress_key' => 'total_bet'
+                    ],
+                    [
+                        'id' => 'stage1_task3',
+                        'title' => '再充值一次',
+                        'type' => 'recharge',
+                        'target' => 1,
+                        'progress_key' => 'recharge_count'
+                    ]
+                ]
+            ],
+            'stage2' => [
+                'reward' => 10,
+                'tasks' => [
+                    [
+                        'id' => 'stage2_task1',
+                        'title' => '玩六款游戏',
+                        'type' => 'play_games',
+                        'target' => 6,
+                        'progress_key' => 'played_games_count'
+                    ],
+                    [
+                        'id' => 'stage2_task2',
+                        'title' => '下注金额达到3000',
+                        'type' => 'bet_amount',
+                        'target' => 3000,
+                        'progress_key' => 'total_bet'
+                    ],
+                    [
+                        'id' => 'stage2_task3',
+                        'title' => '发起一次邀请',
+                        'type' => 'invite',
+                        'target' => 1,
+                        'progress_key' => 'invite_count'
+                    ]
+                ]
+            ],
+            'stage3' => [
+                'tasks' => [
+                    [
+                        'id' => 'stage3_task1',
+                        'title' => '下注金额达到600',
+                        'type' => 'bet_amount',
+                        'target' => 600,
+                        'reward' => 20,
+                        'progress_key' => 'stage3_current_bet'
+                    ],
+                    [
+                        'id' => 'stage3_task2',
+                        'title' => '下注金额达到1200',
+                        'type' => 'bet_amount',
+                        'target' => 1200,
+                        'reward' => 40,
+                        'progress_key' => 'stage3_current_bet'
+                    ]
+                ]
+            ]
+        ];
+    }
+
+    /**
+     * 初始化用户任务数据
+     */
+    private function initUserTaskData($userId)
+    {
+        return [
+            // 阶段1任务
+            'stage1_task1' => false,
+            'stage1_task2' => false,
+            'stage1_task3' => false,
+            'stage1_completed' => false,
+            'stage1_withdrawn' => false,
+
+            // 阶段2任务
+            'stage2_task1' => false,
+            'stage2_task2' => false,
+            'stage2_task3' => false,
+            'stage2_completed' => false,
+            'stage2_withdrawn' => false,
+
+            // 阶段3任务(循环)
+            'stage3_task1' => false,
+            'stage3_task2' => false,
+            'stage3_task1_withdrawn' => false,
+            'stage3_task2_withdrawn' => false,
+            'stage3_loop_count' => 0,
+            'stage3_current_bet' => 0,
+            'stage3_available_amount' => 0,
+
+            // 统计数据
+            'total_bet' => 0,
+            'recharge_count' => 0,
+            'played_games_count' => 0,
+            'invite_count' => 0,
+            'sign_in_count' => 0
+        ];
+    }
+
+    /**
+     * 更新实时统计数据
+     */
+    private function updateRealTimeStats($userId, &$taskData)
+    {
+
+        $userTotalStatistics = DB::table('QPRecordDB.dbo.RecordUserTotalStatistics')
+            ->where('UserID', $userId)
+            ->first();
+
+        // 获取总下注金额
+        $totalBet =$userTotalStatistics ?$userTotalStatistics->TotalBet: 0;
+        $taskData['total_bet'] = $totalBet / NumConfig::NUM_VALUE;
+
+        // 获取充值次数
+        $rechargeCount = $userTotalStatistics?$userTotalStatistics->RechargeTimes:0;
+        $taskData['recharge_count'] = $rechargeCount;
+
+        // 获取玩过的游戏数量(去重)
+        $playedGames = DB::table('QPRecordDB.dbo.RecordUserGameCount')
+            ->where('UserID', $userId)
+            ->distinct()
+            ->count('GameID');
+        $taskData['played_games_count'] = $playedGames;
+
+        // 邀请人数从Redis读取(通过 triggerInvite 方法触发)
+        if (!isset($taskData['invite_count'])) {
+            $taskData['invite_count'] = 0;
+        }
+
+        // 签到次数从Redis读取(通过 triggerSignIn 方法触发)
+        if (!isset($taskData['sign_in_count'])) {
+            $taskData['sign_in_count'] = 0;
+        }
+
+        // 阶段3累计下注:基于总下注的增量进行累加(非时间周期)
+        if (!isset($taskData['stage3_current_bet'])) {
+            $taskData['stage3_current_bet'] = 0;
+        }
+        if (!isset($taskData['stage3_last_total_bet'])) {
+            $taskData['stage3_last_total_bet'] = $totalBet; // 记录原始总下注(原始单位)
+        }
+        // 计算本次新增下注(转为金额单位)
+        $deltaBet = $totalBet - ($taskData['stage3_last_total_bet'] ?? 0);
+        if ($deltaBet > 0) {
+            $taskData['stage3_current_bet'] += ($deltaBet / NumConfig::NUM_VALUE);
+            $taskData['stage3_last_total_bet'] = $totalBet;
+        }
+    }
+
+    /**
+     * 检查任务完成状态
+     */
+    private function checkTaskCompletion(&$taskData)
+    {
+        // 阶段1任务检查
+        $taskData['stage1_task1'] = $taskData['sign_in_count'] >= 1;
+        $taskData['stage1_task2'] = $taskData['total_bet'] >= 100;
+        $taskData['stage1_task3'] = $taskData['recharge_count'] >= 1;
+        $taskData['stage1_completed'] = $taskData['stage1_task1'] && 
+                                         $taskData['stage1_task2'] && 
+                                         $taskData['stage1_task3'];
+
+        // 阶段2任务检查
+        if ($taskData['stage1_completed']) {
+            $taskData['stage2_task1'] = $taskData['played_games_count'] >= 6;
+            $taskData['stage2_task2'] = $taskData['total_bet'] >= 3000;
+            $taskData['stage2_task3'] = $taskData['invite_count'] >= 1;
+            $taskData['stage2_completed'] = $taskData['stage2_task1'] && 
+                                             $taskData['stage2_task2'] && 
+                                             $taskData['stage2_task3'];
+        }
+
+        // 阶段3任务检查(循环):基于累计下注,不使用时间周期
+        if ($taskData['stage2_completed']) {
+            $taskData['stage3_task1'] = ($taskData['stage3_current_bet'] ?? 0) >= 600;
+            $taskData['stage3_task2'] = ($taskData['stage3_current_bet'] ?? 0) >= 1200;
+        }
+    }
+
+    /**
+     * 更新任务进度
+     */
+    private function updateTaskProgress($userId, $key, $value)
+    {
+        $redisKey = "vip_withdraw_task_{$userId}";
+        $data = Redis::get($redisKey);
+        
+        if ($data) {
+            $taskData = json_decode($data, true);
+            $taskData[$key] = $value;
+            Redis::setex($redisKey, 3600, json_encode($taskData));
+        }
+    }
+
+    /**
+     * 重置阶段3循环任务
+     */
+    private function resetStage3Tasks($userId)
+    {
+        $redisKey = "vip_withdraw_task_{$userId}";
+        $data = Redis::get($redisKey);
+        
+        if ($data) {
+            $taskData = json_decode($data, true);
+            $taskData['stage3_task1'] = false;
+            $taskData['stage3_task2'] = false;
+            $taskData['stage3_task1_withdrawn'] = false;
+            $taskData['stage3_task2_withdrawn'] = false;
+            $taskData['stage3_current_bet'] = 0;
+            $taskData['stage3_cycle_start'] = (int)date('Ymd');
+            $taskData['stage3_loop_count'] = ($taskData['stage3_loop_count'] ?? 0) + 1;
+            Redis::setex($redisKey, 3600, json_encode($taskData));
+        }
+    }
+
+    /**
+     * 手动触发签到(供其他地方调用)
+     * 注意:只有充值用户才会计数
+     */
+    public function triggerSignIn($userId)
+    {
+        // 检查用户是否已充值
+        $user_recharge = DB::table(TableName::QPAccountsDB() . 'YN_VIPAccount')
+            ->where('UserID', $userId)
+            ->value('Recharge') ?: 0;
+        
+        if ($user_recharge <= 0) {
+            \Log::info('VIP提现任务-签到触发失败', [
+                'user_id' => $userId,
+                'reason' => '用户未充值'
+            ]);
+            return false;
+        }
+        
+        $redisKey = "vip_withdraw_task_{$userId}";
+        $data = Redis::get($redisKey);
+        
+        if ($data) {
+            $taskData = json_decode($data, true);
+            $taskData['sign_in_count'] = ($taskData['sign_in_count'] ?? 0) + 1;
+            Redis::setex($redisKey, 3600, json_encode($taskData));
+            
+            \Log::info('VIP提现任务-签到触发成功', [
+                'user_id' => $userId,
+                'sign_in_count' => $taskData['sign_in_count']
+            ]);
+            
+            return true;
+        } else {
+            // 如果Redis没有数据,初始化
+            $taskData = $this->initUserTaskData($userId);
+            $taskData['sign_in_count'] = 1;
+            Redis::setex($redisKey, 3600, json_encode($taskData));
+            
+            \Log::info('VIP提现任务-签到触发成功(首次)', [
+                'user_id' => $userId,
+                'sign_in_count' => 1
+            ]);
+            
+            return true;
+        }
+    }
+
+    /**
+     * 手动触发邀请(供其他地方调用)
+     * 注意:只有充值用户且阶段1完成后才会计数
+     */
+    public function triggerInvite($userId)
+    {
+        // 检查用户是否已充值
+        $user_recharge = DB::table(TableName::QPAccountsDB() . 'YN_VIPAccount')
+            ->where('UserID', $userId)
+            ->value('Recharge') ?: 0;
+        
+        if ($user_recharge <= 0) {
+            \Log::info('VIP提现任务-邀请触发失败', [
+                'user_id' => $userId,
+                'reason' => '用户未充值'
+            ]);
+            return false;
+        }
+        
+        $redisKey = "vip_withdraw_task_{$userId}";
+        $data = Redis::get($redisKey);
+        
+        if ($data) {
+            $taskData = json_decode($data, true);
+            
+            // 检查阶段1是否完成
+            if (!isset($taskData['stage1_completed']) || !$taskData['stage1_completed']) {
+                // 阶段1未完成,不计数
+                \Log::info('VIP提现任务-邀请触发失败', [
+                    'user_id' => $userId,
+                    'reason' => '阶段1未完成',
+                    'stage1_completed' => $taskData['stage1_completed'] ?? false
+                ]);
+                return false;
+            }
+            
+            // 阶段1已完成,增加邀请计数
+            $taskData['invite_count'] = ($taskData['invite_count'] ?? 0) + 1;
+            Redis::setex($redisKey, 3600, json_encode($taskData));
+            
+            \Log::info('VIP提现任务-邀请触发成功', [
+                'user_id' => $userId,
+                'invite_count' => $taskData['invite_count']
+            ]);
+            
+            return true;
+        } else {
+            // 如果Redis没有数据但用户已充值且阶段1可能已完成,初始化
+            // 但邀请需要阶段1完成,此时阶段1可能未完成,所以不计数
+            \Log::info('VIP提现任务-邀请触发失败', [
+                'user_id' => $userId,
+                'reason' => 'Redis数据不存在或阶段1未完成'
+            ]);
+            return false;
+        }
+    }
+
 }

+ 3 - 0
routes/game.php

@@ -267,6 +267,9 @@ Route::group([
     $route->any('/redpack/receive', 'Game\ActivityController@RedReceive');
     $route->any('/turnplate/bonus', 'Game\ExtensionsController@kanBonus');//bonus
 
+    // VIP提现诱导任务
+    $route->any('/vip-withdraw/tasks', 'Game\ActivityController@getVipWithdrawTasks');
+    $route->any('/vip-withdraw/claim', 'Game\ActivityController@claimVipWithdrawReward');
 
     $route->any('/mail/check', 'Game\MailController@newMsg');
     $route->any('/mail/list', 'Game\MailController@mailList');