FormItemUpload.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <template>
  2. <div class="form-item-dashed hover flex w-full" @click="importModalClick">
  3. <div v-if="uploadValue" class="flex-1 truncate">{{ fileNameValue }}</div>
  4. <div v-else class="flex-1">点此上传文件</div>
  5. <div v-if="uploadValue" class="text-hover" @click.stop="previewClick">预览文件</div>
  6. </div>
  7. <!-- 上传 -->
  8. <hc-new-dialog v-model="importModal" :loading="uploadDisabled" save-text="确认上传" title="上传文件" widths="38rem" @close="importModalClose" @save="importModalYesClick">
  9. <el-upload
  10. ref="uploadRef" :accept="accept" :action="api + action" :auto-upload="false"
  11. :before-upload="beforeUpload" :data="uploadData" :disabled="uploadDisabled"
  12. :headers="getHeader()" :limit="1"
  13. :on-change="uploadChange"
  14. :on-error="uploadError" :on-exceed="uploadExceed" :on-progress="uploadprogress"
  15. :on-success="uploadSuccess" :show-file-list="false" class="hc-upload-border approach" drag
  16. >
  17. <div v-loading="uploadDisabled" class="hc-upload-loading upload-file-info" element-loading-text="上传中...">
  18. <template v-if="uploadFileInfo?.name">
  19. <HcIcon class="upload-file-icon" name="file-text" />
  20. <div class="upload-file-name">{{ uploadFileInfo?.name }}</div>
  21. </template>
  22. <template v-else>
  23. <HcIcon class="upload-icon" name="upload-cloud" />
  24. <div class="el-upload__text">拖动文件到这里 或 <em>点击这里选择文件</em> 并上传</div>
  25. </template>
  26. </div>
  27. <template #tip>
  28. <div class="el-upload__tip">允许格式:{{ formatTip }}, 文件大小 小于 {{ size }}MB</div>
  29. </template>
  30. </el-upload>
  31. </hc-new-dialog>
  32. </template>
  33. <script setup>
  34. import { onMounted, ref, watch } from 'vue'
  35. import { getHeader } from 'hc-vue3-ui'
  36. import { isFileSize } from 'js-fast-way'
  37. import { genFileId } from 'element-plus'
  38. import { toPdfPage } from '~uti/btn-auth'
  39. const props = defineProps({
  40. modelValue: {
  41. type: String,
  42. default: '',
  43. },
  44. datas: {
  45. type: Object,
  46. default: () => ({}),
  47. },
  48. action: {
  49. type: String,
  50. default: 'upload-file',
  51. },
  52. accept: {
  53. type: String,
  54. default: 'image/png,image/jpg,image/jpeg,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/pdf,.doc,.docx,application/msword',
  55. },
  56. size: {
  57. type: Number,
  58. default: 20,
  59. },
  60. formatTip: {
  61. type: String,
  62. default: 'png/jpg/jpeg/excel/pdf/doc/docx',
  63. },
  64. fileName:{
  65. type: String,
  66. default: '',
  67. },
  68. })
  69. //事件
  70. const emit = defineEmits(['progress', 'change', 'update:modelValue'])
  71. //变量
  72. const uploadRef = ref(null)
  73. const uploadData = ref(props.datas)
  74. const uploadFileInfo = ref({})
  75. const uploadDisabled = ref(false)
  76. const uploadValue = ref(props.modelValue)
  77. const fileNameVal = ref(props.fileName)
  78. const api = '/api/blade-resource/oss/endpoint/'
  79. //监听
  80. watch(() => [
  81. props.datas,
  82. props.modelValue,
  83. props.fileName,
  84. ], ([datas, val, name]) => {
  85. uploadData.value = datas
  86. uploadValue.value = val
  87. // getFileName(val)
  88. fileNameVal.value = name
  89. })
  90. onMounted(() => {
  91. // getFileName(props.modelValue)
  92. fileNameValue.value = fileNameVal.value
  93. })
  94. //上传弹窗
  95. const importModal = ref(false)
  96. const importModalClick = () => {
  97. importModal.value = true
  98. }
  99. //确认上传
  100. const importModalYesClick = () => {
  101. uploadRef.value?.submit()
  102. }
  103. //关闭上传
  104. const importModalClose = () => {
  105. uploadRef.value?.clearFiles()
  106. importModal.value = false
  107. }
  108. //获取文件名
  109. const fileNameValue = ref('')
  110. const getFileName = (url) => {
  111. if (url) {
  112. let num = url.lastIndexOf('/') + 1
  113. fileNameValue.value = url.substring(num)
  114. } else {
  115. fileNameValue.value = ''
  116. }
  117. }
  118. //上传前
  119. const beforeUpload = async (file) => {
  120. if (isFileSize(file?.size, props.size)) {
  121. return true
  122. } else {
  123. window?.$message?.warning('文件大小, 不能过' + props.size + 'M!')
  124. return false
  125. }
  126. }
  127. //超出限制时
  128. const uploadExceed = (files) => {
  129. uploadRef.value?.clearFiles()
  130. const file = files[0]
  131. file.uid = genFileId()
  132. uploadRef.value?.handleStart(file)
  133. }
  134. //上传中
  135. const uploadprogress = () => {
  136. uploadDisabled.value = true
  137. emit('progress', true)
  138. }
  139. //上传完成
  140. const uploadSuccess = ({ code, data }) => {
  141. uploadDisabled.value = false
  142. emit('progress', false)
  143. // const pdfUrl = data?.pdfUrl ?? ''
  144. const pdfUrl = data
  145. if (code === 200 && pdfUrl) {
  146. uploadValue.value = pdfUrl
  147. window?.$message?.success('上传成功')
  148. importModal.value = false
  149. // getFileName(pdfUrl)
  150. fileNameValue.value = data?.originalName
  151. //事件
  152. emit('update:modelValue', data?.pdfUrl)
  153. emit('change', data?.pdfUrl)
  154. } else {
  155. window?.$message?.error('上传失败')
  156. }
  157. }
  158. //上传失败
  159. const uploadError = () => {
  160. uploadDisabled.value = false
  161. emit('progress', false)
  162. window?.$message?.error('上传失败')
  163. }
  164. //文件改变时
  165. const uploadChange = (file) => {
  166. uploadFileInfo.value = file
  167. }
  168. //预览文件
  169. const previewClick = () => {
  170. toPdfPage(uploadValue.value)
  171. //const pdfUrl = uploadValue.value ?? ''
  172. //if (pdfUrl) window.open(pdfUrl, '_blank')
  173. }
  174. </script>
  175. <style lang="scss">
  176. .hc-upload-border.approach {
  177. .el-upload-dragger {
  178. padding: 24px;
  179. }
  180. .hc-upload-loading.upload-file-info {
  181. .hc-icon-i {
  182. font-size: 40px;
  183. }
  184. .upload-icon {
  185. color: var(--el-text-color-placeholder);
  186. }
  187. .upload-file-icon {
  188. color: var(--el-color-primary-light-5);
  189. }
  190. .el-upload__text {
  191. margin-top: 10px;
  192. }
  193. .upload-file-name {
  194. margin-top: 10px;
  195. font-size: 14px;
  196. text-align: center;
  197. color: var(--el-color-primary);
  198. }
  199. }
  200. .el-upload__tip {
  201. font-size: 14px;
  202. margin-top: 16px;
  203. color: var(--el-text-color-placeholder);
  204. }
  205. }
  206. </style>
  207. <style scoped>
  208. .form-item-dashed{
  209. border: 1px dashed lightgray;
  210. padding: 5px;
  211. }
  212. </style>