UnifiedCostCalculationJob.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. <?php
  2. namespace app\job;
  3. use think\Db;
  4. use think\Log;
  5. /**
  6. * 成本计算队列任务
  7. */
  8. class UnifiedCostCalculationJob
  9. {
  10. /**
  11. * 任务处理方法
  12. * @param \think\Job $job 任务对象
  13. * @param array $data 任务数据
  14. */
  15. public function fire($job, $data)
  16. {
  17. try {
  18. $taskId = $data['task_id'] ?? 0;
  19. $month = $data['month'] ?? '';
  20. // 更新任务状态为执行中(须先于 Log,且勿用 Log::info($msg, $array) — TP5 第二参是 type 会触发 Illegal offset type)
  21. $this->updateTaskStatus($taskId, 'processing', [
  22. 'start_time' => date('Y-m-d H:i:s'),
  23. 'retry_count' => $job->attempts()
  24. ]);
  25. Log::info('开始执行成本计算队列任务: ' . json_encode($data, JSON_UNESCAPED_UNICODE));
  26. // 执行成本计算
  27. $result = $this->executeCostCalculation($month, $data['sys_id'] ?? '');
  28. if ($result['success']) {
  29. // 任务成功
  30. $job->delete();
  31. $this->updateTaskStatus($taskId, 'success', [
  32. 'end_time' => date('Y-m-d H:i:s'),
  33. 'result' => json_encode($result, JSON_UNESCAPED_UNICODE)
  34. ]);
  35. Log::info('成本计算任务执行成功', ['month' => $month, 'result' => $result]);
  36. } else {
  37. // 任务失败
  38. if ($job->attempts() >= 3) {
  39. $job->delete();
  40. $this->updateTaskStatus($taskId, 'failed', [
  41. 'end_time' => date('Y-m-d H:i:s'),
  42. 'error' => $result['message'],
  43. 'retry_count' => $job->attempts()
  44. ]);
  45. Log::error('成本计算任务重试超过3次失败', ['month' => $month, 'error' => $result['message']]);
  46. } else {
  47. $delay = $this->getRetryDelay($job->attempts());
  48. $job->release($delay);
  49. Log::warning('成本计算任务重试', ['month' => $month, 'attempts' => $job->attempts(), 'delay' => $delay]);
  50. }
  51. }
  52. } catch (\Throwable $e) {
  53. Log::error('成本计算队列任务异常: ' . $e->getMessage());
  54. if ($job->attempts() >= 3) {
  55. $job->delete();
  56. $this->updateTaskStatus($taskId ?? 0, 'error', [
  57. 'end_time' => date('Y-m-d H:i:s'),
  58. 'error' => $e->getMessage(),
  59. 'retry_count' => $job->attempts()
  60. ]);
  61. } else {
  62. $job->release(60); // 延迟60秒重试
  63. }
  64. }
  65. }
  66. /**
  67. * 执行成本计算
  68. */
  69. protected function executeCostCalculation(string $month, string $sysId = ''): array
  70. {
  71. try {
  72. // 这里调用您的成本计算服务
  73. $service = new \app\service\UnifiedCostCalculationService();
  74. return $service->calculateAndSaveAll([
  75. 'month' => $month,
  76. 'sys_id' => $sysId,
  77. ]);
  78. } catch (\Exception $e) {
  79. return [
  80. 'success' => false,
  81. 'message' => '成本计算执行失败: ' . $e->getMessage()
  82. ];
  83. }
  84. }
  85. /**
  86. * 更新任务状态
  87. */
  88. protected function updateTaskStatus($taskId, string $status, array $data = []): void
  89. {
  90. if (empty($taskId)) {
  91. return;
  92. }
  93. $updateData = array_merge(['status' => $status, 'update_time' => date('Y-m-d H:i:s')], $data);
  94. Db::name('queue_tasks')
  95. ->where('id', $taskId)
  96. ->update($updateData);
  97. }
  98. /**
  99. * 获取重试延迟时间
  100. */
  101. protected function getRetryDelay(int $attempts): int
  102. {
  103. $delays = [10, 30, 60]; // 10秒, 30秒, 1分钟
  104. return $delays[min($attempts - 1, count($delays) - 1)] ?? 60;
  105. }
  106. }