diff --git a/extend/base/admin/service/AdminUpdateServiceBase.php b/extend/base/admin/service/AdminUpdateServiceBase.php index c6a37a1..12b796e 100644 --- a/extend/base/admin/service/AdminUpdateServiceBase.php +++ b/extend/base/admin/service/AdminUpdateServiceBase.php @@ -381,12 +381,121 @@ class AdminUpdateServiceBase $add_count = count(array_filter($need_process_files, fn($t) => $t === 'add')); $delete_count = count(array_filter($need_process_files, fn($t) => $t === 'delete')); $update_count = count(array_filter($need_process_files, fn($t) => $t === 'update')); + $output->writeln(''); $output->writeln('[预览模式] 以下文件将被变更:'); - foreach ($need_process_files as $file_path => $type) { - $output->writeln(" [{$type}] " . $file_path); + + // Determine which files to show + $showScope = $this->showScope ?: 'all'; + $display_files = []; + + if ($showScope === 'conflict') { + // Only show conflict files + foreach ($optional_update_waring_files as $fp => $t) { + $label = "[{$t}]"; + if (isset($need_process_files[$fp])) { + $label .= "[conflict:optional:overwrite]"; + } else { + $label .= "[skipped][conflict:optional:skip]"; + } + $display_files[$fp] = $label; + } + foreach ($force_update_waring_files as $fp => $t) { + $label = "[{$t}]"; + if (isset($need_process_files[$fp])) { + $label .= "[conflict:force:overwrite]"; + } else { + $label .= "[skipped][conflict:force:skip]"; + } + $display_files[$fp] = $label; + } + } else { + // Show all files (default) + // First add all non-conflict files from need_process_files + foreach ($need_process_files as $fp => $t) { + $label = "[{$t}]"; + // Check if this is a conflict file + if (isset($optional_update_waring_files[$fp])) { + $label .= "[conflict:optional:overwrite]"; + } elseif (isset($force_update_waring_files[$fp])) { + $label .= "[conflict:force:overwrite]"; + } + $display_files[$fp] = $label; + } + // Then add skipped conflict files + foreach ($this->skippedConflictFiles as $fp => $info) { + $t = $info['type']; + $cat = $info['category']; + $display_files[$fp] = "[{$t}][skipped][conflict:{$cat}:skip]"; + } } + + // Group by directory if > 5 files + if (count($display_files) > 5) { + $groups = []; + $dir_order = ['extend/base/', 'extend/think/', 'app/', 'config/', 'route/', 'public/', 'database/', 'composer']; + foreach ($display_files as $fp => $label) { + $group_name = '其他'; + foreach ($dir_order as $prefix) { + if (str_starts_with($fp, $prefix)) { + $group_name = $prefix; + break; + } + } + // Root files (no /) + if (strpos($fp, '/') === false) { + $group_name = '根目录'; + } + $groups[$group_name][$fp] = $label; + } + foreach ($groups as $group_name => $files) { + $output->writeln(" [{$group_name}]"); + foreach ($files as $fp => $label) { + $output->writeln(" {$label} " . $fp); + } + } + } else { + foreach ($display_files as $fp => $label) { + $output->writeln(" {$label} " . $fp); + } + } + $output->writeln("统计: 新增 {$add_count}, 删除 {$delete_count}, 更新 {$update_count}"); + + // Risk summary + $force_conflict_count = count($force_update_waring_files); + $optional_conflict_count = count($optional_update_waring_files); + $no_conflict_count = count($need_process_files) - $force_conflict_count - $optional_conflict_count; + if ($no_conflict_count < 0) $no_conflict_count = 0; + $output->writeln("风险评估: 强制冲突 {$force_conflict_count}个(高风险) | 可选冲突 {$optional_conflict_count}个(中风险) | 无冲突变更 {$no_conflict_count}个(低风险)"); + } + + // 非 dry-run 模式:仅在显式传了 --show 时输出变更摘要 + if (!$this->dryRun && $this->showScope !== null && !empty($need_process_files)) { + $showScope = $this->showScope ?: 'all'; + $output->writeln(''); + $output->writeln('变更摘要:'); + + if ($showScope === 'conflict') { + $conflict_count = count($optional_update_waring_files) + count($force_update_waring_files); + $output->writeln(" 冲突文件: {$conflict_count}个"); + foreach ($optional_update_waring_files as $fp => $t) { + $processed = isset($need_process_files[$fp]) ? '已处理' : '已跳过'; + $output->writeln(" [可选][{$processed}] " . $fp); + } + foreach ($force_update_waring_files as $fp => $t) { + $processed = isset($need_process_files[$fp]) ? '已处理' : '已跳过'; + $output->writeln(" [强制][{$processed}] " . $fp); + } + } else { + $output->writeln(" 变更文件: " . count($need_process_files) . "个"); + } + + $force_conflict_count = count($force_update_waring_files); + $optional_conflict_count = count($optional_update_waring_files); + $no_conflict_count = count($need_process_files) - $force_conflict_count - $optional_conflict_count; + if ($no_conflict_count < 0) $no_conflict_count = 0; + $output->writeln("风险评估: 强制冲突 {$force_conflict_count}个(高风险) | 可选冲突 {$optional_conflict_count}个(中风险) | 无冲突变更 {$no_conflict_count}个(低风险)"); } // 对比 composer.json 依赖差异