<!--
  图片上传组件
  @author terrfly
  @site https://www.jeequan.com
  @date 2022/11/30 18:18
-->
<template>
	<view style="flex-grow: 1">
		<!-- 图片内 带 x 号的模式。  -->
		<template v-if="props.mode == 'img'">
			<!-- 包含图片 -->
			<template v-if="props.src">
				<view class="image-wrapper">
					<image v-if="!props.readonly" @tap="delImg" class="del-image" src="/static/iconImg/icon-x-white.svg" mode="scaleToFill" />
					<image class="default-img" :src="props.src" @tap="preview"></image>
				</view>
			</template>
			<template v-else>
				<!-- 不包含图片 -->
				<view @tap="chooseImageAndUpload" style="flex-grow: 1; display: flex; justify-content: space-between; align-items: center">
					<image
						v-if="!props.readonly"
						style="width: 150rpx; height: 150rpx; background-color: #f7f7f7; border-radius: 15rpx"
						src="/static/iconImg/default-img.svg"
						mode="scaleToFill"
					/>
					<image src="/pageDevice/static/devIconImg/icon-arrow-sex.svg" mode="scaleToFill" style="width: 120rpx; height: 120rpx" />
				</view>
			</template>
		</template>

		<!-- 页面图片 加入 切换按钮  -->
		<template v-if="props.mode == 'viewbtn'">
			<image class="default-img" :src="props.src" @tap="preview" mode="aspectFill"></image>

			<!-- 图片预览（手写非原生） -->
			<enlarge v-if="vdata.showEnlarge" :imgs="props.src" :changeIsShow="!props.readonly" @chooseImg="chooseImageAndUpload" @enlargeClose="vdata.showEnlarge = false" />
		</template>
	</view>
</template>

<script setup>
import { ref, reactive } from 'vue';
import http from '@/http/http.js';
import infoBox from '@/commons/utils/infoBox.js';
import enlarge from './enlarge.vue'; // 图片预览
import { API_URL_SINGLE_FILE_UPLOAD, $ossFilesForm } from '@/http/apiManager.js';

// emit 父组件使用： v-model:src="val" 进行双向绑定。
const emit = defineEmits(['update:src', 'change']);

// 定义 父组件传参
const props = defineProps({
	src: { type: String, default: '' }, // 双向绑定  文件地址
	bizType: { type: String, default: '' }, // 业务类型
	imgSize: { type: Number, default: 5 }, // 上传图片大小限制 默认 5 M

	// 两种模式： img - 图片包含删除按钮支持删除，  viewbtn-图片内支预览按钮切换。
	mode: { type: String, default: 'img' },

	// 预览模式， 不支持切换图片。
	readonly: { type: Boolean, default: false }
});

// 定义响应式数据
const vdata = reactive({
	showEnlarge: false,

	action: '', // 文件form表单请求地址

	uploadForm: {
		action: '', // 请求地址
		header: {}, // 请求头
		params: {} // 参数
	}
});

// 预览图片
function preview() {
	if (props.mode == 'img') {
		// 原生图片预览

		uni.previewImage({ urls: [props.src] });
	} else {
		// 组件模式

		vdata.showEnlarge = true;
	}
}

// 删除图片
function delImg() {
	emit('update:src', '');
	emit('change', '');
}

// 选择图片 and 上传
function chooseImageAndUpload() {
	// 最多选择一张图片 && 压缩图片 && 支持相册 和 相机
	uni.chooseImage({ count: 1, sizeType: ['compressed'], sourceType: ['album', 'camera'] }).then((res) => {
		let file = res.tempFiles[0];

		// 预先检查
		if (!beforeCheck(file)) {
			return false;
		}

		// 检查通过

		$ossFilesForm(props.bizType, file).then(({ bizData }) => {
			// 本地方式
			if (bizData.formActionUrl === 'LOCAL_SINGLE_FILE_URL') {
				return http.upload(API_URL_SINGLE_FILE_UPLOAD, { bizType: props.bizType }, file).then(({ bizData }) => {
					emit('update:src', bizData);
					emit('change', bizData);
				});
			}

			// oss 直传
			uni.uploadFile({ url: bizData.formActionUrl, filePath: file.path, name: 'file', formData: bizData.formParams }).then((ossRes) => {
				if (ossRes.statusCode == 200) {
					// 上传成功
					emit('update:src', bizData.ossFileUrl);
					emit('change', bizData.ossFileUrl);
					return false;
				}

				infoBox.showToast('oss服务响应异常');
			});
		});
	});
}

function beforeCheck(file) {
	return true;
}

defineExpose({
	preview
});
</script>

<style lang="scss" scoped>
.default-img {
	display: block;
	width: 150rpx;
	height: 150rpx;
	background-color: #f7f7f7;
	border-radius: 15rpx;
}
.image-wrapper {
	position: relative;
	width: 150rpx;
	height: 150rpx;
	margin-bottom: 20upx;
	.del-image {
		position: absolute;
		top: -20rpx;
		right: -20rpx;
		z-index: 10;
		width: 40rpx;
		height: 40rpx;
		border-radius: 50%;
		background-color: tomato;
	}
}
</style>
