91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用ThinkJs怎么搭建微信中控服務

發布時間:2021-02-07 14:28:17 來源:億速云 閱讀:127 作者:小新 欄目:web開發

這篇文章主要介紹了使用ThinkJs怎么搭建微信中控服務,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

本文不涉及任何接口安全、參數校驗之類的東西,默認對調用方無腦級的信任:joy: 目前自用的接口包括但不限于以下這些

|--- 微信相關
| |--- 0. 處理微信推過來的一些消息
| |--- 1. 獲取微信SDK配置參數
| |--- 2. 微信鑒權登陸
| |--- 3. 獲取微信用戶信息
| |--- 4. 獲取AccessToken
| |--- 5. 批量發送模版消息
| |--- 6. 獲取模版消息列表
| |--- 7. 批量發送客服消息

背景

  • 【需求】小項目很多很雜,而且大部分需求都是基于微信開發的,每次都查微信文檔的話就會很郁悶:unamused:...

  • 【號多】公眾號超級多,項目中偶爾會涉及借權獲取用戶信息(在不綁定微信開放平臺的前提下,需要臨時自建各個公眾號的openid關聯關系),類似這樣同時需要不止一個公眾號配合來完成一件事的需求,就容易把人整懵逼...

  • 【支付】微信支付的商戶號也很多,而且有時候支付需要用的商戶號,還不能用關聯的公眾號取出來的openid去支付...

  • 【官方】微信官方文檔建議!把獲取AccessToken等微信API抽離成單獨的服務... 等等等等........所以...:joy:

創建ThinkJS項目

官網

thinkjs.org/

簡介

ThinkJS 是一款面向未來開發的 Node.js 框架,整合了大量的項目最佳實踐,讓企業級開發變得如此簡單、高效。從 3.0 開始,框架底層基于 Koa 2.x 實現,兼容 Koa 的所有功能。

安裝腳手架

$ npm install -g think-cli

創建及啟動項目

$ thinkjs new demo;
$ cd demo;
$ npm install; 
$ npm start;

目錄結構

|--- development.js  //開發環境下的入口文件
|--- nginx.conf //nginx 配置文件
|--- package.json
|--- pm2.json //pm2 配置文件
|--- production.js //生產環境下的入口文件
|--- README.md
|--- src
| |--- bootstrap //啟動自動執行目錄 
| | |--- master.js //Master 進程下自動執行
| | |--- worker.js //Worker 進程下自動執行
| |--- config //配置文件目錄
| | |--- adapter.js // adapter 配置文件 
| | |--- config.js // 默認配置文件 
| | |--- config.production.js //生產環境下的默認配置文件,和 config.js 合并 
| | |--- extend.js //extend 配置文件 
| | |--- middleware.js //middleware 配置文件 
| | |--- router.js //自定義路由配置文件
| |--- controller //控制器目錄 
| | |--- base.js
| | |--- index.js
| |--- logic //logic 目錄
| | |--- index.js
| |--- model //模型目錄
| | |--- index.js
|--- view //模板目錄
| |--- index_index.html

安裝think-wechat插件

介紹

微信中間件,基于 node-webot/wechat,支持 thinkJS 3.0

安裝

$ npm install think-wechat --save

$ cnpm install think-wechat --save

配置

文件:/src/config/middleware.js

const wechat = require('think-wechat')
module.exports = [
  ...
   {
    handle: wechat,
    match: '/index',
    options: {
      token: '', // 令牌,和公眾號/基本配置/服務器配置里面寫一樣的即可
      appid: '', // 這里貌似可以隨便填,因為我們后面要用數據庫配置多個公眾號
      encodingAESKey: '',
      checkSignature: false
    }
  }, {
    handle: 'payload', // think-wechat 必須要在 payload 中間件前面加載,它會代替 payload 處理微信發過來的 post 請求中的數據。
    options: {
      keepExtensions: true,
      limit: '5mb'
    }
  },
]

注:match下我這里寫的是 /index ,對應的項目文件是 /src/controller/index.js ,對應的公眾號后臺所需配置的服務器地址就是 http(https)://域名:端口/index

創建數據庫和相關表

我這里創建了三個微信的相關表。

配置表:wx_config

字段類型說明
idint主鍵
namevarchar名稱
appidvarcharappid
secretvarcharsecret

用戶表:wx_userinfo


字段類型注釋
idint主鍵
subscribeint用戶是否訂閱該公眾號標識,值為0時,代表此用戶沒有關注該公眾號,拉取不到其余信息。
nicknamevarchar用戶的昵稱
sexint用戶的性別,值為1時是男性,值為2時是女性,值為0時是未知
languagevarchar用戶所在省份
cityvarchar用戶所在城市
provincevarchar用戶所在省份
countryvarchar用戶所在國家
headimgurllongtext用戶頭像,最后一個數值代表正方形頭像大小(有0、46、64、96、132數值可選,0代表640*640正方形頭像),用戶沒有頭像時該項為空。若用戶更換頭像,原有頭像URL將失效。
subscribe_timedouble用戶關注時間,為時間戳。如果用戶曾多次關注,則取最后關注時間
unionidvarchar只有在用戶將公眾號綁定到微信開放平臺帳號后,才會出現該字段。
openidvarchar用戶的標識,對當前公眾號唯一
wx_config_idint對應配置的微信號id

模版消息日志表:wx_template_log

字段類型注釋
idint主鍵
template_idvarchar模版id
openidvarchar用戶的標識,對當前公眾號唯一
urlvarchar跳轉url
miniprogramvarchar跳轉小程序
datavarchar發送內容json字符串
add_timedouble添加時間戳
send_timedouble發送時間戳
send_statusvarchar發送結果
wx_config_iddouble對應配置的微信號id
uuidvarchar本次發送的uuid,業務系統可通過uuid查詢模版消息推送結果

處理微信推送消息

文件目錄

/src/controller/index.js

文件內容

module.exports = class extends think.Controller {
  /*
  * 入口:驗證開發者服務器
  * 驗證開發者服務器,這里只是演示,所以沒做簽名校驗,實際上應該要根據微信要求進行簽名校驗
  */
  async indexAction() {
    let that = this;
    if (that.method != 'REPLY') {
      return that.json({code: 1, msg: '非法請求', data: null})
    }
    const {echostr} = that.get();
    return that.end(echostr);
  }
   
  /*
  * 文字
  * 用于處理微信推過來的文字消息
  */
  async textAction() {
    let that = this;
    let {id, signature, timestamp, nonce, openid} = that.get();
    let {ToUserName, FromUserName, CreateTime, MsgType, Content, MsgId} = that.post();
    .....
    that.success('')
  }
  
  /*
  * 事件
  * 用于處理微信推過來的事件消息,例如點擊菜單等
  */
  async eventAction() {
    let that = this;
    let {id, signature, timestamp, nonce, openid} = that.get();
    let {ToUserName, FromUserName, CreateTime, MsgType, Event, EventKey, Ticket, Latitude, Longitude, Precision} = that.post();
    switch (Event) {
      case 'subscribe': // 關注公眾號
        ...
        break;
      case 'unsubscribe': // 取消關注公眾號
        ...
        break;
      case 'SCAN': // 已關注掃碼
        ...
        break;
      case 'LOCATION': // 地理位置
        ...
        break;
      case 'CLICK': // 自定義菜菜單
        ...
        break;
      case 'VIEW': // 跳轉
        ...
        break;
      case 'TEMPLATESENDJOBFINISH':// 模版消息發送完畢
        ...
        break;
    } 
    that.success('')
  }
}

注:支持的action包括: textActionimageActionvoiceActionvideoActionshortvideoActionlocationActionlinkActioneventActiondeviceTextActiondeviceEventAction

公眾號后臺配置

使用ThinkJs怎么搭建微信中控服務

注:后面跟的id參數是為了區分是哪個公眾號推過來的消息,在上面的接口參數中也有體現

微信相關API的編寫

目錄結構

|--- src
| |--- controller //控制器目錄 
| | |--- index.js // 處理微信推送的消息,上面有寫到
| | |--- common.js // 一些公共方法
| | |--- open // 開放給其他業務服務的api接口
| | | |--- wx.js
| | |--- private // 放一些內部調用的方法,調用微信api的方法主要在這里面
| | | |--- wx.js

這個目錄結構可能不太合理,后期再改進吧:grin:

公共方法

// src/controller/common.js

import axios from 'axios'
import {baseSql} from "./unit";

module.exports = class extends think.Controller {
  // 獲取appinfo
  async getWxConfigById(id) {
    let that = this;
    let data = await that.cache(`wx_config:wxid_${id}`, async () => {
      // 數據庫內取
      let info = await that.model('wx_config', baseSql).where({id: id}).find();
      if (!think.isEmpty(info)) {
        return info
      }
    })
    return data || {}
  }

  // 獲取access_token
  async getAccessToken(id) {
    let that = this;
    let accessToken = await that.cache(`wx_access_token:wxid_${id}`, async () => {
      let {appid, secret} = await that.getWxConfigById(id);
      let {data} = await axios({
        method: 'get',
        url: `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`
      });
      return data.access_token
    });
    return accessToken
  }
}

接口過濾器

所有開放出來的接口的前置方法,俗稱過濾器?所有開放的接口必傳get參數是 wxid ,對應數據庫表wx_config里面 id

// src/controller/open/wx.js

async __before() {
  let that = this;
  let wxid = that.get('wxid');
  if (think.isEmpty(wxid)) {
    return that.json({code: 1, msg: 'wxid不存在'})
  }
  that.wxConfig = await that.controller('common').getWxConfigById(wxid);
  if (think.isEmpty(that.wxConfig)) {
    return that.json({code: 1, msg: 'wxid不存在'})
  }
}

接口 - 獲取AccessToken

代碼

// src/controller/open/wx.js

async get_access_tokenAction() {
  let that = this;
  let accessToken = await that.controller('common').getAccessToken(that.wxConfig.id);
  return that.json({code: 0, msg: '', data: {access_token: accessToken}})
}

文檔

使用ThinkJs怎么搭建微信中控服務 

接口 - 獲取微信sdk的config

代碼

// src/controller/open/wx.js

async get_wxsdk_configAction() {
  let that = this;
  let {url} = that.get();
  if (think.isEmpty(url)) {
    return that.json({code: 1, msg: '參數不正確'})
  }
  let sdkConfig = await that.controller('private/wx').getSdkConfig(that.wxConfig.id, url);
  return that.json({code: 0, msg: '', data: sdkConfig})
}


// src/controller/private/wx.js

const sha1 = require('sha1');
const getTimestamp = () => parseInt(Date.now() / 1000)
const getNonceStr = () => Math.random().toString(36).substr(2, 15)
const getSignature = (params) => sha1(Object.keys(params).sort().map(key => `${key.toLowerCase()}=${params[key]}`).join('&'));

async getSdkConfig(id, url) {
  let that = this;
  let {appid} = await that.controller('common').getWxConfigById(id);
  let shareConfig = {
    nonceStr: getNonceStr(),
    jsapi_ticket: await that.getJsapiTicket(id),
    timestamp: getTimestamp(),
    url: url
  }
  return {
    appId: appid,
    timestamp: shareConfig.timestamp,
    nonceStr: shareConfig.nonceStr,
    signature: getSignature(shareConfig)
  }
}

文檔

使用ThinkJs怎么搭建微信中控服務 

接口 - 獲取UserInfo

代碼

// src/controller/open/wx.js

async get_userinfoAction() {
  let that = this;
  let {openid} = that.get();
  if (think.isEmpty(openid)) {
    return that.json({code: 1, msg: '參數不正確'})
  }
  let userInfo = await that.controller('private/wx').getUserInfo(that.wxConfig.id, openid);
  if (think.isEmpty(userInfo)) {
    return that.json({code: 1, msg: 'openid不存在', data: null})
  }
  return that.json({code: 0, msg: '', data: userInfo})
}


// src/controller/private/wx.js

async getUserInfo(id, openid) {
  let that = this;
  let userInfo = await that.cache(`wx_userinfo:wxid_${id}:${openid}`, async () => {
    //先取數據庫
    let model = that.model('wx_userinfo', baseSql);
    let userInfo = await model.where({wx_config_id: id, openid: openid}).find();
    if (!think.isEmpty(userInfo) && userInfo.subscribe == 1 && userInfo.unionid != null) {
      return userInfo
    }
    //如果數據庫內沒有,取新的存入數據庫
    let accessToken = await that.controller('common').getAccessToken(id);
    let url = `https://api.weixin.qq.com/cgi-bin/user/info?access_token=${accessToken}&openid=${openid}&lang=zh_CN`;
    let {data} = await axios({method: 'get', url: url});
    if (data.openid) {
      //命中修改,沒有命中添加
      let resId = await model.thenUpdate(
        Object.assign(data, {wx_config_id: id}),
        {openid: openid, wx_config_id: id});
      return await model.where({id: resId}).find();
    }
  })
  return userInfo
}

文檔

使用ThinkJs怎么搭建微信中控服務 

接口 - 批量發送文字客服消息

代碼

// src/controller/open/wx.js

async send_msg_textAction() {
  let that = this;
  let {list} = that.post();
  if (think.isEmpty(list)) {
    return that.json({code: 1, msg: '參數不正確'})
  }
  that._sendMsgTextList(that.wxConfig.id, list);
  return that.json({code: 0, msg: '', data: null})
 }
 
 async _sendMsgTextList(wxid, list) {
  let that = this;
  let apiWxController = that.controller('private/wx');
  for (let item of list) {
    let data = await apiWxController.sendMsgText(wxid, item.openid, item.text)
  }
}


// src/controller/private/wx.js

async sendMsgText(id, openid, content) {
  let that = this;
  let accessToken = await that.controller('common').getAccessToken(id);
  let url = `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${accessToken}`
  let {data} = await axios({
    method: 'post', url: url, data: {"msgtype": 'text', "touser": openid, "text": {"content": content}}
  })
  return data;
}

文檔

使用ThinkJs怎么搭建微信中控服務 

感謝你能夠認真閱讀完這篇文章,希望小編分享的“使用ThinkJs怎么搭建微信中控服務”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

闽侯县| 高台县| 琼中| 平舆县| 电白县| 青州市| 尤溪县| 东乡族自治县| 汉源县| 蒙城县| 若尔盖县| 宣化县| 云霄县| 辰溪县| 水城县| 搜索| 滨海县| 龙泉市| 崇义县| 潜山县| 青岛市| 丹阳市| 扎赉特旗| 肃宁县| 伊通| 景谷| 兴义市| 邛崃市| 烟台市| 长阳| 大余县| 辽中县| 呼图壁县| 自治县| 项城市| 颍上县| 宜宾市| 通化县| 竹溪县| 福贡县| 河津市|