fix(risk-assessment): 修正统计数据处理及图表更新逻辑
Some checks failed
Lint Code / Lint Code (push) Failing after 3m6s
Some checks failed
Lint Code / Lint Code (push) Failing after 3m6s
- 修正 getRiskStatistics 接口返回数据结构,去除 code 和 data 包装,直接使用业务数据 - 添加详细日志输出统计数据和图表输入数据,便于调试追踪 - 优化饼图和趋势图初始化逻辑,改为懒初始化实例,避免无效初始化 - 饼图数据转换中新增字符串转数字的兼容处理,过滤数值为0的项 - 趋势图调整为使用风险等级分布数据 levelStats,支持字符串及数字类型转换 - 延迟更新图表,确保 DOM 渲染完成后初始化和设置图表 - 移除无用的图表初始化调用,改为数据加载完成后统一更新图表 - 增加 DOM 元素存在性检查及相关警告,防止渲染时出现异常
This commit is contained in:
@@ -261,15 +261,11 @@ async function loadRiskList() {
|
|||||||
params.projectId = String(queryParams.value.projectId);
|
params.projectId = String(queryParams.value.projectId);
|
||||||
}
|
}
|
||||||
const res = await getRiskList(params);
|
const res = await getRiskList(params);
|
||||||
// res.data 直接是业务数据 { total, rows, code, msg }
|
|
||||||
const businessData = res.data as any;
|
const businessData = res.data as any;
|
||||||
console.log("API业务数据:", businessData);
|
|
||||||
if (businessData.code === 200) {
|
if (businessData.code === 200) {
|
||||||
const rows = businessData.rows || [];
|
const rows = businessData.rows || [];
|
||||||
dataList.value = rows;
|
dataList.value = rows;
|
||||||
// 处理字符串类型的total
|
|
||||||
pagination.value.total = parseInt(businessData.total) || rows.length || 0;
|
pagination.value.total = parseInt(businessData.total) || rows.length || 0;
|
||||||
console.log("风险列表数据:", rows);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message("加载风险列表失败", { type: "error" });
|
message("加载风险列表失败", { type: "error" });
|
||||||
@@ -278,29 +274,23 @@ async function loadRiskList() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载项目列表
|
|
||||||
async function loadProjectList() {
|
async function loadProjectList() {
|
||||||
try {
|
try {
|
||||||
const res = await getProjectList({ pageNum: 1, pageSize: 100 });
|
const res = await getProjectList({ pageNum: 1, pageSize: 100 });
|
||||||
// res.data 直接是业务数据 { total, rows, code, msg }
|
|
||||||
const businessData = res.data as any;
|
const businessData = res.data as any;
|
||||||
if (businessData.code === 200) {
|
if (businessData.code === 200) {
|
||||||
projectList.value = businessData.rows || [];
|
projectList.value = businessData.rows || [];
|
||||||
console.log("项目列表:", projectList.value);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("加载项目列表失败", error);
|
console.error("加载项目列表失败", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载统计数据
|
|
||||||
async function loadStatistics() {
|
async function loadStatistics() {
|
||||||
try {
|
try {
|
||||||
const res = await getRiskStatistics();
|
const res = await getRiskStatistics();
|
||||||
const statsResponse = res.data as any;
|
const data = res.data as any;
|
||||||
if (statsResponse.code === 200 && statsResponse.data) {
|
|
||||||
const data = statsResponse.data;
|
|
||||||
// 处理字符串类型的统计数据
|
|
||||||
statistics.value = {
|
statistics.value = {
|
||||||
totalCount: parseInt(data.totalCount) || 0,
|
totalCount: parseInt(data.totalCount) || 0,
|
||||||
identifiedCount: parseInt(data.identifiedCount) || 0,
|
identifiedCount: parseInt(data.identifiedCount) || 0,
|
||||||
@@ -318,25 +308,21 @@ async function loadStatistics() {
|
|||||||
averageRiskScore: parseFloat(data.averageRiskScore) || 0,
|
averageRiskScore: parseFloat(data.averageRiskScore) || 0,
|
||||||
unresolvedHighCount: parseInt(data.unresolvedHighCount) || 0
|
unresolvedHighCount: parseInt(data.unresolvedHighCount) || 0
|
||||||
};
|
};
|
||||||
|
setTimeout(() => {
|
||||||
updateCharts();
|
updateCharts();
|
||||||
}
|
}, 100);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("加载统计数据失败", error);
|
console.error("加载统计数据失败", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化饼图
|
|
||||||
function initPieChart() {
|
|
||||||
if (!pieChartRef.value) return;
|
|
||||||
pieChart = echarts.init(pieChartRef.value);
|
|
||||||
updatePieChart();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新饼图 - 使用 categoryStats 分类统计数据
|
// 更新饼图 - 使用 categoryStats 分类统计数据
|
||||||
function updatePieChart() {
|
function updatePieChart() {
|
||||||
if (!pieChart) return;
|
if (!pieChartRef.value) return;
|
||||||
|
if (!pieChart) {
|
||||||
|
pieChart = echarts.init(pieChartRef.value);
|
||||||
|
}
|
||||||
|
|
||||||
// 从 categoryStats 获取分类统计数据
|
|
||||||
const categoryStats = statistics.value.categoryStats || {};
|
const categoryStats = statistics.value.categoryStats || {};
|
||||||
const categoryColors: Record<string, string> = {
|
const categoryColors: Record<string, string> = {
|
||||||
schedule: "#409eff", // 进度 - 蓝色
|
schedule: "#409eff", // 进度 - 蓝色
|
||||||
@@ -359,13 +345,17 @@ function updatePieChart() {
|
|||||||
other: "其他风险"
|
other: "其他风险"
|
||||||
};
|
};
|
||||||
|
|
||||||
// 构建饼图数据
|
// 构建饼图数据 - 处理字符串类型的值
|
||||||
const data = Object.entries(categoryStats)
|
const data = Object.entries(categoryStats)
|
||||||
.map(([key, value]) => ({
|
.map(([key, value]) => {
|
||||||
value: parseInt(String(value)) || 0,
|
const numValue =
|
||||||
|
typeof value === "string" ? parseInt(value) : (value as number) || 0;
|
||||||
|
return {
|
||||||
|
value: numValue,
|
||||||
name: categoryNames[key] || key,
|
name: categoryNames[key] || key,
|
||||||
itemStyle: { color: categoryColors[key] || "#909399" }
|
itemStyle: { color: categoryColors[key] || "#909399" }
|
||||||
}))
|
};
|
||||||
|
})
|
||||||
.filter(item => item.value > 0)
|
.filter(item => item.value > 0)
|
||||||
.sort((a, b) => b.value - a.value);
|
.sort((a, b) => b.value - a.value);
|
||||||
|
|
||||||
@@ -416,45 +406,53 @@ function updatePieChart() {
|
|||||||
pieChart.setOption(option);
|
pieChart.setOption(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化趋势图
|
|
||||||
function initTrendChart() {
|
function initTrendChart() {
|
||||||
if (!trendChartRef.value) return;
|
if (!trendChartRef.value) return;
|
||||||
trendChart = echarts.init(trendChartRef.value);
|
trendChart = echarts.init(trendChartRef.value);
|
||||||
updateTrendChart();
|
updateTrendChart();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新趋势图 - 使用风险状态分布数据
|
|
||||||
function updateTrendChart() {
|
function updateTrendChart() {
|
||||||
if (!trendChart) return;
|
if (!trendChartRef.value) return;
|
||||||
|
if (!trendChart) {
|
||||||
|
trendChart = echarts.init(trendChartRef.value);
|
||||||
|
}
|
||||||
|
|
||||||
// 使用状态统计数据展示风险状态分布
|
const levelStats = statistics.value.levelStats || {};
|
||||||
const statusData = [
|
const levelData = [
|
||||||
{
|
{
|
||||||
name: "已识别",
|
name: "严重",
|
||||||
value: statistics.value.identifiedCount || 0,
|
value:
|
||||||
color: "#909399"
|
typeof levelStats.critical === "string"
|
||||||
|
? parseInt(levelStats.critical)
|
||||||
|
: (levelStats.critical as number) || 0,
|
||||||
|
color: "#f56c6c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "已分派",
|
name: "高",
|
||||||
value: statistics.value.assignedCount || 0,
|
value:
|
||||||
color: "#409eff"
|
typeof levelStats.high === "string"
|
||||||
},
|
? parseInt(levelStats.high)
|
||||||
{
|
: (levelStats.high as number) || 0,
|
||||||
name: "缓解中",
|
|
||||||
value: statistics.value.mitigatingCount || 0,
|
|
||||||
color: "#e6a23c"
|
color: "#e6a23c"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "已解决",
|
name: "中",
|
||||||
value: statistics.value.resolvedCount || 0,
|
value:
|
||||||
color: "#67c23a"
|
typeof levelStats.medium === "string"
|
||||||
|
? parseInt(levelStats.medium)
|
||||||
|
: (levelStats.medium as number) || 0,
|
||||||
|
color: "#409eff"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "已关闭",
|
name: "低",
|
||||||
value: statistics.value.closedCount || 0,
|
value:
|
||||||
color: "#13c2c2"
|
typeof levelStats.low === "string"
|
||||||
|
? parseInt(levelStats.low)
|
||||||
|
: (levelStats.low as number) || 0,
|
||||||
|
color: "#67c23a"
|
||||||
}
|
}
|
||||||
];
|
].filter(item => item.value > 0);
|
||||||
|
|
||||||
const option = {
|
const option = {
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@@ -474,7 +472,7 @@ function updateTrendChart() {
|
|||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: "category",
|
type: "category",
|
||||||
data: statusData.map(item => item.name),
|
data: levelData.map(item => item.name),
|
||||||
axisLine: { lineStyle: { color: "#dcdfe6" } },
|
axisLine: { lineStyle: { color: "#dcdfe6" } },
|
||||||
axisLabel: { color: "#606266", fontSize: 12 },
|
axisLabel: { color: "#606266", fontSize: 12 },
|
||||||
axisTick: { show: false }
|
axisTick: { show: false }
|
||||||
@@ -489,7 +487,7 @@ function updateTrendChart() {
|
|||||||
{
|
{
|
||||||
name: "风险数量",
|
name: "风险数量",
|
||||||
type: "bar",
|
type: "bar",
|
||||||
data: statusData.map((item, index) => ({
|
data: levelData.map((item, index) => ({
|
||||||
value: item.value,
|
value: item.value,
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
color: item.color,
|
color: item.color,
|
||||||
@@ -510,7 +508,6 @@ function updateTrendChart() {
|
|||||||
trendChart.setOption(option);
|
trendChart.setOption(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新图表
|
|
||||||
function updateCharts() {
|
function updateCharts() {
|
||||||
updatePieChart();
|
updatePieChart();
|
||||||
updateTrendChart();
|
updateTrendChart();
|
||||||
@@ -566,24 +563,15 @@ async function handleCreate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 直接传递字符串ID,避免精度丢失
|
|
||||||
const res = await submitRiskAssessment(String(queryParams.value.projectId));
|
const res = await submitRiskAssessment(String(queryParams.value.projectId));
|
||||||
console.log("风险评估API响应:", res);
|
|
||||||
console.log("res.data:", res.data);
|
|
||||||
const responseData = res.data as any;
|
const responseData = res.data as any;
|
||||||
// 扁平化结构:res.data 直接是 { code: 200, data: {...}, message: "..." }
|
|
||||||
if (responseData.code === 200) {
|
if (responseData.code === 200) {
|
||||||
message("风险评估任务已提交,AI 正在分析中...", { type: "success" });
|
message("风险评估任务已提交,AI 正在分析中...", { type: "success" });
|
||||||
} else {
|
} else {
|
||||||
console.error(
|
|
||||||
"响应code不是200:",
|
|
||||||
responseData.code,
|
|
||||||
responseData.message
|
|
||||||
);
|
|
||||||
message(responseData.message || "提交失败", { type: "error" });
|
message(responseData.message || "提交失败", { type: "error" });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("风险评估请求异常:", error);
|
console.error("风险评估请求异常", error);
|
||||||
message("提交风险评估任务失败", { type: "error" });
|
message("提交风险评估任务失败", { type: "error" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -631,8 +619,7 @@ onMounted(() => {
|
|||||||
loadProjectList();
|
loadProjectList();
|
||||||
loadRiskList();
|
loadRiskList();
|
||||||
loadStatistics();
|
loadStatistics();
|
||||||
initPieChart();
|
// 初始化的图表会在数据加载后通过 updateCharts 自动渲染
|
||||||
initTrendChart();
|
|
||||||
window.addEventListener("resize", handleResize);
|
window.addEventListener("resize", handleResize);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user