<template>
	<view class="htz-image-upload-list">
		<view class="htz-image-upload-Item" v-for="(item,index) in uploadLists" :key="index">
			<view class="htz-image-upload-Item-video" v-if="isVideo(item)">
				<!-- #ifndef APP-PLUS -->
				<video :disabled="false" :controls="false" :src="getFileUrl(item)">
					<cover-view class="htz-image-upload-Item-video-fixed" @tap.stop="previewVideo(getFileUrl(item))">
					</cover-view>

					<cover-view class="htz-image-upload-Item-del-cover" v-if="remove && previewVideoSrc==''" @tap.stop="imgDel(index)">×</cover-view>

				</video>
				<!-- #endif -->
				<!-- #ifdef APP-PLUS -->
				<view class="htz-image-upload-Item-video-fixed" @tap.stop="previewVideo(getFileUrl(item))"></view>
				<image v-if="dataType==1 && item.cover" class="htz-image-upload-Item-video-app-poster" mode="widthFix" :src="item.cover"></image>
				<image v-else class="htz-image-upload-Item-video-app-poster" mode="widthFix" :src="appVideoPoster"></image>
				<!-- #endif -->
			</view>

			<image v-else :src="getFileUrl(item)" @tap.stop="imgPreview(getFileUrl(item))"></image>
			
			<!-- #ifdef APP-PLUS -->
			<view class="htz-image-upload-Item-del" v-if="remove" @tap.stop="imgDel(index)">×</view>
			<!-- #endif -->
		</view>
		<view class="htz-image-upload-Item htz-image-upload-Item-add" v-if="uploadLists.length<max && add" @click="chooseFile">
			+
		</view>
		<view class="preview-full" v-if="previewVideoSrc!=''">
			<video :autoplay="true" :src="previewVideoSrc" :show-fullscreen-btn="false">
				<cover-view class="preview-full-close" @click="previewVideoClose"> ×
				</cover-view>
			</video>
		</view>


		<!--  -->
	</view>
</template>

<style>
	.ceshi {
		width: 100%;
		height: 100%;
		position: relative;
		top: 0;
		left: 0;
		bottom: 0;
		right: 0;
		background-color: #FFFFFF;
		color: #2C405A;
		opacity: 0.5;
		z-index: 100;
	}
</style>

<script>
	export default {
		name: 'htz-image-upload',
		props: {
			max: { //展示图片最大值
				type: Number,
				default: 1,
			},
			chooseNum: { //选择图片数
				type: Number,
				default: 9,
			},
			name: { //发到后台的文件参数名
				type: String,
				default: 'file',
			},
			dataType: { //v-model的数据结构类型
				type: Number,
				default: 0, // 0: ['http://xxxx.jpg','http://xxxx.jpg'] 1:[{type:0,url:'http://xxxx.jpg'}]  type 0 图片 1 视频 url 文件地址 此类型是为了给没有文件后缀的状况使用的
			},
			remove: { //是否展示删除按钮
				type: Boolean,
				default: true,
			},
			add: { //是否展示添加按钮
				type: Boolean,
				default: true,
			},
			disabled: { //是否禁用
				type: Boolean,
				default: false,
			},
			sourceType: { //选择照片来源 【ps：H5就别费劲了，设置了也没用。不是我说的，官方文档就这样！！！】
				type: Array,
				default: () => ['album', 'camera'],
			},
			action: { //上传地址 如需使用uniCloud服务，设置为uniCloud即可
				type: String,
				default: '',
			},
			headers: { //上传的请求头部
				type: Object,
				default: () => {},
			},
			formData: { //HTTP 请求中其他额外的 form data
				type: Object,
				default: () => {},
			},
			compress: { //是否需要压缩
				type: Boolean,
				default: true,
			},
			quality: { //压缩质量，范围0～100
				type: Number,
				default: 80,
			},
			// #ifndef VUE3
			value: { //受控图片列表
				type: Array,
				default: () => [],
			},
			// #endif
			// #ifdef VUE3
			modelValue: { //受控图片列表
				type: Array,
				default: () => [],
			},
			// #endif
			uploadSuccess: {
				default: (res) => {
					return {
						success: false,
						url: ''
					}
				},
			},
			mediaType: { //文件类型 image/video/all
				type: String,
				default: 'image',
			},
			maxDuration: { //拍摄视频最长拍摄时间，单位秒。最长支持 60 秒。 (只针对拍摄视频有用)
				type: Number,
				default: 60,
			},
			camera: { //'front'、'back'，默认'back'(只针对拍摄视频有用)
				type: String,
				default: 'back',
			},
			appVideoPoster: { //app端视频展示封面 只对app有效
				type: String,
				default: '/static/htz-image-upload/play.png',
			},
		},
		data() {
			return {
				uploadLists: [],
				mediaTypeData: ['image', 'video', 'all'],
				previewVideoSrc: '',
			}
		},
		mounted: function() {
			this.$nextTick(function() {
				// #ifndef VUE3
				this.uploadLists = this.value;
				// #endif
				// #ifdef VUE3
				this.uploadLists = this.modelValue;
				// #endif
				if (this.mediaTypeData.indexOf(this.mediaType) == -1) {
					uni.showModal({
						title: '提示',
						content: 'mediaType参数不正确',
						showCancel: false,
						success: function(res) {
							if (res.confirm) {
								//console.log('用户点击确定');
							} else if (res.cancel) {
								//console.log('用户点击取消');
							}
						}
					});
				}
			});
		},
		watch: {
			// #ifndef VUE3
			value(val, oldVal) {
				//console.log('value',val, oldVal)
				this.uploadLists = val;
			},
			// #endif
			// #ifdef VUE3
			modelValue(val, oldVal) {
				//console.log('value',val, oldVal)
				this.uploadLists = val;
			},
			// #endif

		},
		methods: {
			isVideo(item) {
				let isPass = false
				if ((!/.(gif|jpg|jpeg|png|gif|jpg|png)$/i.test(item) && this.dataType == 0) || (this.dataType == 1 && item
						.type == 1)) {
					isPass = true
				}
				return isPass
			},
			getFileUrl(item) {
				var url = item;
				if (this.dataType == 1) {
					url = item.url
				}
				//console.log('url', url)
				return url
			},
			previewVideo(src) {
				this.previewVideoSrc = src;
				// this.previewVideoSrc =
				// 	'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-fbd63a76-dc76-485c-b711-f79f2986daeb/ba804d82-860b-4d1a-a706-5a4c8ce137c3.mp4'
			},
			previewVideoClose() {
				this.previewVideoSrc = ''
				//console.log('previewVideoClose', this.previewVideoSrc)
			},
			imgDel(index) {
				// this.uploadLists.splice(index, 1)
				// this.$emit("input", this.uploadLists);
				// this.$emit("imgDelete", this.uploadLists);
				let delUrl = this.uploadLists[index]
				this.uploadLists.splice(index, 1)
				// #ifndef VUE3
				this.$emit("input", this.uploadLists);
				// #endif
				// #ifdef VUE3
				this.$emit("update:modelValue", this.uploadLists);
				// #endif
				this.$emit("imgDelete", {
					del: delUrl,
					tempFilePaths: this.uploadLists
				});
			},
			imgPreview(index) {

				var imgData = []

				this.uploadLists.forEach(item => {
					if (!this.isVideo(item)) {
						imgData.push(this.getFileUrl(item))
					}
				})


				//console.log('imgPreview', imgData)
				uni.previewImage({
					urls: imgData,
					current: index,
					loop: true,
				});


			},
			chooseFile() {
				if (this.disabled) {
					return false;
				}
				switch (this.mediaTypeData.indexOf(this.mediaType)) {
					case 1: //视频
						this.videoAdd();
						break;
					case 2: //全部
						uni.showActionSheet({
							itemList: ['相册', '视频'],
							success: (res) => {
								if (res.tapIndex == 1) {
									this.videoAdd();
								} else if (res.tapIndex == 0) {
									this.imgAdd();
								}
							},
							fail: (res) => {
								console.log(res.errMsg);
							}
						});
						break;
					default: //图片
						this.imgAdd();
						break;
				}


				//if(this.mediaType=='image'){


			},
			videoAdd() {
				//console.log('videoAdd')
				let nowNum = Math.abs(this.uploadLists.length - this.max);
				let thisNum = (this.chooseNum > nowNum ? nowNum : this.chooseNum) //可选数量
				uni.chooseVideo({
					compressed: this.compress,
					sourceType: this.sourceType,
					camera: this.camera,
					maxDuration: this.maxDuration,
					success: (res) => {
						// console.log('videoAdd', res)
						// console.log(res.tempFilePath)
						this.chooseSuccessMethod([res.tempFilePath], 1)
						//this.imgUpload([res.tempFilePath]);
						//console.log('tempFiles', res)
						// if (this.action == '') { //未配置上传路径
						// 	this.$emit("chooseSuccess", res.tempFilePaths);
						// } else {
						// 	if (this.compress && (res.tempFiles[0].size / 1024 > 1025)) { //设置了需要压缩 并且 文件大于1M，进行压缩上传
						// 		this.imgCompress(res.tempFilePaths);
						// 	} else {
						// 		this.imgUpload(res.tempFilePaths);
						// 	}
						// }
					}
				});
			},
			imgAdd() {
				//console.log('imgAdd')
				let nowNum = Math.abs(this.uploadLists.length - this.max);
				let thisNum = (this.chooseNum > nowNum ? nowNum : this.chooseNum) //可选数量
				//console.log('nowNum', nowNum)
				//console.log('thisNum', thisNum)
				// #ifdef APP-PLUS
				if (this.sourceType.length > 1) {
					uni.showActionSheet({
						itemList: ['拍摄', '从手机相册选择'],
						success: (res) => {
							if (res.tapIndex == 1) {
								this.appGallery(thisNum);
							} else if (res.tapIndex == 0) {
								this.appCamera();
							}
						},
						fail: (res) => {
							console.log(res.errMsg);
						}
					});
				}
				if (this.sourceType.length == 1 && this.sourceType.indexOf('album') > -1) {
					this.appGallery(thisNum);
				}

				if (this.sourceType.length == 1 && this.sourceType.indexOf('camera') > -1) {
					this.appCamera();
				}
				// #endif
				//#ifndef APP-PLUS
				uni.chooseImage({
					count: thisNum,
					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
					sourceType: this.sourceType,
					success: (res) => {
						this.chooseSuccessMethod(res.tempFilePaths, 0)
						//console.log('tempFiles', res)
						// if (this.action == '') { //未配置上传路径
						// 	this.$emit("chooseSuccess", res.tempFilePaths);
						// } else {
						// 	if (this.compress && (res.tempFiles[0].size / 1024 > 1025)) { //设置了需要压缩 并且 文件大于1M，进行压缩上传
						// 		this.imgCompress(res.tempFilePaths);
						// 	} else {
						// 		this.imgUpload(res.tempFilePaths);
						// 	}
						// }
					}
				});
				// #endif
			},
			appCamera() {
				var cmr = plus.camera.getCamera();
				var res = cmr.supportedImageResolutions[0];
				var fmt = cmr.supportedImageFormats[0];
				//console.log("Resolution: " + res + ", Format: " + fmt);
				cmr.captureImage((path) => {
						//alert("Capture image success: " + path);
						this.chooseSuccessMethod([path], 0)
					},
					(error) => {
						//alert("Capture image failed: " + error.message);
						console.log("Capture image failed: " + error.message)
					}, {
						resolution: res,
						format: fmt
					}
				);
			},
			appGallery(maxNum) {
				plus.gallery.pick((res) => {
					this.chooseSuccessMethod(res.files, 0)
				}, function(e) {
					//console.log("取消选择图片");
				}, {
					filter: "image",
					multiple: true,
					maximum: maxNum
				});
			},
			chooseSuccessMethod(filePaths, type) {
				if (this.action == '') { //未配置上传路径
					this.$emit("chooseSuccess", filePaths, type); //filePaths 路径 type 0 为图片 1为视频
				} else {
					if (type == 1) {
						this.imgUpload(filePaths, type);
					} else {
						if (this.compress) { //设置了需要压缩
							this.imgCompress(filePaths, type);
						} else {
							this.imgUpload(filePaths, type);
						}
					}

				}
			},
			imgCompress(tempFilePaths, type) { //type 0 为图片 1为视频
				uni.showLoading({
					title: '压缩中...'
				});

				let compressImgs = [];
				let results = [];
				tempFilePaths.forEach((item, index) => {
					compressImgs.push(new Promise((resolve, reject) => {
						// #ifndef H5
						uni.compressImage({
							src: item,
							quality: this.quality,
							success: res => {
								//console.log('compressImage', res.tempFilePath)
								results.push(res.tempFilePath);
								resolve(res.tempFilePath);
							},
							fail: (err) => {
								//console.log(err.errMsg);
								reject(err);
							},
							complete: () => {
								//uni.hideLoading();
							}
						})
						// #endif
						// #ifdef H5
						this.canvasDataURL(item, {
							quality: this.quality / 100
						}, (base64Codes) => {
							//this.imgUpload(base64Codes);
							results.push(base64Codes);
							resolve(base64Codes);
						})
						// #endif
					}))
				})
				Promise.all(compressImgs) //执行所有需请求的接口
					.then((results) => {
						uni.hideLoading();
						//console.log('imgCompress', type)
						this.imgUpload(results, type);
					})
					.catch((res, object) => {
						uni.hideLoading();
					});
			},
			imgUpload(tempFilePaths, type) { //type 0 为图片 1为视频
				// if (this.action == '') {
				// 	uni.showToast({
				// 		title: '未配置上传地址',
				// 		icon: 'none',
				// 		duration: 2000
				// 	});
				// 	return false;
				// }
				if (this.action == 'uniCloud') {
					this.uniCloudUpload(tempFilePaths, type)
					return
				}
				uni.showLoading({
					title: '上传中'
				});
				//console.log('imgUpload', tempFilePaths)
				let uploadImgs = [];
				tempFilePaths.forEach((item, index) => {
					uploadImgs.push(new Promise((resolve, reject) => {
						//console.log(index, item)
						const uploadTask = uni.uploadFile({
							url: this.action, //仅为示例，非真实的接口地址
							filePath: item,
							name: this.name,
							fileType: 'image',
							formData: this.formData,
							header: this.headers,
							success: (uploadFileRes) => {
								//uni.hideLoading();
								//console.log(typeof this.uploadSuccess)
								//console.log('')
								uploadFileRes.fileType = type
								if (typeof this.uploadSuccess == 'function') {

									let thisUploadSuccess = this.uploadSuccess(
										uploadFileRes)
									if (thisUploadSuccess.success) {
										let keyName = '';
										// #ifndef VUE3
										keyName = 'value'
										// #endif
										// #ifdef VUE3
										keyName = 'modelValue'
										// #endif
										if (this.dataType == 0) {
											this[keyName].push(thisUploadSuccess.url)
										} else {
											this[keyName].push({
												type: type,
												url: thisUploadSuccess.url,
												...thisUploadSuccess
											})
										}

										//this.$emit("input", this.uploadLists);
										// #ifndef VUE3
										this.$emit("input", this.uploadLists);
										// #endif
										// #ifdef VUE3
										this.$emit("update:modelValue", this.uploadLists);
										// #endif
									}
								}
								resolve(uploadFileRes);
								this.$emit("uploadSuccess", uploadFileRes);
							},
							fail: (err) => {
								console.log(err);
								//uni.hideLoading();
								reject(err);
								this.$emit("uploadFail", err);
							},
							complete: () => {
								//uni.hideLoading();
							}
						});
					}))
				})
				Promise.all(uploadImgs) //执行所有需请求的接口
					.then((results) => {
						uni.hideLoading();
					})
					.catch((res, object) => {
						uni.hideLoading();
						this.$emit("uploadFail", res);
					});
				// uploadTask.onProgressUpdate((res) => {
				// 	//console.log('',)
				// 	uni.showLoading({
				// 		title: '上传中' + res.progress + '%'
				// 	});
				// 	if (res.progress == 100) {
				// 		uni.hideLoading();
				// 	}
				// });
			},
			uniCloudUpload(tempFilePaths, type) {
				uni.showLoading({
					title: '上传中'
				});
				console.log('uniCloudUpload', tempFilePaths);
				let uploadImgs = [];
				tempFilePaths.forEach((item, index) => {
					uploadImgs.push(new Promise((resolve, reject) => {

						uniCloud.uploadFile({
							filePath: item,
							cloudPath: this.guid() + '.' + this.getFileType(item, type),
							success(uploadFileRes) {
								if (uploadFileRes.success) {
									resolve(uploadFileRes.fileID);
								}
							},
							fail(err) {
								console.log(err);
								reject(err);
							},
							complete() {}
						});

					}))
				})
				Promise.all(uploadImgs) //执行所有需请求的接口
					.then((results) => {
						uni.hideLoading();
						// console.log('then', results)

						uniCloud.getTempFileURL({
							fileList: results,
							success: (res) => {
								//console.log('success',res.fileList)
								res.fileList.forEach(item => {
									//console.log(item.tempFileURL)
									//this.value.push(item.tempFileURL)
									// #ifndef VUE3
									this.value.push(item.tempFileURL)
									this.$emit("input", this.value);
									// #endif
									// #ifdef VUE3
									this.modelValue.push(item.tempFileURL)
									this.$emit("update:modelValue", this.modelValue);
									// #endif
								})
							},
							fail() {},
							complete() {}
						});
					})
					.catch((res, object) => {
						uni.hideLoading();
					});
			},
			getFileType(path, type) { //手机端默认图片为jpg 视频为mp4
				// #ifdef H5 
				var result = type == 0 ? 'jpg' : 'mp4';
				// #endif


				// #ifndef H5
				var result = path.split('.').pop().toLowerCase();
				// #ifdef MP 
				if (this.compress) { //微信小程序压缩完没有后缀
					result = type == 0 ? 'jpg' : 'mp4';
				}
				// #endif
				// #endif
				return result;
			},
			guid() {
				return 'xxxxxxxx-date-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
					var r = Math.random() * 16 | 0,
						v = c == 'x' ? r : (r & 0x3 | 0x8);
					return v.toString(16);
				}).replace(/date/g, function(c) {
					return Date.parse(new Date());
				});
			},
			canvasDataURL(path, obj, callback) {
				var img = new Image();
				img.src = path;
				img.onload = function() {
					var that = this;
					// 默认按比例压缩
					var w = that.width,
						h = that.height,
						scale = w / h;
					w = obj.width || w;
					h = obj.height || (w / scale);
					var quality = 0.8; // 默认图片质量为0.8
					//生成canvas
					var canvas = document.createElement('canvas');
					var ctx = canvas.getContext('2d');
					// 创建属性节点
					var anw = document.createAttribute("width");
					anw.nodeValue = w;
					var anh = document.createAttribute("height");
					anh.nodeValue = h;
					canvas.setAttributeNode(anw);
					canvas.setAttributeNode(anh);
					ctx.drawImage(that, 0, 0, w, h);
					// 图像质量
					if (obj.quality && obj.quality <= 1 && obj.quality > 0) {
						quality = obj.quality;
					}
					// quality值越小，所绘制出的图像越模糊
					var base64 = canvas.toDataURL('image/jpeg', quality);
					// 回调函数返回base64的值
					callback(base64);
				}
			},
		}
	}
</script>

<style>
	.preview-full {
		position: fixed;
		top: 0;
		left: 0;
		bottom: 0;
		width: 100%;
		height: 100%;
		z-index: 1002;
	}

	.preview-full video {
		width: 100%;
		height: 100%;
		z-index: 1002;
	}

	.preview-full-close {
		position: fixed;
		right: 32rpx;
		top: 25rpx;
		width: 80rpx;
		height: 80rpx;
		line-height: 60rpx;
		text-align: center;
		z-index: 1003;
		/* 	background-color: #808080; */
		color: #fff;
		font-size: 65rpx;
		font-weight: bold;
		text-shadow: 1px 2px 5px rgb(0 0 0);
	}



	/* .preview-full-close-before,
	.preview-full-close-after {
		position: absolute;
		top: 50%;
		left: 50%;
		content: '';
		height: 60rpx;
		margin-top: -30rpx;
		width: 6rpx;
		margin-left: -3rpx;
		background-color: #FFFFFF;
		z-index: 20000;
	}

	.preview-full-close-before {
		transform: rotate(45deg);

	}

	.preview-full-close-after {
		transform: rotate(-45deg);

	} */

	.htz-image-upload-list {
		display: flex;
		flex-wrap: wrap;
	}

	.htz-image-upload-Item {
		width: 160rpx;
		height: 160rpx;
		margin: 13rpx;
		border-radius: 10rpx;
		position: relative;
	}

	.htz-image-upload-Item image {
		width: 100%;
		height: 100%;
		border-radius: 10rpx;
	}

	.htz-image-upload-Item-video {
		width: 100%;
		height: 100%;
		border-radius: 10rpx;
		position: relative;

	}

	.htz-image-upload-Item-video-fixed {
		position: absolute;
		top: 0;
		left: 0;
		bottom: 0;
		width: 100%;
		height: 100%;
		border-radius: 10rpx;
		z-index: 996;

	}

	.htz-image-upload-Item video {
		width: 100%;
		height: 100%;
		border-radius: 10rpx;

	}

	.htz-image-upload-Item-add {
		font-size: 105rpx;
		/* line-height: 160rpx; */
		text-align: center;
		border: 1px dashed #d9d9d9;
		color: #d9d9d9;
	}

	.htz-image-upload-Item-del {
		background-color: var(--ui-BG-Main);
		font-size: 24rpx;
		position: absolute;
		width: 35rpx;
		height: 35rpx;
		line-height: 35rpx;
		text-align: center;
		top: 0;
		right: 0;
		z-index: 997;
		color: #fff;
		border-top-right-radius: 10rpx;
	}

	.htz-image-upload-Item-del-cover {
		background-color: var(--ui-BG-Main);
		font-size: 24rpx;
		position: absolute;
		width: 35rpx;
		height: 35rpx;
		text-align: center;
		top: 0;
		right: 0;
		color: #fff;
		/* #ifdef APP-PLUS */
		line-height: 25rpx;
		/* #endif */
		/* #ifndef APP-PLUS */
		line-height: 35rpx;
		/* #endif */
		z-index: 997;
		border-top-right-radius: 10rpx;
	}

	.htz-image-upload-Item-video-app-poster {
		width: 100%;
		height: 100%;
	}
</style>
