<template>
|
<div class="app-container">
|
<el-row :gutter="20" class="stat-cards">
|
<el-col :span="6">
|
<el-card>
|
<div class="stat-item">
|
<div class="stat-icon" style="background: #67c23a;"><el-icon><CircleCheck /></el-icon></div>
|
<div class="stat-info">
|
<span class="stat-value">{{ todayStats.completionRate }}%</span>
|
<span class="stat-label">当日巡检完成率</span>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="6">
|
<el-card>
|
<div class="stat-item">
|
<div class="stat-icon" style="background: #409eff;"><el-icon><User /></el-icon></div>
|
<div class="stat-info">
|
<span class="stat-value">{{ todayStats.inspectorCount }}</span>
|
<span class="stat-label">巡检人员数</span>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="6">
|
<el-card>
|
<div class="stat-item">
|
<div class="stat-icon" style="background: #e6a23c;"><el-icon><Warning /></el-icon></div>
|
<div class="stat-info">
|
<span class="stat-value">{{ todayStats.abnormalCount }}</span>
|
<span class="stat-label">异常记录数</span>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="6">
|
<el-card>
|
<div class="stat-item">
|
<div class="stat-icon" style="background: #f56c6c;"><el-icon><CircleClose /></el-icon></div>
|
<div class="stat-info">
|
<span class="stat-value">{{ todayStats.missedCount }}</span>
|
<span class="stat-label">漏检记录数</span>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
<el-row :gutter="20" class="chart-row">
|
<el-col :span="12">
|
<el-card>
|
<template #header>
|
<span>巡检任务执行趋势</span>
|
</template>
|
<div ref="trendChartRef" style="height: 300px;"></div>
|
</el-card>
|
</el-col>
|
<el-col :span="12">
|
<el-card>
|
<template #header>
|
<span>巡检类型与频率分布</span>
|
</template>
|
<div ref="typeChartRef" style="height: 300px;"></div>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
<el-card class="table-card">
|
<template #header>
|
<span>巡检记录明细</span>
|
</template>
|
<el-form :model="filters" :inline="true">
|
<el-form-item label="巡检日期">
|
<el-date-picker v-model="filters.dateRange" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" />
|
</el-form-item>
|
<el-form-item label="巡检人员">
|
<el-input v-model="filters.inspector" placeholder="请输入巡检人员" clearable style="width: 200px" />
|
</el-form-item>
|
<el-form-item label="状态">
|
<el-select v-model="filters.status" placeholder="请选择" clearable style="width: 150px">
|
<el-option label="正常" value="normal" />
|
<el-option label="异常" value="abnormal" />
|
<el-option label="漏检" value="missed" />
|
<el-option label="未执行" value="unexecuted" />
|
</el-select>
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" @click="getData">搜索</el-button>
|
<el-button @click="resetFilters">重置</el-button>
|
</el-form-item>
|
</el-form>
|
<PIMTable :column="columns" :tableData="dataList" :page="pagination" @pagination="changePage" />
|
</el-card>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, reactive, onMounted } from "vue";
|
import PIMTable from "@/components/PIMTable/PIMTable.vue";
|
import * as echarts from "echarts";
|
|
defineOptions({
|
name: "巡检数据报表",
|
});
|
|
const todayStats = reactive({
|
completionRate: 95,
|
inspectorCount: 8,
|
abnormalCount: 2,
|
missedCount: 1,
|
});
|
|
const filters = reactive({
|
dateRange: [],
|
inspector: "",
|
status: "",
|
});
|
|
const dataList = ref([]);
|
const pagination = reactive({ current: 1, size: 10, total: 0 });
|
|
const columns = [
|
{ label: "巡检时间", prop: "inspectionTime", align: "center" },
|
{ label: "巡检人员", prop: "inspector", align: "center" },
|
{ label: "巡检区域", prop: "area", align: "center" },
|
{ label: "巡检类型", prop: "type", align: "center" },
|
{ label: "状态", prop: "status", align: "center" },
|
{ label: "异常情况", prop: "abnormalDesc", align: "center" },
|
];
|
|
const trendChartRef = ref(null);
|
const typeChartRef = ref(null);
|
|
onMounted(() => {
|
initTrendChart();
|
initTypeChart();
|
});
|
|
const initTrendChart = () => {
|
const chart = echarts.init(trendChartRef.value);
|
const option = {
|
xAxis: {
|
type: "category",
|
data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
|
},
|
yAxis: { type: "value" },
|
series: [
|
{ name: "已完成", type: "line", data: [120, 132, 101, 134, 90, 230, 210], smooth: true },
|
{ name: "未完成", type: "line", data: [20, 12, 21, 14, 30, 20, 10], smooth: true },
|
],
|
legend: { data: ["已完成", "未完成"], bottom: 0 },
|
grid: { left: "3%", right: "4%", bottom: "10%", containLabel: true },
|
};
|
chart.setOption(option);
|
};
|
|
const initTypeChart = () => {
|
const chart = echarts.init(typeChartRef.value);
|
const option = {
|
series: [
|
{
|
type: "pie",
|
radius: ["40%", "70%"],
|
data: [
|
{ value: 335, name: "设备巡检" },
|
{ value: 310, name: "安全巡检" },
|
{ value: 234, name: "环境巡检" },
|
{ value: 135, name: "消防巡检" },
|
],
|
},
|
],
|
legend: { orient: "vertical", left: "left" },
|
};
|
chart.setOption(option);
|
};
|
|
const getData = () => {};
|
const resetFilters = () => {
|
filters.dateRange = [];
|
filters.inspector = "";
|
filters.status = "";
|
};
|
const changePage = ({ page, limit }) => {
|
pagination.current = page;
|
pagination.size = limit;
|
};
|
</script>
|
|
<style lang="scss" scoped>
|
.stat-cards {
|
margin-bottom: 20px;
|
.stat-item {
|
display: flex;
|
align-items: center;
|
.stat-icon {
|
width: 60px;
|
height: 60px;
|
border-radius: 50%;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
color: #fff;
|
font-size: 28px;
|
margin-right: 15px;
|
}
|
.stat-info {
|
display: flex;
|
flex-direction: column;
|
.stat-value {
|
font-size: 24px;
|
font-weight: bold;
|
color: #333;
|
}
|
.stat-label {
|
font-size: 14px;
|
color: #666;
|
margin-top: 5px;
|
}
|
}
|
}
|
}
|
|
.chart-row {
|
margin-bottom: 20px;
|
}
|
|
.table-card {
|
:deep(.el-card__header) {
|
font-weight: bold;
|
}
|
}
|
</style>
|