基于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号