PictureSelectUpload.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. <!-- 图片选择 -->
  2. <template>
  3. <div>
  4. <img :src="Picture" class="w-35px h-35px" @click="selectAndUpload" />
  5. </div>
  6. </template>
  7. <script lang="ts" setup>
  8. import Picture from '@/views/mall/promotion/kefu/components/asserts/picture.svg'
  9. import * as FileApi from '@/api/infra/file'
  10. defineOptions({ name: 'PictureSelectUpload' })
  11. const message = useMessage() // 消息弹窗
  12. /** 选择并上传文件 */
  13. const emits = defineEmits<{
  14. (e: 'send-picture', v: string): void
  15. }>()
  16. const selectAndUpload = async () => {
  17. const files: any = await getFiles()
  18. message.success('图片发送中请稍等。。。')
  19. const res = await FileApi.updateFile({ file: files[0].file })
  20. emits('send-picture', res.data)
  21. }
  22. /**
  23. * 唤起文件选择窗口,并获取选择的文件
  24. *
  25. * @param {Object} options - 配置选项
  26. * @param {boolean} [options.multiple=true] - 是否支持多选
  27. * @param {string} [options.accept=''] - 文件上传格式限制
  28. * @param {number} [options.limit=1] - 单次上传最大文件数
  29. * @param {number} [options.fileSize=500] - 单个文件大小限制(单位:MB)
  30. * @returns {Promise<Array>} 选择的文件列表,每个文件带有一个uid
  31. */
  32. async function getFiles(options = {}) {
  33. const { multiple, accept, limit, fileSize } = {
  34. multiple: true,
  35. accept: 'image/jpeg, image/png, image/gif', // 默认选择图片
  36. limit: 1,
  37. fileSize: 500,
  38. ...options
  39. }
  40. // 创建文件选择元素
  41. const input = document.createElement('input')
  42. input.type = 'file'
  43. input.style.display = 'none'
  44. if (multiple) input.multiple = true
  45. if (accept) input.accept = accept
  46. // 将文件选择元素添加到文档中
  47. document.body.appendChild(input)
  48. // 触发文件选择元素的点击事件
  49. input.click()
  50. // 等待文件选择元素的 change 事件
  51. try {
  52. return await new Promise((resolve, reject) => {
  53. input.addEventListener('change', (event: any) => {
  54. const filesArray = Array.from(event?.target?.files || [])
  55. // 从文档中移除文件选择元素
  56. document.body.removeChild(input)
  57. // 判断是否超出上传数量限制
  58. if (filesArray.length > limit) {
  59. reject({ errorType: 'limit', files: filesArray })
  60. return
  61. }
  62. // 判断是否超出上传文件大小限制
  63. const overSizedFiles = filesArray.filter((file: File) => file.size / 1024 ** 2 > fileSize)
  64. if (overSizedFiles.length > 0) {
  65. reject({ errorType: 'fileSize', files: overSizedFiles })
  66. return
  67. }
  68. // 生成文件列表,并添加 uid
  69. const fileList = filesArray.map((file, index) => ({ file, uid: Date.now() + index }))
  70. resolve(fileList)
  71. })
  72. })
  73. } catch (error) {
  74. console.error('选择文件出错:', error)
  75. throw error
  76. }
  77. }
  78. </script>
  79. <style lang="scss" scoped></style>