RewardSourceResolver.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. <?php
  2. namespace App\Module\Game\Services;
  3. use App\Module\Game\Enums\REWARD_SOURCE_TYPE;
  4. use App\Module\Activity\Models\Activity;
  5. use App\Module\Task\Models\Task;
  6. use App\Module\Farm\Models\FarmLand;
  7. use App\Module\UrsPromotion\Models\UrsUserMapping;
  8. use Illuminate\Support\Facades\Log;
  9. /**
  10. * 奖励来源解析服务
  11. *
  12. * 根据source_type和source_id解析具体的业务来源信息
  13. */
  14. class RewardSourceResolver
  15. {
  16. /**
  17. * 解析奖励来源信息
  18. *
  19. * @param string $sourceType 来源类型
  20. * @param int $sourceId 来源ID
  21. * @return array 包含详细信息的数组
  22. */
  23. public static function resolve(string $sourceType, int $sourceId): array
  24. {
  25. try {
  26. // 首先获取枚举信息
  27. $typeInfo = REWARD_SOURCE_TYPE::getTypeInfo($sourceType);
  28. switch ($sourceType) {
  29. case REWARD_SOURCE_TYPE::TASK->value:
  30. return self::resolveTaskSource($sourceId, $typeInfo);
  31. case REWARD_SOURCE_TYPE::ACTIVITY->value:
  32. return self::resolveActivitySource($sourceId, $typeInfo);
  33. case REWARD_SOURCE_TYPE::FARM_INIT->value:
  34. case REWARD_SOURCE_TYPE::FARM_HARVEST->value:
  35. case REWARD_SOURCE_TYPE::FARM_PLANT->value:
  36. return self::resolveFarmSource($sourceType, $sourceId, $typeInfo);
  37. case REWARD_SOURCE_TYPE::USER_REGISTER_TEST->value:
  38. case REWARD_SOURCE_TYPE::PROMOTION_REWARD->value:
  39. return self::resolvePromotionSource($sourceType, $sourceId, $typeInfo);
  40. case REWARD_SOURCE_TYPE::SIGN_IN->value:
  41. return self::resolveSignInSource($sourceId, $typeInfo);
  42. case REWARD_SOURCE_TYPE::ACHIEVEMENT->value:
  43. return self::resolveAchievementSource($sourceId, $typeInfo);
  44. case REWARD_SOURCE_TYPE::LEVEL->value:
  45. return self::resolveLevelSource($sourceId, $typeInfo);
  46. case REWARD_SOURCE_TYPE::CHEST->value:
  47. return self::resolveChestSource($sourceId, $typeInfo);
  48. case REWARD_SOURCE_TYPE::SHOP_PURCHASE->value:
  49. return self::resolveShopSource($sourceId, $typeInfo);
  50. case REWARD_SOURCE_TYPE::DAILY_LOGIN->value:
  51. return self::resolveDailyLoginSource($sourceId, $typeInfo);
  52. case REWARD_SOURCE_TYPE::INVITE_FRIEND->value:
  53. return self::resolveInviteSource($sourceId, $typeInfo);
  54. case REWARD_SOURCE_TYPE::SYSTEM->value:
  55. case REWARD_SOURCE_TYPE::TEST->value:
  56. return self::resolveSystemSource($sourceType, $sourceId, $typeInfo);
  57. default:
  58. return self::getUnknownSource($sourceType, $sourceId);
  59. }
  60. } catch (\Exception $e) {
  61. Log::warning('解析奖励来源失败', [
  62. 'source_type' => $sourceType,
  63. 'source_id' => $sourceId,
  64. 'error' => $e->getMessage()
  65. ]);
  66. return self::getErrorSource($sourceType, $sourceId, $e->getMessage());
  67. }
  68. }
  69. /**
  70. * 解析任务来源
  71. */
  72. private static function resolveTaskSource(int $taskId, array $typeInfo): array
  73. {
  74. // 由于Task模型可能不存在,先返回基础信息
  75. return [
  76. 'type' => $typeInfo['name'],
  77. 'name' => "任务奖励 (ID: {$taskId})",
  78. 'description' => $typeInfo['description'],
  79. 'link' => $typeInfo['admin_link'] ? "{$typeInfo['admin_link']}/{$taskId}" : null,
  80. 'status' => 'found',
  81. 'category' => $typeInfo['category'],
  82. 'extra' => [
  83. 'task_id' => $taskId,
  84. 'source_type' => REWARD_SOURCE_TYPE::TASK->value
  85. ]
  86. ];
  87. }
  88. /**
  89. * 解析活动来源
  90. */
  91. private static function resolveActivitySource(int $activityId, array $typeInfo): array
  92. {
  93. return [
  94. 'type' => $typeInfo['name'],
  95. 'name' => "活动奖励 (ID: {$activityId})",
  96. 'description' => $typeInfo['description'],
  97. 'link' => $typeInfo['admin_link'] ? "{$typeInfo['admin_link']}/{$activityId}" : null,
  98. 'status' => 'found',
  99. 'category' => $typeInfo['category'],
  100. 'extra' => [
  101. 'activity_id' => $activityId,
  102. 'source_type' => REWARD_SOURCE_TYPE::ACTIVITY->value
  103. ]
  104. ];
  105. }
  106. /**
  107. * 解析农场来源
  108. */
  109. private static function resolveFarmSource(string $sourceType, int $sourceId, array $typeInfo): array
  110. {
  111. // 根据不同的农场操作类型,sourceId可能指向不同的表
  112. if ($sourceType === REWARD_SOURCE_TYPE::FARM_INIT->value) {
  113. // 农场初始化,sourceId通常是用户ID
  114. return [
  115. 'type' => $typeInfo['name'],
  116. 'name' => "用户农场初始化 (用户ID: {$sourceId})",
  117. 'description' => $typeInfo['description'],
  118. 'link' => $typeInfo['admin_link'] ? "{$typeInfo['admin_link']}/users/{$sourceId}" : null,
  119. 'status' => 'found',
  120. 'category' => $typeInfo['category'],
  121. 'extra' => [
  122. 'operation_type' => $sourceType,
  123. 'target_user_id' => $sourceId,
  124. 'source_type' => $sourceType
  125. ]
  126. ];
  127. }
  128. // 其他农场操作
  129. return [
  130. 'type' => $typeInfo['name'],
  131. 'name' => "农场操作奖励 (ID: {$sourceId})",
  132. 'description' => $typeInfo['description'],
  133. 'link' => $typeInfo['admin_link'],
  134. 'status' => 'found',
  135. 'category' => $typeInfo['category'],
  136. 'extra' => [
  137. 'operation_type' => $sourceType,
  138. 'operation_id' => $sourceId,
  139. 'source_type' => $sourceType
  140. ]
  141. ];
  142. }
  143. /**
  144. * 解析推广来源
  145. */
  146. private static function resolvePromotionSource(string $sourceType, int $sourceId, array $typeInfo): array
  147. {
  148. return [
  149. 'type' => $typeInfo['name'],
  150. 'name' => "URS推广奖励 (ID: {$sourceId})",
  151. 'description' => $typeInfo['description'],
  152. 'link' => $typeInfo['admin_link'] ? "{$typeInfo['admin_link']}/user-mappings/{$sourceId}" : null,
  153. 'status' => 'found',
  154. 'category' => $typeInfo['category'],
  155. 'extra' => [
  156. 'mapping_id' => $sourceId,
  157. 'source_type' => $sourceType
  158. ]
  159. ];
  160. }
  161. /**
  162. * 解析签到来源
  163. */
  164. private static function resolveSignInSource(int $sourceId, array $typeInfo): array
  165. {
  166. return [
  167. 'type' => $typeInfo['name'],
  168. 'name' => "每日签到奖励 (ID: {$sourceId})",
  169. 'description' => $typeInfo['description'],
  170. 'link' => $typeInfo['admin_link'] ? "{$typeInfo['admin_link']}/logs/{$sourceId}" : null,
  171. 'status' => 'found',
  172. 'category' => $typeInfo['category'],
  173. 'extra' => [
  174. 'sign_in_id' => $sourceId,
  175. 'source_type' => REWARD_SOURCE_TYPE::SIGN_IN->value
  176. ]
  177. ];
  178. }
  179. /**
  180. * 解析成就来源
  181. */
  182. private static function resolveAchievementSource(int $sourceId, array $typeInfo): array
  183. {
  184. return [
  185. 'type' => $typeInfo['name'],
  186. 'name' => "成就奖励 (ID: {$sourceId})",
  187. 'description' => $typeInfo['description'],
  188. 'link' => $typeInfo['admin_link'] ? "{$typeInfo['admin_link']}/{$sourceId}" : null,
  189. 'status' => 'found',
  190. 'category' => $typeInfo['category'],
  191. 'extra' => [
  192. 'achievement_id' => $sourceId,
  193. 'source_type' => REWARD_SOURCE_TYPE::ACHIEVEMENT->value
  194. ]
  195. ];
  196. }
  197. /**
  198. * 解析等级来源
  199. */
  200. private static function resolveLevelSource(int $sourceId, array $typeInfo): array
  201. {
  202. return [
  203. 'type' => $typeInfo['name'],
  204. 'name' => "等级奖励 (等级: {$sourceId})",
  205. 'description' => $typeInfo['description'],
  206. 'link' => $typeInfo['admin_link'],
  207. 'status' => 'found',
  208. 'category' => $typeInfo['category'],
  209. 'extra' => [
  210. 'level' => $sourceId,
  211. 'source_type' => REWARD_SOURCE_TYPE::LEVEL->value
  212. ]
  213. ];
  214. }
  215. /**
  216. * 解析宝箱来源
  217. */
  218. private static function resolveChestSource(int $sourceId, array $typeInfo): array
  219. {
  220. return [
  221. 'type' => $typeInfo['name'],
  222. 'name' => "宝箱奖励 (ID: {$sourceId})",
  223. 'description' => $typeInfo['description'],
  224. 'link' => $typeInfo['admin_link'] ? "{$typeInfo['admin_link']}/{$sourceId}" : null,
  225. 'status' => 'found',
  226. 'category' => $typeInfo['category'],
  227. 'extra' => [
  228. 'chest_id' => $sourceId,
  229. 'source_type' => REWARD_SOURCE_TYPE::CHEST->value
  230. ]
  231. ];
  232. }
  233. /**
  234. * 解析商店来源
  235. */
  236. private static function resolveShopSource(int $sourceId, array $typeInfo): array
  237. {
  238. return [
  239. 'type' => $typeInfo['name'],
  240. 'name' => "商店购买奖励 (订单ID: {$sourceId})",
  241. 'description' => $typeInfo['description'],
  242. 'link' => $typeInfo['admin_link'] ? "{$typeInfo['admin_link']}/orders/{$sourceId}" : null,
  243. 'status' => 'found',
  244. 'category' => $typeInfo['category'],
  245. 'extra' => [
  246. 'order_id' => $sourceId,
  247. 'source_type' => REWARD_SOURCE_TYPE::SHOP_PURCHASE->value
  248. ]
  249. ];
  250. }
  251. /**
  252. * 解析每日登录来源
  253. */
  254. private static function resolveDailyLoginSource(int $sourceId, array $typeInfo): array
  255. {
  256. return [
  257. 'type' => $typeInfo['name'],
  258. 'name' => "每日登录奖励 (ID: {$sourceId})",
  259. 'description' => $typeInfo['description'],
  260. 'link' => $typeInfo['admin_link'] ? "{$typeInfo['admin_link']}/logs/{$sourceId}" : null,
  261. 'status' => 'found',
  262. 'category' => $typeInfo['category'],
  263. 'extra' => [
  264. 'login_id' => $sourceId,
  265. 'source_type' => REWARD_SOURCE_TYPE::DAILY_LOGIN->value
  266. ]
  267. ];
  268. }
  269. /**
  270. * 解析邀请好友来源
  271. */
  272. private static function resolveInviteSource(int $sourceId, array $typeInfo): array
  273. {
  274. return [
  275. 'type' => $typeInfo['name'],
  276. 'name' => "邀请好友奖励 (邀请ID: {$sourceId})",
  277. 'description' => $typeInfo['description'],
  278. 'link' => $typeInfo['admin_link'] ? "{$typeInfo['admin_link']}/invites/{$sourceId}" : null,
  279. 'status' => 'found',
  280. 'category' => $typeInfo['category'],
  281. 'extra' => [
  282. 'invite_id' => $sourceId,
  283. 'source_type' => REWARD_SOURCE_TYPE::INVITE_FRIEND->value
  284. ]
  285. ];
  286. }
  287. /**
  288. * 解析系统来源
  289. */
  290. private static function resolveSystemSource(string $sourceType, int $sourceId, array $typeInfo): array
  291. {
  292. return [
  293. 'type' => $typeInfo['name'],
  294. 'name' => "{$typeInfo['name']} (ID: {$sourceId})",
  295. 'description' => $typeInfo['description'],
  296. 'link' => $typeInfo['admin_link'],
  297. 'status' => 'found',
  298. 'category' => $typeInfo['category'],
  299. 'extra' => [
  300. 'operation_id' => $sourceId,
  301. 'source_type' => $sourceType
  302. ]
  303. ];
  304. }
  305. /**
  306. * 获取未知来源信息
  307. */
  308. private static function getUnknownSource(string $sourceType, int $sourceId): array
  309. {
  310. return [
  311. 'type' => '未知来源',
  312. 'name' => "未知来源类型: {$sourceType}",
  313. 'description' => "来源ID: {$sourceId}",
  314. 'link' => null,
  315. 'status' => 'unknown',
  316. 'extra' => [
  317. 'raw_source_type' => $sourceType,
  318. 'raw_source_id' => $sourceId
  319. ]
  320. ];
  321. }
  322. /**
  323. * 获取错误来源信息
  324. */
  325. private static function getErrorSource(string $sourceType, int $sourceId, string $error): array
  326. {
  327. return [
  328. 'type' => '解析错误',
  329. 'name' => "解析失败: {$sourceType}",
  330. 'description' => "来源ID: {$sourceId}, 错误: {$error}",
  331. 'link' => null,
  332. 'status' => 'error',
  333. 'extra' => [
  334. 'error_message' => $error,
  335. 'raw_source_type' => $sourceType,
  336. 'raw_source_id' => $sourceId
  337. ]
  338. ];
  339. }
  340. /**
  341. * 获取格式化的显示文本
  342. *
  343. * @param string $sourceType 来源类型
  344. * @param int $sourceId 来源ID
  345. * @param bool $includeLink 是否包含链接
  346. * @return string 格式化的显示文本
  347. */
  348. public static function getDisplayText(string $sourceType, int $sourceId, bool $includeLink = false): string
  349. {
  350. $info = self::resolve($sourceType, $sourceId);
  351. $text = "{$info['type']}: {$info['name']}";
  352. if ($includeLink && $info['link']) {
  353. return "<a href='{$info['link']}' target='_blank'>{$text}</a>";
  354. }
  355. return $text;
  356. }
  357. /**
  358. * 获取简短的显示文本
  359. *
  360. * @param string $sourceType 来源类型
  361. * @param int $sourceId 来源ID
  362. * @return string 简短的显示文本
  363. */
  364. public static function getShortDisplayText(string $sourceType, int $sourceId): string
  365. {
  366. $info = self::resolve($sourceType, $sourceId);
  367. return $info['name'];
  368. }
  369. }