RewardSourceResolver.php 15 KB

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