|  | @@ -0,0 +1,290 @@
 | 
	
		
			
				|  |  | +<!--
 | 
	
		
			
				|  |  | + * @Description: 单个图片[.jpg,.png]文件上传组件
 | 
	
		
			
				|  |  | + * @Author: Rockery
 | 
	
		
			
				|  |  | + * @Date: 2021-12-27 11:19:47
 | 
	
		
			
				|  |  | + * @LastEditors: Rockery
 | 
	
		
			
				|  |  | + * @LastEditTime: 2021-12-27 13:57:09
 | 
	
		
			
				|  |  | + * @FilePath: \party_construct_web\src\components\RocImgFileUpload\index.vue
 | 
	
		
			
				|  |  | + * @Copyright: Copyright (c) 2016~2021 Rockery(1113269755@qq.com)
 | 
	
		
			
				|  |  | +-->
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +<template>
 | 
	
		
			
				|  |  | +  <div class="rocimgfileupload">
 | 
	
		
			
				|  |  | +    <div class="rocimgfileupload-attachment" v-loading="removeLoading">
 | 
	
		
			
				|  |  | +      <el-upload
 | 
	
		
			
				|  |  | +        ref="rocImgFileUploadRef"
 | 
	
		
			
				|  |  | +        :limit="1"
 | 
	
		
			
				|  |  | +        accept=".jpg, .png"
 | 
	
		
			
				|  |  | +        :auto-upload="false"
 | 
	
		
			
				|  |  | +        :show-file-list="true"
 | 
	
		
			
				|  |  | +        :action="actionUrl"
 | 
	
		
			
				|  |  | +        :headers="headers"
 | 
	
		
			
				|  |  | +        :before-upload="handleRocImgFileUploadBeforeUpload"
 | 
	
		
			
				|  |  | +        :on-success="handleRocImgFileUploadOnsuccess"
 | 
	
		
			
				|  |  | +        :on-change="handleRocImgFileUploadOnchange"
 | 
	
		
			
				|  |  | +        :on-remove="handleRocImgFileUploadOnRemove"
 | 
	
		
			
				|  |  | +        :on-exceed="handleRocImgFileUploadOnExceed"
 | 
	
		
			
				|  |  | +        class="rocimgfileupload-attachment-fileupload"
 | 
	
		
			
				|  |  | +      >
 | 
	
		
			
				|  |  | +        <div class="rocimgfileupload-attachment-fileupload-content">
 | 
	
		
			
				|  |  | +          <i class="el-icon-plus" />
 | 
	
		
			
				|  |  | +          上传文件,格式:JPG、PNG
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +      </el-upload>
 | 
	
		
			
				|  |  | +      <div v-if="isUploadSuccess" v-viewer class="fl rocimgfileupload-attachment-addr">
 | 
	
		
			
				|  |  | +        <img :src="successResp.successUrl" :alt="successResp.url" @error="imgViewerOnerror" />
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +      <el-button
 | 
	
		
			
				|  |  | +        v-if="isSelect && !isUploadSuccess"
 | 
	
		
			
				|  |  | +        type="primary"
 | 
	
		
			
				|  |  | +        size="small"
 | 
	
		
			
				|  |  | +        @click="submitRocImgFileUploadClick"
 | 
	
		
			
				|  |  | +      >上传文件</el-button>
 | 
	
		
			
				|  |  | +      <el-button
 | 
	
		
			
				|  |  | +        v-if="isSelect"
 | 
	
		
			
				|  |  | +        type="info"
 | 
	
		
			
				|  |  | +        size="small"
 | 
	
		
			
				|  |  | +        @click="removeRocImgFileUploadClick"
 | 
	
		
			
				|  |  | +      >移除文件</el-button>
 | 
	
		
			
				|  |  | +    </div>
 | 
	
		
			
				|  |  | +  </div>
 | 
	
		
			
				|  |  | +</template>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +<script>
 | 
	
		
			
				|  |  | +import { getToken } from '@/utils/auth';
 | 
	
		
			
				|  |  | +import Viewer from 'v-viewer';
 | 
	
		
			
				|  |  | +import 'viewerjs/dist/viewer.css';
 | 
	
		
			
				|  |  | +import Vue from 'vue';
 | 
	
		
			
				|  |  | +Vue.use(Viewer, {
 | 
	
		
			
				|  |  | +  defaultOptions: {
 | 
	
		
			
				|  |  | +    zIndex: 9999
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +});
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +export default {
 | 
	
		
			
				|  |  | +  name: 'Rocimgfileupload',
 | 
	
		
			
				|  |  | +  props: {
 | 
	
		
			
				|  |  | +    // 值
 | 
	
		
			
				|  |  | +    value: {
 | 
	
		
			
				|  |  | +      type: String,
 | 
	
		
			
				|  |  | +      default: ''
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    // 文件上传地址
 | 
	
		
			
				|  |  | +    uploadUrl: {
 | 
	
		
			
				|  |  | +      type: String,
 | 
	
		
			
				|  |  | +      default: `${process.env.VUE_APP_FILE_UPLOAD_API}`
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    // 请求头对象
 | 
	
		
			
				|  |  | +    uploadHeaders: {
 | 
	
		
			
				|  |  | +      type: Object,
 | 
	
		
			
				|  |  | +      default: () => {
 | 
	
		
			
				|  |  | +        return {
 | 
	
		
			
				|  |  | +          Authorization: 'Bearer ' + getToken()
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    // 上传文件标题
 | 
	
		
			
				|  |  | +    uploadFileTitle: {
 | 
	
		
			
				|  |  | +      type: String,
 | 
	
		
			
				|  |  | +      default: ''
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  data() {
 | 
	
		
			
				|  |  | +    return {
 | 
	
		
			
				|  |  | +      // 是否选择文件
 | 
	
		
			
				|  |  | +      isSelect: false,
 | 
	
		
			
				|  |  | +      // 是否上传文件成功
 | 
	
		
			
				|  |  | +      isUploadSuccess: false,
 | 
	
		
			
				|  |  | +      // 文件上传成功数据对象
 | 
	
		
			
				|  |  | +      successUrl: '',
 | 
	
		
			
				|  |  | +      // 文件上传成功数据对象
 | 
	
		
			
				|  |  | +      successResp: {},
 | 
	
		
			
				|  |  | +      removeLoading: false,
 | 
	
		
			
				|  |  | +      setTimeoutTimer: null
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  computed: {
 | 
	
		
			
				|  |  | +    // 文件上传地址
 | 
	
		
			
				|  |  | +    actionUrl() {
 | 
	
		
			
				|  |  | +      return this.uploadUrl;
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    // 请求头对象
 | 
	
		
			
				|  |  | +    headers() {
 | 
	
		
			
				|  |  | +      return this.uploadHeaders;
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    // 上传文件标题
 | 
	
		
			
				|  |  | +    fileTitle() {
 | 
	
		
			
				|  |  | +      if (this.uploadFileTitle) {
 | 
	
		
			
				|  |  | +        return `文件【${this.uploadFileTitle}】`;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      return '文件';
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  destroyed() {
 | 
	
		
			
				|  |  | +    this.setTimeoutTimer && clearTimeout(this.setTimeoutTimer);
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  | +  methods: {
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 文件上传预处理
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    handleRocImgFileUploadBeforeUpload(file) {
 | 
	
		
			
				|  |  | +      if(!['image/png', 'image/jpeg'].includes(file.type || '')){
 | 
	
		
			
				|  |  | +        this.$refs.rocImgFileUploadRef.clearFiles();
 | 
	
		
			
				|  |  | +        this.msgError(`${this.fileTitle}格式错误,请上传类型格式为jpg或png的图片文件!`);
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 文件上传成功处理
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    handleRocImgFileUploadOnsuccess(response, file, fileList) {
 | 
	
		
			
				|  |  | +      // 校验封面图片是否上传成功
 | 
	
		
			
				|  |  | +      if (response.code !== 200) {
 | 
	
		
			
				|  |  | +        this.$refs.rocImgFileUploadRef?.clearFiles?.();
 | 
	
		
			
				|  |  | +        this.isSelect = false;
 | 
	
		
			
				|  |  | +        this.isUploadSuccess = false;
 | 
	
		
			
				|  |  | +        this.msgError(`上传${this.fileTitle}失败,请重新选择图片文件上传!`);
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      let successUrl = `${window.origin}${process.env.VUE_APP_FILE_VIEW_API}${response?.data?.url}`;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 绑定封面图片数据
 | 
	
		
			
				|  |  | +      this.successUrl = successUrl;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // 文件上传成功数据对象
 | 
	
		
			
				|  |  | +      this.successResp = {
 | 
	
		
			
				|  |  | +        ...response?.data,
 | 
	
		
			
				|  |  | +        successUrl: successUrl
 | 
	
		
			
				|  |  | +      };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      this.$emit('input', response?.data?.url);
 | 
	
		
			
				|  |  | +      this.isUploadSuccess = true;
 | 
	
		
			
				|  |  | +      this.$alert(`${this.fileTitle}上传成功!`, '上传结果', { dangerouslyUseHTMLString: true });
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 文件状态改变
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    handleRocImgFileUploadOnchange(file, fileList) {
 | 
	
		
			
				|  |  | +      debugger;
 | 
	
		
			
				|  |  | +      console.log('(file.raw || {}).type===', (file.raw || {}).type || '');
 | 
	
		
			
				|  |  | +      if (file.status === 'ready') {
 | 
	
		
			
				|  |  | +        if(!['image/png', 'image/jpeg'].includes((file.raw || {}).type || '')){
 | 
	
		
			
				|  |  | +          this.$refs.rocImgFileUploadRef.clearFiles();
 | 
	
		
			
				|  |  | +          this.isSelect = false;
 | 
	
		
			
				|  |  | +          this.msgError(`${this.fileTitle}格式错误,请上传类型格式为jpg或png的图片文件!`);
 | 
	
		
			
				|  |  | +          return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        this.isSelect = true;
 | 
	
		
			
				|  |  | +        this.isUploadSuccess = false;
 | 
	
		
			
				|  |  | +        this.$emit('input', 'ROCIMGUPLOADSELECT');
 | 
	
		
			
				|  |  | +      } else if (file.status === 'success') {
 | 
	
		
			
				|  |  | +        this.isUploadSuccess = true;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        this.isUploadSuccess = false;
 | 
	
		
			
				|  |  | +        this.isSelect = false;
 | 
	
		
			
				|  |  | +        this.$emit('input', 'ROCIMGUPLOADSELECT');
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 文件列表移除文件时的钩子
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    handleRocImgFileUploadOnRemove(file, fileList) {
 | 
	
		
			
				|  |  | +      this.removeLoading = true;
 | 
	
		
			
				|  |  | +      this.setTimeoutTimer = setTimeout(() => {
 | 
	
		
			
				|  |  | +        this.successResp = {};
 | 
	
		
			
				|  |  | +        this.successUrl = '';
 | 
	
		
			
				|  |  | +        this.isUploadSuccess = false;
 | 
	
		
			
				|  |  | +        this.isSelect = false;
 | 
	
		
			
				|  |  | +        this.$emit('input', '');
 | 
	
		
			
				|  |  | +        this.setTimeoutTimer && clearTimeout(this.setTimeoutTimer);
 | 
	
		
			
				|  |  | +        this.removeLoading = false;
 | 
	
		
			
				|  |  | +      }, 900);
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 文件超出个数限制时的钩子
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    handleRocImgFileUploadOnExceed(files, fileList) {
 | 
	
		
			
				|  |  | +      this.msgWarning(`只允许上传单个${this.fileTitle}`);
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 提交上传相关材料文件
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    submitRocImgFileUploadClick() {
 | 
	
		
			
				|  |  | +      if (!this.isSelect) { return; }
 | 
	
		
			
				|  |  | +      this.$confirm(`确定上传${this.fileTitle}操作吗?`, '提示', {
 | 
	
		
			
				|  |  | +        confirmButtonText: '确定 ',
 | 
	
		
			
				|  |  | +        cancelButtonText: '取消 ',
 | 
	
		
			
				|  |  | +        type: 'info'
 | 
	
		
			
				|  |  | +      }).then(() => {
 | 
	
		
			
				|  |  | +        this.$refs.rocImgFileUploadRef?.submit?.();
 | 
	
		
			
				|  |  | +      }).catch(() => {
 | 
	
		
			
				|  |  | +        this.msgInfo('您已取消上传操作!');
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 移除选择相关材料文件
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    removeRocImgFileUploadClick() {
 | 
	
		
			
				|  |  | +      this.removeLoading = true;
 | 
	
		
			
				|  |  | +      this.$refs.rocImgFileUploadRef.clearFiles();
 | 
	
		
			
				|  |  | +      this.setTimeoutTimer = setTimeout(() => {
 | 
	
		
			
				|  |  | +        this.isSelect = false;
 | 
	
		
			
				|  |  | +        this.isUploadSuccess = false;
 | 
	
		
			
				|  |  | +        this.successResp = {};
 | 
	
		
			
				|  |  | +        this.successUrl = '';
 | 
	
		
			
				|  |  | +        this.$emit('input', '');
 | 
	
		
			
				|  |  | +        this.setTimeoutTimer && clearTimeout(this.setTimeoutTimer);
 | 
	
		
			
				|  |  | +        this.removeLoading = false;
 | 
	
		
			
				|  |  | +      }, 1000);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +</script>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +<style lang="scss">
 | 
	
		
			
				|  |  | +.rocimgfileupload {
 | 
	
		
			
				|  |  | +  .rocimgfileupload-attachment {
 | 
	
		
			
				|  |  | +    &-fileupload {
 | 
	
		
			
				|  |  | +      .el-upload {
 | 
	
		
			
				|  |  | +        width: 100%;
 | 
	
		
			
				|  |  | +        border: 1px dashed #d9d9d9;
 | 
	
		
			
				|  |  | +        border-radius: 6px;
 | 
	
		
			
				|  |  | +        cursor: pointer;
 | 
	
		
			
				|  |  | +        position: relative;
 | 
	
		
			
				|  |  | +        overflow: hidden;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        &:hover {
 | 
	
		
			
				|  |  | +          border-color: #409eff;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      .el-upload-list.el-upload-list--text {
 | 
	
		
			
				|  |  | +        .el-upload-list__item:first-child {
 | 
	
		
			
				|  |  | +          margin-top: 0;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      &-content {
 | 
	
		
			
				|  |  | +        width: 100%;
 | 
	
		
			
				|  |  | +        height: 32px;
 | 
	
		
			
				|  |  | +        font-size: 14px;
 | 
	
		
			
				|  |  | +        font-weight: 400;
 | 
	
		
			
				|  |  | +        color: #8c939d;
 | 
	
		
			
				|  |  | +        text-align: center;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    &-addr {
 | 
	
		
			
				|  |  | +      width: 100%;
 | 
	
		
			
				|  |  | +      padding: 5px 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      img {
 | 
	
		
			
				|  |  | +        max-width: 100px;
 | 
	
		
			
				|  |  | +        max-height: 100px;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +</style>
 |