<template>
	<a-upload
		v-if="props.uploadMode === 'defaults'"
		v-model:file-list="fileList"
		name="file"
		:action="action"
		:headers="headers"
		:maxCount="props.uploadNumber"
		@change="handleChange"
		:before-upload="beforeUpload"
		:data="data"
	>
		<a-button>
			<upload-outlined/>
			上传
		</a-button>
	</a-upload>

	<a-upload
		v-if="props.uploadMode === 'pic'"
		v-model:file-list="fileList"
		name="file"
		accept="image/jpeg,image/jpg,image/png,"
		list-type="picture-card"
		:action="action"
		:headers="headers"
		:maxCount="props.uploadNumber"
		@change="handleChange"
		@preview="handlePreview"
		:before-upload="beforeUpload"
		:data="data"
	>
		<div v-if="fileList.length < props.uploadNumber">
			<plus-outlined/>
		</div>
	</a-upload>

	<a-upload-dragger
		v-if="props.uploadMode === 'drag'"
		v-model:fileList="fileList"
		name="file"
		:multiple="true"
		:action="action"
		:headers="headers"
		:maxCount="props.uploadNumber"
		@change="handleChange"
		:before-upload="beforeUpload"
		:data="data"
	>
		<p class="ant-upload-drag-icon">
			<inbox-outlined/>
		</p>
		<p class="ant-upload-text">单击或拖动文件到此区域上传</p>
		<p class="ant-upload-hint"></p>
	</a-upload-dragger>

	<div style="display: none">
		<a-image-preview-group :preview="{
        'visible' :openImage,
        'minScale' : 0.1,
        'current' : openIndex,
        onVisibleChange: vis => (openImage = vis)
      }">
			<a-image :width="200"
					 v-for="(item, index) in fileList" :src="item.url || item.thumbUrl"/>
		</a-image-preview-group>
	</div>
</template>

<script setup name="uploadIndex">
import tool from '@/utils/tool'
import sysConfig from '@/config/index'
import {message} from "ant-design-vue";

const fileList = ref([])
const emit = defineEmits({uploadDone: null})
const headers = ref({
	token: tool.data.get('TOKEN')
})
const props = defineProps({
	action: {
		type: String,
		default: '/dev/file/upload',
		required: false
	},
	// 上传方式 defaults（默认） | pic（图片上传） | drag（拖拽上传）
	uploadMode: {
		type: String,
		default: 'defaults',
		required: false
	},
	// 上传数量
	uploadNumber: {
		type: Number,
		default: 1,
		required: false
	},
	// 上传文件大小. 单位-KB
	size: {
		type: Number,
		default: null,
		required: false
	},
	// 图片会被压缩到的大小. 单位-b
	maxSize: {
		type: Number,
		default: null,
		required: false
	},
})
const action = sysConfig.API_URL + props.action

// 填充数据
const setFileList = (datas) => {
	fileList.value = datas.map(x => {
		return {status: 'done', url: x.url, name: x.name}
	})
}

// 文件上传前
const beforeUpload = file => {
	if (props.size) {
		const sizeCheck = (file.size / 1024) < props.size;
		if (!sizeCheck) {
			let msg = props.size < 1024 ? '上传的文件不能大于' + props.size + 'K' : '上传的文件不能大于' + (props.size / 1024).toFixed(2) + 'M'
			message.error(msg)
		}
		return sizeCheck
	}
	return true
}

// 上传时间，构造上传数组，主动推送至调用组件，单文件可以使用
const handleChange = () => {
	// 处理未调用上传方法的文件
	let list = []
	fileList.value.forEach(f => {
		if (f.status) {
			list.push(f)
		}
	})
	fileList.value = list
	// 单个文件可以使用回调方法，多个文件建议主动获取
	let result = []
	for (let a = 0; a < props.uploadNumber; a++) {
		const file = fileList.value[a]
		if (file && file.status === 'done' && file.response && file.response.code === 200) {
			const resultObj = {
				name: file.name,
				url: file.response.data
			}
			result.push(resultObj)
		}
	}
	emit('uploadDone', result)
}
// 通过DOM获取上传的文件
const uploadFileList = () => {
	if (fileList.value) {
		const result = []
		// 只返回这些就够用了，其他基本用不到
		fileList.value.forEach((item) => {
			const obj = {
				name: item.name,
				type: item.type,
				size: item.size,
				url: item.url || item.response.data
			}
			result.push(obj)
		})
		return result
	} else {
		return []
	}
}

// 图片预览
const openImage = ref(false)
const openIndex = ref(0)
const handlePreview = (file) => {
	openImage.value = true
	let index = fileList.value.findIndex(item => {
		if (item.uid === file.uid) {
			return true
		}
	})
	if (index !== -1) {
		openIndex.value = index
	} else {
		openIndex.value = 0
	}
}

const data = (file) => {
	let maxSize = props.maxSize
	if (maxSize !== null && maxSize !== undefined) {
		return {'maxSize': maxSize}
	} else {
		return {}
	}
}

// 抛出这个获取文件列表的方法
defineExpose({
	uploadFileList, setFileList
})
</script>

<style>
/* you can make up upload button and sample style by using stylesheets */
.ant-upload-select-picture-card i {
	font-size: 32px;
	color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
	margin-top: 8px;
	color: #666;
}
</style>
