<!-- 
    filename: AssetsUpload.vue
    author: liubin
    date: 2023-10-12 16:40:14
    description: 上传资料/图片 组件
-->

<template>
	<div class="assets-upload">
		<section class="operations">
			<el-button type="text" class="expand-btn" @click="expand = !expand">
				<i class="el-icon-folder-opened" v-if="expand"></i>
				<i class="el-icon-folder" v-else></i>
				展开
			</el-button>
			<!-- <div class="preview-btn">
				<i class="el-icon-view"></i>
				预览
			</div> -->
		</section>
		<section
			class="file-area"
			:style="{
				height: expand ? 'auto' : isPicMode ? '180px' : '152px',
				gap: isPicMode ? '0 24px' : '24px',
				gridAutoRows: isPicMode ? '180px' : '152px',
			}">
			<el-upload
				class="equipment-upload"
				:disabled="disabled"
				drag
				:action="uploadUrl"
				:headers="headers"
				multiple
				:show-file-list="false"
				:before-upload="beforeUpload"
				:on-success="handleSuccess">
				<i class="el-icon-upload"></i>
				<div class="el-upload__text">
					<span>将文件拖到此处或</span>
					<em>点击上传</em>
				</div>
				<div class="el-upload__tip" slot="tip">
					{{
						isPicMode ? '仅支持上传 .jpg .png 格式文件, 且' : ''
					}}文件大小不超过2MB
				</div>
			</el-upload>
			<div
				v-for="(file, index) in files"
				:key="file.fileName"
				style="width: 100%">
				<div
					class="file-list__item"
					v-if="!isPicMode"
					:style="{
						background: isPicMode
							? `url(${file.fileUrl}) no-repeat`
							: `url(${defaultBg}) no-repeat`,
						backgroundSize: isPicMode ? '100% 100%' : '64px',
						backgroundPosition: isPicMode ? '0% 0%' : 'center',
					}"
					@click="handleDownload(file)"
					:data-name="file.fileName">
					<el-button
						v-if="!disabled"
						type="text"
						class="el-icon-delete"
						style="padding: 0"
						@click="(e) => handleDelete(file)" />
				</div>

				<el-image
					v-else
					class="file-list__item"
					style="width: 100%"
					:src="file.fileUrl"
					:preview-src-list="files.map((item) => item.fileUrl)"></el-image>
			</div>
		</section>
	</div>
</template>

<script>
import { getAccessToken } from '@/utils/auth';
import defaultBg from '../../../../assets/images/default-file-icon.png';

function checkSize(file, message) {
	const isLt2M = file.size / 1024 / 1024 < 2;
	if (!isLt2M) {
		message.error('上传文件大小不能超过 2MB!');
	}
	return isLt2M;
}

function checkPic(file, message) {
	const isJPG = file.type === 'image/jpeg';
	const isPNG = file.type === 'image/png';
	const isPic = isJPG || isPNG;
	if (!isPic) {
		message.error('上传图片只能是 JPG/PNG 格式!');
	}
	return isPic;
}

export default {
	name: 'AssetsUpload',
	components: {},
	model: {
		prop: 'dataSource',
		event: 'update',
	},
	props: {
		type: {
			type: String,
			default: 'image',
		},
		dataSource: {
			type: Array,
			default: () => [],
		},
		equipmentId: {
			type: String,
			default: '',
		},
		isPicMode: {
			type: Boolean,
			default: false,
		},
		disabled: {
			type: Boolean,
			default: false,
		},
	},
	emits: ['update-filelist'],
	data() {
		return {
			defaultBg,
			expand: false,
			headers: { Authorization: 'Bearer ' + getAccessToken() }, // 设置上传的请求头部
			fileList: [],
			uploadUrl: process.env.VUE_APP_BASE_API + '/admin-api/infra/file/upload',
			files: [],
			updateTimer: null,
		};
	},
	watch: {
		dataSource: {
			handler(val) {
				this.files = JSON.parse(JSON.stringify(val));
			},
			immediate: true,
			deep: true,
		},
	},
	mounted() {},
	methods: {
		// handle success, per file!
		handleSuccess(response, file, fileList) {
			this.$notify({
				title: '成功',
				message: '上传成功! 点击确认保存上传结果',
				type: 'success',
			});
			if (
				response == null ||
				!('data' in response) ||
				response.data == null ||
				response.data.trim() == ''
			) {
				this.$message.error('上传出错了!');
				return;
			}
			this.files.push({
				fileName: file.name,
				fileUrl: response.data,
				fileType: this.isPicMode ? 1 : 2,
			});
			// debugger;

			// 延时更新
			if (this.updateTimer) {
				clearTimeout(this.updateTimer);
			}
			this.updateTimer = setTimeout(() => {
				// console.log('[AssetsUpload] 更新上传列表');
				this.emitFilelist();
				clearTimeout(this.updateTimer);
				this.updateTimer = null;
			}, 500);
		},

		async handleDownload(file) {
			if (this.isPicMode) {
				// this.$emit('preview', file);
				const link = document.createElement('a');
				link.href = file.fileUrl;
				link.target = '_blank';
				document.body.appendChild(link);
				link.click();
				document.body.removeChild(link);
			} else {
				// this.$emit('download', file);
				const data = await this.$axios({
					url: file.fileUrl,
					method: 'get',
					responseType: 'blob',
				});
				const link = document.createElement('a');
				link.href = window.URL.createObjectURL(new Blob([data]));
				link.download = file.fileName;
				document.body.appendChild(link);
				link.click();
				document.body.removeChild(link);
				window.URL.revokeObjectURL(link.href);
			}
		},

		emitFilelist() {
			this.$emit('update', this.files);
		},

		handleRemove(file, fileList) {
			debugger;
		},

		handleDelete(file) {
			// fileName fileType 都可能一样，但 fileUrl 一定不一样
			this.files = this.files.filter((item) => item.fileUrl != file.fileUrl);
			this.$notify({
				title: '成功',
				message: '删除成功! 需点击确认保存删除结果',
				type: 'success',
			});
			this.emitFilelist();
		},

		beforeUpload(file) {
			if (this.isPicMode) {
				return checkPic(file, this.$message) && checkSize(file, this.$message);
			}
			return checkSize(file, this.$message);
		},

		handleUpload() {
			switch (this.type) {
				case 'image':
					break;
				case 'asset':
					break;
			}
		},
		updateFileList(appendFilelist) {
			// Array
			this.$emit('update-filelist', this.appendFilelist);
		},
	},
};
</script>

<style scoped lang="scss">
.assets-upload {
	position: relative;
}

.operations {
	position: absolute;
	top: -36px;
	right: 0;
	display: flex;
	align-items: center;
}

.expand-btn,
.preview-btn {
	font-size: 14px;
	line-height: 1.2;
	display: inline-block;
	padding-left: 20px;
	cursor: pointer;
	z-index: 1000;
}

.expand-btn {
	margin-right: 12px;
}

.preview-btn {
	color: #ccc;
}

.expand-btn,
.preview-btn:hover,
.preview-btn.active {
	// color: #0042d0;
	color: #0b58ff;
}

:deep(.equipment-upload) {
	.el-upload-dragger {
		width: 188px;
		height: 128px;
	}

	.el-icon-upload {
		margin: 12px 0;
		font-size: 48px;
	}

	.el-upload__text {
		font-size: 12px;
		line-height: 2px;
		display: flex;
		flex-direction: column;

		em {
			margin-top: 12px;
		}
	}

	.el-upload__tip {
		font-size: 12px;
		line-height: 1.5;
		color: #d1d1d1;
		margin: 0 0 12px;
		transform: translateY(-12px);
		user-select: none;
	}
}

.equipment-upload {
	margin-bottom: 24px;
}

.file-list {
	padding: 12px;
	border: 1px solid #ccc;
}

// custom
.file-area {
	display: grid;
	grid-template-columns: repeat(auto-fill, 188px);
	grid-auto-rows: 152px;
	gap: 48px 24px;
	overflow: hidden;
}

.file-list__item {
	height: 128px;
	background-color: #fff;
	border: 1px dashed #d9d9d9;
	border-radius: 6px;
	-webkit-box-sizing: border-box;
	box-sizing: border-box;
	text-align: center;
	cursor: pointer;
	position: relative;
	// overflow: hidden;

	&:hover {
		.el-icon-delete {
			display: block;
		}
	}

	.el-icon-delete {
		color: #ccc;
		position: absolute;
		top: 8px;
		right: 8px;
		display: none;

		&:hover {
			color: rgb(210, 41, 41);
		}
	}
}

.file-list__item:hover {
	border-color: #0b58ff;
}

.file-list__item::after {
	content: attr(data-name);
	position: absolute;
	left: 0;
	bottom: -26px;
	font-size: 14px;
	line-height: 2;
	color: #616161;
}

.default-icon {
	background: url(../../../../assets/images/default-file-icon.png) no-repeat;
	background-position: center;
	background-size: 64px;
}
</style>
