FileUpload.vue 2.96 KB
<template>
  <setting-item :name="fileSizeMsg">
    <n-upload
      :max="max"
      :customRequest="customRequest"
      :onBeforeUpload="beforeUploadHandle"
      :default-file-list="fileList"
      @change="handleUploadChange"
    >
      <n-button> 上传文件</n-button>
    </n-upload>
  </setting-item>
</template>

<script setup lang="ts">
import { ref, nextTick } from 'vue'
import { SettingItem } from '@/components/Pages/ChartItemSetting'
import { uploadFile } from '@/api/external/contentSave/content'
import type { UploadFileInfo } from 'naive-ui'
import { UploadCustomRequestOptions } from 'naive-ui'

const props = defineProps({
  max: {
    type: Number,
    default: 1
  },
  fileSizeConst: {
    type: Number,
    default: 50
  },
  singleFileType: {
    type: String,
    default: 'mtl'
  },
  threeSupportFileFormat: {
    type: Array,
    default: () => []
  }
})

const emits = defineEmits(['fileStaticUri'])

const fileList = ref<UploadFileInfo[]>([])

const fileSizeMsg = ref(`文件需小于 ${props.fileSizeConst}M;格式为${props.threeSupportFileFormat.join(',')}的文件`)

const extname = (filename: string) => {
  if (!filename || typeof filename != 'string') {
    return false
  }
  let a = filename.split('').reverse().join('')
  let b = a.substring(0, a.search(/\./)).split('').reverse().join('')
  return b
}

// 上传图片前置处理
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
const beforeUploadHandle = async ({ file }) => {
  const type = extname(file.file.name) as string
  const size = file.file.size
  if (size / (1024 * 1024) > props.fileSizeConst) {
    window['$message'].warning(`文件超出 ${props.fileSizeConst}M限制,请重新上传!`)
    return false
  }
  if (!props.threeSupportFileFormat.includes(type)) {
    window['$message'].warning('文件格式不符合,请重新上传!')
    return false
  }
  return true
}

const handleUploadChange = (data: { fileList: UploadFileInfo[] }) => {
  fileList.value = []
  emits('fileStaticUri', data.fileList as never as any)
}

// 自定义上传操作
const customRequest = (options: UploadCustomRequestOptions) => {
  const { file } = options
  nextTick(async () => {
    if (file.file) {
      const formData = new FormData()
      formData.append('file', file.file)
      const uploadRes = await uploadFile(formData)
      if (uploadRes) {
        fileList.value.push({
          id: -Math.random() + '',
          name: uploadRes?.fileName,
          status: 'finished',
          url: uploadRes?.fileStaticUri
        })
        fileList.value = fileList.value.filter((item: UploadFileInfo) => {
          return item.status === 'finished'
        })
        emits('fileStaticUri', fileList.value)
        window['$message'].success('上传文件成功!')
      }
    } else {
      window['$message'].error('上传文件失败,请稍后重试!')
    }
  })
}
</script>