本文以打卡小程序为例,记录开发过程及相关注意事项。
正式介绍开发之前先阅读下“小程序内用户帐号登录规范调整和优化建议”
地址:小程序内用户帐号登录规范调整和优化建议主要目的就是了解在设计小程序时的一些反面案例。本人小程序设计之初,用户登录授权后才可以查看使用所有功能,然而到最后审核不通过,因为官方要求是在没授权时,就要用户大概了解小程序的功能(解决办法:用户进入小程序可以查看功能,要使用时候再让他授权),只是举个列子,开发之前多了解他们的审核机制,多了解不至于后期要改来改去。
一.摘要
1.注册小程序,填写小程序详细信息,企业信息以及一些开发信息等 。 微信公众平台微信公众平台,这一步就不多说了
2.下载微信开发工具,登录微信开发工具创建项目时,微信appid可在步骤一中获取。
3.正式开发项目(包括代码编写、调试、测试等环节)
4.项目代码编写完成,上传审核、发布等过程。
二.项目基本功能
本项目主要记录打卡数据,统计个人打卡次数,统计所有打卡次数,点赞功能及上传下载文件(ppt、word、pdf等支持在线或下载打开)等功能
三.关键功能实现
1.微信授权获取唯一openid
openId是用户在当前公众号下的唯一标识(‘身份证’),就是说通过这个openId,就能区分在这个公众号下具体是哪个用户。
那么如何获取呢?
登录微信公众号查看开发设置,获取AppID(小程序ID)、Appsecret(小程序密钥),此作为后台接口参数,获取openid
首先看下app.js文件,通过请求服务器获取openid
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId(获取唯一标识)
if (res.code) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: authorize => {
// 可以将 authorize 发送给后台解码出 unionId
this.globalData.userInfo = authorize.userInfo;
JSON.stringify(authorize)
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(authorize)
}
wx.request({
url: 'xxxxxxxxxxxxxxxxxx/getOpenId',//请求后台获取openID路径
data: {
code: res.code,
encryptedData: authorize.encryptedData,
iv: authorize.iv
},
method: "Get",
header: {
'content-type': 'application/x-www-form-urlencoded',
},
success: function (data) {
//console.log("登录返回的数据:" + data);
that.globalData.openId = data.data.userInfo.openId;
that.globalData.userInfo = data.data.userInfo; //将openid存储到全局
wx.redirectTo({
url: '../button/button', //成功获取后跳转页面
})
},
fail: function (error) {
console.log(error);
}
})
}
})
}
},
})
服务器端:根据code、encryptedData、iv三个参数,即小程序端传递过来的参数,通过请求腾讯指定接口即可获取openid,可以将openid添加缓存,方便调用。自己封装一下请求的sendGet()方法
@ResponseBody
@RequestMapping(value = "/getOpenId", method = RequestMethod.GET)
public Map getOpenIdServlet(String code, String encryptedData, String iv) {
Map map = new HashMap();
// 登录凭证不能为空
if (code == null || code.length() == 0) {
map.put("status", 0);
map.put("msg", "code 不能为空");
return map;
}
String wxspAppid = "xxxxxxxx";// 可在微信公众平台获取
String wxspSecret = "xxxxxxxx";// 可在微信公众平台获取
String grant_type = "authorization_code";// 授权
// 请求参数
String params = "appid=" + wxspAppid + "&secret=" + wxspSecret + "&js_code=" + code + "&grant_type="
+ grant_type;
// 发送请求
String sr = Request.sendGet("https://api.weixin.qq.com/sns/jscode2session", params);
// 解析相应内容(转换成json对象)
JSONObject json = JSONObject.fromObject(sr);
// 获取会话密钥(session_key)
String session_key = json.get("session_key").toString();
// 用户的唯一标识(openid)
String openid = (String) json.get("openid");
// 对encryptedData加密数据进行AES解密
try {
String result = AesCbcUtil.decrypt(encryptedData, session_key, iv, "UTF-8");
if (null != result && result.length() > 0) {
map.put("status", 1);
map.put("msg", "解密成功");
JSONObject userInfoJSON = JSONObject.fromObject(result);
Map userInfo = new HashMap();
userInfo.put("openId", userInfoJSON.get("openId"));
userInfo.put("nickName", userInfoJSON.get("nickName"));
userInfo.put("gender", userInfoJSON.get("gender"));
userInfo.put("city", userInfoJSON.get("city"));
userInfo.put("province", userInfoJSON.get("province"));
userInfo.put("country", userInfoJSON.get("country"));
userInfo.put("avatarUrl", userInfoJSON.get("avatarUrl"));
userInfo.put("unionId", userInfoJSON.get("unionId"));
map.put("userInfo", userInfo);
return map;
}
} catch (Exception e) {
e.printStackTrace();
}
map.put("status", 0);
map.put("msg", "解密失败");
return map;
}
2.在线打卡,批量上传图片
在线打卡难点就在批量上传图片这里,其他只是读取数据传递到后台保存即可。微信小程序官方并未提供批量上传图片接口,所以本人的做法是循环上传图片
//选择图片时,将图片存储在一个数组中,循环这个数组上传
for (var i = 0; i < length; i++) {
wx.uploadFile({
url: 'xxxxxxxxxxxx',
filePath: tempFilePaths[i],
name: 'file',
formData: {
'w': "800",
'h': "400"
},
success: function (data) {
console.log("批量上传成功");
//将同一批图片路径保存到变量中
that.setData({
samebatchImg: that.data.samebatchImg.concat(data.data),
})
},
complete: function (data) {
}
})
}
3.点赞功能
点赞的难点在于如何知道当前的记录自己已经点过赞。
已点赞状态:再次点击,取消点赞,数据库点赞数量-1;未点赞状态:再次点击,点赞,数据库点赞数量+1;
在微信小程序代码中,起初设置了一个flag,点击变为true;但是存在一个问题,点赞其中一条记录,其他都无法再点击。后面改成点赞的记录的id缓存到一个数组中,下次点赞判断该条记录ID是否在数组中,存在则取消点赞,不存在则点赞成功。
favorclick: function (e) {// 点赞
var that = this;
var comment_id = e.currentTarget.dataset.id;
var openId = app.globalData.openId;
var numbers = app.globalData.numbers;
var numlength = numbers.length;
var index=numbers.indexOf(comment_id); //结果为-1说明不存在,可点赞
if(numlength==0 || index==-1){//存在即取消点赞
wx.request({
url: 'xxxxxxxx',//点赞接口
data: {
id: comment_id,
openId:openId,
},
headers: {
'Content-Type': 'application/json'
},
success: function (res) {
console.log(res.errMsg)
if (res.errMsg == "request:ok") {
console.log("恭喜你,已点赞");
that.setData({
currentId:comment_id,
recordlist: res.data,
})
app.globalData.numbers = app.globalData.numbers.concat(comment_id);
} else {
console.log("点赞失败");
}
}
})
} else{//不存在
wx.request({
url: 'xxxxxxxxx',//取消点赞
data: {
id: comment_id,
openId:openId,
},
headers: {
'Content-Type': 'application/json'
},
success: function (res) {
console.log(res.errMsg)
if (res.errMsg == "request:ok") {
console.log("恭喜你,已取消点赞");
that.setData({
currentId:comment_id,
recordlist: res.data,
})
app.globalData.numbers = app.globalData.numbers.splice(comment_id, 1);
} else {
console.log("取消点赞失败");
}
}
})
}
},
后台的代码就不放了,只是根据当前记录ID变更记录点赞状态、点赞数量。另外小程序页面,根据点赞状态的不同设置不同的图片显示是否点赞即可。
4.文件上传,在线打开文件(android),ios需下载打开
文件上传涉及到的问题点:1.批量或单个上传;2.文件过期处理;3.文件格式。下面看下代码
data: {
filename:"",
filelist:[],
fileType:["doc","docx","pdf","ppt","pptx"],//自己在data里定义的数组
},
choosefile:function(){
var that = this;
var filename = that.filename;
wx.chooseMessageFile({
count: 1, //上传文件的数量
type: 'file',
success (res) {
// tempFilePath可以作为img标签的src属性显示图片
const tempFilePaths = res.tempFiles;
if(tempFilePaths.length<=0){
wx.showModal({
title: '提示',
content: '文件过期或已被清理',
success: function(res) {
if (res.confirm) {
console.log('用户点击确定')
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
return;
}
var length = res.tempFiles[0].name.length;
var index = tempFilePaths[0].name.lastIndexOf("\.");
var type = tempFilePaths[0].name.substring(index+1,length);
if(that.data.fileType.indexOf(type)>=0){//文件格式限制,判断上传的文件在不在上面的格式中
that.setData({
filelist: tempFilePaths,
})
}else{
wx.showToast({
title: '不支持该格式',
})
return;
}
}
})
},
这样获取到文件存储在filelist中,目前只是选择好文件还未上传,通过wx.uploadFile({ })上传,但是wx.uploadFile跟上传图片一样,只支持一个文件的上传。所以在选择文件时,设置只可选择一个文件最好。如果想选择多个文件在wx.uploadFile中就需要循环上传后台,处理很多麻烦。
说明:到这样打卡小程序的主要功能难点就介绍完了。最后需将代码上传审核,等待微信官方审核。另外补充一点,对于涉及到上传图片、文件、视频类的功能,最好加上图片、文件等内容法规检验(微信官方有提供接口),检验是否包含违规、涉黄等信息,防止到最后审核不通过。