reward_group_id) { return RewardGroupService::getRewardItems($task->reward_group_id); } // 否则使用旧版本的奖励(已废弃) $rewards = []; foreach ($task->rewards as $reward) { $rewards[] = [ 'id' => $reward->id, 'type' => $reward->reward_type, 'target_id' => $reward->reward_param2, 'quantity' => $reward->quantity, 'extra_data' => $reward->extra_data, ]; } return $rewards; } catch (\Exception $e) { Log::error('获取任务奖励失败', [ 'task_id' => $taskId, 'error' => $e->getMessage() ]); return []; } } /** * 发放任务奖励 * * @param int $userId 用户ID * @param int $taskId 任务ID * @param int $userTaskId 用户任务ID * @param string $ipAddress IP地址 * @param string $deviceInfo 设备信息 * @return array 发放结果 */ public static function distributeRewards( int $userId, int $taskId, int $userTaskId, string $ipAddress = '', string $deviceInfo = '' ): array { try { // 开始事务 DB::beginTransaction(); $task = Task::find($taskId); if (!$task) { throw new \Exception('任务不存在'); } // 如果任务关联了奖励组,则使用奖励组服务发放奖励 if ($task->reward_group_id) { $result = RewardService::grantReward($userId, $task->reward_group_id, REWARD_SOURCE_TYPE::TASK, $taskId); // 记录奖励发放日志 TaskRewardLog::create([ 'user_id' => $userId, 'task_id' => $taskId, 'user_task_id' => $userTaskId, 'rewards' => $result->rewardItems, 'rewarded_at' => now(), 'ip_address' => $ipAddress, 'device_info' => $deviceInfo, ]); DB::commit(); return [ 'success' => $result->success, 'message' => $result->message, 'rewards' => $result->rewardItems, ]; } // 否则使用旧版本的奖励发放逻辑(已废弃) $rewardService = new TaskRewardService(); $result = $rewardService->distributeRewards($userId, $taskId, $userTaskId); DB::commit(); return $result; } catch (\Exception $e) { DB::rollBack(); Log::error('发放任务奖励失败', [ 'user_id' => $userId, 'task_id' => $taskId, 'user_task_id' => $userTaskId, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return [ 'success' => false, 'message' => '发放奖励失败: ' . $e->getMessage(), 'rewards' => [], ]; } } /** * 迁移任务奖励到奖励组 * * 将旧版本的任务奖励迁移到奖励组 * * @param int $taskId 任务ID * @return array 迁移结果 */ public static function migrateTaskRewardsToRewardGroup(int $taskId): array { try { // 开始事务 DB::beginTransaction(); $task = Task::with('rewards')->find($taskId); if (!$task) { throw new \Exception('任务不存在'); } // 如果任务已经关联了奖励组,则跳过 if ($task->reward_group_id) { return [ 'success' => true, 'message' => '任务已关联奖励组,无需迁移', 'reward_group_id' => $task->reward_group_id, ]; } // 如果任务没有奖励,则跳过 if ($task->rewards->isEmpty()) { return [ 'success' => true, 'message' => '任务没有奖励,无需迁移', 'reward_group_id' => null, ]; } // 创建奖励组 $rewardGroup = \App\Module\Game\Models\GameRewardGroup::create([ 'name' => "任务奖励: {$task->name}", 'code' => "task_reward_{$task->id}_" . time(), 'description' => "任务 {$task->name} 的奖励", 'is_random' => false, 'random_count' => 0, ]); // 创建奖励项 foreach ($task->rewards as $reward) { // 根据任务奖励类型映射到奖励组的奖励类型 $rewardType = self::mapRewardType($reward->reward_type); $targetId = (int)$reward->reward_param2; \App\Module\Game\Models\GameRewardItem::create([ 'group_id' => $rewardGroup->id, 'reward_type' => $rewardType, 'target_id' => $targetId, 'param1' => 0, 'param2' => 0, 'quantity' => $reward->quantity, 'weight' => 1.0, 'is_guaranteed' => true, 'extra_data' => $reward->extra_data, ]); } // 更新任务,关联到新创建的奖励组 $task->reward_group_id = $rewardGroup->id; $task->save(); DB::commit(); return [ 'success' => true, 'message' => '任务奖励迁移成功', 'reward_group_id' => $rewardGroup->id, ]; } catch (\Exception $e) { DB::rollBack(); Log::error('迁移任务奖励到奖励组失败', [ 'task_id' => $taskId, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return [ 'success' => false, 'message' => '迁移任务奖励失败: ' . $e->getMessage(), 'reward_group_id' => null, ]; } } /** * 映射任务奖励类型到奖励组的奖励类型 * * @param string $taskRewardType 任务奖励类型 * @return int 奖励组的奖励类型 */ private static function mapRewardType(string $taskRewardType): int { switch ($taskRewardType) { case 'item': return \App\Module\Game\Enums\REWARD_TYPE::ITEM->value; case 'currency': return \App\Module\Game\Enums\REWARD_TYPE::CURRENCY->value; case 'pet': return \App\Module\Game\Enums\REWARD_TYPE::PET_EXP->value; case 'pet_item': return \App\Module\Game\Enums\REWARD_TYPE::ITEM->value; default: return \App\Module\Game\Enums\REWARD_TYPE::OTHER->value; } } }