ZZJ
2022-02-11 d365829b14ca4256d39694b9cdcd43bad0ad8595
src/components/subComponents/FileUpload/file.vue
@@ -24,28 +24,36 @@
      :extension="extension"
      :file-category="fileCategory"
    >
      <div class="uploader-file-progress" :class="progressingClass" :style="progressStyle"></div>
      <div
        class="uploader-file-progress"
        :class="progressingClass"
        :style="progressStyle"
      ></div>
      <div class="uploader-file-info">
        <div class="uploader-file-name">
          <i class="uploader-file-icon" :icon="fileCategory"></i>
          {{file.name}}
          {{ file.name }}
        </div>
        <div class="uploader-file-size">{{formatedSize}}</div>
        <div class="uploader-file-size">{{ formatedSize }}</div>
        <div class="uploader-file-meta"></div>
        <div class="uploader-file-status">
          <span v-show="status !== 'uploading'">{{statusText}}</span>
          <span v-show="status !== 'uploading'">{{ statusText }}</span>
          <span v-show="status === 'uploading'">
            <span>{{progressStyle.progress}}</span>
            <em>{{formatedAverageSpeed}}</em>
            <span>{{ progressStyle.progress }}</span>
            <em>{{ formatedAverageSpeed }}</em>
            <i>&nbsp;&nbsp;{{formatedTimeRemaining}}</i>
            <i>&nbsp;&nbsp;{{ formatedTimeRemaining }}</i>
          </span>
        </div>
        <div class="uploader-file-actions">
          <span class="uploader-file-pause" @click="pause"></span>
          <span class="uploader-file-resume" @click="resume">️</span>
          <span class="uploader-file-retry" @click="retry"></span>
          <span class="uploader-file-remove" @click="remove"></span>
          <el-tooltip effect="dark" content="重新上传" placement="bottom">
            <span class="uploader-file-retry" @click="retry"></span>
          </el-tooltip>
          <el-tooltip effect="dark" content="删除" placement="bottom">
            <span class="uploader-file-remove" @click="remove"></span>
          </el-tooltip>
        </div>
      </div>
    </slot>
@@ -53,11 +61,11 @@
</template>
<script>
import Uploader from 'simple-uploader.js'
import events from './common/file-events'
import { secondsToStr } from './common/utils'
import Uploader from "simple-uploader.js";
import events from "./common/file-events";
import { secondsToStr } from "./common/utils";
const COMPONENT_NAME = 'uploader-file'
const COMPONENT_NAME = "uploader-file";
export default {
  name: COMPONENT_NAME,
@@ -65,13 +73,13 @@
    file: {
      type: Object,
      default() {
        return {}
      }
        return {};
      },
    },
    list: {
      type: Boolean,
      default: false
    }
      default: false,
    },
  },
  data() {
    return {
@@ -83,231 +91,248 @@
      isComplete: false,
      isUploading: false,
      size: 0,
      formatedSize: '',
      formatedSize: "",
      uploadedSize: 0,
      progress: 0,
      timeRemaining: 0,
      type: '',
      extension: '',
      progressingClass: ''
    }
      type: "",
      extension: "",
      progressingClass: "",
    };
  },
  computed: {
    fileCategory() {
      const extension = this.extension
      const isFolder = this.file.isFolder
      let type = isFolder ? 'folder' : 'unknown'
      const categoryMap = this.file.uploader.opts.categoryMap
      const extension = this.extension;
      const isFolder = this.file.isFolder;
      let type = isFolder ? "folder" : "unknown";
      const categoryMap = this.file.uploader.opts.categoryMap;
      const typeMap = categoryMap || {
        image: ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp'],
        video: ['mp4', 'm3u8', 'rmvb', 'avi', 'swf', '3gp', 'mkv', 'flv'],
        audio: ['mp3', 'wav', 'wma', 'ogg', 'aac', 'flac'],
        document: ['doc', 'txt', 'docx', 'pages', 'epub', 'pdf', 'numbers', 'csv', 'xls', 'xlsx', 'keynote', 'ppt', 'pptx']
      }
        image: ["gif", "jpg", "jpeg", "png", "bmp", "webp"],
        video: ["mp4", "m3u8", "rmvb", "avi", "swf", "3gp", "mkv", "flv"],
        audio: ["mp3", "wav", "wma", "ogg", "aac", "flac"],
        document: [
          "doc",
          "txt",
          "docx",
          "pages",
          "epub",
          "pdf",
          "numbers",
          "csv",
          "xls",
          "xlsx",
          "keynote",
          "ppt",
          "pptx",
        ],
      };
      Object.keys(typeMap).forEach((_type) => {
        const extensions = typeMap[_type]
        const extensions = typeMap[_type];
        if (extensions.indexOf(extension) > -1) {
          type = _type
          type = _type;
        }
      })
      return type
      });
      return type;
    },
    progressStyle() {
      const progress = Math.floor(this.progress * 100)
      const style = `translateX(${Math.floor(progress - 100)}%)`
      const progress = Math.floor(this.progress * 100);
      const style = `translateX(${Math.floor(progress - 100)}%)`;
      return {
        progress: `${progress}%`,
        webkitTransform: style,
        mozTransform: style,
        msTransform: style,
        transform: style
      }
        transform: style,
      };
    },
    formatedAverageSpeed() {
      return `${Uploader.utils.formatSize(this.averageSpeed)} / s`
      return `${Uploader.utils.formatSize(this.averageSpeed)} / s`;
    },
    status() {
      const isUploading = this.isUploading
      const isComplete = this.isComplete
      const isError = this.error
      const paused = this.paused
      const isUploading = this.isUploading;
      const isComplete = this.isComplete;
      const isError = this.error;
      const paused = this.paused;
      if (isComplete) {
        return 'success'
        return "success";
      } else if (isError) {
        return 'error'
        return "error";
      } else if (isUploading) {
        return 'uploading'
        return "uploading";
      } else if (paused) {
        return 'paused'
        return "paused";
      } else {
        return 'waiting'
        return "waiting";
      }
    },
    statusText() {
      const status = this.status
      const fileStatusText = this.file.uploader.fileStatusText
      let txt = status
      if (typeof fileStatusText === 'function') {
        txt = fileStatusText(status, this.response)
      const status = this.status;
      const fileStatusText = this.file.uploader.fileStatusText;
      let txt = status;
      if (typeof fileStatusText === "function") {
        txt = fileStatusText(status, this.response);
      } else {
        txt = fileStatusText[status]
        txt = fileStatusText[status];
      }
      return txt || status
      return txt || status;
    },
    formatedTimeRemaining() {
      const timeRemaining = this.timeRemaining
      const file = this.file
      const timeRemaining = this.timeRemaining;
      const file = this.file;
      if (timeRemaining === Number.POSITIVE_INFINITY || timeRemaining === 0) {
        return ''
        return "";
      }
      let parsedTimeRemaining = secondsToStr(timeRemaining)
      const parseTimeRemaining = file.uploader.opts.parseTimeRemaining
      let parsedTimeRemaining = secondsToStr(timeRemaining);
      const parseTimeRemaining = file.uploader.opts.parseTimeRemaining;
      if (parseTimeRemaining) {
        parsedTimeRemaining = parseTimeRemaining(timeRemaining, parsedTimeRemaining)
        parsedTimeRemaining = parseTimeRemaining(
          timeRemaining,
          parsedTimeRemaining
        );
      }
      return parsedTimeRemaining
    }
      return parsedTimeRemaining;
    },
  },
  watch: {
    status(newStatus, oldStatus) {
      if (oldStatus && newStatus === 'uploading' && oldStatus !== 'uploading') {
      if (oldStatus && newStatus === "uploading" && oldStatus !== "uploading") {
        this.tid = setTimeout(() => {
          this.progressingClass = 'uploader-file-progressing'
        }, 200)
          this.progressingClass = "uploader-file-progressing";
        }, 200);
      } else {
        clearTimeout(this.tid)
        this.progressingClass = ''
        clearTimeout(this.tid);
        this.progressingClass = "";
      }
    }
    },
  },
  methods: {
    _actionCheck() {
      this.paused = this.file.paused
      this.error = this.file.error
      this.isUploading = this.file.isUploading()
      this.paused = this.file.paused;
      this.error = this.file.error;
      this.isUploading = this.file.isUploading();
    },
    pause() {
      this.file.pause()
      this._actionCheck()
      this._fileProgress()
      this.file.pause();
      this._actionCheck();
      this._fileProgress();
    },
    resume() {
      this.file.resume()
      this._actionCheck()
      this.file.resume();
      this._actionCheck();
    },
    remove() {
      this.file.cancel()
      this.file.cancel();
    },
    retry() {
      this.file.retry()
      this._actionCheck()
      this.file.retry();
      this._actionCheck();
    },
    processResponse(message) {
      let res = message
      let res = message;
      try {
        res = JSON.parse(message)
      } catch (e) { }
      this.response = res
        res = JSON.parse(message);
      } catch (e) {}
      this.response = res;
    },
    fileEventsHandler(event, args) {
      const rootFile = args[0]
      const file = args[1]
      const target = this.list ? rootFile : file
      const rootFile = args[0];
      const file = args[1];
      const target = this.list ? rootFile : file;
      if (this.file === target) {
        if (this.list && event === 'fileSuccess') {
          this.processResponse(args[2])
          return
        if (this.list && event === "fileSuccess") {
          this.processResponse(args[2]);
          return;
        }
        this[`_${event}`].apply(this, args)
        this[`_${event}`].apply(this, args);
      }
    },
    _fileProgress() {
      this.progress = this.file.progress()
      this.averageSpeed = this.file.averageSpeed
      this.currentSpeed = this.file.currentSpeed
      this.timeRemaining = this.file.timeRemaining()
      this.uploadedSize = this.file.sizeUploaded()
      this._actionCheck()
      this.progress = this.file.progress();
      this.averageSpeed = this.file.averageSpeed;
      this.currentSpeed = this.file.currentSpeed;
      this.timeRemaining = this.file.timeRemaining();
      this.uploadedSize = this.file.sizeUploaded();
      this._actionCheck();
    },
    _fileSuccess(rootFile, file, message) {
      if (rootFile) {
        this.processResponse(message)
        this.processResponse(message);
      }
      this._fileProgress()
      this.error = false
      this.isComplete = true
      this.isUploading = false
      console.log('rootFile, file, message', rootFile, file, message)
      this._fileProgress();
      this.error = false;
      this.isComplete = true;
      this.isUploading = false;
      console.log("rootFile, file, message", rootFile, file, message);
    },
    _fileComplete() {
      this._fileSuccess()
      this._fileSuccess();
    },
    _fileError(rootFile, file, message) {
      this._fileProgress()
      console.log('rootFile, file, message', rootFile, file, message)
      this.processResponse(message)
      this.error = true
      this.isComplete = false
      this.isUploading = false
    }
      this._fileProgress();
      console.log("rootFile, file, message", rootFile, file, message);
      this.processResponse(message);
      this.error = true;
      this.isComplete = false;
      this.isUploading = false;
    },
  },
  mounted() {
    const staticProps = ['paused', 'error', 'averageSpeed', 'currentSpeed']
    const staticProps = ["paused", "error", "averageSpeed", "currentSpeed"];
    const fnProps = [
      'isComplete',
      'isUploading',
      "isComplete",
      "isUploading",
      {
        key: 'size',
        fn: 'getSize'
        key: "size",
        fn: "getSize",
      },
      {
        key: 'formatedSize',
        fn: 'getFormatSize'
        key: "formatedSize",
        fn: "getFormatSize",
      },
      {
        key: 'uploadedSize',
        fn: 'sizeUploaded'
        key: "uploadedSize",
        fn: "sizeUploaded",
      },
      'progress',
      'timeRemaining',
      "progress",
      "timeRemaining",
      {
        key: 'type',
        fn: 'getType'
        key: "type",
        fn: "getType",
      },
      {
        key: 'extension',
        fn: 'getExtension'
      }
    ]
    staticProps.forEach(prop => {
      this[prop] = this.file[prop]
    })
        key: "extension",
        fn: "getExtension",
      },
    ];
    staticProps.forEach((prop) => {
      this[prop] = this.file[prop];
    });
    fnProps.forEach((fnProp) => {
      if (typeof fnProp === 'string') {
        this[fnProp] = this.file[fnProp]()
      if (typeof fnProp === "string") {
        this[fnProp] = this.file[fnProp]();
      } else {
        this[fnProp.key] = this.file[fnProp.fn]()
        this[fnProp.key] = this.file[fnProp.fn]();
      }
    })
    });
    const handlers = this._handlers = {}
    const handlers = (this._handlers = {});
    const eventHandler = (event) => {
      handlers[event] = (...args) => {
        this.fileEventsHandler(event, args)
      }
      return handlers[event]
    }
        this.fileEventsHandler(event, args);
      };
      return handlers[event];
    };
    events.forEach((event) => {
      this.file.uploader.on(event, eventHandler(event))
    })
      this.file.uploader.on(event, eventHandler(event));
    });
  },
  destroyed() {
    events.forEach((event) => {
      this.file.uploader.off(event, this._handlers[event])
    })
    this._handlers = null
  }
}
      this.file.uploader.off(event, this._handlers[event]);
    });
    this._handlers = null;
  },
};
</script>
<style>