<template> 
 | 
    <div class="file"> 
 | 
        <div class="file_list"> 
 | 
            <div class="file_list_item" :style="{width: width, height: height}" v-for="(item, index) in list" :key="index"> 
 | 
                <div class="dele" @click="deleItem(index)"> 
 | 
                    <i class="el-icon-close"></i> 
 | 
                </div> 
 | 
                <img :src="item.url" v-if="fileType(item.url) === 'img'" /> 
 | 
                <video controls autoplay :src="item.url" v-else></video> 
 | 
            </div> 
 | 
            <div class="file_list_item" :style="{width: width, height: height, cursor: 'pointer'}" @click="$refs.file.click()"> 
 | 
                <i class="el-icon-plus"></i> 
 | 
            </div> 
 | 
        </div> 
 | 
        <div style="display: block;"> 
 | 
          <input type="file" ref="file" :accept="accept" @change="getFile" /> 
 | 
<!--          <progress id="progressBar" value="0" max="100" ></progress>--> 
 | 
<!--          <span id="status">0%</span>--> 
 | 
        </div> 
 | 
    </div> 
 | 
</template> 
 | 
  
 | 
<script> 
 | 
import axios from 'axios' 
 | 
export default { 
 | 
  props: { 
 | 
    width: { 
 | 
      type: String, 
 | 
      default: '90px' 
 | 
    }, 
 | 
    height: { 
 | 
      type: String, 
 | 
      default: '90px' 
 | 
    }, 
 | 
    list: { 
 | 
      type: Array, 
 | 
      // eslint-disable-next-line vue/require-valid-default-prop 
 | 
      default: [] 
 | 
    }, 
 | 
    accept: { 
 | 
      type: String, 
 | 
      default: '' 
 | 
    }, 
 | 
    folder: { 
 | 
      type: String, 
 | 
      default: '' 
 | 
    } 
 | 
  }, 
 | 
  data () { 
 | 
    return { 
 | 
      loading:null, 
 | 
      uuid: null, 
 | 
      timer: null, 
 | 
      message:'开始上传', 
 | 
      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/visitsAdmin/cloudService/public/upload', 
 | 
      uploadProgressUrl: process.env.VUE_APP_API_PREFIX + '/public' 
 | 
    } 
 | 
  }, 
 | 
  
 | 
  methods: { 
 | 
    fileType (url) { 
 | 
      if (url.indexOf('.mp4') !== -1) { 
 | 
        return 'video' 
 | 
      } else { 
 | 
        return 'img' 
 | 
      } 
 | 
    }, 
 | 
    getFile (e) { 
 | 
      if (e.target && e.target.files.length > 0) { 
 | 
        var that = this 
 | 
        const config = { 
 | 
          onUploadProgress: function (progressEvent) { 
 | 
            console.log(progressEvent) 
 | 
            const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total) 
 | 
            // document.getElementById('progressBar').value = percentCompleted 
 | 
            // document.getElementById('status').textContent = '准备' + percentCompleted + '%' 
 | 
            that.loading.setText('上传中【 ' + percentCompleted + ' 】%') 
 | 
          }, 
 | 
          headers: { 
 | 
            'Content-Type': 'multipart/form-data' 
 | 
          } 
 | 
        } 
 | 
        this.loading = this.$loading({ 
 | 
          lock: true, 
 | 
          text: '上传中,请等待', 
 | 
          spinner: 'el-icon-loading', 
 | 
          customClass: 'loadingclz', 
 | 
          background: 'rgba(0, 0, 0, 0.7)' 
 | 
        }) 
 | 
        this.$emit('loading') 
 | 
        const formdate = new FormData() 
 | 
        this.uuid = this.generateUUID().replaceAll('-', '') 
 | 
        formdate.append('file', e.target.files[0]) 
 | 
        formdate.append('folder', this.folder) 
 | 
        formdate.append('uuid', this.uuid) 
 | 
        axios.post(this.uploadImgUrl, formdate, config) 
 | 
          .then(res => { 
 | 
            if(res.data.data == null || res.data.data.imgaddr == null){ 
 | 
              this.$message.error('数据上传失败!') 
 | 
            }else{ 
 | 
              this.$emit('success', res.data.data) 
 | 
            } 
 | 
          }) 
 | 
          .catch(e => { 
 | 
            if(this.timer){ 
 | 
              clearInterval(this.timer) 
 | 
            } 
 | 
            this.$message.error(e) 
 | 
          }) 
 | 
          .finally(() => { 
 | 
            if(this.timer){ 
 | 
              clearInterval(this.timer) 
 | 
            } 
 | 
            that.loading.close() 
 | 
            this.$refs.file.value = null 
 | 
          }) 
 | 
        this.startProgress() 
 | 
      } 
 | 
    }, 
 | 
    startProgress () { 
 | 
    }, 
 | 
    generateUUID () { 
 | 
      return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 
 | 
        const r = (Math.random() * 16) | 0 
 | 
        const v = c === 'x' ? r : (r & 0x3) | 0x8 
 | 
        return v.toString(16) 
 | 
      }) 
 | 
    }, 
 | 
    deleItem (index) { 
 | 
      this.$emit('dele', index) 
 | 
    } 
 | 
  } 
 | 
} 
 | 
</script> 
 | 
<style> 
 | 
  .loadingclz { 
 | 
    .el-loading-text{ 
 | 
      font-size: 18px  !important; 
 | 
      color: #2977f8 !important; 
 | 
    } 
 | 
   .el-loading-spinner i { 
 | 
      color: #2977f8 !important; 
 | 
    } 
 | 
  } 
 | 
</style> 
 | 
<style lang="scss" scoped> 
 | 
    .file { 
 | 
        /*width: 100%;*/ 
 | 
        /*height: 90px;*/ 
 | 
      padding: 10px; 
 | 
      box-sizing: border-box; 
 | 
      display: flex; 
 | 
      align-items: center; 
 | 
      justify-content: space-between; 
 | 
      position: relative; 
 | 
      margin-bottom: 10px; 
 | 
      /* margin-right: 20px; */ 
 | 
       /* margin: 10px 0;*/ 
 | 
        input { 
 | 
            opacity: 0; 
 | 
        } 
 | 
        .file_list { 
 | 
            width: 100%; 
 | 
            height: 100%; 
 | 
            display: flex; 
 | 
            align-items: center; 
 | 
            flex-wrap: wrap; 
 | 
            .file_list_item { 
 | 
                display: flex; 
 | 
                flex-direction: column; 
 | 
                align-items: center; 
 | 
                justify-content: center; 
 | 
                overflow: hidden; 
 | 
                border-radius: 5px; 
 | 
                border: 1px solid #d5d5d5; 
 | 
                margin-left: 15px; 
 | 
                position: relative; 
 | 
                &:first-child { 
 | 
                    margin: 0 !important; 
 | 
                } 
 | 
                .dele { 
 | 
                    position: absolute; 
 | 
                    right: 0; 
 | 
                    top: 0; 
 | 
                    width: 20px; 
 | 
                    height: 20px; 
 | 
                    background: red; 
 | 
                    display: flex; 
 | 
                    align-items: center; 
 | 
                    justify-content: center; 
 | 
                    cursor: pointer; 
 | 
                    .el-icon-close { 
 | 
                        color: #ffffff; 
 | 
                        font-size: 19px; 
 | 
                    } 
 | 
                } 
 | 
                .el-icon-plus { 
 | 
                    font-size: 30px; 
 | 
                    color: black; 
 | 
                } 
 | 
                img { 
 | 
                    width: 100%; 
 | 
                } 
 | 
                video { 
 | 
                    width: 100%; 
 | 
                    height: 100%; 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
</style> 
 |