前言
上周接了一个小项目赚点外快,原以为很简单结果被卡在一个小坑爬了好半天
它是一个供电力局使用的报修小程序,需要特定用户在第一次使用时进行激活操作,通俗的说就是当某用户打开时,判断此用户是否激活过,若未激活则进入激活页面,若已经激活则直接进入首页面。
逻辑上很简单,但是在实现上碰到坑了。
上图为已激活用户或不需要激活的用户打开小程序后进入的第一个页面,下图为未激活用户打开小程序后进入的第一个页面。
思考过程
"pages": [ "pages/index/index", "pages/active/active", "pages/index/add", "pages/my/my", "pages/mylist/mylist", "pages/home/home", "pages/rating/rating", "pages/login/mylogin", "pages/login/login", "pages/detail/detail", "pages/mylist/list", "pages/mylist/mydetail" ],
而在app.json中必须引入全部的页面,且第一个引入的页面为首页面。
但是判断逻辑必须要在用户一打开小程序后就进行,但事实是必须先打开index页面(即上图),所以按照微信小程序的生命周期,我首先想到的办法是将判断逻辑写在index页的onload函数中。
在加载过程中进行判断,从而跳转。
var currentUser = Bmob.User.current();
var currentUserId = currentUser.id;
var User = Bmob.Object.extend("_User");
var queryUser = new Bmob.Query(User);
queryUser.get(currentUserId, {
success: function (result) {
console.log(result)
var status = result.attributes.status;
var usertype = result.attributes.usertype;
if (status==null&& usertype == 1) {
wx.navigateTo({
url: '/pages/active/active?lineid=' + lineid
})
}
},
error: function (object, error) {
}
});
以上代码就是我写入onload中的判断逻辑,先获取当前用户的id,从而进入数据库查询,获取此用户的status状态和userType类型,只有status为false且userType为1时,才进行跳转激活。
但是实际在测试时发现一个始料未及被忽视的问题。
wx.login({
success: function (res) {
user.loginWithWeapp(res.code).then(function (user) {
var openid = user.get("authData").weapp.openid;
console.log(user, 'user', user.id, res);
if (user.get("nickName")) {
// 第二次访问
console.log(user.get("nickName"), 'res.get("nickName")');
var currentUser = Bmob.User.current();
var currentUserId = currentUser.id;
var User = Bmob.Object.extend("_User");
var queryUser = new Bmob.Query(User);
queryUser.get(currentUserId, {
success: function (result) {
var status = result.attributes.status;
var usertype = result.attributes.usertype;
console.log(status);
},
error: function (object, error) {
console.log(result);
}
});
} else {
wx.setStorageSync('status', false),
wx.setStorageSync('usertype', 1),
//保存用户其他信息
wx.getUserInfo({
success: function (result) {
var userInfo = result.userInfo;
var nickName = userInfo.nickName;
var avatarUrl = userInfo.avatarUrl;
var u = Bmob.Object.extend("_User");
var query = new Bmob.Query(u);
// 这个 id 是要修改条目的 id,你在生成这个存储并成功时可以获取到,请看前面的文档
query.get(user.id, {
success: function (result) {
// 自动绑定之前的账号
result.set('nickName', nickName);
result.set("userPic", avatarUrl);
result.set("openid", openid);
result.set("isbind", 0);
result.set("status", false);
result.set("usertype", 1);
result.save();
}
});
wx.setStorageSync('openid', openid)
wx.setStorageSync('username', user.get("username"))
wx.setStorageSync('userpic', avatarUrl)
wx.setStorageSync('nickname', nickName)
}
});
}
}, function (err) {
console.log(err, 'errr');
});
}
});
因为我在app.js中进行了微信登录,即获取到了用户授权信息后,将用户的微信名、头像以及初始化的userType和status写入数据库中。以上为此逻辑的代码。
故在用户授权前,数据库中此用户的userType和status是空的,而这时候按照微信小程序的生命周期,第一个首页面已经加载完毕并显示,即onload在判断时,此用户的userType和status状态为空,则认为此用户无需激活。而用户点完授权后,即使存入正确的userType和status已经于事无补。
用户第一次打开小程序,可见此时页面已经加载完毕,但是用户还未授权微信登录
而这时候的用户数据均为空
用户点击确定授权后才会写入数据,但这时候页面的onload早已执行完毕
只能再寻找其它的解决办法。
解决过程
总结了一下刚才失败的原因,是因为在执行onload时,逻辑判断语句并没有取到正确的参数。所以要想办法在onload函数执行前,就传入正确的参数。
于是尝试另外一种方法,使用本地缓存进行传值判断。
即用户在一打开小程序加载app.js时,先在本地缓存中将用户的userType和status值存入,然后在index页面的onLoad函数中使用判断,这样就不存在微信登录授权的时间差。
于是需要在用户第一次使用时进行初始化参数并存入缓存以供onload函数判断,而用户如果不是第一次使用,则直接从数据库中查找到此用户并将此用户的userType和status取出存入本地缓存,供onLoad函数判断。
于是首先在app.js中加入以下两行代码进行新用户初始化缓存存入
wx.setStorageSync('status', false),
wx.setStorageSync('usertype', 1),
加入以下两行代码进行老用户获取参数进行缓存存入
queryUser.get(currentUserId, {
success: function (result) {
var status = result.attributes.status;
var usertype = result.attributes.usertype;
wx.setStorageSync('status', status)
wx.setStorageSync('usertype', usertype)
console.log(status);
},
error: function (object, error) {
console.log(result);
}
});
然后在index的onload函数中写入以下逻辑,进行判断。
var status = wx.getStorageSync('status')
var usertype = wx.getStorageSync('usertype')
// console.log(usertype)
if (!status &&!usertype) {
wx.navigateTo({
url: '/pages/active/active?lineid=' + lineid
})
} else if (status ==false && usertype == 1) {
wx.navigateTo({
url: '/pages/active/active?lineid=' + lineid
})
}
这里要注意,因为考虑到了缓存溢出的情况,多加了判断status和userType非空的操作。
于是至此这个坑被完美的填了,从入坑到找坑到爬坑耗时两小时。
总结
还是像上一篇文章说的,这是一个填坑的过程,第一个吃螃蟹的人不光要被夹,还得告诉后人怎么撬开螃蟹壳。
我栽树了大家乘凉吧~