这是作者第一次做小程序也是第一次用nodejs,以下有写的不好的地方请前辈们指出,谢谢。
一、 先说一下小程序码的作用,就是用户可以通过微信扫描小程序码进入小程序的特定页面,比如某件商品或者某个人的主页。小程序码生成时可以携带参数,我们可以在小程序码跳转的页面接收参数进行相应的操作。
二、简单说一下小程序码生成的大体过程,就是通过appid和appsecrect换取accesstoken然后再用accesstoken加上其他参数换取小程序码。对于如何用appid和appsecrect获取accesstoken我就不爱赘述了,网上有大把的资料可以借鉴。
三、接下来就分享小编的实现方式吧。
1、首先获取accesstoken。这段代码是对accesstoken进行检查更新的。因为小程序好多地方都用到了accesstoken而且每天获取次数有限,所以,我把获取的accesstoken保存到数据库,每次用到都会对accesstoken检查更新从而避免失效的情况。
g.js
var util = require('../getCode/libs/access_tokenManager')//从数据库中获取access_token
var Promise = require('bluebird');//导入这个模块来调用Promise,来实现数据继续往下传
var request = Promise.promisify(require('request'));
var prefix = 'https://api.weixin.qq.com/cgi-bin/';//因为这一部分API是固定的
var conf = require('../config.js')
var api = {
accessToken: prefix + 'token?grant_type=client_credential'
}
function checkToken(opts) {
var that = this;
this.appID = conf.appId;
this.appSecret = conf.appSecret;
this.getAccessToken = opts.getAccessToken;
this.saveAccessToken = opts.saveAccessToken;
this.data = '';
//按照上面我们讲的逻辑来实现getAccessToken
that.getAccessToken().then(function (data) {
try {
console.log('data=' + data);
data = (JSON.parse(data))[0];
console.log('datadatadatadatadata', data);
}
catch (e) {
console.log('netscape');
return that.updateAccessToken();
}
if (that.isValidAccessToken(data)) {
console.log('下传参数', data);
that.data = data
Promise.resolve(data);
}
else {
return that.updateAccessToken();
}
})
.then(function (data) {
data = data ? data : that.data
that.access_token = data.access_token;
that.expires_in = data.expires_in;
that.saveAccessToken(data);
})
}
//为这个对象添加我们需要的函数
checkToken.prototype.isValidAccessToken = function (data) {
if (!data || !data.access_token || !data.expires_in) {
return false;
}
var access_token = data.access_token;
var expires_in = data.expires_in;
console.log('token有效时间expires_in', expires_in);
var now = (new Date().getTime())
if (now < expires_in) {
console.log('token有效');
return true;
} else {
return false;
}
}
checkToken.prototype.updateAccessToken = function () {
var appID = this.appID;
var appSecret = this.appSecret;
var url = api.accessToken + '&appid=' + appID + '&secret=' + appSecret;
return new Promise(function (resolve, reject) {
request({ url: url, json: true }, function (error, response, body) {
if (!error && response.statusCode === 200) {
var data = body;
var now = (new Date().getTime());
var expires_in = now + (data.expires_in - 20) * 1000;
data.expires_in = expires_in;
resolve(data);
} else {
reject()
}
});
})
}
module.exports = function (opts){
var CheckToken= new checkToken(opts);
}
2、生成二维码,并将二维码保存到特定路径下。
'use strict'
var Koa = require('koa')//把koa给导进来
var path = require('path')//把path模块导入进来
var wechat = require('../getCode/wechat/g')//这个是微信获取access_token的代码逻辑
//var util = require('../getCode/libs/util')//这个辅助代码的实现
var util = require('../getCode/libs/access_tokenManager')//从数据库中获取access_token
var request = require('request');
var fs = require('fs');
var Promise = require('bluebird');
//这个是配置文件
var config = {
wechat: {
fileName:'',
getAccessToken: function () {
//通过这个来实现获取access_token
return util.readFileAsync(wechat_file);
},
saveAccessToken: function (data) {
// data = JSON.stringify(data)
//通过这个来保存access_token
return util.writeFileAsync(data)
},
//生成二维码
getQrcode: function (data,fileName) {
var postData = {
path: "pages/index/index",//二维码默认打开小程序页面
scene: fileName,//打开页面时携带的参数
width: 430,
auto_color: false
}
postData = JSON.stringify(postData);
request({
method: 'POST',
url: 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' + data.access_token,
body: postData
}).pipe(fs.createWriteStream('./images/' + fileName+'.png'));//将返回的数据流保存为图片
}
}
}
module.exports = async (ctx, next) => {
config.wechat.fileName = ctx.query.fileName;
wechat(config.wechat)
}