<template>
    <el-upload ref="uploadRef" class="hc-file-upload-box" :action="api + action" :headers="getTokenHeader()" :data="uploadData" :accept="accept" :disabled="uploadDisabled" :limit="1" :show-file-list="false"
               :on-success="uploadSuccess" :on-exceed="uploadExceed" :on-error="uploadError" :before-upload="beforeUpload" :on-progress="uploadprogress">
        <slot></slot>
    </el-upload>
</template>

<script setup>
import {ref,watch,onMounted} from "vue";
import {getTokenHeader} from '~src/api/request/header';
import {isSize, deepClone, getObjValue} from "vue-utils-plus"
import {genFileId} from "element-plus";
const props = defineProps({
    datas: {
        type: Object,
        default: () => ({})
    },
    api: {
        type: String,
        default: "/api/blade-resource/oss/endpoint/"
    },
    action: {
        type: String,
        default: "upload-file"
    },
    accept: {
        type: String,
        default: "image/png,image/jpg,image/jpeg,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/pdf,.doc,.docx,application/msword"
    },
    size: {
        type: Number,
        default: 60
    }
})

//变量
const uploadRef = ref(null)
const uploadData = ref(props.datas)
const uploadDisabled = ref(false)

//监听
watch(() => [
    props.datas,
], ([datas]) => {
    uploadData.value = datas
})

//渲染完成
onMounted(()=> {
    beforeFileNum.value = 0
    finishFileNum.value = 0
    errorFileNum.value = 0
})

//事件
const emit = defineEmits(['change', 'progress'])

//上传前
const beforeFileNum = ref(0)
const beforeUpload = async (file) => {
    if (isSize(file?.size, props.size)) {
        beforeFileNum.value ++;
        return true;
    } else {
        beforeFileNum.value = 0;
        window?.$message?.warning(`文件大小, 不能过${props.size}M!`);
        return false;
    }
}

//超出限制时
const uploadExceed = (files) => {
    uploadRef.value?.clearFiles()
    const file = files[0]
    file.uid = genFileId()
    uploadRef.value?.handleStart(file)
}

//上传中
const uploadprogress = () => {
    uploadDisabled.value = true
    emit('progress', true)
}

//上传完成
const finishFileNum = ref(0)
const uploadSuccess = (response, uploadFile, uploadFiles) => {
    finishFileNum.value ++;
    if (beforeFileNum.value === finishFileNum.value) {
        const fileList = getUploadFile(deepClone(uploadFiles))
        uploadClearFiles()
        emit('change', {type: 'success', fileList})
        emit('progress', false)
    }
}

//上传失败
const errorFileNum = ref(0)
const uploadError = (error,uploadFile,uploadFiles) => {
    errorFileNum.value ++;
    window?.$message?.error('上传失败');
    const num = finishFileNum.value + errorFileNum.value;
    if (beforeFileNum.value === num) {
        const fileList = getUploadFile(deepClone(uploadFiles))
        uploadClearFiles()
        emit('change', {type: 'error', fileList})
        emit('progress', false)
    }
}

const uploadClearFiles = () => {
    finishFileNum.value = 0
    beforeFileNum.value = 0
    errorFileNum.value = 0
    uploadDisabled.value = false
    uploadRef.value?.clearFiles()
}

//获取文件
const getUploadFile = (fileList) => {
    let fileArr = [];
    for (let i = 0; i < fileList.length; i++) {
        const item = getObjValue(fileList[i]?.response?.data)
        fileArr.push(item)
    }
    return fileArr
}
</script>

<style lang="scss">
.hc-file-upload-box .el-upload-list .el-upload-list__item {
    .el-upload-list__item-status-label, .el-icon--close-tip {
        display: none;
    }
}
</style>
