TestAutoWeedingOptimization.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <?php
  2. namespace App\Console\Commands;
  3. use Illuminate\Console\Command;
  4. use App\Module\Pet\Logic\PetAutoSkillLogic;
  5. use App\Module\Pet\Models\PetActiveSkill;
  6. use App\Module\Pet\Models\PetUser;
  7. use App\Module\Farm\Models\FarmLand;
  8. use App\Module\Farm\Models\FarmCrop;
  9. use App\Module\Farm\Enums\DISASTER_TYPE;
  10. use App\Module\Farm\Enums\LAND_STATUS;
  11. use App\Module\Farm\Enums\GROWTH_STAGE;
  12. use App\Module\GameItems\Models\ItemUser;
  13. use Illuminate\Support\Facades\DB;
  14. use Illuminate\Support\Facades\Log;
  15. /**
  16. * 测试自动除草优化功能
  17. */
  18. class TestAutoWeedingOptimization extends Command
  19. {
  20. /**
  21. * 命令签名
  22. *
  23. * @var string
  24. */
  25. protected $signature = 'test:auto-skill-optimization {user_id=1} {--skill=all : 测试的技能类型 (weeding|watering|pest_control|all)}';
  26. /**
  27. * 命令描述
  28. *
  29. * @var string
  30. */
  31. protected $description = '测试自动技能功能处理多个灾害的优化 (除草、浇水、杀虫)';
  32. /**
  33. * 执行命令
  34. */
  35. public function handle(): int
  36. {
  37. $userId = (int) $this->argument('user_id');
  38. $skillType = $this->option('skill');
  39. $this->info("开始测试用户 {$userId} 的自动技能优化功能 (技能类型: {$skillType})");
  40. try {
  41. if ($skillType === 'all') {
  42. $this->testAllSkills($userId);
  43. } else {
  44. $this->testSingleSkill($userId, $skillType);
  45. }
  46. $this->info('测试完成!');
  47. return 0;
  48. } catch (\Exception $e) {
  49. $this->error('测试失败: ' . $e->getMessage());
  50. $this->error('堆栈跟踪: ' . $e->getTraceAsString());
  51. return 1;
  52. }
  53. }
  54. /**
  55. * 测试所有技能
  56. */
  57. private function testAllSkills(int $userId): void
  58. {
  59. $skills = ['weeding', 'watering', 'pest_control'];
  60. foreach ($skills as $skill) {
  61. $this->info("\n" . str_repeat('=', 50));
  62. $this->info("测试 {$skill} 技能");
  63. $this->info(str_repeat('=', 50));
  64. $this->testSingleSkill($userId, $skill);
  65. }
  66. }
  67. /**
  68. * 测试单个技能
  69. */
  70. private function testSingleSkill(int $userId, string $skillType): void
  71. {
  72. // 1. 创建测试数据
  73. $this->createTestData($userId, $skillType);
  74. // 2. 执行自动技能
  75. $this->executeAutoSkill($userId, $skillType);
  76. // 3. 验证结果
  77. $this->verifyResults($userId, $skillType);
  78. }
  79. /**
  80. * 创建测试数据
  81. */
  82. private function createTestData(int $userId, string $skillType = 'weeding'): void
  83. {
  84. $this->info('创建测试数据...');
  85. DB::beginTransaction();
  86. try {
  87. // 查找或创建宠物
  88. $pet = PetUser::where('user_id', $userId)->first();
  89. if (!$pet) {
  90. $this->warn("用户 {$userId} 没有宠物,跳过测试");
  91. DB::rollback();
  92. return;
  93. }
  94. // 查找有作物的土地
  95. $land = FarmLand::where('user_id', $userId)
  96. ->where('has_crop', true)
  97. ->first();
  98. if (!$land) {
  99. $this->warn("用户 {$userId} 没有种植作物的土地,跳过测试");
  100. DB::rollback();
  101. return;
  102. }
  103. // 获取作物
  104. $crop = FarmCrop::where('land_id', $land->id)->first();
  105. if (!$crop) {
  106. $this->warn("土地 {$land->id} 没有作物,跳过测试");
  107. DB::rollback();
  108. return;
  109. }
  110. // 为作物添加多个杂草灾害
  111. $disasters = $crop->disasters ?? [];
  112. // 清除现有的杂草灾害
  113. $disasters = array_filter($disasters, function($disaster) {
  114. return ($disaster['type'] ?? 0) != DISASTER_TYPE::WEED->value;
  115. });
  116. // 添加3个新的杂草灾害
  117. for ($i = 1; $i <= 3; $i++) {
  118. $disasters[] = [
  119. 'id' => time() + $i,
  120. 'type' => DISASTER_TYPE::WEED->value,
  121. 'status' => 'active',
  122. 'created_at' => now()->subMinutes(30 - $i * 5)->toDateTimeString()
  123. ];
  124. }
  125. $crop->disasters = $disasters;
  126. $crop->save();
  127. // 确保用户有足够的除草剂
  128. $userItem = ItemUser::where('user_id', $userId)
  129. ->where('item_id', 22) // 除草剂ID
  130. ->first();
  131. if (!$userItem) {
  132. ItemUser::create([
  133. 'user_id' => $userId,
  134. 'item_id' => 22,
  135. 'quantity' => 10
  136. ]);
  137. } else {
  138. $userItem->quantity = 2; // 设置为只有2个除草剂,测试道具不足情况
  139. $userItem->save();
  140. }
  141. // 创建或更新激活的自动除草技能
  142. $activeSkill = PetActiveSkill::where('pet_id', $pet->id)
  143. ->where('skill_name', \App\Module\Pet\Enums\PET_SKILL_NAME::AUTO_WEEDING->value)
  144. ->first();
  145. if (!$activeSkill) {
  146. PetActiveSkill::create([
  147. 'pet_id' => $pet->id,
  148. 'skill_id' => 1, // 假设技能ID
  149. 'skill_name' => \App\Module\Pet\Enums\PET_SKILL_NAME::AUTO_WEEDING->value,
  150. 'start_time' => now()->subMinutes(10),
  151. 'end_time' => now()->addHours(3),
  152. 'status' => 'active',
  153. 'last_check_time' => now()->subMinutes(5)
  154. ]);
  155. }
  156. DB::commit();
  157. $this->info("测试数据创建完成:");
  158. $this->info("- 宠物ID: {$pet->id}");
  159. $this->info("- 土地ID: {$land->id}");
  160. $this->info("- 作物ID: {$crop->id}");
  161. $this->info("- 杂草灾害数量: 3个");
  162. } catch (\Exception $e) {
  163. DB::rollback();
  164. throw $e;
  165. }
  166. }
  167. /**
  168. * 执行自动除草
  169. */
  170. private function executeAutoWeeding(int $userId): void
  171. {
  172. $this->info('执行自动除草...');
  173. $pet = PetUser::where('user_id', $userId)->first();
  174. $activeSkill = PetActiveSkill::where('pet_id', $pet->id)
  175. ->where('skill_name', \App\Module\Pet\Enums\PET_SKILL_NAME::AUTO_WEEDING->value)
  176. ->first();
  177. if (!$activeSkill) {
  178. throw new \Exception('没有找到激活的自动除草技能');
  179. }
  180. DB::beginTransaction();
  181. $autoSkillLogic = new PetAutoSkillLogic();
  182. $autoSkillLogic->processAutoWeeding($activeSkill);
  183. DB::commit();
  184. $this->info('自动除草执行完成');
  185. }
  186. /**
  187. * 验证结果
  188. */
  189. private function verifyResults(int $userId): void
  190. {
  191. $this->info('验证结果...');
  192. $land = FarmLand::where('user_id', $userId)
  193. ->where('has_crop', true)
  194. ->first();
  195. if (!$land) {
  196. $this->warn('没有找到有作物的土地');
  197. return;
  198. }
  199. $crop = FarmCrop::where('land_id', $land->id)->first();
  200. if (!$crop) {
  201. $this->warn('没有找到作物');
  202. return;
  203. }
  204. // 统计剩余的活跃杂草灾害
  205. $activeWeeds = array_filter($crop->disasters ?? [], function($disaster) {
  206. return ($disaster['type'] ?? 0) == DISASTER_TYPE::WEED->value &&
  207. ($disaster['status'] ?? '') === 'active';
  208. });
  209. $clearedWeeds = array_filter($crop->disasters ?? [], function($disaster) {
  210. return ($disaster['type'] ?? 0) == DISASTER_TYPE::WEED->value &&
  211. ($disaster['status'] ?? '') === 'cleared';
  212. });
  213. // 检查道具消耗
  214. $userItem = ItemUser::where('user_id', $userId)
  215. ->where('item_id', 22)
  216. ->first();
  217. $this->info('验证结果:');
  218. $this->info("- 剩余活跃杂草灾害: " . count($activeWeeds) . "个");
  219. $this->info("- 已清除杂草灾害: " . count($clearedWeeds) . "个");
  220. $this->info("- 剩余除草剂数量: " . ($userItem ? $userItem->quantity : 0));
  221. if (count($activeWeeds) == 0) {
  222. $this->info('✅ 优化成功!所有杂草灾害都被清除了');
  223. } else {
  224. $this->warn('⚠️ 还有杂草灾害未被清除,可能是道具不足');
  225. }
  226. }
  227. }