最近有一个生成很多小程序码的需求,生成的小程序码还要嵌入在指定的图片模板上,就去找轮子,没找到合适的轮子。。无奈之下就决定去撸一个。目前已经完成并发布npm。
Github: github.com/Jon-Millent…
需求
如下图
开始干活
生成带参数的小程序二维码
createWXAQRCode
获取小程序二维码
,适用于需要的码数量较少的业务场景。通过该接口生成的小程序码,永久有效,有数量限制。官方说明getWXACode
获取小程序码
,适用于需要的码数量较少的业务场景。通过该接口生成的小程序码,永久有效,有数量限制。官方说明getWXACodeUnlimit
获取小程序码
,适用于需要的码数量极多的业务场景。通过该接口生成的小程序码,永久有效,数量暂无限制。官方说明
这些接口都要通过 access_token
来换取。让我们造个类
let AngerWechat = require('anger-wechat') // 微信操作辅助库(自己写的)
class miniqrcode {
// 存放三种模式的接口
constructor(config) {
this.mode = {
'getWXACode': 'https://api.weixin.qq.com/wxa/getwxacode','getWXACodeUnlimit': 'https://api.weixin.qq.com/wxa/getwxacodeunlimit',0);">'createWXAQRCode': 'https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode',}
// 初始化微信辅助库
this.$wx = new AngerWechat({
appId: this.config.appId,// appId 必传
appSecret: this.config.appSecret,136);">// appSecret 必传
})
// 临时数据存放文件,用于存放access_token,因为access_token有2个小时的生存期,避免重复获取
this.databasePath = path.join(__dirname,0);">'../',0);">'database.json')
}
}
复制代码
实现核心方法
// 生成核心方法
async getWxQrcodeInfo(concatConfig){
// 获取已经存放的文件里的access_token,如果有的话并且有效的话就不用再掉接口
let innerDatabase = this.getDatabase()
// 如果本地的数据没有access_token 或者超过2个小时 就去请求获取
if(!innerDatabase.access_token || ((new Date().getTime() - innerDatabase.create_time) > 7200000) ) {
let accessInfo = await this.$wx.getGlobalAccesstoken()
// 获取access_token然后写入文件
// 具体代码省略
}
// 获取到access_token去请求接口
let qrcodeInfo = this.postMan(
this.getApiUrl(innerDatabase.access_token,concatConfig.mode),136);">// 根据mode来区调用接口
concatConfig.config // 用户传的参数
)
let returnData = {
}
if(qrcodeInfo.type.indexOf('image') !== -1) { //类型是图片的就是获取成功了
// 请求成功 保存图片
returnData = {
code: 200,image: qrcodeInfo.data,error: null
}
} else {
returnData = {
code: 500,error: JSON.stringify(qrcodeInfo.data.toString()),image: null
}
}
return returnData
}
复制代码
写好后让我们测试一下
let qrocode = new miniqrcode({
appId: 'xxx',appSecret: 'xxx'
});
let info = await qrocode.getWxQrcodeInfo({
mode: 'getWXACode',config: {
path: `pages/index/main?id=123456`
},})
fs.writeFileSync(`./output-juejin-test1.png`,info.image,0);">'utf8');
复制代码
效果:
如何测试参数?我在这个已经发布的小程序里面加了个彩蛋,就是长按 红色圈出区域两次
即可调出控制台看参数
将二维码合成到模板图片里面
这个操作依赖于 sharp
库
);
miniSharp {
constructor(templateUrl){
this.templateUrl = templateUrl
}
// 重置图片大小
async resizeQrcode(imageBuffer,config){
return Promise(resolve => {
sharp(imageBuffer).resize(config.width,config.width).toBuffer().then(function(outputBuffer) {
resolve(outputBuffer)
});
})
}
// 合并图片
async concatimage(buffer,0);">Promise(resolve => {
sharp(this.templateUrl)
.overlayWith(buffer,{
top: config.top,left: config.left
}).toBuffer().then(function(outputBuffer) {
resolve(outputBuffer)
});
})
}
// 主函数
async renderImage(qrcodeBuffer,config){
let resizeQrcodeBuffer = this.resizeQrcode(qrcodeBuffer,config)
let concatQrocdeBuffer = this.concatimage(resizeQrcodeBuffer,config)
return concatQrocdeBuffer
}
}
module.exports = miniSharp
复制代码
测试一下
,0);">'xxx'
});
let mySharp = new miniSharp('./template.png');
await qrocode.getWxQrcodeInfo({
mode: config: {
path: `pages/index/main?id=123456`
},})
let renderBuffer = await mySharp.renderImage(info.image,136);">// 二维码图片的 buffer 数组
{
width: // 重新设置二维码宽度
left: 362,136);">// x轴偏移
top: 53 // y轴偏移
})
fs.writeFileSync('utf8');
复制代码
批量处理
正常情况下,批量生成 100
张需要 62.556秒
,平均每张需要 0.62556秒
,1万张大概需要 1.73小时
。 批量示例代码
关于调试
使用微信开发者工具可以进行模拟参数调试
测试接口
这里我提供了一个测试接口,可以带参数生成线上的小程序码,用来调试
[get]
http://wx.toolos.cc
参数
-
mode
必传 [createWXAQRCode | getWXACode | getWXACodeUnlimit] 之一
注意
示例
http://wx.toolos.cc/?mode=createWXAQRCode&path=pages%2Findex%2Fmain
复制代码
关于参数模式
createWXAQRCode & getWXACode
这两种生成的参数,生成二维码数量有限,参数直接跟在path路径后面,例如:
,config: {
page: `pages/index/main?sgr=521314&i=loveyou`
},})
复制代码
getWXACodeUnlimit
这个可以生成无限个,但是只能携带有局限性的参数 scene
,在这里推荐一种解析方式 key:value-key:value
,0);">index/main`,scene: 'i:loveyou-sgr:521314'
},254);'>解析示例
onLoad (query) {
// scene 需要使用 decodeURIComponent 才能获取到生成二维码时传入的 scene
this.scene = decodeURIComponent(query.scene)
this.queryJson = JSON.stringify(query)
// 尝试解析 scene 格式: shop:1-id:2
try {
let oneArr = this.scene.split('-')
let twoJson = {}
for(let i=0; i<oneArr.length; i++) {
let target = oneArr[i].split(':')
twoJson[target[0]] = target[1]
}
this.twoJson = JSON.stringify(twoJson)
} catch(e) {
this.twoJson = e
}
},复制代码
在开发者工具中例如下面模拟
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。