最近做了一个红包兑换小程序,遇到了一些问题这里做一下总结。

1、需求:回流用户在game客户端获取到口令,然后在小程序这边输入口令兑换红包,成功之后钱会发到用户微信账户里。

2、流程:若未授权,显示授权按钮。点击授权登录,授权成功后获取到私密字段iv和encryptedData,调取登陆接口,错误则提示相关信息,正确则跳转校验姓名和shenfenzheng的页面,校验通过就调取提现接口,成功则提示提现成功,同时显示生成分享图按钮。分享图由用户昵称,头像,二维码,提现金额等等组成。

3、框架:uniapp

分享图的问题

1、 measureText 获取宽度的时候,传入的参数如果是数字,则会返回0。

let money = 10;  //这里需要把数字转成字符串
ctx.measureText(money).width;

2、绘制图片的时候不要忘了先使用 getImageInfo 转成临时地址,再 drawImage ,如果不经过这步,虽然开发者工具上看到是正常的,但是真机是显示不了。

3、需要绘制微信头像的时候,要在后台配置downloadFile合法域名 https://wx.qlogo.cn

4、最初背景图大概170KB,尺寸750*1334,最终绘制出来的分享图太大了。解决方法:

  • 把背景图片尽量再压缩,最终是60多KB。
  • 调 canvasToTempFilePath 的时候,设置 fileType 为jpg,quality范围是(0,1],取个合适的值。
    5、小程序里面的保存图片并不是长按保存的,需要点击按钮授权。
onGotUserInfo(e){
    uni.saveImageToPhotosAlbum({
        filePath: this.tempPath,
        success(res) {
            uni.showToast({
              title: '保存成功',
              icon: 'success',
              duration: 1500
            })
        },
        fail(err){

        }
    })
}
...

如图:如果用户点击确定,就会正常保存图片到本地相册了。

新年红包大派送,做个红包兑换小程序大家乐一乐,红包小程序小结_第1张图片

如果用户点击取消,不授权呢?那还能怎么样,点击再弹出原来的弹窗重新授权呗。很遗憾,这里并不能像授权登录弹窗一样点了取消之后,再次点击授权按钮还会唤起那个弹窗。

解决方法:在 saveImageToPhotosAlbum 的fail回调函数里面操作,再次获取保存到相册权限。

if (err.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || err.errMsg === "saveImageToPhotosAlbum:fail authorize no response" || err.errMsg === "saveImageToPhotosAlbum:fail auth deny") {
  uni.showModal({
    title: '提示',
    content: '需要您授权保存相册',
    showCancel: false,
    success:res=>{
      uni.openSetting({
        success(settingdata) {
          if (settingdata.authSetting['scope.writePhotosAlbum']) {
            uni.showModal({
              title: '提示',
              content: '获取权限成功,再次点击保存图片按钮即可保存',
              showCancel: false,
            })
          } else {
            uni.showModal({
              title: '提示',
              content: '获取权限失败,将无法保存到相册哦~',
              showCancel: false,
            })
          }
        },
        fail(failData) {
          console.log("failData",failData)
        },
        complete(finishData) {
          console.log("finishData", finishData)
        }
      })
    }
  })
}

点击取消按钮之后,会跳转到这里。打开设置里的“保存到相册”的开关即可。

新年红包大派送,做个红包兑换小程序大家乐一乐,红包小程序小结_第2张图片

原生微信小程序和uniapp框架的一些对比

针对此次项目,这里挑两点来写。

全局变量的管理

1、原生微信小程序可以在app.js的globalData对象中对全局变量进行管理

app.js

App({
    globalData: {
        session:""
    }
})

pages/index/index.js

...
const app = getApp()//获取应用实例
app.globalData.session = "xxxx" //设置
app.globalData.session  //读取
...

2、uniapp用的是vue的那套,所以可以用vuex来管理状态

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const store = new Vuex.Store({
     state : {
        session:""
     },
     mutations : {
        getSession(state, res){
            state.session = res;
        },
     }
});
export default store

设置

this.$store.commit('getSession',res.session) //接口返回res.session

获取

this.$store.state.session

页面获取全局函数返回的值

1、原生微信小程序,比如在app.js中获取用户信息保存在 globalData 中userInfo字段,然后页面在onload的时候获取全局的userInfo,你会发现有时候拿不到。由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回,所以需要加入 callback 以防止这种情况。

app.js

App({
  onLaunch: function() {
    this.init()
  },
  init: function() {
    // 获取用户授权结果
    wx.getSetting({
      success: (res) => {
        if (res.authSetting['scope.userInfo']) {
          wx.getUserInfo({ // 获取用户信息
            success: res => {
              this.globalData.userInfo = res.userInfo;
              if (this.userInfoReadyCallback) {
                this.userInfoReadyCallback(res)
              }
            },
            //拒绝授权
            fail: res => {

            }
          })
        } else {

        }
      }
    })
  },
  globalData: {
    userInfo: ""
  }
})

pages/index/index.js

const app = getApp()
Page({
  data: {
    userInfo:""
  },
  onLoad: function() {
    if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
      })
    } else{
      app.userInfoReadyCallback = res => {
        this.setData({
          userInfo: res.userInfo,
        })
      }
    } 
  },
})

2、uniapp是配合vuex和计算属性computed来处理的

APP.vue

export default {
    onLaunch: function() {
        this.getUserInfo();
    },
    methods:{
        getUserInfo() {
            uni.getSetting({
              success: (res) => {
                if (res.authSetting['scope.userInfo']) {
                  uni.getUserInfo({ // 获取用户信息 
                    success: res => {
                        this.$store.commit('userInfo',{
                            avatarUrl:res.userInfo.avatarUrl,
                            nickName:res.userInfo.nickName
                        })
                    },
                    fail: res => {

                    }
                  })
                } else {

                }
              }
            })
        },  
    }
}

pages/index/index.vue

获取到 userInfo 便可以使用了,如果需要,还可以使用watch监听。

export default {
    data() {
        return {

        } 
    },
    onLoad(){

    },
    computed: {
        userInfo() {
            return this.$store.state.hasUserInfo
        }
    },
    watch:{
        userInfo(val){
            if(val){

            }
        }
    },
    created() {

    },
    methods: {

    }
}

看完上面,可以尝试做一个

第一次看文章的朋友可以关注我,会不定期发布大厂面试题、Android架构技术知识点及解析等内容,还有Android学习PDF+源码笔记+面试文档+进阶视频+Flutter+Kotlin+小程序等学习内容分享

今天的小程序想学习的话,可以关注我,私信我【小程序】知道怎样免费领取

更多Android学习内容还可以看我的GitHub链接:https://github.com/Meng997998/AndroidJX,
看完顺便点一下star

新年红包大派送,做个红包兑换小程序大家乐一乐,红包小程序小结_第3张图片

新年红包大派送,做个红包兑换小程序大家乐一乐,红包小程序小结_第4张图片

新年红包大派送,做个红包兑换小程序大家乐一乐,红包小程序小结_第5张图片