UpdateCropGrowthCommand.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <?php
  2. namespace App\Module\Farm\Commands;
  3. use App\Module\Farm\Enums\GROWTH_STAGE;
  4. use App\Module\Farm\Events\CropGrowthStageChangedEvent;
  5. use App\Module\Farm\Models\FarmCrop;
  6. use Illuminate\Console\Command;
  7. use Illuminate\Support\Facades\Log;
  8. /**
  9. * 更新作物生长状态命令
  10. */
  11. class UpdateCropGrowthCommand extends Command
  12. {
  13. /**
  14. * 命令名称
  15. *
  16. * @var string
  17. */
  18. protected $signature = 'farm:update-crop-growth';
  19. /**
  20. * 命令描述
  21. *
  22. * @var string
  23. */
  24. protected $description = '更新作物生长状态';
  25. /**
  26. * 执行命令
  27. *
  28. * @return int
  29. */
  30. public function handle()
  31. {
  32. $this->info('开始更新作物生长状态...');
  33. try {
  34. // 获取需要更新生长阶段的作物
  35. /**
  36. * @var FarmCrop[] $crops
  37. *
  38. */
  39. $crops = FarmCrop::whereNotNull('stage_end_time')
  40. ->where('stage_end_time', '<=', now())
  41. ->where('growth_stage', '<', GROWTH_STAGE::WITHERED)
  42. ->get();
  43. $this->info("找到 {$crops->count()} 个需要更新的作物");
  44. $updatedCount = 0;
  45. foreach ($crops as $crop) {
  46. $userId = $crop->user_id;
  47. $oldStage = $crop->growth_stage;
  48. // 计算新的生长阶段
  49. $newStage = $this->calculateNextStage($crop);
  50. // 计算新阶段的结束时间
  51. $stageEndTime = $this->calculateStageEndTime($crop, $newStage);
  52. // 更新作物信息
  53. $crop->growth_stage = $newStage;
  54. $crop->stage_end_time = $stageEndTime;
  55. $crop->fertilized = false; // 重置施肥状态
  56. $crop->save();
  57. // 触发生长阶段变更事件
  58. event(new CropGrowthStageChangedEvent($userId, $crop, $oldStage, $newStage));
  59. $updatedCount++;
  60. $this->info("作物 ID: {$crop->id}, 用户 ID: {$userId}, 阶段: {$oldStage} -> {$newStage}");
  61. }
  62. $this->info("成功更新 {$updatedCount} 个作物的生长状态");
  63. Log::info('作物生长状态更新成功', [
  64. 'total' => $crops->count(),
  65. 'updated' => $updatedCount
  66. ]);
  67. return 0;
  68. } catch (\Exception $e) {
  69. $this->error('作物生长状态更新失败: ' . $e->getMessage());
  70. Log::error('作物生长状态更新失败', [
  71. 'error' => $e->getMessage(),
  72. 'trace' => $e->getTraceAsString()
  73. ]);
  74. return 1;
  75. }
  76. }
  77. /**
  78. * 计算下一个生长阶段
  79. *
  80. * @param FarmCrop $crop
  81. * @return int
  82. */
  83. private function calculateNextStage(FarmCrop $crop): int
  84. {
  85. $currentStage = $crop->growth_stage;
  86. // 如果当前是成熟期,且超过一定时间,则进入枯萎期
  87. if ($currentStage === GROWTH_STAGE::MATURE) {
  88. // 成熟期持续时间,默认为24小时
  89. $matureDuration = 24 * 60 * 60;
  90. // 如果成熟期已经超过指定时间,则进入枯萎期
  91. if ($crop->stage_end_time && now()->diffInSeconds($crop->stage_end_time->subSeconds($matureDuration)) > $matureDuration) {
  92. return GROWTH_STAGE::WITHERED;
  93. }
  94. return GROWTH_STAGE::MATURE;
  95. }
  96. // 正常阶段递增
  97. return $currentStage + 1;
  98. }
  99. /**
  100. * 计算阶段结束时间
  101. *
  102. * @param FarmCrop $crop
  103. * @param int $stage
  104. * @return \Carbon\Carbon|null
  105. */
  106. private function calculateStageEndTime(FarmCrop $crop, int $stage)
  107. {
  108. $seed = $crop->seed;
  109. if (!$seed) {
  110. return null;
  111. }
  112. $now = now();
  113. switch ($stage) {
  114. case GROWTH_STAGE::SEED:
  115. return $now->addSeconds($seed->seed_time);
  116. case GROWTH_STAGE::SPROUT:
  117. return $now->addSeconds($seed->sprout_time);
  118. case GROWTH_STAGE::GROWTH:
  119. return $now->addSeconds($seed->growth_time);
  120. case GROWTH_STAGE::MATURE:
  121. // 成熟期持续24小时后进入枯萎期
  122. return $now->addHours(24);
  123. case GROWTH_STAGE::WITHERED:
  124. // 枯萎期没有结束时间
  125. return null;
  126. default:
  127. return null;
  128. }
  129. }
  130. }