wx-gzh
Version:
401 lines (400 loc) • 20.6 kB
JavaScript
"use strict";
/*
* @Description:
* @Author: chtao
* @Github: https://github.com/LadyYang
* @Email: 1763615252@qq.com
* @Date: 2020-07-26 20:45:01
* @LastEditTime: 2020-08-03 14:00:42
* @LastEditors: chtao
* @FilePath: \wx-gzh\index.ts
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var crypto_1 = __importDefault(require("crypto"));
var xml2js_1 = require("xml2js");
var response_1 = require("./lib/response");
var menu_1 = require("./lib/menu");
var code_1 = require("./lib/code");
var Observe_1 = __importDefault(require("./lib/Observe"));
var pay_1 = require("./lib/pay");
var utils_1 = require("./utils");
var sdk_1 = __importDefault(require("./lib/sdk"));
var instance = null;
var WeChat = /** @class */ (function (_super) {
__extends(WeChat, _super);
function WeChat(options, web) {
if (web === void 0) { web = false; }
var _this = _super.call(this) || this;
_this.useMiddleware = _this._useMiddleware.bind(_this);
_this.getQRCode = code_1.getQRCode;
_this.createH5PayOrder = pay_1.createH5PayOrder;
_this.createJSAPIPayOrder = pay_1.createJSAPIPayOrder;
_this.getSignature = sdk_1.default;
_this.authToken = options.token;
_this.appID = options.appID;
_this.appsecret = options.appsecret;
_this.path = options.routePath;
_this.payOptions = options.payOptions;
(function () { return __awaiter(_this, void 0, void 0, function () {
var _a, e_1;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 5, , 6]);
// 获取 token
return [4 /*yield*/, this.getWechatAccessToken()];
case 1:
// 获取 token
_b.sent();
return [4 /*yield*/, menu_1.createMenu.call(this, options.menuData)];
case 2:
_b.sent();
_a = web;
if (!_a) return [3 /*break*/, 4];
return [4 /*yield*/, this.getWeChatTicket()];
case 3:
_a = (_b.sent());
_b.label = 4;
case 4:
_a;
return [3 /*break*/, 6];
case 5:
e_1 = _b.sent();
this.emit('error', e_1);
return [3 /*break*/, 6];
case 6: return [2 /*return*/];
}
});
}); })();
if (instance) {
return instance;
}
instance = _this;
return _this;
}
Object.defineProperty(WeChat.prototype, "accessToken", {
get: function () {
return this._accessToken;
},
set: function (val) {
this._accessToken = val;
this.emit('ready', val);
},
enumerable: false,
configurable: true
});
/**
* 获取 access_token
*/
WeChat.prototype.getWechatAccessToken = function () {
return __awaiter(this, void 0, void 0, function () {
var result;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, utils_1.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + this.appID + "&secret=" + this.appsecret)];
case 1:
result = _a.sent();
if (result.errmsg) {
throw Error(JSON.stringify(result));
}
this.accessToken = result.access_token;
setTimeout(this.getWechatAccessToken.bind(this), (result.expires_in - 1200) * 1000);
return [2 /*return*/];
}
});
});
};
WeChat.prototype.getWeChatTicket = function () {
return __awaiter(this, void 0, void 0, function () {
var result;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, utils_1.get("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + this.accessToken + "&type=jsapi")];
case 1:
result = _a.sent();
this.ticket = result.ticket;
// if (result.errcode !== 0) {
// throw new Error(result);
// }
setTimeout(this.getWeChatTicket.bind(this), (result.expires_in - 1200) * 1000);
return [2 /*return*/];
}
});
});
};
WeChat.prototype.dealGZHEvent = function (ctx) {
return __awaiter(this, void 0, void 0, function () {
var xml, key, contents, _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
xml = ctx.request.body.xml;
for (key in xml) {
xml[key] = xml[key][0];
}
_a = xml.MsgType;
switch (_a) {
case 'text': return [3 /*break*/, 1];
}
return [3 /*break*/, 3];
case 1: return [4 /*yield*/, this.emit('text', xml)];
case 2:
contents = _c.sent();
return [2 /*return*/, response_1.responseText(xml, contents.join(''), ctx)];
case 3:
_b = xml.Event;
switch (_b) {
case 'SCAN': return [3 /*break*/, 4];
case 'subscribe': return [3 /*break*/, 6];
case 'unsubscribe': return [3 /*break*/, 8];
case 'CLICK': return [3 /*break*/, 10];
}
return [3 /*break*/, 12];
case 4: return [4 /*yield*/, this.emit('scan', xml)];
case 5:
contents = _c.sent();
return [2 /*return*/, response_1.responseText(xml, contents.join(''), ctx)];
case 6: return [4 /*yield*/, this.emit('subscribe', xml)];
case 7:
contents = _c.sent();
return [2 /*return*/, response_1.responseText(xml, contents.join(''), ctx)];
case 8: return [4 /*yield*/, this.emit('unsubscribe', xml)];
case 9:
contents = _c.sent();
return [2 /*return*/, response_1.responseText(xml, contents.join(''), ctx)];
case 10: return [4 /*yield*/, this.emit('click', xml)];
case 11:
contents = _c.sent();
return [2 /*return*/, response_1.responseText(xml, contents.join(''), ctx)];
case 12: return [4 /*yield*/, this.emit('unknow', xml)];
case 13:
contents = _c.sent();
return [2 /*return*/, response_1.responseText(xml, contents.join(''), ctx)];
}
});
});
};
WeChat.prototype._useMiddleware = function (ctx, next) {
var _a;
return __awaiter(this, void 0, void 0, function () {
var e_2;
var _this = this;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 4, , 5]);
if (ctx.href.includes(this.path) && /^(POST)$/i.test(ctx.method)) {
return [2 /*return*/, new Promise(function (resolve) {
var result = '';
ctx.req.on('data', function (chunk) { return (result += chunk); });
ctx.req.on('end', function () { return __awaiter(_this, void 0, void 0, function () {
var res, e_3;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 3, , 4]);
return [4 /*yield*/, xml2js_1.parseStringPromise(result)];
case 1:
res = _a.sent();
if (!(ctx.request.body && typeof ctx.request.body === 'object')) {
ctx.request.body = {};
}
ctx.request.body.xml = res.xml;
return [4 /*yield*/, this.dealGZHEvent(ctx)];
case 2:
_a.sent();
resolve();
return [3 /*break*/, 4];
case 3:
e_3 = _a.sent();
this.emit('error', e_3);
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}
});
}); });
ctx.req.on('aborted', function (e) { return _this.emit('error', e); });
ctx.req.on('error', function (e) { return _this.emit('error', e); });
})];
}
if (!(ctx.href.includes(this.path) && /^(GET)$/i.test(ctx.method))) return [3 /*break*/, 2];
return [4 /*yield*/, this.auth(ctx)];
case 1: return [2 /*return*/, _b.sent()];
case 2:
if (ctx.href.includes((_a = this.payOptions) === null || _a === void 0 ? void 0 : _a.notify_url)) {
return [2 /*return*/, new Promise(function (resolve) {
var result = '';
ctx.req.on('data', function (chunk) { return (result += chunk); });
ctx.req.on('end', function () { return __awaiter(_this, void 0, void 0, function () {
var res, e_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 3, , 4]);
return [4 /*yield*/, xml2js_1.parseStringPromise(result)];
case 1:
res = _a.sent();
if (!(ctx.request.body && typeof ctx.request.body === 'object')) {
ctx.request.body = {};
}
ctx.request.body.xml = res.xml;
return [4 /*yield*/, this.dealPayEvent(ctx)];
case 2:
_a.sent();
resolve();
return [3 /*break*/, 4];
case 3:
e_4 = _a.sent();
this.emit('error', e_4);
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}
});
}); });
ctx.req.on('aborted', function (e) { return _this.emit('error', e); });
ctx.req.on('error', function (e) { return _this.emit('error', e); });
})];
}
return [4 /*yield*/, next()];
case 3:
_b.sent();
return [3 /*break*/, 5];
case 4:
e_2 = _b.sent();
response_1.responseText(ctx.request.body.xml, 'error', ctx);
this.emit('error', e_2);
return [3 /*break*/, 5];
case 5: return [2 /*return*/];
}
});
});
};
WeChat.prototype.dealPayEvent = function (ctx) {
return __awaiter(this, void 0, void 0, function () {
var xml, key;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
xml = ctx.request.body.xml;
for (key in xml) {
xml[key] = xml[key][0];
}
if (!(xml.return_code === 'SUCCESS')) return [3 /*break*/, 2];
return [4 /*yield*/, this.emit('paySuccess', xml)];
case 1:
_a.sent();
response_1.responsePay(ctx);
_a.label = 2;
case 2:
if (!(xml.return_code === 'FAIL')) return [3 /*break*/, 4];
return [4 /*yield*/, this.emit('payFail', undefined)];
case 3:
_a.sent();
response_1.responsePay(ctx);
_a.label = 4;
case 4: return [2 /*return*/];
}
});
});
};
/** 开启 web 开发,用户获取 ticket */
WeChat.prototype.openWeb = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getWeChatTicket()];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
/** 验证微信接口 */
WeChat.prototype.auth = function (ctx) {
return __awaiter(this, void 0, void 0, function () {
var _a, signature, timestamp, nonce, echostr, authStr, hashStr;
return __generator(this, function (_b) {
_a = ctx.request.query, signature = _a.signature, timestamp = _a.timestamp, nonce = _a.nonce, echostr = _a.echostr;
authStr = [this.authToken, timestamp, nonce].sort().join('');
hashStr = crypto_1.default
.createHash('sha1')
.update(authStr, 'utf8')
.digest('hex');
if (hashStr === signature) {
ctx.body = echostr;
}
else {
ctx.body = {
message: '微信回调认证失败',
};
}
return [2 /*return*/];
});
});
};
WeChat.prototype.getUserInfo = function (openid) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, utils_1.get("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + this.accessToken + "&openid=" + openid + "&lang=zh_CN")];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
};
return WeChat;
}(Observe_1.default));
exports.default = WeChat;