UnifiedCostCalculationJob.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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. Log::info('开始执行成本计算队列任务', $data);
  19. // 获取任务ID
  20. $taskId = $data['task_id'] ?? 0;
  21. $month = $data['month'];
  22. // 更新任务状态为执行中
  23. $this->updateTaskStatus($taskId, 'processing', [
  24. 'start_time' => date('Y-m-d H:i:s'),
  25. 'retry_count' => $job->attempts()
  26. ]);
  27. // 执行成本计算
  28. $result = $this->executeCostCalculation($month, $data['sys_id'] ?? '');
  29. if ($result['success']) {
  30. // 任务成功
  31. $job->delete();
  32. $this->updateTaskStatus($taskId, 'success', [
  33. 'end_time' => date('Y-m-d H:i:s'),
  34. 'result' => json_encode($result, JSON_UNESCAPED_UNICODE)
  35. ]);
  36. Log::info('成本计算任务执行成功', ['month' => $month, 'result' => $result]);
  37. } else {
  38. // 任务失败
  39. if ($job->attempts() >= 3) {
  40. $job->delete();
  41. $this->updateTaskStatus($taskId, 'failed', [
  42. 'end_time' => date('Y-m-d H:i:s'),
  43. 'error' => $result['message'],
  44. 'retry_count' => $job->attempts()
  45. ]);
  46. Log::error('成本计算任务重试超过3次失败', ['month' => $month, 'error' => $result['message']]);
  47. } else {
  48. $delay = $this->getRetryDelay($job->attempts());
  49. $job->release($delay);
  50. Log::warning('成本计算任务重试', ['month' => $month, 'attempts' => $job->attempts(), 'delay' => $delay]);
  51. }
  52. }
  53. } catch (\Exception $e) {
  54. Log::error('成本计算队列任务异常: ' . $e->getMessage());
  55. if ($job->attempts() >= 3) {
  56. $job->delete();
  57. $this->updateTaskStatus($taskId ?? 0, 'error', [
  58. 'end_time' => date('Y-m-d H:i:s'),
  59. 'error' => $e->getMessage(),
  60. 'retry_count' => $job->attempts()
  61. ]);
  62. } else {
  63. $job->release(60); // 延迟60秒重试
  64. }
  65. }
  66. }
  67. /**
  68. * 执行成本计算
  69. */
  70. protected function executeCostCalculation(string $month, string $sysId = ''): array
  71. {
  72. try {
  73. // 这里调用您的成本计算服务
  74. $service = new \app\service\UnifiedCostCalculationService();
  75. return $service->calculateAndSaveAll([
  76. 'month' => $month,
  77. 'sys_id' => $sysId,
  78. ]);
  79. } catch (\Exception $e) {
  80. return [
  81. 'success' => false,
  82. 'message' => '成本计算执行失败: ' . $e->getMessage()
  83. ];
  84. }
  85. }
  86. /**
  87. * 更新任务状态
  88. */
  89. protected function updateTaskStatus(int $taskId, string $status, array $data = []): void
  90. {
  91. if ($taskId <= 0) return;
  92. $updateData = array_merge(['status' => $status, 'update_time' => date('Y-m-d H:i:s')], $data);
  93. Db::name('queue_tasks')
  94. ->where('id', $taskId)
  95. ->update($updateData);
  96. }
  97. /**
  98. * 获取重试延迟时间
  99. */
  100. protected function getRetryDelay(int $attempts): int
  101. {
  102. $delays = [10, 30, 60]; // 10秒, 30秒, 1分钟
  103. return $delays[min($attempts - 1, count($delays) - 1)] ?? 60;
  104. }
  105. }