<template>
	<view>
		<div class="upload-box">
			<slot>
				<ul>
					<li class="list_img" v-for="(item,index) in showImgList" :key="index" :style="{ width: size + 'rpx', height: size + 'rpx' }">
						<view class="iconfont icondelete" @click="delImg(index)"></view>
						<img :src="item" @click="viewImg(item)" :style="{ width: size + 'rpx', height: size + 'rpx' }" :mode="imgMode" />
					</li>
					<li v-if="showImgList.length < num" class="uploadImg" @click="chooseImage" :style="{ width: size + 'rpx', height: size + 'rpx' }">
						<view class="iconfont icontupiantianjia"></view>
					</li>
				</ul>
			</slot>
		</div>
	</view>
</template>
<script>
import { uploadPic } from '@/api/common'
export default {
	name: 'app-uploader',
	props: {
		// 传入的图片数组
		imgList: {
			type: Array,
			default: () => []
		},
		manualDel: {
			type: Boolean,
			default: false
		},
		// 图片的尺寸
		size: {
			type: Number,
			default: 200
		},
		// 上传图片数量
		num: {
			type: Number,
			default: 9
		},
		// 压缩图片
		compress: {
			type: Boolean,
			default: true
		},
		// 默认限制图片1.5M,单位为M
		maxSize: {
			type: String,
			default: '1.5M'
		},
		// 是否记录用户的选择记录
		isSave: {
			type: Boolean,
			default: false
		},
		// 记录用户的缓存字段
		saveStr: {
			type: String,
			default: 'chooseImage'
		},
		// 是否转base64 受数据传输长度限制，不建议在组件中使用，如果一定要使用，在返回结果中自己转换
		isBase64: {
			type: Boolean,
			default: false
		},
		multiple: {
			// 是否多图上传
			type: Boolean,
			default: true
		},
		disabled: {
			// 是否只读
			type: Boolean,
			default: false
		},
		// 图片展示模式
		imgMode: {
			type: String,
			default: 'scaleToFill'
		},
		uploadPicApi: {
			type: Function,
			default: uploadPic
		}
	},
	data() {
		return {
			resultData: {},
			showImgList: [],
			base64ImgList: [],
			xssarr: ['data:', 'text', 'txt', 'html', 'js', 'css', 'json', 'exe', 'sql', 'xml', 'doc', 'docx']
		}
	},
	onLoad() {
		if (this.isSave) {
			let str = uni.getStorageSync(this.saveStr)
			if (str !== '') {
				str = str.split(',')
				if (str.length > this.num) {
					str = str.slice(0, this.num)
				}
				this.showImgList = str
			}
		} else {
			uni.removeStorageSync(this.saveStr)
		}
		this.showImgList = [...this.imgList]
	},
	methods: {
		chooseImage: async function() {
			if (this.disabled) {
				return
			}
			let that = this
			let tempFilePaths = await that.getImage()
			await that.blobToBase64(tempFilePaths)
			await that.autoUploadImg()
			await that.postMsg()
			return this.showImgList
		},

		postMsg() {
			this.$emit('update:imgList', this.showImgList)
			this.$emit('chooseImage', this.showImgList)
			this.$emit('resultData', this.resultData)
		},

		autoUploadImg() {
			let that = this
			let base64ImgList = that.base64ImgList
			let params = {}
			if (base64ImgList.length === 1) {
				params['file[content]'] = base64ImgList[0]
			} else {
				base64ImgList.forEach((item, index) => {
					params[`file[${index}][content]`] = item
				})
			}
			return new Promise((resolve, reject) => {
				this.uploadPicApi({
					...params,
					relative_path: 1
				}).then(res => {
					if (res.code === 1) {
						let imgArr = [res.data.url]
						that.showImgList = [...that.showImgList, ...imgArr]
						that.resultData = res.data
						this.$emit('currentUpload', imgArr)
						this.$emit('getResult', that.showImgList)
						resolve(that.showImgList)
					} else {
						reject(res)
					}
				})
			})
		},
		// 转64
		async blobToBase64(tempFilePaths) {
			let that = this
			that.base64ImgList = []
			let newImgList = [...tempFilePaths]
			for (let i = 0; i < newImgList.length; i++) {
				let blob = newImgList[i]
				// 转64位后可以看文件类型 data:text/
				// #ifdef H5
				// 如果是服务器返回的图片不转base64
				// if (blob.indexOf('blob') !== 0) {
				// 	that.imgPathList.push(blob)
				// 	continue
				// }
				await that.h5b64(blob).then(res => {
					let startindex = res.indexOf(':')
					let endindex = res.indexOf('/')
					let type = res.substring(startindex + 1, endindex)
					if (that.xssarr.indexOf(type) === -1) {
						that.base64ImgList.push(res)
					}
				})
				// #endif

				// #ifdef MP-WEIXIN
				// 微信临时文件  http://tmp/wx3a16...
				// if (blob.indexOf('http://tmp/') !== 0) {
				// 	that.imgPathList.push(blob)
				// 	continue
				// }
				await that.WEIXINb64(blob).then(res => {
					that.base64ImgList.push(res)
				})
				// #endif
			}
		},
		WEIXINb64(blob) {
			return new Promise((resolve, reject) => {
				uni.getFileSystemManager().readFile({
					filePath: blob, // 选择图片返回的相对路径
					encoding: 'base64', // 编码格式
					success: function(res) {
						let b64str = 'data:image/jpeg;base64,' + res.data
						resolve(b64str)
					},
					fail: function(err) {
						console.log(err)
					}
				})
			})
		},
		h5b64(blob) {
			return fetch(blob, {
				method: 'GET',
				headers: new Headers({
					'Access-Control-Allow-Origin': '*',
					'Content-Type': 'text/plain'
				}),
				mode: 'no-cors'
			})
				.then(data => {
					const blob = data.blob()
					return blob
				})
				.then(async blob => {
					let reader = new FileReader()
					reader.readAsDataURL(blob)
					return await new Promise((res, reg) => {
						reader.onloadend = function() {
							const data = reader.result
							res(data)
						}
					})
				})
		},

		// 上传图片
		getImage() {
			let that = this
			let showImgList = that.showImgList
			let count = that.num - showImgList.length
			return new Promise((resolve, reject) => {
				uni.chooseImage({
					count: this.multiple ? count : 1, // 默认9
					sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图，默认二者都有
					sourceType: ['album', 'camera'], // 从相册选择
					success: async function(res) {
						await that.fileValid(res)
						var tempFilePaths = res.tempFilePaths
						if (that.isSave) {
							uni.setStorageSync(that.saveStr, showImgList.join(','))
						}
						resolve(tempFilePaths)
					}
				})
			})
		},
		// 文件过滤
		fileValid(res) {
			let tempFiles = res.tempFiles
			let tempFilePaths = res.tempFilePaths
			let newtempFiles = []
			let newtempFilePaths = []

			for (let i = 0; i < tempFiles.length; i++) {
				// 大于1.5m就不让上传
				let fileSize = tempFiles[i].size
				if (fileSize > 1024 * 1024 * 1.5) {
					uni.showToast({
						title: '过滤不能大于1.5m的文件',
						duration: 2000,
						icon: 'none'
					})
					continue
				}

				// 文件类型设置
				let spl = tempFiles[i].path.split('.')
				let fileType = spl[spl.length - 1]
				if (fileType && this.xssarr.indexOf(fileType) >= 0) {
					uni.showToast({
						title: '过滤不符合规范文件',
						duration: 2000,
						icon: 'none'
					})
					continue
				}

				newtempFiles.push(tempFiles[i])
				newtempFilePaths.push(tempFilePaths[i])
			}
			res.tempFiles = newtempFiles
			res.tempFilePaths = newtempFilePaths
			// console.log('过滤完了')
		},
		// 删除
		async delImg(index) {
			if (this.disabled) {
				return
			}
			if (this.isSave) {
				uni.setStorageSync(this.saveStr, this.showImgList.join(','))
			}
			if (!this.manualDel) {
				this.showImgList.splice(index, 1)
			} else {
				this.$emit('delImage', index)
			}
			await this.postMsg()
		},
		// 预览
		viewImg(path) {
			uni.previewImage({
				urls: this.showImgList,
				current: path
			})
		},
		// 获取图片信息
		getImageInfo(image, cb) {
			uni.getImageInfo({
				src: image,
				success: function(image) {
					cb(image)
					return image
				}
			})
		},
		// 图片压缩
		compressImage() {
			uni.compressImage({
				src: image,
				quality: 80,
				complete: res => {}
			})
		}
	},
	watch: {
		imgList(val) {
			console.log('监听')
			this.showImgList = [...val]
		}
	}
}
</script>
<style scoped lang="scss">
	.uni-system-preview-image {
		background-color: rgba(0, 0, 0, 0.9);

		.uni-preview-image {
			max-width: 100%;
		}
	}

	.upload-box {
		padding: 0 30px;
		&:first-child {
			padding-left: 0;
		}

		& > ul {
			display: inline-block;
			display: flex;
			flex-wrap: wrap;

			& > li {
				list-style: none;
				width: 210px;
				height: 210px;
				margin: 0 20px 20px 0;
				position: relative;
				background-color: #fff;

				.icondelete {
					font-size: 25px;
					z-index: 999;
					position: absolute;
					right: 0;
					bottom: 0;
					color: #fff;
					padding: 0 2px;
					background-color: rgba(0, 0, 0, 0.45);
				}
			}
		}

		& .list_img {
			& > img {
				width: 100%;
				height: 100%;
			}
		}

		& .uploadImg {
			border: 1px dashed #e5e5e5;
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: center;
			box-sizing: border-box;

			.upload_ipt {
				position: absolute;
				width: 100%;
				height: 100%;
				/*overflow:hidden;*/
				cursor: pointer;
				opacity: 0;
			}

			.iconfont {
				color: rgb(150, 151, 153);
				font-size: 40px;
			}
		}
	}
</style>
