ut-files-upload.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <template>
  2. <view class="">
  3. <up-button v-if="fileList.length < count" class="mb-10" @click="addFiles" :customStyle="{ color: '#2a6d52', backgroundColor: '#F9FDFB', borderColor: '#E1EEE9' }">
  4. <up-icon class="mr-5" name="plus-circle" color="#2a6d52" size="30rpx"></up-icon>
  5. <span>{{ btnText }}</span>
  6. </up-button>
  7. <template v-for="(file, index) in fileList" :key="index">
  8. <view class="d-flex a-c file-item-box mb-10" @click="downloadFile(file)">
  9. <view class="mr-20">
  10. <template v-if="['doc', 'docx', 'DOC', 'DOCX'].includes(getFileSuffix(file?.fileName))">
  11. <image class="file-icon" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images/common/doc.png" mode="widthFix" />
  12. </template>
  13. <template v-if="['pdf', 'PDF'].includes(getFileSuffix(file?.fileName))">
  14. <image class="file-icon" src="https://ta.zycpzs.cn/oss-file/smart-trace/szyy/images/common/pdf.png" mode="widthFix" />
  15. </template>
  16. </view>
  17. <view class="flex1 ov-hd mr-20">
  18. <view class="f-s-28 c-light-black f-w-5 mb-8">{{ file?.fileName }}</view>
  19. <view v-if="file?.size" class="f-s-24 c-999">大小:{{changeByte(file?.size)}}</view>
  20. </view>
  21. <view class="d-flex flex-cln j-c a-c" @click="deleteFile(index)">
  22. <up-icon size="30rpx" color="#f56c6c" name="trash-fill"></up-icon>
  23. <view class="f-s-22 c-danger">删除</view>
  24. </view>
  25. </view>
  26. </template>
  27. </view>
  28. </template>
  29. <script setup>
  30. import { ref } from 'vue';
  31. import upload, { exportDataFn } from '@/utils/upload';
  32. import { changeByte, getFileSuffix } from '@/utils/ruoyi';
  33. const props = defineProps({
  34. modelValue: {
  35. type: [Array, Object],
  36. default: () => []
  37. },
  38. btnText: {
  39. type: String,
  40. default: '上传文件'
  41. },
  42. disabled: {
  43. type: Boolean,
  44. default: false
  45. },
  46. maxSize: {
  47. type: Number,
  48. default: 10
  49. },
  50. count: {
  51. type: Number,
  52. default: 5 // 默认最多上传5个文件
  53. },
  54. extension: {
  55. type: Array,
  56. default: () => ['PDF', 'pdf', 'doc', 'docx', 'DOC', 'DOCX'] // 默认支持的文件类型
  57. }
  58. });
  59. const fileList = ref(props.modelValue || []);
  60. const emit = defineEmits(['update:modelValue']);
  61. const addFiles = async () => {
  62. if (props.disabled) return;
  63. uni.chooseMessageFile({
  64. count: props.count - fileList.value.length,
  65. type: 'file',
  66. extension: props.extension,
  67. success (res) {
  68. const tempFiles = res.tempFiles;
  69. uploadFiles(tempFiles)
  70. },
  71. fail (err) {
  72. console.error(err);
  73. uni.showToast({
  74. title: '选择文件失败',
  75. icon: 'none'
  76. });
  77. }
  78. });
  79. };
  80. const deleteFile = (index) => {
  81. fileList.value.splice(index, 1);
  82. emit('update:modelValue', fileList.value);
  83. };
  84. // 上传多个文件
  85. const uploadFiles = async (files) => {
  86. const uploadedFiles = [];
  87. for (const file of files) {
  88. if (file.size > props.maxSize * 1024 * 1024) {
  89. uni.showToast({
  90. title: `文件 ${file.name} 超过最大限制 ${props.maxSize}MB`,
  91. icon: 'none'
  92. });
  93. continue;
  94. }
  95. try {
  96. const res = await upload({
  97. filePath: file.path,
  98. url: '/resource/oss/upload',
  99. formData: {
  100. fileName: file.name,
  101. }
  102. });
  103. if (res.code === 200) {
  104. uploadedFiles.push({
  105. ...res.data,
  106. fileName: file.name,
  107. });
  108. } else {
  109. uni.showToast({
  110. title: `上传失败: ${res.message}`,
  111. icon: 'none'
  112. });
  113. }
  114. } catch (error) {
  115. uni.showToast({
  116. title: '上传失败',
  117. icon: 'none'
  118. });
  119. }
  120. }
  121. fileList.value = [...fileList.value, ...uploadedFiles];
  122. emit('update:modelValue', fileList.value);
  123. };
  124. </script>
  125. <style lang="scss" scoped>
  126. .file-item-box {
  127. padding: 24rpx 30rpx;
  128. background-color: #fff;
  129. border: 1rpx solid $u-border-color;
  130. border-radius: 16rpx;
  131. }
  132. .file-icon {
  133. width: 56rpx;
  134. height: 56rpx;
  135. }
  136. </style>