import { useState, useRef, useEffect } from "react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Textarea } from "@/components/ui/textarea"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Progress } from "@/components/ui/progress"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { AlertTriangle, CheckCircle, Clock, Code, FileText, Info, Lightbulb, Shield, Target, TrendingUp, Upload, Zap, X } from "lucide-react"; import { CodeAnalysisEngine } from "@/features/analysis/services"; import { api } from "@/shared/config/database"; import type { CodeAnalysisResult } from "@/shared/types"; import { toast } from "sonner"; // AI解释解析函数 function parseAIExplanation(aiExplanation: string) { try { const parsed = JSON.parse(aiExplanation); // 检查是否有xai字段 if (parsed.xai) { return parsed.xai; } // 检查是否直接包含what, why, how字段 if (parsed.what || parsed.why || parsed.how) { return parsed; } // 如果都没有,返回null表示无法解析 return null; } catch (error) { // JSON解析失败,返回null return null; } } export default function InstantAnalysis() { const user = null as any; const [code, setCode] = useState(""); const [language, setLanguage] = useState(""); const [analyzing, setAnalyzing] = useState(false); const [result, setResult] = useState(null); const [analysisTime, setAnalysisTime] = useState(0); const fileInputRef = useRef(null); const loadingCardRef = useRef(null); const supportedLanguages = CodeAnalysisEngine.getSupportedLanguages(); // 监听analyzing状态变化,自动滚动到加载卡片 useEffect(() => { if (analyzing && loadingCardRef.current) { // 使用requestAnimationFrame确保DOM更新完成后再滚动 requestAnimationFrame(() => { setTimeout(() => { if (loadingCardRef.current) { loadingCardRef.current.scrollIntoView({ behavior: 'smooth', block: 'center' }); } }, 50); }); } }, [analyzing]); // 示例代码 const exampleCodes = { javascript: `// 示例JavaScript代码 - 包含多种问题 var userName = "admin"; var password = "123456"; // 硬编码密码 function validateUser(input) { if (input == userName) { // 使用 == 比较 console.log("User validated"); // 生产代码中的console.log return true; } return false; } // 性能问题:循环中重复计算长度 function processItems(items) { for (var i = 0; i < items.length; i++) { for (var j = 0; j < items.length; j++) { console.log(items[i] + items[j]); } } } // 安全问题:使用eval function executeCode(userInput) { eval(userInput); // 危险的eval使用 }`, python: `# 示例Python代码 - 包含多种问题 import * # 通配符导入 password = "secret123" # 硬编码密码 def process_data(data): try: result = [] for item in data: print(item) # 使用print而非logging result.append(item * 2) return result except: # 裸露的except语句 pass def complex_function(): # 函数过长示例 if True: if True: if True: if True: if True: # 嵌套过深 print("Deep nesting")`, java: `// 示例Java代码 - 包含多种问题 public class Example { private String password = "admin123"; // 硬编码密码 public void processData() { System.out.println("Processing..."); // 使用System.out.print try { // 一些处理逻辑 String data = getData(); } catch (Exception e) { // 空的异常处理 } } private String getData() { return "data"; } }` }; const handleAnalyze = async () => { if (!code.trim()) { toast.error("请输入要分析的代码"); return; } if (!language) { toast.error("请选择编程语言"); return; } try { setAnalyzing(true); // 立即滚动到页面底部(加载卡片会出现的位置) setTimeout(() => { window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); }, 100); const startTime = Date.now(); const analysisResult = await CodeAnalysisEngine.analyzeCode(code, language); const endTime = Date.now(); const duration = (endTime - startTime) / 1000; setResult(analysisResult); setAnalysisTime(duration); // 保存分析记录(可选,未登录时跳过) if (user) { await api.createInstantAnalysis({ user_id: user.id, language, // 不存储代码内容,仅存储摘要 code_content: '', analysis_result: JSON.stringify(analysisResult), issues_count: analysisResult.issues.length, quality_score: analysisResult.quality_score, analysis_time: duration }); } toast.success(`分析完成!发现 ${analysisResult.issues.length} 个问题`); } catch (error) { console.error('Analysis failed:', error); toast.error("分析失败,请稍后重试"); } finally { setAnalyzing(false); // 即时分析结束后清空前端内存中的代码(满足NFR-2销毁要求) setCode(""); } }; const handleFileUpload = (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (!file) return; const reader = new FileReader(); reader.onload = (e) => { const content = e.target?.result as string; setCode(content); // 根据文件扩展名自动选择语言 const extension = file.name.split('.').pop()?.toLowerCase(); const languageMap: Record = { 'js': 'javascript', 'jsx': 'javascript', 'ts': 'typescript', 'tsx': 'typescript', 'py': 'python', 'java': 'java', 'go': 'go', 'rs': 'rust', 'cpp': 'cpp', 'c': 'cpp', 'cs': 'csharp', 'php': 'php', 'rb': 'ruby' }; if (extension && languageMap[extension]) { setLanguage(languageMap[extension]); } }; reader.readAsText(file); }; const loadExampleCode = (lang: string) => { const example = exampleCodes[lang as keyof typeof exampleCodes]; if (example) { setCode(example); setLanguage(lang); toast.success(`已加载${lang}示例代码`); } }; const getSeverityColor = (severity: string) => { switch (severity) { case 'critical': return 'bg-red-100 text-red-800 border-red-200'; case 'high': return 'bg-orange-100 text-orange-800 border-orange-200'; case 'medium': return 'bg-yellow-100 text-yellow-800 border-yellow-200'; case 'low': return 'bg-red-50 text-red-800 border-red-200'; default: return 'bg-gray-100 text-gray-800 border-gray-200'; } }; const getTypeIcon = (type: string) => { switch (type) { case 'security': return ; case 'bug': return ; case 'performance': return ; case 'style': return ; case 'maintainability': return ; default: return ; } }; const clearAnalysis = () => { setCode(""); setLanguage(""); setResult(null); setAnalysisTime(0); }; // 渲染问题的函数,使用紧凑样式 const renderIssue = (issue: any, index: number) => (
{getTypeIcon(issue.type)}

{issue.title}

📍 第 {issue.line} 行 {issue.column && ,第 {issue.column} 列}
{issue.severity === 'critical' ? '严重' : issue.severity === 'high' ? '高' : issue.severity === 'medium' ? '中等' : '低'}
{issue.description && (
问题详情

{issue.description}

)} {issue.code_snippet && (
问题代码
第 {issue.line} 行
              {issue.code_snippet}
            
)}
{issue.suggestion && (
修复建议

{issue.suggestion}

)} {issue.ai_explanation && (() => { const parsedExplanation = parseAIExplanation(issue.ai_explanation); if (parsedExplanation) { return (
AI 解释
{parsedExplanation.what && (
问题: {parsedExplanation.what}
)} {parsedExplanation.why && (
原因: {parsedExplanation.why}
)} {parsedExplanation.how && (
方案: {parsedExplanation.how}
)} {parsedExplanation.learn_more && ( )}
); } else { // 如果无法解析JSON,回退到原始显示方式 return (
AI 解释

{issue.ai_explanation}

); } })()}
); return (
{/* 页面标题 */}

即时代码分析

快速分析代码片段,发现潜在问题并获得修复建议

{/* 代码输入区域 */}
代码分析 {result && ( )}
{/* 工具栏 */}
{/* 快速示例 */}
示例:
{/* 代码编辑器 */}