# Action: Generate Report 汇总所有发现,生成结构化审查报告。 ## Purpose 生成最终的代码审查报告: - 汇总所有维度的发现 - 按严重程度排序 - 提供统计摘要 - 输出 Markdown 格式报告 ## Preconditions - [ ] state.status === 'running' - [ ] 所有维度已审查完成 (reviewed_dimensions.length === 6) ## Execution ```javascript async function execute(state, workDir) { const context = state.context; const findings = state.findings; // 1. 汇总所有发现 const allFindings = [ ...findings.correctness, ...findings.readability, ...findings.performance, ...findings.security, ...findings.testing, ...findings.architecture ]; // 2. 按严重程度排序 const severityOrder = { critical: 0, high: 1, medium: 2, low: 3, info: 4 }; allFindings.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]); // 3. 统计 const stats = { total_issues: allFindings.length, critical: allFindings.filter(f => f.severity === 'critical').length, high: allFindings.filter(f => f.severity === 'high').length, medium: allFindings.filter(f => f.severity === 'medium').length, low: allFindings.filter(f => f.severity === 'low').length, info: allFindings.filter(f => f.severity === 'info').length, by_dimension: { correctness: findings.correctness.length, readability: findings.readability.length, performance: findings.performance.length, security: findings.security.length, testing: findings.testing.length, architecture: findings.architecture.length } }; // 4. 生成报告 const report = generateMarkdownReport(context, stats, allFindings, state.scan_summary); // 5. 保存报告 const reportPath = `${workDir}/review-report.md`; Write(reportPath, report); return { stateUpdates: { report_generated: true, report_path: reportPath, summary: { ...stats, review_duration_ms: Date.now() - new Date(state.started_at).getTime() } } }; } function generateMarkdownReport(context, stats, findings, scanSummary) { const severityEmoji = { critical: '🔴', high: '🟠', medium: '🟡', low: '🔵', info: '⚪' }; let report = `# Code Review Report ## 审查概览 | 项目 | 值 | |------|------| | 目标路径 | \`${context.target_path}\` | | 文件数量 | ${context.file_count} | | 代码行数 | ${context.total_lines} | | 主要语言 | ${context.language} | | 框架 | ${context.framework || 'N/A'} | ## 问题统计 | 严重程度 | 数量 | |----------|------| | 🔴 Critical | ${stats.critical} | | 🟠 High | ${stats.high} | | 🟡 Medium | ${stats.medium} | | 🔵 Low | ${stats.low} | | ⚪ Info | ${stats.info} | | **总计** | **${stats.total_issues}** | ### 按维度统计 | 维度 | 问题数 | |------|--------| | Correctness (正确性) | ${stats.by_dimension.correctness} | | Security (安全性) | ${stats.by_dimension.security} | | Performance (性能) | ${stats.by_dimension.performance} | | Readability (可读性) | ${stats.by_dimension.readability} | | Testing (测试) | ${stats.by_dimension.testing} | | Architecture (架构) | ${stats.by_dimension.architecture} | --- ## 高风险区域 `; if (scanSummary?.risk_areas?.length > 0) { report += `| 文件 | 原因 | 优先级 | |------|------|--------| `; for (const area of scanSummary.risk_areas.slice(0, 10)) { report += `| \`${area.file}\` | ${area.reason} | ${area.priority} |\n`; } } else { report += `未发现明显的高风险区域。\n`; } report += ` --- ## 问题详情 `; // 按维度分组输出 const dimensions = ['correctness', 'security', 'performance', 'readability', 'testing', 'architecture']; const dimensionNames = { correctness: '正确性 (Correctness)', security: '安全性 (Security)', performance: '性能 (Performance)', readability: '可读性 (Readability)', testing: '测试 (Testing)', architecture: '架构 (Architecture)' }; for (const dim of dimensions) { const dimFindings = findings.filter(f => f.dimension === dim); if (dimFindings.length === 0) continue; report += `### ${dimensionNames[dim]} `; for (const finding of dimFindings) { report += `#### ${severityEmoji[finding.severity]} [${finding.id}] ${finding.category} - **严重程度**: ${finding.severity.toUpperCase()} - **文件**: \`${finding.file}\`${finding.line ? `:${finding.line}` : ''} - **描述**: ${finding.description} `; if (finding.code_snippet) { report += ` \`\`\` ${finding.code_snippet} \`\`\` `; } report += ` **建议**: ${finding.recommendation} `; if (finding.fix_example) { report += ` **修复示例**: \`\`\` ${finding.fix_example} \`\`\` `; } report += ` --- `; } } report += ` ## 审查建议 ### 必须修复 (Must Fix) ${stats.critical + stats.high > 0 ? `发现 ${stats.critical} 个严重问题和 ${stats.high} 个高优先级问题,建议在合并前修复。` : '未发现必须立即修复的问题。'} ### 建议改进 (Should Fix) ${stats.medium > 0 ? `发现 ${stats.medium} 个中等优先级问题,建议在后续迭代中改进。` : '代码质量良好,无明显需要改进的地方。'} ### 可选优化 (Nice to Have) ${stats.low + stats.info > 0 ? `发现 ${stats.low + stats.info} 个低优先级建议,可根据团队规范酌情处理。` : '无额外建议。'} --- *报告生成时间: ${new Date().toISOString()}* `; return report; } ``` ## State Updates ```javascript return { stateUpdates: { report_generated: true, report_path: reportPath, summary: { total_issues: totalCount, critical: criticalCount, high: highCount, medium: mediumCount, low: lowCount, info: infoCount, review_duration_ms: duration } } }; ``` ## Output - **File**: `review-report.md` - **Location**: `${workDir}/review-report.md` - **Format**: Markdown ## Error Handling | Error Type | Recovery | |------------|----------| | 写入失败 | 尝试备用位置 | | 模板错误 | 使用简化格式 | ## Next Actions - 成功: action-complete