<template>
  <div class="uploadImg-wrap">
    <ul class="imgList-box" v-show="imgList && imgList.length > 0">
      <li class="imgItem" v-for="(item, index) in imgList" :key="index" :style='imgBoxStyle'>
        <img :src="item.fullSrc" alt="" @click="previewImg(index)" v-if="item.fullSrc !== undefined && item.fullSrc !== null && item.fullSrc !== ''">
        <img :src="loadingImg" alt="" v-else>
        <i class="icon1 delete-item" v-if="ableDelete" @click="handleDeleteImage(item.objectKey, index)">&#xe827;</i>
      </li>
    </ul>
    <div class="upload-btn" v-if="imgList.length < limitAmount" :style='imgBoxStyle'>
      <input id="upload" type="file" accept="image/*" required capture="camera" :multiple='isMultifile' ref="inputref" @change="uploadImg" />
      <i class="icon1 icon-iconfontadd"></i>
    </div>
    <div v-transfer-dom>
      <previewer :list="listPreviewer" ref="previewer"></previewer>
    </div>
  </div>
</template>

<script>
import aliOssApi from '@/api/aliOssApi'
import ossPaths from '@/assets/ossPaths'
import ossConfig from '@/assets/ossConfig'
import ossHandle from '@/assets/ossHandle'
import Common from '@/assets/common'
import client from '@/assets/oss'
import CryptoJS from 'crypto-js'
import { Previewer, TransferDom } from 'vux'
import loadingImg from '@/assets/images/loading.png'
export default {
    name: 'BrowserUploadImage',
    components: {
        Previewer
    },
    directives: {
        TransferDom
    },
    props: {
    /**
     * 图片集合
     * 类型 Array 默认 空数组
     */
        imgList: {
            type: Array,
            default: () => []
        },
        /**
     * 限制上传图片的数量
     * 类型 Number 默认 3
     */
        limitAmount: {
            type: Number,
            default: () => 3
        },
        /**
     * 是否可以多选文件
     * 类型 Boolean 默认 多选
     */
        isMultifile: {
            type: Boolean,
            default: () => true
        },
        /**
     *  是否允许删除
     *  类型 Boolean 默认 true（允许删除）
     * */
        ableDelete: {
            type: Boolean,
            default: true
        },
        /**
     * 图片域名
     * 类型 String 必传
     *
     * */
        fileDomain: {
            type: String,
            default: 'https://vschool-solution.oss-cn-shenzhen.aliyuncs.com'
        },
        /**
     * 图片外面盒子的样式
     * 类型 String 非必传
     * */
        imgBoxStyle: {
            type: String,
            default: ''
        }
    },
    data () {
        return {
            ossParams: {
                accessKeyId: '',
                accessKeySecret: '',
                stsToken: '',
                endpoint: ossConfig.bussinessFileBucket.endpoint,
                bucket: ossConfig.bussinessFileBucket.bucket,
                region: ossConfig.bussinessFileBucket.region
            },
            filePath: ossPaths.moralEducation.recordPic,
            imgUrl: '',
            percentage: 100,
            currentImageIndex: -1, // 当前操作图片的索引
            listPreviewer: [],
            loadingImg: loadingImg
        }
    },
    created () {
        this.getAliOssParams()
        this.getPreviewImgList()
    },
    methods: {
    // 上传图片之前先获取sts秘钥
        getAliOssParams () {
            aliOssApi.getToken().then(res => {
                let data = res.data
                if (data.Status) {
                    this.ossParams.accessKeyId = data.Data.AccessKeyId
                    this.ossParams.accessKeySecret = data.Data.AccessKeySecret
                    this.ossParams.stsToken = data.Data.SecurityToken
                } else {
                    this.$vux.toast.show({
                        text: data.ResponseError.LongMessage,
                        type: 'cancel'
                    })
                }
            }).catch(err => {
                console.log(err)
            })
        },
        // 上传文件
        uploadFile (fileParams) {
            this.uploading = true
            let loadingInstance
            let file = fileParams
            let point = file.name.lastIndexOf('.')
            let suffix = file.name.substr(point) // 文件后缀名
            let fileName = file.name.substr(0, point) // 去掉后缀名的文件名
            let fileAliasName = `wx_file_${this.randomNum(10)}`
            const date = Common.formatDate(
                new Date().getFullYear(),
                new Date().getMonth() + 1,
                new Date().getDate()
            ).replace(/\s/g, '')
            let size = file.size // 单位B
            let storeAs = `${this.filePath}/${date}/${fileAliasName}_${fileName}${suffix}`
            let progress = {
                progress: function (p) {
                    this.percentage = Math.floor(p * 100)
                    return Math.floor(p * 100)
                }
            }
            let ossClient = client(this.ossParams)
            ossClient.multipartUpload(storeAs, file, progress).then(result => {
                // 下面是如果对返回结果再进行处理，根据项目需要
                if (result.res && result.res.status === 200) {
                    let obj = {
                        object_key: result.name,
                        file_name: fileName,
                        file_size: size,
                        filesuffix: suffix,
                        fileUrl: `/${result.name}`,
                        src: `/${result.name}`,
                        fullSrc: `${this.fileDomain}/${result.name}`,
                        msrc: `/${result.name}?x-oss-process=image/resize,p_50`
                    }
                    this.$vux.loading.show({
                        text: '上传' + this.percentage + '%'
                    })
                    let timer = setTimeout(() => {
                        this.$vux.loading.hide()
                        clearTimeout(timer)
                    }, 2000)
                    this.$emit('uploadSucc', obj)
                    this.getPreviewImgList()
                }
                this.uploading = false
                if (this.multiple) {
                    loadingInstance.close()
                }
            }).catch(err => {
                this.uploading = false
                console.log(err)
                if (this.multiple) {
                    loadingInstance.close()
                }
            })
        },
        // 字符串转成URL安全base64编码
        getBase64 (word) {
            var str = CryptoJS.enc.Utf8.parse(word)
            var base64 = CryptoJS.enc.Base64.stringify(str)
            return base64
        },
        /**
     * 删除图片
     */
        handleDeleteImage (objectKey, index) {
            this.$vux.confirm.show({
                // 组件除show外的属性
                title: '提示',
                content: '确认删除图片吗？',
                onCancel: () => {},
                onConfirm: () => {
                    this.currentImageIndex = index
                    ossHandle.handleDelete(this.handleDeleteImageSucc, objectKey)
                }
            })
        },
        // 删除图片成功
        handleDeleteImageSucc () {
            let index = this.currentImageIndex
            this.$emit('deleteImageSucc', index)
        },
        // 日期时间格式
        formatDateTime (date) {
            var y = date.getFullYear()
            var m = date.getMonth() + 1
            m = m < 10 ? '0' + m : m
            var d = date.getDate()
            d = d < 10 ? '0' + d : d
            var h = date.getHours()
            h = h < 10 ? '0' + h : h
            var minute = date.getMinutes()
            minute = minute < 10 ? '0' + minute : minute
            var second = date.getSeconds()
            second = second < 10 ? '0' + second : second
            return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second
        },
        /**
     * 获取指定位数的随机数
     * @param {Number} n = [随机数的位数]
     * */
        randomNum (n) {
            var rnd = ''
            for (var i = 0; i < n; i++) {
                rnd += Math.floor(Math.random() * 10)
            }
            return rnd
        },
        uploadImg (e) {
            let len = e.target.files.length
            let imgListLen = this.imgList.length
            if (this.isMultifile === true && this.limitAmount < imgListLen + len) {
                this.$vux.toast.show({
                    text: `最多只能上传${this.limitAmount}张图片，请重新选择`,
                    type: 'warn'
                })
                return
            }
            if (len > 1) { // 上传多张图片
                for (let index = 0; index < len; index++) {
                    const file = e.target.files[index]
                    this.uploadFile(file)
                }
            } else { // 上传单张图片
                this.uploadFile(e.target.files[0])
            }
        },
        /**
     * 封装预览图片集合
     */
        getPreviewImgList () {
            if (this.imgList.length > 0) {
                this.listPreviewer.length = 0
                this.imgList.forEach(item => {
                    let obj = {
                        src: item.fullSrc
                    }
                    this.listPreviewer.push(obj)
                })
            }
        },
        /**
     * 预览图片
     */
        previewImg (index) {
            this.$refs.previewer.show(index)
        }
    }
}
</script>

<style lang="less" scoped>
.uploadImg-wrap {
  display: flex;
  padding-top: .14rem;
  .imgList-box{
    display: flex;
    flex-wrap: wrap;
    li{
      width: .7rem;
      height: .7rem;
      margin-right: .13rem;
      position: relative;
      i{
        position: absolute;
        right: -9px;
        top: -9px;
        color: #fff;
        width: 18px;
        height: 18px;
        background: red;
        border-radius: 50%;
        overflow: hidden;
        line-height: 18px;
        text-align: center;
        font-size: 0.13rem;
      }
      img{
        width: 100%;
        height: 100%;
        display: block;
      }
    }
  }
  .upload-btn{
    width: .7rem;
    height: .7rem;
    overflow: hidden;
    position: relative;
    border: 1px dashed #ddd;
    border-radius: 4px;
    text-align: center;
    input{
      opacity: 0;
      width: 200%;
      height: 200%;
      font-size: 1rem;
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      margin: auto;
      z-index: 99;
    }
    i{
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      margin: auto;
      z-index: 1;
      font-size: .6rem;
      color: #999;
      line-height: .7rem;
    }
  }
}
</style>
