<template>
|
<div class="app-container">
|
<el-form :model="filters" :inline="true">
|
<el-form-item label="巡检名称">
|
<el-input
|
v-model="filters.name"
|
style="width: 240px"
|
placeholder="请输入巡检名称"
|
clearable
|
:prefix-icon="Search"
|
@change="getTableData"
|
/>
|
</el-form-item>
|
<el-form-item label="巡检状态">
|
<el-select
|
v-model="filters.status"
|
style="width: 240px"
|
placeholder="请选择巡检状态"
|
clearable
|
@change="getTableData"
|
>
|
<el-option label="待执行" value="0"></el-option>
|
<el-option label="执行中" value="1"></el-option>
|
<el-option label="已完成" value="2"></el-option>
|
<el-option label="已取消" value="3"></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="巡检类型">
|
<el-select
|
v-model="filters.type"
|
style="width: 240px"
|
placeholder="请选择巡检类型"
|
clearable
|
@change="getTableData"
|
>
|
<el-option label="定期巡检" value="0"></el-option>
|
<el-option label="临时巡检" value="1"></el-option>
|
<el-option label="故障巡检" value="2"></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item>
|
<el-button type="primary" @click="getTableData">搜索</el-button>
|
<el-button @click="resetFilters">重置</el-button>
|
</el-form-item>
|
</el-form>
|
<div class="table_list">
|
<div class="actions">
|
<div></div>
|
<div>
|
<el-button type="primary" @click="add" icon="Plus"> 新增 </el-button>
|
<el-button
|
type="danger"
|
icon="Delete"
|
:disabled="multipleList.length <= 0"
|
@click="batchDelete"
|
>批量删除</el-button
|
>
|
</div>
|
</div>
|
<PIMTable
|
rowKey="id"
|
isSelection
|
:column="columns"
|
:tableData="dataList"
|
:page="{
|
current: pagination.currentPage,
|
size: pagination.pageSize,
|
total: pagination.total,
|
}"
|
@selection-change="handleSelectionChange"
|
@pagination="changePage"
|
>
|
</PIMTable>
|
</div>
|
<!-- 新增编辑弹窗 -->
|
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
|
<el-form :model="formData" label-width="100px">
|
<el-form-item label="巡检名称" required>
|
<el-input
|
v-model="formData.name"
|
placeholder="请输入巡检名称"
|
></el-input>
|
</el-form-item>
|
<el-form-item label="巡检类型" required>
|
<el-select v-model="formData.type" placeholder="请选择巡检类型">
|
<el-option label="定期巡检" value="0"></el-option>
|
<el-option label="临时巡检" value="1"></el-option>
|
<el-option label="故障巡检" value="2"></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="巡检区域" required>
|
<el-input
|
v-model="formData.area"
|
placeholder="请输入巡检区域"
|
></el-input>
|
</el-form-item>
|
<el-form-item label="巡检人员" required>
|
<el-input
|
v-model="formData.inspector"
|
placeholder="请输入巡检人员"
|
></el-input>
|
</el-form-item>
|
<el-form-item label="计划开始时间" required>
|
<el-date-picker
|
v-model="formData.planStartTime"
|
type="datetime"
|
placeholder="请选择计划开始时间"
|
style="width: 100%"
|
></el-date-picker>
|
</el-form-item>
|
<el-form-item label="计划结束时间" required>
|
<el-date-picker
|
v-model="formData.planEndTime"
|
type="datetime"
|
placeholder="请选择计划结束时间"
|
style="width: 100%"
|
></el-date-picker>
|
</el-form-item>
|
<el-form-item label="巡检内容">
|
<el-input
|
v-model="formData.content"
|
type="textarea"
|
rows="3"
|
placeholder="请输入巡检内容"
|
></el-input>
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-button type="primary" @click="saveData">确定</el-button>
|
</span>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, reactive, computed, onMounted } from "vue";
|
import { Search, Plus, Delete } from "@element-plus/icons-vue";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
import dayjs from "dayjs";
|
|
// 定义假数据
|
const mockData = [
|
{
|
id: 1,
|
name: "东门区域日常巡检",
|
type: "0",
|
status: "2",
|
planStartTime: "2025-12-30 08:00:00",
|
planEndTime: "2025-12-30 09:00:00",
|
actualStartTime: "2025-12-30 08:05:00",
|
actualEndTime: "2025-12-30 08:55:00",
|
inspector: "张三",
|
area: "东门区域",
|
content: "检查门禁设备运行状态、环境监测设备数据",
|
},
|
{
|
id: 2,
|
name: "西门区域临时巡检",
|
type: "1",
|
status: "2",
|
planStartTime: "2025-12-30 10:00:00",
|
planEndTime: "2025-12-30 11:00:00",
|
actualStartTime: "2025-12-30 10:00:00",
|
actualEndTime: "2025-12-30 10:45:00",
|
inspector: "李四",
|
area: "西门区域",
|
content: "检查异常报警设备",
|
},
|
{
|
id: 3,
|
name: "南门门禁故障巡检",
|
type: "2",
|
status: "1",
|
planStartTime: "2025-12-30 13:00:00",
|
planEndTime: "2025-12-30 14:00:00",
|
actualStartTime: "2025-12-30 13:10:00",
|
actualEndTime: "",
|
inspector: "王五",
|
area: "南门区域",
|
content: "修复门禁故障",
|
},
|
{
|
id: 4,
|
name: "中控室定期巡检",
|
type: "0",
|
status: "0",
|
planStartTime: "2025-12-31 09:00:00",
|
planEndTime: "2025-12-31 10:00:00",
|
actualStartTime: "",
|
actualEndTime: "",
|
inspector: "赵六",
|
area: "中控区域",
|
content: "检查监控设备、服务器运行状态",
|
},
|
{
|
id: 5,
|
name: "北门区域日常巡检",
|
type: "0",
|
status: "2",
|
planStartTime: "2025-12-30 15:00:00",
|
planEndTime: "2025-12-30 16:00:00",
|
actualStartTime: "2025-12-30 15:00:00",
|
actualEndTime: "2025-12-30 15:50:00",
|
inspector: "张三",
|
area: "北门区域",
|
content: "检查车辆识别设备、道闸运行状态",
|
},
|
];
|
|
// 响应式数据
|
const filters = reactive({
|
name: "",
|
status: "",
|
type: "",
|
});
|
|
const dataList = ref([]);
|
const pagination = reactive({
|
currentPage: 1,
|
pageSize: 10,
|
total: 0,
|
});
|
|
const multipleList = ref([]);
|
const dialogVisible = ref(false);
|
const dialogTitle = ref("新增巡检");
|
const formData = reactive({
|
id: "",
|
name: "",
|
type: "0",
|
status: "0",
|
planStartTime: "",
|
planEndTime: "",
|
actualStartTime: "",
|
actualEndTime: "",
|
inspector: "",
|
area: "",
|
content: "",
|
});
|
|
// 状态映射
|
const statusMap = {
|
'0': '<el-tag type="warning">待执行</el-tag>',
|
'1': '<el-tag type="primary">执行中</el-tag>',
|
'2': '<el-tag type="success">已完成</el-tag>',
|
'3': '<el-tag type="danger">已取消</el-tag>',
|
};
|
|
// 类型映射
|
const typeMap = {
|
0: "定期巡检",
|
1: "临时巡检",
|
2: "故障巡检",
|
};
|
|
// 表格列配置
|
const columns = [
|
{
|
label: "巡检名称",
|
align: "center",
|
prop: "name",
|
},
|
{
|
label: "巡检类型",
|
align: "center",
|
prop: "type",
|
formatter: (row) => {
|
return typeMap[row.type];
|
},
|
},
|
{
|
label: "巡检状态",
|
align: "center",
|
prop: "status",
|
formatter: (row) => {
|
return statusMap[row.status];
|
},
|
},
|
{
|
label: "计划开始时间",
|
align: "center",
|
prop: "planStartTime",
|
},
|
{
|
label: "计划结束时间",
|
align: "center",
|
prop: "planEndTime",
|
},
|
{
|
label: "实际开始时间",
|
align: "center",
|
prop: "actualStartTime",
|
formatter: (row) => {
|
return row.actualStartTime || "-";
|
},
|
},
|
{
|
label: "实际结束时间",
|
align: "center",
|
prop: "actualEndTime",
|
formatter: (row) => {
|
return row.actualEndTime || "-";
|
},
|
},
|
{
|
label: "巡检人员",
|
align: "center",
|
prop: "inspector",
|
},
|
{
|
label: "巡检区域",
|
align: "center",
|
prop: "area",
|
},
|
{
|
dataType: "action",
|
label: "操作",
|
align: "center",
|
fixed: "right",
|
width: 180,
|
operation: [
|
{
|
name: "编辑",
|
type: "text",
|
clickFun: (row) => {
|
edit(row);
|
},
|
},
|
{
|
name: "开始执行",
|
type: "text",
|
clickFun: (row) => {
|
startInspection(row);
|
},
|
visible: (row) => {
|
return row.status === "0";
|
},
|
},
|
{
|
name: "完成巡检",
|
type: "text",
|
clickFun: (row) => {
|
completeInspection(row);
|
},
|
visible: (row) => {
|
return row.status === "1";
|
},
|
},
|
{
|
name: "取消巡检",
|
type: "text",
|
clickFun: (row) => {
|
cancelInspection(row);
|
},
|
visible: (row) => {
|
return ["0", "1"].includes(row.status);
|
},
|
},
|
{
|
name: "删除",
|
type: "text",
|
clickFun: (row) => {
|
deleteRow(row.id);
|
},
|
},
|
],
|
},
|
];
|
|
// 过滤后的数据
|
const filteredData = computed(() => {
|
return mockData.filter((item) => {
|
const nameMatch = !filters.name || item.name.includes(filters.name);
|
const statusMatch = !filters.status || item.status === filters.status;
|
const typeMatch = !filters.type || item.type === filters.type;
|
return nameMatch && statusMatch && typeMatch;
|
});
|
});
|
|
// 获取表格数据
|
const getTableData = () => {
|
pagination.total = filteredData.value.length;
|
const start = (pagination.currentPage - 1) * pagination.pageSize;
|
const end = start + pagination.pageSize;
|
dataList.value = filteredData.value.slice(start, end);
|
};
|
|
// 重置过滤器
|
const resetFilters = () => {
|
filters.name = "";
|
filters.status = "";
|
filters.type = "";
|
pagination.currentPage = 1;
|
getTableData();
|
};
|
|
// 分页变化
|
const changePage = ({ page, limit }) => {
|
pagination.currentPage = page;
|
pagination.pageSize = limit;
|
getTableData();
|
};
|
|
// 多选处理
|
const handleSelectionChange = (selectionList) => {
|
multipleList.value = selectionList;
|
};
|
|
// 新增
|
const add = () => {
|
dialogTitle.value = "新增巡检";
|
formData.id = "";
|
formData.name = "";
|
formData.type = "0";
|
formData.status = "0";
|
formData.planStartTime = "";
|
formData.planEndTime = "";
|
formData.actualStartTime = "";
|
formData.actualEndTime = "";
|
formData.inspector = "";
|
formData.area = "";
|
formData.content = "";
|
dialogVisible.value = true;
|
};
|
|
// 编辑
|
const edit = (row) => {
|
dialogTitle.value = "编辑巡检";
|
formData.id = row.id;
|
formData.name = row.name;
|
formData.type = row.type;
|
formData.status = row.status;
|
formData.planStartTime = row.planStartTime;
|
formData.planEndTime = row.planEndTime;
|
formData.actualStartTime = row.actualStartTime;
|
formData.actualEndTime = row.actualEndTime;
|
formData.inspector = row.inspector;
|
formData.area = row.area;
|
formData.content = row.content;
|
dialogVisible.value = true;
|
};
|
|
// 保存数据
|
const saveData = () => {
|
if (
|
!formData.name ||
|
!formData.planStartTime ||
|
!formData.planEndTime ||
|
!formData.inspector ||
|
!formData.area
|
) {
|
ElMessage.warning("请填写必填字段");
|
return;
|
}
|
|
if (formData.id) {
|
// 编辑
|
const index = mockData.findIndex((item) => item.id === formData.id);
|
if (index !== -1) {
|
mockData[index] = {
|
...mockData[index],
|
...formData,
|
};
|
ElMessage.success("编辑成功");
|
}
|
} else {
|
// 新增
|
const newId = Math.max(...mockData.map((item) => item.id), 0) + 1;
|
mockData.unshift({
|
...formData,
|
id: newId,
|
});
|
ElMessage.success("新增成功");
|
}
|
dialogVisible.value = false;
|
getTableData();
|
};
|
|
// 开始巡检
|
const startInspection = (row) => {
|
const index = mockData.findIndex((item) => item.id === row.id);
|
if (index !== -1) {
|
mockData[index].status = "1";
|
mockData[index].actualStartTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
ElMessage.success("巡检已开始");
|
getTableData();
|
}
|
};
|
|
// 完成巡检
|
const completeInspection = (row) => {
|
const index = mockData.findIndex((item) => item.id === row.id);
|
if (index !== -1) {
|
mockData[index].status = "2";
|
mockData[index].actualEndTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
ElMessage.success("巡检已完成");
|
getTableData();
|
}
|
};
|
|
// 取消巡检
|
const cancelInspection = (row) => {
|
ElMessageBox.confirm("确定要取消该巡检吗?", "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(() => {
|
const index = mockData.findIndex((item) => item.id === row.id);
|
if (index !== -1) {
|
mockData[index].status = "3";
|
ElMessage.success("巡检已取消");
|
getTableData();
|
}
|
})
|
.catch(() => {});
|
};
|
|
// 删除
|
const deleteRow = (id) => {
|
ElMessageBox.confirm("此操作将永久删除该巡检记录, 是否继续?", "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(() => {
|
const index = mockData.findIndex((item) => item.id === id);
|
if (index !== -1) {
|
mockData.splice(index, 1);
|
ElMessage.success("删除成功");
|
getTableData();
|
}
|
})
|
.catch(() => {});
|
};
|
|
// 批量删除
|
const batchDelete = () => {
|
if (multipleList.value.length === 0) {
|
ElMessage.warning("请选择要删除的数据");
|
return;
|
}
|
|
ElMessageBox.confirm("此操作将永久删除所选巡检记录, 是否继续?", "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
})
|
.then(() => {
|
const ids = multipleList.value.map((item) => item.id);
|
mockData.forEach((item, index) => {
|
if (ids.includes(item.id)) {
|
mockData.splice(index, 1);
|
}
|
});
|
ElMessage.success("删除成功");
|
getTableData();
|
multipleList.value = [];
|
})
|
.catch(() => {});
|
};
|
|
// 初始化数据
|
onMounted(() => {
|
getTableData();
|
});
|
</script>
|
|
<style lang="scss" scoped>
|
.table_list {
|
margin-top: unset;
|
}
|
.actions {
|
display: flex;
|
justify-content: space-between;
|
margin-bottom: 10px;
|
}
|
</style>
|