报表分析页面添加人员类型和时间范围搜索条件,优化搜索表单布局 #1

Merged
OYX merged 1 commits from 3-20 into main 2026-03-21 13:47:42 +08:00
2 changed files with 158 additions and 52 deletions
Showing only changes of commit 3d0490313e - Show all commits

View File

@@ -55,8 +55,8 @@
<el-table-column label="序号" align="center" prop="id" /> <el-table-column label="序号" align="center" prop="id" />
<el-table-column label="巡检点" align="center" prop="inspectionPoint" /> <el-table-column label="巡检点" align="center" prop="inspectionPoint" />
<el-table-column label="巡检要求" align="center" prop="inspectionRequirements" /> <el-table-column label="巡检要求" align="center" prop="inspectionRequirements" />
<!-- 新增巡检点类型展示 --> <!-- 新增人员类型展示 -->
<el-table-column label="巡检点类型" align="center" prop="inspectionPointType"> <el-table-column label="人员类型" align="center" prop="inspectionPointType">
<template #default="scope"> <template #default="scope">
<dict-tag :options="inspection_point_type" :value="scope.row.inspectionPointType" /> <dict-tag :options="inspection_point_type" :value="scope.row.inspectionPointType" />
</template> </template>
@@ -92,9 +92,9 @@
<el-form-item label="巡检要求" prop="inspectionRequirements"> <el-form-item label="巡检要求" prop="inspectionRequirements">
<el-input v-model="form.inspectionRequirements" placeholder="请输入巡检要求" type="textarea" /> <el-input v-model="form.inspectionRequirements" placeholder="请输入巡检要求" type="textarea" />
</el-form-item> </el-form-item>
<!-- 新增巡检点类型选择 --> <!-- 新增人员类型选择 -->
<el-form-item label="巡检点类型" prop="inspectionPointType"> <el-form-item label="人员类型" prop="inspectionPointType">
<el-select v-model="form.inspectionPointType" placeholder="请选择巡检点类型"> <el-select v-model="form.inspectionPointType" placeholder="请选择人员类型">
<el-option v-for="dict in inspection_point_type" :key="dict.value" :label="dict.label" :value="dict.value" /> <el-option v-for="dict in inspection_point_type" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -130,7 +130,7 @@ import { ref, onMounted, onUnmounted, nextTick } from "vue";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { inspection_point_status } = proxy.useDict("inspection_point_status"); const { inspection_point_status } = proxy.useDict("inspection_point_status");
// 新增:巡检点类型字典 // 新增:人员类型字典
const { inspection_point_type } = proxy.useDict("inspection_point_type"); const { inspection_point_type } = proxy.useDict("inspection_point_type");
// 子组件 // 子组件
const qrCodeDownloaderRef = ref(null); const qrCodeDownloaderRef = ref(null);
@@ -165,7 +165,7 @@ const data = reactive({
], ],
// 新增:类型为必填 // 新增:类型为必填
inspectionPointType: [ inspectionPointType: [
{ required: true, message: "巡检点类型不能为空", trigger: "change" } { required: true, message: "人员类型不能为空", trigger: "change" }
], ],
inspectionStatus: [ inspectionStatus: [
{ required: true, message: "巡检点状态不能为空", trigger: "change" } { required: true, message: "巡检点状态不能为空", trigger: "change" }

View File

@@ -6,20 +6,67 @@
<el-form <el-form
:model="queryParams" :model="queryParams"
ref="queryRef" ref="queryRef"
:inline="true"
v-show="showSearch" v-show="showSearch"
label-width="100px" label-width="100px"
> >
<el-form-item label="巡检点" prop="inspectionPoint"> <el-row :gutter="20">
<el-input v-model="queryParams.inspectionPoint" placeholder="输入巡检点"></el-input> <el-col :span="8">
</el-form-item> <el-form-item label="巡检点" prop="inspectionPoint">
<el-form-item label="巡检人" prop="inspectorId"> <el-input
<el-input v-model="queryParams.inspectorId" placeholder="输入巡检人姓名"></el-input> v-model="queryParams.inspectionPoint"
</el-form-item> placeholder="输入巡检点"
<el-form-item> ></el-input>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> </el-form-item>
<el-button icon="Refresh" @click="resetQuery">重置</el-button> </el-col>
</el-form-item> <el-col :span="8">
<el-form-item label="巡检人" prop="inspectorId">
<el-input
v-model="queryParams.inspectorId"
placeholder="输入巡检人姓名"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="人员类型" prop="personType">
<el-select
v-model="queryParams.personType"
placeholder="请选择人员类型"
clearable
style="width: 100%"
>
<el-option
v-for="dict in inspection_point_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="时间范围">
<el-date-picker
v-model="daterange"
value-format="YYYY-MM-DD"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
style="width: 100%"
></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"
>搜索</el-button
>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form> </el-form>
</el-col> </el-col>
</el-row> </el-row>
@@ -31,8 +78,12 @@
<el-card shadow="never" class="section-card"> <el-card shadow="never" class="section-card">
<div class="section-title">总计</div> <div class="section-title">总计</div>
<el-row :gutter="16"> <el-row :gutter="16">
<el-col :span="12"><Histogram :chart-data="histogramTotalData" /></el-col> <el-col :span="12"
<el-col :span="12"><CircularDiagram :data="inspectorTotalData" /></el-col> ><Histogram :chart-data="histogramTotalData"
/></el-col>
<el-col :span="12"
><CircularDiagram :data="inspectorTotalData"
/></el-col>
</el-row> </el-row>
</el-card> </el-card>
</el-col> </el-col>
@@ -45,8 +96,12 @@
<el-card shadow="never" class="section-card"> <el-card shadow="never" class="section-card">
<div class="section-title">本月</div> <div class="section-title">本月</div>
<el-row :gutter="16"> <el-row :gutter="16">
<el-col :span="12"><Histogram :chart-data="histogramMonthData" /></el-col> <el-col :span="12"
<el-col :span="12"><CircularDiagram :data="inspectorMonthData" /></el-col> ><Histogram :chart-data="histogramMonthData"
/></el-col>
<el-col :span="12"
><CircularDiagram :data="inspectorMonthData"
/></el-col>
</el-row> </el-row>
</el-card> </el-card>
</el-col> </el-col>
@@ -59,8 +114,12 @@
<el-card shadow="never" class="section-card"> <el-card shadow="never" class="section-card">
<div class="section-title">本日</div> <div class="section-title">本日</div>
<el-row :gutter="16"> <el-row :gutter="16">
<el-col :span="12"><Histogram :chart-data="histogramDayData" /></el-col> <el-col :span="12"
<el-col :span="12"><CircularDiagram :data="inspectorDayData" /></el-col> ><Histogram :chart-data="histogramDayData"
/></el-col>
<el-col :span="12"
><CircularDiagram :data="inspectorDayData"
/></el-col>
</el-row> </el-row>
</el-card> </el-card>
</el-col> </el-col>
@@ -71,12 +130,13 @@
<script setup> <script setup>
import * as echarts from "echarts"; import * as echarts from "echarts";
import Histogram from "@/components/ReportAnalytics/Histogram.vue"; import Histogram from "@/components/ReportAnalytics/Histogram.vue";
import CircularDiagram from "@/components/ReportAnalytics/reportCircularDiagram.vue" import CircularDiagram from "@/components/ReportAnalytics/reportCircularDiagram.vue";
import { pointStats3, inspectorStats3 } from "@/api/inspection/report.js"; import { pointStats3, inspectorStats3 } from "@/api/inspection/report.js";
import { ref, reactive, toRefs, getCurrentInstance } from "vue"; import { ref, reactive, toRefs, getCurrentInstance } from "vue";
const showSearch = ref(true); const showSearch = ref(true);
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { inspection_point_type } = proxy.useDict("inspection_point_type");
// 三套柱状数据:总计 / 本月 / 本日(巡检点统计) // 三套柱状数据:总计 / 本月 / 本日(巡检点统计)
const histogramTotalData = ref({ xAxis: [], seriesData: [] }); const histogramTotalData = ref({ xAxis: [], seriesData: [] });
@@ -93,15 +153,16 @@ const totalUser = ref(0);
const monthPoint = ref(0); const monthPoint = ref(0);
const monthUser = ref(0); const monthUser = ref(0);
// const daterangeOccurTime = ref([]); const daterange = ref([]);
const data = reactive({ const data = reactive({
queryParams: { queryParams: {
startTime: null, startTime: null,
endTime: null, endTime: null,
inspectionPoint: '', inspectionPoint: "",
inspectorId: '' inspectorId: "",
} personType: null,
},
}); });
const { queryParams } = toRefs(data); const { queryParams } = toRefs(data);
@@ -109,30 +170,65 @@ const { queryParams } = toRefs(data);
function getList() { function getList() {
queryParams.value = { queryParams.value = {
inspectionPoint: data.queryParams.inspectionPoint, inspectionPoint: data.queryParams.inspectionPoint,
inspectorId: data.queryParams.inspectorId inspectorId: data.queryParams.inspectorId,
personType: data.queryParams.personType,
}; };
if (daterange.value && daterange.value.length === 2) {
queryParams.value.startTime = daterange.value[0];
queryParams.value.endTime = daterange.value[1];
}
// 巡检点统计(三合一:总/月/日) // 巡检点统计(三合一:总/月/日)
pointStats3(queryParams.value).then(res => { pointStats3(queryParams.value).then((res) => {
const d = res.data || {}; const d = res.data || {};
const total = d.total || { xAxis: [], seriesData: [] }; const total = d.total || { xAxis: [], seriesData: [] };
const month = d.month || { xAxis: [], seriesData: [] }; const month = d.month || { xAxis: [], seriesData: [] };
const day = d.day || { xAxis: [], seriesData: [] }; const day = d.day || { xAxis: [], seriesData: [] };
histogramTotalData.value = { xAxis: total.xAxis || [], seriesData: total.seriesData || [] }; histogramTotalData.value = {
histogramMonthData.value = { xAxis: month.xAxis || [], seriesData: month.seriesData || [] }; xAxis: total.xAxis || [],
histogramDayData.value = { xAxis: day.xAxis || [], seriesData: day.seriesData || [] }; seriesData: total.seriesData || [],
totalPoint.value = (histogramTotalData.value.seriesData || []).reduce((a,b)=>a+(b||0),0); };
monthPoint.value = (histogramMonthData.value.seriesData || []).reduce((a,b)=>a+(b||0),0); histogramMonthData.value = {
xAxis: month.xAxis || [],
seriesData: month.seriesData || [],
};
histogramDayData.value = {
xAxis: day.xAxis || [],
seriesData: day.seriesData || [],
};
totalPoint.value = (histogramTotalData.value.seriesData || []).reduce(
(a, b) => a + (b || 0),
0,
);
monthPoint.value = (histogramMonthData.value.seriesData || []).reduce(
(a, b) => a + (b || 0),
0,
);
}); });
// 巡检人统计(三合一:总/月/日) // 巡检人统计(三合一:总/月/日)
inspectorStats3(queryParams.value).then(res=>{ inspectorStats3(queryParams.value).then((res) => {
const d = res.data || {}; const d = res.data || {};
inspectorTotalData.value = (d.total || []).map(i=>({ name:i.name, value:i.value })); inspectorTotalData.value = (d.total || []).map((i) => ({
inspectorMonthData.value = (d.month || []).map(i=>({ name:i.name, value:i.value })); name: i.name,
inspectorDayData.value = (d.day || []).map(i=>({ name:i.name, value:i.value })); value: i.value,
}));
inspectorMonthData.value = (d.month || []).map((i) => ({
name: i.name,
value: i.value,
}));
inspectorDayData.value = (d.day || []).map((i) => ({
name: i.name,
value: i.value,
}));
// 统计卡片上的“巡检人总次数”汇总 // 统计卡片上的“巡检人总次数”汇总
totalUser.value = inspectorTotalData.value.reduce((a,b)=>a+(b.value||0),0); totalUser.value = inspectorTotalData.value.reduce(
monthUser.value = inspectorMonthData.value.reduce((a,b)=>a+(b.value||0),0); (a, b) => a + (b.value || 0),
0,
);
monthUser.value = inspectorMonthData.value.reduce(
(a, b) => a + (b.value || 0),
0,
);
}); });
// 巡检人统计(三合一:总/月/日)保持不变 // 巡检人统计(三合一:总/月/日)保持不变
@@ -143,18 +239,20 @@ function handleQuery() {
} }
function resetQuery() { function resetQuery() {
daterange.value = [];
proxy.resetForm("queryRef"); proxy.resetForm("queryRef");
handleQuery(); handleQuery();
} }
getList(); getList();
// 时间格式工具yyyy-MM-dd HH:mm:ss // 时间格式工具yyyy-MM-dd HH:mm:ss
function pad(n){ return n < 10 ? '0'+n : ''+n } function pad(n) {
function formatDateTime(d){ return n < 10 ? "0" + n : "" + n;
}
function formatDateTime(d) {
const y = d.getFullYear(); const y = d.getFullYear();
const m = pad(d.getMonth()+1); const m = pad(d.getMonth() + 1);
const day = pad(d.getDate()); const day = pad(d.getDate());
const hh = pad(d.getHours()); const hh = pad(d.getHours());
const mm = pad(d.getMinutes()); const mm = pad(d.getMinutes());
@@ -164,10 +262,18 @@ function formatDateTime(d){
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.el-row { .el-row:first-child {
margin-bottom: 20px; margin: 20px 0;
margin-top: 50px; }
.section-card {
padding: 8px 12px;
}
.section-title {
font-weight: 600;
margin-bottom: 8px;
}
:deep(.el-form-item__content) {
margin-left: 10px !important;
} }
.section-card { padding: 8px 12px; }
.section-title { font-weight: 600; margin-bottom: 8px; }
</style> </style>