diff --git a/src/views/Jyh/security/components/HighRiskComponentRank.vue b/src/views/Jyh/security/components/HighRiskComponentRank.vue new file mode 100644 index 0000000..8094959 --- /dev/null +++ b/src/views/Jyh/security/components/HighRiskComponentRank.vue @@ -0,0 +1,219 @@ + + + + + \ No newline at end of file diff --git a/src/views/Jyh/security/components/IndustryDistribution.vue b/src/views/Jyh/security/components/IndustryDistribution.vue new file mode 100644 index 0000000..e109e52 --- /dev/null +++ b/src/views/Jyh/security/components/IndustryDistribution.vue @@ -0,0 +1,212 @@ + + + + + \ No newline at end of file diff --git a/src/views/Jyh/security/index.vue b/src/views/Jyh/security/index.vue index 7f8e31a..f5b7c55 100644 --- a/src/views/Jyh/security/index.vue +++ b/src/views/Jyh/security/index.vue @@ -74,21 +74,11 @@ -
-

行业分布

-
-
-
-
-
+ + -
-

高危组件 Top 10

-
-
-
-
-
+ +

情报流

@@ -172,6 +162,8 @@ import { onMounted, ref, nextTick, watch, onUnmounted } from 'vue'; import * as echarts from 'echarts'; import { usePageResize } from '@/utils/hooks/usePageResize'; import ThreatIntelMap from './components/ThreatIntelMap.vue'; +import IndustryDistribution from './components/IndustryDistribution.vue'; +import HighRiskComponentRank from './components/HighRiskComponentRank.vue'; // 页面尺寸响应式 const { widthType } = usePageResize(); @@ -370,20 +362,6 @@ const chartData = ref({ ] }, - // 高危组件数据(基于真实开源项目使用情况和漏洞统计) - highRiskComponent: [ - { name: 'Log4j2', cvss: 9.8, vulnCount: 15, usage: '1200万+', desc: 'CVE-2021-44228等严重RCE漏洞' }, - { name: 'Apache Struts2', cvss: 9.7, vulnCount: 12, usage: '850万+', desc: 'S2系列远程代码执行漏洞' }, - { name: 'OpenSSL', cvss: 9.6, vulnCount: 18, usage: '2500万+', desc: '心脏出血、幽灵猫等高危漏洞' }, - { name: 'Spring Framework', cvss: 9.5, vulnCount: 9, usage: '1800万+', desc: 'Spring4Shell等RCE漏洞' }, - { name: 'Jackson', cvss: 9.4, vulnCount: 11, usage: '1000万+', desc: '反序列化漏洞,影响Java生态' }, - { name: 'Fastjson', cvss: 9.3, vulnCount: 14, usage: '600万+', desc: '多个反序列化RCE漏洞' }, - { name: 'Apache Commons', cvss: 9.2, vulnCount: 8, usage: '1500万+', desc: 'Collections反序列化漏洞' }, - { name: 'jQuery', cvss: 9.1, vulnCount: 6, usage: '3000万+', desc: 'XSS和原型污染漏洞' }, - { name: 'Lodash', cvss: 9.0, vulnCount: 5, usage: '2200万+', desc: '原型污染漏洞,影响Node.js生态' }, - { name: 'Moment.js', cvss: 9.0, vulnCount: 4, usage: '1100万+', desc: 'ReDoS和原型污染漏洞' } - ], - // 漏洞占比数据 vulnerabilitySeverity: { categories: ['2024Q1', '2024Q2', '2024Q3', '2024Q4', '2025Q1', '2025Q2', '2025Q3', '2025Q4'], @@ -415,24 +393,8 @@ const chartData = ref({ ] }, - // 行业分布数据 - industryDistribution: [ - { value: 25.8, name: '人工智能' }, - { value: 18.4, name: '云计算' }, - { value: 15.6, name: '大数据' }, - { value: 12.2, name: '物联网' }, - { value: 9.6, name: '网络安全' }, - { value: 7.1, name: '区块链' }, - { value: 6.4, name: '工业互联网' }, - { value: 4.9, name: '移动开发' } - ], - // 科技感配色方案 - industryColorPalette: [ - '#00f0ff', '#00b03e', '#ffeb00', '#ffab00', - '#ff5100', '#c0232a', '#a262f2', '#379bff' - ], - // CVE图表数据 - cveData: { + // CVE图表数据 + cveData: { // 全球CVE:2024年实际数据(基于Excel数据) global: { cveCount: [98402, 418, 7025, 3711, 5115, 3228, 3044, 2957, 2592, 1455, 4826, 4661], @@ -487,8 +449,7 @@ const isEmpty = ref({ ossCompass: false, developer: false, languageTech: false, - highRiskComponent: false, - industryDistribution: false, + cveData: false }); @@ -499,7 +460,6 @@ const chartInstances = ref<{ [key: string]: echarts.ECharts | null }>({ ossCompassChart: null, developerChart: null, languageTechChart: null, - highRiskComponentRank: null, cweAttackSurfaceRadar: null, CVEChart: null }); @@ -926,122 +886,9 @@ const initDeveloperChart = () => { }); }; -// 初始化行业分布图表(饼图) -const initIndustryDistributionChart = () => { - const el = document.getElementById('cweAttackSurfaceRadar'); - if (!el) return; - if (chartInstances.value.cweAttackSurfaceRadar) { - chartInstances.value.cweAttackSurfaceRadar.dispose(); - } - const myChart = echarts.init(el); - chartInstances.value.cweAttackSurfaceRadar = myChart; - myChart.setOption({ - tooltip: { - trigger: 'item', - formatter: (params: any) => `${params.name}: ${params.percent}% (${params.value}%)` - }, - legend: { - bottom: '0', - textStyle: { fontSize: 12 }, - itemWidth: 10, - itemHeight: 10 - }, - color: chartData.value.industryColorPalette, - series: [ - { - name: '行业分布', - type: 'pie', - radius: ['40%', '70%'], - data: chartData.value.industryDistribution, - label: { - show: true, - formatter: '{b}: {d}%', - fontSize: 10 - } - } - ], - grid: { left: 0, bottom: 0, top: 0, right: 0 } - }); -}; - -// 初始化高危组件Top 10图表(横向柱状图) -const initHighRiskComponentChart = () => { - const el = document.getElementById('highRiskComponentRank'); - if (!el) return; - - if (chartInstances.value.highRiskComponentRank) { - chartInstances.value.highRiskComponentRank.dispose(); - } - - const myChart = echarts.init(el); - chartInstances.value.highRiskComponentRank = myChart; - - // 提取组件名称和CVSS评分 - const yAxisData = chartData.value.highRiskComponent.map(item => item.name); - const seriesData = chartData.value.highRiskComponent.map(item => ({ - value: item.cvss, - vulnCount: item.vulnCount, - usage: item.usage, - desc: item.desc - })); - - myChart.setOption({ - tooltip: { - trigger: 'axis', - axisPointer: { type: 'shadow' }, - formatter: (params: any) => { - const data = chartData.value.highRiskComponent[params[0].dataIndex]; - return ` -
-
${data.name}
-
CVSS评分: ${data.cvss}
-
漏洞数量: ${data.vulnCount}个
-
使用量: ${data.usage}
-
漏洞描述: ${data.desc}
-
- `; - } - }, - grid: { left: '15%', right: '4%', bottom: '3%', top: '3%', containLabel: true }, - xAxis: { - type: 'value', - name: 'CVSS评分', - nameTextStyle: { fontSize: 12 }, - axisLabel: { fontSize: 12 }, - max: 10 - }, - yAxis: { - type: 'category', - data: yAxisData, - axisLabel: { fontSize: 12 } - }, - series: [ - { - name: 'CVSS评分', - type: 'bar', - data: seriesData, - itemStyle: { - color: (params: any) => { - const value = params.value; - if (value >= 9.0) return '#ef4444'; // 红色 - 严重 - if (value >= 7.0) return '#f97316'; // 橙色 - 高危 - if (value >= 4.0) return '#eab308'; // 黄色 - 中危 - return '#22c55e'; // 绿色 - 低危 - } - }, - label: { - show: true, - position: 'right', - formatter: '{c}', - fontSize: 12 - } - } - ] - }); -}; // 初始化编程语言使用趋势堆叠面积图 const initLanguageTrendChart = () => { @@ -1311,8 +1158,8 @@ const initCharts = () => { ossCompass: chartData.value.ossCompass.data.every(item => item === 0), developer: chartData.value.developer.data.every(item => item === 0), languageTech: chartData.value.languageTech.series.every(s => s.data.every(d => d === 0)), - highRiskComponent: chartData.value.highRiskComponent.length === 0, - industryDistribution: chartData.value.industryDistribution.length === 0, + + cveData: chartData.value.cveData.global.cveCount.every(item => item === 0) && chartData.value.cveData.regional.cveCount.every(item => item === 0), languageTrend: chartData.value.languageTrend.series.every(s => s.data.every(d => d === 0)), @@ -1326,8 +1173,8 @@ const initCharts = () => { if (!isEmpty.value.ossCompass) nextTick(() => initOssCompassChart()); if (!isEmpty.value.developer) nextTick(() => initDeveloperChart()); if (!isEmpty.value.languageTech) nextTick(() => initLanguageTechChart()); - if (!isEmpty.value.highRiskComponent) nextTick(() => initHighRiskComponentChart()); - if (!isEmpty.value.industryDistribution) nextTick(() => initIndustryDistributionChart()); + + if (!isEmpty.value.cveData) nextTick(() => initCVEChart()); if (!isEmpty.value.languageTrend) nextTick(() => initLanguageTrendChart()); if (!isEmpty.value.vulnerabilitySeverity) nextTick(() => initVulnerabilitySeverityChart());