基于angular4 + express + wechat + svn + PM2 实现微信公众号开发(三)
基于angular4 + express + wechat + svn + PM2 实现微信公众号开发(三)
项目搭建
我们使用angular-cli 来初始化我们的项目。
# 安装 angular-cli
npm install -g @angular/cli
ng new wechat_searve
项目目录结构如下:
-wechat_searve
-config # 项目配置文件 放一些全局配置
-dist # angular 构建后目录
-logs # 日志目录
-service # node 服务器文件
-src # angular 源码文件
.angular-cli.json # angular cli 配置文件
.editorconfig # 代码风格配置文件
package.json # 包管理
service.js # 服务器入口文件
tsconfig.json # typeScript 配置文件
tslint.json # 代码检查配置文件
PM2.json # PM2 启动配置文件
依赖包介绍
"express": "^4.15.3", # 这个我就不介绍了
"mysql": "^2.14.0", # 同上
"node-xlsx": "^0.10.0", # node 读取 excel
"request": "^2.81.0", # 服务器发送请求
"require-directory": "^2.1.1", # require 整个目录(很方便的)
"wechat": "^2.1.0" # wechat 模块
代码编写
打开 service.js 输入下面代码
'use strict'
const express = require('express');
const config = require('./config/config.json')
const wechat = require('./service/wechat/wechat');
const WenpengApi = require('./service/WenpengApi');
const app = express();
// app.use(express.query()); 老版本的 express 需要使用下 query 中间件
// 微信基础服务
app.use('/wechat', new wechat(config).init);
// api 接口
app.use('/api',new WenpengApi().router)
// 静态资源目录(web 容器)
app.use('/', express.static('dist'))
app.listen(config.host.port, function () {
console.log("app runing at " + config.host.port);
});
config.json
{
// 微信配置
"wechat": {
"appid": "********",
"appsecret": "*******",
"token": "******",
"encodingAESKey": "*********"
},
"host": {
"ip": "110.110.110.110",
"port": 80 // 微信服务器接入需要使用 80 端口 如果不想使用 80 也可以使用 nginx 代理或者使用其他方法
},
"apiDomain":"https://api.weixin.qq.com/",
// 接入了图灵机器人 聊天
"tuling": {
"domain": "http://www.tuling123.com/openapi/api",
"key": "****"
},
"apiURL":{
"accessTokenApi":"%scgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
"createMenus": "%scgi-bin/menu/create?access_token=%s",
"userInfo": "%scgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN "
},
"mysql": {
"host": "****",
"user": "****",
"password": "123456",
"database": "wechat"
}
}
wechat.js
'use strict'
const wechat = require('wechat'); // 引入 wechat 模块
const baseMsgUtils = require('./baseMsgUtil'); // 引入 基本消息处理模块
const request = require('request'); // 引入 request 模块
const util = require('util'); // 引入工具包 使用 format 拼接字符串
const accessToken = require('./wechat_config/accessToken.json'); // 引入 accesstoken json 文件
const fs = require('fs'); // 引入 fs 模块
const mysql = require('../db').mysql;
class Wechat {
constructor (config) {
this.config = config; // 保存 config 信息 方便内部调用
this.wechat = wechat(config.wechat); // 填写配置 验证微信接口
this.init = this._init(); // 初始对象
this.mysql = new mysql(); // 创建 mysql 实例
this.access_token = accessToken; // 初始化access
this._create_menus(); // 创建自定义菜单
}
// 初始化基本 消息回复
_init () {
for(let key in baseMsgUtils){// 处理不同的所有业务逻辑
this.wechat[key](baseMsgUtils[key].bind(this))
}
return this.wechat.middlewarify(); // 返回处理业务逻辑函数
}
// 判断accessToken 是否过期并且过期自动请求
check_access_time() {
const nowTime = new Date().getTime();
const preAccessTokenTime = this.access_token.expires_time;
if(nowTime < preAccessTokenTime) {
console.log('本地 token');
// 更新 对象 access_token 属性 如果没有就创建
return Promise.resolve(this.access_token);
}
console.log('远端 token');
return this._access_token();
}
// 获取 access
_access_token() {
var that = this;
return new Promise((resolve, reject) => {
request.get(util.format( // 发送请求
this.config.apiURL.accessTokenApi,
this.config.apiDomain,
this.config.wechat.appid,
this.config.wechat.appsecret))
.on('error', err => reject(err))// 监听 error 事件
.on('data', data => { // 监听 data 事件
const access = JSON.parse(data.toString()),
time = new Date().getTime(),
accessTokenStr = {
"access_token": access.access_token,
"expires_time": time + access.expires_in * 1000
};
fs.writeFile(__dirname + '/wechat_config/accessToken.json', JSON.stringify(accessTokenStr)) // 更新 access Token.json 文件
that.access_token = accessTokenStr; // 更新 对象 access_token 属性
resolve(that.access_token); // 更新 promise 状态
})
})
}
// 创建菜单
_create_menus () {
this.check_access_time() // 获取 token
.then(() => {
console.log()
request.post(util.format(this.config.apiURL.createMenus, this.config.apiDomain, this.access_token.access_token))
.json(require('./wechat_config/wechat_menu.json'))
.on('error', err => {throw err})
.on('data', data => {
const dataObj = JSON.parse(data.toString());
if(dataObj.errcode !==0){
throw dataObj.errmsg;
}
})
}, err => {throw err})
return this;
}
// mysql 执行 sql 语句
query(sql) {
return this.mysql.query(sql)
}
}
module.exports = Wechat;
浙公网安备 33010602011771号