微信小程序生成页面太阳码及分享海报

@

效果图

![在这里插入图片描述](https://img-blog.csdnimg.cn/0430f6d2f9cb4ef88511db0867c4d168.png

实现方式

后端node获取小程序token及太阳码参考文章 点我
生成海报使用插件 painter 地址点我
小程序生成太阳码文档 点我

踩坑

  1. 千万不要直接在小程序上调用wx http接口,真机无法使用https://api.weixin.qq.com/wxa/getwxacodeunlimit 这个接口,需要在后台写
  2. 该接口生成arraybuffer 原来想的是通过wx.arrayBufferToBase64()接口转为base64图片使用,但是最好不要。原因有两个: 1. wx.arrayBufferToBase64后续版本不会维护 2. 转canvas海报不支持base64格式
  3. 海报如果需求和我一样是分享的时候显示 进入页面的时候不显示,那就会想到使用wx:if或者hidden去隐藏海报父级view。但是这样painter在绘制canvas的时候会报错 获取不到该canvas的宽高,所以最好用层级或者直接定位-9999给隐藏,显示海报的时候通过z-index:0或者 left: 0给调整回来
  4. 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 (本人自己写的 不允许除本人外的人转载)

posted @ 2022-09-26 11:38  今晚吃火锅耶  阅读(904)  评论(0编辑  收藏  举报