<template>
	<view class="s-add-list">
		<view class="s-add-list-items" :style="{
				height: size[0],
				width: size[1]
			}" v-for="(item, index) in imageList" :key="index">
			<image :src="item[filedImage]" :url="item.url" @tap="showImgs" class="s-add-list-img" :mode="imgMode">
			</image>
			<view class="s-add-list-remove s-icons icon-close" @tap.stop="removeImg" :id="'s-items-img-' + index">
				<icon type="clear" :color="closeColor"></icon>
			</view>
			<view class="upload-progress" :style="{ width: size[1] }">
				<progress :percent="item.progress" :stroke-width="progressSize" :activeColor="progressColor"
					:backgroundColor="progressBgColor" />
			</view>
			<view class="s-add-list-reup" @tap.stop="retry" :data-index="index" v-if="item.error">
				<text class="s-add-list-reup-icon s-icons icon-retry"></text>
				<text class="s-add-list-reup-text">失败重试</text>
			</view>
		</view>
		<view class="s-add-list-items s-add-list-btn" :style="{
				height: size[0],
				width: size[1],
				backgroundColor: backgroundColor
			}" :class="disabled ? 's-disabled' : ''" @tap="addImg" v-if="imageList.length < number">
			<slot name="icon"></slot>
			<view class="s-add-list-btn-text">{{ title }}</view>
		</view>
	</view>
</template>
<script>
	export default {
		props: {
			// 图片字段
			filedImage: {
				type: String,
				default: 'url'
			},
			// 背景颜色
			backgroundColor: {
				type: String,
				default: '#f7f7f7'
			},
			// 是否禁用
			disabled: {
				type: Boolean,
				default: false
			},
			// 上传数量
			number: {
				type: Number,
				default: 9
			},
			// 按钮名称
			title: {
				type: String,
				default: '添加照片'
			},
			// 上传文字颜色
			titleColor: {
				type: String,
				default: "#999"
			},
			// 图片大小
			size: {
				type: Array,
				default: () => ['222rpx', '222rpx']
			},
			// 上传前钩子
			beforeUpload: {
				type: Function
			},
			// 关闭按钮颜色
			closeColor: {
				type: String,
				default: "#999"
			},
			// 服务器地址
			url: {
				type: String,
				default: ''
			},
			// 进度条进度
			progressSize: {
				type: Number,
				default: 1
			},
			// 进度条颜色
			progressColor: {
				type: String,
				default: "#09A0F7"
			},
			// 进度条背景颜色
			progressBgColor: {
				type: String,
				default: "#999"
			},
			// 上传文件名称
			fileName: {
				type: String,
				default: 'img'
			},
			// 携带的form数据
			formData: {
				type: Object,
				default: () => {
					return {};
				}
			},
			// 图片模式
			imgMode: {
				type: String,
				default: 'widthFix'
			},
			// 携带的请求头
			header: {
				type: Object,
				default: () => {
					return {};
				}
			},
			// 返回状态码，默认0
			statusCode: {
				type: Number,
				default: 0
			},
			// 返回状态判断字段
			statusField: {
				type: String,
				default: 'errno'
			},
		},
		data() {
			return {
				imageList: [],
				upDate: false
			};
		},
		watch: {
			imageList(newVal, oldVal) {
				if (!this.upDate) {
					this.$emit('change', newVal);
				}
			}
		},
		methods: {
			clearAllImgs() {
				this.imageList = [];
			},
			addImg() {
				if (this.disabled) return;
				let num = this.number - this.imageList.length;
				if (num < 1) {
					return false;
				}
				uni.chooseImage({
					count: num,
					sizeType: ['compressed'],
					success: async res => {
						let file = res.tempFiles;
						for (let i = 0; i < res.tempFilePaths.length; i++) {
							if (this.beforeUpload) {
								const valid = await this.beforeUpload(file[i], i);
								if (valid === false) {
									return false;
								}
							}
							this.imageList.push({
								url: res.tempFilePaths[i],
								progress: 0,
								error: false
							});
						}
					}
				});
			},
			removeImg(e) {
				let index = e.currentTarget.id.replace('s-items-img-', '');
				let removeImg = this.imageList.splice(index, 1);
				this.$emit('remove', removeImg[0]);
			},
			showImgs(e) {
				let currentImg = e.currentTarget.dataset.url;
				let imgs = [];
				for (let i = 0; i < this.imageList.length; i++) {
					imgs.push(this.imageList[i][this.filedImage]);
				}
				uni.previewImage({
					urls: imgs,
					current: currentImg
				});
			},
			upload(index) {
				if (this.upDate) {
					return;
				}
				this.upDate = true;
				if (!index) {
					index = 0;
				}
				uni.showLoading({
					title: '图片上传中'
				});
				this.uploadBase(index);
			},
			retry(e) {
				let index = e.currentTarget.dataset.index;
				this.upload(index);
			},
			uploadBase(index) {
				// 全部上传完成
				if (index > this.imageList.length - 1) {
					uni.hideLoading();
					this.upDate = false;
					this.$emit('upload', this.imageList);
					return;
				}
				// 验证后端
				if (this.url == '') {
					uni.showToast({
						title: '请设置上传服务器地址',
						icon: 'none'
					});
					return;
				}
				// 检查是否是默认值
				if (this.imageList[index].progress >= 1) {
					this.uploadBase(index + 1);
					return;
				}
				this.imageList[index].error = false;
				// 创建上传对象
				const upTask = uni.uploadFile({
					url: this.url,
					filePath: this.imageList[index].url,
					name: 'file' || this.fileName,
					formData: this.formData,
					header: this.header,
					// #ifdef MP-ALIPAY
					fileType: 'image',
					// #endif
					success: uploadRes => {
						uploadRes = JSON.parse(uploadRes.data);
						if (uploadRes[this.statusField] != this.statusCode) {
							uni.showToast({
								title: '上传失败 : ' + uploadRes.data,
								icon: 'none'
							});
							this.error(index);
						} else {
							//上传图片成功
							this.imageList[index].progress = 100;
							this.imageList[index].url = uploadRes.data;
							this.imageList[index].result = uploadRes;
							this.uploadBase(index + 1);
						}
					},
					fail: e => {
						uni.showToast({
							title: '上传失败，请点击图片重试',
							icon: 'none'
						});
						this.error(index);
					}
				});
				upTask.onProgressUpdate(res => {
					if (res.progress > 0) {
						this.imageList[index].progress = res.progress;
						this.imageList.splice(index, 1, this.imageList[index]);
					}
				});
			},
			// 上传错误
			error(index) {
				this.upDate = false;
				setTimeout(() => {
					this.imageList[index].progress = 0;
					this.imageList[index].error = true;
					this.$emit('uploaderror');
				}, 500);
			},
			// 设置默认值
			setItems(items) {
				if (items.length) {
					this.imageList = [];
					for (let i = 0; i < items.length; i++) {
						this.imageList.push({
							url: items[i],
							progress: 100
						});
					}
				}
			}
		}
	};
</script>
<style lang="scss" scoped>
	.s-disabled {
		cursor: not-allowed;
	}

	.s-add-list {
		display: flex;
		flex-wrap: wrap;
	}

	.s-add-list-btn {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.s-add-list-btn-text {
		font-size: 1.875rem;
		line-height: 36rpx;
		text-align: center;
		color: #999;
		width: 100%;
	}

	.s-add-list-items {
		width: 222rpx;
		height: 222rpx;
		overflow: hidden;
		margin-bottom: 10rpx;
		margin-right: 11rpx;
		/* background: #f6f7f8; */
		font-size: 0;
		position: relative;
		border-radius: 10rpx;
	}

	.s-add-list-image {
		width: 222rpx;
	}

	.s-add-list-remove {
		position: absolute;
		z-index: 15;
		right: 10rpx;
		top: 0;
		color: #888888;
	}

	.upload-progress {
		position: absolute;
		z-index: 99;
		left: 0;
		bottom: 10rpx;
		// width: 180rpx;
		padding: 0 21rpx;
	}

	.s-add-list-reup {
		position: absolute;
		z-index: 3;
		left: 0;
		top: 0rpx;
		width: 100%;
		height: 222rpx;
		display: flex;
		justify-content: center;
		align-items: center;
		background-color: rgba(0, 0, 0, 0.3);
		flex-direction: column;
	}

	.s-add-list-reup-icon {
		text-align: center;
		width: 100%;
		color: #ffffff;
		display: block;
		font-size: 80rpx;
		line-height: 100rpx;
	}

	.s-add-list-reup-text {
		text-align: center;
		width: 100%;
		color: #ffffff;
		display: block;
		font-size: 20rpx;
		line-height: 30rpx;
	}

	.s-add-list-img {
		width: 100%;
		height: 100%;
	}
</style>