fix:修改病害确认弹窗,修改大屏查看图片详情弹窗
This commit is contained in:
		
							parent
							
								
									1f93df8130
								
							
						
					
					
						commit
						ad59aa7960
					
				| @ -2,7 +2,7 @@ | ||||
|  * @Author: SunTao 328867980@qq.com | ||||
|  * @Date: 2024-10-22 15:30:25 | ||||
|  * @LastEditors: SunTao 328867980@qq.com | ||||
|  * @LastEditTime: 2024-12-10 11:45:44 | ||||
|  * @LastEditTime: 2024-12-25 16:53:29 | ||||
|  * @FilePath: \znxjxt-ui\src\views\big-screen\components\img-dialog.vue | ||||
|  * @Description: 大屏查看图片弹窗 | ||||
| --> | ||||
| @ -96,21 +96,6 @@ | ||||
|               clearable | ||||
|             /> | ||||
|           </el-form-item> | ||||
|           <el-form-item class="form-item" label="病害状态" prop="state"> | ||||
|             <el-select | ||||
|               v-model="imgForm.state" | ||||
|               :popper-append-to-body="false" | ||||
|               placeholder="请选择病害状态" | ||||
|               clearable | ||||
|             > | ||||
|               <el-option | ||||
|                 v-for="item in defectStatus" | ||||
|                 :key="item.value" | ||||
|                 :label="item.label" | ||||
|                 :value="item.value" | ||||
|               /> | ||||
|             </el-select> | ||||
|           </el-form-item> | ||||
|           <el-button | ||||
|             type="primary" | ||||
|             class="btn-submit" | ||||
| @ -193,6 +178,7 @@ import { | ||||
|   getMediaIndex, | ||||
| } from "@/api/xj/screen/index"; | ||||
| import throttle from "lodash/throttle"; | ||||
| import debounce from "lodash/debounce"; | ||||
| export default { | ||||
|   name: "ImgDialog", | ||||
|   props: { | ||||
| @ -237,18 +223,11 @@ export default { | ||||
|         stakeStart: "", | ||||
|         // 终止公里桩 | ||||
|         stakeEnd: "", | ||||
|         // 病害状态 | ||||
|         state: "", | ||||
|       }, | ||||
|       // 路段下拉数据 | ||||
|       roadTypeList: [], | ||||
|       // 病害类型下拉数据 | ||||
|       defectTypeList: [], | ||||
|       // 病害状态下拉数据 | ||||
|       defectStatus: [ | ||||
|         { label: "已修复", value: "2" }, | ||||
|         { label: "未修复", value: "1" }, | ||||
|       ], | ||||
|       // 分页绑定 | ||||
|       params: { | ||||
|         page: 1, | ||||
| @ -277,9 +256,9 @@ export default { | ||||
|         if (index !== this.selectedThumbnail) { | ||||
|           return this.defectData[this.currentIndex].items[ | ||||
|             this.selectedThumbnail | ||||
|           ].img; | ||||
|           ]?.img; | ||||
|         } | ||||
|         return this.defectData[this.currentIndex].items[index].img; | ||||
|         return this.defectData[this.currentIndex].items[index]?.img; | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
| @ -364,7 +343,7 @@ export default { | ||||
|             if (this.pageTip > 1) { | ||||
|               this.loadMoreTopImages(); | ||||
|             } | ||||
|           }, 1000); | ||||
|           }, 500); | ||||
|         }); | ||||
|     }, | ||||
| 
 | ||||
| @ -445,6 +424,7 @@ export default { | ||||
|           } | ||||
|         }) | ||||
|         .finally(() => { | ||||
|           this.showImage(this.currentIndex); | ||||
|           this.loading = false; | ||||
|         }); | ||||
|     }, | ||||
| @ -511,7 +491,6 @@ export default { | ||||
|         defectType: "", | ||||
|         stakeStart: "", | ||||
|         stakeEnd: "", | ||||
|         state: "", | ||||
|       }; | ||||
|       this.params = { | ||||
|         page: 1, | ||||
| @ -530,12 +509,11 @@ export default { | ||||
|       // if (this.currentIndex === this.defectData.length - 1) { | ||||
|       //   this.loadMoreBottomImages(); | ||||
|       // } | ||||
| 
 | ||||
|       this.currentIndex = index; | ||||
|       const indexInfo = this.defectData[this.currentIndex].items.length - 1; | ||||
|       const indexInfo = this.defectData[this.currentIndex]?.items.length - 1; | ||||
|       this.selectedThumbnail = indexInfo; // Reset to the first thumbnail when changing the main item | ||||
|       this.scrollToCurrentImage(); | ||||
|       this.$nextTick(() => { | ||||
|         this.scrollToCurrentImage(); | ||||
|         this.updateRects(); | ||||
|       }); | ||||
|     }, | ||||
| @ -555,7 +533,7 @@ export default { | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     scrollToCurrentImage() { | ||||
|     scrollToCurrentImage: debounce(function () { | ||||
|       if (this.$refs.sidebar) { | ||||
|         const sidebarImages = this.$refs.sidebar.querySelectorAll("img"); | ||||
|         const currentImageElement = sidebarImages[this.currentIndex]; | ||||
| @ -566,8 +544,7 @@ export default { | ||||
|           }); | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     }, 200), | ||||
|     /** | ||||
|      * @description: 滚动触发事件 | ||||
|      * @param {*} | ||||
| @ -700,7 +677,7 @@ export default { | ||||
|           }; | ||||
|         }); | ||||
|         this.checkedRectList = this.rectItem; | ||||
|         this.checkedRect = this.rectItem.map((item) => item.id); | ||||
|         this.checkedRect = this.rectItem?.map((item) => item.id); | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
| @ -741,7 +718,7 @@ export default { | ||||
|     window.addEventListener("resize", this.updateRects); | ||||
|   }, | ||||
|   beforeDestroy() { | ||||
|     window.removeEventListener("keydown",this.handleKeydown); | ||||
|     window.removeEventListener("keydown", this.handleKeydown); | ||||
|     window.removeEventListener("resize", this.updateRects); | ||||
|   }, | ||||
| }; | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
|  * @Author: SunTao 328867980@qq.com | ||||
|  * @Date: 2024-10-17 11:34:00 | ||||
|  * @LastEditors: SunTao 328867980@qq.com | ||||
|  * @LastEditTime: 2024-12-24 15:58:07 | ||||
|  * @LastEditTime: 2024-12-25 09:31:03 | ||||
|  * @FilePath: \znxjxt-ui\src\views\big-screen\index.vue | ||||
|  * @Description: 大屏首页 | ||||
| --> | ||||
|  | ||||
| @ -0,0 +1,957 @@ | ||||
| <!-- | ||||
|  * @Author: SunTao 328867980@qq.com | ||||
|  * @Date: 2024-10-22 15:30:25 | ||||
|  * @LastEditors: SunTao 328867980@qq.com | ||||
|  * @LastEditTime: 2024-12-25 16:22:03 | ||||
|  * @FilePath: \znxjxt-ui\src\views\big-screen\components\img-dialog.vue | ||||
|  * @Description: 大屏查看图片弹窗 | ||||
| --> | ||||
| 
 | ||||
| <template> | ||||
|   <div class="app"> | ||||
|     <div class="left-list"> | ||||
|       <div class="sidebar" ref="sidebar" @scroll="handleScroll"> | ||||
|         <img | ||||
|           v-for="(item, index) in defectData" | ||||
|           :key="`${item.id}-${index}`" | ||||
|           :src="item.media[0].img" | ||||
|           :alt="'Image ' + (index + 1)" | ||||
|           @click="showImage(index)" | ||||
|           :class="{ selected: currentIndex === index }" | ||||
|         /> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="main-content"> | ||||
|       <!-- 搜索表单 --> | ||||
|       <div class="toolbar"> | ||||
|         <el-form | ||||
|           :model="imgForm" | ||||
|           ref="imgForm" | ||||
|           size="small" | ||||
|           :inline="true" | ||||
|           label-width="6rem" | ||||
|         > | ||||
|           <el-form-item label="路段名称"> | ||||
|             <el-select | ||||
|               v-model="imgForm.segmentId" | ||||
|               placeholder="请选择路段名称" | ||||
|               :popper-append-to-body="false" | ||||
|               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="病害类型"> | ||||
|             <el-select | ||||
|               v-model="imgForm.defectType" | ||||
|               placeholder="请选择病害类型" | ||||
|               :popper-append-to-body="false" | ||||
|               clearable | ||||
|             > | ||||
|               <el-option | ||||
|                 v-for="item in defectTypeList" | ||||
|                 :key="item.value" | ||||
|                 :label="item.label" | ||||
|                 :value="item.value" | ||||
|               /> | ||||
|             </el-select> | ||||
|           </el-form-item> | ||||
| 
 | ||||
|           <el-form-item label="公里桩"> | ||||
|             <el-input | ||||
|               v-model="imgForm.stakeStart" | ||||
|               placeholder="起始公里桩" | ||||
|               style="width: 8rem" | ||||
|               clearable | ||||
|             /> | ||||
|             <span style="margin: 0 5px">-</span> | ||||
|             <el-input | ||||
|               v-model="imgForm.stakeEnd" | ||||
|               placeholder="终止公里桩" | ||||
|               style="width: 8rem" | ||||
|               clearable | ||||
|             /> | ||||
|           </el-form-item> | ||||
|           <el-button | ||||
|             type="primary" | ||||
|             class="btn-submit" | ||||
|             size="mini" | ||||
|             @click="handleQuery" | ||||
|             >搜索</el-button | ||||
|           > | ||||
|           <el-button class="btn-cancel" size="mini" @click="resetQuery" | ||||
|             >重置</el-button | ||||
|           > | ||||
|         </el-form> | ||||
|       </div> | ||||
|       <!-- 图片展示 --> | ||||
|       <div class="image-viewer"> | ||||
|         <div class="image-container" ref="imageContainer"> | ||||
|           <div | ||||
|             class="rect-overlay" | ||||
|             v-for="(item, index) in checkedRectList" | ||||
|             :key="`rect-overlay-${index}`" | ||||
|             :style="getRectStyle(item.rectPosition, index)" | ||||
|             @click="clickImage(item)" | ||||
|           > | ||||
|             <div :style="{ color: colorList[index] }" class="rect-overlay-text"> | ||||
|               目标详情>> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="rect-image"> | ||||
|             <el-checkbox-group | ||||
|               v-model="checkedRect" | ||||
|               @change="handleCheckedRectChange" | ||||
|             > | ||||
|               <el-checkbox | ||||
|                 class="image-info" | ||||
|                 v-for="(item, index) in rectItem" | ||||
|                 :label="item.id" | ||||
|                 :key="`image-info-${index}`" | ||||
|                 :style="{ color: colorList[index] }" | ||||
|                 >采集时间: | ||||
|                 {{ new Date(item.createdTime).toLocaleString() }} 起始桩号: | ||||
|                 {{ item.stakeStart || "暂无数据" }} 终止桩号: | ||||
|                 {{ item.stakeEnd || "暂无数据" }} | ||||
|                 病害类型: | ||||
|                 {{ item.defectTypeName || "暂无数据" }} | ||||
|                 <span v-if="bottomTipClick === '1'"> | ||||
|                   病害面积:{{ item.targetArea }}平方米 病害长度:{{ | ||||
|                     item.targetLen * 1 <= 0 ? "暂无数据" : `${item.targetLen}米` | ||||
|                   }} | ||||
|                 </span> | ||||
|               </el-checkbox> | ||||
|             </el-checkbox-group> | ||||
|           </div> | ||||
|           <img | ||||
|             :src="currentImage" | ||||
|             alt="Main Image" | ||||
|             ref="mainImage" | ||||
|             @load="updateRects" | ||||
|           /> | ||||
|         </div> | ||||
|       </div> | ||||
|       <!-- 小图展示 --> | ||||
|       <div class="thumbnail-row"> | ||||
|         <div | ||||
|           class="thumbnail-image" | ||||
|           :style="{ | ||||
|             justifyContent: currentThumbnails.length > 8 ? '' : 'center', | ||||
|           }" | ||||
|         > | ||||
|           <img | ||||
|             v-for="(mediaItem, index) in currentThumbnails" | ||||
|             :key="'thumb-' + index" | ||||
|             :src="mediaItem.img" | ||||
|             :alt="'Thumb ' + (index + 1)" | ||||
|             @click="showThumbnailImage(index)" | ||||
|             :class="{ selected: selectedThumbnail === index }" | ||||
|           /> | ||||
|         </div> | ||||
|         <div class="thumbnail-btn"> | ||||
|           <el-button type="success" plain size="mini" @click="changeDefect(2)" | ||||
|             >是病害(Y)</el-button | ||||
|           > | ||||
|           <el-button type="warning" plain size="mini" @click="changeDefect(3)" | ||||
|             >不是病害(N)</el-button | ||||
|           > | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| import { getItemTypes } from "@/api/xj/screen/index"; | ||||
| import { listDefect, mergeDefect } from "@/api/xj/confirmation"; | ||||
| import throttle from "lodash/throttle"; | ||||
| import debounce from "lodash/debounce"; | ||||
| export default { | ||||
|   name: "ImgDialog", | ||||
|   props: { | ||||
|     bottomTipClick: { | ||||
|       type: String, | ||||
|       default: "1", | ||||
|     }, | ||||
|     imageItem: { | ||||
|       type: Object, | ||||
|       default: () => {}, | ||||
|     }, | ||||
|     segmentList: { | ||||
|       type: Array, | ||||
|       default: () => [], | ||||
|     }, | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       // 维度选择 | ||||
|       labelCheck: "aim", | ||||
|       // 目标维度事件 | ||||
|       aimList: [], | ||||
|       // 空间维度数据 | ||||
|       ariaList: [], | ||||
|       // 左侧图片数据 | ||||
|       defectData: [], | ||||
|       // 当前选择的index | ||||
|       currentIndex: null, | ||||
|       // 下方点击的index绑定 | ||||
|       selectedThumbnail: 0, | ||||
|       // 选中框绑定 | ||||
|       checkedRect: [], | ||||
|       // 顶端选中框数据 | ||||
|       checkedRectList: [], | ||||
|       // 加载状态 | ||||
|       loading: false, | ||||
|       // 表单绑定 | ||||
|       imgForm: { | ||||
|         // 点击详情传的id | ||||
|         id: null, | ||||
|         // 路段名称 | ||||
|         segmentId: "", | ||||
|         // 病害类型 | ||||
|         defectType: "", | ||||
|         // 起始公里桩 | ||||
|         stakeStart: "", | ||||
|         // 终止公里桩 | ||||
|         stakeEnd: "", | ||||
|       }, | ||||
|       // 病害类型下拉数据 | ||||
|       defectTypeList: [], | ||||
|       // 分页绑定 | ||||
|       params: { | ||||
|         page: 1, | ||||
|         size: 10, | ||||
|       }, | ||||
|       pageTip: 1, | ||||
|       // 图片病害位置红框信息 | ||||
|       rectItem: [], | ||||
|       // 图片病害框的颜色 | ||||
|       colorList: ["#FFFFFF", "#07E8E2", "#DD9F18", "#994EFF", "#08B4A6"], | ||||
|     }; | ||||
|   }, | ||||
|   computed: { | ||||
|     /** | ||||
|      * @description: 当前展示的图片url | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     currentImage() { | ||||
|       const thumbnails = this.currentThumbnails; | ||||
|       return ( | ||||
|         thumbnails[this.selectedThumbnail]?.img || thumbnails[0]?.img || "" | ||||
|       ); | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 下方小列表数据 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     currentThumbnails() { | ||||
|       return this.defectData[this.currentIndex]?.media || []; | ||||
|     }, | ||||
|   }, | ||||
|   watch: { | ||||
|     imageItem: { | ||||
|       handler(val) { | ||||
|         if (val) { | ||||
|           this.getMediaBySnapshotid(val); | ||||
|         } | ||||
|       }, | ||||
|       deep: true, | ||||
|       immediate: true, | ||||
|     }, | ||||
|     bottomTipClick: { | ||||
|       handler() { | ||||
|         this.getDefectType(); | ||||
|       }, | ||||
|     }, | ||||
|   }, | ||||
|   created() { | ||||
|     this.getDefectType(); | ||||
|   }, | ||||
|   methods: { | ||||
|     /** | ||||
|      * @description: 获取病害类型下拉数据 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     getDefectType() { | ||||
|       getItemTypes({ classType: this.bottomTipClick }).then( | ||||
|         ({ code, data }) => { | ||||
|           if (code === 200) { | ||||
|             this.defectTypeList = data; | ||||
|           } | ||||
|         } | ||||
|       ); | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 根据传回来的快照id查图片详细数据 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     getMediaBySnapshotid(val) { | ||||
|       this.currentIndex = val.index; | ||||
|       this.pageTip = val.params.page; | ||||
|       this.params = { ...val.params }; | ||||
|       this.imgForm.segmentId = val.segmentId; | ||||
|       this.getList(); | ||||
|       setTimeout(() => { | ||||
|         if (this.pageTip > 1) { | ||||
|           this.loadMoreTopImages(); | ||||
|         } | ||||
|       }, 500); | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 向下获取左侧列表事件 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     getList() { | ||||
|       this.loading = true; | ||||
|       const data = { | ||||
|         classType: this.bottomTipClick, | ||||
|         lastId: this.defectData[this.defectData.length - 1]?.snapshotId || "", | ||||
|         ...this.imgForm, | ||||
|         ...this.params, | ||||
|       }; | ||||
|       listDefect(data) | ||||
|         .then(({ code, rows }) => { | ||||
|           if (code === 200) { | ||||
|             this.defectData.push(...rows); | ||||
|             this.loading = false; | ||||
|           } | ||||
|         }) | ||||
|         .finally(() => { | ||||
|           this.showImage(this.currentIndex); | ||||
|           this.loading = false; | ||||
|         }); | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 向上获取列表数据 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     getListTop() { | ||||
|       this.loading = true; | ||||
|       const data = { | ||||
|         classType: this.bottomTipClick, | ||||
|         ...this.imgForm, | ||||
|         ...this.params, | ||||
|         lastId: this.defectData[this.defectData.length - 1]?.snapshotId || "", | ||||
|       }; | ||||
|       listDefect(data) | ||||
|         .then(({ code, rows }) => { | ||||
|           if (code === 200) { | ||||
|             this.defectData.unshift(...rows); | ||||
|             this.loading = false; | ||||
|           } | ||||
|         }) | ||||
|         .finally(() => { | ||||
|           this.showImage(this.currentIndex); | ||||
|           this.loading = false; | ||||
|         }); | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 点击搜索事件 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     handleQuery() { | ||||
|       const stakeReg = /^K\d{4}\+\d{3}$/; | ||||
|       if (this.imgForm.stakeStart) { | ||||
|         if (stakeReg.test(this.imgForm.stakeStart)) { | ||||
|           this.defectData = []; | ||||
|           this.ariaList = []; | ||||
|           this.aimList = []; | ||||
|           this.params = { | ||||
|             page: 1, | ||||
|             size: 10, | ||||
|           }; | ||||
|           this.getList(); | ||||
|           this.showImage(0); | ||||
|         } else { | ||||
|           this.$modal.msgWarning("请按照'K0000+000'格式填写公里桩进行修改"); | ||||
|         } | ||||
|       } else if (this.imgForm.stakeEnd) { | ||||
|         if (stakeReg.test(this.imgForm.stakeEnd)) { | ||||
|           this.defectData = []; | ||||
|           this.ariaList = []; | ||||
|           this.aimList = []; | ||||
|           this.params = { | ||||
|             page: 1, | ||||
|             size: 10, | ||||
|           }; | ||||
|           this.getList(); | ||||
|           this.showImage(0); | ||||
|         } else { | ||||
|           this.$modal.msgWarning("请按照'K0000+000'格式填写公里桩进行修改"); | ||||
|         } | ||||
|       } else { | ||||
|         this.defectData = []; | ||||
|         this.ariaList = []; | ||||
|         this.aimList = []; | ||||
|         this.params = { | ||||
|           page: 1, | ||||
|           size: 10, | ||||
|         }; | ||||
|         this.getList(); | ||||
|         this.showImage(0); | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 重置事件 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     resetQuery() { | ||||
|       this.defectData = []; | ||||
|       this.ariaList = []; | ||||
|       this.aimList = []; | ||||
|       this.imgForm = { | ||||
|         segmentId: "", | ||||
|         defectType: "", | ||||
|         stakeStart: "", | ||||
|         stakeEnd: "", | ||||
|       }; | ||||
|       this.params = { | ||||
|         page: 1, | ||||
|         size: 10, | ||||
|       }; | ||||
|       this.getList(); | ||||
|       this.showImage(0); | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 左侧点击图片事件 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     showImage(index) { | ||||
|       this.currentIndex = index; | ||||
|       const indexInfo = this.defectData[this.currentIndex].media.length - 1; | ||||
|       this.selectedThumbnail = indexInfo; // Reset to the first thumbnail when changing the main item | ||||
|       this.$nextTick(() => { | ||||
|         this.scrollToCurrentImage(); | ||||
|         this.updateRects(); | ||||
|       }); | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 点击下方小列表 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     showThumbnailImage(index) { | ||||
|       this.selectedThumbnail = index; | ||||
|       this.updateRects(); | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 使图片展示在父级容器可视区域 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     scrollToCurrentImage: debounce(function () { | ||||
|       if (this.$refs.sidebar) { | ||||
|         const sidebarImages = this.$refs.sidebar.querySelectorAll("img"); | ||||
|         const currentImageElement = sidebarImages[this.currentIndex]; | ||||
|         if (currentImageElement) { | ||||
|           currentImageElement.scrollIntoView({ | ||||
|             behavior: "smooth", | ||||
|             block: "center", | ||||
|           }); | ||||
|         } | ||||
|       } | ||||
|     }, 200), | ||||
|     /** | ||||
|      * @description: 滚动触发事件 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     handleScroll() { | ||||
|       const sidebar = this.$refs.sidebar; | ||||
|       // 滚动到顶加载数据 | ||||
|       if (sidebar.scrollTop < 2 && this.pageTip > 1 && !this.loading) { | ||||
|         this.loadMoreTopImages(); | ||||
|       } | ||||
| 
 | ||||
|       // 滚动到底加载数据 | ||||
|       // 滚动高度+容器高度  滚动区域高度 | ||||
|       if ( | ||||
|         sidebar.scrollTop + sidebar.clientHeight >= sidebar.scrollHeight - 1 && | ||||
|         !this.loading | ||||
|       ) { | ||||
|         this.loadMoreBottomImages(); | ||||
|       } | ||||
|       // if (this.currentIndex === this.defectData.length - 1) { | ||||
|       //   this.loadMoreBottomImages(); | ||||
|       // } | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 向下加载更多图片方法 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     loadMoreBottomImages() { | ||||
|       this.params.page += 1; | ||||
|       this.getList(); | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 向上加载更多图片 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     loadMoreTopImages() { | ||||
|       this.pageTip -= 1; | ||||
|       this.params.page -= 1; | ||||
|       this.currentIndex += this.params.size; | ||||
|       this.getListTop(); | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 键盘事件 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     handleKeydown(event) { | ||||
|       if (event.key === "ArrowUp") { | ||||
|         event.preventDefault(); | ||||
|         if (this.currentIndex > 0) { | ||||
|           this.currentIndex--; | ||||
|           const index = this.defectData[this.currentIndex].media.length - 1; | ||||
|           this.selectedThumbnail = index; // Reset when changing main images via keyboard | ||||
|           this.scrollToCurrentImage(); | ||||
|           this.updateRects(); | ||||
|         } | ||||
|       } else if (event.key === "ArrowDown") { | ||||
|         event.preventDefault(); | ||||
|         if (this.currentIndex < this.defectData.length - 1) { | ||||
|           this.currentIndex === this.defectData.length - 1 | ||||
|             ? this.currentIndex | ||||
|             : this.currentIndex++; | ||||
|           const index = this.defectData[this.currentIndex].media.length - 1; | ||||
|           this.selectedThumbnail = index; // Reset when changing main images via keyboard | ||||
|           this.scrollToCurrentImage(); | ||||
|           this.updateRects(); | ||||
|         } else { | ||||
|           this.loadMoreBottomImages(); | ||||
|         } | ||||
|       } else if (event.keyCode === 89) { | ||||
|         // 确认病害 | ||||
|         this.changeDefect(2); | ||||
|       } else if (event.keyCode === 78) { | ||||
|         // 不是病害 | ||||
|         this.changeDefect(3); | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 选择框修改事件 | ||||
|      * @param {*} val | ||||
|      * @return {*} | ||||
|      */ | ||||
|     handleCheckedRectChange(val) { | ||||
|       this.checkedRectList = this.rectItem.filter((item) => { | ||||
|         return val.includes(item.id); | ||||
|       }); | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 图片位置信息获取 | ||||
|      * @param {*} val | ||||
|      * @return {*} | ||||
|      */ | ||||
|     updateRects() { | ||||
|       this.rectItem = []; | ||||
|       if ( | ||||
|         this.defectData.length > 0 && | ||||
|         this.defectData.length > this.currentIndex | ||||
|       ) { | ||||
|         if ( | ||||
|           this.selectedThumbnail > | ||||
|           this.defectData[this.currentIndex]?.media.length - 1 | ||||
|         ) { | ||||
|           this.selectedThumbnail = | ||||
|             this.defectData[this.currentIndex]?.media.length - 1; | ||||
|         } | ||||
|         const array = this.defectData[this.currentIndex]?.media.map((item) => { | ||||
|           return { | ||||
|             ...item, | ||||
|             createdTime: this.defectData[this.currentIndex].createdTime, | ||||
|             stakeEnd: this.defectData[this.currentIndex].stakeEnd, | ||||
|             stakeStart: this.defectData[this.currentIndex].stakeStart, | ||||
|             defectTypeName: this.defectData[this.currentIndex].defectTypeName, | ||||
|             targetArea: this.defectData[this.currentIndex].targetArea, | ||||
|             targetLen: this.defectData[this.currentIndex].targetLen, | ||||
|             rectPosition: item.rect?.split(",").map(Number), | ||||
|           }; | ||||
|         }); | ||||
|         this.rectItem = [array[this.selectedThumbnail]]; | ||||
|         this.checkedRectList = this.rectItem; | ||||
|         this.checkedRect = [array[this.selectedThumbnail].id]; | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 图片红框位置 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     getRectStyle([left, top, width, height], index) { | ||||
|       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", | ||||
|         border: `2px solid ${this.colorList[index]}`, | ||||
|       }; | ||||
|     }, | ||||
| 
 | ||||
|     /** | ||||
|      * @description: 是病害/不是病害点击事件 | ||||
|      * @param {*} | ||||
|      * @return {*} | ||||
|      */ | ||||
|     changeDefect(value) { | ||||
|       if (this.defectData.length > 0) { | ||||
|         mergeDefect({ | ||||
|           status: value, | ||||
|           snapShotIds: [this.defectData[this.currentIndex].snapshotId], | ||||
|         }) | ||||
|           .then(({ code, msg }) => { | ||||
|             if (code === 200) { | ||||
|               this.defectData.splice(this.currentIndex, 1); | ||||
|               // this.currentIndex + 1; | ||||
|               this.$modal.msgSuccess("修改成功"); | ||||
|             } else { | ||||
|               this.$modal.msgWarning(msg); | ||||
|             } | ||||
|           }) | ||||
|           .finally(() => { | ||||
|             this.showImage(this.currentIndex); | ||||
|             if (this.defectData.length < 4) { | ||||
|               this.defectData.splice( | ||||
|                 (this.params.page - 1) * 10, | ||||
|                 this.defectData.length - 1 | ||||
|               ); | ||||
|               this.getList(); | ||||
|             } | ||||
|           }); | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|   mounted() { | ||||
|     window.addEventListener("keydown", throttle(this.handleKeydown, 100)); | ||||
|     window.addEventListener("resize", this.updateRects); | ||||
|   }, | ||||
|   beforeDestroy() { | ||||
|     window.removeEventListener("keydown", this.handleKeydown); | ||||
|     window.removeEventListener("resize", this.updateRects); | ||||
|   }, | ||||
| }; | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" scoped> | ||||
| .app { | ||||
|   width: 100%; | ||||
|   // height: 54rem; | ||||
|   height: calc(100vh - 7rem); | ||||
|   display: flex; | ||||
|   flex-direction: row; | ||||
|   background-color: #2e3a46; | ||||
| } | ||||
| 
 | ||||
| .left-list { | ||||
|   width: 16rem; | ||||
|   height: 100%; | ||||
| 
 | ||||
|   .sidebar { | ||||
|     width: 15.5rem; | ||||
|     height: calc(100% - 0.5rem); | ||||
|     // height: 815px; | ||||
|     background-color: #1f292e; | ||||
|     padding: 10px; | ||||
|     overflow-y: auto; | ||||
|   } | ||||
| 
 | ||||
|   .sidebar::-webkit-scrollbar { | ||||
|     width: 8px; | ||||
|   } | ||||
| 
 | ||||
|   .sidebar::-webkit-scrollbar-track { | ||||
|     background: #2e3a46; | ||||
|     border-radius: 10px; | ||||
|   } | ||||
| 
 | ||||
|   .sidebar::-webkit-scrollbar-thumb { | ||||
|     background: #444c51; | ||||
|     border-radius: 10px; | ||||
|   } | ||||
| 
 | ||||
|   .sidebar::-webkit-scrollbar-thumb:hover { | ||||
|     background: #00aaff; | ||||
|   } | ||||
| 
 | ||||
|   .sidebar img { | ||||
|     width: 100%; | ||||
|     margin-bottom: 5px; | ||||
|     cursor: pointer; | ||||
|     border-radius: 3px; | ||||
|     transition: transform 0.2s, border 0.2s; | ||||
|     box-sizing: border-box; | ||||
|   } | ||||
| 
 | ||||
|   .sidebar img.selected { | ||||
|     border: 3px solid #00aaff; | ||||
|     transform: scale(1.05); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .main-content { | ||||
|   width: calc(100% - 250px); | ||||
|   height: 100%; | ||||
|   background-color: #1b2126; | ||||
|   padding: 10px; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
| } | ||||
| 
 | ||||
| .toolbar { | ||||
|   width: 100%; | ||||
|   height: 4rem; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   background-color: #333c42; | ||||
|   padding: 5px; | ||||
|   border-bottom: 1px solid #333c42; | ||||
| 
 | ||||
|   ::v-deep .el-form { | ||||
|     width: 100%; | ||||
| 
 | ||||
|     .el-form-item--small .el-form-item__label { | ||||
|       color: #ffffff; | ||||
|     } | ||||
| 
 | ||||
|     .el-select { | ||||
|       width: 10rem; | ||||
| 
 | ||||
|       .el-input--small .el-input__inner { | ||||
|         color: #ffffff; | ||||
|         background-color: #333c42; | ||||
|       } | ||||
| 
 | ||||
|       .el-select-dropdown { | ||||
|         background-color: #102649; | ||||
|         border-color: #08204f; | ||||
| 
 | ||||
|         .el-scrollbar { | ||||
|           .el-select-dropdown__wrap { | ||||
|             .el-scrollbar__view { | ||||
|               .el-select-dropdown__item { | ||||
|                 color: #ffffff; | ||||
|               } | ||||
| 
 | ||||
|               .el-select-dropdown__item:hover { | ||||
|                 background-color: #2b4c7e; | ||||
|               } | ||||
| 
 | ||||
|               .el-select-dropdown__item.selected { | ||||
|                 background-color: #2b4c7e; | ||||
|               } | ||||
| 
 | ||||
|               .el-select-dropdown__item.hover { | ||||
|                 background-color: #2b4c7e; | ||||
|               } | ||||
|             } | ||||
| 
 | ||||
|             .el-select-dropdown__list { | ||||
|               background-color: #333c42; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     .el-input--small .el-input__inner { | ||||
|       color: #ffffff; | ||||
|       background-color: #333c42; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .image-container { | ||||
|   position: relative; | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   overflow: hidden; | ||||
| 
 | ||||
|   ::v-deep .image-info { | ||||
|     width: 100%; | ||||
|     background-color: rgba(0, 0, 0, 0.5); | ||||
| 
 | ||||
|     .el-checkbox__input.is-checked + .el-checkbox__label { | ||||
|       color: inherit; | ||||
|       font-size: 0.8rem; | ||||
|     } | ||||
| 
 | ||||
|     .el-checkbox__label { | ||||
|       color: inherit; | ||||
|       font-size: 0.8rem; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .image-container img { | ||||
|   max-width: 100%; | ||||
|   max-height: 100%; | ||||
|   object-fit: contain; | ||||
| } | ||||
| 
 | ||||
| // 画框样式 | ||||
| .rect-overlay { | ||||
|   position: absolute; | ||||
| 
 | ||||
|   // pointer-events: none; | ||||
|   // border: 2px solid red; | ||||
|   &:hover { | ||||
|     opacity: 0.7; | ||||
|   } | ||||
| 
 | ||||
|   > div { | ||||
|     cursor: pointer; | ||||
|     white-space: nowrap; | ||||
|     position: absolute; | ||||
|     top: -1.2rem; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // 图片信息 | ||||
| .rect-image { | ||||
|   width: 90%; | ||||
|   position: absolute; | ||||
|   top: 0; | ||||
| } | ||||
| 
 | ||||
| .image-viewer { | ||||
|   // height: 43rem; | ||||
|   height: calc(100% - 9rem); | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   background-color: #22272b; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .thumbnail-row { | ||||
|   width: 100%; | ||||
|   height: 5rem; | ||||
|   display: flex; | ||||
| 
 | ||||
|   .thumbnail-image { | ||||
|     width: 87%; | ||||
|     height: 100%; | ||||
|     display: flex; | ||||
|     // justify-content: center; | ||||
|     overflow-x: auto; | ||||
|     padding: 0.4rem; | ||||
|     background-color: #333c42; | ||||
|     gap: 5px; | ||||
|   } | ||||
| 
 | ||||
|   .thumbnail-image img { | ||||
|     width: 100px; | ||||
|     height: 60px; | ||||
|     cursor: pointer; | ||||
|     border-radius: 3px; | ||||
|     transition: transform 0.2s, border 0.2s; | ||||
|     box-sizing: border-box; | ||||
|   } | ||||
| 
 | ||||
|   .thumbnail-image img.selected { | ||||
|     border: 3px solid #00aaff; | ||||
|   } | ||||
| 
 | ||||
|   .thumbnail-btn { | ||||
|     width: 13%; | ||||
|     height: 100%; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     align-items: center; | ||||
|     justify-content: space-around; | ||||
|     padding: 0.4rem; | ||||
|     background-color: #333c42; | ||||
| 
 | ||||
|     > button { | ||||
|       width: 6rem; | ||||
|       margin: 0; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // 按钮样式 | ||||
| .btn-submit { | ||||
|   background-color: transparent; | ||||
|   background-image: url("~@/assets/screen/index/btn-submit.png"); | ||||
|   background-repeat: no-repeat; | ||||
|   background-size: 100% 100%; | ||||
|   background-position: 50%; | ||||
|   border-color: transparent; | ||||
|   color: #ffffff; | ||||
| 
 | ||||
|   &:active { | ||||
|     color: #0d9ee2; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .btn-cancel { | ||||
|   background-color: transparent; | ||||
|   background-image: url("~@/assets/screen/index/btn-cancel.png"); | ||||
|   background-repeat: no-repeat; | ||||
|   background-size: 100% 100%; | ||||
|   background-position: 50%; | ||||
|   border-color: transparent; | ||||
|   color: #ffffff; | ||||
| 
 | ||||
|   &:active { | ||||
|     color: #0d9ee2; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @ -2,7 +2,7 @@ | ||||
|  * @Author: SunTao 328867980@qq.com | ||||
|  * @Date: 2024-11-01 13:17:41 | ||||
|  * @LastEditors: SunTao 328867980@qq.com | ||||
|  * @LastEditTime: 2024-12-24 16:01:10 | ||||
|  * @LastEditTime: 2024-12-25 17:02:47 | ||||
|  * @FilePath: \znxjxt-ui\src\views\xj\inspection\confirmation-management\index.vue | ||||
|  * @Description: 巡检信息-病害确认 | ||||
| --> | ||||
| @ -22,6 +22,7 @@ | ||||
|           v-model="queryParams.segmentName" | ||||
|           placeholder="请选择路段" | ||||
|           clearable | ||||
|           filterable | ||||
|         > | ||||
|           <el-option | ||||
|             v-for="item in segmentList" | ||||
| @ -181,7 +182,7 @@ | ||||
|           >不是病害 | ||||
|         </el-button> | ||||
|       </el-col> | ||||
|       <el-col :span="1.5"> | ||||
|       <!-- <el-col :span="1.5"> | ||||
|         <el-button | ||||
|           type="primary" | ||||
|           plain | ||||
| @ -190,7 +191,7 @@ | ||||
|           @click="handleBatch()" | ||||
|           >影像模式 | ||||
|         </el-button> | ||||
|       </el-col> | ||||
|       </el-col> --> | ||||
|     </el-row> | ||||
| 
 | ||||
|     <!-- 数据表格 --> | ||||
| @ -226,7 +227,7 @@ | ||||
|       <el-table-column label="病害图片" align="center" prop="media"> | ||||
|         <template slot-scope="scope"> | ||||
|           <img | ||||
|             @click="showScreenImg(scope.row)" | ||||
|             @click="showScreenImg(scope.row, scope.$index)" | ||||
|             height="50" | ||||
|             :src="scope.row.mediaUrl" | ||||
|           /> | ||||
| @ -255,7 +256,7 @@ | ||||
|     </div> | ||||
| 
 | ||||
|     <!-- 查看图片大图 --> | ||||
|     <el-dialog | ||||
|     <!-- <el-dialog | ||||
|       title="查看图片" | ||||
|       :visible.sync="showImageDialog" | ||||
|       width="85rem" | ||||
| @ -289,7 +290,7 @@ | ||||
|           }} | ||||
|         </div> | ||||
|       </div> | ||||
|     </el-dialog> | ||||
|     </el-dialog> --> | ||||
| 
 | ||||
|     <!-- 影像模式弹窗 --> | ||||
|     <el-dialog | ||||
| @ -305,6 +306,19 @@ | ||||
|         :tableDefect="tableDefect" | ||||
|       ></image-dialog> | ||||
|     </el-dialog> | ||||
| 
 | ||||
|     <!-- 详情图片弹窗 --> | ||||
|     <el-dialog | ||||
|       title="详情" | ||||
|       :visible.sync="showImageDialog" | ||||
|       width="85rem" | ||||
|       append-to-body | ||||
|       :close-on-click-modal="false" | ||||
|       destroy-on-close | ||||
|       @close="imgCancel" | ||||
|     > | ||||
|       <img-dialog v-if="showImageDialog" :segmentList="segmentList" :imageItem="imageItem"></img-dialog> | ||||
|     </el-dialog> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| @ -316,8 +330,9 @@ import { | ||||
|   mergeDefect, | ||||
| } from "@/api/xj/confirmation"; | ||||
| import imageDialog from "./components/image-dialog.vue"; | ||||
| import imgDialog from "./components/img-dialog.vue"; | ||||
| export default { | ||||
|   components: { imageDialog }, | ||||
|   components: { imageDialog, imgDialog }, | ||||
|   name: "ConfirmationManagement", | ||||
|   data() { | ||||
|     return { | ||||
| @ -534,8 +549,15 @@ export default { | ||||
|     }, | ||||
| 
 | ||||
|     /* 打开查看图片弹窗 */ | ||||
|     showScreenImg(item) { | ||||
|       this.currentImageItem = item; | ||||
|     showScreenImg(item, index) { | ||||
|       // this.currentImageItem = item; | ||||
|       // this.showImageDialog = true; | ||||
|       this.imageItem = { | ||||
|         ...item, | ||||
|         index, | ||||
|         pageTip: this.pagination.page, | ||||
|         params: this.pagination, | ||||
|       }; | ||||
|       this.showImageDialog = true; | ||||
|     }, | ||||
| 
 | ||||
| @ -648,4 +670,48 @@ export default { | ||||
|   color: #ffffff; | ||||
|   background-color: rgba(0, 0, 0, 0.5); | ||||
| } | ||||
| 
 | ||||
| /* 修改弹窗样式 */ | ||||
| ::v-deep .el-dialog { | ||||
|   background-color: transparent; | ||||
| } | ||||
| 
 | ||||
| ::v-deep .el-dialog__header { | ||||
|   padding: 10px; | ||||
|   background-color: #113463; | ||||
| 
 | ||||
|   span, | ||||
|   i { | ||||
|     color: #ffffff; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| ::v-deep .el-dialog__body { | ||||
|   padding: 0; | ||||
|   // background-color: #113463; | ||||
| 
 | ||||
|   /* 查看点位大图弹窗 */ | ||||
|   .view-image-container { | ||||
|     position: relative; | ||||
|     width: 100%; | ||||
|     height: 50rem; | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     align-items: center; | ||||
|     justify-content: center; | ||||
|     overflow: hidden; | ||||
|   } | ||||
| 
 | ||||
|   .view-image-container img { | ||||
|     max-width: 100%; | ||||
|     max-height: 100%; | ||||
|     object-fit: contain; | ||||
|   } | ||||
| 
 | ||||
|   .rect-overlay { | ||||
|     position: absolute; | ||||
|     // pointer-events: none; | ||||
|     border: 2px solid red; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user