cleanup-orders.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /**
  2. * 订单清理脚本
  3. * 用于手动清理 Pacifica 账户的开放订单
  4. *
  5. * 使用方法:
  6. * npm run cleanup-orders # 清理所有账户的订单
  7. * npm run cleanup-orders -- --dry # 干运行模式,只显示要清理的订单
  8. */
  9. import { ConfigManager } from '../src/core/ConfigManager';
  10. import { AccountManager } from '../src/services/AccountManager';
  11. import { OrderCleanupService, CleanupOptions } from '../src/services/OrderCleanupService';
  12. import Logger from '../src/utils/Logger';
  13. async function main() {
  14. const logger = Logger.getInstance();
  15. const configManager = ConfigManager.getInstance();
  16. const accountManager = new AccountManager();
  17. const cleanupService = new OrderCleanupService();
  18. try {
  19. console.log('\n🧹 Pacifica 订单清理工具');
  20. console.log('==========================================\n');
  21. // 检查是否为干运行模式
  22. const isDryRun = process.argv.includes('--dry') || process.argv.includes('-d');
  23. if (isDryRun) {
  24. console.log('⚠️ 干运行模式:只显示要清理的订单,不实际执行\n');
  25. }
  26. // 初始化账户管理器
  27. logger.info('初始化账户管理器...');
  28. await accountManager.initialize();
  29. const accounts = accountManager.getActiveAccounts();
  30. if (accounts.length === 0) {
  31. console.log('❌ 没有找到活跃账户');
  32. process.exit(1);
  33. }
  34. console.log(`📊 找到 ${accounts.length} 个活跃账户\n`);
  35. // 为每个账户初始化清理服务
  36. for (const account of accounts) {
  37. cleanupService.initializeAccount(account);
  38. console.log(`✅ 账户已加载: ${account.getName()} (${account.getId()})`);
  39. }
  40. console.log('\n------------------------------------------\n');
  41. // 清理选项
  42. const cleanupOptions: CleanupOptions = {
  43. cleanAll: true, // 清理所有订单
  44. includeReduceOnly: false, // 不清理 reduce_only 订单
  45. mode: 'selective', // 逐个取消
  46. dryRun: isDryRun
  47. };
  48. console.log('🔧 清理选项:', {
  49. 清理所有订单: cleanupOptions.cleanAll,
  50. 包含ReduceOnly订单: cleanupOptions.includeReduceOnly,
  51. 模式: cleanupOptions.mode,
  52. 干运行: cleanupOptions.dryRun
  53. });
  54. console.log('\n------------------------------------------\n');
  55. // 执行清理
  56. const startTime = Date.now();
  57. console.log('🚀 开始清理订单...\n');
  58. const results = await cleanupService.cleanupMultipleAccounts(
  59. accounts,
  60. cleanupOptions
  61. );
  62. const duration = Date.now() - startTime;
  63. // 汇总结果
  64. console.log('\n==========================================');
  65. console.log('📊 清理结果汇总');
  66. console.log('==========================================\n');
  67. let totalOrders = 0;
  68. let totalCancelled = 0;
  69. let totalFailed = 0;
  70. for (const [accountId, result] of results.entries()) {
  71. const account = accounts.find(acc => acc.getId() === accountId);
  72. const accountName = account ? account.getName() : accountId;
  73. totalOrders += result.totalOrders;
  74. totalCancelled += result.cancelledOrders;
  75. totalFailed += result.failedOrders;
  76. console.log(`📌 ${accountName} (${accountId})`);
  77. console.log(` 开放订单: ${result.totalOrders}`);
  78. console.log(` 需要清理: ${result.ordersToClean}`);
  79. if (isDryRun) {
  80. console.log(` 将要取消: ${result.ordersToClean}`);
  81. } else {
  82. console.log(` 已取消: ${result.cancelledOrders}`);
  83. console.log(` 失败: ${result.failedOrders}`);
  84. }
  85. console.log(` 耗时: ${result.duration}ms\n`);
  86. // 如果有错误,显示详情
  87. if (result.errors.length > 0) {
  88. console.log(` ⚠️ 错误详情:`);
  89. result.errors.slice(0, 3).forEach(error => {
  90. console.log(` 订单ID ${error.orderId}: ${error.error}`);
  91. });
  92. if (result.errors.length > 3) {
  93. console.log(` ... 还有 ${result.errors.length - 3} 个错误`);
  94. }
  95. console.log('');
  96. }
  97. }
  98. console.log('==========================================');
  99. console.log('🎯 总计');
  100. console.log('==========================================');
  101. console.log(`账户数: ${accounts.length}`);
  102. console.log(`总订单数: ${totalOrders}`);
  103. if (isDryRun) {
  104. console.log(`将要取消: ${totalCancelled}`);
  105. } else {
  106. console.log(`成功取消: ${totalCancelled}`);
  107. console.log(`取消失败: ${totalFailed}`);
  108. }
  109. console.log(`总耗时: ${duration}ms`);
  110. console.log('==========================================\n');
  111. if (isDryRun) {
  112. console.log('💡 提示: 移除 --dry 参数以实际执行清理\n');
  113. } else if (totalCancelled > 0) {
  114. console.log('✅ 订单清理完成!\n');
  115. } else if (totalOrders === 0) {
  116. console.log('✅ 没有需要清理的订单\n');
  117. } else {
  118. console.log('⚠️ 清理完成,但有部分订单清理失败\n');
  119. }
  120. // 清理资源
  121. await accountManager.shutdown();
  122. await cleanupService.shutdown();
  123. process.exit(0);
  124. } catch (error) {
  125. logger.error('订单清理失败', {
  126. error: error instanceof Error ? error.message : '未知错误'
  127. });
  128. console.error('\n❌ 订单清理失败:', error instanceof Error ? error.message : '未知错误');
  129. process.exit(1);
  130. }
  131. }
  132. // 运行脚本
  133. main().catch(error => {
  134. console.error('脚本执行失败:', error);
  135. process.exit(1);
  136. });