<template>
    <div class="img-upload-container">
        <div class="img-upload" :class="{ 'limit-num': fileList.length >= limit, 'mini': size === 'small' }">
            <el-upload class="avatar-uploader" ref="upload" :action="url" :headers="{ 'Authorization': token }"
                :file-list="fileList" list-type="picture-card" :on-success="handleSuccess" :on-remove="handleRemove"
                :data="{ fileType, villageCode }" :limit="1" :on-preview="handlePictureCardPreview"
                :before-upload="beforeAvatarUpload">
                <i class="el-icon-plus"></i>
                <p class="el-upload__tip" slot="tip" v-if="tips">{{ tips }}</p>
                <p class="el-upload__tip" slot="tip" v-if="tips2">{{ tips2 }}</p>
                <div slot="file" slot-scope="{file}" class="img-con">
                    <img class="el-upload-list__item-thumbnail" :src="file.url" alt="">
                    <span class="el-upload-list__item-actions">
                        <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
                            <i class="el-icon-zoom-in"></i>
                        </span>
                        <span class="el-upload-list__item-delete" @click="handleRemove(file)">
                            <i class="el-icon-delete"></i>
                        </span>
                        <span v-if="size === 'small'" style="display:block;marginLeft:0" class="el-upload-list__item-delete"
                            @click="onChangeHandle(file)">
                            <i class="el-icon-edit"></i>
                        </span>
                        <span v-else class="el-upload-list__item-delete" @click="onChangeHandle(file)">
                            <i class="el-icon-edit"></i>
                        </span>
                    </span>
                </div>
            </el-upload>

            <el-dialog :visible.sync="dialogVisible">
                <img width="100%" append-to-body :src="dialogImageUrl" alt />
            </el-dialog>
        </div>
    </div>
</template>
  
<script>
import { getToken } from '@/utils/auth'
export default {
    name: 'ImgUpload',
    componentName: 'ImgUpload',
    data() {
        return {
            imgWidth: 0,
            imgHeight: 0,
            // url: `http://${window.location.host}/hjapi/common/upload`, // 图片上传接口地址
            url: `http://192.168.0.188:8118/zhapi/common/upload`, // 图片上传接口地址
            fileList: [],
            dialogImageUrl: '',
            dialogVisible: false,
            picIndex: -1,
            vmodelType: '',
            token: '',
            villageData: {},
            imageUrl: ''
        }
    },
    props: {
        value: {
            type: [String, Array]
        },
        tips: {
            type: String,
            default: ''
        },
        tips2: {
            type: String,
            default: ''
        },
        size: {
            type: String,
            default: 'medium' // small
        },
        limit: {
            type: Number,
            default: 2
        },
        limitSize: {
            type: Number,
            default: 10
        },
        valueType: {
            type: String,
            default: 'String' // Object
        },
        // 是否校验图片尺寸，默认不校验
        isCheckPicSize: {
            type: Boolean,
            default: false
        },
        checkWidth: {
            type: Number,
            default: 0 // 图片限制宽度
        },
        checkHeight: {
            type: Number,
            default: 0 // 图片限制高度
        },
        topLimitWidth: {
            type: Number,
            default: 0 // 图片限制宽度上限（有时需要校验上传图片宽度在一个范围内）
        },
        topLimitHeight: {
            type: Number,
            default: 0 // 图片限制高度上限（有时需要校验上传图片高度在一个范围内）
        },
        busiType: {
            type: Number,
            default: 2
        },
        index: {
            type: Number,
            default: -1 // 当前图片index，限制可以上传多张时，针对某一张进行操作，需要知道当前的index
        },
        limitType: {
            type: String,
            default: '' // gif,webp/gif/webp （限制上传格式）
        },
        fileType: {
            type: String,
            default: 'userpic'
        },
        villageCode: {
            default: ''
        }
    },
    watch: {
        value: {
            deep: true,
            handler: function (val) {
                if (val) {
                    if (this.valueType === 'Object') {
                        this.fileList = this.value.map(item => ({ id: item.id, url: item.url, name: item.name }))
                    } else {
                        if (this.vmodelType === 'array') {
                            this.fileList = this.value.map(item => ({ url: item }))
                        } else {
                            this.fileList = [{ url: val }]
                        }
                    }
                } else {
                    this.fileList = []
                }
            }
        }
    },
    created() {
        this.agetToken()
        if (this.valueType === 'Object') {
            this.vmodelType = 'array'
        } else {
            const res = this.isString(this.value)
            if (res === true) {
                this.vmodelType = 'string'
            } else {
                this.vmodelType = 'array'
            }
        }
        // console.log('created vmodelType', this.vmodelType)
        if (this.value) {
            if (this.valueType === 'Object') {
                this.fileList = this.value.map(item => ({
                    id: item.id ? item.id : '',
                    url: item.url,
                    name: item.name
                }))
            } else {
                if (this.vmodelType === 'array') {
                    this.fileList = this.value.map(item => ({ url: item }))
                } else {
                    this.fileList = [{ url: this.value }]
                }
            }
        }
    },
    mounted() {
    },
    methods: {
        agetToken() {
            this.token = 'Bearer ' + getToken()
        },
        findItem(uid) {
            this.fileList.forEach((ele, i) => {
                if (uid === ele.uid) {
                    this.picIndex = i
                }
            })
        },
        onChangeHandle(file) {
            // console.log('onChangeHandle', file, this.fileList)
            this.findItem(file.uid)
            this.$refs.upload.$refs['upload-inner'].handleClick()
        },
        beforeAvatarUpload(file) {
            const imgType = file.type
            const isLtSize = file.size / 1024 / 1024 < this.limitSize
            const TYPE_NOGIFWEBP = ['image/png', 'image/jpeg', 'image/jpg']
            const TYPE_NOGIF = ['image/png', 'image/jpeg', 'image/jpg', 'image/webp']
            const TYPE_NOWEBP = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif']
            const TYPE_ALL = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/webp']
            let isType = true
            if (this.limitType && this.limitType.indexOf('gif') !== -1 && this.limitType.indexOf('webp') !== -1) {
                if (TYPE_NOGIFWEBP.indexOf(imgType) === -1) {
                    isType = false
                    this.$message.error('仅支持上传 jpg、png、jpeg、gif、webp 格式的图片!')
                }
            } else if (this.limitType && this.limitType.indexOf('gif') === -1 && this.limitType.indexOf('webp') === -1) {
                if (TYPE_NOGIFWEBP.indexOf(imgType) === -1) {
                    isType = false
                    this.$message.error('仅支持上传 jpg、png、jpeg 格式的图片!')
                }
            } else if (this.limitType && this.limitType.indexOf('webp') !== -1) {
                if (TYPE_NOGIF.indexOf(imgType) === -1) {
                    isType = false
                    this.$message.error('仅支持上传 jpg、png、jpeg、webp 格式的图片!')
                }
            } else if (this.limitType && this.limitType.indexOf('gif') !== -1) {
                if (TYPE_NOWEBP.indexOf(imgType) === -1) {
                    isType = false
                    this.$message.error('仅支持上传 jpg、png、jpeg、gif 格式的图片!')
                }
            } else {
                if (TYPE_ALL.indexOf(imgType) === -1) {
                    isType = false
                    this.$message.error('仅支持上传 jpg、png、jpeg、webp、gif 格式的图片!')
                }
            }

            if (!isLtSize) {
                this.$message.error(`上传图片大小不能超过${this.limitSize}MB!`)
            }
            if (this.isCheckPicSize === true) {
                const width = this.checkWidth
                const height = this.checkHeight
                const topWidth = this.topLimitWidth
                const topHeight = this.topLimitHeight
                const that = this
                const isSize = new Promise((resolve, reject) => {
                    // window对象，将blob或file读取成一个url
                    const _URL = window.URL || window.webkitURL
                    const img = new Image()
                    // image对象的onload事件，当图片加载完成后执行的函数
                    img.onload = () => {
                        that.imgWidth = img.width
                        that.imgHeight = img.height
                        if (width && height) { // 校验图片的宽度和高度
                            let valid = false
                            if (topWidth && topHeight) {
                                // 校验图片宽度和高度范围
                                valid = ((width <= img.width) && (img.width <= topWidth)) && ((height <= img.height) && (img.height <= topHeight))
                            } else if (topHeight) {
                                // 校验图片高度范围
                                valid = img.width === width && ((height <= img.height) && (img.height <= topHeight))
                            } else if (topWidth) {
                                // 校验图片宽度范围
                                valid = ((width <= img.width) && (img.width <= topWidth)) && img.height === height
                            } else {
                                // 校验图片宽度、高度固定值
                                valid = img.width === width && height === img.height
                            }
                            valid ? resolve() : reject(new Error('error'))
                        } else if (width) { // 只校验图片的宽度
                            let valid = false
                            if (topWidth) {
                                // 校验图片宽度范围
                                valid = (width <= img.width) && (img.width <= topWidth)
                            } else {
                                // 校验图片宽度固定值
                                valid = img.width === width
                            }
                            valid ? resolve() : reject(new Error('error'))
                        } if (height) { // 只校验图片的高度
                            let valid = false
                            if (topHeight) {
                                // 校验图片高度范围
                                valid = (height <= img.height) && (img.height <= topHeight)
                            } else {
                                // 校验图片高度固定值
                                valid = img.height === height
                            }
                            valid ? resolve() : reject(new Error('error'))
                        }
                    }
                    img.src = _URL.createObjectURL(file)
                }).then(() => {
                    return file
                }, () => {
                    let text = ''
                    if (width && height) {
                        if (topWidth && topHeight) {
                            text = `图片尺寸限制为：宽度${width}~${topWidth}px，高度${height}~${topHeight}px！`
                        } else if (topHeight) {
                            text = `图片尺寸限制为：宽度${width}px，高度${height}~${topHeight}px！`
                        } else if (topWidth) {
                            text = `图片尺寸限制为：宽度${width}~${topWidth}px，高度${height}px！`
                        } else {
                            text = `图片尺寸限制为：宽度${width}px，高度${height}px！`
                        }
                    } else if (width) {
                        if (topWidth) {
                            text = `图片尺寸限制为：宽度${width}~${topWidth}px！`
                        } else {
                            text = `图片尺寸限制为：宽度${width}px！`
                        }
                    } else if (height) {
                        if (topHeight) {
                            text = `图片尺寸限制为：高度${height}~${topHeight}px！`
                        } else {
                            text = `图片尺寸限制为：高度${height}px！`
                        }
                    }
                    this.$message.error(text)
                    return Promise.reject(new Error('error'))
                })
                return isType && isLtSize && isSize
            } else {
                // window对象，将blob或file读取成一个url
                const _URL = window.URL || window.webkitURL
                const img = new Image()
                img.onload = () => { // image对象的onload事件，当图片加载完成后执行的函数
                    this.imgWidth = img.width
                    this.imgHeight = img.height
                    // console.log('getWidthAndHeight', this.imgWidth, this.imgHeight)
                }
                img.src = _URL.createObjectURL(file)
                return isType && isLtSize
            }
        },
        // 判断是否是String
        isString(str) {
            return ((str instanceof String) || (typeof str).toLowerCase() === 'string')
        },
        handleRemove(file) {
            this.findItem(file.uid)
            this.fileList.splice(this.picIndex, 1)
            // fileList = JSON.parse(JSON.stringify(this.fileList))
            // this.exportImg(fileList)
        },
        handleSuccess(res, file, fileList) {


            console.log(fileList, 'success');
            console.log(this.picIndex, 'this.picIndex');
            if (this.picIndex !== -1) {
                fileList.splice(this.picIndex, 1)
            }
            // this.exportImg(fileList)
            console.log(res.url, 'res.url');
            this.imageUrl = res.url
            this.$emit('upSuccess', res.url)
        },
        handleError(err) {
            this.$message.error(err)
        },
        handlePictureCardPreview(file) {
            this.dialogImageUrl = file.url
            this.dialogVisible = true
        },
        exportImg(fileList = []) {
            // console.log('exportImg fileList', fileList)
            this.fileList = fileList
            if (fileList.length !== 0) {
                if (this.valueType === 'Object') {
                    const imgs = fileList.map(item => {
                        if (item.response && item.response.result) {
                            item.id = item.response.result[0].id
                            item.url = item.response.result[0].url + '&width=' + this.imgWidth + '&height=' + this.imgHeight
                            item.name = item.response.result[0].fileName
                        }
                        return {
                            id: item.id,
                            url: item.url,
                            name: item.name
                        }
                    })
                    this.$emit('input', imgs)
                    // console.log('exportImg imgs', imgs)
                } else {
                    if (this.vmodelType === 'array') {
                        const imgs = fileList.map(item => {
                            if (item.response && item.response.result) {
                                item.url = item.response.result[0].url + '&width=' + this.imgWidth + '&height=' + this.imgHeight
                            }
                            return item.url
                        })
                        this.$emit('input', imgs)
                        // console.log('exportImg imgs', imgs)
                    } else {
                        const resUrl = fileList[0].response.result[0].url + '&width=' + this.imgWidth + '&height=' + this.imgHeight
                        this.$emit('input', resUrl)
                        // console.log('exportImg resUrl', resUrl)
                    }
                }
            } else {
                this.$emit('input', '')
            }
            this.picIndex = -1
        }
    }
}
</script>
  
<style lang='less'>
@small-size: 80px;

.img-upload&&.limit-num {
    .el-upload--picture-card {
        display: none !important;
    }
}

.el-upload--picture-card {
    background: url("~@/assets/companyFile/uploadicon.png") center no-repeat !important;
    background-size: 40% 40% !important;

    .el-icon-plus {
        display: none;
    }
}

.img-upload&&.mini {
    .el-upload {
        border: 1px dashed #d9d9d9;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
    }

    .el-upload-list__item {
        width: @small-size;
        height: @small-size;
        text-align: center;
        /*去除upload组件过渡效果*/
        transition: none !important;
    }

    .el-upload--picture-card {
        width: @small-size;
        height: @small-size;
        line-height: @small-size;
        text-align: center;
    }
}

.el-upload-list__item&&.is-success {
    .img-con {
        width: 100%;
        height: 100%;
    }
}

.avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
}

.avatar-uploader .el-upload:hover {
    border-color: #409eff;
}

.avatar-uploader-icon {
    font-size: 28px;
    position: relative;
    color: #8c939d;
    width: 220px;
    height: 220px;
    background: url("~@/assets/companyFile/uploadicon.png") center no-repeat !important;
    background-size: 40% 40% !important;

    div {
        position: absolute;
        top: 160px;
        left: 16px;
        font-size: 19px;
    }
}
</style>
  