TransferCallbackCommand.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <?php
  2. namespace App\Module\Transfer\Commands;
  3. use App\Module\Transfer\Models\TransferOrder;
  4. use App\Module\Transfer\Enums\TransferStatus;
  5. use App\Module\Transfer\Jobs\SendCallbackJob;
  6. use Illuminate\Console\Command;
  7. use Illuminate\Support\Facades\Log;
  8. /**
  9. * 划转回调处理命令
  10. */
  11. class TransferCallbackCommand extends Command
  12. {
  13. /**
  14. * 命令签名
  15. *
  16. * @var string
  17. */
  18. protected $signature = 'transfer:callback
  19. {--order-id= : 指定订单ID}
  20. {--status= : 指定订单状态}
  21. {--limit=100 : 处理数量限制}
  22. {--force : 强制发送回调,忽略状态检查}
  23. {--dry-run : 仅显示将要处理的订单,不实际发送}';
  24. /**
  25. * 命令描述
  26. *
  27. * @var string
  28. */
  29. protected $description = '处理划转订单回调发送';
  30. /**
  31. * 执行命令
  32. *
  33. * @return int
  34. */
  35. public function handle(): int
  36. {
  37. $this->info('开始处理划转订单回调...');
  38. try {
  39. // 获取命令参数
  40. $orderId = $this->option('order-id');
  41. $status = $this->option('status');
  42. $limit = (int) $this->option('limit');
  43. $force = $this->option('force');
  44. $dryRun = $this->option('dry-run');
  45. // 构建查询
  46. $query = TransferOrder::with('transferApp');
  47. if ($orderId) {
  48. $query->where('id', $orderId);
  49. } else {
  50. // 默认查询已完成但未发送回调的订单
  51. if ($status) {
  52. $statusEnum = TransferStatus::tryFrom((int) $status);
  53. if (!$statusEnum) {
  54. $this->error("无效的状态值: {$status}");
  55. return 1;
  56. }
  57. $query->where('status', $statusEnum);
  58. } else {
  59. $query->where('status', TransferStatus::COMPLETED);
  60. }
  61. // 只处理支持回调的应用
  62. if (!$force) {
  63. $query->whereHas('transferApp', function ($q) {
  64. $q->whereNotNull('order_callback_url')
  65. ->where('order_callback_url', '!=', '');
  66. });
  67. // 排除已发送回调的订单
  68. $query->whereNull('callback_at');
  69. }
  70. $query->orderBy('created_at', 'asc')->limit($limit);
  71. }
  72. $orders = $query->get();
  73. if ($orders->isEmpty()) {
  74. $this->info('没有找到需要处理的订单');
  75. return 0;
  76. }
  77. $this->info("找到 {$orders->count()} 个订单需要处理");
  78. if ($dryRun) {
  79. $this->displayOrders($orders);
  80. return 0;
  81. }
  82. // 处理订单
  83. $successCount = 0;
  84. $failCount = 0;
  85. foreach ($orders as $order) {
  86. try {
  87. $this->processOrder($order, $force);
  88. $successCount++;
  89. $this->line("✓ 订单 {$order->id} 回调已加入队列");
  90. } catch (\Exception $e) {
  91. $failCount++;
  92. $this->error("✗ 订单 {$order->id} 处理失败: {$e->getMessage()}");
  93. Log::error('Transfer callback command error', [
  94. 'order_id' => $order->id,
  95. 'error' => $e->getMessage()
  96. ]);
  97. }
  98. }
  99. $this->info("处理完成: 成功 {$successCount} 个,失败 {$failCount} 个");
  100. return $failCount > 0 ? 1 : 0;
  101. } catch (\Exception $e) {
  102. $this->error("命令执行失败: {$e->getMessage()}");
  103. Log::error('Transfer callback command failed', [
  104. 'error' => $e->getMessage(),
  105. 'trace' => $e->getTraceAsString()
  106. ]);
  107. return 1;
  108. }
  109. }
  110. /**
  111. * 处理单个订单
  112. *
  113. * @param TransferOrder $order
  114. * @param bool $force
  115. * @return void
  116. */
  117. protected function processOrder(TransferOrder $order, bool $force): void
  118. {
  119. // 检查应用是否支持回调
  120. if (!$force && !$order->transferApp->supportsCallback()) {
  121. throw new \Exception('应用不支持回调');
  122. }
  123. // 检查是否已发送回调
  124. if (!$force && $order->callback_at) {
  125. throw new \Exception('回调已发送');
  126. }
  127. // 发送回调任务
  128. SendCallbackJob::dispatch($order);
  129. Log::info('Transfer callback job dispatched', [
  130. 'order_id' => $order->id,
  131. 'force' => $force
  132. ]);
  133. }
  134. /**
  135. * 显示订单列表
  136. *
  137. * @param \Illuminate\Support\Collection $orders
  138. * @return void
  139. */
  140. protected function displayOrders($orders): void
  141. {
  142. $headers = ['订单ID', '类型', '状态', '金额', '用户ID', '应用', '创建时间', '回调时间'];
  143. $rows = [];
  144. foreach ($orders as $order) {
  145. $rows[] = [
  146. $order->id,
  147. $order->type->getDescription(),
  148. $order->status->getDescription(),
  149. $order->amount,
  150. $order->user_id,
  151. $order->transferApp->title,
  152. $order->created_at->format('Y-m-d H:i:s'),
  153. $order->callback_at ? $order->callback_at->format('Y-m-d H:i:s') : '-'
  154. ];
  155. }
  156. $this->table($headers, $rows);
  157. }
  158. /**
  159. * 获取状态选项说明
  160. *
  161. * @return void
  162. */
  163. protected function showStatusOptions(): void
  164. {
  165. $this->info('可用的状态值:');
  166. foreach (TransferStatus::cases() as $status) {
  167. $this->line(" {$status->value} - {$status->getDescription()}");
  168. }
  169. }
  170. }