大文件分片上传(带进度条)组件

1. 父文件
<template>
<div id="filePicker">选择文件</div>
      <div class="file-panel">
        <!-- <h2>文件列表</h2> -->
        <div class="file-list">
          <el-table class="imageContrast"
                    :data="fileList"
                    height="100%"
                    ref="table"
                    stripe
                    :element-loading-text="$t('base.table.loading')"
                    element-loading-spinner="el-icon-loading"
                    element-loading-background="rgba(255, 255, 255, 0.8)"
                    :headerRowStyle="{background:'#ebeef5;'}">
            <el-table-column prop="name"
                             show-overflow-tooltip
                             label="文件名称"
                             min-width="25%">
              <template v-slot="scope">
                <!-- <div class="line1"
                     :tilte="scope.row.name"> {{scope.row.name}}</div> -->
                {{scope.row.name}}
              </template>
            </el-table-column>
            <el-table-column prop="createTime"
                             label="文件大小"
                             min-width="20%">
              <template v-slot="scope">
                {{fileSize(scope.row.size)}}
              </template>
            </el-table-column>
            <el-table-column prop="userName"
                             label="上传进度"
                             min-width="50%"
                             class-name="tabStatus">
              <template v-slot="scope">
                <div class="progress"
                     :class="`progress-${scope.row.id}`"></div>
                <div class="file-status"
                     :class="`file-status-${scope.row.id}`"></div>
              </template>
            </el-table-column>
            <el-table-column label="文件状态"
                             prop="status"
                             min-width="25%">
              <!-- <template v-slot="scope">
                {{scope.row.status}}
              </template> -->
              <template v-slot="scope">
                <div class="file-upload"
                     :class="`file-upload-${scope.row.id}`">等待上传...</div>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
      <vueUpload ref="uploader"
                 url="/gateway/sxdl-server/large/file/upload"
                 uploadButton="#filePicker"
                 multiple
                 @anylise="anylise"
                 @anyliFail="anyliFail"
                 @fileChange="fileChange"
                 @progress="onProgress"
                 @success="onSuccess"></vueUpload>
</template>
<script>
import vueUpload from "../dialogs/vue-upload.vue";
export default {
	components:{
		vueUpload,
	}
	data(){
		return{
			
		}
	}
	method(){
		//大文件上传文件列表改变
    fileChange(file) {
      if (!file.size) return;
      // debugger
      $(`.file-upload-${file.id}`).html("等待上传...");
      this.fileList.push(file);
    },
    anylise(file) {
      $(`.file-upload-${file.id}`).html("上传解析成功");
    },
    onProgress(file, percent) {
      // debugger
      $(`.file-upload-${file.id}`).html("上传中...");
      $(`.file-${file.id} .progress`).css("width", percent * 20 + "%");
      $(`.file-${file.id} .file-status`).html((percent * 100).toFixed(2) + "%");
      $(`.progress-${file.id}`).css("width", percent * 100 + "%");
      $(`.file-status-${file.id}`).html((percent * 100).toFixed(2) + "%");
    },
    anyliFail(file) {
      $(`.file-upload-${file.id}`).html("解析失败");
    },
    onSuccess(file, response) {
      $(`.file-upload-${file.id}`).html("解析中...");
      console.log(file, response);
      if (response.needMerge) {
        api
          .mergeUpload({
            tempName: response.tempName,
            fileName: file.name,
          })
          .then((res) => {
            let $fileStatus = $(`.file-${file.id} .file-status`);
            if (res.status === 0) {
              $fileStatus.html("上传成功,转码中");
            } else if (res.status === 1) {
              $fileStatus.html("上传失败");
            } else if (res.status === 2) {
              $fileStatus.html("上传成功");
            }
          });
      }
    },
    fileCategory(ext) {
      let type = "";
      const typeMap = {
        image: ["gif", "jpg", "jpeg", "png", "bmp", "webp", "tif"],
        video: ["mp4", "m3u8", "rmvb", "avi", "swf", "3gp", "mkv", "flv"],
        text: ["doc", "txt", "docx", "pages", "epub", "pdf", "numbers", "csv", "xls", "xlsx", "keynote", "ppt", "pptx"],
      };
      Object.keys(typeMap).forEach((_type) => {
        const extensions = typeMap[_type];
        if (extensions.indexOf(ext) > -1) {
          type = _type;
        }
      });
      return type;
    },
    fileSize(size) {
      return WebUploader.Base.formatSize(size);
    },
	}
}
</script>

<style>
.file-panel {
    flex: 1;
  }
  .file-panel .file-list {
    height: 100%;
  }
  /* .#1ba9a4 */
  .progress {
    height: 15px;
    background: #1ba9a4;
    margin-bottom: 0;
  }
  .file-panel .imageContrast .tabStatus .cell {
    display: flex;
    align-items: center;
  }
  .file-panel .imageContrast .tabStatus .cell .file-status {
    width: 70px;
    flex-shrink: 0;
    text-align: right;
  }
</style>
2. 子组件
<template>
  <div class="upload"
       style="width:200px; height:0px">
  </div>
</template>
<script>
export default {
  name: "vueUpload",
  props: {
    accept: {
      type: Object,
      default: null,
    },
    // 上传地址
    url: {
      type: String,
      default: "",
    },
    // 上传最大数量 默认为100
    fileNumLimit: {
      type: Number,
      default: 100,
    },
    // 大小限制 默认2M
    fileSingleSizeLimit: {
      type: Number,
      default: 1024 * 1024 * 1024,
    },
    // 上传时传给后端的参数,一般为token,key等
    formData: {
      type: Object,
      default() {
        return { guid: "" };
      },
    },
    // 生成formData中文件的key,下面只是个例子,具体哪种形式和后端商议
    keyGenerator: {
      type: Function,
      default(file) {
        const currentTime = new Date().getTime();
        const key = `${currentTime}.${file.name}`;
        return key;
      },
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    // 上传按钮ID
    uploadButton: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      uploader: null,
      fileArray: [],
      timer: "",
      mergeData: {},
      mergeStatus: "",
    };
  },
  mounted() {
    this.initWebUpload();
  },
  methods: {
    showSuccess() {
      this.$message({
        type: "success",
        message: "chenggong",
      });
    },
    initWebUpload() {
      this.uploader = WebUploader.create({
        auto: true, // 选完文件后,是否自动上传
        swf: "../../assets/Uploader.swf", // swf文件路径
        server: this.url, // 文件接收服务端
        pick: {
          id: this.uploadButton, // 选择文件的按钮
          multiple: false, // 是否多文件上传 默认false
          label: "",
        },
        accept: {
          title: "Images",
          extensions: "tif",
          mimeTypes: "image/tiff",
        },
        threads: 3,
        // fileNumLimit: this.fileNumLimit, // 限制上传个数
        fileSingleSizeLimit: this.fileSingleSizeLimit, // 限制单个上传图片的大小
        formData: this.formData, // 上传所需参数
        chunked: true, //分片上传
        chunkSize: 1024 * 1024 * 20, //分片大小
        duplicate: true, // 重复上传
      });
      // console.log(this.uploader)

      // 当有文件被添加进队列的时候,添加到页面预览
      this.uploader.on("fileQueued", (file) => {
        file.status = "等待上传...";
        this.$emit("fileChange", file);
      });

      this.uploader.on("uploadStart", (file) => {
        // 在这里可以准备好formData的数据
        var guid = WebUploader.Base.guid();
        var paramOb = { guid: guid, filedId: file.source.ruid };
        this.uploader.options.formData.guid = guid;
        this.fileArray.push(paramOb);
        //this.uploader.options.formData.key = this.keyGenerator(file);
      });

      // 文件上传过程中创建进度条实时显示。
      this.uploader.on("uploadProgress", (file, percentage) => {
        file.status = "上传中...";
        this.$emit("progress", file, percentage);
      });

      this.uploader.on("uploadSuccess", (file, response) => {
        file.status = "解析发布中...";
        var successFileId = file.source.ruid;
        var successDuid;
        if (this.fileArray.length > 0) {
          for (var i = 0; i < this.fileArray.length; i++) {
            if (this.fileArray[i].filedId === successFileId) {
              successDuid = this.fileArray[i].guid;
              this.fileArray.splice(i, 1);
            }
          }
        }
        var that = this;
        $.ajax({
          url: "/gateway/sxdl-server/large/file/merge",
          type: "get",
          data: { guid: successDuid },
          success: function (data, status) {
            console.log(data, status);
            if (data.code == 200) {
              that.$emit("anylise", file);
              // that.$message.success("TIF文件上传并解析成功!");
            } else {
              that.$emit("anyliFail", file);
              that.$message.error("文件解析失败,请上传正确的TIF文件!");
            }
          },
          error: function (data, status) {
            console.log(data, status);
            that.$emit("anyliFail", file);
            that.$message.error("服务器内部异常,请联系管理员!");
            return
          },
        });
        this.$emit("success", file, response);
      });

      this.uploader.on("uploadError", (file, reason) => {
        var that = this;
        that.$message({
          message: reason,
          type: "error",
          showClose: true,
          duration: 3000,
        });
        that.$emit("uploadError", file, reason);
      });

      this.uploader.on("error", (type) => {
        let errorMessage = "";
        if (type === "F_EXCEED_SIZE") {
          this.$message({
            message: "文件最大不能超过1G,请重新选择",
            type: "warning",
          });
          // errorMessage = `文件大小不能超过${this.fileSingleSizeLimit / (1024 * 1000)}M`;
        } else if (type === "Q_EXCEED_NUM_LIMIT") {
          errorMessage = "文件上传已达到最大上限数";
          // console.log(1222222222);
        } else {
          if (type == "Q_TYPE_DENIED") {
            this.$message({
              message: "文件类型错误,请重新选择",
              type: "warning",
            });
          }
          // errorMessage = `上传出错!请检查后重新上传!错误代码${type}`;
        }
        // console.error(errorMessage);
        this.$emit("error", errorMessage);
      });

      this.uploader.on("uploadComplete", (file, response) => {
        this.$emit("complete", file, response);
      });
    },

    upload(file) {
      this.uploader.upload(file);
    },
    stop(file) {
      this.uploader.stop(file);
    },
    // 取消并中断文件上传
    cancelFile(file) {
      this.uploader.cancelFile(file);
    },
    // 在队列中移除文件
    removeFile(file, bool) {
      this.uploader.removeFile(file, bool);
    },

    getAccept(accept) {
      return "tif";
    },
  },
};
</script>
<style scoped>
</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值