917 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-11 15:14:16
* @LastEditors: SunTao 328867980@qq.com
* @LastEditTime: 2025-01-14 14:24:28
* @FilePath: \znxjxt-ui\src\views\xj\inspection\road-management\index.vue
* @Description: 巡检信息-路产管理
-->
<template>
<div class="app-container">
<!-- 搜索表单 -->
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
label-width="100px"
>
<el-form-item label="道路名称" prop="segmentName">
<el-select
v-model="queryParams.segmentName"
placeholder="请选择道路名称"
filterable
clearable
>
<el-option
v-for="item in segmentList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="采集时间" prop="dateTime">
<el-date-picker
v-model="dateTime"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
clearable
/>
</el-form-item>
<el-form-item label="路产类型" prop="equipmentType">
<el-select
v-model="queryParams.equipmentType"
placeholder="请选择路产类型"
clearable
>
<el-option
v-for="item in roadType"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="校验状态" prop="dataStatus">
<el-select
v-model="queryParams.dataStatus"
placeholder="请选择校验状态"
clearable
>
<el-option
v-for="item in verifyStatus"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="上下行" prop="inspectDirection">
<el-select
v-model="queryParams.inspectDirection"
placeholder="请选择"
clearable
>
<el-option label="上行" value="0" />
<el-option label="下行" value="1" />
</el-select>
</el-form-item>
<el-form-item label="公里桩" prop="stakeRange">
<el-input
v-model="queryParams.stakeStart"
placeholder="起始公里桩"
style="width: 10rem"
clearable
/>
<span style="margin: 0 5px">-</span>
<el-input
v-model="queryParams.stakeEnd"
placeholder="终止公里桩"
style="width: 10rem"
clearable
/>
<el-tooltip
class="item"
effect="dark"
content="格式为K0000+000"
placement="top"
>
<i class="el-icon-info"></i>
</el-tooltip>
</el-form-item>
<el-form-item label="巡检任务" prop="taskId">
<el-select
v-model="queryParams.taskId"
placeholder="请选择巡检任务"
filterable
clearable
>
<el-option
v-for="item in taskList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="路产状态" prop="state">
<el-select
v-model="queryParams.state"
placeholder="请选择路产状态"
clearable
>
<el-option
v-for="item in defectStatus"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="路产id" prop="id">
<el-input
v-model="queryParams.id"
placeholder="请填写路产id"
clearable=""
></el-input>
</el-form-item>
<el-form-item>
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button
>
</el-form-item>
</el-form>
<!-- 操作按钮 -->
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete(null)"
>删除
</el-button>
</el-col>
</el-row>
<!-- 列表 -->
<el-table
ref="roadTable"
v-loading="loading"
:data="roadList"
@selection-change="handleSelectionChange"
style="width: 100%"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="道路名称" align="center" prop="segmentName" />
<el-table-column label="采集时间" align="center" prop="createdTime">
<template slot-scope="scope">
<span>{{ new Date(scope.row.createdTime).toLocaleString() }}</span>
</template>
</el-table-column>
<el-table-column label="路产类型" align="center" prop="equipmentType">
<template slot-scope="scope">
<span>{{ filterDefect(scope.row.equipmentType) }}</span>
</template>
</el-table-column>
<el-table-column label="路产状态" align="center" prop="state">
<template slot-scope="scope">
<span>{{ filterState(scope.row.state) }}</span>
</template>
</el-table-column>
<el-table-column label="校验状态" align="center" prop="dataStatus">
<template slot-scope="scope">
<span>{{
scope.row.dataStatus
? scope.row.dataStatus === 1
? "未校验"
: "已校验"
: ""
}}</span>
</template>
</el-table-column>
<el-table-column label="开始桩号" align="center" prop="stakeStart" />
<el-table-column label="结束桩号" align="center" prop="stakeEnd" />
<el-table-column label="路产图片" align="center" prop="media">
<template slot-scope="scope">
<img
@click="showScreenImg(scope.row)"
height="50"
:src="scope.row.mediaUrl"
/>
</template>
</el-table-column>
<el-table-column label="巡检任务" align="center" prop="taskId" />
<!-- <el-table-column label="校验状态" align="center" prop="datastatus">
<template slot-scope="scope">
<span>{{ scope.row.datastatus === "1" ? "未校验" : "已校验" }}</span>
</template>
</el-table-column> -->
<el-table-column label="道路方向" align="center" prop="inspectDirection">
<template slot-scope="scope">
<span>{{
scope.row.inspectDirection === "0" ? "上行" : "下行"
}}</span>
</template>
</el-table-column>
<el-table-column label="路产id" align="center" prop="id" />
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="viewDefect(scope.row)"
>查看
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>修改
</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<div class="pagination-part">
<el-pagination
background
:current-page.sync="pagination.page"
@current-change="handleCurrentChange"
:page-sizes="[10, 20, 30, 40]"
:page-size.sync="pagination.size"
@size-change="handleSizeChange"
layout="total, sizes, prev, pager, next, jumper"
:total="tableTotal"
>
</el-pagination>
</div>
<!-- 新增/编辑弹窗 -->
<el-dialog
:title="addTitle"
:visible.sync="addVisible"
width="60rem"
append-to-body
:close-on-click-modal="false"
destroy-on-close
@close="addCancel"
>
<road-add
v-if="addVisible"
@cancel="addCancel"
:dialogItem="dialogItem"
:segmentList="segmentList"
:roadType="roadType"
:defectStatus="defectStatus"
></road-add>
</el-dialog>
<!-- 查看弹窗 -->
<el-dialog
title="查看路产"
:visible.sync="viewVisible"
width="55rem"
append-to-body
:close-on-click-modal="false"
destroy-on-close
@close="viewCancel"
>
<road-view
v-if="viewVisible"
@cancel="viewCancel"
:dialogItem="dialogItem"
:roadType="roadType"
></road-view>
</el-dialog>
<!-- 查看图片大图 -->
<el-dialog
title="查看图片"
:visible.sync="showImageDialog"
width="85rem"
append-to-body
destroy-on-close
@close="imgCancel"
>
<div class="image-container" ref="imageContainer">
<img
:src="currentImageItem.mediaUrl"
alt="Main Image"
ref="mainImage"
@load="updateRects"
/>
<div
v-for="(rect, index) in rects"
:key="index"
class="rect-overlay"
:style="getRectStyle(rect)"
></div>
<div class="rect-image">
采集时间:
{{ new Date(currentImageItem.createdTime).toLocaleString() }}
起始桩号 {{ currentImageItem.stakeStart || "暂无数据" }} 终止桩号
{{ currentImageItem.stakeEnd || "暂无数据" }}
路产类型
{{ filterDefect(currentImageItem.equipmentType) || "暂无数据" }}
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import {
getRoadTable,
getSegment,
getRoadType,
getDefectStatus,
deleteRoad,
changeRoad,
getTaskList,
} from "@/api/xj/road";
import RoadAdd from "./components/road-add.vue";
import RoadView from "./components/road-view.vue";
export default {
components: { RoadAdd, RoadView },
data() {
return {
// 查询表单
queryParams: {
// 道路名称
segmentName: "",
// 路产类型
equipmentType: "",
// 校验状态
dataStatus: "",
// 巡检任务
taskId: "",
// 公里桩
stakeStart: "",
stakeEnd: "",
// 上下行
inspectDirection: "",
// 路产状态
state: "",
// 路产id
id: "",
},
// 采集时间
dateTime: [],
// 传查询接口表单
searchForm: {},
// 道路名称下拉
segmentList: [],
// 路产类型下拉
roadType: [],
// 路产状态下拉
defectStatus: [],
// 校验状态下拉
verifyStatus: [
{ label: "未校验", value: "1" },
{ label: "已校验", value: "2" },
],
// 列表数据绑定
roadList: [],
// 巡检任务下拉数据
taskList: [],
// 列表加载状态
loading: false,
// 列表已选数组
checkIds: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 分页-列表总数
tableTotal: 0,
// 分页-页数页码
pagination: {
page: 1,
size: 10,
},
// 传弹窗的数据
dialogItem: {},
// 弹窗标题
addTitle: "添加路产",
// 新增/编辑弹窗显隐控制
addVisible: false,
// 查看弹窗显隐控制
viewVisible: false,
// 查看图片大图弹窗显隐控制
showImageDialog: false,
// 查看大图片路径
currentImageItem: "",
// 图片病害位置信息
rects: [],
};
},
created() {
this.getRoadList();
this.getSegmentList();
this.getRoadTypeList();
this.getDefectStatusList();
this.getTaskSelectList();
},
methods: {
/**
* @description: 获取道路名称下拉数据
* @param {*}
* @return {*}
*/
getSegmentList() {
getSegment().then(({ code, data }) => {
if (code === 200) {
this.segmentList = data;
}
});
},
/**
* @description: 获取路产类型下拉数据
* @param {*}
* @return {*}
*/
getRoadTypeList() {
getRoadType().then(({ code, data }) => {
if (code === 200) {
this.roadType = data;
}
});
},
/**
* @description: 获取路产状态下拉数据
* @param {*}
* @return {*}
*/
getDefectStatusList() {
getDefectStatus().then(({ data, code }) => {
if (code === 200) {
this.defectStatus = data;
}
});
},
/**
* @description: 获取巡检任务下拉数据
* @param {*}
* @return {*}
*/
getTaskSelectList() {
getTaskList().then(({ data, code }) => {
if (code === 200) {
this.taskList = data;
}
});
},
/**
* @description: 点击搜索事件
* @param {*}
* @return {*}
*/
handleQuery() {
const phonereg = /^K\d{4}\+\d{3}$/;
if (this.queryParams.stakeStart) {
if (phonereg.test(this.queryParams.stakeStart)) {
this.pagination.page = 1;
this.searchForm = JSON.parse(JSON.stringify(this.queryParams));
this.getRoadList();
} else {
this.$modal.msgWarning("请按照格式填写公里桩进行修改");
}
} else if (this.queryParams.stakeEnd) {
if (phonereg.test(this.queryParams.stakeEnd)) {
this.pagination.page = 1;
this.searchForm = JSON.parse(JSON.stringify(this.queryParams));
this.getRoadList();
} else {
this.$modal.msgWarning("请按照格式填写公里桩进行修改");
}
} else {
this.pagination.page = 1;
this.searchForm = JSON.parse(JSON.stringify(this.queryParams));
this.getRoadList();
}
},
/**
* @description: 点击重置事件
* @param {*}
* @return {*}
*/
resetQuery() {
this.searchForm = {};
this.queryParams = {
segmentName: "",
equipmentType: "",
dataStatus: "",
inspectDirection: "",
taskId: "",
stakeStart: "",
stakeEnd: "",
state: "",
id: "",
};
this.dateTime = [];
this.getRoadList();
},
/**
* @description: 获取列表数据
* @param {*}
* @return {*}
*/
getRoadList() {
const params = {
...this.pagination,
...this.searchForm,
startTime: this.dateTime ? this.dateTime[0] : "",
endTime: this.dateTime ? this.dateTime[1] : "",
};
getRoadTable(params).then(({ code, rows, total }) => {
if (code === 200) {
this.roadList = rows;
this.tableTotal = total;
}
});
},
/**
* @description: 过滤列表路产类型
* @param {*} value
* @return {*}
*/
filterDefect(value) {
let a = null;
[a] = this.roadType.filter((item) => {
return item.value === value;
});
if (a) {
return a.label;
}
},
/**
* @description: 过滤路产状态
* @param {*} value
* @return {*}
*/
filterState(value) {
let a = null;
[a] = this.defectStatus.filter((item) => {
return item.value === value;
});
if (a) {
return a.label;
}
},
/**
* @description: 点击新增事件
* @param {*}
* @return {*}
*/
handleAdd() {
this.addVisible = true;
this.addTitle = "添加路产";
this.dialogItem = {
title: "添加路产",
};
},
/**
* @description: 点击删除事件
* @param {*} row
* @return {*}
*/
handleDelete(row) {
const checkIds = row ? [row.snapshotId] : this.checkIds;
if (!checkIds.length) {
this.$modal.msgWarning("请选择要删除的记录");
return;
}
this.$modal
.confirm(`是否确认删除选中的${checkIds.length}条记录?`)
.then(() => {
return deleteRoad(checkIds);
})
.then(() => {
this.getRoadList();
this.$refs.defectTable.clearSelection();
this.$modal.msgSuccess("删除成功");
})
.catch(() => {});
},
/**
* @description: 点击导出事件
* @param {*}
* @return {*}
*/
handleExport() {},
/**
* @description: 批量确认事件
* @param {*}
* @return {*}
*/
handleUpdateBatch() {
if (this.checkIds.length > 0) {
changeRoad(this.checkIds).then(({ code, data }) => {
if (code === 200) {
this.$modal.msgSuccess(`修改${data}`);
this.$refs.defectTable.clearSelection();
this.checkIds = [];
}
});
} else {
this.$modal.msgWarning("请选择一条记录进行修改");
}
},
/**
* @description: 列表选择改变事件
* @param {*} selection
* @return {*}
*/
handleSelectionChange(selection) {
this.checkIds = selection.map((item) => item.snapshotId);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},
/**
* @description: 列表-点击修改事件
* @param {*} item
* @return {*}
*/
handleUpdate(item) {
this.addVisible = true;
this.addTitle = "修改路产";
this.dialogItem = {
title: "修改路产",
...item,
};
},
/**
* @description: 列表-点击查看事件
* @param {*} item
* @return {*}
*/
viewDefect(item) {
this.viewVisible = true;
this.dialogItem = {
title: "查看路产",
...item,
};
},
/**
* @description: 切换分页
* @param {*} arg
* @return {*}
*/
handleCurrentChange(arg) {
this.pagination.page = arg;
this.getRoadList();
},
/**
* @description: 切换每条/页
* @param {*} arg
* @return {*}
*/
handleSizeChange(arg) {
this.pagination.size = arg;
this.getRoadList();
},
/**
* @description: 关闭新增/编辑弹窗
* @param {*}
* @return {*}
*/
addCancel() {
this.addVisible = false;
this.dialogItem = { title: "添加路产" };
this.addTitle = "";
this.getRoadList();
},
/**
* @description: 关闭查看弹窗
* @param {*}
* @return {*}
*/
viewCancel() {
this.viewVisible = false;
this.dialogItem = { title: "添加路产" };
},
/**
* @description: 打开查看图片弹窗
* @param {*} item
* @return {*}
*/
showScreenImg(item) {
this.currentImageItem = item;
this.showImageDialog = true;
},
/**
* @description: 图片位置信息获取
* @param {*}
* @return {*}
*/
updateRects() {
this.rects = [];
this.rectsItem = {};
const image = this.$refs.mainImage;
const rects = this.currentImageItem?.rect?.split(",").map(Number) || [];
this.rects = [
{
left: rects[0],
top: rects[1],
width: rects[2],
height: rects[3],
},
];
// this.rectsItem = this.defectData[this.currentIndex];
},
/**
* @description: 图片红框位置
* @param {*} { left, top, width, height }
* @return {*}
*/
getRectStyle({ left, top, width, height }) {
const image = this.$refs.mainImage;
const container = this.$refs.imageContainer;
if (!image || !container) return {};
const scaleX = container.clientWidth / image.naturalWidth;
const scaleY = container.clientHeight / image.naturalHeight;
const scale = Math.min(scaleX, scaleY);
const renderedWidth = image.naturalWidth * scale;
const renderedHeight = image.naturalHeight * scale;
const offsetX = (container.clientWidth - renderedWidth) / 2;
const offsetY = (container.clientHeight - renderedHeight) / 2;
return {
position: "absolute",
left: `${left * scale + offsetX}px`,
top: `${top * scale + offsetY}px`,
width: `${width * scale}px`,
height: `${height * scale}px`,
border: "2px solid #FF0000",
boxSizing: "border-box",
};
},
/**
* @description: 关闭查看图片弹窗
* @param {*}
* @return {*}
*/
imgCancel() {
this.showImageDialog = false;
this.currentImageItem = {};
this.rects = [];
},
},
};
</script>
<style lang="scss" scoped>
.app-container {
padding: 20px;
}
.mb8 {
margin-bottom: 8px;
}
.small-padding {
padding: 0 5px;
}
.fixed-width {
width: 120px;
}
/* 分页样式 */
.pagination-part {
width: 100%;
display: flex;
padding-top: 1rem;
justify-content: flex-end;
}
/* 新增弹窗/编辑弹窗 */
.addForm {
.el-select,
.el-cascader {
width: 100%;
}
}
/* 新增地图框样式 */
.no-hand-cursor {
cursor: default !important;
width: 100%;
height: 20rem;
}
/* 上传文件列表样式 */
::v-deep .el-upload-list {
img {
width: auto;
}
}
/* 查看弹窗-图片框样式 */
.view-carousel {
height: 15rem;
// .el-carousel__item{
// height: 12rem;
img {
max-height: 15rem;
max-width: 25rem;
}
}
/* 查看大图弹窗 */
.image-container {
position: relative;
width: 100%;
height: 80%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden;
}
.image-container img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
.rect-overlay {
position: absolute;
pointer-events: none;
border: 2px solid red;
}
// 图片信息
.rect-image {
width: 90%;
position: absolute;
top: 0;
font-size: 1.2rem;
color: #ffffff;
background-color: rgba(0, 0, 0, 0.5);
}
</style>