微信小程序:在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)
        }
    },
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容