<!-- * @Description: * @Autor: renchao * @LastEditTime: 2023-06-14 11:10:26 --> <template> <div class="rlPopup"> <div class="prev handle-btn" v-if="!isScan" @click="prev()"> <i class="el-icon-arrow-left"></i> </div> <div class="next handle-btn" v-if="!isScan" @click="next()"> <i class="el-icon-arrow-right"></i> </div> <div class="img-list-wrap"> <img src="http://127.0.0.1:38088/video=stream&camidx=0" v-if="isScan" alt="高拍仪"> <div v-for="(img, i) in previewImg.imgList" :key="i" v-else> <photo-zoom :url="img.fjurl" :bigWidth="165" v-if="i === previewImg.index" :scale="2" overlayStyle="width: 100%;height:100%"> </photo-zoom> </div> </div> <!--缩略图--> <div class="thumb-wrap"> <div class="thumb-wrap-button"> <el-button type="primary" @click="clickImage">(放大) 显示(缩小)</el-button> <el-upload class="fileUpdate" ref="upload" action="" :show-file-list="false" :multiple="true" :auto-upload="false" :on-change="handleChange" accept=".JPG, .PNG, .JPEG,.jpg, .png, .jpeg" :before-upload="beforeUpload"> <el-button icon="el-icon-upload" type="primary" v-if="!this.$route.query.viewtype">上传</el-button> </el-upload> <el-button type="primary" icon="el-icon-delete-solid" @click="handleDelete" v-if="!this.$route.query.viewtype && thumbnailImages.length>0">删除</el-button> <el-button type="primary" @click="handleOpenScan">{{scanTitle}}</el-button> <el-button type="primary" @click="handleViewScan" v-if="isScan">拍照</el-button> </div> <ul> <li v-for="(img, index) in thumbnailImages" :key="index" :class="{ active: previewImg.index === index }" @click="showCurrent(index)"> <img :src="img.fjurl"> </li> </ul> </div> <!-- 点开后的视图 --> <publicPicture v-if="showViewer" :url-list="allLi" :initialIndex="initialIndex" @close-viewer="closeViewer"> </publicPicture> </div> </template> <script> import axios from 'axios' import PhotoZoom from '@/components/PhotoZoom' import { uploadSjClmx, deleteClmx } from "@/api/clxx.js"; import publicPicture from '@/components/publicPicture/index.vue' export default { name: 'PreviewImage', props: { previewImg: { type: Object, default: () => { } } }, components: { PhotoZoom, publicPicture }, data () { return { isScan: false, // 打开高拍仪 scanTitle: '打开高拍仪', transform: { scale: 1, degree: 0 }, maxLength: 0, // 缩略图 thumbnailImages: [], showViewer: false, initialIndex: undefined, allLi: [], } }, watch: { previewImg: { handler (newValue, oldValue) { if (newValue.imgList.length > 0) { this.allLi = _.cloneDeep(newValue.imgList).map(item => item.fjurl) this.thumbnailImages = newValue.imgList } }, deep: true } }, created () { this.maxLength = 0; this.allLi = _.cloneDeep(this.previewImg.imgList).map(item => item.fjurl) this.thumbnailImages = this.previewImg.imgList }, computed: { isFirst () { return this.previewImg.index === 0 }, isLast () { return this.previewImg.index === this.previewImg.imgList.length - 1 } }, methods: { /** * @description: 打开高拍仪 * @author: renchao */ handleOpenScan () { this.isScan = !this.isScan if (this.isScan) { this.$message({ message: '正在启动程序请稍等', type: 'success' }) setTimeout(() => { this.scanTitle = '关闭高拍仪' }, 4000) } else { this.scanTitle = '打开高拍仪' } }, /** * @description: 拍照 * @author: renchao */ handleViewScan () { function dataURLtoBlob (base64String) { const arr = base64String.split(','); if (arr.length !== 2) { throw new Error('Invalid Base64 format'); } const mime = arr[0].match(/:(.*?);/)[1]; if (!mime) { throw new Error('Cannot retrieve MIME type'); } const bstr = atob(arr[1]); const n = bstr.length; const u8arr = new Uint8Array(n); for (let i = 0; i < n; i++) { u8arr[i] = bstr.charCodeAt(i); } return new Blob([u8arr], { type: mime }); } function blobToFile (blob) { const options = { type: blob.type }; const file = new File([blob], options); return file; } let data = { "filepath": "base64", "rotate": "0", "cutpage": "0", "camidx": "0", "ColorMode": "0", "quality": "3" } axios.post("http://127.0.0.1:38088/video=grabimage", JSON.stringify(data)).then((res) => { let blob = dataURLtoBlob('data:image/png;base64,' + res.data.photoBase64); let file = blobToFile(blob); var formData = new FormData(); formData.append('file', file.raw) formData.append("bsmSj", this.previewImg.bsmSj); formData.append("bsmSlsq", this.previewImg.bsmSlsq); uploadSjClmx(formData).then((res) => { if (res.code == 200) { this.$emit('updateList', res.result) this.$message({ message: '上传成功!', type: 'success' }) } }) }) }, prev () { let len = this.previewImg.imgList.length if (this.isFirst || len == 0) { this.$emit('prevPriview') } else { this.$parent.previewImg.index = (this.$parent.previewImg.index - 1 + len) % len } }, next () { let len = this.previewImg.imgList.length if (this.isLast || len == 0) { this.$emit('nextPriview') } else { this.$parent.previewImg.index = (this.$parent.previewImg.index + 1) % len } }, showCurrent (index) { this.previewImg.index = index }, closeViewer () { this.showViewer = false }, clickImage () { this.showViewer = true }, // 上传 beforeUpload (file) { const isJPEG = file.type === 'image/jpeg' const isPNG = file.type === 'image/png' const isJPG = file.type === 'image/jpg' const isGIF = file.type === 'image/gif' const isLt5M = file.size / 1024 / 1024 < 5 if (!isJPEG && !isGIF && !isPNG && !isJPG && !isGIF) { this.$message.error('请选择jpeg/png/jpg/bmp/gif格式的图片后重试') this.loading = false } if (!isLt5M) { this.$message.error('上传图片大小不能超过 5MB!') this.loading = false } this.imgHidden = (isJPG || isJPEG || isPNG || isGIF) && isLt5M return this.imgHidden }, async handleChange (file, files) { // 清空 fileList 数组 let length = files.length; this.maxLength = Math.max(length, this.maxLength) this.$refs.upload.clearFiles(); setTimeout(() => { if (length !== this.maxLength) return var formData = new FormData(); files.forEach(file => { formData.append('file', file.raw) }) formData.append("bsmSj", this.previewImg.bsmSj); formData.append("bsmSlsq", this.previewImg.bsmSlsq); uploadSjClmx(formData).then((res) => { if (res.code == 200) { this.$emit('updateList', res.result) this.$message({ message: '上传成功!', type: 'success' }) } }) }, 0) }, handleDelete () { let that = this this.$confirm('此操作将永久删除, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(async () => { let bsmClmx = this.previewImg.imgList[this.previewImg.index].bsmClmx deleteClmx(bsmClmx).then(res => { if (res.code == 200) { that.$emit('updateList', res.result) that.$message({ message: '删除成功!', type: 'success' }) } }) }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }) }) } } } </script> <style lang="scss" scoped> // 查看大图 .rlPopup { position: relative; width: 100%; text-align: center; height: 100%; .handle-btn { position: absolute; top: 50%; transform: translateY(-100%); width: 66px; height: 66px; line-height: 75px; color: #fff; background-color: rgb(239, 239, 239); border-radius: 50%; cursor: pointer; text-align: center; transition: all 0.3s; i { font-size: 24px; } } .handle-btn:hover { background-color: rgb(185, 183, 183); } .prev { left: 1%; } .next { right: 1%; } .img-list-wrap { width: 100%; display: flex; justify-content: center; height: calc(100% - 80px); align-items: center; background: rgba(194, 190, 190, 0.1); overflow: scroll; img { display: block; object-fit: scale-down; transition: all 0.3s; max-width: 100%; } } .thumb-wrap { &-button { display: flex; justify-content: center; .fileUpdate { margin: 0 10px; } } li { float: left; width: 60px; height: 45px; border: solid 1px #ececec; position: relative; margin-right: 5px; cursor: pointer; &:last-child { margin-right: 0; } img { max-width: 57px; max-height: 42px; display: block; object-fit: scale-down; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } } .active { border-color: #409eff; } } } </style> <style> .zoom-on-hover { position: relative; overflow: hidden; } .zoom-on-hover .normal { width: 100%; } .zoom-on-hover .zoom { position: absolute; opacity: 0; transform-origin: top left; } .zoom-on-hover.zoomed .zoom { opacity: 1; } .zoom-on-hover.zoomed .normal { opacity: 0; } </style>