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