el - 上传组件

<template>
<div class="freePic">
<!--  -->
	<el-upload
        class="avatar-uploader"
        :list-type="uploadType"
        :action="fileuploadUrl"
        :file-list="fileList"
        :before-upload="fileChange"
        :on-success="uploadSuccess"
        :on-error="uploadFiled"
        :on-exceed="overfileuploadNumber"
        :beforeRemove="fileBerofeRemove"
        :on-remove="fileRemove"
        :limit="limit"
        :disabled="!isShow"
        :on-preview="handlePictureCardPreview"
        :class="{hide:hideUpload}"
	>
    <i class="el-icon-upload"  v-if="isShow" style="font-size: 50px;line-height: 1.5;"><p style="font-size: 19px;font-weight: lighter">点击上传</p></i>
<!--    <el-button style="margin-left: 10px;" size="mini"  type="success" v-if="isShow" >点击上传</el-button>-->
	</el-upload>
  <div slot="tip" v-if="isShow" class="el-upload__tip">【请上传 {{this.suffixList.join('、')}} 文件, {{fileSize?'单个文件最大'+fileSize+'MB,':''}}<span style="color: red"> 上传{{limit?'最多'+limit:'可多'}}个</span>】</div>
    <!-- 图片放大展示 -->
    <el-dialog :visible.sync="dialogVisible">
        <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
</div>
</template>
<script>
import fileApi from '@/api/file-api';
export default {
	/* 图片展示 upload */
	name: "upload-pic-card",
    props: {
        /* v-model绑定的值 */
        value: {
            type: Array,
            default: () => []
        },
        /* 上传文件类型*/
        uploadType:{
          type: String,
          default: ''
        },
        //上传文件位置URL路径-分类
        uploadUrl: {
            type: String
        },
        /* 限制上传数量*/
        limit: {
            type: Number,
            default: null
        },
        /* 允许上传文件的后缀类型 */
        suffixList:{
          type:Array,
          default(){
            return []
          }
        },
        /* 允许上传文件的-大小 */
        fileSize:{
          type:Number,
          default: null
        },
        /* 是否服务端删除图片 */
        serverdel: {
            type: Boolean,
            default: true
        },
      disabled: {
        type: Boolean,
        default: false
      },
      isShow:{
        type: Boolean,
        default: false
      }
    },
	data() {
		return {
			dialogImageUrl: "",//展示地址链接
			dialogVisible: false,
      fileList: this.value,
      fileuploadUrl: fileApi.uploadFiles( `uploadChildPath=${this.uploadUrl}`), // 上传文件地址
		};
	},
  computed: {
    // 上传张数大于限制张数的时候将上传框隐藏
    hideUpload() {
      return !this.isShow;
    }
  },
     watch: {
        value: function(n) {
            this.fileList = n
            // 修改 v-model 数据
            this.$emit('input', n)
        },
    },
  methods: {
        //放大展示
		handlePictureCardPreview(file) {
			// this.dialogImageUrl = file.url;
			// this.dialogVisible = true;
      this.$emit("preview",file.url);
		},
         // 上传文件 改变时
         // 文件上传成功
        uploadSuccess(response, file, fileList) {
		      this.$emit("warrantySuccess",response)
          this.$emit('repairSuccess',response)
          this.$emit('upkeepSuccess',response)
            const { raw } = file
            const { data,  success} = response
            const { type } = raw;
            if(success && data) {
              data.map(item=>this.fileList.push({name: item.fileName, url: item.url, type: 'image'}))
                // this.fileList.push({name: data[0].fileName, url: data[0].url, type: 'image'})
                this.$message({message: '文件上传成功', type: 'success',duration: 2000})
            } else {
                this.$message({message: '文件上传失败', type: 'warning',duration: 2000})
                fileList.pop()
            }
            // this.loading = false
            // 修改 v-model 数据
            this.$emit('input', this.fileList)
            if (this.limit&&this.fileList.length >= this.limit) {
              document.getElementsByClassName('el-upload--picture-card')[0].style.display = 'none';
            }
        },
        // 图片改变时大小类型验证
        fileChange(file) {
            // if(file.status === "ready") {
                // 文件准备就绪未上传
                /*
                    image/jpeg
                    image/png
                    const isJPG = file.type === 'image/jpeg';
                */
                const FileExt = file.name.replace(/.+\./, "");
                const isLt5M = this.fileSize?file.size / 1024 / 1024 > this.fileSize:false;
                if (this.suffixList.length>0&&this.suffixList.toString().toLowerCase().indexOf(FileExt.toLowerCase()) === -1) {
                  this.$message({
                    type: 'warning',
                    message: `请上传后缀名为${this.suffixList.join(',')}文件!`
                  });
                  return false;
                }else {
                    if(isLt5M) {
                        this.$notify.error({
                            title: '异常',
                            message: `上传图片大小不能超过 ${this.fileSize}MB!`,
                            duration: 2000
                        });
                        return false
                    }else {
                      return true
                    }
                }
            // }
        },
        // 文件超出上传个数
        overfileuploadNumber(file, fileList) {
            this.$notify.error({
                title: '异常',
                message: `文件最多上传${fileList.length}个`,
                duration: 2000
            });
        },
        // 文件在列表被移除前
        async fileBerofeRemove(file, fileList) {
            if(file.status === 'success') {
              // console.log(!this.serverdel)
                return new Promise((resvole, reject) => {
                    if(!this.serverdel) {
                        resvole()
                        return
                    }
                    this.$confirm('该操作删除文件后不可找回,请谨慎操作?', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }).then(res =>{
                        Promise.all([fileApi.delServerFile({url: file.url}), file.id? fileApi.delete({id: file.id}):'']).then(res => {
                            const [resOne, resTwo] = res;
                            this.$message({type: 'success', message: '文件删除成功',duration: 2000})
                            resvole()
                        }).catch(err => {
                            this.$message({type: 'error', message: '文件删除失败',duration: 2000})
                            reject()
                        })
                    }).catch(err => console.log(err))
                })
            }
            if(file.status === "uploading") {
                this.$message({type: 'warning', message: '文件上传被取消',duration: 2000})
                // this.loading = false
            }
        },
         // 文件在列表被移除后
        fileRemove(file, fileList) {
          // this.fileList = this.fileList.filter(item => item.uid !== file.uid); // 删除时候过滤掉被删除的内容
            /*const index = this.fileList.findIndex(item => item.uid === file.uid)
            this.fileList.splice(index, 1)*/
            this.fileList=fileList
            // 修改 v-model 数据
            this.$emit('input', this.fileList)
            if (this.fileList.length>0&&this.fileList.length < this.limit) {
              document.getElementsByClassName('el-upload--picture-card')[0].style.display='';
            }
        },
        // 文件上传失败
        uploadFiled(err, file, fileList) {
            this.$message({message: '文件上传失败', type: 'warning',duration: 2000})
            this.loading = false
        },
        //获取文件名称
        getFileName(url) {
          let name = "";
          if (url && url !== "") {
            name = url.substring(url.lastIndexOf("/") + 1);
          } else {
            name = "无";
          }
          return name;
        },

	},
};
</script>
<style lang="scss" scoped>

.freePic ::v-deep .hide .el-upload--picture-card {
  display: none;
}
  .avatar-uploader .el-upload {
      border: 1px dashed #d9d9d9;
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
  }
  .avatar-uploader .el-upload:hover {
      border-color: #409EFF;
  }
  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 100px;
    height: 100px;
    line-height: 100px;
    text-align: center;
  }
  .avatar {
    width: 100px;
    height: 100px;
    display: block;
  }
</style>

2. 调用

<uploadPicAcard uploadUrl="userDows/goods/test" v-model="goodsImgUrlList" :fileSize="5" :suffixList="suffixList_1" :uploadType="'picture-card'" :limit="8" :isShow="viewType" @preview="preview"/>

 // 文件预览组件 
 <FilePreviewComp ref="fpc"></FilePreviewComp>


import FilePreviewComp from "@/components/file-preview";
export default {
    name: 'goods-info-page',
    data() {
        return {
            suffixList_1:['jpg','png'],
             /* 货物图片 */
            goodsImgUrlList: [],
            viewType:false,
components: {FilePreviewComp },

    methods: {
      //文件预览 (1. 需要添加class:【message_box_alert】)
      preview(val){
        this.$refs.fpc.preview(val);
      },
    }

 3. 预览组件 (创建组件)

<style>
.el-dialog--center .el-dialog__body{
  padding: 0 30px;
}
.el-dialog__body {
  padding: 0;
  overflow-y: auto;
  height: calc(100vh - 50px) !important;
}
</style>

<template>
	<div v-if="typeS == '1'">
    <el-dialog
        :visible.sync="dialogFormVisible"
        :close-on-click-modal="false"
        :destroy-on-close="dialogDestroy"
        :fullscreen="true"
        width="100%"
        center>
      <h1 slot="title" class="title-h1">{{title}}</h1>
      <iframe width="100%" height="98%" :src="previewUrl"/>
    </el-dialog>
	</div>

  <div v-else-if="typeS == '2'">
    <viewimg-comp ref="viewimgcomp" :options="{image: previewUrl, smallImgShow: false, imgHeight: '40px'}" ></viewimg-comp>
  </div>

  <div v-else>
    <el-dialog
        :visible.sync="dialogFormVisible"
        :close-on-click-modal="false"
        :destroy-on-close="dialogDestroy"
        :fullscreen="true"
        center
    >
      <h1 slot="title" class="title-h1">{{title}}</h1>
      <iframe width="100%" height="98%" :src="previewUrl"/>
    </el-dialog>
  </div>
</template>



<script>

import {matchType} from "@/utils/utils";
import fileApi from "@/api/file-api";

export default {
  props:{
   /* previewUrl: {
      type: String,
      default: ''
    },*/
  },
  data(){
    return {
      title:'文件预览',
      typeS:'0',
      dialogDestroy:true,
      dialogFormVisible: false,
      previewUrl:'',
    }
  },
  mounted() {
  },
  methods: {
  /*  preview(val){
      // 这里需要取下 html 的高度,因为浏览器有默认的 margin
      const html = document.body.parentElement
      const scrollHeight = `${html ? html.scrollHeight-130 : document.body.scrollHeight-130}px`
      // const scrollWidth = `${html ? html.scrollWidth : document.body.scrollWidth}px`
      this.$alert(`<iframe style="padding: 0;margin: 0" width="100%" height="${scrollHeight}" src="${fileApi.onlinePreview(val)}"/>` , '预览', {
        dangerouslyUseHTMLString: true,
        customClass:'message_box_alert'
      });
    },*/
    // 文件预览
    preview(val){
      if (matchType(val) === "pdf"){
        this.typeS='1'
        this.previewUrl=val;
      }else if (matchType(val) === "image"){
        this.typeS='2'
        this.previewUrl=val;
        // 调用子组件的方法
        setTimeout(() => {
          return this.$refs.viewimgcomp.show()
        }, 100);
      }else {
        this.previewUrl=`https://view.officeapps.live.com/op/view.aspx?src=${val}`
      }
      this.dialogFormVisible = true
    }
  }
}


</script>
<style lang="scss" scoped>
/*.message_box_alert {
  word-break: break-all !important;
  width: 100%;
}*/
.title-h1{
  font-size: 17px;
  color: #000000;
}
</style>

/*根据文件名后缀区分 文件类型*/
export const matchType = fileName => {
    // 后缀获取
    var suffix = '';
    // 获取类型结果
    var result = '';
    try {
        var flieArr = fileName.split('.');
        suffix = flieArr[flieArr.length - 1].toLowerCase();
    } catch (err) {
        suffix = '';
    }
    // fileName无后缀返回 false
    if (!suffix) {
        result = false;
        return result;
    }
    // 图片格式
    var imglist = ['png', 'jpg', 'jpeg', 'bmp', 'gif'];
    // 进行图片匹配
    result = imglist.some(function (item) {
        return item == suffix;
    });
    if (result) {
        result = 'image';
        return result;
    };
    // 匹配txt
    var txtlist = ['txt'];
    result = txtlist.some(function (item) {
        return item == suffix;
    });
    if (result) {
        result = 'txt';
        return result;
    };
    // 匹配 excel
    var excelist = ['xls', 'xlsx'];
    result = excelist.some(function (item) {
        return item == suffix;
    });
    if (result) {
        result = 'excel';
        return result;
    };
    // 匹配 word
    var wordlist = ['doc', 'docx'];
    result = wordlist.some(function (item) {
        return item == suffix;
    });
    if (result) {
        result = 'word';
        return result;
    };
    // 匹配 pdf
    var pdflist = ['pdf'];
    result = pdflist.some(function (item) {
        return item == suffix;
    });
    if (result) {
        result = 'pdf';
        return result;
    };
    // 匹配 ppt
    var pptlist = ['ppt'];
    result = pptlist.some(function (item) {
        return item == suffix;
    });
    if (result) {
        result = 'ppt';
        return result;
    };
    // 匹配 视频
    var videolist = ['mp4', 'm2v', 'mkv'];
    result = videolist.some(function (item) {
        return item == suffix;
    });
    if (result) {
        result = 'video';
        return result;
    };
    // 匹配 音频
    var radiolist = ['mp3', 'wav', 'wmv'];
    result = radiolist.some(function (item) {
        return item == suffix;
    });
    if (result) {
        result = 'radio';
        return result;
    }
    // 其他 文件类型
    result = 'other';
    return result;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

oh LAN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值