欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

小程序云函數(shù)接口設(shè)計 - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設(shè)-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設(shè)/小程序開發(fā)/軟件開發(fā)

知識

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運(yùn)營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!

您當(dāng)前位置>首頁 » 新聞資訊 » 小程序相關(guān) >

小程序云函數(shù)接口設(shè)計

發(fā)表時間:2021-1-5

發(fā)布人:葵宇科技

瀏覽次數(shù):73

微信為小程序開發(fā)者提供了云函數(shù),作為替代后臺的一種serverless解決方案。微信云函數(shù)與微信小程序前端功能結(jié)合的很緊密,為開發(fā)者提供了相當(dāng)大的便利。但云函數(shù)在設(shè)計、開發(fā)、調(diào)試上與傳統(tǒng)的服務(wù)端開發(fā)有著許多不同。

我們的團(tuán)隊近期開發(fā)了一款小程序產(chǎn)品。為了更大程度的減少server的使用,業(yè)務(wù)后臺完全使用云函數(shù)提供服務(wù)(主要是我們的團(tuán)隊沒有專業(yè)后端-_-)。另外采用前端童鞋熟悉的eggjs+vue做了一套簡易的管理后臺,用來進(jìn)行審核和數(shù)據(jù)管理工作。

系統(tǒng)分為小程序端,云函數(shù)端,web端。數(shù)據(jù)庫使用云服務(wù)的數(shù)據(jù)庫。

一、云函數(shù)調(diào)用通用接口定義

1、云端

我們在云端封裝了一個通用的runFunc方法,所有的云函數(shù)都走這個方法然后再根據(jù)fname分別進(jìn)入對應(yīng)函數(shù)處理。

runFunc基本的入?yún)ⅲ?/p>

屬性含義
fname自定義云函數(shù)名
clientType小程序端/web端
version版本信息,用于必要時進(jìn)行更新干預(yù)控制
token用戶token
adminOpenIdweb端用戶的openid不能自動獲取,需要手動傳入

runFunc基本的處理流程,會順序進(jìn)行一系列判斷:

代碼:

//cloudfunctions/runFunc/index.js
async function main(event, context) {
  let {fname, version, token, clientType, adminOpenId, ...opt} = event
  let result, role
  const { OPENID } = cloud.getWXContext()
  //先校驗fname是否存在
  if(!fname){
    return {code: '0422', info:'參數(shù)錯誤'}
  }
  //getToken方法
  if(fname==='getToken'){
    return await getToken(cloud, db)
  }
  //小程序端,需要校驗版本
  if(clientType===0){
    if (semver.lt(version, LOWEST_VERSION)) {
      return {code: '0602', info: '當(dāng)前版本過低!'}
    }
    const authResult = authCheck(token)
    role = authResult.role
    //校驗token
    if(!token || authResult.unauthorized) {
      return {code: '0401', info: '用戶狀態(tài)失效', data: {role}}
    }
  } else {
    role = opt.role
  }
  switch(fname){
    case 'getList':
      return await getList()
    //...
    default: 
      return {code: '0404', info:'未找到對應(yīng)方法'}
  }
}
復(fù)制代碼

2、小程序端

在小程序端,我們也對應(yīng)封裝一個云函數(shù)調(diào)用方法,可以集中處理標(biāo)準(zhǔn)的云函數(shù)調(diào)用錯誤。

遺憾的是,官方文檔沒有給出標(biāo)準(zhǔn)的云函數(shù)返回值定義,通過調(diào)試,發(fā)現(xiàn)云函數(shù)調(diào)用通常會拋出errCode, errMsg, requestId, result這些值,通常errCode為空時執(zhí)行正常,但有些方法執(zhí)行失敗也不返回errCode(什么鬼……)在官方論壇上提問也沒有得到回復(fù),我們只能通過errCode || !/ok/.test(errMsg)來判斷是不是執(zhí)行失敗了。

//miniprogram/utils/api.js/callCloud
const app = getApp()

async function callCloud(fname, opt){
  try{
    const {errCode, errMsg, requestId, result} = await wx.cloud.callFunction({
      name: 'runFunc',
      data: {
        fname,
        clientType: 0,
        version: app.globalData.appVersion,
        token: app.globalData.token, 
        ...opt
      }
    })
    if(errCode || !/ok/.test(errMsg)){
      wx.showToast({
        title: '服務(wù)器錯誤',
        icon: 'none',
        duration: 2000
      })
      return {code: '0700', info: '服務(wù)器繁忙', subcode: errCode, subinfo: errMsg}
    }
    else {
      const {code, info, data} = result
      if(code === '0401'){
        wx.showToast({
          title: info,
          duration: 2000
        })
      }
      if(code === '0602'){
        // todo: 做強(qiáng)制升級代碼
        wx.showToast({
          title: info || '去強(qiáng)制升級',
          icon: 'none',
          duration: 2000
        })
      }
      if(code!=='0000'){
        wx.showToast({
          title: info || '錯誤',
          icon: 'none',
          duration: 2000
        })
      }
      return result
    }
  } catch(e){
    return {code: '0500', info: e.message || '服務(wù)器繁忙'}
  }
}

exports.callCloud = callCloud
復(fù)制代碼

在page的js里,調(diào)用云函數(shù):

//miniprogram/pages/demo/demo.js
const api = require('../../utils/api')
Page({
  data:{///...},
  onLoad: async function(){
  	const {code, info} = await api.callCloud('getList')
    //...
  }
})
復(fù)制代碼

3、web端-接口

在web服務(wù)端,我們提供一個通用的調(diào)用云函數(shù)的route

//router.js
router.post('/call/:funcname', jwt, controller.home.callCloudFunction)
復(fù)制代碼

在controller里我們發(fā)送如下的url請求:

POST https://api.weixin.qq.com/tcb/invokecloudfunction?access_token=ACCESS_TOKEN&env=ENV&name=FUNCTION_NAME
復(fù)制代碼
//home.controller
const url = util.format('https://api.weixin.qq.com/tcb/invokecloudfunction?access_token=%s&env=%s&name=%s', access_token, cloudEnv, functionName)
const { data: optData, ...restOpt } = opt
const result = await ctx.curl(url, {
  method: 'POST',
  contentType: 'json',
  dataType: 'json',
  data: {
    clientType: 1,
    adminOpenId: ctx.state.user && ctx.state.user.openId ? ctx.state.user.openId : '',
    role: ctx.state.user && ctx.state.user.role ? parseInt(ctx.state.user.role) : 0,
    ...optData
  },
  ...restOpt
})
const { errcode, errmsg, resp_data } = result.data
/*
errcode為空,返回JSON.parse(resp_data)
errcode不為空,返回對應(yīng)的errmsg
*/
復(fù)制代碼

4、web端-前端

對應(yīng)的,web前端的調(diào)用非常簡單:

const {code, info, data} = await axios('/call/runFunc', { data: {fname: functionName, options} })
復(fù)制代碼

這樣我們保證云函數(shù)的數(shù)據(jù)結(jié)構(gòu),錯誤碼在三端都是統(tǒng)一的。

二、關(guān)于用戶狀態(tài)

常規(guī)web項目或者app項目,都是用token來做用戶登錄狀態(tài)保持。 在小程序里使用云函數(shù)的好處之一是無需自己寫登錄流程,小程序端的每個請求均可通過云端的cloud.getWXContext()方法均輕松獲得用戶的openid,如下:

const { OPENID } = cloud.getWXContext()
復(fù)制代碼

那么在小程序項目是否只需要openid,不再需要token了呢?我依然建議通過token來標(biāo)識用戶的有效性,因為在token中可以攜帶用戶角色\登錄時間等信息,用于更精細(xì)的業(yè)務(wù)控制。

//云函數(shù)端
const token = encode({ t: now, r: role })
復(fù)制代碼

用戶進(jìn)入首頁后如果token不存在或失效,通過調(diào)用云端getToken方法進(jìn)行更新token,同時在user表中新增或更新該用戶的記錄。

//小程序端,如果沒有token,去取token
if(!app.globalData.token){
  app.globalData.token = await api.callCloud('getToken')
}
復(fù)制代碼

api.callCloud就是前面所述的自定義云函數(shù)的通用方法。

//云端的getToken方法
async function getToken(cloud, db){
  try{
    const { OPENID } = cloud.getWXContext()
    let result = await db.collection('user').where({openId: OPENID}).get()
    //如果用戶表中已經(jīng)存在這個用戶,更新用戶的最近登錄時間
    if(result.data && result.data.length>0){
        await db.collection('user').where({openId: OPENID}).update({
          data: {
            latestTime: now
          }
        })
        token = encode({ d: now, r: record.role })
        return {code: '0000', info: '成功', data: {token, openId: OPENID, role: record.role}}
      }
    } else{
      let record = {
        openId: OPENID,
        firstTime: now,
        latestTime: now,
        role: 0
      }
      //如果user標(biāo)準(zhǔn)沒有這個用戶,則新增一條用戶記錄
      await db.collection('user').add({
        data: record
      })
      token = encode({ d: now, r:0})
      return {code: '0000', info: '成功', data: {token, openId: OPENID, role: 0}}
    }
  }catch(e){
    return {code: '0500', info: e.message || '系統(tǒng)錯誤'}
  }
}
復(fù)制代碼

web端可以通過小程序端掃碼進(jìn)行登錄,這樣就可以在web端也帶入用戶的openid,與小程序端使用同一套用戶體系。


作者:dunhuang
來源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

相關(guān)案例查看更多