FixMissingTransactionRecordsCommand.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. namespace App\Module\Mex\Commands;
  3. use App\Module\Mex\Models\MexOrder;
  4. use App\Module\Mex\Models\MexTransaction;
  5. use App\Module\Mex\Enums\OrderStatus;
  6. use App\Module\Mex\Enums\TransactionType;
  7. use Illuminate\Console\Command;
  8. use Illuminate\Support\Facades\DB;
  9. /**
  10. * 修复缺失的成交记录命令
  11. *
  12. * 用于修复已完成的订单但没有对应成交记录的数据不一致问题
  13. */
  14. class FixMissingTransactionRecordsCommand extends Command
  15. {
  16. /**
  17. * 命令签名
  18. *
  19. * @var string
  20. */
  21. protected $signature = 'mex:fix-missing-transactions {--dry-run : 仅显示需要修复的数据,不执行修复}';
  22. /**
  23. * 命令描述
  24. *
  25. * @var string
  26. */
  27. protected $description = '修复Mex模块中已完成订单但缺失成交记录的数据不一致问题';
  28. /**
  29. * 仓库账户ID
  30. */
  31. const WAREHOUSE_USER_ID = 15;
  32. /**
  33. * 执行命令
  34. *
  35. * @return int
  36. */
  37. public function handle()
  38. {
  39. $this->info('开始检查Mex模块数据一致性...');
  40. // 查找已完成但没有成交记录的订单
  41. $missingTransactionOrders = $this->findOrdersWithMissingTransactions();
  42. if ($missingTransactionOrders->isEmpty()) {
  43. $this->info('✅ 没有发现数据不一致问题');
  44. return 0;
  45. }
  46. $this->warn("发现 {$missingTransactionOrders->count()} 个已完成订单缺失成交记录:");
  47. // 显示问题订单
  48. $this->displayProblematicOrders($missingTransactionOrders);
  49. if ($this->option('dry-run')) {
  50. $this->info('🔍 仅预览模式,未执行修复操作');
  51. return 0;
  52. }
  53. // 确认是否执行修复
  54. if (!$this->confirm('是否要修复这些数据不一致问题?')) {
  55. $this->info('❌ 用户取消修复操作');
  56. return 0;
  57. }
  58. // 执行修复
  59. $this->fixMissingTransactions($missingTransactionOrders);
  60. $this->info('✅ 修复完成');
  61. return 0;
  62. }
  63. /**
  64. * 查找已完成但没有成交记录的订单
  65. *
  66. * @return \Illuminate\Database\Eloquent\Collection
  67. */
  68. private function findOrdersWithMissingTransactions()
  69. {
  70. return MexOrder::where('status', OrderStatus::COMPLETED)
  71. ->whereDoesntHave('buyTransactions')
  72. ->whereDoesntHave('sellTransactions')
  73. ->orderBy('completed_at')
  74. ->get();
  75. }
  76. /**
  77. * 显示有问题的订单
  78. *
  79. * @param \Illuminate\Database\Eloquent\Collection $orders
  80. */
  81. private function displayProblematicOrders($orders)
  82. {
  83. $headers = ['订单ID', '用户ID', '商品ID', '订单类型', '数量', '价格', '总金额', '完成时间'];
  84. $rows = [];
  85. foreach ($orders as $order) {
  86. $rows[] = [
  87. $order->id,
  88. $order->user_id,
  89. $order->item_id,
  90. $order->order_type->value,
  91. $order->quantity,
  92. $order->price,
  93. $order->total_amount,
  94. $order->completed_at ? $order->completed_at->format('Y-m-d H:i:s') : '未知',
  95. ];
  96. }
  97. $this->table($headers, $rows);
  98. }
  99. /**
  100. * 修复缺失的成交记录
  101. *
  102. * @param \Illuminate\Database\Eloquent\Collection $orders
  103. */
  104. private function fixMissingTransactions($orders)
  105. {
  106. $fixedCount = 0;
  107. $errorCount = 0;
  108. foreach ($orders as $order) {
  109. try {
  110. DB::transaction(function () use ($order) {
  111. $this->createMissingTransaction($order);
  112. });
  113. $fixedCount++;
  114. $this->info("✅ 订单 {$order->id} 的成交记录已修复");
  115. } catch (\Exception $e) {
  116. $errorCount++;
  117. $this->error("❌ 订单 {$order->id} 修复失败: " . $e->getMessage());
  118. }
  119. }
  120. $this->info("修复统计: 成功 {$fixedCount} 个,失败 {$errorCount} 个");
  121. }
  122. /**
  123. * 为订单创建缺失的成交记录
  124. *
  125. * @param MexOrder $order
  126. */
  127. private function createMissingTransaction(MexOrder $order)
  128. {
  129. // 根据订单类型确定买方和卖方
  130. if ($order->order_type->value === 'BUY') {
  131. $buyOrderId = $order->id;
  132. $sellOrderId = null;
  133. $buyerId = $order->user_id;
  134. $sellerId = self::WAREHOUSE_USER_ID;
  135. $transactionType = TransactionType::USER_BUY;
  136. } else {
  137. $buyOrderId = null;
  138. $sellOrderId = $order->id;
  139. $buyerId = self::WAREHOUSE_USER_ID;
  140. $sellerId = $order->user_id;
  141. $transactionType = TransactionType::USER_SELL;
  142. }
  143. // 创建成交记录
  144. $transaction = MexTransaction::create([
  145. 'buy_order_id' => $buyOrderId,
  146. 'sell_order_id' => $sellOrderId,
  147. 'buyer_id' => $buyerId,
  148. 'seller_id' => $sellerId,
  149. 'item_id' => $order->item_id,
  150. 'currency_type' => $order->currency_type->value,
  151. 'quantity' => $order->completed_quantity ?: $order->quantity,
  152. 'price' => $order->price,
  153. 'total_amount' => $order->completed_amount ?: $order->total_amount,
  154. 'transaction_type' => $transactionType,
  155. 'is_admin_operation' => false,
  156. 'created_at' => $order->completed_at ?: $order->updated_at,
  157. ]);
  158. if (!$transaction || !$transaction->id) {
  159. throw new \Exception('成交记录创建失败');
  160. }
  161. }
  162. }