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

搞了兩天,法克啊

官網(wǎng)參考:
獲取不限制的小程序碼
https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/getUnlimitedQRCode.html

業(yè)務(wù)背景:
A小程序是商戶端,B小程序是會員端;
商戶需要在A小程序中生成B小程序的小程序碼讓會員掃碼訪問;

代碼主要邏輯
使用了小程序官方的云函數(shù)和云儲存

  1. 使用觸發(fā)器定時獲取B小程序的 Access Token,并存儲到數(shù)據(jù)庫。
  2. 從數(shù)據(jù)庫中獲取 B小程序的 Access Token,通過 HTTPS 請求方式獲取小程序圖片二進制,并存儲到云存儲。
  3. 判斷云存儲中是否有小程序碼,沒有則通過云函數(shù)獲取。

云函數(shù)觸發(fā)器配置
官網(wǎng)參考:
https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/functions/triggers.html
config.json 文件代碼,每小時定時執(zhí)行一次

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

云函數(shù)執(zhí)行代碼
index.js 文件代碼

......
// 云函數(shù)入口函數(shù)
exports.main = async (event, context) => {  
    // 判斷調(diào)用來源是觸發(fā)器
    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'  // 如果在測試環(huán)境調(diào)該接口,則線上對應(yīng)的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)
  }
}

從數(shù)據(jù)庫中獲取 Access Token,然后調(diào)用接口獲取小程序碼圖片二進制,并上傳到云存儲中

// 生成商戶小程序碼
async function generate_wxcode(event, wxContext) {
  try {
    // 從數(shù)據(jù)庫中獲取 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,                                  // 參數(shù)名是 check_path ,不是 check_page 。
        env_version: 'develop',                             // 正式版 "release",體驗版 "trial",開發(fā)版 "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)
        })
    },

    // 解析云函數(shù)返回結(jié)果
    parseGenerateWxCode(res) {
        try {
            // 獲取云存儲的商戶小程序碼
            let wxacodeCloudPath = res.data.wxacodeCloudPath
            this.setData({ wxacodeCloudPath: wxacodeCloudPath })
        } catch (error) {
            console.error(error)
            let title = '提示'
            let content = '生成商戶小程序碼發(fā)生異常'
            this.popupModalMessage(title, content)
        }
    },
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容