TestUrsEntryRewardIntegrationCommand.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <?php
  2. namespace App\Module\UrsPromotion\Commands;
  3. use App\Module\UrsPromotion\Services\UrsUserMappingService;
  4. use App\Module\UrsPromotion\Services\UrsBackfillRewardService;
  5. use Illuminate\Console\Command;
  6. /**
  7. * URS用户进入农场奖励补发集成测试命令
  8. */
  9. class TestUrsEntryRewardIntegrationCommand extends Command
  10. {
  11. /**
  12. * 命令签名
  13. *
  14. * @var string
  15. */
  16. protected $signature = 'urs:test-entry-reward-integration {urs_user_id : URS用户ID} {--clean : 清理测试数据}';
  17. /**
  18. * 命令描述
  19. *
  20. * @var string
  21. */
  22. protected $description = '测试URS用户进入农场时的推荐奖励补发完整流程';
  23. /**
  24. * 执行命令
  25. */
  26. public function handle()
  27. {
  28. $ursUserId = (int)$this->argument('urs_user_id');
  29. $shouldClean = $this->option('clean');
  30. $this->info("开始URS用户进入农场奖励补发集成测试");
  31. $this->info("URS用户ID: {$ursUserId}");
  32. $this->line('');
  33. // 1. 清理测试数据(如果需要)
  34. if ($shouldClean) {
  35. $this->cleanTestData($ursUserId);
  36. }
  37. // 2. 显示测试前状态
  38. $this->displayPreTestStatus($ursUserId);
  39. // 3. 模拟用户进入农场流程
  40. $this->simulateUserEntryFlow($ursUserId);
  41. // 4. 验证测试结果
  42. $this->verifyTestResults($ursUserId);
  43. $this->line('');
  44. $this->info('集成测试完成!');
  45. }
  46. /**
  47. * 清理测试数据
  48. */
  49. private function cleanTestData(int $ursUserId): void
  50. {
  51. $this->info("=== 清理测试数据 ===");
  52. try {
  53. // 删除用户映射关系
  54. $deletedMappings = DB::connection('mysql')->table('kku_urs_promotion_user_mappings')
  55. ->where('urs_user_id', $ursUserId)
  56. ->delete();
  57. // 删除奖励记录
  58. $deletedRewards = DB::connection('mysql')->table('kku_game_reward_logs')
  59. ->where('source_type', 'urs_promotion_backfill')
  60. ->where('source_id', $ursUserId)
  61. ->delete();
  62. $this->line("已删除映射关系: {$deletedMappings} 条");
  63. $this->line("已删除奖励记录: {$deletedRewards} 条");
  64. } catch (\Exception $e) {
  65. $this->error("清理测试数据失败: " . $e->getMessage());
  66. }
  67. $this->line('');
  68. }
  69. /**
  70. * 显示测试前状态
  71. */
  72. private function displayPreTestStatus(int $ursUserId): void
  73. {
  74. $this->info("=== 测试前状态 ===");
  75. // 检查是否已进入农场
  76. $hasEntered = UrsUserMappingService::hasEnteredFarm($ursUserId);
  77. $this->line("是否已进入农场: " . ($hasEntered ? '是' : '否'));
  78. // 检查下级统计
  79. $stats = UrsBackfillRewardService::getSubordinateStats($ursUserId);
  80. $this->line("直推下级数量: {$stats['direct_count']}");
  81. $this->line("间推下级数量: {$stats['indirect_count']}");
  82. $this->line("三推下级数量: {$stats['third_count']}");
  83. $this->line("下级总数量: {$stats['total_count']}");
  84. // 检查现有奖励记录
  85. $existingRewards = DB::connection('mysql')->table('kku_game_reward_logs')
  86. ->where('source_type', 'urs_promotion_backfill')
  87. ->where('source_id', $ursUserId)
  88. ->count();
  89. $this->line("现有奖励记录数量: {$existingRewards}");
  90. $this->line('');
  91. }
  92. /**
  93. * 模拟用户进入农场流程
  94. */
  95. private function simulateUserEntryFlow(int $ursUserId): void
  96. {
  97. $this->info("=== 模拟用户进入农场流程 ===");
  98. try {
  99. // 模拟用户通过userKey进入农场
  100. $userKey = "test_user_key_{$ursUserId}";
  101. $this->line("模拟用户登录并进入农场...");
  102. $this->line("UserKey: {$userKey}");
  103. // 调用获取农场用户ID的方法,这会触发自动创建和事件
  104. $farmUserId = UrsUserMappingService::getFarmUserIdByUserKeyWithAutoCreate($userKey, $ursUserId);
  105. if ($farmUserId) {
  106. $this->info("✅ 用户成功进入农场");
  107. $this->line("农场用户ID: {$farmUserId}");
  108. // 等待一下让事件处理完成
  109. sleep(1);
  110. } else {
  111. $this->error("❌ 用户进入农场失败");
  112. }
  113. } catch (\Exception $e) {
  114. $this->error("模拟用户进入农场流程失败: " . $e->getMessage());
  115. }
  116. $this->line('');
  117. }
  118. /**
  119. * 验证测试结果
  120. */
  121. private function verifyTestResults(int $ursUserId): void
  122. {
  123. $this->info("=== 验证测试结果 ===");
  124. try {
  125. // 1. 验证用户映射关系
  126. $hasEntered = UrsUserMappingService::hasEnteredFarm($ursUserId);
  127. $this->line("用户是否已进入农场: " . ($hasEntered ? '✅ 是' : '❌ 否'));
  128. if ($hasEntered) {
  129. $farmUserId = UrsUserMappingService::getFarmUserId($ursUserId);
  130. $this->line("农场用户ID: {$farmUserId}");
  131. }
  132. // 2. 验证奖励记录
  133. $rewardLogs = DB::connection('mysql')->table('kku_game_reward_logs')
  134. ->where('source_type', 'urs_promotion_backfill')
  135. ->where('source_id', $ursUserId)
  136. ->get();
  137. $this->line("奖励记录数量: " . $rewardLogs->count());
  138. if ($rewardLogs->count() > 0) {
  139. $this->line("奖励详情:");
  140. $groupedRewards = $rewardLogs->groupBy('group_id');
  141. foreach ($groupedRewards as $groupId => $rewards) {
  142. $totalQuantity = $rewards->sum(function($reward) {
  143. $items = json_decode($reward->reward_items, true);
  144. return array_sum(array_column($items, 'quantity'));
  145. });
  146. $this->line(" - 奖励组ID {$groupId}: {$rewards->count()} 条记录, 总数量: {$totalQuantity}");
  147. }
  148. }
  149. // 3. 验证下级统计
  150. $stats = UrsBackfillRewardService::getSubordinateStats($ursUserId);
  151. $expectedRewards = 0;
  152. if ($stats['direct_count'] > 0) $expectedRewards++;
  153. if ($stats['indirect_count'] > 0) $expectedRewards++;
  154. if ($stats['third_count'] > 0) $expectedRewards++;
  155. $this->line("预期奖励记录数: {$expectedRewards}");
  156. // 4. 结果判断
  157. if ($hasEntered && $rewardLogs->count() >= $expectedRewards) {
  158. $this->info("🎉 集成测试通过!");
  159. } else {
  160. $this->warn("⚠️ 集成测试结果异常,请检查日志");
  161. }
  162. } catch (\Exception $e) {
  163. $this->error("验证测试结果失败: " . $e->getMessage());
  164. }
  165. }
  166. }