微信小程序生成页面太阳码及分享海报
@
效果图
实现方式
后端node获取小程序token及太阳码参考文章 点我
生成海报使用插件 painter 地址点我
小程序生成太阳码文档 点我
踩坑
- 千万不要直接在小程序上调用wx http接口,真机无法使用https://api.weixin.qq.com/wxa/getwxacodeunlimit 这个接口,需要在后台写
- 该接口生成arraybuffer 原来想的是通过wx.arrayBufferToBase64()接口转为base64图片使用,但是最好不要。原因有两个: 1. wx.arrayBufferToBase64后续版本不会维护 2. 转canvas海报不支持base64格式
- 海报如果需求和我一样是分享的时候显示 进入页面的时候不显示,那就会想到使用wx:if或者hidden去隐藏海报父级view。但是这样painter在绘制canvas的时候会报错 获取不到该canvas的宽高,所以最好用层级或者直接定位-9999给隐藏,显示海报的时候通过z-index:0或者 left: 0给调整回来
- painter组件里面带有下载图片功能,如果真机上设置海报背景或太阳码无法显示 需要到小程序后台配置白名单
代码
逻辑步骤如下: 进入某小程序页面 先向后端请求该页面的太阳码,用于后续生成海报
点击分享按钮 渲染painter组件生成海报 点击保存按钮将海报下载到本地相册,后续扫描小程序太阳码进入页面起到分享作用
小程序:
wx.request({
url: request_url.baseUrl+'api/page_qrcode', //请求后端api
data:{
scene: str, //页面所需参数
page: "pages/homeitem/homeitem" //这里按照需求设置值和参数
},
success(res) {
console.log(res.data.status)
if (res.data.status) {
that.setData({
qrcode: request_url.baseUrl+res.data.imgurl+'?'+new Date().valueOf() //把生成太阳码存进data,后面painter绘制要用 问号后面那串是为了防止图片缓存
})
}
}
})
xxx.wxml文件 需要先引入painter组件 去上面地址里面下载到本地components
<view class='pyq-cover' catchtap="closeQrCodeInfo" style="left:{{showQrcode?'0': '-99999px'}}; overflow: {{showQrcode?'unset': 'hidden'}};">
<painter
widthPixels="1000"
customStyle='margin: 0 auto;'
dancePalette="{{template}}"
palette="{{paintPallette}}"
bind:imgOK="onImgOK"
/>
<button bindtap="saveImage" class="save-btn-type">保存</button>
</view>
xxx.js文件
getQrCodeInfo() { // 这个方法我调用的时机是点击分享按钮需要显示海报的时候调用的
var that = this
var user = wx.getStorageSync('userInfo')
if(user == '') {
wx.showToast({
title: '请先登录',
icon:'none'
})
return
}
if (that.data.qrcode=='') {
wx.showToast({
title: '页面二维码生成中,请稍后再试',
icon:'none'
})
that.setTemplatInfo()
return
}
var temp = {
width: '650rpx',
height: '820rpx',
background: 'https://qiniu.cdn.zhiliaotang.cn/166312181913155.png',
borderRadius: '10rpx',
views: [
{
id: 'company-info',
type: 'text',
text: that.data.datalist.companyname,
css: [{
width: '100%',
height: 'auto',
top: `121rpx`,
fontWeight: 'bold',
fontSize: '42rpx',
maxLines: 1,
textAlign:'center'
}],
},
{
id: 'company-info-sub',
type: 'text',
text: that.data.datalist.company_collect.intro,
css: [{
width: '70%',
height:'auto',
top: `192rpx`,
left: '106rpx',
fontWeight: 'normal',
fontSize: '22rpx',
color:'#393939',
maxLines: 1,
textAlign:'center'
}],
},
{
id: 'employ-info',
type: 'text',
text: that.data.datalist.position,
css: [{
width: '100%',
height:'auto',
top: `300rpx`,
fontWeight: 'bold',
fontSize: '40rpx',
textAlign: 'center',
}],
},
{
id: 'line',
type: 'image',
url: 'http://qiniu.cdn.zhiliaotang.cn/166312434065899.png',
css: [{
height:'1rpx',
width:'70%',
top: '266rpx',
left:'106rpx'
}],
},
{
id: 'rect-1',
type: 'rect',
css: {
width: '18rpx',
left: '154rpx',
top: '400rpx',
height: '18rpx',
borderRadius:'9rpx',
color:'#F3D041'
},
},
{
id: 'rect-2',
type: 'rect',
css: {
width: '18rpx',
left: '316rpx',
top: '400rpx',
height: '18rpx',
borderRadius:'9rpx',
color:'#F3D041'
},
},
{
id: 'rect-3',
type: 'rect',
css: {
width: '18rpx',
right: '154rpx',
top: '400rpx',
height: '18rpx',
borderRadius:'9rpx',
color:'#F3D041'
},
},
{
id: 'other-1',
type: 'text',
text: that.data.datalist.experience==''?'不限':that.data.datalist.experience,
css: [{
height:'auto',
top: `390rpx`,
left:'182rpx',
color: '#000',
fontWeight: 'normal',
fontSize: '26rpx',
}],
},
{
id: 'other-2',
type: 'text',
text: that.data.datalist.education==''?'不限': that.data.datalist.education,
css: [{
height:'auto',
top: `390rpx`,
left:'350rpx',
color: '#000',
fontWeight: 'normal',
fontSize: '26rpx',
}],
},
{
id: 'other-3',
type: 'text',
text: that.data.datalist.num==''?'不限':that.data.datalist.num+'人',
css: [{
height:'auto',
top: `390rpx`,
right:'100rpx',
color: '#000',
fontWeight: 'normal',
fontSize: '26rpx',
}],
},
{
type: 'image',
url: that.data.qrcode,
css: [{
top: '460rpx',
left: '34%',
width: '200rpx',
height: '200rpx',
}],
},
{
id: 'subText-sub',
type: 'text',
text: '长按识别,查看小程序',
css: [{
width: '100%',
height:'auto',
bottom: `106rpx`,
color: '#000',
fontWeight: 'normal',
fontSize: '24rpx',
textAlign: 'center',
}],
}
],
}
that.setData({
template: temp, //temp是生成的海报样式 可以去painter里面看具体使用方式 主要的类型有rect image和text
showQrcode: true
})
},
生成成功后回调然后保存到本地
onImgOK(e) {
this.imagePath = e.detail.path;
this.setData({
image: this.imagePath
})
if (this.isSave) {
this.saveImage(this.imagePath);
}
},
saveImage() {
var that = this
if (!this.isSave) {
this.isSave = true;
this.setData({
paintPallette: this.data.template,
});
} else if (this.imagePath) {
this.isSave = false;
console.log(this.imagePath)
wx.saveImageToPhotosAlbum({
filePath: that.imagePath,
success() {
wx.showToast({
title: '成功保存到本地相册,快去发圈吧',
})
that.setData({
showQrcode:false
})
}
});
}
},
node端代码主要是参考上面链接的大神
// 生成小程序页面二维码
router.get("/api/page_qrcode", (req, res) => {
let { page,scene } = req.query;
//请求token的时候需要替换你的appid和secret
request('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid= blablabla&secret=blablabla',function(error,response,body){
if(!error && response.statusCode == 200){ //请求成功处理逻辑
var data = JSON.parse(body);
access_token = data.access_token;
console.log(access_token,'access_token')
//console.log(data.access_token);
getwxcode(access_token,function(){
res.json({status:true,imgurl:'images/qcode.png'});// 会在本地生成太阳码 直接用接口地址+images/qcode.png就能访问
},page,scene); //获取二维码
}
})
});
function getwxcode(access_token,cb,page,scene){ //通过access_token获取小程序二维码
var postData = {
page: page,//二维码默认打开小程序页面
scene: scene,//打开页面时携带的参数
}
postData = JSON.stringify(postData);
var myP = new Promise(function (resolve, reject) { //由于request pipe是异步下载图片的,需要同步的话需添加一个promise
var stream = request({
method: 'POST',
url: 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' + access_token,
body: postData
}, function(error,response,body) {
// console.log(error,response,JSON.parse(body))
}).pipe(fs.createWriteStream('./public/images/qcode.png'));
stream.on('finish', function () {
cb&&cb();
});
});
}
转载于 https://blog.csdn.net/weixin_44835957/article/details/126876732 (本人自己写的 不允许除本人外的人转载)