封装组件——上传文件(vue+element)

<template>
  <div :id="fileId + '_upfile'"
       v-if="!readOnly"
       :style="'min-width:' + 'px;color:#999'">
    <el-popover v-if="showHepl && !disabled"
                class="hepl"
                placement="top-start"
                trigger="hover">
      <slot name="template"></slot>
      <i type="info"
         slot="reference"
         v-if="showHepl"
         class="hand el-icon-question "></i>
    </el-popover>
    <el-upload :style="buttonSty"
               class="upload-demo uploadinfo"
               :name="FileName"
               :action="action"
               :on-progress="onprogress"
               :on-success="onsuccess"
               :on-error="onerror"
               :with-credentials="true"
               :show-file-list="false"
               :headers="myheaders"
               v-if="!disabled"
               :before-upload="beforeAvatarUpload"
               accept=".doc,.docx,.txt,.xls,.xlsx,.jpg,.png,.jpep,.pdf,.zip,.rar,.mp4,.ogg,.flv,.avi,.wmv,.rmvb">
      <template v-if="!materialDown"
                :style="buttonSty">
        <!-- <div :style="buttonSty"> -->
        <el-button size="mini"
                   :type="buttonType">
          <i class="el-icon-upload2"></i> {{ !hasfileUid ? '上传文件' : multiple ? '继续上传' : '修改上传' }}
        </el-button>
        <p class="el-upload__tip"
           slot="tip">
          支持扩展名:.doc,.docx,.txt,.xls,.xlsx,.jpg,.png,.jpep,.pdf,.zip,.rar,.mp4,.ogg,.flv,.avi,.wmv,.rmvb
        </p>
        <!-- </div> -->
      </template>
      <el-button size="small"
                 type="primary"
                 plain
                 v-else> 导入 </el-button>
    </el-upload>
    <!-- <template v-if="multiple&&!disabled"><span class="tips">3个及以上附件请打包上传!</span></template> -->
    <template v-if="hasfileUid && !materialDown">
      <div style="display:flex">
        <!-- <template v-if="downFileInfo.length>=2&&disabled">
          <el-button size="mini"
                     type="success"
                     @click="downAll"
                     plain
                     style="margin-right:20px"> 批量下载</el-button>
        </template> -->

        <div style="flex:1; min-height:32px;line-height:32px; border:1px solid rgba(233,238,240,1);background:rgba(251,252,253,1);border-radius:4px;">
          <template v-for="item in downFileInfo">
            <!-- <div :style="' width:'+(width-20)+'px;   overflow: hidden;  white-space: nowrap;  text-overflow: ellipsis;float:left'"> -->
            <div style="display:flex;position:relative"
                 :key="item.id">
              <!-- @click="zxyl(item.id,item.name)" -->
              <div class="imgpat hand"
                   style="flex:1"
                   title="在线预览"
                   @click="zxyl(item.id, item.name)">
                <!-- <el-tag hit disable-transitions>{{item.name.substring(item.name.lastIndexOf(".") + 1).toUpperCase()}}</el-tag>  -->
                <template v-if="
                    'PPT,PPTX,PPS,PPSX'.indexOf(item.name.substring(item.name.lastIndexOf('.') + 1).toUpperCase()) > -1
                  ">
                  <img src="@/assets/attechmentIcon/PPT.png"
                       height="20px" />
                </template>
                <template v-else-if="
                    'PNG,JPG,JPEG,GIF,BNP'.indexOf(item.name.substring(item.name.lastIndexOf('.') + 1).toUpperCase()) >
                      -1
                  ">
                  <img src="@/assets/attechmentIcon/PHOTO.png"
                       height="20px" />
                </template>
                <template v-else-if="
                    'DOC,DOCX,WPS'.indexOf(item.name.substring(item.name.lastIndexOf('.') + 1).toUpperCase()) > -1
                  ">
                  <img src="@/assets/attechmentIcon/WORD.png"
                       height="20px" />
                </template>
                <template v-else-if="
                    'XLS,XLSX,CSV'.indexOf(item.name.substring(item.name.lastIndexOf('.') + 1).toUpperCase()) > -1
                  ">
                  <img src="@/assets/attechmentIcon/ECEL.png"
                       height="20px" />
                </template>
                <template v-else-if="'PDF'.indexOf(item.name.substring(item.name.lastIndexOf('.') + 1).toUpperCase()) > -1">
                  <img src="@/assets/attechmentIcon/PDF.png"
                       height="20px" />
                </template>
                <template v-else-if="
                    'ZIP,RAR,7Z'.indexOf(item.name.substring(item.name.lastIndexOf('.') + 1).toUpperCase()) > -1
                  ">
                  <img src="@/assets/attechmentIcon/ZIP.png"
                       height="20px" />
                </template>
                <template v-else-if="
                    'mp4,ogg,flv,avi,wmv,rmvb'.indexOf(
                      item.name.substring(item.name.lastIndexOf('.') + 1).toUpperCase(),
                    ) > -1
                  ">
                  <img src="@/assets/attechmentIcon/OTHER.png"
                       height="20px" />
                </template>
                <template v-else>
                  <img src="@/assets/attechmentIcon/OTHER.png"
                       height="20px" />
                </template>
                <div href="#"
                     :style="
                    `margin-left:42px;white-space: nowrap;  text-overflow:ellipsis; overflow:hidden;color:#409EFF;width:${divwidth -
                      (divwidth >= 650 ? 440 : 140)}px`
                  ">
                  {{ item.name }}
                </div>
              </div>
              <div v-if="divwidth >= 650"
                   style="width:100px;text-align:right;color:#999">
                {{ (item.size / 1024).toFixed(0) }}K
              </div>
              <div v-if="divwidth >= 650"
                   style="width:250px;text-align:center;color:#999">{{ item.created }}</div>
              <div style="color:#409EFF;"
                   class="operateList"
                   :style="{ width: disabled ? '30px' : '60px' }">
                <i class="iconfont icon-xiazai mr10 hand"
                   title="下载"
                   @click="downFile(item.id, item.name)"></i>
                <i class="iconfont icon-iconfont-shanchu hand"
                   v-if="!disabled"
                   title="删除"
                   :style="{ cursor: disabled ? 'not-allowed' : '' }"
                   @click="disabled ? '' : onremove(item.id)"></i>
              </div>
            </div>
          </template>
        </div>
      </div>
    </template>
    <template v-if="!hasfileUid && !materialDown">
      <div style="border:1px solid rgba(233,238,240,1);background:rgba(251,252,253,1);border-radius:4px;margin-top:0px">
        <el-button size="mini"
                   style="padding:0px 12px;"
                   disabled
                   type="text">暂无附件</el-button>
      </div>
    </template>

    <!-- <el-dialog title="图片预览"
               :visible.sync="show"
               width="700"
               append-to-body>
      <div v-if="show"
           :style="boxStyle">
        <img :style="styleObject"
             :src="imgSrc"
             ref="img" />

      </div>
      <div slot="footer">
        <el-button @click="xz">旋转</el-button>
      </div>
    </el-dialog> -->
  </div>
  <div v-else-if="readOnly">
    {{ downFileInfo.map((r) => r.name).join(',') }}
  </div>
</template>

<script>
import { getAuthorization, getSystemUid } from "@/plugins/auth.js";

export default {
  name: "UpFile",
  model: {
    prop: "fileUid",
    event: "changeUid",
  },
  props: {
    fileUid: {
      type: String,
    },
    action: {
      type: String,
      default: process.env.VUE_APP_PublicPath + "api/attachment/fileUpload",
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },

    width: {
      type: Number,
      default: 300,
    },
    showDownload: {
      type: Boolean,
      default: false,
    },
    materialDown: {
      type: Boolean,
      default: false,
    },
    readOnly: {
      type: Boolean,
      default: false,
    },
    limitSize: {
      type: Number,
      default: 100,
    },
    filterFileName: {
      type: Boolean,
      default: false,
    },
    buttonType: {
      type: String,
      default: "",
    },
    buttonSty: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      fileId: "",
      divwidth: 0,
      showHepl: false,
      boxStyle: {
        "text-align": "center",
        "align-items": "center",

        display: "flex",
        width: "100%",
        maxHeight: "50vh",
        overflow: "auto",
      },
      styleObject: {
        transform: "rotate(0deg)",
        Width: "100%",
        // maxHeight: "100%"
      },
      hasfileUid: false,
      fileList: [],
      myheaders: {
        Authorization: getAuthorization(),
        SystemUid: getSystemUid(),
      },
      FileName: "fileName",
      downurl: "",
      name: "",
      downFileName: "",
      loadingUp: null,
      downFileUids: null,
      downFileInfo: [],
      imgSrc: "",
      show: false,
      deg: 0,
    };
  },
  methods: {
    xz() {
      this.deg = this.deg + 90;
      let width = this.$refs.img.width;
      let height = this.$refs.img.height;
      this.styleObject.width = width + "px";
      this.styleObject.height = height + "px";
      if ((this.deg / 90) % 2 != 0) {
        this.boxStyle.width = height + "px";
        this.boxStyle.height = width + "px";
      } else {
        this.boxStyle.width = width + "px";
        this.boxStyle.height = height + "px";
      }

      this.styleObject.transform = `rotate(${this.deg}deg)`;
    },
    onprogress(event) {
      this.loadingUp.text = "附件上传中(" + event.percent.toFixed(2) + "%)";
    },

    onsuccess(response) {
      if (!response) {
        this.fileList = [];
        this.$message({
          type: "error",
          message: "上传错误",
        });
        this.loadingUp.close();
        return;
      }

      // this.name = response.result.path.split("\\").reverse()[0];
      this.$message({
        message: "附件上传成功",
        type: "success",
        duration: 2000,
      });
      this.$emit("clearrules");
      this.loadingUp.close();
      if (this.multiple) {
        this.downFileUids.push(response);
        // this.downFileInfo.push({
        //   id: response.result.id,
        //   name: response.result.fileName,
        //   created: response.result.created,
        //   size: response.result.fileSize
        // });
      } else {
        this.downFileUids = [response];
        // this.downFileInfo = [
        //   {
        //     id: response.result.id,
        //     name: response.result.fileName,
        //     created: response.result.created,
        //     size: response.result.fileSize
        //   }
        // ];
      }
      this.$emit("changeUid", this.downFileUids.join(","));
      this.$emit("onChange", this.downFileUids.join(","));

      // this.$emit("changeUid", response.result.id);
    },
    onerror(err) {
      this.$message({
        type: "error",
        message: "上传出错请重试!",
      });
      this.loadingUp.close();
    },
    onremove(uid) {
      //   this.fileList = [];
      this.$confirm("是否删除?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        for (let i = 0; i < this.downFileUids.length; i++) {
          if (this.downFileUids[i] == uid) {
            this.downFileUids.splice(i, 1);
          }
        }
        this.$emit("changeUid", this.downFileUids.join(","));
        this.$emit("onRemove", this.downFileUids.join(","));
      });
    },
    downFile(id, name) {
      var a = document.createElement("a"); // 转换完成,创建一个a标签用于下载
      a.download = name;
      a.href =
        process.env.VUE_APP_PublicPath + "api/attachment/download?md5=" + id;
      a.target = "_blank";
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);

      return false;
    },

    //预览
    zxyl(id, name) {
      // let fileSrc = `${
      //   window.location.origin
      // }/dc/api/attachment/download?md5=${id}&fullfilename=aaaa${name.substring(
      //   name.lastIndexOf(".")
      // )}`;
      let fileSrc = `http://127.0.0.1:8050/dc/api/attachment/download?md5=${id}&fullfilename=aaaa${name.substring(
        name.lastIndexOf(".")
      )}`;
      window.open(
        process.env.VUE_APP_OnlinePreview +
          "/onlinePreview?url=" +
          encodeURIComponent(fileSrc)
      );
    },
    reloadfinish() {
      //  debugger;
      if (this.fileUid && this.fileUid.length > 0) {
        this.hasfileUid = true;
        this.downFileUids = this.fileUid.split(",");
        this.downFileInfo = [];
        this.downFileUids.forEach((ele) => {
          this.$getAction("/attachment/get", {
            md5: ele,
          }).then((res) => {
            this.downFileInfo.push({
              id: res.md5,
              name: res.fileName,
              created: res.created,
              size: res.fileSize,
            });
            this.$emit(
              "update:fileName",
              this.filterFileName
                ? res.fileName
                : res.fileName.substring(0, res.fileName.lastIndexOf("."))
            );
          });
        });
        // this.downurl =
        //   process.env.VUE_APP_BaseUrl + "/Login/download?attachmentId=" + this.fileUid;
        // this.getFileInfo();
      } else {
        this.hasfileUid = false;
        this.downFileInfo = [];
        this.downFileUids = [];
      }
    },
    beforeAvatarUpload(file) {
      this.loadingUp = this.$loading({
        lock: true,
        text: "附件上传中(0%)",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)",
      });
      const isLt2M = file.size / 1024 / 1024 < this.limitSize;
      console.log(file.size / 1024 / 1024, this.limitSize);
      if (!isLt2M) {
        this.$message.error(`上传附件大小不能超过 ${this.limitSize}MB!`);
        this.loadingUp.close();
        return false;
      }
    },
    getGuid() {
      function S4() {
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
      }
      return (
        S4() +
        S4() +
        "-" +
        S4() +
        "-" +
        S4() +
        "-" +
        S4() +
        "-" +
        S4() +
        S4() +
        S4()
      );
    },
  },
  watch: {
    fileUid() {
      this.reloadfinish();
    },
  },
  mounted() {
    // this.downurl =
    //   process.env.VUE_APP_BaseUrl + "/Login/download?attachmentId=" + this.fileUid;
    this.reloadfinish();
    if (!this.readOnly) {
      this.$nextTick(() => {
        this.divwidth = document.getElementById(
          this.fileId + "_upfile"
        ).offsetWidth;
        this.divwidth = this.divwidth > 800 ? 800 : this.divwidth;
      });
    }
  },
  created() {
    this.fileId = this.getGuid();
    let templateSlot = this.$slots.template;
    if (templateSlot && templateSlot.length > 0) {
      this.showHepl = true;
    }
  },
};
</script>
<style scoped>
.UpFile {
  width: 100%;
}
.tips {
  color: orange;
}
</style>

<style>
.UpFile .el-upload {
  height: 100%;
  width: 100%;
  text-align: center;
  /* background: beige; */
  /* display: block; */
  /* margin: 0 auto; */
}

#popTip {
  margin: 0;
  padding: 0;
  position: absolute;
  left: 0;
  top: 0;
}
.el-form-item__content a {
  line-height: 18px;
  max-width: 300px;
  color: blue;
}

.ml20 {
  margin-left: 20px;
}

.showDownload {
  margin-left: 20px;
}

.hepl {
  position: absolute;
  margin-left: 100px;
  font-size: 150%;
  color: #a4cef9;
}
.imgpat img {
  position: absolute;
  margin-top: 6px;
  padding-left: 10px;
}
</style>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值