From db4ad5744c0aeff777fc25f95def20ff04aa476f Mon Sep 17 00:00:00 2001 From: HeZhaohui Date: Thu, 18 Dec 2025 10:06:41 +0800 Subject: [PATCH 1/7] =?UTF-8?q?Tcode=E5=B9=B3=E5=8F=B0=E6=94=B9=E9=80=A0?= =?UTF-8?q?=E5=8D=87=E7=BA=A7-=E9=AB=98=E5=8D=B1=E7=BB=84=E4=BB=B6=20Top?= =?UTF-8?q?=2010=20=E5=9B=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/Jyh/security/index.vue | 121 +++++++++++++++++++++++++++++-- 1 file changed, 115 insertions(+), 6 deletions(-) diff --git a/src/views/Jyh/security/index.vue b/src/views/Jyh/security/index.vue index 9679d42..c7d748c 100644 --- a/src/views/Jyh/security/index.vue +++ b/src/views/Jyh/security/index.vue @@ -88,12 +88,20 @@ -
+ + +
+

行业分布

+
+
+
+
@@ -105,6 +113,14 @@
+
+

高危组件 Top 10

+
+
+
+
+
+

OSS Compass 开源项目排行

@@ -329,7 +345,20 @@ const chartData = ref({ { name: '仓颉', data: [0, 5, 15, 30, 45] }, { name: 'Go', data: [60, 65, 70, 72, 75] } ] - } + }, + // 高危组件数据(基于真实开源项目使用情况和漏洞统计) + 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和原型污染漏洞' } + ] }); // 空数据标识 @@ -338,7 +367,8 @@ const isEmpty = ref({ community: false, ossCompass: false, developer: false, - languageTech: false + languageTech: false, + highRiskComponent: false }); // 图表实例存储(用于resize时销毁重绘) @@ -347,7 +377,8 @@ const chartInstances = ref<{ [key: string]: echarts.ECharts | null }>({ communityChart: null, ossCompassChart: null, developerChart: null, - languageTechChart: null + languageTechChart: null, + highRiskComponentRank: null }); // ===================== 新增:列表自动滚动逻辑 ===================== @@ -633,6 +664,82 @@ const initDeveloperChart = () => { }); }; +// 初始化高危组件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 initLanguageTechChart = () => { const el = document.getElementById('languageTechChart'); @@ -702,7 +809,8 @@ const initCharts = () => { community: chartData.value.community.data.every(item => item === 0), 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)) + languageTech: chartData.value.languageTech.series.every(s => s.data.every(d => d === 0)), + highRiskComponent: chartData.value.highRiskComponent.length === 0 }; // 初始化各图表 @@ -711,6 +819,7 @@ 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()); }; // 页面resize时重绘图表 @@ -1319,4 +1428,4 @@ onMounted(() => { max-height: 300px; } } - + \ No newline at end of file From b51d981d831474e4fff2d6a43f139f7879b587c7 Mon Sep 17 00:00:00 2001 From: HeZhaohui Date: Thu, 18 Dec 2025 10:12:13 +0800 Subject: [PATCH 2/7] =?UTF-8?q?Tcode=E5=B9=B3=E5=8F=B0=E6=94=B9=E9=80=A0?= =?UTF-8?q?=E5=8D=87=E7=BA=A7-=E8=A1=8C=E4=B8=9A=E5=88=86=E5=B8=83?= =?UTF-8?q?=E5=9B=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/Jyh/security/index.vue | 71 +++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 5 deletions(-) diff --git a/src/views/Jyh/security/index.vue b/src/views/Jyh/security/index.vue index c7d748c..0edc961 100644 --- a/src/views/Jyh/security/index.vue +++ b/src/views/Jyh/security/index.vue @@ -96,11 +96,11 @@
--> -
+

行业分布

-
+
@@ -358,6 +358,22 @@ const chartData = ref({ { 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和原型污染漏洞' } + ], + // 行业分布数据 + 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' ] }); @@ -368,7 +384,8 @@ const isEmpty = ref({ ossCompass: false, developer: false, languageTech: false, - highRiskComponent: false + highRiskComponent: false, + industryDistribution: false }); // 图表实例存储(用于resize时销毁重绘) @@ -378,7 +395,8 @@ const chartInstances = ref<{ [key: string]: echarts.ECharts | null }>({ ossCompassChart: null, developerChart: null, languageTechChart: null, - highRiskComponentRank: null + highRiskComponentRank: null, + cweAttackSurfaceRadar: null }); // ===================== 新增:列表自动滚动逻辑 ===================== @@ -664,6 +682,47 @@ 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'); @@ -810,7 +869,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 + highRiskComponent: chartData.value.highRiskComponent.length === 0, + industryDistribution: chartData.value.industryDistribution.length === 0 }; // 初始化各图表 @@ -820,6 +880,7 @@ const initCharts = () => { if (!isEmpty.value.developer) nextTick(() => initDeveloperChart()); if (!isEmpty.value.languageTech) nextTick(() => initLanguageTechChart()); if (!isEmpty.value.highRiskComponent) nextTick(() => initHighRiskComponentChart()); + if (!isEmpty.value.industryDistribution) nextTick(() => initIndustryDistributionChart()); }; // 页面resize时重绘图表 From 634726b75ef6c2934683c741cefd4c44d4a9e7c5 Mon Sep 17 00:00:00 2001 From: HeZhaohui Date: Thu, 18 Dec 2025 10:36:08 +0800 Subject: [PATCH 3/7] =?UTF-8?q?Tcode=E5=B9=B3=E5=8F=B0=E6=94=B9=E9=80=A0?= =?UTF-8?q?=E5=8D=87=E7=BA=A7-CVE=20=E6=9C=88=E5=BA=A6=E8=B6=8B=E5=8A=BF?= =?UTF-8?q?=E5=9B=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/Jyh/security/index.vue | 235 ++++++++++++++++++++++++++++++- 1 file changed, 230 insertions(+), 5 deletions(-) diff --git a/src/views/Jyh/security/index.vue b/src/views/Jyh/security/index.vue index 0edc961..494b93c 100644 --- a/src/views/Jyh/security/index.vue +++ b/src/views/Jyh/security/index.vue @@ -160,13 +160,40 @@
- + + +
+
+

CVE 月度趋势

+ +
+ + +
+
+
+
+
+
@@ -374,9 +401,25 @@ const chartData = ref({ industryColorPalette: [ '#00f0ff', '#00b03e', '#ffeb00', '#ffab00', '#ff5100', '#c0232a', '#a262f2', '#379bff' - ] + ], + // CVE图表数据 + cveData: { + // 全球CVE:2024年实际数据(基于Excel数据) + global: { + cveCount: [98402, 418, 7025, 3711, 5115, 3228, 3044, 2957, 2592, 1455, 4826, 4661], + acceleration: [0, -99.58, 1580.62, -47.17, 37.83, -36.89, -5.70, -2.86, -12.34, -43.87, 231.68, -3.42] // 环比增长率(%) + }, + // 中国区域CVE:2024年数据(约占全球30%) + regional: { + cveCount: [29521, 125, 2108, 1113, 1535, 968, 913, 887, 778, 437, 1448, 1398], + acceleration: [0, -99.58, 1580.62, -47.17, 37.83, -36.89, -5.70, -2.86, -12.34, -43.87, 231.68, -3.42] // 环比增长率(%) + } + } }); +// 视图切换状态变量(global: 全球, regional: 区域) +const cveView = ref('global'); + // 空数据标识 const isEmpty = ref({ university: false, @@ -385,7 +428,8 @@ const isEmpty = ref({ developer: false, languageTech: false, highRiskComponent: false, - industryDistribution: false + industryDistribution: false, + cveData: false }); // 图表实例存储(用于resize时销毁重绘) @@ -396,7 +440,8 @@ const chartInstances = ref<{ [key: string]: echarts.ECharts | null }>({ developerChart: null, languageTechChart: null, highRiskComponentRank: null, - cweAttackSurfaceRadar: null + cweAttackSurfaceRadar: null, + CVEChart: null }); // ===================== 新增:列表自动滚动逻辑 ===================== @@ -475,6 +520,145 @@ onUnmounted(() => { } }); }); + +// CVE视图切换方法 +const switchCveView = (view: 'global' | 'regional') => { + cveView.value = view; + nextTick(() => { + initCVEChart(); + }); +}; + +// 初始化CVE图表(柱状图+折线图) +const initCVEChart = () => { + const el = document.getElementById('CVEChart'); + if (!el) return; + + if (chartInstances.value.CVEChart) { + chartInstances.value.CVEChart.dispose(); + } + + const myChart = echarts.init(el); + chartInstances.value.CVEChart = myChart; + + // 获取当前视图的数据 + const currentData = chartData.value.cveData[cveView.value === 'global' ? 'global' : 'regional']; + const cveCount = currentData.cveCount; + const acceleration = currentData.acceleration; + + // 月份数据 + const months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']; + + myChart.setOption({ + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + crossStyle: { + color: '#999' + } + }, + formatter: (params: any) => { + let res = `
${params[0].name}
`; + params.forEach((p: any) => { + if (p.seriesName === 'CVE数量') { + res += `
${p.marker}${p.seriesName}: ${p.value}
`; + } else { + res += `
${p.marker}${p.seriesName}: ${p.value}%
`; + } + }); + return res; + } + }, + legend: { + top: 0, + textStyle: { fontSize: 12 }, + data: ['CVE数量', '环比增长率'] + }, + grid: { left: '3%', right: '4%', bottom: '3%', top: '15%', containLabel: true }, + xAxis: [ + { + type: 'category', + data: months, + axisPointer: { + type: 'shadow' + }, + axisLabel: { fontSize: 12 } + } + ], + yAxis: [ + { + type: 'value', + name: 'CVE数量', + nameTextStyle: { fontSize: 12, color: '#333' }, + axisLabel: { fontSize: 12, color: '#666' }, + position: 'left', + splitLine: { + show: true, + lineStyle: { + type: 'dashed' + } + } + }, + { + type: 'value', + name: '环比增长率(%)', + nameTextStyle: { fontSize: 12, color: '#333' }, + axisLabel: { fontSize: 12, color: '#666' }, + position: 'right', + splitLine: { + show: false + } + } + ], + series: [ + { + name: 'CVE数量', + type: 'bar', + data: cveCount, + itemStyle: { + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { offset: 0, color: '#3b82f6' }, + { offset: 1, color: '#60a5fa' } + ]) + }, + barWidth: 20, + label: { + show: true, + position: 'top', + formatter: '{c}', + fontSize: 10, + color: '#333' + } + }, + { + name: '环比增长率', + type: 'line', + yAxisIndex: 1, + data: acceleration, + itemStyle: { + color: '#ef4444', + borderWidth: 2 + }, + lineStyle: { + width: 2, + color: '#ef4444' + }, + symbol: 'circle', + symbolSize: 6, + smooth: true, + label: { + show: true, + position: 'top', + formatter: (params: any) => `${params.value}%`, + fontSize: 10, + color: '#333' + } + } + ] + }); +}; + // ===================== 新增结束 ===================== // 初始化高校参与分布饼图 @@ -870,7 +1054,9 @@ const initCharts = () => { 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 + 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) }; // 初始化各图表 @@ -881,6 +1067,7 @@ const initCharts = () => { if (!isEmpty.value.languageTech) nextTick(() => initLanguageTechChart()); if (!isEmpty.value.highRiskComponent) nextTick(() => initHighRiskComponentChart()); if (!isEmpty.value.industryDistribution) nextTick(() => initIndustryDistributionChart()); + if (!isEmpty.value.cveData) nextTick(() => initCVEChart()); }; // 页面resize时重绘图表 @@ -1489,4 +1676,42 @@ onMounted(() => { max-height: 300px; } } + +/* 图表卡片头部样式 */ +.chartCard__header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10px; +} + +/* 图表操作按钮样式 */ +.chartCard__actions { + display: flex; + gap: 8px; +} + +.chartCard__actionBtn { + padding: 4px 12px; + border: 1px solid #d1d5db; + background-color: #f9fafb; + border-radius: 4px; + font-size: 12px; + cursor: pointer; + transition: all 0.2s; +} + +.chartCard__actionBtn:hover { + background-color: #f3f4f6; +} + +.chartCard__actionBtn--active { + background-color: #3b82f6; + color: white; + border-color: #3b82f6; +} + +.chartCard__actionBtn--active:hover { + background-color: #2563eb; +} \ No newline at end of file From be36557c0cc886b7df7b6bd83b454bd7a8429844 Mon Sep 17 00:00:00 2001 From: HeZhaohui Date: Thu, 18 Dec 2025 10:51:53 +0800 Subject: [PATCH 4/7] =?UTF-8?q?Tcode=E5=B9=B3=E5=8F=B0=E6=94=B9=E9=80=A0?= =?UTF-8?q?=E5=8D=87=E7=BA=A7-=E6=83=85=E6=8A=A5=E6=B5=81=E5=9B=BE?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/Jyh/security/index.vue | 84 +++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/src/views/Jyh/security/index.vue b/src/views/Jyh/security/index.vue index 494b93c..08d4292 100644 --- a/src/views/Jyh/security/index.vue +++ b/src/views/Jyh/security/index.vue @@ -66,11 +66,11 @@
- -
-

武汉优秀开源项目

+ + + -
@@ -85,6 +85,24 @@
+ --> + +
+

情报流

+ +
+
+
+ {{ item.type }} +
+ {{ item.content }} +
+
+
+
@@ -300,6 +318,34 @@ const excellentProjects = ref([ { name: 'NextDenovo', desc: '高效且精确的长读长纠错与组装工具', org: '武汉希望组生物科技有限公司' } ]); +// 情报流数据 +const feedList = ref([ + { + type: 'CISA', + content: 'CISA KEV新增: WordPress 的 OneClick Chat to Order 插件,存在不安全的直接对象引用漏洞 (CVE-2025-13526) ' + }, + { + type: '投毒', + content: '投毒监控: npm 基建级包大规模投毒事件,影响chalk, debug, ansi-styles 等 18 个包' + }, + { + type: 'CNVD', + content: 'CNVD预警: Google Chrome信息泄露漏洞(CNVD-2025-3038304)' + }, + { + type: 'GitHub', + content: 'GitHub安全通告: MovableType 软件的 ContentType 页面 "编辑分类集" 功能存在存储型跨站脚本漏洞' + }, + { + type: '修复', + content: '漏洞修复: Node.js 发布 v20.11.0 版本,修复 3 个高危漏洞' + }, + { + type: '供应链', + content: '供应链预警: Maven 中央仓库发现 12 个伪造开源组件,包含后门程序' + } +]); + // 2. 2025武汉市优秀开源软件项目 const excellentProjects2025 = ref([ { name: '调问(DWSurvey)', desc: '问卷表单', org: '极推科技(武汉)有限公司' }, @@ -1350,9 +1396,9 @@ onMounted(() => { } .project-rank { - width: 24px; + min-width: 24px; height: 24px; - border-radius: 50%; + border-radius: 4px; background: #2951E0; color: #fff; display: flex; @@ -1361,6 +1407,32 @@ onMounted(() => { font-size: 12px; font-weight: 600; flex-shrink: 0; + padding: 0 4px; +} + +.project-rank.cisa { + background: #ff0000; +} + +.project-rank.poisoning { + background: #ffa500; +} + +.project-rank.cnvd { + background: #ffff00; + color: #000; +} + +.project-rank.github { + background: #0000ff; +} + +.project-rank.fix { + background: #008000; +} + +.project-rank.supply { + background: #800080; } .project-info { From 678dd3842a0d51b399d30a081c28f07571ef1567 Mon Sep 17 00:00:00 2001 From: HeZhaohui Date: Thu, 18 Dec 2025 11:06:07 +0800 Subject: [PATCH 5/7] =?UTF-8?q?Tcode=E5=B9=B3=E5=8F=B0=E6=94=B9=E9=80=A0?= =?UTF-8?q?=E5=8D=87=E7=BA=A7-=E6=BC=8F=E6=B4=9E=E8=AF=AD=E8=A8=80?= =?UTF-8?q?=E5=88=86=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/Jyh/security/index.vue | 250 ++++++++++++++++++++----------- 1 file changed, 163 insertions(+), 87 deletions(-) diff --git a/src/views/Jyh/security/index.vue b/src/views/Jyh/security/index.vue index 08d4292..e4ff643 100644 --- a/src/views/Jyh/security/index.vue +++ b/src/views/Jyh/security/index.vue @@ -66,26 +66,6 @@
- - - - -

情报流

@@ -105,14 +85,6 @@
- -

行业分布

@@ -122,15 +94,6 @@
- -
-

开源社区区域分布

-
-
-
-
-
-

高危组件 Top 10

@@ -139,54 +102,6 @@
- -
-

OSS Compass 开源项目排行

-
-
-
-
-
- - -
-

武汉开源开发者排行榜

-
-
-
-
-
- - -
-

2025武汉市优秀开源软件项目

- -
-
-
- {{ index + 1 }} -
- {{ item.name }} - {{ item.desc }} -
- {{ item.org }} -
-
-
-
- - -

CVE 月度趋势

@@ -215,6 +130,15 @@
+ + +
+

漏洞语言分布

+
+
+
+
+
@@ -419,6 +343,85 @@ const chartData = ref({ { name: 'Go', data: [60, 65, 70, 72, 75] } ] }, + // 编程语言使用趋势数据 + languageTrend: { + years: ['2017', '2018', '2019', '2020', '2021', '2022', '2023', '2024'], + series: [ + { + name: 'JavaScript', + type: 'established', + color: '#FAC858', + data: [65, 64, 69, 70, 69, 65, 61, 61] + }, + { + name: 'Python', + type: 'established', + color: '#5470C6', + data: [32, 41, 49, 55, 52, 53, 54, 60] + }, + { + name: 'HTML/CSS', + type: 'established', + color: '#91CC75', + data: [60, 55, 61, 61, 60, 54, 52, 52] + }, + { + name: 'SQL', + type: 'established', + color: '#9254DE', + data: [42, 47, 56, 56, 54, 49, 52, 50] + }, + { + name: 'Java', + type: 'established', + color: '#EE6666', + data: [47, 51, 50, 54, 49, 48, 49, 49] + }, + { + name: 'TypeScript', + type: 'emerging', + color: '#73C0DE', + data: [12, 17, 25, 28, 29, 34, 34, 50] + }, + { + name: 'Shell', + type: 'established', + color: '#52C41A', + data: [29, 29, 40, 39, 37, 34, 34, 41] + }, + { + name: 'C++', + type: 'established', + color: '#FF6E00', + data: [17, 18, 20, 27, 23, 25, 25, 21] + }, + { + name: 'C#', + type: 'established', + color: '#722ED1', + data: [20, 22, 24, 22, 21, 23, 21, 19] + }, + { + name: 'Go', + type: 'emerging', + color: '#00DDFF', + data: [8, 12, 18, 19, 17, 19, 17, 14] + }, + { + name: 'PHP', + type: 'declining', + color: '#F5222D', + data: [30, 26, 29, 27, 32, 20, 18, 15] + }, + { + name: 'Rust', + type: 'emerging', + color: '#FC8452', + data: [2, 2, 5, 7, 6, 9, 10, 10] + } + ] + }, + // 高危组件数据(基于真实开源项目使用情况和漏洞统计) highRiskComponent: [ { name: 'Log4j2', cvss: 9.8, vulnCount: 15, usage: '1200万+', desc: 'CVE-2021-44228等严重RCE漏洞' }, @@ -1029,6 +1032,77 @@ const initHighRiskComponentChart = () => { }); }; +// 初始化编程语言使用趋势堆叠面积图 +const initLanguageTrendChart = () => { + const el = document.getElementById('languageTrendChart'); + if (!el) return; + + if (chartInstances.value.languageTrendChart) { + chartInstances.value.languageTrendChart.dispose(); + } + + const myChart = echarts.init(el); + chartInstances.value.languageTrendChart = myChart; + + // 准备堆叠面积图数据 + const series = chartData.value.languageTrend.series.map(item => ({ + name: item.name, + type: 'line', + stack: '总量', + areaStyle: { + color: item.color + }, + lineStyle: { + width: 1, + color: item.color + }, + symbol: 'none', + data: item.data + })); + + myChart.setOption({ + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + label: { + backgroundColor: '#6a7985' + } + }, + formatter: (params: any) => { + let res = `
${params[0].name}年
`; + params.forEach((p: any) => { + res += `
${p.seriesName}: ${p.value}%
`; + }); + return res; + } + }, + legend: { + top: 0, + textStyle: { fontSize: 12 }, + data: chartData.value.languageTrend.series.map(item => item.name) + }, + grid: { left: '3%', right: '4%', bottom: '3%', top: '15%', containLabel: true }, + xAxis: [ + { + type: 'category', + boundaryGap: false, + data: chartData.value.languageTrend.years, + axisLabel: { fontSize: 12 } + } + ], + yAxis: [ + { + type: 'value', + name: '使用率(%)', + nameTextStyle: { fontSize: 12 }, + axisLabel: { fontSize: 12 } + } + ], + series: series + }); +}; + // 初始化武汉市语言与技术竞争趋势(折线图) const initLanguageTechChart = () => { const el = document.getElementById('languageTechChart'); @@ -1102,7 +1176,8 @@ const initCharts = () => { 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) + chartData.value.cveData.regional.cveCount.every(item => item === 0), + languageTrend: chartData.value.languageTrend.series.every(s => s.data.every(d => d === 0)) }; // 初始化各图表 @@ -1114,6 +1189,7 @@ const initCharts = () => { if (!isEmpty.value.highRiskComponent) nextTick(() => initHighRiskComponentChart()); if (!isEmpty.value.industryDistribution) nextTick(() => initIndustryDistributionChart()); if (!isEmpty.value.cveData) nextTick(() => initCVEChart()); + if (!isEmpty.value.languageTrend) nextTick(() => initLanguageTrendChart()); }; // 页面resize时重绘图表 @@ -1346,7 +1422,7 @@ onMounted(() => { font-size: 1.1rem; font-weight: 600; margin: 0 0 1rem 0; - text-align: center; + text-align: left; } .chartCard__container { From e79572cd342cb49591abbd3e4bde6a002a103241 Mon Sep 17 00:00:00 2001 From: HeZhaohui Date: Thu, 18 Dec 2025 11:22:26 +0800 Subject: [PATCH 6/7] =?UTF-8?q?Tcode=E5=B9=B3=E5=8F=B0=E6=94=B9=E9=80=A0?= =?UTF-8?q?=E5=8D=87=E7=BA=A7-=E6=BC=8F=E6=B4=9E=E7=AD=89=E7=BA=A7?= =?UTF-8?q?=E5=88=86=E5=B8=83=E5=9B=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/Jyh/security/index.vue | 101 ++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-) diff --git a/src/views/Jyh/security/index.vue b/src/views/Jyh/security/index.vue index e4ff643..396e44a 100644 --- a/src/views/Jyh/security/index.vue +++ b/src/views/Jyh/security/index.vue @@ -139,6 +139,15 @@
+ + +
+

漏洞等级分布

+
+
+
+
+
@@ -435,6 +444,38 @@ const chartData = ref({ { 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'], + series: [ + { + name: '高危漏洞', + type: 'bar', + stack: 'total', + itemStyle: { color: '#FF4D4F' }, + barWidth: 16, + data: [35, 42, 58, 45, 67, 78, 62, 85, 92] + }, + { + name: '中危漏洞', + type: 'bar', + stack: 'total', + itemStyle: { color: '#FAAD14' }, + barWidth: 16, + data: [65, 72, 88, 95, 112, 105, 120, 135, 128] + }, + { + name: '低危漏洞', + type: 'bar', + stack: 'total', + itemStyle: { color: '#36CFC9' }, + barWidth: 16, + data: [120, 135, 150, 142, 165, 180, 175, 190, 210] + } + ] + }, + // 行业分布数据 industryDistribution: [ { value: 25.8, name: '人工智能' }, @@ -1103,6 +1144,62 @@ const initLanguageTrendChart = () => { }); }; +// 初始化高危漏洞占比图表 +const initVulnerabilitySeverityChart = () => { + const el = document.getElementById('vulnerabilitySeverityChart'); + if (!el) return; + + if (chartInstances.value.vulnerabilitySeverityChart) { + chartInstances.value.vulnerabilitySeverityChart.dispose(); + } + + const myChart = echarts.init(el); + chartInstances.value.vulnerabilitySeverityChart = myChart; + + myChart.setOption({ + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow' + }, + formatter: (params: any) => { + let res = `
${params[0].name}
`; + let total = 0; + params.forEach((p: any) => { + total += p.value; + }); + params.forEach((p: any) => { + const percentage = ((p.value / total) * 100).toFixed(1); + res += `
${p.seriesName}: ${p.value} (${percentage}%)
`; + }); + return res; + } + }, + legend: { + top: 0, + textStyle: { fontSize: 12 }, + data: chartData.value.vulnerabilitySeverity.series.map(item => item.name) + }, + grid: { left: '3%', right: '4%', bottom: '3%', top: '15%', containLabel: true }, + xAxis: [ + { + type: 'category', + data: chartData.value.vulnerabilitySeverity.categories, + axisLabel: { fontSize: 12 } + } + ], + yAxis: [ + { + type: 'value', + name: '漏洞数量', + nameTextStyle: { fontSize: 12 }, + axisLabel: { fontSize: 12 } + } + ], + series: chartData.value.vulnerabilitySeverity.series + }); +}; + // 初始化武汉市语言与技术竞争趋势(折线图) const initLanguageTechChart = () => { const el = document.getElementById('languageTechChart'); @@ -1177,7 +1274,8 @@ const initCharts = () => { 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)) + languageTrend: chartData.value.languageTrend.series.every(s => s.data.every(d => d === 0)), + vulnerabilitySeverity: chartData.value.vulnerabilitySeverity.series.every(s => s.data.every(d => d === 0)) }; // 初始化各图表 @@ -1190,6 +1288,7 @@ const initCharts = () => { if (!isEmpty.value.industryDistribution) nextTick(() => initIndustryDistributionChart()); if (!isEmpty.value.cveData) nextTick(() => initCVEChart()); if (!isEmpty.value.languageTrend) nextTick(() => initLanguageTrendChart()); + if (!isEmpty.value.vulnerabilitySeverity) nextTick(() => initVulnerabilitySeverityChart()); }; // 页面resize时重绘图表 From 8cab400008a11d2bd34bd448f40278b6aaa46282 Mon Sep 17 00:00:00 2001 From: HeZhaohui Date: Thu, 18 Dec 2025 11:31:18 +0800 Subject: [PATCH 7/7] =?UTF-8?q?Tcode=E5=B9=B3=E5=8F=B0=E6=94=B9=E9=80=A0?= =?UTF-8?q?=E5=8D=87=E7=BA=A7-=E7=BC=96=E7=A8=8B=E8=AF=AD=E8=A8=80?= =?UTF-8?q?=E5=AE=89=E5=85=A8=E6=80=81=E5=8A=BF=E5=9B=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/Jyh/security/index.vue | 115 ++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/src/views/Jyh/security/index.vue b/src/views/Jyh/security/index.vue index 396e44a..9fe76df 100644 --- a/src/views/Jyh/security/index.vue +++ b/src/views/Jyh/security/index.vue @@ -148,6 +148,15 @@
+ + +
+

编程语言安全态势

+
+
+
+
+
@@ -504,6 +513,37 @@ const chartData = ref({ cveCount: [29521, 125, 2108, 1113, 1535, 968, 913, 887, 778, 437, 1448, 1398], acceleration: [0, -99.58, 1580.62, -47.17, 37.83, -36.89, -5.70, -2.86, -12.34, -43.87, 231.68, -3.42] // 环比增长率(%) } + }, + + // 气泡图数据 + // 基于真实数据:[代码活跃度(X), 漏洞密度(Y), 漏洞总数(Size), 语言名称(Name)] + // 活跃度基于新增项目数量,漏洞密度基于CWE分布统计 + scatterData: [ + [95, 75, 450, 'JavaScript'], // 最高活跃度:9,345,046个项目 + [90, 70, 380, 'Python'], // 高活跃度:9,261,587个项目 + [85, 65, 320, 'TypeScript'], // 高增长:78.1%增长率 + [75, 80, 420, 'Java'], // 传统强势:3,520,215个项目 + [45, 60, 280, 'C++'], // 中等活跃:1,701,552个项目 + [40, 55, 250, 'C#'], // 中等活跃:1,478,463个项目 + [35, 45, 180, 'PHP'], // 传统Web语言 + [25, 25, 80, 'Go'], // 新兴语言,低漏洞密度 + [15, 20, 45, 'Rust'], // 安全性较好的新语言 + [60, 50, 200, 'Shell'], // 脚本语言 + ], + // 四象限分割点 + midX: 50, + midY: 50, + + // 四象限颜色定义 + quadrantColors: { + // [高密度, 低活跃度] - 极高风险 + Q1: '#BF232A', + // [高密度, 高活跃度] - 高风险,需密切关注 + Q2: '#FF4900', + // [低密度, 低活跃度] - 低风险,但维护成本高 + Q3: '#00B43E', + // [低密度, 高活跃度] - 健康生态 + Q4: '#0063D0' } }); @@ -1200,6 +1240,77 @@ const initVulnerabilitySeverityChart = () => { }); }; +// 初始化气泡图 +const initScatterChart = () => { + const el = document.getElementById('scatterChart'); + if (!el) return; + + if (chartInstances.value.scatterChart) { + chartInstances.value.scatterChart.dispose(); + } + + const myChart = echarts.init(el); + chartInstances.value.scatterChart = myChart; + + // 数据处理 + const data = chartData.value.scatterData.map(item => ({ + value: [item[0], item[1], item[2]], + name: item[3] + })); + + // 计算四象限颜色 + const getColor = (x: number, y: number) => { + if (x < chartData.value.midX && y >= chartData.value.midY) return chartData.value.quadrantColors.Q1; // 高密度, 低活跃度 - 极高风险 + if (x >= chartData.value.midX && y >= chartData.value.midY) return chartData.value.quadrantColors.Q2; // 高密度, 高活跃度 - 高风险 + if (x < chartData.value.midX && y < chartData.value.midY) return chartData.value.quadrantColors.Q3; // 低密度, 低活跃度 - 低风险 + return chartData.value.quadrantColors.Q4; // 低密度, 高活跃度 - 健康生态 + }; + + myChart.setOption({ + tooltip: { + trigger: 'item', + formatter: (params: any) => { + return ` +
${params.data.name}
+
代码活跃度: ${params.data.value[0]}
+
漏洞密度: ${params.data.value[1]}
+
漏洞总数: ${params.data.value[2]}
+ `; + } + }, + grid: { left: '3%', right: '4%', bottom: '3%', top: '15%', containLabel: true }, + xAxis: { + type: 'value', + name: '代码活跃度', + nameTextStyle: { fontSize: 12 }, + axisLabel: { fontSize: 12 }, + splitLine: { show: true } + }, + yAxis: { + type: 'value', + name: '漏洞密度', + nameTextStyle: { fontSize: 12 }, + axisLabel: { fontSize: 12 }, + splitLine: { show: true } + }, + series: [{ + type: 'scatter', + data: data, + symbolSize: (val: any) => val[2] / 2, // 根据漏洞总数调整气泡大小 + itemStyle: { + color: (params: any) => getColor(params.value[0], params.value[1]) + }, + label: { + show: true, + formatter: (params: any) => params.data.name, + position: 'inside', + fontSize: 10, + color: '#fff' + } + }] + }); +}; + // 初始化武汉市语言与技术竞争趋势(折线图) const initLanguageTechChart = () => { const el = document.getElementById('languageTechChart'); @@ -1275,7 +1386,8 @@ const initCharts = () => { 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)), - vulnerabilitySeverity: chartData.value.vulnerabilitySeverity.series.every(s => s.data.every(d => d === 0)) + vulnerabilitySeverity: chartData.value.vulnerabilitySeverity.series.every(s => s.data.every(d => d === 0)), + scatterData: chartData.value.scatterData.length === 0 }; // 初始化各图表 @@ -1289,6 +1401,7 @@ const initCharts = () => { if (!isEmpty.value.cveData) nextTick(() => initCVEChart()); if (!isEmpty.value.languageTrend) nextTick(() => initLanguageTrendChart()); if (!isEmpty.value.vulnerabilitySeverity) nextTick(() => initVulnerabilitySeverityChart()); + if (!isEmpty.value.scatterData) nextTick(() => initScatterChart()); }; // 页面resize时重绘图表