ScanTablesCommand.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. namespace App\Module\Cleanup\Commands;
  3. use App\Module\Cleanup\Services\CleanupService;
  4. use Illuminate\Console\Command;
  5. /**
  6. * 扫描数据表命令
  7. *
  8. * 扫描系统中的所有数据表并生成清理配置
  9. */
  10. class ScanTablesCommand extends Command
  11. {
  12. /**
  13. * 命令签名
  14. */
  15. protected $signature = 'cleanup:scan-tables
  16. {--force : 强制重新扫描所有表}
  17. {--show-details : 显示详细信息}';
  18. /**
  19. * 命令描述
  20. */
  21. protected $description = '扫描系统中的所有数据表并生成清理配置';
  22. /**
  23. * 执行命令
  24. */
  25. public function handle(): int
  26. {
  27. $this->info('开始扫描数据表...');
  28. $this->newLine();
  29. $forceRefresh = $this->option('force');
  30. $showDetails = $this->option('show-details');
  31. if ($forceRefresh) {
  32. $this->warn('强制刷新模式:将重新生成所有表的配置');
  33. }
  34. try {
  35. // 执行扫描
  36. $result = CleanupService::scanTables($forceRefresh);
  37. // 显示扫描结果
  38. $this->displayScanResults($result, $showDetails);
  39. $this->newLine();
  40. $this->info('✅ 数据表扫描完成!');
  41. return Command::SUCCESS;
  42. } catch (\Exception $e) {
  43. $this->error('❌ 扫描失败: ' . $e->getMessage());
  44. $this->error('详细错误: ' . $e->getTraceAsString());
  45. return Command::FAILURE;
  46. }
  47. }
  48. /**
  49. * 显示扫描结果
  50. *
  51. * @param array $result 扫描结果
  52. * @param bool $showDetails 是否显示详细信息
  53. */
  54. private function displayScanResults(array $result, bool $showDetails): void
  55. {
  56. // 显示统计信息
  57. $this->info("📊 扫描统计:");
  58. $this->table(
  59. ['项目', '数量'],
  60. [
  61. ['总表数', $result['total_tables']],
  62. ['已扫描', $result['scanned_tables']],
  63. ['新增配置', $result['new_tables']],
  64. ['更新配置', $result['updated_tables']],
  65. ['扫描耗时', $result['scan_time'] . ' 秒'],
  66. ]
  67. );
  68. if (!$showDetails) {
  69. return;
  70. }
  71. $this->newLine();
  72. $this->info("📋 表详细信息:");
  73. // 按数据分类分组显示
  74. $tablesByCategory = [];
  75. foreach ($result['tables'] as $table) {
  76. $category = $table['data_category_name'];
  77. if (!isset($tablesByCategory[$category])) {
  78. $tablesByCategory[$category] = [];
  79. }
  80. $tablesByCategory[$category][] = $table;
  81. }
  82. foreach ($tablesByCategory as $category => $tables) {
  83. $this->newLine();
  84. $this->line("<fg=cyan>📁 {$category} ({count($tables)} 个表)</>");
  85. $tableData = [];
  86. foreach ($tables as $table) {
  87. $status = [];
  88. if ($table['is_new']) {
  89. $status[] = '<fg=green>新增</>';
  90. }
  91. if ($table['is_updated']) {
  92. $status[] = '<fg=yellow>更新</>';
  93. }
  94. $tableData[] = [
  95. $table['table_name'],
  96. $table['module_name'],
  97. number_format($table['record_count']),
  98. $table['table_size_mb'] . ' MB',
  99. $table['has_time_field'] ? '✅' : '❌',
  100. $table['has_user_field'] ? '✅' : '❌',
  101. implode(' ', $status) ?: '-',
  102. ];
  103. }
  104. $this->table(
  105. ['表名', '模块', '记录数', '大小', '时间字段', '用户字段', '状态'],
  106. $tableData
  107. );
  108. }
  109. // 显示字段分析
  110. $this->newLine();
  111. $this->info("🔍 字段分析:");
  112. $timeFieldTables = array_filter($result['tables'], fn($t) => $t['has_time_field']);
  113. $userFieldTables = array_filter($result['tables'], fn($t) => $t['has_user_field']);
  114. $this->table(
  115. ['分析项', '数量', '百分比'],
  116. [
  117. ['包含时间字段的表', count($timeFieldTables), round(count($timeFieldTables) / $result['total_tables'] * 100, 1) . '%'],
  118. ['包含用户字段的表', count($userFieldTables), round(count($userFieldTables) / $result['total_tables'] * 100, 1) . '%'],
  119. ]
  120. );
  121. // 显示推荐的清理计划
  122. $this->newLine();
  123. $this->info("💡 推荐的清理计划:");
  124. $recommendations = CleanupService::getRecommendedPlans();
  125. if (empty($recommendations)) {
  126. $this->line('暂无推荐的清理计划');
  127. } else {
  128. foreach ($recommendations as $recommendation) {
  129. $this->line("• {$recommendation['title']} - {$recommendation['description']} (预计 {$recommendation['estimated_tables']} 个表)");
  130. }
  131. }
  132. }
  133. }