HcFileUpload1.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <template>
  2. <el-upload
  3. ref="uploadRef" :accept="accept" :action="api + action" :before-upload="beforeUpload"
  4. :data="uploadData" :disabled="uploadDisabled" :headers="getHeader()" :limit="1" :on-error="uploadError"
  5. :on-exceed="uploadExceed" :on-progress="uploadprogress" :on-success="uploadSuccess"
  6. :show-file-list="false" class="hc-file-upload-box"
  7. >
  8. <slot />
  9. </el-upload>
  10. </template>
  11. <script setup>
  12. import { onMounted, ref, watch } from 'vue'
  13. import { getHeader } from 'hc-vue3-ui'
  14. import { deepClone, getObjValue, isFileSize } from 'js-fast-way'
  15. import { genFileId } from 'element-plus'
  16. const props = defineProps({
  17. datas: {
  18. type: Object,
  19. default: () => ({}),
  20. },
  21. api: {
  22. type: String,
  23. default: '/api/blade-resource/oss/endpoint/',
  24. },
  25. action: {
  26. type: String,
  27. default: 'upload-file',
  28. },
  29. accept: {
  30. type: String,
  31. default: 'image/png,image/jpg,image/jpeg,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/pdf,.doc,.docx,application/msword',
  32. },
  33. size: {
  34. type: Number,
  35. default: 60,
  36. },
  37. })
  38. //事件
  39. const emit = defineEmits(['change', 'progress'])
  40. //变量
  41. const uploadRef = ref(null)
  42. const uploadData = ref(props.datas)
  43. const uploadDisabled = ref(false)
  44. //监听
  45. watch(() => [
  46. props.datas,
  47. ], ([datas]) => {
  48. uploadData.value = datas
  49. })
  50. //渲染完成
  51. onMounted(() => {
  52. beforeFileNum.value = 0
  53. finishFileNum.value = 0
  54. errorFileNum.value = 0
  55. })
  56. //上传前
  57. const beforeFileNum = ref(0)
  58. const beforeUpload = async (file) => {
  59. if (isFileSize(file?.size, props.size)) {
  60. beforeFileNum.value++
  61. return true
  62. } else {
  63. beforeFileNum.value = 0
  64. window?.$message?.warning(`文件大小, 不能过${props.size}M!`)
  65. return false
  66. }
  67. }
  68. //超出限制时
  69. const uploadExceed = (files) => {
  70. uploadRef.value?.clearFiles()
  71. const file = files[0]
  72. file.uid = genFileId()
  73. uploadRef.value?.handleStart(file)
  74. }
  75. //上传中
  76. const uploadprogress = () => {
  77. uploadDisabled.value = true
  78. emit('progress', true)
  79. }
  80. //上传完成
  81. const finishFileNum = ref(0)
  82. const uploadSuccess = (response, uploadFile, uploadFiles) => {
  83. finishFileNum.value++
  84. if (beforeFileNum.value === finishFileNum.value) {
  85. const fileList = getUploadFile(deepClone(uploadFiles))
  86. uploadClearFiles()
  87. emit('change', { type: 'success', fileList })
  88. emit('progress', false)
  89. }
  90. }
  91. //上传失败
  92. const errorFileNum = ref(0)
  93. const uploadError = (error, uploadFile, uploadFiles) => {
  94. errorFileNum.value++
  95. window?.$message?.error('上传失败')
  96. const num = finishFileNum.value + errorFileNum.value
  97. if (beforeFileNum.value === num) {
  98. const fileList = getUploadFile(deepClone(uploadFiles))
  99. uploadClearFiles()
  100. emit('change', { type: 'error', fileList })
  101. emit('progress', false)
  102. }
  103. }
  104. const uploadClearFiles = () => {
  105. finishFileNum.value = 0
  106. beforeFileNum.value = 0
  107. errorFileNum.value = 0
  108. uploadDisabled.value = false
  109. uploadRef.value?.clearFiles()
  110. }
  111. //获取文件
  112. const getUploadFile = (fileList) => {
  113. let fileArr = []
  114. for (let i = 0; i < fileList.length; i++) {
  115. const item = getObjValue(fileList[i]?.response?.data)
  116. fileArr.push(item)
  117. }
  118. return fileArr
  119. }
  120. </script>
  121. <style lang="scss">
  122. .hc-file-upload-box .el-upload-list .el-upload-list__item {
  123. .el-upload-list__item-status-label, .el-icon--close-tip {
  124. display: none;
  125. }
  126. }
  127. </style>