From fe92640a8bb57552c5a4c6a1337aa7896da109f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=B4=8B?= <2146658457@qq.com> Date: Tue, 18 Nov 2025 14:05:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend.js | 148 ++++++++++ src/frontend/index.html | 15 +- src/frontend/js/app.js | 67 +++++ src/server/services/aiAnalyzer.js | 472 +++++++++++++++++++++++++----- src/start_server.bat | 9 +- src/配置中心设计.md | 424 +++++++++++++++++++++++++++ 6 files changed, 1056 insertions(+), 79 deletions(-) create mode 100644 src/配置中心设计.md diff --git a/src/backend.js b/src/backend.js index 5aea270..7625b75 100644 --- a/src/backend.js +++ b/src/backend.js @@ -841,6 +841,154 @@ app.post('/api/projects/:id/check', async (req, res) => { } }); +// 导出分析报告为Markdown +app.post('/api/projects/:id/export-report', (req, res) => { + try { + const projectId = parseInt(req.params.id); + const project = projects.find(p => p.id === projectId); + + if (!project) { + return res.status(404).json({ + success: false, + error: '项目不存在' + }); + } + + const resultData = req.body.resultData; + if (!resultData || !resultData.all_issues) { + return res.status(400).json({ + success: false, + error: '缺少检查结果数据' + }); + } + + // 生成Markdown报告 + const markdown = generateMarkdownReport(project, resultData); + + // 设置响应头,支持下载 + const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5); + const filename = `${project.name}_报告_${timestamp}.md`; + + res.setHeader('Content-Type', 'text/markdown; charset=utf-8'); + res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(filename)}"`); + res.send(markdown); + } catch (error) { + console.error('导出报告失败:', error); + res.status(500).json({ + success: false, + error: error.message + }); + } +}); + +// 生成Markdown报告 +function generateMarkdownReport(project, resultData) { + const issues = resultData.all_issues || []; + const timestamp = new Date().toLocaleString('zh-CN'); + + let markdown = `# 代码质量检查报告\n\n`; + markdown += `**项目名称:** ${project.name}\n`; + markdown += `**检查时间:** ${timestamp}\n`; + markdown += `**项目路径:** ${project.path}\n\n`; + + // 统计信息 + const errorCount = resultData.error_count || issues.filter(i => i.type === 'error').length; + const warningCount = resultData.warning_count || issues.filter(i => i.type === 'warning').length; + const infoCount = resultData.info_count || issues.filter(i => i.type === 'info').length; + const totalCount = resultData.total_issues || issues.length; + + markdown += `## 📊 检查结果摘要\n\n`; + markdown += `| 类型 | 数量 |\n`; + markdown += `|------|------|\n`; + markdown += `| ❌ 错误 | ${errorCount} |\n`; + markdown += `| ⚠️ 警告 | ${warningCount} |\n`; + markdown += `| ℹ️ 信息 | ${infoCount} |\n`; + markdown += `| 📋 总计 | ${totalCount} |\n\n`; + + // AI分析统计 + if (resultData.ai_analyzed) { + const highRiskCount = resultData.high_risk_count || issues.filter(i => i.risk_level === 'high').length; + const mediumRiskCount = resultData.medium_risk_count || issues.filter(i => i.risk_level === 'medium').length; + const lowRiskCount = resultData.low_risk_count || issues.filter(i => i.risk_level === 'low').length; + const duplicatesRemoved = resultData.duplicates_removed || 0; + const analysisMethod = resultData.analysis_method || 'none'; + + markdown += `## 🤖 AI分析结果\n\n`; + markdown += `**分析方式:** ${analysisMethod === 'ai-powered' ? 'AI增强分析' : '规则基础分析'}\n`; + if (duplicatesRemoved > 0) { + markdown += `**去重数量:** ${duplicatesRemoved} 个重复问题已合并\n`; + } + markdown += `\n### 风险评估\n\n`; + markdown += `| 风险等级 | 数量 |\n`; + markdown += `|----------|------|\n`; + markdown += `| 🔴 高风险 | ${highRiskCount} |\n`; + markdown += `| 🟡 中风险 | ${mediumRiskCount} |\n`; + markdown += `| 🟢 低风险 | ${lowRiskCount} |\n\n`; + } + + // 问题详情 + markdown += `## 🔍 问题详情\n\n`; + + if (issues.length === 0) { + markdown += `✅ **检查完成!未发现任何问题,代码质量良好。**\n`; + } else { + // 按文件分组 + const issuesByFile = new Map(); + issues.forEach(issue => { + const filePath = issue.relative_path || issue.file || '未知文件'; + if (!issuesByFile.has(filePath)) { + issuesByFile.set(filePath, []); + } + issuesByFile.get(filePath).push(issue); + }); + + let issueIndex = 1; + for (const [filePath, fileIssues] of issuesByFile.entries()) { + markdown += `### 📄 文件: ${filePath}\n\n`; + + fileIssues.forEach(issue => { + const riskLevel = issue.risk_level || 'low'; + const riskEmoji = riskLevel === 'high' ? '🔴' : riskLevel === 'medium' ? '🟡' : '🟢'; + const riskLabel = riskLevel === 'high' ? '高风险' : riskLevel === 'medium' ? '中风险' : '低风险'; + + markdown += `#### 问题 #${issueIndex}\n\n`; + markdown += `- **位置:** ${filePath}:${issue.line}:${issue.column || 0}\n`; + markdown += `- **类型:** ${issue.type || 'unknown'}\n`; + markdown += `- **规则:** ${issue.rule || '未知规则'}\n`; + markdown += `- **消息:** ${issue.message || '无'}\n`; + markdown += `- **严重程度:** ${issue.severity || 'medium'}\n`; + markdown += `- **检测工具:** ${(issue.detected_by && issue.detected_by.length > 0) ? issue.detected_by.join(', ') : (issue.tool || '未知')}\n`; + + if (issue.risk_level) { + markdown += `- **风险等级:** ${riskEmoji} ${riskLabel}\n`; + } + if (issue.risk_score !== undefined) { + markdown += `- **风险评分:** ${issue.risk_score}/100\n`; + } + if (issue.confidence) { + markdown += `- **置信度:** ${issue.confidence}\n`; + } + + markdown += `\n`; + + if (issue.suggestion) { + markdown += `**💡 修改建议:**\n\n`; + markdown += `${issue.suggestion}\n\n`; + } + + markdown += `---\n\n`; + issueIndex++; + }); + } + } + + markdown += `\n---\n\n`; + markdown += `*报告生成时间: ${timestamp}*\n`; + markdown += `*由代码质量检查系统自动生成*\n`; + + return markdown; +} + // 上传文件到项目 app.post('/api/projects/:id/upload-files', upload.array('files'), (req, res) => { try { diff --git a/src/frontend/index.html b/src/frontend/index.html index 408acd9..75abd82 100644 --- a/src/frontend/index.html +++ b/src/frontend/index.html @@ -308,11 +308,16 @@