前端分片上传 vue element-ui

<!-- 游戏原包编辑弹窗 -->
<template>
  <el-dialog
    :title="isUpdate ? '修改游戏原包' : '添加游戏原包'"
    :visible="visible"
    width="1000px"
    :destroy-on-close="true"
    :lock-scroll="false"
    @update:visible="updateVisible"
    :close-on-click-modal="false"
  >
    <el-form ref="form" :model="form" :rules="rules" label-width="100px">

      <el-form-item label="文件路径:" prop="file_url">
        <el-upload
          accept=".ipa,.apk,.exe"
          class="upload-demo"
          :action="uploadImgUrl"
          :on-preview="handlePreview"
          :on-remove="handleRemove"
          :before-remove="beforeRemove"
          multiple
          :limit="1"
          :headers="myHeaders"
          :on-exceed="handleExceed"
          :file-list="fileList"
          :http-request="uploadChunk"
        >
          <div>
            <el-button size="small" type="primary">点击上传</el-button>
            <div>文件上传(仅支持.ipa.apk 和 .exe格式)</div>
          </div>
        </el-upload>
        <!-- 添加进度条 -->
        <el-progress v-if="showProgress" :percentage="uploadProgress" />
      </el-form-item>
    
    </el-form>
    <div slot="footer">
      <el-button @click="updateVisible(false)">取消</el-button>
      <el-button type="primary" @click="save" :loading="loading"
        >保存
      </el-button>
    </div>
  </el-dialog>
</template>

<script>
import setting from "@/config/setting";
import md5 from "js-md5"; //引入MD5加密


export default {
  name: "GameSourceEdit",
  props: {
    // 弹窗是否打开
    visible: Boolean,
    // 修改回显的数据
    data: Object
  },
  components: {  },
  data() {
    let token = setting.takeToken();
    return {
      // 表单数据
      fileList: [],
      sdk_version: "",
      package_Id: "",
      package_Name: "",
      uploadImgUrl: "",
      form: Object.assign({ status: 1 }, this.data),
      myHeaders: { Authorization: token },
      // 表单验证规则
      rules: {
        file_url: [{ required: true, message: "请上传文件", trigger: "blur" }],
        file_size: [
          { required: true, message: "请输入文件大小", trigger: "blur" }
        ],
      
      },
      // 提交状态
      loading: false,
      // 是否是修改
      isUpdate: false,
      file_disabled: true,
      // 是否选中的游戏包为苹果
      isApple: false,
      currentChunk: 0, // 当前分片数
      showProgress: false, // 是否显示进度条
      uploadProgress: 0 // 上传进度
    };
  },
  watch: {
    data() {
      if (this.data) {
        this.form = Object.assign({}, this.data);
        console.log(this.form, "xiugai1");
        this.isUpdate = true;
        this.showProgress = false;
        this.uploadProgress = 0;
      } else {
        this.form = {};
        this.showProgress = false;
        this.uploadProgress = 0;
        this.isUpdate = false;
      }
    },
    "form.game_id"(val) {
      if (val) {
        this.gameAll.forEach(item => {
          if (item.id == val) {
            console.log("item", item);
            this.$set(this.form, "file_type", item.sdk_version);
            this.$set(this.form, "game_name", item.game_name);
          }
        });
      }
    },
    isApple(newV) {
      if (newV) {
        this.rules.pack_name = [
          { required: true, message: "请输入原包包名", trigger: "blur" }
        ];
      } else {
        this.rules.pack_name = [
          { required: false, message: "请输入原包包名", trigger: "blur" }
        ];
      }
    },
    fileList: {
      handler(val) {
        if (val.length) {
          this.$set(this.form, "file_url", val[0].save_name);
          this.$set(this.form, "file_size", val[0].file_size);
          this.$set(this.form, "file_name", val[0].file_name);
        } else {
          this.$set(this.form, "file_url", "");
          this.$set(this.form, "file_size", "");
          this.$set(this.form, "file_name", "");
        }
      },
      deep: true
    },
    "form.package_name"(newV, oldV) {
      if (newV != oldV) {
        console.log("!!!", newV, oldV);
        if (newV != undefined) {
          // console.log("this.gameAll", this.gameAll);

          this.gameAll.forEach(item => {
            // sdk_version和package_id

            if (item.id == newV) {
              // 渲染类型
              this.$set(this.form, "file_type", item.sdk_version);
              console.log(item, "item");
              this.sdk_version = item.sdk_version;
              this.package_Id = item.id;
              this.package_Name = item.package_name;
              this.uploadImgUrl =
                process.env.VUE_APP_API_BASE_URL +
                "/upload/zoneUpload?sdk_version=" +
                this.sdk_version;
              console.log("sdk_version", this.sdk_version);
              console.log("this.package_Id", this.package_Id);
              console.log("this.package_Name", this.package_Name);
              console.log("this.uploadImgUrl", this.uploadImgUrl);
              this.$set(this.form, "package_name", this.package_Name);
              this.$set(this.form, "package_id", this.package_Id);
              console.log("this.fffffff", this.form);

              item.sdk_version == 2
                ? (this.isApple = true)
                : (this.isApple = false);
            }
          });
          this.file_disabled = true;
        } else {
          console.log("不可以选则");
          this.file_disabled = true;
        }
      } else {
        console.log("aaa");
        console.log("aaa", newV, oldV);
      }
    },
    "form.file_type"(val) {
      this.rules.pack_name =
        val == 2
          ? [{ required: true, message: "请输入原包包名", trigger: "blur" }]
          : { required: false, message: "请输入原包包名", trigger: "blur" };
    }
    // form(newVal, oldVal) {
    //   console.log("!!", newVal, "!!!", oldVal);
    //   // if (newVal.package_name !== ) {

    //   // }
    // }
  },
  methods: {
    getAllOptioin(arr) {
      this.gameAll = arr;
    },
    handleRemove() {
      this.fileList = [];
    },
    handlePreview(file) {
      console.log(file);
    },
    successUpload(response) {
      // this.$set(this.form, 'attach', response.data)
      console.log(response);
      // this.$set(this.fileList, this.fileList.length, {
      //   file_name: response.data.file_name,
      //   save_name: response.data.save_name,
      //   file_size: response.data.file_size,
      //   name: response.data.file_name
      // });
    },
    handleExceed() {
      this.$message.warning(`当前限制选择 1 个文件`);
    },
    async beforeRemove(file) {
      try {
        await this.$confirm(`确定移除 ${file.name}?`);
        // 用户点击确定后执行的代码
        this.showProgress = false;
        this.uploadProgress = 0;

        this.rules.file_url = [
          { required: true, message: "请上传文件", trigger: "blur" }
        ];
        this.uploadChunk("false");
      } catch (error) {
        // 用户点击取消或关闭对话框时执行的代码,这里不需要做任何操作
      }
    },
    // 分片上传文件
    async uploadChunk(file) {
      console.log(file, "file");
      if (file == "false") {
        window.location.reload();
        return;
      } else if (this.form.package_name == undefined) {
        console.log(this.form.package_name);
        this.$message.error("请先选择游戏包");
        this.fileList = [];
        return;
      } else if (file == "none") {
        return;
      }
      const totalSize = file.file.size;
      const totalSizeInMegabytes = totalSize / (1024 * 1024);
      // file_size
      const totalSizeInMegabytesFixed = totalSizeInMegabytes.toFixed(2) + "MB";

      const chunkSize = 10 * 1024 * 1024; // 10MB
      const chunkCount = Math.ceil(totalSize / chunkSize);
      console.log(
        chunkCount,
        "chunkCount",
        "totalSize",
        totalSizeInMegabytesFixed,
        "chunkSize",
        chunkSize
      );

      // 显示进度条
      this.showProgress = true;
      this.uploadProgress = 0;
      const readChunkMD5 = async chunk => {
        return new Promise(resolve => {
          let fileReaderInstance = new FileReader();
          fileReaderInstance.readAsBinaryString(chunk);
          fileReaderInstance.addEventListener("load", e => {
            let fileBlob = e.target.result;
            let chunkMD5 = md5(fileBlob);
            resolve(chunkMD5);
          });
        });
      };

      const uploadChunkRecursive = async index => {
        if (index >= chunkCount) {
          return;
        }
        // 更新当前分片数和总分片数
        this.currentChunk = index + 1;

        const start = index * chunkSize;
        const end = Math.min(start + chunkSize, totalSize);
        const chunk = file.file.slice(start, end);

        const chunkMD5 = await readChunkMD5(chunk);

        const formData = new FormData();
        const Sdk_version = this.isUpdate
          ? this.form.file_type
          : this.sdk_version;
        formData.append("file", chunk);
        formData.append("chunkNumber", index + 1);
        formData.append("chunkSize", chunkSize);
        formData.append("currentChunkSize", chunk.size);
        formData.append("filename", file.file.name);
        formData.append("totalChunks", chunkCount);
        formData.append("md5", chunkMD5);
        console.log("mmmmd", chunkMD5);

        try {
          const res = await this.$http.post(
            `/upload/zoneUpload?sdk_version=` + Sdk_version,
            formData
          );
          console.log(res);
          if (res.data.code === 2) {
            this.rules.file_url = [
              { required: false, message: "请上传文件", trigger: "blur" }
            ];
            this.uploadProgress = Math.round(
              (this.currentChunk / chunkCount) * 100
            );
            this.$set(this.form, "file_url", res.data.file_path);
            this.$set(this.form, "file_size", totalSizeInMegabytesFixed);
            this.$set(this.form, "file_name", file.file.name);
            console.log(this.form);
            this.$message.success(res.data.msg);
          } else if (res.data.code === 1) {
            this.uploadProgress = Math.round(
              (this.currentChunk / chunkCount) * 100
            );
            await uploadChunkRecursive(index + 1);
          }
        } catch (e) {
          this.loading = false;
          this.$message.error(e.message);
        }
      };

      await uploadChunkRecursive(0);
    },
    /* 保存编辑 */
    save() {
      this.$refs["form"].validate(valid => {
        if (valid) {
          this.loading = true;
          if (!this.isUpdate) {
            this.form.package_id = this.package_Id;
            this.form.package_name = this.package_Name;
          }

          console.log(this.form, "item");
          this.$http
            .post("/gamesource/edit", this.form)
            .then(res => {
              this.loading = false;
              if (res.data.code === 0) {
                this.$message.success(res.data.msg);
                if (!this.isUpdate) {
                  this.form = {};
                }
                this.rules.file_url = [
                  { required: true, message: "请上传文件", trigger: "blur" }
                ];
                this.showProgress = false;
                this.uploadProgress = 0;
                this.updateVisible(false);
                this.$emit("done");
              } else {
                this.$message.error(res.data.msg);
              }
            })
            .catch(e => {
              this.loading = false;
              this.$message.error(e.message);
            });
        } else {
          return false;
        }
      });
    },
    /* 更新visible */
    updateVisible(value) {
      this.$emit("update:visible", value);
      console.log(this.fileList, "fflst");
      if (this.showProgress) {
        this.uploadChunk("false");
      }
      this.showProgress = false;
      this.uploadProgress = 0;
    },
    // 是否更改了
    remoteMethod(query) {
      // console.log("!!!");
      if (query !== "") {
        this.loading = true;
      } else {
        // console.log("!!!!!");
      }
    }
  }
};
</script>

<style scoped>
::v-deep .el-upload {
  text-align: left;
}
</style>

 

就是按固定的文件大小分成一片片的文件去上传给后端,一片传完再传下一片

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值