0926
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="operation-inspection">
|
||||
<div class="navigation-tabs">
|
||||
<!-- <div class="navigation-tabs">
|
||||
<div class="nav-tab" @click="handleInspection1">待办事项</div>
|
||||
<div class="nav-tab active" @click="handleInspection2">巡检管理</div>
|
||||
<div class="nav-tab" @click="handleInspection3">试验管理</div>
|
||||
@ -8,7 +8,7 @@
|
||||
<div class="nav-tab" @click="handleInspection5">抢修管理</div>
|
||||
<div class="nav-tab" @click="handleInspection6">工单管理</div>
|
||||
<div class="nav-tab" @click="handleInspection7">运维组织</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="header-container">
|
||||
<div class="header-actions">
|
||||
<el-button type="primary" class="export-btn">筛选</el-button>
|
||||
@ -127,14 +127,14 @@
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<div class="flex justify-between text-sm mb-1">
|
||||
<span class="text-gray-600">完成率</span>
|
||||
<span class="text-gray-600">巡检完成率</span>
|
||||
<span class="font-medium text-gray-800">{{ completionRate }}%</span>
|
||||
</div>
|
||||
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
|
||||
<div class="bg-blue-500 h-2 rounded-full transition-all duration-1500 ease-out" :style="{ width: completionRate + '%' }"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<!-- <div>
|
||||
<div class="flex justify-between text-sm mb-1">
|
||||
<span class="text-gray-600">解决率</span>
|
||||
<span class="font-medium text-gray-800">{{ resolutionRate }}%</span>
|
||||
@ -142,10 +142,10 @@
|
||||
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
|
||||
<div class="bg-red-500 h-2 rounded-full transition-all duration-1500 ease-out" :style="{ width: resolutionRate + '%' }"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div>
|
||||
<div class="flex justify-between text-sm mb-1">
|
||||
<span class="text-gray-600">及时率</span>
|
||||
<span class="text-gray-600">解决效率</span>
|
||||
<span class="font-medium text-gray-800">{{ timelinessRate }}%</span>
|
||||
</div>
|
||||
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
|
||||
@ -161,65 +161,8 @@
|
||||
<!-- 发现问题种类 -->
|
||||
<div class="py-4">
|
||||
<h3 class="section-title">发现问题种类</h3>
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<div class="flex justify-between text-sm mb-1">
|
||||
<span class="text-gray-600">温度异常率</span>
|
||||
<span class="text-gray-500">{{ problemTypes.temperature }}%</span>
|
||||
</div>
|
||||
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
|
||||
<div
|
||||
class="bg-blue-500 h-2 rounded-full transition-all duration-1500 ease-out"
|
||||
:style="{ width: problemTypes.temperature + '%' }"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex justify-between text-sm mb-1">
|
||||
<span class="text-gray-600">内存使用率</span>
|
||||
<span class="text-gray-500">{{ problemTypes.memory }}%</span>
|
||||
</div>
|
||||
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
|
||||
<div
|
||||
class="bg-blue-500 h-2 rounded-full transition-all duration-1500 ease-out"
|
||||
:style="{ width: problemTypes.memory + '%' }"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex justify-between text-sm mb-1">
|
||||
<span class="text-gray-600">CPU负载</span>
|
||||
<span class="text-gray-500">{{ problemTypes.cpu }}%</span>
|
||||
</div>
|
||||
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
|
||||
<div class="bg-blue-500 h-2 rounded-full transition-all duration-1500 ease-out" :style="{ width: problemTypes.cpu + '%' }"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex justify-between text-sm mb-1">
|
||||
<span class="text-gray-600">响应时间</span>
|
||||
<span class="text-gray-500">{{ problemTypes.responseTime }}%</span>
|
||||
</div>
|
||||
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
|
||||
<div
|
||||
class="bg-blue-500 h-2 rounded-full transition-all duration-1500 ease-out"
|
||||
:style="{ width: problemTypes.responseTime + '%' }"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex justify-between text-sm mb-1">
|
||||
<span class="text-gray-600">磁盘空间状态</span>
|
||||
<span class="text-gray-500">{{ problemTypes.diskSpace }}%</span>
|
||||
</div>
|
||||
<div class="w-full bg-gray-200 rounded-full h-2 overflow-hidden">
|
||||
<div
|
||||
class="bg-blue-500 h-2 rounded-full transition-all duration-1500 ease-out"
|
||||
:style="{ width: problemTypes.diskSpace + '%' }"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 柱状图容器 -->
|
||||
<div id="problemTypesChart" class="bar-chart-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -388,16 +331,17 @@ const avgCompletionTime = ref('45分钟');
|
||||
|
||||
// 问题类型数据
|
||||
const problemTypes = ref({
|
||||
temperature: 85, // 温度异常率
|
||||
memory: 62, // 内存使用率
|
||||
cpu: 45, // CPU负载
|
||||
responseTime: 30, // 响应时间
|
||||
diskSpace: 15 // 磁盘空间状态
|
||||
temperature: 0, // 温度异常数量
|
||||
memory: 0, // 内存使用率问题数量
|
||||
cpu: 0, // CPU负载问题数量
|
||||
responseTime: 0, // 响应时间问题数量
|
||||
diskSpace: 0 // 磁盘空间问题数量
|
||||
});
|
||||
|
||||
// ECharts 饼图相关
|
||||
// ECharts 图表相关
|
||||
const pieChartRef = ref(null);
|
||||
let pieChart = null;
|
||||
let barChart = null;
|
||||
|
||||
// 计算平均完成度
|
||||
const averageRate = computed(() => (completionRate.value + resolutionRate.value + timelinessRate.value) / 3);
|
||||
@ -426,7 +370,7 @@ const initPieChart = () => {
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '进度指标',
|
||||
name: '指标对比',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
@ -442,20 +386,15 @@ const initPieChart = () => {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 40,
|
||||
fontWeight: 'bold',
|
||||
formatter: function (params) {
|
||||
// 鼠标悬停时显示当前指标的百分比
|
||||
return params.value + '%';
|
||||
}
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: completionRate.value, name: '完成率', itemStyle: { color: '#5470c6' } },
|
||||
{ value: resolutionRate.value, name: '解决率', itemStyle: { color: '#f56c6c' } },
|
||||
{ value: timelinessRate.value, name: '及时率', itemStyle: { color: '#67c23a' } }
|
||||
{ value: completionRate.value, name: '巡检完成率', itemStyle: { color: '#409eff' } },
|
||||
{ value: timelinessRate.value, name: '解决效率', itemStyle: { color: '#67c23a' } }
|
||||
]
|
||||
}
|
||||
]
|
||||
@ -506,11 +445,7 @@ const fetchDashboardData = async () => {
|
||||
// 构建查询参数
|
||||
const queryParams = {
|
||||
projectId: 1,
|
||||
type: type,
|
||||
status: filterStatus.value !== 'all' ? filterStatus.value : undefined,
|
||||
inspectionType: filterType.value !== 'all' ? filterType.value : undefined,
|
||||
startTime: dateRange.value.length > 0 ? dateRange.value[0] : undefined,
|
||||
endTime: dateRange.value.length > 0 ? dateRange.value[1] : undefined
|
||||
type: type
|
||||
};
|
||||
|
||||
// 调用接口获取数据
|
||||
@ -526,22 +461,26 @@ const fetchDashboardData = async () => {
|
||||
solvedProblems.value = data.solvedProblemCount || 0;
|
||||
avgCompletionTime.value = data.averageCompletionTime ? `${data.averageCompletionTime}分钟` : '0分钟';
|
||||
|
||||
// 计算完成率、解决率、及时率
|
||||
completionRate.value = data.finishInspectionCount && data.finishInspectionCount > 0 ? Math.round(Math.random() * 30 + 60) : 0;
|
||||
resolutionRate.value = data.solvedProblemCount && data.problemCount ? Math.round((data.solvedProblemCount / data.problemCount) * 100) : 0;
|
||||
timelinessRate.value = data.finishInspectionCount && data.finishInspectionCount > 0 ? Math.round(Math.random() * 30 + 50) : 0;
|
||||
// 使用接口返回的xjwcl(巡检完成率)和jjxl(解决效率)
|
||||
completionRate.value = data.xjwcl ? parseFloat(data.xjwcl) : 0;
|
||||
timelinessRate.value = data.jjxl ? parseFloat(data.jjxl) : 0;
|
||||
|
||||
// 更新问题类型数据
|
||||
// 由于接口不再返回解决率,将其设置为0或保持原值
|
||||
resolutionRate.value = 0;
|
||||
|
||||
// 更新问题类型数据 - 直接使用接口返回的数值,不再计算为百分比
|
||||
problemTypes.value = {
|
||||
temperature: data.sbyxzt ? Math.min(100, Math.round(data.sbyxzt * 5)) : 0, // 设备运行状态映射为温度异常
|
||||
memory: data.ncsyl ? Math.min(100, data.ncsyl * 10) : 0, // 内存使用率
|
||||
cpu: Math.round(Math.random() * 50 + 20), // CPU负载(模拟数据)
|
||||
responseTime: data.xysj ? Math.min(100, data.xysj * 5) : 0, // 响应时间
|
||||
diskSpace: data.cpsyl ? Math.min(100, data.cpsyl * 8) : 0 // 磁盘使用率
|
||||
temperature: data.sbyxzt || 0, // 设备运行状态类型问题数量
|
||||
memory: data.ncsyl || 0, // 内存使用率类型问题数量
|
||||
cpu: data.fwzt || 0, // 服务状态类型问题数量
|
||||
responseTime: data.xysj || 0, // 响应时间类型问题数量
|
||||
diskSpace: data.cpsyl || 0 // 磁盘使用率类型问题数量
|
||||
};
|
||||
|
||||
// 更新饼图
|
||||
initPieChart();
|
||||
// 更新柱状图
|
||||
initBarChart();
|
||||
} else {
|
||||
ElMessage.error(response.msg || '获取数据失败');
|
||||
}
|
||||
@ -551,17 +490,115 @@ const fetchDashboardData = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 页面加载时获取数据
|
||||
// 页面加载时直接获取数据
|
||||
onMounted(() => {
|
||||
fetchDashboardData();
|
||||
});
|
||||
|
||||
// 初始化柱状图
|
||||
const initBarChart = () => {
|
||||
const chartDom = document.getElementById('problemTypesChart');
|
||||
if (!chartDom) return;
|
||||
|
||||
// 销毁旧实例
|
||||
if (barChart) {
|
||||
barChart.dispose();
|
||||
}
|
||||
|
||||
// 创建新实例
|
||||
barChart = echarts.init(chartDom);
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
},
|
||||
formatter: function (params) {
|
||||
return params[0].name + ': ' + params[0].value + '个';
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '5%',
|
||||
right: '5%',
|
||||
bottom: '10%',
|
||||
top: '5%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
name: '问题数量',
|
||||
axisLabel: {
|
||||
formatter: '{value}个'
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'dashed'
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
data: ['温度异常', '内存使用率', 'CPU负载', '响应时间', '磁盘空间'],
|
||||
axisLabel: {
|
||||
interval: 0
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '问题数量',
|
||||
type: 'bar',
|
||||
barWidth: '40%',
|
||||
data: [
|
||||
problemTypes.value.temperature,
|
||||
problemTypes.value.memory,
|
||||
problemTypes.value.cpu,
|
||||
problemTypes.value.responseTime,
|
||||
problemTypes.value.diskSpace
|
||||
],
|
||||
itemStyle: {
|
||||
color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
|
||||
{ offset: 0, color: '#5470c6' },
|
||||
{ offset: 1, color: '#91cc75' }
|
||||
]),
|
||||
borderRadius: [0, 4, 4, 0]
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: 'right',
|
||||
formatter: '{c}个'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
barChart.setOption(option);
|
||||
|
||||
// 响应式处理
|
||||
const handleResize = () => {
|
||||
if (barChart) {
|
||||
barChart.resize();
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('resize', handleResize);
|
||||
|
||||
// 组件卸载时移除事件监听
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
});
|
||||
};
|
||||
|
||||
// 组件卸载时销毁图表实例
|
||||
onUnmounted(() => {
|
||||
if (pieChart) {
|
||||
pieChart.dispose();
|
||||
pieChart = null;
|
||||
}
|
||||
if (barChart) {
|
||||
barChart.dispose();
|
||||
barChart = null;
|
||||
}
|
||||
});
|
||||
|
||||
// 导航方法
|
||||
@ -802,6 +839,17 @@ const handleInspectionManagement3 = () => {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* 柱状图容器 */
|
||||
.bar-chart-container {
|
||||
width: 100%;
|
||||
height: 350px;
|
||||
margin: 0 auto;
|
||||
background-color: #fafafa;
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
/* 区域标题 */
|
||||
.section-title {
|
||||
font-size: 14px;
|
||||
|
||||
Reference in New Issue
Block a user