TaskRewardGroupService.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <?php
  2. namespace App\Module\Task\Services;
  3. use App\Module\Game\Enums\REWARD_SOURCE_TYPE;
  4. use App\Module\Game\Services\RewardGroupService;
  5. use App\Module\Game\Services\RewardService;
  6. use App\Module\Task\Models\Task;
  7. use App\Module\Task\Models\TaskRewardLog;
  8. use Illuminate\Support\Facades\DB;
  9. use Illuminate\Support\Facades\Log;
  10. /**
  11. * 任务奖励组服务类
  12. *
  13. * 提供任务奖励组相关的服务,包括获取任务奖励、发放任务奖励等功能
  14. */
  15. class TaskRewardGroupService
  16. {
  17. /**
  18. * 获取任务奖励
  19. *
  20. * @param int $taskId 任务ID
  21. * @return array 奖励列表
  22. */
  23. public static function getTaskRewards(int $taskId): array
  24. {
  25. try {
  26. $task = Task::find($taskId);
  27. if (!$task) {
  28. return [];
  29. }
  30. // 如果任务关联了奖励组,则使用奖励组服务获取奖励
  31. if ($task->reward_group_id) {
  32. return RewardGroupService::getRewardItems($task->reward_group_id);
  33. }
  34. // 否则使用旧版本的奖励(已废弃)
  35. $rewards = [];
  36. foreach ($task->rewards as $reward) {
  37. $rewards[] = [
  38. 'id' => $reward->id,
  39. 'type' => $reward->reward_type,
  40. 'target_id' => $reward->reward_param2,
  41. 'quantity' => $reward->quantity,
  42. 'extra_data' => $reward->extra_data,
  43. ];
  44. }
  45. return $rewards;
  46. } catch (\Exception $e) {
  47. Log::error('获取任务奖励失败', [
  48. 'task_id' => $taskId,
  49. 'error' => $e->getMessage()
  50. ]);
  51. return [];
  52. }
  53. }
  54. /**
  55. * 发放任务奖励
  56. *
  57. * @param int $userId 用户ID
  58. * @param int $taskId 任务ID
  59. * @param int $userTaskId 用户任务ID
  60. * @param string $ipAddress IP地址
  61. * @param string $deviceInfo 设备信息
  62. * @return array 发放结果
  63. */
  64. public static function distributeRewards(
  65. int $userId,
  66. int $taskId,
  67. int $userTaskId,
  68. string $ipAddress = '',
  69. string $deviceInfo = ''
  70. ): array {
  71. try {
  72. // 检查事务是否已开启,如果已开启则不再开启新事务
  73. \UCore\Db\Helper::check_tr();
  74. $task = Task::find($taskId);
  75. if (!$task) {
  76. throw new \Exception('任务不存在');
  77. }
  78. // 如果任务关联了奖励组,则使用奖励组服务发放奖励
  79. if ($task->reward_group_id) {
  80. $result = RewardService::grantReward($userId, $task->reward_group_id, REWARD_SOURCE_TYPE::TASK, $taskId);
  81. // 记录奖励发放日志
  82. TaskRewardLog::create([
  83. 'user_id' => $userId,
  84. 'task_id' => $taskId,
  85. 'user_task_id' => $userTaskId,
  86. 'rewards' => $result->items,
  87. 'rewarded_at' => now(),
  88. 'ip_address' => $ipAddress,
  89. 'device_info' => $deviceInfo,
  90. ]);
  91. return [
  92. 'success' => $result->success,
  93. 'message' => $result->errorMessage ?? '奖励发放成功',
  94. 'rewards' => $result->items,
  95. ];
  96. }
  97. // 否则使用旧版本的奖励发放逻辑(已废弃)
  98. // 注意:旧版本的TaskRewardService已废弃,这里返回错误
  99. throw new \Exception('任务未配置奖励组,且旧版奖励系统已废弃');
  100. } catch (\Exception $e) {
  101. // 注意:不在这里回滚事务,由调用方处理
  102. Log::error('发放任务奖励失败', [
  103. 'user_id' => $userId,
  104. 'task_id' => $taskId,
  105. 'user_task_id' => $userTaskId,
  106. 'error' => $e->getMessage(),
  107. 'trace' => $e->getTraceAsString()
  108. ]);
  109. return [
  110. 'success' => false,
  111. 'message' => '发放奖励失败: ' . $e->getMessage(),
  112. 'rewards' => [],
  113. ];
  114. }
  115. }
  116. /**
  117. * 迁移任务奖励到奖励组
  118. *
  119. * 将旧版本的任务奖励迁移到奖励组
  120. *
  121. * @param int $taskId 任务ID
  122. * @return array 迁移结果
  123. */
  124. public static function migrateTaskRewardsToRewardGroup(int $taskId): array
  125. {
  126. try {
  127. // 开始事务
  128. DB::beginTransaction();
  129. $task = Task::with('rewards')->find($taskId);
  130. if (!$task) {
  131. throw new \Exception('任务不存在');
  132. }
  133. // 如果任务已经关联了奖励组,则跳过
  134. if ($task->reward_group_id) {
  135. return [
  136. 'success' => true,
  137. 'message' => '任务已关联奖励组,无需迁移',
  138. 'reward_group_id' => $task->reward_group_id,
  139. ];
  140. }
  141. // 如果任务没有奖励,则跳过
  142. if ($task->rewards->isEmpty()) {
  143. return [
  144. 'success' => true,
  145. 'message' => '任务没有奖励,无需迁移',
  146. 'reward_group_id' => null,
  147. ];
  148. }
  149. // 创建奖励组
  150. $rewardGroup = \App\Module\Game\Models\GameRewardGroup::create([
  151. 'name' => "任务奖励: {$task->name}",
  152. 'code' => "task_reward_{$task->id}_" . time(),
  153. 'description' => "任务 {$task->name} 的奖励",
  154. 'is_random' => false,
  155. 'random_count' => 0,
  156. ]);
  157. // 创建奖励项
  158. foreach ($task->rewards as $reward) {
  159. // 根据任务奖励类型映射到奖励组的奖励类型
  160. $rewardType = self::mapRewardType($reward->reward_type);
  161. $targetId = (int)$reward->reward_param2;
  162. \App\Module\Game\Models\GameRewardItem::create([
  163. 'group_id' => $rewardGroup->id,
  164. 'reward_type' => $rewardType,
  165. 'target_id' => $targetId,
  166. 'param1' => 0,
  167. 'param2' => 0,
  168. 'quantity' => $reward->quantity,
  169. 'weight' => 1.0,
  170. 'is_guaranteed' => true,
  171. 'extra_data' => $reward->extra_data,
  172. ]);
  173. }
  174. // 更新任务,关联到新创建的奖励组
  175. $task->reward_group_id = $rewardGroup->id;
  176. $task->save();
  177. DB::commit();
  178. return [
  179. 'success' => true,
  180. 'message' => '任务奖励迁移成功',
  181. 'reward_group_id' => $rewardGroup->id,
  182. ];
  183. } catch (\Exception $e) {
  184. DB::rollBack();
  185. Log::error('迁移任务奖励到奖励组失败', [
  186. 'task_id' => $taskId,
  187. 'error' => $e->getMessage(),
  188. 'trace' => $e->getTraceAsString()
  189. ]);
  190. return [
  191. 'success' => false,
  192. 'message' => '迁移任务奖励失败: ' . $e->getMessage(),
  193. 'reward_group_id' => null,
  194. ];
  195. }
  196. }
  197. /**
  198. * 映射任务奖励类型到奖励组的奖励类型
  199. *
  200. * @param string $taskRewardType 任务奖励类型
  201. * @return int 奖励组的奖励类型
  202. */
  203. private static function mapRewardType(string $taskRewardType): int
  204. {
  205. switch ($taskRewardType) {
  206. case 'item':
  207. return \App\Module\Game\Enums\REWARD_TYPE::ITEM->value;
  208. case 'currency':
  209. return \App\Module\Game\Enums\REWARD_TYPE::CURRENCY->value;
  210. case 'pet':
  211. return \App\Module\Game\Enums\REWARD_TYPE::PET_EXP->value;
  212. case 'pet_item':
  213. return \App\Module\Game\Enums\REWARD_TYPE::ITEM->value;
  214. default:
  215. return \App\Module\Game\Enums\REWARD_TYPE::OTHER->value;
  216. }
  217. }
  218. }