美文网首页工作生活
微信多图上传 ios手机上偶尔出现报错chooseImage:t

微信多图上传 ios手机上偶尔出现报错chooseImage:t

作者: 八妹sss | 来源:发表于2019-07-03 16:35 被阅读0次

问题:微信多图上传 ios手机上偶尔出现报错chooseImage:the permission value is offline verifying(上传流程wx.chooseImage、给后台serverId用wx.uploadImage、本地展示用wx.getLocalImgData)

image.png

问题分析: 开启debug测试得出,先报错chooseImage:the permission value is offline verifying,在弹出config:ok

得出结论:导致错误的原因是"先执行了wx.chooseImage方法再执行wx.config(有请求异步导致)"。正常的情况是先弹出config,再调用wx.chooseImage方法

解决方法:

1、 setTimeout(() => { }, 400) // 延迟一下
2、放在wx.ready里面 确保wx.config执行完成触发

实现代码

Publish.vue

html
<!--图片展示-->
<div class="form-img-container" v-if="arr.length > 0">
  <!-- 微信上传图片 -->
  <wechat-uploader-img v-if="data" @addImg="addImg" @success="success(index)" @error="error(index)" :is-publish="true"   @showImgDetail="showImgDetail(index, data)"
                      v-for="(data,index) in arr" :key="index" :index="index" :info="data" :mold="'bulletin'"/>
</div>
<!--上传按钮-->
<template>
  <div class="uploaderImg" @click="handleChooseImage()">
    <div class="add-img-icon"></div>
    <div class="add-img-text">图片{{ arr.length }}/3张</div>
  </div>
</template>
js
// 微信上传
import WechatUploaderImg from '@/components/WechatUploaderImg'
export default {
  data () {
    return {
      form: {
        images: [] // 上传到服务器的相册
      },
      isLoading: false,
      // 暂存读取后数据
      arr: [],
      // 是否显示提示框
      showDialog: false,
      // 是否是ios手机
      isIos: this.$utils.isIOS()
    }
  },
  components: {
    WechatUploaderImg
  },
  methods: {
    // 图片上传(微信的js-dk)
    handleChooseImage () {
      if (this.isLoading) {
        return
      }
      this.isLoading = true

      let arr = []
      for (let i = 0; i < this.arr.length; i++) {
        if (this.arr[i]) {
          arr.push(this.arr[i])
        }
      }
      // 实际可用长度
      let arrLen = arr.length
      if (arrLen >= 3) {
        this.isLoading = false
        this.$utils.showMessage('亲,最多只能上传3张图片哦~')
      } else {
        if (this.isIos) {
          setTimeout(() => { // 解决问题的重要代码(定时器延时)
            this.fetChooseImage(arrLen)
          }, 400)
        } else {
          this.fetChooseImage(arrLen)
        }
      }
    },
    fetChooseImage (arrLen) {
      // eslint-disable-next-line
      wx.ready(() => { // 解决问题的重要代码(方wx.ready里面)
        this.$store.dispatch('Wechat/chooseImage', 3).then(res => {
          this.isLoading = false
          let localIds = res.localIds
          if (localIds.length > 0 && 3 - arrLen >= localIds.length) {
            this.localIdArr = localIds
          } else if (localIds.length > 0 && 3 - arrLen < localIds.length) {
            this.localIdArr = localIds.slice(0, 3 - arrLen)
          }
          this.handleUploadImage()
        }).catch(err => {
          this.isLoading = false
          if (err.errMsg !== 'chooseImage:cancel') {
            this.$utils.showErrorMsg('chooseImage:' + JSON.stringify(err))
          }
        })
      })
    },
    handleUploadImage () {
      if (!this.localIdArr.length) {
        return
      }
      let localId = this.localIdArr.shift()
      this.$store.dispatch('Wechat/uploadImage', localId).then(res => {
        let serverId = res.serverId // 返回图片的服务器端ID
        this.handleGetLocalImgData(localId, serverId)
        this.handleUploadImage()
      }).catch(err => {
        this.$utils.showErrorMsg(err)
      })
    },
    handleGetLocalImgData (localId, serverId) {
      this.$store.dispatch('Wechat/getLocalImgData', localId).then(res => {
        let localData = res.localData
        let obj = {
          // 读取成功的数据
          readData: localData,
          serverId: serverId,
          // 上传成功的状态 true代表成功,false代表还在上传,null代表错误
          isSuccess: false,
          // 是否显示蒙层
          isShow: true
        }
        this.arr.push(obj)
      }).catch(err => {
        this.$utils.showErrorMsg(err)
      })
    },
    // 数据库添加图片
    addImg (src, index) {
      if (index !== undefined && this.form.images.length > index) {
        this.form.images.splice(index, 1, {url: src})
      }
      if (index !== undefined && this.form.images.length <= index) {
        this.form.images[index] = {url: src}
      }
    },
    // 删除图片
    deleteImg () {
      this.arr.splice(this.imgDetailIndex, 1)
      this.form.images.splice(this.imgDetailIndex, 1)
      this.isShowImgDetail = false
    },
    // 上传成功的状态
    success (index) {
      this.arr[index].isShow = false
      this.arr[index].isSuccess = true
    },
    // 上传失败的提示
    error (index) {
      this.arr[index].isSuccess = null
    }
  },
  watch: {
    arr (newVal) {
      let length = newVal.length
      if (length === 0) {
        this.$refs.formInside.style.minHeight = '7.1rem'
        this.$refs.formMid.style.minHeight = '5.4rem'
      } else if (length > 0) {
        let trueLength = 0
        newVal.forEach(item => {
          if (item) {
            trueLength++
          }
        })
        if (trueLength > 0) {
          this.$refs.formInside.style.minHeight = 'unset'
          this.$refs.formMid.style.minHeight = '2.172rem'
        } else {
          this.$refs.formInside.style.minHeight = '7.1rem'
          this.$refs.formMid.style.minHeight = '5.4rem'
        }
      }
    }
  }
}

components/WechatUploaderImg

html
  <template v-if="mold == 'bulletin'">
      <div @click.prevent.stop="showImgDetail" v-if="info.readData" class="form-img">
        <!-- 公告预览 有http开头的图片 先判断http的图片再判断机型 -->
        <img v-if="info.readData.indexOf('http') === 0"  :src="info.readData" alt="">
        <img v-else-if="isIos" :src="info.readData" alt="">
        <img v-else :src="'data:image/gif;base64,' + info.readData" alt="">
        <transition name="fade">
          <div v-if="info.isShow" :id="index" class="img_circle"></div>
        </transition>
      </div>
  </template>

js

export default {
  created () {
    // 当url是http时不用上传
    if (this.info.readData && this.info.readData.indexOf('http') !== 0) {
      this.fetchImages()
    }
  },
  props: {
    info: {
      type: Object
    },
    index: {
      type: Number
    },
    mold: {
      type: String
    }
  },
  data () {
    return {
      loading: {
        rate: 0
      },
      // 是否是ios手机
      isIos: this.$utils.isIOS()
    }
  },
  methods: {
    // 图片上传到七牛
    fetchImages () {
      this.$http.post(`v1/common/upload/img`, {
        img_content: this.info.serverId,
        type: 1
      }).then(res => {
        let src = res.data.meta.img_url
        this.$emit('addImg', src, this.index)
        this.success()
      }).catch(err => {
        this.$utils.showErrorMsg(err)
        this.error()
      })
    },
    // 上传失败
    error () {
      this.$emit('error', this.index)
      this.$utils.showErrorMsg('图片上传有误,请重新上传')
    },
    // 上传成功
    success () {
      this.$emit('success', this.index)
    },
    // 删除
    splice () {
      this.$emit('splice', this.index)
    },
    // 点击预览
    showImgDetail () {
      this.$emit('showImgDetail', this.index)
    }
  },
  watch: {
    info (val) {
      // 微信上传
      if (this.mold === 'avatar' && this.info.readData && this.info.readData.indexOf('http') !== 0) {
        this.fetchImages()
      }
    }
  }
}

Wechat.js

import Http from '@/libs/Http'
import Utils from '@/libs/Utils'

const state = {
  url: ''
}

const mutations = {
  /**
   * 设置校验url
   * @param {Object} state 状态
   */
  setUrl (state) {
    let currentUrl = document.URL
    if (Utils.isIOS()) {
      let landingUrl = sessionStorage.getItem('ios_landing_url')
      if (landingUrl) {
        state.url = landingUrl
      } else {
        state.url = currentUrl
      }
    } else {
      state.url = currentUrl
    }
  }
}

const actions = {
  /**
   * 初始化微信配置
   * @param {*} param0
   * @param {*} payload payload.perms微信权限
   */
  initConfig ({commit, state}, payload) {
    return new Promise((resolve, reject) => {
      let data = {
        url: state.url,
        perms: payload.perms
      }
      Http.post('/v1/wechat/js', data).then(response => {
        let wechatJs = response.data.meta.wechat_js
        // wechatJs.debug = true
        /* eslint-disable no-undef */
        wx.config(wechatJs)
        resolve()
        wx.error(err => {
          console.log('wx.err', err)
        })
      }).catch(err => {
        Utils.showError(err)
        reject(err)
      })
    })
  },

  /**
   * 分享操作
   * @param {Object} param0
   * @param {Object} payload {title:'',link:null,desc:null,type:null,img:''}
   */
  share ({dispatch, state}, payload) {
    return new Promise((resolve, reject) => {
      dispatch('initConfig', {perms: ['onMenuShareTimeline', 'onMenuShareAppMessage']}).then(() => {
      // dispatch('initConfig', {perms: ['updateAppMessageShareData', 'updateTimelineShareData']}).then(() => {
        let parsedLink = payload.link === undefined || !payload.link ? window.location.href : payload.link
        /* eslint-disable no-undef */
        wx.ready(() => { // 因为是页面加载时就需要调用相关接口所以要加wx.ready方法
          let share = {
            title: payload.title,
            link: parsedLink,
            desc: payload.desc,
            type: payload.type === null ? 'link' : payload.type,
            imgUrl: payload.img === undefined || !payload.img ? null : payload.img,
            success: resolve,
            cancel: reject
          }
          wx.onMenuShareTimeline(share)
          wx.onMenuShareAppMessage(share)
          // wx.updateAppMessageShareData(share)
          // wx.updateTimelineShareData(share)
        })
      })
    })
  },
  /**
   * 关闭分享操作
   */
  unShare ({dispatch, state}, payload) {
    return new Promise((resolve, reject) => {
      if (payload === 'both') {
        dispatch('initConfig', {perms: ['chooseImage', 'getLocalImgData', 'uploadImage', 'hideAllNonBaseMenuItem']}).then(() => {
          /* eslint-disable no-undef */
          wx.ready(() => { // 因为是页面加载时就需要调用相关接口所以要加wx.ready方法
            wx.hideAllNonBaseMenuItem()
          })
        })
      } else {
        dispatch('initConfig', {perms: ['hideAllNonBaseMenuItem']}).then(() => {
          /* eslint-disable no-undef */
          wx.ready(() => { // 因为是页面加载时就需要调用相关接口所以要加wx.ready方法
            wx.hideAllNonBaseMenuItem()
          })
        })
      }
    })
  },

  /**
   * 从相册中选图片或者拍照
   */
  chooseImage ({dispatch, state}, payload) {
    return new Promise((resolve, reject) => {
      // 因为是用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中
      wx.chooseImage({
        count: payload, // 默认9张照片
        sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
        sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
        success: resolve,
        fail: reject,
        complete: reject
      })
    })
  },

  /**
   * 获取本地图片
   */
  getLocalImgData ({dispatch, state}, payload) {
    return new Promise((resolve, reject) => {
      // 因为是用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中
      wx.getLocalImgData({
        localId: payload, // 图片的localID
        success: resolve,
        fail: reject
      })
    })
  },

  /**
   * 上传图片接口
   */
  uploadImage ({ dispatch, state }, payload) {
    return new Promise((resolve, reject) => {
      wx.uploadImage({
        localId: payload, // 需要上传的图片的本地ID,由chooseImage接口获得
        isShowProgressTips: 0, // 默认为1,显示进度提示
        success: resolve,
        fail: reject
      })
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

相关文章

网友评论

    本文标题:微信多图上传 ios手机上偶尔出现报错chooseImage:t

    本文链接:https://www.haomeiwen.com/subject/sbqchctx.html