微信小程序:在A小程序中生成B小程序的小程序码

搞了两天,法克啊

官网参考:
获取不限制的小程序码
https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/getUnlimitedQRCode.html

业务背景:
A小程序是商户端,B小程序是会员端;
商户需要在A小程序中生成B小程序的小程序码让会员扫码访问;

代码主要逻辑
使用了小程序官方的云函数和云储存

  1. 使用触发器定时获取B小程序的 Access Token,并存储到数据库。
  2. 从数据库中获取 B小程序的 Access Token,通过 HTTPS 请求方式获取小程序图片二进制,并存储到云存储。
  3. 判断云存储中是否有小程序码,没有则通过云函数获取。

云函数触发器配置
官网参考:
https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/functions/triggers.html
config.json 文件代码,每小时定时执行一次

{
    "permissions": {
        "openapi": [
        ]
    },
    "triggers": [
        {
            "name": "access_token_trigger",
            "type": "timer",
            "config": "0 0 * * * * *"
        }
    ]
}

云函数执行代码
index.js 文件代码

......
// 云函数入口函数
exports.main = async (event, context) => {  
    // 判断调用来源是触发器
    if(wxContext.SOURCE === 'wx_trigger') {
      // 刷新 access token
      return update_access_token(event, wxContext)
    }
}
......
// 刷新 access token
async function update_access_token(event, wxContext) {
  const now_date = new Date()
  try {    
    // 使用 HTTPS GET 请求方式获取会员端 Access Token
    let grant_type = 'client_credential'                      // 填写:'client_credential'
    let appid = '******************'                          // 会员端 AppID
    let secret = '********************************'           // 会员端 AppSecret(不能泄露给他人)
    let base_url = 'https://api.weixin.qq.com/cgi-bin/token'  // 如果在测试环境调该接口,则线上对应的access_token会失效(未验证)
    let token_url = base_url + '?grant_type=' + grant_type + '&appid=' + appid + '&secret=' + secret
    const token_response = await axios.get(token_url)
    let access_token = token_response.data.access_token
    let expires_in = token_response.data.expires_in
    // 存储会员端 Access Token
    return await db.collection(SR_SETTINGS_TABLE).where({
      _id: 'PK000001',                                        // 该表只有一条主键固定的记录
    }).update({
      data: {
        sr_customer_access_token: _.push({
          each: [{
            at: access_token,
            ei: expires_in,
            ud: now_date,
            ut: now_date.getTime()
          }],
          position: 0,
          slice: 72
        })
      }
    })
  } catch (e) {
    console.error(e)
  }
}

从数据库中获取 Access Token,然后调用接口获取小程序码图片二进制,并上传到云存储中

// 生成商户小程序码
async function generate_wxcode(event, wxContext) {
  try {
    // 从数据库中获取 Access Token  
    const result =  await db.collection(SR_SETTINGS_TABLE).where({
      _id: 'PK000001',
    })
    .field({
      _id: true,
      sr_customer_access_token: true,
    })
    .limit(1)
    .get()
    if(result.errMsg != 'collection.get:ok' || result.data.length==0) {
      return result
    }
    let access_token = result.data[0].sr_customer_access_token[0].at
    // 获取不限制的小程序码
    let wxacode_url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' + access_token
    const wxacode_response = await axios.post(wxacode_url,  // HTTPS POST 请求方式
      {
        path: 'pages/main/main',                            // 注意不是 page,而是 path
        scene: 'merchant_id=' + event.data.merchant_id,     // scene 最大32个可见字符
        check_path: false,                                  // 参数名是 check_path ,不是 check_page 。
        env_version: 'develop',                             // 正式版 "release",体验版 "trial",开发版 "develop"
        width: 320
      }, 
      {
        responseType: 'arraybuffer'
      }
    )    
    // 云存储小程序码    
    let cloudUrlMainDirectory = event.data.cloudUrlMainDirectory
    let cloudPath = cloudUrlMainDirectory +'/' + event.data.merchant_id + '/wxacode/' + 'wxacode.jpg'
    const uploadResult = await cloud.uploadFile({
      cloudPath: cloudPath,  
      fileContent: wxacode_response.data,
    })
    // 返回云存储文件ID
    return {
      data: { wxacodeCloudPath: uploadResult.fileID },
      errMsg: 'collection.get:ok',
    }
  } catch (e) {
    console.error(e)
    return e
  }
}

小程序码Cloud ID固定,前端可以判断是否存在

        // 尝试从云存储获取小程序码
        let fileID = this.data.cloudUrlBase+'/'+this.data.cloudUrlMainDirectory+'/'+this.data.merchant_info._id+'/wxacode/wxacode.jpg'
        console.log(fileID)
        wx.cloud.downloadFile({
            fileID: fileID,
            success (res) {
                    console.log('从云存储获取小程序码成功')
                    that.setData({ wxacodeCloudPath: res.tempFilePath })
            },
            fail(res) {
                // 获取失败则生成小程序码
                console.log('从云存储获取小程序码失败')
                let merchant_id = that.data.merchant_info._id
                if(merchant_id) {
                    that.callGenerateWxCode(merchant_id)
                }
            }
        })
    // 生成商户小程序码
    async callGenerateWxCode(merchant_id) {
        var that = this
        await app.call({ 
            type: 'generate_wxcode',
            data: { 
                merchant_id: merchant_id,
                cloudUrlMainDirectory: that.data.cloudUrlMainDirectory
            },
            tips: '获取中'
        }).then((res) => {
            that.parseGenerateWxCode(res)
        })
    },

    // 解析云函数返回结果
    parseGenerateWxCode(res) {
        try {
            // 获取云存储的商户小程序码
            let wxacodeCloudPath = res.data.wxacodeCloudPath
            this.setData({ wxacodeCloudPath: wxacodeCloudPath })
        } catch (error) {
            console.error(error)
            let title = '提示'
            let content = '生成商户小程序码发生异常'
            this.popupModalMessage(title, content)
        }
    },
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容