index.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <template>
  2. <u-upload v-bind="$attrs" :fileList="fileList" @afterRead="afterRead" @delete="deletePic" :notFile="notFile"
  3. :disabled="disabled" :multiple="multiple" :maxCount="maxCount">
  4. </u-upload>
  5. <view class="tips" v-if="tips">{{tips}}</view>
  6. </template>
  7. <script setup name="cyUpload">
  8. import {
  9. watch,
  10. ref
  11. } from 'vue';
  12. import baseUrl from '@/config/request.js';
  13. const emit = defineEmits(['update:filename', 'update:keyValue', 'success','update:loading'])
  14. const props = defineProps({
  15. filename: {
  16. type: [Array, String],
  17. default: () => []
  18. },
  19. url: {
  20. type: String,
  21. default: '/app/common/upload'
  22. },
  23. notFile: {
  24. type: Boolean,
  25. default: false
  26. },
  27. tips: {
  28. type: String
  29. },
  30. disabled: {
  31. type: Boolean,
  32. default: false
  33. },
  34. isUpdate: {
  35. type: Boolean,
  36. default: false
  37. },
  38. loading:{
  39. type:Boolean,
  40. default:false
  41. },
  42. multiple: {
  43. type: Boolean,
  44. default: false
  45. },
  46. maxCount: {
  47. type: [Number, String],
  48. default: 9
  49. }
  50. })
  51. const fileList = ref([])
  52. watch(() => props.filename, (filename) => {
  53. if (!filename) return fileList.value = []
  54. if (typeof filename == 'string') {
  55. fileList.value = filename.split(',').map(v => ({
  56. url: baseUrl + v,
  57. }))
  58. } else {
  59. fileList.value = filename && filename.length > 0 ? filename.map(v => ({
  60. url: v.url || v,
  61. })) : []
  62. }
  63. }, {
  64. immediate: true,
  65. deep: true
  66. })
  67. const afterRead = async (e) => {
  68. const files = Array.isArray(e.file) ? e.file : [e.file]
  69. emit('update:loading', true)
  70. try {
  71. for (const file of files) {
  72. const idx = fileList.value.length
  73. fileList.value.push({
  74. ...file,
  75. status: 'uploading',
  76. message: '上传中...',
  77. })
  78. const result = await uploadFilePromise(file.url, props.url)
  79. if (fileList.value[idx]) {
  80. fileList.value[idx].url = result.url || result.data?.url || result.fileName || file.url
  81. fileList.value[idx].status = 'success'
  82. fileList.value[idx].message = ''
  83. }
  84. emit('success', result)
  85. }
  86. emit('update:filename', fileList.value.map(v => v.url).filter(Boolean))
  87. } finally {
  88. emit('update:loading', false)
  89. }
  90. }
  91. const deletePic = (event) => {
  92. fileList.value.splice(event.index, 1);
  93. emit('update:filename', fileList.value.map(v => v.url).filter(Boolean))
  94. }
  95. const uploadFilePromise = (url, baseStr = '/app/common/upload') => {
  96. let token = uni.getStorageSync('token')
  97. return new Promise((resolve, reject) => {
  98. let a = uni.uploadFile({
  99. url: baseUrl + baseStr,
  100. filePath: url,
  101. name: 'file',
  102. header: {
  103. "Authorization": token
  104. },
  105. success: (res) => {
  106. let respic = JSON.parse(res.data)
  107. resolve(respic)
  108. },
  109. fail: reject
  110. });
  111. });
  112. };
  113. </script>
  114. <style lang="scss" scoped>
  115. .tips {
  116. font-size: 24rpx;
  117. font-family: PingFangSC, PingFang SC;
  118. font-weight: 400;
  119. color: #969696;
  120. line-height: 48rpx;
  121. margin-top: 10rpx;
  122. }
  123. ::v-deep .align-right .u-upload__wrap {
  124. justify-content: flex-end;
  125. }
  126. </style>