<template>
	<section>
		<slot :open="open">
			<el-button type="info" plain icon="el-icon-upload" @click="open()"></el-button>
		</slot>
		<el-dialog v-model="dialog" title="导入" :width="550" :close-on-click-modal="false" append-to-body
				   destroy-on-close>
			<el-progress v-if="loading" :text-inside="true" :stroke-width="20" :percentage="percentage"
						 style="margin-bottom: 15px;"/>
			<div v-loading="loading">
				<el-upload ref="uploaderRef"
						   drag
						   :accept="accept"
						   :maxSize="maxSize"
						   :limit="1"
						   :data="data"
						   :show-file-list="false"
						   :http-request="request"
						   :before-upload="before"
						   :on-progress="progress"
						   :on-success="success"
						   :on-error="error"
				>
					<slot name="uploader">
						<el-icon class="el-icon--upload">
							<el-icon-upload-filled/>
						</el-icon>
						<div class="el-upload__text">
							将文件拖到此处或 <em>点击选择文件上传</em>
						</div>
					</slot>
					<template #tip>
						<div class="el-upload__tip">
							<template v-if="tip">{{ tip }}</template>
							<template v-else>请上传小于或等于 {{ maxSize }}M 的 {{ accept }} 格式文件</template>
							<p v-if="templateUrl" style="margin-top: 7px;">
								<el-link :href="templateUrl" target="_blank" type="primary" underline="never">
									下载导入模板
								</el-link>
							</p>
						</div>
					</template>
				</el-upload>
				<el-form v-if="$slots.form" inline label-width="100px" label-position="left" style="margin-top: 18px;">
					<slot name="form" :formData="formData"></slot>
				</el-form>
			</div>
		</el-dialog>
	</section>
</template>

<script setup>
import {getCurrentInstance, ref} from "vue"

const emit = defineEmits(["success"])
const uploaderRef = ref(null)
const props = defineProps({
	api: {type: Function, required: true},
	data: {
		type: Object, default: () => {
		}
	},
	accept: {type: String, default: ".xls, .xlsx"},
	maxSize: {type: Number, default: 10},
	tip: {type: String, default: ""},
	templateUrl: {type: String, default: ""}
})
const {proxy} = getCurrentInstance()

let dialog = ref(false)
let loading = ref(false)
let percentage = ref(0)
let formData = ref({})

function open() {
	dialog.value = true
	formData.value = {}
}

function close() {
	dialog.value = false
}

function before(file) {
	const maxSize = file.size / 1024 / 1024 < props.maxSize;
	if (!maxSize) {
		proxy.$message.warning(`上传文件大小不能超过 ${props.maxSize}MB!`);
		return false;
	}
	loading.value = true
}

function progress(e) {
	percentage.value = e.percent
}

function success(res, file) {
	uploaderRef.value.handleRemove(file)
	uploaderRef.value.clearFiles()
	loading.value = false
	percentage.value = 0
	close()
	emit('success', res)
	proxy.$message.success(res.msg);
}

function error(err) {
	loading.value = false
	percentage.value = 0
	proxy.$notify.error({
		title: '上传文件未成功',
		message: err
	})
}

function request(param) {
	Object.assign(param.data, formData.value)
	const data = new FormData();
	data.append(param.filename, param.file);
	for (const key in param.data) {
		data.append(key, param.data[key]);
	}
	props.api(data, {
		onUploadProgress: e => {
			const complete = parseInt(((e.loaded / e.total) * 100) | 0, 10)
			param.onProgress({percent: complete})
		}
	}).then(res => {
		param.onSuccess(res)
	}).catch(err => {
		param.onError(err)
	})
}
</script>

<style lang="scss" scoped>

</style>
