zhangzengfei
2023-10-09 8e40a69fcfe8bc799fee141fec953a2b0892dbd4
src/pages/ai/FileUpload/uploader.vue
New file
@@ -0,0 +1,189 @@
<template>
  <div class="uploader">
    <!-- <div class="close" @click="closeHandle">x</div> -->
    <slot :files="files" :file-list="fileList" :started="started">
      <uploader-unsupport></uploader-unsupport>
      <UploaderDrop>
        <p>拖动文件到该区域上传</p>
        <uploader-btn >选择文件</uploader-btn>
        <uploader-btn :directory="true" >选择文件夹</uploader-btn>
      </UploaderDrop>
      <uploader-list></uploader-list>
    </slot>
  </div>
</template>
<script>
import Uploader from 'simple-uploader.js'
import { kebabCase } from './common/utils'
import UploaderBtn from './btn.vue'
import UploaderDrop from './drop.vue'
import UploaderUnsupport from './unsupport.vue'
import UploaderList from './list.vue'
const COMPONENT_NAME = 'uploader'
const FILE_ADDED_EVENT = 'fileAdded'
const FILES_ADDED_EVENT = 'filesAdded'
const UPLOAD_START_EVENT = 'uploadStart'
export default {
  name: COMPONENT_NAME,
  provide() {
    return {
      uploader: this
    }
  },
  props: {
    attrs: {
      type: Object,
      default() {
        return {}
      }
    },
    sourceType: {
      type: Number,
    },
    options: {
      type: Object,
      default() {
        return {}
      }
    },
    autoStart: {
      type: Boolean,
      default: true
    },
    fileStatusText: {
      type: [Object, Function],
      default() {
        return {
          success: 'success',
          error: 'error',
          uploading: 'uploading',
          paused: 'paused',
          waiting: 'waiting'
        }
      }
    }
  },
  data() {
    return {
      started: false,
      files: [],
      fileList: []
    }
  },
  methods: {
    uploadStart() {
      this.started = true
    },
    fileAdded(file) {
      this.$emit(kebabCase(FILE_ADDED_EVENT), file)
      if (file.ignored) {
        // is ignored, filter it
        return false
      }
    },
    filesAdded(files, fileList) {
      if (this.sourceType == 3 && files[0]) {
        if (
          !files[0].name.endsWith(".tar") ||
          !files[0].name.endsWith(".gz") ||
          !files[0].name.endsWith(".tar.gz")
        ) {
          this.shouldStop = true
          return
        }
      }
      this.$emit(kebabCase(FILES_ADDED_EVENT), files, fileList)
      if (files.ignored || fileList.ignored) {
        // is ignored, filter it
        return false
      }
    },
    fileRemoved(file) {
      this.files = this.uploader.files
      this.fileList = this.uploader.fileList
    },
    filesSubmitted(files, fileList) {
      if (this.sourceType == 3&& files[0]) {
        if (
          !files[0].name.endsWith(".tar") ||
          !files[0].name.endsWith(".gz") ||
          !files[0].name.endsWith(".tar.gz")
        ) {
          this.shouldStop = true
          return
        }
      }
      this.files = this.uploader.files
      this.fileList = this.uploader.fileList
      if (this.autoStart) {
        this.uploader.upload()
      }
    },
    allEvent(...args) {
      const name = args[0]
      const EVENTSMAP = {
        [FILE_ADDED_EVENT]: true,
        [FILES_ADDED_EVENT]: true,
        [UPLOAD_START_EVENT]: 'uploadStart'
      }
      const handler = EVENTSMAP[name]
      if (handler) {
        if (handler === true) {
          return
        }
        this[handler].apply(this, args.slice(1))
      }
      args[0] = kebabCase(name)
      this.$emit.apply(this, args)
    },
    closeHandle() {
      this.$emit("close")
    }
  },
  created() {
    // this.bindUploader();
    this.options.initialPaused = !this.autoStart
    const uploader = new Uploader(this.options)
    this.uploader = uploader
    this.uploader.fileStatusText = this.fileStatusText
    uploader.on('catchAll', this.allEvent)
    uploader.on(FILE_ADDED_EVENT, this.fileAdded)
    uploader.on(FILES_ADDED_EVENT, this.filesAdded)
    uploader.on('fileRemoved', this.fileRemoved)
    uploader.on('filesSubmitted', this.filesSubmitted)
  },
  mounted() {
  },
  destroyed() {
    const uploader = this.uploader
    uploader.off('catchAll', this.allEvent)
    uploader.off(FILE_ADDED_EVENT, this.fileAdded)
    uploader.off(FILES_ADDED_EVENT, this.filesAdded)
    uploader.off('fileRemoved', this.fileRemoved)
    uploader.off('filesSubmitted', this.filesSubmitted)
    this.uploader = null
  },
  components: {
    UploaderBtn,
    UploaderDrop,
    UploaderUnsupport,
    UploaderList
  }
}
</script>
<style lang="scss">
.uploader {
  .close {
    position: absolute;
    right: 5px;
    top: 3px;
    cursor: pointer;
  }
}
</style>