<!-- 上传图片 -->
<template>
  <div>
    <div ref="uploadImage" class="upload-image">
      <div
        class="image-item"
        v-for="(item, index) in list"
        :style="{
          backgroundImage: 'url(' + item.url + ')',
          width: currentWidth,
          height: currentHeight
        }"
        :key="index"
        @click="showImage(item)"
      >
        <van-icon class="delete" name="clear" @click.stop="deleteImage(index)" v-if="!readonly" />
      </div>
      <div class="clearfloat"></div>

      <div
        class="image-item upload-btn"
        :style="{ width: currentWidth, height: currentHeight }"
        @click.stop="chooseImage"
        v-if="list.length < maxCount && !readonly"
      >
        <van-icon class="icon" name="photograph" />
      </div>
    </div>

    <van-uploader ref="uploader" :multiple="multiple" :after-read="afterRead" v-show="false"> </van-uploader>
  </div>
</template>
<script>
export default {
  name: 'CsUploadImage',
  components: {},
  props: {
    // 当前输入的值
    value: {
      default: null
    },
    // 类型 default、wechat
    type: {
      type: String,
      default: 'default'
    },
    // 租户编号
    tenantId: {
      default: null
    },
    // 图片宽度
    width: {
      type: String,
      default: ''
    },
    // 图片高度
    height: {
      type: String,
      default: ''
    },
    // 是否选择多个文件
    multiple: {
      type: Boolean,
      default: null
    },
    // 最大上传张数
    max: {
      type: Number,
      default: 50
    },
    // 只读
    readonly: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      currentValue: '',
      currentWidth: '',
      currentHeight: '',
      currentType: this.type,
      list: []
    }
  },
  //监听属性 类似于data概念
  computed: {
    maxCount() {
      if (this.multiple) {
        return Number(this.max)
      } else {
        return 1
      }
    }
  },
  //监控data中的数据变化
  watch: {
    value: {
      handler(val, oldVal) {
        if (this.currentValue != val && val !== oldVal) {
          this.setData()
        }
      },
      immediate: true, // 首次绑定是否执行
      deep: true // 对象内部的属性监听，也叫深度监听
    }
  },
  //方法集合
  methods: {
    change() {
      this.$forceUpdate()
    },

    /** 查看图片 */
    showImage(item) {
      let urls = []
      let startPosition = 0
      for (let i = 0; i < this.list.length; i++) {
        const urlItem = this.list[i]
        urls.push(urlItem.originalUrl)
        if (urlItem.fileId === item.fileId) {
          startPosition = i
        }
      }

      // 微信公众号
      if (this.type == 'wechat') {
        this.$weixin.previewImage(item.originalUrl, urls)
      }
      // 默认h5
      else {
        vant.ImagePreview({
          images: urls,
          startPosition: startPosition
        })
      }
    },

    /** 选择图片 */
    chooseImage() {
      if (this.currentType == 'wechat') {
        this.wxChooseImg()
      } else {
        this.$refs.uploader.chooseFile()
      }
    },

    // *************************************** begin 微信jssdk上传文件 ***************************************
    /** 微信接口选择图片 */
    async wxChooseImg() {
      let updateCount = 9
      if (this.max < updateCount) {
        updateCount = this.max
      }
      await this.$weixin.chooseImg(updateCount, async localIds => {
        if (localIds.length <= 0) {
          this.$util.warning('选择图片失败')
          return
        }
        // 上传数量检查
        if (!this.uploadCountCheck(localIds.length)) {
          return
        }

        var serviceIds = []
        for (let i = 0; i < localIds.length; i++) {
          const localId = localIds[i]
          vant.Toast.loading({
            duration: 0,
            message: `正在解析第${i + 1}/${localIds.length}张图片...`,
            forbidClick: true
          })
          console.log(`解析第${i + 1}张图片`)
          let serviceId = await this.wxUploadImg(localId)
          serviceIds.push(serviceId)
        }
        this.uploadWeiXinFile(serviceIds)
      })
    },

    /** 微信接口上传图片 */
    wxUploadImg(localId) {
      return new Promise((resolve, reject) => {
        this.$weixin.uploadImg(localId, serviceId => {
          resolve(serviceId)
        })
      })
    },

    /** 微信上传图片 */
    uploadWeiXinFile(serviceIds) {
      vant.Toast.loading({
        duration: 0,
        message: `正在上传图片...`,
        forbidClick: true
      })
      var wxUserInfo = window.allInfo.WxUserInfo
      this.postAxios(
        `//api/v2/Foundation/DbFile`,
        { action: 'NewWeiXinFile', tenantId: this.tenantId },
        { ServiceIds: serviceIds, AppId: wxUserInfo.AppId },
        null,
        { disableLoading: true }
      )
        .then(res => {
          vant.Toast.clear()
          if (res && res.length > 0) {
            res.forEach(fileId => {
              let url = this.$util.getThumbnail(this.tenantId, fileId)
              let originalUrl = this.$util.getFileUrl(this.tenantId, fileId)
              this.list.push({ fileId: fileId, url: url, originalUrl: originalUrl })
            })
            this.change()
            this.setCurrentValue()
            this.$util.info('上传图片成功')
          } else {
            this.$util.warning('上传图片失败')
          }
        })
        .catch(error => {
          vant.Toast.clear()
        })
    },
    // *************************************** end 微信jssdk上传文件 ***************************************

    // *************************************** begin h5上传文件 ***************************************
    /** 文件读取完成后的回调函数 */
    async afterRead(files) {
      if (!files.length) {
        files = [files]
      }
      // 上传数量检查
      if (!this.uploadCountCheck(files.length)) {
        return
      }
      for (let i = 0; i < files.length; i++) {
        const file = files[i]
        vant.Toast.loading({
          duration: 0,
          message: `正在上传第${i + 1}/${files.length}张图片...`,
          forbidClick: true
        })
        await this.defaultUploadFile(file)
      }
      vant.Toast.clear()
      this.setCurrentValue()
      this.$util.info('上传图片成功')
    },

    /** 默认上传图片文件 */
    async defaultUploadFile(file) {
      await this.postAxios(
        `//api/v2/Foundation/DbFile`,
        { action: 'New', tenantId: this.tenantId },
        file,
        { 'content-type': 'multipart/form-data' },
        { disableLoading: true }
      )
        .then(res => {
          let url = this.$util.getThumbnail(this.tenantId, res.Id)
          let originalUrl = this.$util.getFileUrl(this.tenantId, res.Id)
          this.list.push({ fileId: res.Id, url: url, originalUrl: originalUrl })
          this.change()
        })
        .catch(error => {
          console.error(error)
          vant.Toast.clear()
        })
    },
    // *************************************** end h5上传文件 ***************************************

    /** 删除图片 */
    deleteImage(index) {
      vant.Dialog.confirm({
        message: `请确认是否要删除第${index + 1}张图片？`
      })
        .then(() => {
          this.list.splice(index, 1)
          this.setCurrentValue()
          this.$util.info('删除成功')
        })
        .catch(() => {})
    },

    /** 上传数量检查 */
    uploadCountCheck(count) {
      if (this.list.length + count > this.maxCount) {
        this.$util.warning(`最多可以上传${this.maxCount}张图片`)
        return false
      }
      return true
    },

    /** 设置返回的字段 */
    setCurrentValue(fileId) {
      let currentValue = null
      if (this.multiple) {
        let fileIds = []
        this.list.forEach(item => {
          fileIds.push(item.fileId)
        })
        currentValue = fileIds.join(',')
      } else {
        if (this.list.length > 0) {
          currentValue = Number(this.list[0].fileId)
        }
      }
      this.currentValue = currentValue
      this.$emit('input', this.currentValue)
    },

    /** 设置图片大小 */
    setImageSize() {
      this.$nextTick(() => {
        let currentWidth = ''
        let currentHeight = ''

        if (this.width) {
          currentWidth = this.width
        }
        if (this.height) {
          currentHeight = this.height
        }

        let visibleWidth = this.$refs.uploadImage.scrollWidth
        if (!currentWidth) {
          currentWidth = `${(visibleWidth / 3) * 0.9}px`
        }

        if (!currentHeight) {
          currentHeight = `${(visibleWidth / 3) * 0.9}px`
        }
        this.currentWidth = currentWidth
        this.currentHeight = currentHeight
      })
    },

    setData() {
      let list = []
      if (this.multiple) {
        let values = []
        if (this.value) {
          values = this.value.split(',')
        }
        for (let i = 0; i < values.length; i++) {
          const fileId = values[i]
          if (fileId && Number(fileId)) {
            let url = this.$util.getThumbnail(this.tenantId, fileId)
            let originalUrl = this.$util.getFileUrl(this.tenantId, fileId)
            list.push({ fileId: Number(fileId), url: url, originalUrl: originalUrl })
          }
        }
      } else {
        if (Number(this.value)) {
          let url = this.$util.getThumbnail(this.tenantId, this.value)
          let originalUrl = this.$util.getFileUrl(this.tenantId, this.value)
          list.push({ fileId: Number(this.value), url: url, originalUrl: originalUrl })
        }
      }
      this.list = list
      this.setCurrentValue()
    }
  },
  //生命周期 - 创建完成（可以访问当前this实例）
  created() {},
  //生命周期 - 挂载完成（可以访问DOM元素）
  mounted() {
    if (!this.tenantId && this.tenantId !== 0) {
      this.$util.warning('请设置租户编号')
    }
    if (this.type == 'wechat') {
      this.currentType = 'wechat'
    } else {
      if (this.$util.isWei() || this.$util.isQYWei()) {
        this.currentType = 'wechat'
      }
    }

    this.setImageSize()
    this.setData()
  },
  beforeCreate() {}, //生命周期 - 创建之前
  beforeMount() {}, //生命周期 - 挂载之前
  beforeUpdate() {}, //生命周期 - 更新之前
  updated() {}, //生命周期 - 更新之后
  beforeDestroy() {}, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
  activated() {} //如果页面有keep-alive缓存功能，这个函数会触发
}
</script>
<style lang="scss" scoped>
//图片盒子
.upload-image {
  width: 100%;
  display: flex;
  flex-wrap: wrap;

  .image-item {
    position: relative;
    margin: 0 2% 2% 0;
    padding: 0;
    background-repeat: no-repeat;
    background-position: center;
    background-size: cover;
  }

  .delete {
    position: absolute;
    top: 7px;
    right: 0px;
    opacity: 0.8;
    color: #fff;
    width: 25px;
    height: 25px;
    border-radius: 0 0 0 15px;
    z-index: 100;
  }

  // 上传图片按钮
  .upload-btn {
    box-sizing: border-box;
    background: #f7f8fa;
    border-radius: 5px;

    .icon {
      position: absolute;
      top: calc(50% - 3.18vw);
      right: calc(50% - 3.18vw);
      object-fit: cover;
      font-size: 6.36vw;
      color: #dfdfdf;
    }
  }
}
</style>
