最近做了一个红包兑换小程序,遇到了一些问题这里做一下总结。
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){
}
})
}
...
如图:如果用户点击确定,就会正常保存图片到本地相册了。
如果用户点击取消,不授权呢?那还能怎么样,点击再弹出原来的弹窗重新授权呗。很遗憾,这里并不能像授权登录弹窗一样点了取消之后,再次点击授权按钮还会唤起那个弹窗。
解决方法:在 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)
}
})
}
})
}
点击取消按钮之后,会跳转到这里。打开设置里的“保存到相册”的开关即可。
原生微信小程序和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