import React, { useState, useRef, useEffect } from 'react'; import { Card, Button, Space, Tag, message } from 'antd'; import { SaveOutlined, ReloadOutlined, BugOutlined, CheckCircleOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; import { vulnerabilityService } from '../../services/api'; import { Vulnerability } from '../../types'; import './CodeEditor.css'; interface CodeEditorProps { filePath: string; content: string; language: string; vulnerabilities: Vulnerability[]; onSave: (content: string) => Promise; onRefresh: () => void; } const CodeEditor: React.FC = ({ filePath, content, language, vulnerabilities, onSave, onRefresh }) => { const [editedContent, setEditedContent] = useState(content); const [selectedVulnerability, setSelectedVulnerability] = useState(null); const [isSaving, setIsSaving] = useState(false); const textareaRef = useRef(null); useEffect(() => { setEditedContent(content); }, [content]); const getSeverityColor = (severity: string) => { const colorMap: { [key: string]: string } = { critical: '#ff4d4f', high: '#ff7a45', medium: '#ffa940', low: '#73d13d', info: '#40a9ff', }; return colorMap[severity] || '#d9d9d9'; }; const getSeverityIcon = (severity: string) => { const iconMap: { [key: string]: React.ReactNode } = { critical: , high: , medium: , low: , info: , }; return iconMap[severity] || ; }; const handleSave = async () => { setIsSaving(true); try { await onSave(editedContent); message.success('代码保存成功'); } catch (error) { message.error('代码保存失败'); console.error(error); } finally { setIsSaving(false); } }; const handleVulnerabilityClick = (vulnerability: Vulnerability) => { setSelectedVulnerability(vulnerability); // 滚动到对应行 if (textareaRef.current) { const lines = editedContent.split('\n'); const targetLine = vulnerability.line_number || 1; if (targetLine <= lines.length) { const lineHeight = 20; // 估算行高 const scrollTop = (targetLine - 1) * lineHeight; textareaRef.current.scrollTop = scrollTop; textareaRef.current.focus(); } } }; const applyAIFix = async (vulnerability: Vulnerability) => { if (!vulnerability.ai_suggestion) { message.warning('该漏洞暂无AI修复建议'); return; } try { // 这里可以实现自动应用AI建议的逻辑 // 目前先显示建议内容 message.info(`AI修复建议: ${vulnerability.ai_suggestion}`); // 标记漏洞为已修复 await vulnerabilityService.updateVulnerability(vulnerability.id, { status: 'fixed' }); message.success('漏洞已标记为已修复'); onRefresh(); // 刷新数据 } catch (error) { message.error('修复失败'); console.error(error); } }; const renderLineNumbers = () => { const lines = editedContent.split('\n'); return lines.map((_, index) => (
{index + 1}
)); }; const renderVulnerabilityMarkers = () => { return vulnerabilities.map((vuln) => (
handleVulnerabilityClick(vuln)} title={`${vuln.severity.toUpperCase()}: ${vuln.message}`} /> )); }; return (
{filePath}
} extra={ {vulnerabilities.length > 0 && ( {vulnerabilities.length} 个漏洞 )} } >
{/* 漏洞标记侧边栏 */}
{renderVulnerabilityMarkers()}
{/* 行号 */}
{renderLineNumbers()}
{/* 代码编辑器 */}