303 lines
9.0 KiB
Vue
303 lines
9.0 KiB
Vue
|
|
<template>
|
|||
|
|
<div>
|
|||
|
|
<div class="px-4 text-sm text-gray-500">
|
|||
|
|
分析指数是根据网络行为大数据出具的分析评估参考分数,分数越高越好。该指数仅对本报告有效,不代表对报告查询人的综合定性评价。
|
|||
|
|
</div>
|
|||
|
|
<div ref="chartRef" :style="{ width: '100%', height: '200px' }"></div>
|
|||
|
|
<div class="risk-description">
|
|||
|
|
{{ riskDescription }}
|
|||
|
|
</div>
|
|||
|
|
<div class="risk-legend mt-6">
|
|||
|
|
<div v-for="item in legendItems" :key="item.level" class="risk-legend__item">
|
|||
|
|
<span class="risk-legend__pill" :style="{ backgroundColor: item.color, color: item.textColor }">
|
|||
|
|
{{ item.range }}
|
|||
|
|
</span>
|
|||
|
|
<span class="risk-legend__text">{{ item.level }}</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script setup>
|
|||
|
|
import * as echarts from "echarts";
|
|||
|
|
import { ref, onMounted, onUnmounted, watch, computed } from "vue";
|
|||
|
|
|
|||
|
|
const props = defineProps({
|
|||
|
|
score: {
|
|||
|
|
type: Number,
|
|||
|
|
required: true,
|
|||
|
|
},
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 根据分数计算风险等级和颜色(分数越高越安全)
|
|||
|
|
const riskLevel = computed(() => {
|
|||
|
|
const score = props.score;
|
|||
|
|
if (score >= 75 && score <= 100) {
|
|||
|
|
return {
|
|||
|
|
level: "无任何风险",
|
|||
|
|
color: "#52c41a",
|
|||
|
|
gradient: [
|
|||
|
|
{ offset: 0, color: "#52c41a" },
|
|||
|
|
{ offset: 1, color: "#7fdb42" }
|
|||
|
|
]
|
|||
|
|
};
|
|||
|
|
} else if (score >= 50 && score < 75) {
|
|||
|
|
return {
|
|||
|
|
level: "风险指数较低",
|
|||
|
|
color: "#faad14",
|
|||
|
|
gradient: [
|
|||
|
|
{ offset: 0, color: "#faad14" },
|
|||
|
|
{ offset: 1, color: "#ffc53d" }
|
|||
|
|
]
|
|||
|
|
};
|
|||
|
|
} else if (score >= 25 && score < 50) {
|
|||
|
|
return {
|
|||
|
|
level: "风险指数较高",
|
|||
|
|
color: "#fa8c16",
|
|||
|
|
gradient: [
|
|||
|
|
{ offset: 0, color: "#fa8c16" },
|
|||
|
|
{ offset: 1, color: "#ffa940" }
|
|||
|
|
]
|
|||
|
|
};
|
|||
|
|
} else {
|
|||
|
|
return {
|
|||
|
|
level: "高风险警告",
|
|||
|
|
color: "#f5222d",
|
|||
|
|
gradient: [
|
|||
|
|
{ offset: 0, color: "#f5222d" },
|
|||
|
|
{ offset: 1, color: "#ff4d4f" }
|
|||
|
|
]
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 评分解释文本(分数越高越安全)
|
|||
|
|
const riskDescription = computed(() => {
|
|||
|
|
const score = props.score;
|
|||
|
|
if (score >= 75 && score <= 100) {
|
|||
|
|
return "根据综合分析,当前报告未检测到明显风险因素,各项指标表现正常,总体状况良好。";
|
|||
|
|
} else if (score >= 50 && score < 75) {
|
|||
|
|
return "根据综合分析,当前报告存在少量风险信号,建议关注相关指标变化,保持警惕。";
|
|||
|
|
} else if (score >= 25 && score < 50) {
|
|||
|
|
return "根据综合分析,当前报告风险指数较高,多项指标显示异常,建议进一步核实相关情况。";
|
|||
|
|
} else {
|
|||
|
|
return "根据综合分析,当前报告显示高度风险状态,多项重要指标严重异常,请立即采取相应措施。";
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const chartRef = ref(null);
|
|||
|
|
let chartInstance = null;
|
|||
|
|
|
|||
|
|
const legendItems = [
|
|||
|
|
{ level: "高风险", color: "#f5222d", range: "0-24", textColor: "#ffffff" },
|
|||
|
|
{ level: "一般", color: "#fa8c16", range: "25-49", textColor: "#ffffff" },
|
|||
|
|
{ level: "良好", color: "#faad14", range: "50-74", textColor: "#ffffff" },
|
|||
|
|
{ level: "优秀", color: "#52c41a", range: "75-100", textColor: "#ffffff" }
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
const initChart = () => {
|
|||
|
|
if (!chartRef.value) return;
|
|||
|
|
|
|||
|
|
// 初始化ECharts实例
|
|||
|
|
chartInstance = echarts.init(chartRef.value);
|
|||
|
|
updateChart();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const updateChart = () => {
|
|||
|
|
if (!chartInstance) return;
|
|||
|
|
|
|||
|
|
// 获取当前风险等级信息
|
|||
|
|
const risk = riskLevel.value;
|
|||
|
|
|
|||
|
|
// 配置项
|
|||
|
|
const option = {
|
|||
|
|
series: [
|
|||
|
|
{
|
|||
|
|
type: "gauge",
|
|||
|
|
startAngle: 180,
|
|||
|
|
endAngle: 0,
|
|||
|
|
min: 0,
|
|||
|
|
max: 100,
|
|||
|
|
radius: "100%",
|
|||
|
|
center: ["50%", "80%"],
|
|||
|
|
itemStyle: {
|
|||
|
|
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, risk.gradient),
|
|||
|
|
shadowBlur: 6,
|
|||
|
|
shadowColor: risk.color,
|
|||
|
|
},
|
|||
|
|
progress: {
|
|||
|
|
show: true,
|
|||
|
|
width: 20,
|
|||
|
|
roundCap: true,
|
|||
|
|
clip: false
|
|||
|
|
},
|
|||
|
|
axisLine: {
|
|||
|
|
roundCap: true,
|
|||
|
|
lineStyle: {
|
|||
|
|
width: 20,
|
|||
|
|
color: [
|
|||
|
|
[1, new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: risk.color + "30" // 使用风险颜色,透明度20%
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: risk.color + "25" // 使用风险颜色,透明度10%
|
|||
|
|
}
|
|||
|
|
])]
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
axisTick: {
|
|||
|
|
show: true,
|
|||
|
|
distance: -30,
|
|||
|
|
length: 6,
|
|||
|
|
splitNumber: 10, // 每1分一个小刻度
|
|||
|
|
lineStyle: {
|
|||
|
|
color: risk.color,
|
|||
|
|
width: 1,
|
|||
|
|
opacity: 0.5
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
splitLine: {
|
|||
|
|
show: true,
|
|||
|
|
distance: -36,
|
|||
|
|
length: 12,
|
|||
|
|
splitNumber: 9, // 9个大刻度,100分分成9个区间
|
|||
|
|
lineStyle: {
|
|||
|
|
color: risk.color,
|
|||
|
|
width: 2,
|
|||
|
|
opacity: 0.5
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
axisLabel: {
|
|||
|
|
show: false,
|
|||
|
|
},
|
|||
|
|
anchor: {
|
|||
|
|
show: false
|
|||
|
|
},
|
|||
|
|
pointer: {
|
|||
|
|
icon: "triangle",
|
|||
|
|
iconStyle: {
|
|||
|
|
color: risk.color,
|
|||
|
|
borderColor: risk.color,
|
|||
|
|
borderWidth: 1
|
|||
|
|
},
|
|||
|
|
offsetCenter: ["7%", "-67%"],
|
|||
|
|
length: "10%",
|
|||
|
|
width: 15
|
|||
|
|
},
|
|||
|
|
detail: {
|
|||
|
|
valueAnimation: true,
|
|||
|
|
fontSize: 30,
|
|||
|
|
fontWeight: "bold",
|
|||
|
|
color: risk.color,
|
|||
|
|
offsetCenter: [0, "-25%"],
|
|||
|
|
formatter: function (value) {
|
|||
|
|
return `{value|${value}分}\n{level|${risk.level}}`;
|
|||
|
|
},
|
|||
|
|
rich: {
|
|||
|
|
value: {
|
|||
|
|
fontSize: 30,
|
|||
|
|
fontWeight: 'bold',
|
|||
|
|
color: risk.color,
|
|||
|
|
padding: [0, 0, 5, 0]
|
|||
|
|
},
|
|||
|
|
level: {
|
|||
|
|
fontSize: 14,
|
|||
|
|
fontWeight: 'normal',
|
|||
|
|
color: risk.color,
|
|||
|
|
padding: [5, 0, 0, 0]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
data: [
|
|||
|
|
{
|
|||
|
|
value: props.score
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
title: {
|
|||
|
|
fontSize: 14,
|
|||
|
|
color: risk.color,
|
|||
|
|
offsetCenter: [0, "10%"],
|
|||
|
|
formatter: risk.level
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 使用配置项设置图表
|
|||
|
|
chartInstance.setOption(option);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 监听分数变化
|
|||
|
|
watch(
|
|||
|
|
() => props.score,
|
|||
|
|
() => {
|
|||
|
|
updateChart();
|
|||
|
|
}
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
onMounted(() => {
|
|||
|
|
initChart();
|
|||
|
|
|
|||
|
|
// 处理窗口大小变化
|
|||
|
|
window.addEventListener("resize", () => {
|
|||
|
|
if (chartInstance) {
|
|||
|
|
chartInstance.resize();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 在组件销毁前清理
|
|||
|
|
onUnmounted(() => {
|
|||
|
|
if (chartInstance) {
|
|||
|
|
chartInstance.dispose();
|
|||
|
|
chartInstance = null;
|
|||
|
|
}
|
|||
|
|
window.removeEventListener("resize", chartInstance?.resize);
|
|||
|
|
});
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style scoped>
|
|||
|
|
.risk-description {
|
|||
|
|
margin-bottom: 4px;
|
|||
|
|
padding: 0 12px;
|
|||
|
|
color: #666666;
|
|||
|
|
font-size: 12px;
|
|||
|
|
line-height: 1.5;
|
|||
|
|
text-align: center;
|
|||
|
|
}
|
|||
|
|
.risk-legend {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
gap: 16px;
|
|||
|
|
padding: 0 16px 12px;
|
|||
|
|
font-size: 12px;
|
|||
|
|
color: #666666;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.risk-legend__item {
|
|||
|
|
display: flex;
|
|||
|
|
flex-direction: column;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 6px;
|
|||
|
|
justify-content: center;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.risk-legend__pill {
|
|||
|
|
display: inline-flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
padding: 2px 12px;
|
|||
|
|
border-radius: 9999px;
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 600;
|
|||
|
|
min-width: 64px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.risk-legend__text {
|
|||
|
|
white-space: nowrap;
|
|||
|
|
}
|
|||
|
|
</style>
|