态势感知平台-全球开源风险态势感知监控中心编程语言安全态势接口对接
This commit is contained in:
@@ -9,8 +9,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, nextTick, onMounted, onUnmounted } from 'vue';
|
import { ref, nextTick, onMounted, onUnmounted, watch } from 'vue';
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
|
import { scatterDataPage1 } from '@/api/jyh/situation';
|
||||||
|
|
||||||
// 空数据标识
|
// 空数据标识
|
||||||
const isEmpty = ref({
|
const isEmpty = ref({
|
||||||
@@ -22,11 +23,61 @@ const chartInstances = ref<{ [key: string]: echarts.ECharts | null }>({
|
|||||||
scatterChart: null
|
scatterChart: null
|
||||||
});
|
});
|
||||||
|
|
||||||
// 气泡图数据
|
// 气泡图数据 - 响应式数据
|
||||||
const scatterData = {
|
const scatterData = ref({
|
||||||
// 基于真实数据:[代码活跃度(X), 漏洞密度(Y), 漏洞总数(Size), 语言名称(Name)]
|
scatterData: [] as any[],
|
||||||
// 活跃度基于新增项目数量,漏洞密度基于CWE分布统计
|
midX: 50,
|
||||||
scatterData: [
|
midY: 50,
|
||||||
|
quadrantColors: {
|
||||||
|
Q1: '#BF232A', // [高密度, 低活跃度] - 极高风险
|
||||||
|
Q2: '#FF4900', // [高密度, 高活跃度] - 高风险,需密切关注
|
||||||
|
Q3: '#00B43E', // [低密度, 低活跃度] - 低风险,但维护成本高
|
||||||
|
Q4: '#0063D0' // [低密度, 高活跃度] - 健康生态
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取后端数据
|
||||||
|
const fetchScatterData = async () => {
|
||||||
|
try {
|
||||||
|
console.log('开始请求编程语言安全态势数据...');
|
||||||
|
const response = await scatterDataPage1();
|
||||||
|
console.log('API响应:', response);
|
||||||
|
|
||||||
|
if (response?.code === 200) {
|
||||||
|
console.log('API返回的数据:', response.data);
|
||||||
|
|
||||||
|
// 处理后端返回的数据格式
|
||||||
|
const processedData = processBackendScatterData(response.data);
|
||||||
|
scatterData.value.scatterData = processedData;
|
||||||
|
|
||||||
|
// 更新空数据标识
|
||||||
|
isEmpty.value.scatterData = !processedData || processedData.length === 0;
|
||||||
|
} else {
|
||||||
|
console.error('获取编程语言安全态势数据失败:', response?.msg || '未知错误');
|
||||||
|
// 设置默认数据
|
||||||
|
setDefaultScatterData();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取编程语言安全态势数据异常:', error);
|
||||||
|
// 发生异常时设置默认数据
|
||||||
|
setDefaultScatterData();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理后端返回的数据格式
|
||||||
|
const processBackendScatterData = (backendData: any[]) => {
|
||||||
|
// 后端返回的数据已经是正确的格式,直接转换即可
|
||||||
|
return backendData.map(item => [
|
||||||
|
item.x, // 代码活跃度(X)
|
||||||
|
item.y, // 漏洞密度(Y)
|
||||||
|
item.size, // 漏洞总数(Size)
|
||||||
|
item.name // 语言名称(Name)
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设置默认数据
|
||||||
|
const setDefaultScatterData = () => {
|
||||||
|
scatterData.value.scatterData = [
|
||||||
[95, 75, 450, 'JavaScript'], // 最高活跃度:9,345,046个项目
|
[95, 75, 450, 'JavaScript'], // 最高活跃度:9,345,046个项目
|
||||||
[90, 70, 380, 'Python'], // 高活跃度:9,261,587个项目
|
[90, 70, 380, 'Python'], // 高活跃度:9,261,587个项目
|
||||||
[85, 65, 320, 'TypeScript'], // 高增长:78.1%增长率
|
[85, 65, 320, 'TypeScript'], // 高增长:78.1%增长率
|
||||||
@@ -37,22 +88,8 @@ const scatterData = {
|
|||||||
[25, 25, 80, 'Go'], // 新兴语言,低漏洞密度
|
[25, 25, 80, 'Go'], // 新兴语言,低漏洞密度
|
||||||
[15, 20, 45, 'Rust'], // 安全性较好的新语言
|
[15, 20, 45, 'Rust'], // 安全性较好的新语言
|
||||||
[60, 50, 200, 'Shell'], // 脚本语言
|
[60, 50, 200, 'Shell'], // 脚本语言
|
||||||
],
|
];
|
||||||
// 四象限分割点
|
isEmpty.value.scatterData = false;
|
||||||
midX: 50,
|
|
||||||
midY: 50,
|
|
||||||
|
|
||||||
// 四象限颜色定义
|
|
||||||
quadrantColors: {
|
|
||||||
// [高密度, 低活跃度] - 极高风险
|
|
||||||
Q1: '#BF232A',
|
|
||||||
// [高密度, 高活跃度] - 高风险,需密切关注
|
|
||||||
Q2: '#FF4900',
|
|
||||||
// [低密度, 低活跃度] - 低风险,但维护成本高
|
|
||||||
Q3: '#00B43E',
|
|
||||||
// [低密度, 高活跃度] - 健康生态
|
|
||||||
Q4: '#0063D0'
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 初始化气泡图
|
// 初始化气泡图
|
||||||
@@ -73,17 +110,17 @@ const initScatterChart = () => {
|
|||||||
chartInstances.value.scatterChart = myChart;
|
chartInstances.value.scatterChart = myChart;
|
||||||
|
|
||||||
// 数据处理
|
// 数据处理
|
||||||
const data = scatterData.scatterData.map(item => ({
|
const data = scatterData.value.scatterData.map(item => ({
|
||||||
value: [item[0], item[1], item[2]],
|
value: [item[0], item[1], item[2]],
|
||||||
name: item[3]
|
name: item[3]
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 计算四象限颜色
|
// 计算四象限颜色
|
||||||
const getColor = (x: number, y: number) => {
|
const getColor = (x: number, y: number) => {
|
||||||
if (x < scatterData.midX && y >= scatterData.midY) return scatterData.quadrantColors.Q1; // 高密度, 低活跃度 - 极高风险
|
if (x < scatterData.value.midX && y >= scatterData.value.midY) return scatterData.value.quadrantColors.Q1; // 高密度, 低活跃度 - 极高风险
|
||||||
if (x >= scatterData.midX && y >= scatterData.midY) return scatterData.quadrantColors.Q2; // 高密度, 高活跃度 - 高风险
|
if (x >= scatterData.value.midX && y >= scatterData.value.midY) return scatterData.value.quadrantColors.Q2; // 高密度, 高活跃度 - 高风险
|
||||||
if (x < scatterData.midX && y < scatterData.midY) return scatterData.quadrantColors.Q3; // 低密度, 低活跃度 - 低风险
|
if (x < scatterData.value.midX && y < scatterData.value.midY) return scatterData.value.quadrantColors.Q3; // 低密度, 低活跃度 - 低风险
|
||||||
return scatterData.quadrantColors.Q4; // 低密度, 高活跃度 - 健康生态
|
return scatterData.value.quadrantColors.Q4; // 低密度, 高活跃度 - 健康生态
|
||||||
};
|
};
|
||||||
|
|
||||||
myChart.setOption({
|
myChart.setOption({
|
||||||
@@ -139,13 +176,23 @@ const initScatterChart = () => {
|
|||||||
}, 0);
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 在组件挂载后初始化图表
|
// 在组件挂载后获取数据并初始化图表
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
|
await fetchScatterData();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
initScatterChart();
|
initScatterChart();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 监听数据变化,重新初始化图表
|
||||||
|
watch(scatterData, () => {
|
||||||
|
if (!isEmpty.value.scatterData) {
|
||||||
|
nextTick(() => {
|
||||||
|
initScatterChart();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
// 在组件卸载前清理资源
|
// 在组件卸载前清理资源
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
if (chartInstances.value.scatterChart) {
|
if (chartInstances.value.scatterChart) {
|
||||||
|
|||||||
Reference in New Issue
Block a user