index.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <script setup lang="ts">
  2. import { ref, watch } from 'vue'
  3. import { UpFileToken } from '@/api/public/index'
  4. import { ElMessage, genFileId, ElLoading } from 'element-plus'
  5. import { GlobalStore } from '@/stores/index'
  6. import type { UploadProps, UploadRawFile, UploadFile, UploadFiles } from 'element-plus'
  7. interface FileListType {
  8. url?: string
  9. name?: string | number
  10. }
  11. interface ProTableProps {
  12. showWatch?: boolean
  13. // isImg?: boolean // 是否只能上传图片
  14. disabled?: boolean
  15. limit: number
  16. accept: string
  17. modelValue: string | string[]
  18. listType?: string
  19. errorText?: string
  20. successText?: string
  21. }
  22. const upload = ref()
  23. const globalStore = GlobalStore()
  24. const dialogImageUrl = ref('')
  25. const dialogVisible = ref(false)
  26. const uploadData = {
  27. token: '',
  28. key: ''
  29. }
  30. let loadingInstance: any = null
  31. const emit = defineEmits<{ (event: 'update:modelValue', value: string | string[]): void }>()
  32. // 图片查看 放大
  33. const handlePictureCardPreview = async (file: any) => {
  34. dialogImageUrl.value = file.url as string
  35. dialogVisible.value = true
  36. }
  37. // 图片上传之前
  38. const beforeUpload = (file: any) => {
  39. loadingInstance = ElLoading.service({
  40. lock: true,
  41. text: 'Loading',
  42. background: 'rgba(0, 0, 0, 0.7)'
  43. })
  44. uploadData.key = file.name
  45. }
  46. const clickToken = async () => {
  47. UpFileToken({ User_tokey: globalStore.GET_User_tokey }).then(res => {
  48. uploadData.token = res.Data as string
  49. })
  50. }
  51. // 图片上传超出界限
  52. const handleExceed: UploadProps['onExceed'] = (files: any) => {
  53. upload.value.clearFiles()
  54. const file = files[0] as UploadRawFile
  55. file.uid = genFileId()
  56. upload.value.handleStart(file)
  57. upload.value.submit()
  58. }
  59. let isWatch = ref(false)
  60. // 图片上传成功
  61. const onSuccess = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
  62. console.log('上传成功onSuccess1', response,uploadFiles)
  63. let ERPOSS = import.meta.env.VITE_BZD_ERPOSS_APP_API
  64. let keys:any = []
  65. uploadFiles.forEach((item: any,j:number) =>{
  66. if(item.response){
  67. keys.push(ERPOSS + item.response.key)
  68. }else{
  69. keys.push(item.url)
  70. }
  71. })
  72. emit('update:modelValue', keys)
  73. ElMessage.success(props.successText)
  74. loadingInstance.close()
  75. isWatch.value = true
  76. }
  77. // 图片上传失败
  78. const onError = () => {
  79. ElMessage.error(props.errorText)
  80. console.log('onError')
  81. }
  82. // 图片移除
  83. const handleRemove: UploadProps['onRemove'] = (uploadFile: any, uploadFiles: UploadFiles) => {
  84. if (limit.value === 1) {
  85. emit('update:modelValue', '')
  86. } else {
  87. let keys = uploadFiles.map((item: any) => {
  88. console.log('移除',uploadFile,item)
  89. if (item.url !== uploadFile.url) {
  90. return item.url
  91. }
  92. })
  93. console.log('keys',keys)
  94. emit('update:modelValue', keys)
  95. }
  96. }
  97. // 接受父组件参数,配置默认值
  98. const props = withDefaults(defineProps<ProTableProps>(), {
  99. showWatch: false,
  100. disabled: false,
  101. listType: 'picture-card',
  102. errorText: '图片上传失败!!',
  103. successText: '图片上传成功!!'
  104. })
  105. const fileList = ref<FileListType[]>([])
  106. // const isImg = ref<boolean>(props.isImg)
  107. const limit = ref<number>(props.limit)
  108. watch(() => props.modelValue, pre => {
  109. let arr:any = []
  110. if (!props.showWatch && !isWatch.value) {
  111. (pre as string[]).forEach((item: any) => {
  112. arr.push({
  113. url: item,
  114. name: genFileId()
  115. })
  116. })
  117. fileList.value = arr
  118. }
  119. })
  120. const clearfileList = () => {
  121. fileList.value = []
  122. }
  123. defineExpose({
  124. clearfileList
  125. })
  126. </script>
  127. <template>
  128. <div>
  129. <el-upload ref="upload" :accept="accept" :disabled="disabled" v-model:file-list="fileList"
  130. action="https://up-z2.qiniup.com" :list-type="listType" :limit="limit" :before-upload="beforeUpload"
  131. :auto-upload="true" :on-success="onSuccess" :on-error="onError" :on-exceed="handleExceed"
  132. :on-remove="handleRemove" :on-preview="handlePictureCardPreview" :data="uploadData" @click="clickToken">
  133. <!-- <el-upload v-model:file-list="data.fileList" style="width: 50px;height: 50px;" action="https://up-z2.qiniup.com"
  134. :disabled="data.drawerTiti == '详情' ? true : false" list-type="picture-card" :on-preview="handlePictureCardPreview"
  135. :on-remove="handleRemove">
  136. <el-icon>
  137. <Plus />
  138. </el-icon>
  139. </el-upload> -->
  140. <slot></slot>
  141. <template #tip>
  142. <div class="el-upload__tip">
  143. <slot name="tip"></slot>
  144. </div>
  145. </template>
  146. </el-upload>
  147. <el-dialog v-model="dialogVisible" style="z-index: 10;" :append-to-body="true">
  148. <img w-full :src="dialogImageUrl" class="full-img" alt="Preview Image" />
  149. </el-dialog>
  150. </div>
  151. </template>
  152. <style scoped>
  153. .full-img {
  154. width: 100%;
  155. height: 100%;
  156. }
  157. .el-upload--picture-card {
  158. height: 50px;
  159. width: 50px;
  160. }
  161. </style>