基于angular4 + express + wechat + svn + PM2 实现微信公众号开发(三)

基于angular4 + express + wechat + svn + PM2 实现微信公众号开发(三)

项目搭建

咱们使用angular-cli 来初始化咱们的项目。javascript

# 安装 angular-cli
npm install -g @angular/cli

ng new wechat_searve

项目目录结构以下:java

-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 输入下面代码node

'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.jsonmysql

{
  // 微信配置
  "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.jsnginx

'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;

GitHub: https://github.com/wenp/node-wechat.gitgit

相关文章
相关标签/搜索