欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

vue 实现文件预览和文件上传、下载、预览 - 多图、模型、dwg 图纸、文档(word、excel、ppt、pdf)

最编程 2024-10-17 07:02:28
...

整体思路(模型特殊不考虑,别人封装不具备参考性)

  1. 图片上传采用单独的组件,其他三种类型采用一个上传组件(仅仅文件格式不同)
  2. 文件上传采用前端直接上传阿里云的方式
  3. 图片预览使用elementUI自带的image预览
  4. dwg预览采用 kkfileview 方式,需要后台部署,前端使用 npm install js-base64 ,应该支持所有文件的预览,我们这里仅用作CAD文件的预览
  5. 文档类型的直接在浏览器打开预览,如果不支持需要拼接前缀 "https://view.officeapps.live.com/op/view.aspx?src="
  6. 图片下载为压缩包
  7. 文档类的相同方法下载

上传

在这里插入图片描述

        <el-form
          style="width: 650px"
          :model="form"
          :rules="rules"
          ref="form"
          label-width="180px"
          class="demo-form"
          :disabled="type == 3"
        >
          <el-form-item label="样板格式" prop="modelType">
            <el-radio-group v-model="form.modelType">
              <el-radio label="1">图片样板</el-radio>
              <el-radio label="2">三维样板</el-radio>
              <el-radio label="3">图纸样板</el-radio>
              <el-radio label="4">文档样板</el-radio>
            </el-radio-group>
          </el-form-item>
         <!-- 1 图片样板 2 三维样板 3 图纸样板 4 文档样板 -->
         <el-form-item
            v-if="form.modelType == 1"
            label="样板文件上传"
            prop="url"
         >
            <ImageUpload
              v-model="form.url"
              tip="请上传图片:"
              :limit="10"
              :showIcon="type == 3 ? true : false"
            ></ImageUpload>
         </el-form-item>
         <el-form-item
            v-if="form.modelType != 1"
            label="样板文件上传"
            prop="url"
         >
            <ModelUpload
              v-if="type != 3"
              v-model="form.url"
              :limit="1"
              :fileSize="
                form.modelType == 3 ? 50 : form.modelType == 4 ? 10 : 5120
              "
              :isShowUploadModel="true"
              ref="videoUploadRef"
              @input="uploadTemplate"
              :fileType="
                form.modelType == 3
                  ? ['.dwg']
                  : form.modelType == 4
                  ? ['.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf']
                  : ['.rvt', '.ifc', '.obj', '.stl', '.fbx', '.3DS']
              "
            ></ModelUpload>
            <div v-else class="blue point" @click="preview(form)">
              {{ form.url?.split("/")[form.url?.split("/").length - 1] }}
            </div>
        </el-form-item>

ModelUpload.vue

<template>
  <div class="component-upload-image">
    <el-upload
      action=""
      :http-request="beforeUpload"
      class="avatar-uploader"
      :limit="limit"
      :on-remove="handleDelete"
      :on-error="handleUploadError"
      :on-exceed="handleExceed"
      name="file"
      :show-file-list="true"
      :file-list="fileList"
      ref="uploadRef"
      :on-preview="handlePreview"
      :data="otherQuery"
    >
      <el-button
        size="small"
        type="primary"
        v-if="!modelFlag"
        :disabled="disabled"
        >点击上传</el-button
      >
      <!-- 上传提示 -->
      <div class="el-upload__tip" slot="tip" v-if="showTip">
        <template v-if="fileSize">
          大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
        </template>
        <template v-if="fileType">
          文件类型支持
          <b style="color: #f56c6c">{{ fileType.join(" / ") }}</b> 格式
        </template>
      </div>
      <el-progress
        v-if="modelFlag == true"
        type="circle"
        :percentage="modelUploadPercent"
        style="margin-top: 7px"
      ></el-progress>
    </el-upload>
  </div>
</template>

<script>
export default {
  props: {
    value: [String, Object, Array],
    // 图片数量限制
    limit: {
      type: Number,
      default: 1,
    },
    // 大小限制(MB)
    fileSize: {
      type: Number,
      default: 5120,
    },
    fileType: {
      type: Array,
      default: () => [".rvt", ".ifc", ".dwg", ".obj", ".stl", ".fbx", ".3DS"],
    },
    // 是否显示提示
    isShowTip: {
      type: Boolean,
      default: true,
    },
    // 是否显示进度条
    isShowUploadModel: {
      type: Boolean,
      default: false,
    },
    // 是否显示重新上传按钮
    isShowBtn: {
      type: Boolean,
      default: true,
    },
    // 是否禁用上传按钮
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      number: 0,
      hideUpload: false,
      fileList: [],
      otherQuery: {}, //上传文件传递额外参数
      uploadList: [],
      modelFlag: false,
      modelUploadPercent: 0,
      isCancel: false,
    };
  },
  watch: {
    value: {
      handler(val) {
        if (val) {
          console.log(val, "val");
          if (typeof val == "string") {
            // 首先将值转为数组
            const list = Array.isArray(val) ? val : this.value.split(",");
            // 然后将数组转为对象数组
            this.fileList = list.map((item) => {
              if (typeof item === "string") {
                item = {
                  name: item.substring(item.lastIndexOf("/") + 14),
                  url: item,
                };
              }
              return item;
            });
          } else {
            val.forEach((el) => {
              el.name = el.fileName;
            });
            this.fileList = val;
          }
        } else {
          this.fileList = [];
          return [];
        }
      },
      deep: true,
      immediate: true,
    },
  },
  computed: {
    // 是否显示提示
    showTip() {
      return this.isShowTip && (this.fileType || this.fileSize);
    },
  },
  methods: {
    //自定义上传方法..
    Upload(file, data) {
      console.log(file);
      let OSS = require("ali-oss");
      let client = new OSS({
        region: data.region,
        accessKeyId: data.accessKeyId,
        accessKeySecret: data.accessKeySecret,
        // accessKeyId: "",
        // accessKeySecret: "",
        bucket: "cscec83-openfile",
      });
      // let cdnUrl = data.cdnUrl;
      let cdnUrl = "https://cscec83-openfile.oss-cn-shanghai.aliyuncs.com/";
      this.number++;
      this.isCancel = false;
      const progress = (p, _checkpoint) => {
        console.log(p);
        // console.log(_checkpoint);
        this.modelFlag = true;
        this.modelUploadPercent = Number((Number(p) * 100).toFixed(1));
        console.log(this.isCancel);
        if (this.isCancel) {
          client.cancel();
        }
      };
      let fileName = "model/" + new Date().getTime() + file.file.name;
      client
        .multipartUpload(fileName, file.file, {
          progress,
          // 设置并发上传的分片数量。
          // parallel: 4,
          // 设置分片大小。默认值为1 MB,最小值为100 KB。
          partSize: 5 * 1024 * 1024,
        })
        .then((res) => {
          // console.log(res, "res");
          this.modelFlag = false;
          if (res.name) {
            let obj = {
              fileName: res.name,
              name: res.name,
              size: this.otherQuery.size,
              url: cdnUrl + res.name,
            };
            console.log(cdnUrl + res.name);
            this.uploadList.push(obj);
            if (this.uploadList.length === this.number) {
              this.fileList = this.fileList.concat(this.uploadList);
              this.uploadList = [];
              this.number = 0;
              // let list = this.fileList.map((item) => {
              //   return {
              //     ...item,
              //     modelUrl: item.url,
              //   };
              // });
              this.$emit("input", this.fileList);
            }
          } else {
            this.$modal.msgError("上传失败,请重试");
            this.cancel();
          }
        })
        .catch((err) => {
          console.log(err);
          if (err.name == "cancel") {
            this.$message("上传取消");
          } else {
            this.$modal.msgError(err);
          }
          this.cancel();
        });
    },
    handleDelete(file) {
      const findex = this.fileList
        .map((f) => f.fileName)
        .indexOf(file.fileName);
      if (findex > -1) {
        this.fileList.splice(findex, 1);
        this.$emit("input", this.fileList);
      }
      this.cancel();
    },
    // 上传前loading加载
    beforeUpload(file) {
      console.log(this.fileType, file.file.name);
      this.otherQuery = {};
      this.isCancel = false;
      var fileSize = file.file.size / 1024 / 1024 < this.fileSize; //控制大小  修改50的值即可
      let fileType = file.file.name.substring(file.file.name.lastIndexOf("."));
      let isContinue = true;
      if (
        this.fileType.indexOf(fileType) == -1 //控制格式
      ) {
        this.$modal.msgError(
          `文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`
        );
        this.fileList = [];
        isContinue = false;
      }
      if (!fileSize) {
        this.$modal.msgError(`上传视频大小不能超过 ${this.fileSize} MB!`);
        this.fileList = [];
        isContinue = false;
      }
      this.otherQuery.fileName = file.file.name;
      this.otherQuery.size = (file.file.size / 1024 / 1024).toFixed(2);
      if (!isContinue) return;
      this.$axios.get("/file/ossFile/getOssParameter").then((res) => {
        if (res.code == 200) {
          this.Upload(file, res.data);
        }
      });
    },
    // 预览
    handlePreview(file) {
      window.open(file.url, "_blank");
    },
    // 文件个数超出
    handleExceed() {
      this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);
    },
    // 上传失败
    handleUploadError() {
      this.$modal.msgError("上传失败,请重试");
      // this.loading.close();
    },
    cancel(type) {
      this.isCancel = true;
      this.modelFlag = false;
    },
  },
};
</script>
<style scoped lang="css">
::v-deep.hideUpload .el-upload--picture-card {
  display: none;
}

::v-deep .el-upload--picture-card {
  width: 104px;
  height: 104px;
  line-height: 104px;
}

::v-deep .el-upload-list--picture-card .el-upload
						

上一篇: 女娲科技破茧成蝶--智能工业机器人引领工业新时代

下一篇: 期货外汇报价源 7 Markets CTP 推送服务说明