<!--
 * @Author: zhaojinfeng 121016171@qq.com
 * @Date: 2023-08-16 17:33:41
 * @LastEditors: zhaojinfeng 121016171@qq.com
 * @LastEditTime: 2023-08-18 17:02:06
 * @FilePath: \vue3\packages\upload-list\index.vue
 * @Description:
 *
-->
<template>
  <el-upload
    v-model:file-list="userFiles"
    :accept="accept"
    :disabled="disabled"
    :before-upload="beforeUpload"
    :http-request="httpRequest"
  >
    <el-button type="primary" plain>
      点击上传
    </el-button>
  </el-upload>
</template>

<script lang="ts" setup name="ThUploadList">
import type { UploadRawFile, UploadRequestOptions, UploadUserFile } from 'element-plus'

const props = withDefaults(
  defineProps<{
    /** 可上传的文件类型 */
    accept?: string
    /** 文件集合 */
    fileList?: FileVO[]
    /** 文件上传的请求函数 */
    request: (formData: FormData, args?: any) => Promise<FileVO>
    /** 自定义文件上传路径前缀 */
    filePath?: string
    /** 禁用组件 */
    disabled?: boolean
    /** 最大上传大小（Mb） */
    maxsize?: number
  }>(), {
    fileList: () => [],
    maxsize: 100,
  },
)

const emit = defineEmits<{
  (event: 'update:fileList', file: FileVO[]): void
}>()

const userFiles = ref<UploadUserFile[]>([])

function beforeUpload(rawFile: UploadRawFile) {
  if (rawFile.size > props.maxsize * 1024 * 1024) {
    const err = `文件大小不能超过${props.maxsize}Mb`
    ElMessage.error(err)
    return false
  }
  return true
}
async function httpRequest({ file, onProgress, onSuccess, onError }: UploadRequestOptions) {
  const formData = new FormData()
  formData.append('file', file)
  if (props.filePath)
    formData.append('filePath', props.filePath)
  try {
    const res = await props.request(formData, {
      onUploadProgress: onProgress,
    })
    onSuccess(res)
    emit('update:fileList', [...props.fileList, res])
  }
  catch (err) {
    onError(err)
  }
}

userFiles.value = props.fileList.map(file => ({
  name: file.name!,
  url: file.url,
  status: 'success',
  percentage: 100,
  uid: file.id,
}))

watch(() => userFiles, (files) => {
  emit('update:fileList', files.value.map(file => ({
    name: file.name!,
    url: file.url,
    status: 'success',
    percentage: 100,
  })))
})
</script>
