RewardService.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <?php
  2. namespace App\Module\Game\Services;
  3. use App\Module\Game\Dtos\RewardGroupDto;
  4. use App\Module\Game\Dtos\RewardResultDto;
  5. use App\Module\Game\Enums\REWARD_SOURCE_TYPE;
  6. use App\Module\Game\Logics\RewardLogic;
  7. /**
  8. * 奖励服务类
  9. *
  10. * 提供奖励相关的服务,对外接口
  11. */
  12. class RewardService
  13. {
  14. /**
  15. * 获取奖励组信息
  16. *
  17. * @param int|string $groupIdOrCode 奖励组ID或编码
  18. * @return RewardGroupDto|null 奖励组DTO,不存在时返回null
  19. */
  20. public static function getRewardGroup($groupIdOrCode): ?RewardGroupDto
  21. {
  22. $logic = new RewardLogic();
  23. return $logic->getRewardGroup($groupIdOrCode);
  24. }
  25. /**
  26. * 获取奖励组并转换为Protobuf Reward对象
  27. *
  28. * @param int|string $groupIdOrCode 奖励组ID或编码
  29. * @return \Uraus\Kku\Common\Reward|null Protobuf Reward对象,不存在时返回null
  30. */
  31. public static function getRewardGroupAsReward($groupIdOrCode): ?\Uraus\Kku\Common\Reward
  32. {
  33. $rewardGroupDto = self::getRewardGroup($groupIdOrCode);
  34. if (!$rewardGroupDto) {
  35. return null;
  36. }
  37. return ProtobufConverter::convertRewardGroupToReward($rewardGroupDto);
  38. }
  39. /**
  40. * 发放奖励
  41. *
  42. * @param int $userId 用户ID
  43. * @param int|string $groupIdOrCode 奖励组ID或编码
  44. * @param REWARD_SOURCE_TYPE $sourceType 来源类型枚举
  45. * @param int $sourceId 来源ID
  46. * @param int $multiplier 倍率
  47. * @return RewardResultDto 奖励结果
  48. */
  49. public static function grantReward(int $userId, $groupIdOrCode, REWARD_SOURCE_TYPE $sourceType, int $sourceId, int $multiplier = 1): RewardResultDto
  50. {
  51. // 验证来源类型是否有效
  52. if (!REWARD_SOURCE_TYPE::isValid($sourceType->value)) {
  53. return RewardResultDto::fail("无效的奖励来源类型: {$sourceType->value}");
  54. }
  55. $logic = new RewardLogic();
  56. return $logic->grantReward($userId, $groupIdOrCode, $sourceType->value, $sourceId, $multiplier);
  57. }
  58. /**
  59. * 批量发放奖励
  60. *
  61. * @param array $userIds 用户ID数组
  62. * @param int|string $groupIdOrCode 奖励组ID或编码
  63. * @param REWARD_SOURCE_TYPE $sourceType 来源类型枚举
  64. * @param int $sourceId 来源ID
  65. * @return array 奖励结果数组,键为用户ID,值为RewardResultDto
  66. */
  67. public static function batchGrantReward(array $userIds, $groupIdOrCode, REWARD_SOURCE_TYPE $sourceType, int $sourceId): array
  68. {
  69. // 验证来源类型是否有效
  70. if (!REWARD_SOURCE_TYPE::isValid($sourceType->value)) {
  71. $failResult = RewardResultDto::fail("无效的奖励来源类型: {$sourceType->value}");
  72. return array_fill_keys($userIds, $failResult);
  73. }
  74. $results = [];
  75. $logic = new RewardLogic();
  76. foreach ($userIds as $userId) {
  77. $results[$userId] = $logic->grantReward($userId, $groupIdOrCode, $sourceType->value, $sourceId);
  78. }
  79. return $results;
  80. }
  81. /**
  82. * 检查奖励组是否存在
  83. *
  84. * @param int|string $groupIdOrCode 奖励组ID或编码
  85. * @return bool 是否存在
  86. */
  87. public static function rewardGroupExists($groupIdOrCode): bool
  88. {
  89. return self::getRewardGroup($groupIdOrCode) !== null;
  90. }
  91. /**
  92. * 发放奖励(支持保底机制)
  93. *
  94. * @param int $userId 用户ID
  95. * @param int|string $groupIdOrCode 奖励组ID或编码
  96. * @param REWARD_SOURCE_TYPE $sourceType 来源类型枚举
  97. * @param int $sourceId 来源ID
  98. * @param bool $enablePity 是否启用保底机制
  99. * @return RewardResultDto 奖励结果
  100. */
  101. public static function grantRewardWithPity(int $userId, $groupIdOrCode, REWARD_SOURCE_TYPE $sourceType, int $sourceId, bool $enablePity = true): RewardResultDto
  102. {
  103. // 验证来源类型是否有效
  104. if (!REWARD_SOURCE_TYPE::isValid($sourceType->value)) {
  105. return RewardResultDto::fail("无效的奖励来源类型: {$sourceType->value}");
  106. }
  107. $logic = new RewardLogic();
  108. return $logic->grantRewardWithPity($userId, $groupIdOrCode, $sourceType->value, $sourceId, $enablePity);
  109. }
  110. /**
  111. * 模拟奖励发放(不实际发放,仅返回奖励结果)
  112. *
  113. * @param int|string $groupIdOrCode 奖励组ID或编码
  114. * @return RewardResultDto 奖励结果
  115. */
  116. public static function simulateReward($groupIdOrCode): RewardResultDto
  117. {
  118. $logic = new RewardLogic();
  119. return $logic->simulateReward($groupIdOrCode);
  120. }
  121. /**
  122. * 批量模拟奖励发放(不实际发放,仅返回奖励结果)
  123. *
  124. * @param int|string $groupIdOrCode 奖励组ID或编码
  125. * @param int $count 模拟次数
  126. * @return array 奖励结果数组
  127. */
  128. public static function batchSimulateReward($groupIdOrCode, int $count): array
  129. {
  130. $results = [];
  131. $logic = new RewardLogic();
  132. for ($i = 0; $i < $count; $i++) {
  133. $results[] = $logic->simulateReward($groupIdOrCode);
  134. }
  135. return $results;
  136. }
  137. /**
  138. * 获取用户保底状态
  139. *
  140. * @param int $userId 用户ID
  141. * @param int|string $groupIdOrCode 奖励组ID或编码
  142. * @return array 保底状态信息
  143. */
  144. public static function getUserPityStatus(int $userId, $groupIdOrCode): array
  145. {
  146. $rewardGroup = self::getRewardGroup($groupIdOrCode);
  147. if (!$rewardGroup) {
  148. return [];
  149. }
  150. return PityService::getPityStatus($userId, $rewardGroup->id);
  151. }
  152. /**
  153. * 重置用户保底计数
  154. *
  155. * @param int $userId 用户ID
  156. * @param int|string $groupIdOrCode 奖励组ID或编码
  157. * @return bool 是否成功
  158. */
  159. public static function resetUserPity(int $userId, $groupIdOrCode): bool
  160. {
  161. $rewardGroup = self::getRewardGroup($groupIdOrCode);
  162. if (!$rewardGroup) {
  163. return false;
  164. }
  165. PityService::resetAllPityCounts($userId, $rewardGroup->id);
  166. return true;
  167. }
  168. }