DisasterService.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <?php
  2. namespace App\Module\Farm\Services;
  3. use App\Module\Farm\Enums\DISASTER_TYPE;
  4. use App\Module\Farm\Logics\DisasterLogic;
  5. use Illuminate\Support\Facades\Log;
  6. class DisasterService
  7. {
  8. /**
  9. * 获取所有灾害 减产比例
  10. *
  11. * @return float[]
  12. */
  13. public static function getAllDisasters()
  14. {
  15. $disasterTypes = [
  16. DISASTER_TYPE::DROUGHT->valueInt() => 0.05, // 干旱
  17. DISASTER_TYPE::PEST->valueInt() => 0.05, // 虫害
  18. DISASTER_TYPE::WEED->valueInt() => 0.05, // 杂草
  19. ];
  20. return $disasterTypes;
  21. }
  22. /**
  23. * 获取灾害 产生比例
  24. *
  25. * @return float[]
  26. */
  27. public static function getRate()
  28. {
  29. $disasterTypes = [
  30. DISASTER_TYPE::DROUGHT->valueInt() => 0.9, // 干旱
  31. DISASTER_TYPE::PEST->valueInt() => 0.9, // 虫害
  32. DISASTER_TYPE::WEED->valueInt() => 0.9, // 杂草
  33. ];
  34. return $disasterTypes;
  35. }
  36. /**
  37. * 获取灾害类型对应的键名
  38. *
  39. * @param int $disasterType
  40. * @return string
  41. */
  42. public static function getDisasterKey(int $disasterType): string
  43. {
  44. $keys = [
  45. DISASTER_TYPE::DROUGHT->valueInt() => 'drought',
  46. DISASTER_TYPE::PEST->valueInt() => 'pest',
  47. DISASTER_TYPE::WEED->valueInt() => 'weed',
  48. ];
  49. return $keys[$disasterType] ?? '';
  50. }
  51. /**
  52. * 灾害检查间隔时间(分钟)
  53. *
  54. * @return int
  55. */
  56. public static function getCheckInterval(): int
  57. {
  58. return 5; // 每5分钟检查一次
  59. }
  60. /**
  61. * 批量生成灾害
  62. *
  63. * @param int|null $checkIntervalMinutes 检查间隔(分钟)
  64. * @return array 生成结果统计
  65. */
  66. public static function generateDisasterBatchs(?int $checkIntervalMinutes = null): array
  67. {
  68. try {
  69. $disasterLogic = new DisasterLogic();
  70. // 获取需要检查的作物列表
  71. $crops = $disasterLogic->getCropsNeedingDisasterCheck($checkIntervalMinutes);
  72. $totalCount = $crops->count();
  73. $generatedCount = 0;
  74. $skippedCount = 0;
  75. // 为每个作物单独处理,使用独立事务
  76. foreach ($crops as $crop) {
  77. try {
  78. // 为每个作物的灾害生成使用独立事务
  79. $result = \Illuminate\Support\Facades\DB::transaction(function () use ($disasterLogic, $crop) {
  80. return $disasterLogic->generateDisasters($crop);
  81. });
  82. if ($result === 'generated') {
  83. $generatedCount++;
  84. } elseif ($result === 'skipped') {
  85. $skippedCount++;
  86. }
  87. } catch (\Exception $e) {
  88. Log::error('单个作物灾害生成事务失败', [
  89. 'crop_id' => $crop->id,
  90. 'user_id' => $crop->user_id,
  91. 'error' => $e->getMessage()
  92. ]);
  93. $skippedCount++;
  94. }
  95. }
  96. return [
  97. 'total' => $totalCount,
  98. 'generated' => $generatedCount,
  99. 'skipped' => $skippedCount
  100. ];
  101. } catch (\Exception $e) {
  102. Log::error('批量生成灾害失败', [
  103. 'check_interval_minutes' => $checkIntervalMinutes,
  104. 'error' => $e->getMessage(),
  105. 'trace' => $e->getTraceAsString()
  106. ]);
  107. // 重新抛出异常,不隐藏错误
  108. throw $e;
  109. }
  110. }
  111. }