Blame view

src/views/components/imagePreview.vue 11.7 KB
renchao@pashanhoo.com committed
1
<!--
xiaomiao committed
2
 * @Description:
renchao@pashanhoo.com committed
3
 * @Autor: renchao
4
 * @LastEditTime: 2023-08-18 13:53:23
renchao@pashanhoo.com committed
5
-->
任超 committed
6 7
<template>
  <div class="rlPopup">
renchao@pashanhoo.com committed
8
    <div class="prev handle-btn" v-if="!isScan" @click="prev()">
任超 committed
9 10
      <i class="el-icon-arrow-left"></i>
    </div>
renchao@pashanhoo.com committed
11
    <div class="next handle-btn" v-if="!isScan" @click="next()">
任超 committed
12 13 14
      <i class="el-icon-arrow-right"></i>
    </div>
    <div class="img-list-wrap">
renchao@pashanhoo.com committed
15 16
      <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>
任超 committed
17
        <photo-zoom :url="img.fjurl" :bigWidth="165" v-if="i === previewImg.index" :scale="2"
任超 committed
18
          overlayStyle="width: 100%;height:100%">
任超 committed
19 20 21 22 23 24
        </photo-zoom>
      </div>
    </div>
    <!--缩略图-->
    <div class="thumb-wrap">
      <div class="thumb-wrap-button">
25
        <el-button type="primary" @click="clickImage" v-if="previewImg.imgList.length>0">(放大) 显示(缩小)</el-button>
renchao@pashanhoo.com committed
26
        <el-upload class="fileUpdate" ref="upload" :key="key" action="" :show-file-list="false" :multiple="true" :auto-upload="false"
27
          :on-change="handleChange"
28
          accept=".JPG, .PNG, .JPEG,.jpg, .png, .jpeg">
xiaomiao committed
29
          <el-button icon="el-icon-upload" type="primary" v-if="ableOperation">上传</el-button>
任超 committed
30
        </el-upload>
31
        <el-button type="primary" icon="el-icon-delete-solid" @click="handleDelete"
xiaomiao committed
32 33
          v-if="thumbnailImages.length>0 && ableOperation">删除</el-button>
        <div v-if="ableOperation" class="pl-5">
34 35
          <el-button type="primary" @click="handleOpenScan" v-if="ableOperation">{{scanTitle}}</el-button>
          <el-button type="primary" @click="handleViewScan" v-if="isScan && ableOperation">拍照</el-button>
36
        </div>
任超 committed
37 38
      </div>
      <ul>
任超 committed
39
        <li v-for="(img, index) in thumbnailImages" :key="index" :class="{ active: previewImg.index === index }"
任超 committed
40
          @click="showCurrent(index)">
任超 committed
41
          <img :src="img.fjurl">
任超 committed
42 43 44 45 46 47 48 49 50
        </li>
      </ul>
    </div>
    <!-- 点开后的视图 -->
    <publicPicture v-if="showViewer" :url-list="allLi" :initialIndex="initialIndex" @close-viewer="closeViewer">
    </publicPicture>
  </div>
</template>
<script>
51
  import PhotoZoom from '@/components/PhotoZoom'
52
  import { getAltimeterInfo, getUuid } from '@/utils/operation.js'
53
  import { uploadBatch, deleteClmx } from "@/api/clxx.js";
54 55 56 57 58 59 60
  import publicPicture from '@/components/publicPicture/index.vue'
  export default {
    name: 'PreviewImage',
    props: {
      previewImg: {
        type: Object,
        default: () => { }
61 62 63 64
      },
      ableOperation: {
        type: Boolean,
        default: true
任超 committed
65 66
      }
    },
67 68 69
    components: {
      PhotoZoom,
      publicPicture
任超 committed
70
    },
71 72
    data () {
      return {
renchao@pashanhoo.com committed
73
        key: 0,
renchao@pashanhoo.com committed
74 75 76
        isScan: false,
        // 打开高拍仪
        scanTitle: '打开高拍仪',
77 78 79 80
        transform: {
          scale: 1,
          degree: 0
        },
1  
renchao@pashanhoo.com committed
81
        maxFileLength: 0,
82 83 84 85 86 87
        // 缩略图
        thumbnailImages: [],
        showViewer: false,
        initialIndex: undefined,
        allLi: [],
      }
任超 committed
88
    },
89 90 91
    watch: {
      previewImg: {
        handler (newValue, oldValue) {
92
          if (newValue.imgList && newValue.imgList.length > 0) {
1  
renchao@pashanhoo.com committed
93 94
            this.allLi = _.cloneDeep(newValue.imgList).map(item => item.fjurl)
            this.thumbnailImages = newValue.imgList
95 96 97
          } else {
            this.allLi = []
            this.thumbnailImages = []
1  
renchao@pashanhoo.com committed
98
          }
99
        },
100 101
        deep: true,
        immediate: true
102
      }
任超 committed
103
    },
104 105 106 107
    created () {
      this.maxLength = 0;
      this.allLi = _.cloneDeep(this.previewImg.imgList).map(item => item.fjurl)
      this.thumbnailImages = this.previewImg.imgList
任超 committed
108
    },
109 110 111 112 113 114
    computed: {
      isFirst () {
        return this.previewImg.index === 0
      },
      isLast () {
        return this.previewImg.index === this.previewImg.imgList.length - 1
任超 committed
115 116
      }
    },
117
    methods: {
renchao@pashanhoo.com committed
118 119 120 121 122
      /**
       * @description: 打开高拍仪
       * @author: renchao
       */
      handleOpenScan () {
123 124 125 126 127 128 129 130 131 132 133 134
        this.isScan = !this.isScan
        if (this.isScan) {
          this.$message({
            message: '正在启动程序请稍等',
            type: 'success'
          })
          setTimeout(() => {
            this.scanTitle = '关闭高拍仪'
          }, 4000)
        } else {
          this.scanTitle = '打开高拍仪'
        }
renchao@pashanhoo.com committed
135 136 137 138 139 140
      },
      /**
       * @description: 拍照
       * @author: renchao
       */
      handleViewScan () {
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
        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) {
159 160
          let name = getUuid(8) + '.jpg'
          const file = new File([blob], name);
161 162
          return file;
        }
163
        getAltimeterInfo().then(res => {
164 165 166
          let blob = dataURLtoBlob('data:image/png;base64,' + res.data.photoBase64);
          let file = blobToFile(blob);
          var formData = new FormData();
167
          formData.append('file', file)
168 169 170 171 172 173 174 175 176 177 178
          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'
              })
            }
          })
renchao@pashanhoo.com committed
179 180
        })
      },
yuanbo committed
181 182 183 184
      /**
       * @description: prev
       * @author: renchao
       */
185 186 187 188 189 190
      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
任超 committed
191
        }
192
      },
yuanbo committed
193 194 195 196
      /**
       * @description: next
       * @author: renchao
       */
197 198 199 200 201 202 203 204
      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
        }
      },
yuanbo committed
205 206 207 208 209
      /**
       * @description: showCurrent
       * @param {*} index
       * @author: renchao
       */
210 211 212
      showCurrent (index) {
        this.previewImg.index = index
      },
yuanbo committed
213 214 215 216
      /**
       * @description: closeViewer
       * @author: renchao
       */
217 218 219
      closeViewer () {
        this.showViewer = false
      },
yuanbo committed
220 221 222 223
      /**
       * @description: clickImage
       * @author: renchao
       */
224 225 226
      clickImage () {
        this.showViewer = true
      },
yuanbo committed
227 228 229 230 231 232
      /**
       * @description: handleChange
       * @param {*} file
       * @param {*} files
       * @author: renchao
       */
1  
renchao@pashanhoo.com committed
233 234 235
      async handleChange (file, fileList) {
        let length = fileList.length;
        this.maxFileLength = Math.max(length, this.maxFileLength)
236
        var formData = new FormData();
237
        setTimeout(() => {
1  
renchao@pashanhoo.com committed
238 239 240
          if (this.maxFileLength !== length) {
            return
          }
241 242
          let num = 0, max = 0;
          const isLt5M = file.size / 1024 / 1024 < 5;
1  
renchao@pashanhoo.com committed
243
          fileList.forEach(item => {
244 245 246
            if (!isLt5M) {
              max++
            }
247 248
            if (!['image/jpeg', 'image/png', 'image/jpg', 'image/gif'].includes(item.raw.type)) {
              num++
renchao@pashanhoo.com committed
249 250
            } else {
              formData.append('file', item.raw)
251
            }
252
          })
253 254
          if (num >= 1) {
            this.$message.error("请选择jpeg/png/jpg/bmp/gif格式的图片后重试")
renchao@pashanhoo.com committed
255 256 257
            // 移除不支持的文件类型
            this.key++
            return;
258
          }
259 260 261 262 263
          if (max >= 1) {
            this.$message.error('上传图片大小不能超过 5MB!');
            this.key++
            return;
          }
264 265
          formData.append("bsmSj", this.previewImg.bsmSj);
          formData.append("bsmSlsq", this.previewImg.bsmSlsq);
266
          uploadBatch(formData).then((res) => {
267 268 269 270 271 272
            if (res.code == 200) {
              this.$emit('updateList', res.result)
              this.$message({
                message: '上传成功!',
                type: 'success'
              })
273 274
              this.$refs.upload.clearFiles();
              this.maxFileLength = 0
275 276
            }
          })
277
        }, 0)
278
      },
yuanbo committed
279 280 281 282
      /**
       * @description: handleDelete
       * @author: renchao
       */
283 284 285 286 287 288 289 290
      handleDelete () {
        let that = this
        this.$confirm('此操作将永久删除, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(async () => {
          let bsmClmx = this.previewImg.imgList[this.previewImg.index].bsmClmx
291 292
          let bsmSj = this.previewImg.imgList[this.previewImg.index].bsmSj
          this.previewImg.imgList = this.previewImg.imgList.filter(item => item.bsmClmx != bsmClmx)
293 294
          deleteClmx(bsmClmx).then(res => {
            if (res.code == 200) {
295
              that.$emit('updateList', { children: this.previewImg.imgList, bsmSj: bsmSj })
296 297 298 299 300 301 302 303 304 305 306
              that.$message({
                message: '删除成功!',
                type: 'success'
              })
            }
          })
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          })
任超 committed
307
        })
308
      }
任超 committed
309 310 311 312
    }
  }
</script>
<style lang="scss" scoped>
313 314 315 316
  // 查看大图
  .rlPopup {
    position: relative;
    width: 100%;
任超 committed
317
    text-align: center;
318
    height: 100%;
任超 committed
319

320 321 322 323 324 325 326 327 328 329 330 331 332
    .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;
任超 committed
333

334 335 336 337
      i {
        font-size: 24px;
      }
    }
任超 committed
338

339 340 341
    .handle-btn:hover {
      background-color: rgb(185, 183, 183);
    }
任超 committed
342

343 344 345
    .prev {
      left: 1%;
    }
任超 committed
346

347 348
    .next {
      right: 1%;
任超 committed
349 350
    }

351 352
    .img-list-wrap {
      width: 100%;
任超 committed
353 354
      display: flex;
      justify-content: center;
355 356 357 358
      height: calc(100% - 80px);
      align-items: center;
      background: rgba(194, 190, 190, 0.1);
      overflow: scroll;
任超 committed
359

360 361 362 363 364
      img {
        display: block;
        object-fit: scale-down;
        transition: all 0.3s;
        max-width: 100%;
任超 committed
365 366 367
      }
    }

368 369 370 371
    .thumb-wrap {
      &-button {
        display: flex;
        justify-content: center;
任超 committed
372

373 374 375
        .fileUpdate {
          margin: 0 10px;
        }
任超 committed
376 377
      }

378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
      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%);
        }
任超 committed
401 402
      }

403 404 405
      .active {
        border-color: #409eff;
      }
任超 committed
406 407 408 409
    }
  }
</style>
<style>
410 411 412 413
  .zoom-on-hover {
    position: relative;
    overflow: hidden;
  }
任超 committed
414

415 416 417
  .zoom-on-hover .normal {
    width: 100%;
  }
任超 committed
418

419 420 421 422 423
  .zoom-on-hover .zoom {
    position: absolute;
    opacity: 0;
    transform-origin: top left;
  }
任超 committed
424

425 426 427
  .zoom-on-hover.zoomed .zoom {
    opacity: 1;
  }
任超 committed
428

429 430 431
  .zoom-on-hover.zoomed .normal {
    opacity: 0;
  }
任超 committed
432
</style>