|--- 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}}) }
文档
接口 - 获取微信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) } }
文档
接口 - 获取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 }
文档
接口 - 批量发送文字客服消息
代码