基於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

相關文章
相關標籤/搜索