file.vue 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. <template>
  2. <input type="file" ref="fileInput" :accept="accept" style="display: none;" @change="handleUploadFile"/>
  3. </template>
  4. <script setup>
  5. defineOptions({ name: 'upload-file'})
  6. import { ref } from 'vue'
  7. import Snackbar from '@/plugins/snackbar'
  8. import { useI18n } from '@/hooks/web/useI18n'
  9. import { uploadFile } from '@/api/common'
  10. const emits = defineEmits(['success'])
  11. const props = defineProps({
  12. accept: {
  13. type: String,
  14. default: '.pdf,.doc,.docx'
  15. },
  16. custom: {
  17. type: Boolean,
  18. default: false
  19. },
  20. customName: {
  21. type: String,
  22. default: ''
  23. },
  24. path: {
  25. type: String,
  26. default: 'attachment' // attachment附件, img, video
  27. }
  28. })
  29. const { t } = useI18n()
  30. const clicked = ref(false)
  31. const fileInput = ref()
  32. const trigger = () => {
  33. if (clicked.value) return
  34. clicked.value = true
  35. fileInput.value.click()
  36. clicked.value = false
  37. }
  38. const handleUploadFile = async (e) => {
  39. if (!e.target.files.length) return
  40. const file = e.target.files[0]
  41. const size = file.size
  42. if (size / (1024*1024) > 20) {
  43. Snackbar.warning(t('common.fileSizeExceed'))
  44. return
  45. }
  46. const arr = file.name.split('.')
  47. // 效验文件格式是否正确
  48. const fileType = arr[arr.length - 1]
  49. const acceptArr = props.accept.split(',')
  50. if (!acceptArr.includes(`.${fileType}`)) return Snackbar.warning('请上传指定格式的文件')
  51. const formData = new FormData()
  52. formData.append(props.customName || 'file', file)
  53. formData.append('path', props.path)
  54. if (props.custom) return emits('success', formData)
  55. const { data } = await uploadFile(formData)
  56. if (!data) return
  57. emits('success', data, arr[0], file.name)
  58. }
  59. defineExpose({
  60. trigger
  61. })
  62. </script>
  63. <style scoped lang="scss">
  64. </style>