小程序码生成海报的保存到相册

3,893 阅读1分钟

一、生成小程序码

wxacode.getUnlimited

获取小程序码,适用于需要的码数量极多的业务场景。通过该接口生成的小程序码,永久有效,数量暂无限制。

api链接

注意:该接口在服务端调用

(1) 前端通过该接口调用拿到的数据是base64格式我们需要把base64格式的小程序码放到临时路径里面

// 生成小程序码
/**
*@params page-当前页面的url
*scene--当前页面的参数
*mallId--指定的其他参数
*也可以添加其他必要或额外的参数
*/
async gtUnlimited(curObj) {
    let params = {
      page: curObj.url,
      scene: curObj.options,
      mallId: wepy.$instance.globalData.mallId,
    };
    let res = await getUnlimited(params);
    innerRequest(res, res=>{
      if (res.resultCode == 200) {
        setTimeout(function () {
          wx.hideLoading()
        }, 500);
        let base64Path = res.resultInfo; // base64格式
        // 放入临时路径里面
        this.getTemporaryPath(base64Path)
        this.$apply();
      }
    })
  }

(2)放入临时路径

// 放入临时路径
  getTemporaryPath(path) {
    const fsm = wx.getFileSystemManager(); // 文件管理器
    const userDataPath = wx.env.USER_DATA_PATH;
    let number = Math.random();
    let _this = this;
    // 写文件
    fsm.writeFile({
      filePath: userDataPath + '/pic' + number + '.png', // 要写入的文件路径
      data: path,                                        // 要写入的文本或二进制数据,即base64格式的小程序码
      encoding: 'base64',                                // 指定写入文件的字符编码
      success: res => {
        _this.isCanDraw = true;
        _this.temporaryPath = userDataPath + '/pic' + number + '.png'; // 保存临时路径到变量里面
        _this.$apply();
      }, fail: err => {
        wx.hideLoading();
        wx.showToast({
          title: '正在清理缓存,请稍等...',
          icon: 'none',
        })
        console.log(err)
        this.removeTemPathData(fsm, userDataPath);
      }
    })
  }

(3)放入临时路径里面有内存的限制,小程序里面限制是10M所以还需要清理缓存

removeTemPathData(fsm, userDataPath) {
    fsm.readdir({
      dirPath: userDataPath, /// 获取文件列表,即读取的临时目录路径
      success(res) {
        console.log(res)
        res.files.forEach((val) => { // 遍历文件列表里的数据
          console.log(val)
          fsm.unlink({               // 删除文件
            filePath: userDataPath + '/' + val
          });
        })
      }
    })
  }

以上是针对生成小程序码,微信官方的api-- wxacode.getUnlimited --有参数的长度限制,数量无限制,所以可以采用以下方法

  1. 小程序端把业务所需的参数通过接口 A (生成小程序码的接口)传给小程序后端,小程序后端生成一个小于等于 32 位的 ID 来获取上报的参数,然后把这个 ID 填入生成小程序码接口的 scene 参数中。

  2. 小程序后端新增一个接口 B 用于小程序端通过解析小程序码获取的 scene 参数获取原来小程序端上报的参数。

二、扫码进入小程序

(4)扫小程序码获取生成小程序码的参数进入小程序指定的页面

async getMiniById(scene) {
    let params = {
      codeId: scene
    };
    let res = await miniCodeGetById(params);
    innerRequest(res, res=>{
      if (res.resultCode == 200){
        let sceneObj = res.resultInfo.scene;
        let params = JSON.parse(sceneObj);
        wepy.$instance.globalData.mallId = res.resultInfo.mallId;
        this.isShare = params.isShare;
        this.initData();
        this.getMiniCodeInsert(scene);
        this.$apply();
      }
    })
  }

(5)页面交互

<button class="intro" 
    open-type="getUserInfo" 
    bindgetuserinfo="getUserInfo"
    @tap="createShareImage" 
    wx:if='{{showShareBtn}}'
>
点我生成分享图
</button>
<!--分享图的模板-->
<shareImg wx:if="{{isCanDraw}}" :temporaryPath.sync='temporaryPath' @tap="reInitData" />

(6)canvas合成图片

在shareImg 组件里面做合成图片并保存的操作,这里会用到painter插件来绘制 大家可以点击下面链接学习

painter一款轻量级的小程序海报生成组件

painter合成图片的时候,需要获取下载背景图,用户头像,这些是需要在微信后台配置uplaodFile域名,否则最终在手机上查看是空白的

<view>
    <view class="share-wrap" catchtouchmove="preventDefault">
      <view class="share-back"></view>
      <view class="share-container">
        <view class="close" bindtap="handleClose" data-ptpid="ebe9-1656-ad6a-462e"></view>
        <image mode="widthFix" src="{{sharePath}}" class="share-image" />
        <!-- <view style='background:url(data:image/png;base64,{{sharePath}});background-size:100% 100%; width:300rpx; height:300rpx; margin:20rpx auto;'></view> -->
        <view class="share-tips">保存图片,叫伙伴们来参与吧</view>
        <view class="save-btn" bindtap="handlePhotoSaved" data-ptpid="4095-16fd-bc97-4868"></view>
      </view>
    </view>
    <view class="canvasBox">
      <canvas canvas-id="shareCanvas" style="width:375px;height:300px"></canvas>
    </view>
    <painter style="position: absolute; top: -9999rpx;" wx:if='{{palette}}' :palette.sync="palette" @tap="onImgOK" />
  </view>

(7)保存图片到系统相册

savePhoto(path) {
      wx.saveImageToPhotosAlbum({
        filePath: path,          // 图片文件路径,可以是临时文件路径或永久文件路径,不支持网络图片路径
        success: (res) => {
          wx.showToast({
            title: '保存成功',
            icon: 'none'
          })
          setTimeout(() => {
            // this.isCanDraw = false;
          }, 300)
        },
        fail: (res) => {
          wx.getSetting({
            success: res => {
              let authSetting = res.authSetting
              if (!authSetting['scope.writePhotosAlbum']) {
                this.isModal = true;
              }
            }
          })
          setTimeout(() => {
            wx.hideLoading()
            // this.isCanDraw = false;
          }, 300)
        }
      })
      this.$apply();
    }

最终效果

image.png 这块功能后期会发到github上面,大家可以来光顾一下,有问题可以随时提出,我会尽快解决的。希望和大家一起学习。