<template>
	<div class="w100">
		<slot name="head"> </slot>
		<el-upload
			class="file-upload w100"
			v-model:file-list="fileList"
			:action="action"
			:multiple="true"
			:accept="fileTypeAccept"
			:on-exceed="handleExceed"
			ref="uploadListRef"
			name="fileData"
			:on-change="handleChangeFile"
			:on-success="updateSuccess"
			:disabled="uploadingDisabled"
			:on-error="onUploadError"
			:limit="fileLimit"
			:on-remove="handRemove"
			:before-upload="beforeUpload"
		>
			<template v-if="!uploadingDisabled">
				<el-button> <SvgIcon name="ele-Upload" /> {{ props.name }} </el-button>
			</template>
			<template v-else>
				<el-button v-if="fileList && fileList.length" disabled :loading="uploadLoading">
					{{ uploadLoading ? '上传中，请稍等...' : props.name }}
				</el-button>
				<el-button v-else disabled> 暂无附件 </el-button>
			</template>
			<slot> </slot>
			<template #file="{ file }">
				<el-skeleton :loading="uploadLoading" animated>
					<template #template>
						<el-skeleton-item variant="image" />
					</template>
					<template #default>
						<div class="el-upload-list__item-info" v-loading="uploadLoading">
							<a class="el-upload-list__item-name" @click="onPreview(file)">
								<SvgIcon class="mr3" name="ele-Document" size="16px" />
								<span class="el-upload-list__item-file-name" :title="file.name">{{ file.name }}</span>
								<span @click.stop="" v-if="!props.readonly">
									<el-switch
										class="ml20 mr10"
										v-model="file.publicity"
										active-text="公开"
										inactive-text="不公开"
										inline-prompt
										:active-value="1"
										:inactive-value="0"
										@change="updateData"
									/>
								</span>
							</a>
						</div>
						<SvgIcon name="ele-Download" size="14px" class="el-icon--close mr20" title="下载附件" @click="handleDownload(file)" />
						<SvgIcon name="ele-Close" class="el-icon--close" size="14px" title="删除附件" @click="handleRemove(file)" v-if="!props.readonly" />
					</template>
				</el-skeleton>
			</template>
			<template #tip v-if="!props.readonly">
				<div class="el-upload__tip">大小限制：20M</div>
			</template>
		</el-upload>
		<slot name="footer"> </slot>
	</div>
</template>
<script setup lang="ts" name="annexList">
import { computed, ref, watch } from 'vue';
import { ElMessage, ElMessageBox, UploadFile, UploadFiles, UploadUserFile } from 'element-plus';
import Other from '@/utils/other';
import { fileDownloadByUrl } from '@/api/public/file';
import { useAppConfig } from '@/stores/appConfig';
import { storeToRefs } from 'pinia';
const emit = defineEmits(['update:modelValue', 'update:format', 'change']);
const props = defineProps({
	name: {
		// 上传按钮名称
		type: String,
		default: '上传附件',
	},
	fileLimit: {
		// 限制上传数量
		type: Number,
		default: 10,
	},
	fileSize: {
		// 限制上传大小(M)
		type: Number,
		default: 20,
	},
	businessId: {
		// 业务id
		type: String,
		default: '',
	},
	readonly: {
		// 只读（详情查看）
		type: Boolean,
		default: false,
	},
	classify: {
		// 附件分类
		type: String,
		required: true,
		default: '',
	},
	modelValue: {
		// 附件数据
		type: Array,
		default: () => [],
	},
});
// 创建本地消息变量，并初始化为 props.message
const uploadingDisabled = ref(props.readonly);
// 监听 props.message 的变化，并同步更新 localMessage
watch(
	() => props.readonly,
	(newVal) => {
		uploadingDisabled.value = newVal;
	}
);
const uploadLoading = ref(false);
const beforeUpload = () => {
	uploadLoading.value = true; // 模拟上传过程
	uploadingDisabled.value = true;
};

const appConfigStore = useAppConfig();
const { AppConfigInfo } = storeToRefs(appConfigStore); // 系统配置信息
const fileTypeAccept = AppConfigInfo.value?.fileExt;
const action = computed(() => {
	return import.meta.env.VITE_API_UPLOAD_URL + '/file/upload?source=hotline';
	// return 'http://171.94.154.2:50105/hlfs/file/upload?source=hotline';
});
// 上传成功
const fileList = ref<EmptyArrayType>([]);
const uploadListRef = ref<RefType>(); // 上传组件ref
// 上传成功
const updateSuccess = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
	if (response.result.path) {
		setTimeout(() => {
			updateData();
			uploadLoading.value = false;
			uploadingDisabled.value = false;
		}, 100);
	} else {
		uploadListRef.value.handleRemove(uploadFile);
		ElMessage.error('上传失败');
	}
};
// 更新数据
const updateData = () => {
	emit('update:modelValue', fileList.value);
	const data = formatData(Other.deepClone(fileList.value));
	emit('update:format', data);
	emit('change', fileList.value, data);
};
// 格式化数据
const formatData = (data: any) => {
	return data.map((v: any) => {
		return {
			name: v.name,
			fileName: v.name,
			additions: v?.response?.result.id,
			path: v?.response?.result?.path,
			publicity: v?.publicity ? 1 : 0,
			classify: props.classify,
			key: props.businessId,
			url: import.meta.env.VITE_API_UPLOAD_URL + v?.response?.result?.path,
			allPath: import.meta.env.VITE_API_UPLOAD_URL + v?.response?.result?.path,
		};
	});
};
//文件限制
const handleExceed = (files: any, uploadFiles: UploadUserFile[]) => {
	ElMessage.warning(`当前限制最多上传 ${props.fileLimit} 个文件,已经上传了${uploadFiles.length}个文件，本次选择了 ${files.length} 个文件。`);
	setTimeout(() => {
		uploadLoading.value = false; // 模拟上传过程
		uploadingDisabled.value = false;
	}, 100);
};
//限制文件大小
const handleChangeFile = (file: any, fileList: any) => {
	//限制上传文件大小
	setTimeout(() => {
		updateData();
	}, 100);
	if (!file) return;
	const isLt2M = file.size / 1024 / 1024 < props.fileSize;
	if (!isLt2M) {
		const currIdx = fileList.indexOf(file);
		fileList.splice(currIdx, 1);
		ElMessage.warning(`文件超过了最大限度 ${props.fileSize} MB!`);
		setTimeout(() => {
			uploadLoading.value = false; // 模拟上传过程
			uploadingDisabled.value = false;
		}, 100);
		return false;
	}
};
// 删除文件
const handRemove = () => {
	setTimeout(() => {
		updateData();
	}, 100);
};
// 上传失败
const onUploadError = (error: Error,uploadFile: UploadFile, uploadFiles: UploadFiles) => {
	try {
		const errMessage = JSON.parse(error.message)?.message ?? `文件 ${uploadFile.name} 上传失败`;
		// 从文件列表中移除失败的文件
		fileList.value = fileList.value.filter(item => item.response);
		console.error(`文件 ${uploadFile.name} 上传失败`);
		console.log(fileList.value,'111')
		ElMessage.error(errMessage);
	} catch (e) {
		ElMessage.error(`文件 ${uploadFile.name} 上传失败`);
	}
	setTimeout(() => {
		updateData();
		uploadLoading.value = false; // 模拟上传过程
		uploadingDisabled.value = false;
	}, 100);
};
// 删除
const handleRemove = (uploadFile: any) => {
	ElMessageBox.confirm(`确定要删除该附件吗？`, '提示', {
		confirmButtonText: '确认',
		cancelButtonText: '取消',
		type: 'warning',
		draggable: true,
		cancelButtonClass: 'default-button',
	})
		.then(() => {
			uploadListRef.value.handleRemove(uploadFile);
		})
		.catch(() => {});
};
// 下载
const handleDownload = (uploadFile: any) => {
	const id = uploadFile.path ? uploadFile.additions : uploadFile.response.result.id ? uploadFile.response?.result.id : '';
	if (!id) {
		ElMessage.error('附件不存在');
		return;
	}
	// 确定是否下载
	ElMessageBox.confirm(`确定要下载附件 ${uploadFile.name} 吗？`, '提示', {
		confirmButtonText: '确认',
		cancelButtonText: '取消',
		type: 'warning',
		draggable: true,
		cancelButtonClass: 'default-button',
	})
		.then(() => {
			fileDownloadByUrl({
				Source: 'hotline',
				Id: uploadFile.response.result.id,
			}).then((res: any) => {
				let blob: Blob = new Blob([res.data], { type: res.data.type }); // 创建blob 设置blob文件类型 data 设置为后端返回的文件(例如mp3,jpeg) type:这里设置后端返回的类型 为 mp3
				let down: HTMLAnchorElement = document.createElement('a'); // 创建A标签
				let href: string = window.URL.createObjectURL(blob); // 创建下载的链接
				down.href = href; // 下载地址
				down.download = uploadFile.response.result.fileName; // 下载文件名
				document.body.appendChild(down);
				down.click(); // 模拟点击A标签
				document.body.removeChild(down); // 下载完成移除元素
				window.URL.revokeObjectURL(href); // 释放blob对象
			});
		})
		.catch(() => {});
};
// 预览
const onPreview = (file: any) => {
	const path = file.path ? file.path : file.response.result.path ? file.response?.result.path : '';
	if (!path) {
		ElMessage.error('附件不存在');
		return;
	}
	// 确定是否下载
	const url = import.meta.env.VITE_API_UPLOAD_URL + path;
	window.open(url);
};
watch(
	() => props.modelValue,
	(n: any) => {
		fileList.value = n;
		emit('update:modelValue', fileList.value);
		const data = formatData(Other.deepClone(fileList.value));
		emit('update:format', data);
	},
	{ deep: true, immediate: true }
);
</script>
<style lang="scss">
.file-upload {
	.el-upload__tip {
		margin-top: 0 !important;
	}
	.el-upload-list {
		display: flex !important;
		flex-wrap: wrap;
		.el-upload-list__item {
			max-width: 300px !important;
		}
	}
}
</style>
