init
This commit is contained in:
commit
6ef05cfee1
131
app.js
Normal file
131
app.js
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const mysql = require("mysql");
|
||||||
|
const utils = require('./utils');
|
||||||
|
const event = require('./event');
|
||||||
|
const config = require('./config');
|
||||||
|
const db = require('./db');
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const handlers = {};
|
||||||
|
const middlewares = {};
|
||||||
|
const dbPools = {};
|
||||||
|
let sessionClass = null;
|
||||||
|
let useMiddlewares = [];
|
||||||
|
|
||||||
|
function listen(port) {
|
||||||
|
app.listen(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
function get() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
event.emitEvent(event.APP_INITIALIZED_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerHandler(c, a, cb) {
|
||||||
|
handlers[a + '@' + c] = {
|
||||||
|
'cb': cb,
|
||||||
|
'middlewares': useMiddlewares
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function injectionSession(sessionCls) {
|
||||||
|
sessionClass = sessionCls;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addMiddleware(name, cb) {
|
||||||
|
middlewares[name] = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
function useMiddleware(list, cb) {
|
||||||
|
try {
|
||||||
|
useMiddlewares = [];
|
||||||
|
list.forEach((name) => {
|
||||||
|
useMiddlewares.push(middlewares[name]);
|
||||||
|
});
|
||||||
|
cb();
|
||||||
|
} finally {
|
||||||
|
useMiddlewares = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerDb(name, options) {
|
||||||
|
dbPools[name] = {
|
||||||
|
'options': options,
|
||||||
|
'pool': mysql.createPool({
|
||||||
|
host : options['host'],
|
||||||
|
user : options['user'],
|
||||||
|
password : options['passwd'],
|
||||||
|
database : options['database'],
|
||||||
|
stringifyObjects : true
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDbConn(name) {
|
||||||
|
const ret = {
|
||||||
|
err: null,
|
||||||
|
conn: null,
|
||||||
|
};
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
if (!(name in dbPools)) {
|
||||||
|
ret.err = 'dbname not exists ' + name;
|
||||||
|
resolve(ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const pool = dbPools[name]['pool'];
|
||||||
|
pool.getConnection(function(err, conn) {
|
||||||
|
ret.err = err;
|
||||||
|
ret.conn = new db(conn);
|
||||||
|
resolve(ret);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('unhandledRejection', (reason, promise) => {
|
||||||
|
console.log('Unhandled Rejection at:', promise, 'reason:', reason);
|
||||||
|
throw reason;
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/webapp/index.php', async (req, rsp) => {
|
||||||
|
const c = req.query.c;
|
||||||
|
const a = req.query.a;
|
||||||
|
const handler = handlers[a + '@' + c];
|
||||||
|
if (handler) {
|
||||||
|
const cb = handler['cb'];
|
||||||
|
const middlewares = handler['middlewares'];
|
||||||
|
if (sessionClass) {
|
||||||
|
const session = new sessionClass(req, rsp);
|
||||||
|
middlewares.forEach(async (m) => {
|
||||||
|
await m(session);
|
||||||
|
});
|
||||||
|
await cb(session);
|
||||||
|
} else {
|
||||||
|
middlewares.forEach(async (m) => {
|
||||||
|
await m(req, rsp);
|
||||||
|
});
|
||||||
|
await cb(req, rsp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
utils.rspErr(rsp, 100, 'not found');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
registerHandler('Ops', 'selfChecking', (req, rsp) => {
|
||||||
|
rsp.send(utils.jsonEncode({
|
||||||
|
'errcode': 0,
|
||||||
|
'errmsg': ''
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.init = init;
|
||||||
|
exports.listen = listen;
|
||||||
|
exports.get = get;
|
||||||
|
exports.registerHandler = registerHandler;
|
||||||
|
exports.injectionSession = injectionSession;
|
||||||
|
exports.addMiddleware = addMiddleware;
|
||||||
|
exports.useMiddleware = useMiddleware;
|
||||||
|
exports.registerDb = registerDb;
|
||||||
|
exports.getDbConn = getDbConn;
|
1
channel.js
Normal file
1
channel.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
exports.SELF_SDK = 6000;
|
18
config.js
Normal file
18
config.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
const utils = require('./utils');
|
||||||
|
|
||||||
|
let loaded = false;
|
||||||
|
let configJson = null;
|
||||||
|
|
||||||
|
function config(name) {
|
||||||
|
if (!loaded) {
|
||||||
|
let configDir = './config/';
|
||||||
|
if (utils.isOnlineEnv()) {
|
||||||
|
configDir = '../config/';
|
||||||
|
}
|
||||||
|
loaded = true;
|
||||||
|
configJson = utils.readJsonFromFile(configDir + 'config.json');
|
||||||
|
}
|
||||||
|
return configJson ? configJson[name] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = config;
|
155
db.js
Normal file
155
db.js
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
const util = require("util");
|
||||||
|
const log = require("./log");
|
||||||
|
|
||||||
|
class DB {
|
||||||
|
|
||||||
|
constructor(conn) {
|
||||||
|
this.conn = conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
execQuery(sql, params) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const ret = {
|
||||||
|
err: null,
|
||||||
|
rows: null,
|
||||||
|
};
|
||||||
|
this.conn.query(sql, params, (err, rows) => {
|
||||||
|
try {
|
||||||
|
if (err) {
|
||||||
|
ret.err = err;
|
||||||
|
resolve(ret);
|
||||||
|
log.error(util.format(
|
||||||
|
'sql:%s err:%s',
|
||||||
|
sql, err
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
ret.err = err;
|
||||||
|
ret.rows = rows;
|
||||||
|
resolve(ret);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
//this.conn.release();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async execQueryOne(sql, params) {
|
||||||
|
const {err, rows} = await this.execQuery(sql, params);
|
||||||
|
return {
|
||||||
|
'err': err,
|
||||||
|
'row': rows && rows.length > 0 ? rows[0] : null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async execScript(sql, params) {
|
||||||
|
const {err, rows} = await this.execQuery(sql, params);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
async update(tblName, whereList, fieldList) {
|
||||||
|
const params = [];
|
||||||
|
let sql = 'UPDATE `' + tblName + '` SET ';
|
||||||
|
|
||||||
|
fieldList.forEach((item, index) => {
|
||||||
|
const suffix = (index + 1 < fieldList.length ? ',': '');
|
||||||
|
sql += ' `' + item[0] + '`=?' + suffix;
|
||||||
|
params.push(item[1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
sql += ' WHERE 1=1';
|
||||||
|
whereList.forEach((item, index) => {
|
||||||
|
sql += ' AND ' + item[0] + '=?';
|
||||||
|
params.push(item[1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.execScript(sql, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
async insert(tblName, fieldList) {
|
||||||
|
const params = [];
|
||||||
|
let sql = 'INSERT INTO `' + tblName + '` (';
|
||||||
|
|
||||||
|
fieldList.forEach((item, index) => {
|
||||||
|
const suffix = (index + 1 < fieldList.length ? ',': '');
|
||||||
|
sql += '`' + item[0] + '`' + suffix;
|
||||||
|
});
|
||||||
|
|
||||||
|
sql += ') VALUES (';
|
||||||
|
fieldList.forEach((item, index) => {
|
||||||
|
const suffix = (index + 1 < fieldList.length ? ',': '');
|
||||||
|
sql += '?' + suffix;
|
||||||
|
params.push(item[1]);
|
||||||
|
});
|
||||||
|
sql += ')';
|
||||||
|
|
||||||
|
this.execScript(sql, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
async upsert(tblName, whereList, updateList, insertList, opts = null) {
|
||||||
|
const params = [];
|
||||||
|
let sql = 'SELECT * FROM `' + tblName + '` ';
|
||||||
|
{
|
||||||
|
sql += ' WHERE 1=1';
|
||||||
|
whereList.forEach((item, index) => {
|
||||||
|
sql += ' AND ' + item[0] + '=?';
|
||||||
|
params.push(item[1]);
|
||||||
|
});
|
||||||
|
sql += ' LIMIT 1;'
|
||||||
|
}
|
||||||
|
|
||||||
|
const {err, row} = await this.execQueryOne
|
||||||
|
(
|
||||||
|
sql,
|
||||||
|
params
|
||||||
|
);
|
||||||
|
if (err) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (row) {
|
||||||
|
if (opts && utils.getVal(opts, 'onQueryOk')) {
|
||||||
|
opts['onQueryOk'](row);
|
||||||
|
}
|
||||||
|
await this.update(tblName, whereList, updateList);
|
||||||
|
} else {
|
||||||
|
await this.insert(tblName, insertList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async _delete(tblName, whereList) {
|
||||||
|
const params = [];
|
||||||
|
let sql = 'DELETE FROM `' + tblName + '` ';
|
||||||
|
|
||||||
|
sql += ' WHERE 1=1';
|
||||||
|
whereList.forEach((item, index) => {
|
||||||
|
sql += ' AND ' + item[0] + '=?';
|
||||||
|
params.push(item[1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.execScript(sql, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
async ormSelect(tblName, whereList) {
|
||||||
|
const params = [];
|
||||||
|
let sql = 'SELECT * FROM `' + tblName + '` ';
|
||||||
|
|
||||||
|
sql += ' WHERE 1=1';
|
||||||
|
whereList.forEach((item, index) => {
|
||||||
|
sql += ' AND ' + item[0] + '=?';
|
||||||
|
params.push(item[1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.execQuery(sql, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
async ormSelectOne(tblName, whereList) {
|
||||||
|
const {err, rows} = await this.ormSelect(tblName, whereList);
|
||||||
|
return {
|
||||||
|
'err': err,
|
||||||
|
'row': rows.length > 0 ? rows[0] : null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = DB;
|
17
event.js
Normal file
17
event.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
const events = require('events');
|
||||||
|
|
||||||
|
const event = new events.EventEmitter();
|
||||||
|
|
||||||
|
const APP_INITIALIZED_EVENT = '!app.initialized';
|
||||||
|
|
||||||
|
function addListener(eventName, listener) {
|
||||||
|
event.on(eventName, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
function emitEvent(eventName, ...args) {
|
||||||
|
event.emit(eventName, ...args);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.addListener = addListener;
|
||||||
|
exports.emitEvent = emitEvent;
|
||||||
|
exports.APP_INITIALIZED_EVENT = APP_INITIALIZED_EVENT;
|
33
log.js
Normal file
33
log.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
const utils = require('./utils');
|
||||||
|
|
||||||
|
function warning(msg) {
|
||||||
|
internalLog('[WARNING]', msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
function info(msg) {
|
||||||
|
internalLog('[INFO]', msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
function error(msg) {
|
||||||
|
internalLog('[ERROR]', msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
function alert(msg) {
|
||||||
|
internalLog('[ALERT]', msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
function debug(msg) {
|
||||||
|
if (!utils.isOnlineEnv()) {
|
||||||
|
internalLog('[DEBUG]', msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function internalLog(logClass, msg) {
|
||||||
|
console.log(utils.formatDate(new Date()) + ' ' + logClass + ' ' + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.warning = warning;
|
||||||
|
exports.info = info;
|
||||||
|
exports.alert = alert;
|
||||||
|
exports.error = error;
|
||||||
|
exports.debug = debug;
|
1101
package-lock.json
generated
Normal file
1101
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
12
package.json
Normal file
12
package.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "j7",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {},
|
||||||
|
"dependencies": {
|
||||||
|
"crc-32": "^1.2.1",
|
||||||
|
"express": "^4.17.2",
|
||||||
|
"mysql": "~2.18.1"
|
||||||
|
}
|
||||||
|
}
|
40
sync.js
Normal file
40
sync.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
const utils = require('./utils');
|
||||||
|
|
||||||
|
class Cond {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.waitList = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async wait(timeout) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const waitIdx = this.waitList.length;
|
||||||
|
this.waitList.push({
|
||||||
|
'resolve': resolve,
|
||||||
|
'timer': setTimeout(() => {
|
||||||
|
if (waitIdx < this.waitList.length &&
|
||||||
|
this.waitList[waitIdx]['resolve'] == resolve) {
|
||||||
|
this.waitList = this.waitList.splice(waitIdx, 1);
|
||||||
|
} else {
|
||||||
|
utils.throwError('cond waitIdx error');
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
}, timeout)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyAll() {
|
||||||
|
if (this.waitList.length > 0) {
|
||||||
|
const waitListCopy = this.waitList;
|
||||||
|
this.waitList = [];
|
||||||
|
waitListCopy.forEach((v) => {
|
||||||
|
clearTimeout(v['timer']);
|
||||||
|
v['resolve']();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.Cond = Cond;
|
173
utils.js
Normal file
173
utils.js
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const crypto = require('crypto');
|
||||||
|
const crc32 = require('crc-32');
|
||||||
|
const serverEnv = process.env['SERVER_ENV'];
|
||||||
|
|
||||||
|
function rspErr(rsp, errCode, errMsg) {
|
||||||
|
rsp.send(jsonEncode({
|
||||||
|
'errcode': errCode,
|
||||||
|
'errmsg': errMsg
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function rspOk(rsp) {
|
||||||
|
rsp.send(jsonEncode({
|
||||||
|
'errcode': 0,
|
||||||
|
'errmsg': ''
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function rspData(rsp, data) {
|
||||||
|
data['errcode'] = 0;
|
||||||
|
data['errmsg'] = '';
|
||||||
|
rsp.send(jsonEncode(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function readJsonFromFile(url) {
|
||||||
|
const jsondata = fs.readFileSync(url, "utf8");
|
||||||
|
const json = JSON.parse(jsondata);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sleep(timeout) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
setTimeout(function () {
|
||||||
|
resolve();
|
||||||
|
}, timeout);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function emptyReplace(val, newVal) {
|
||||||
|
return !val ? newVal : val;
|
||||||
|
}
|
||||||
|
|
||||||
|
function throwError(msg) {
|
||||||
|
console.log(msg);
|
||||||
|
throw msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOnlineEnv() {
|
||||||
|
return !serverEnv;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUtcTime() {
|
||||||
|
return Math.floor((new Date()).getTime() / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDate(date) {
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = date.getMonth() + 1;//月份是从0开始的
|
||||||
|
const day = date.getDate();
|
||||||
|
const hour = date.getHours();
|
||||||
|
const min = date.getMinutes();
|
||||||
|
const sec = date.getSeconds();
|
||||||
|
return year + '-' +
|
||||||
|
(month < 10 ? '0' + month : month) + '-' +
|
||||||
|
(day < 10 ? '0' + day : day) + ' ' +
|
||||||
|
(hour < 10 ? '0' + hour : hour) + ':' +
|
||||||
|
(min < 10 ? '0' + min : min) + ':' +
|
||||||
|
(sec < 10 ? '0' + sec : sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
function pad(num, n) {
|
||||||
|
let result = num.toString();
|
||||||
|
let len = result.length;
|
||||||
|
while (len < n) {
|
||||||
|
result = '0' + result;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function randRange(min, max) {
|
||||||
|
if (min >= max) {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
return min + Math.random() * max;
|
||||||
|
}
|
||||||
|
|
||||||
|
function jsonEncode(obj) {
|
||||||
|
return JSON.stringify(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isArray(val) {
|
||||||
|
return Array.isArray(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isObject(val) {
|
||||||
|
return typeof(obj) == "object";
|
||||||
|
}
|
||||||
|
|
||||||
|
function crc32Str(str) {
|
||||||
|
return crc32.str('' + str);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createAccountId(channel, gameId, openId) {
|
||||||
|
const accountId = `${channel}_${gameId}_${openId}`;
|
||||||
|
return accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractChannel(accountId) {
|
||||||
|
const ss = accountId.split('_');
|
||||||
|
return ss[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractGameId(accountId) {
|
||||||
|
const ss = accountId.split('_');
|
||||||
|
return ss[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractOpenId(accountId) {
|
||||||
|
const channel = extractChannel(accountId);
|
||||||
|
const gameId = extractGameId(accountId);
|
||||||
|
const openId = accountId.substr(accountId.indexOf(`${channel}_${gameId}_`));
|
||||||
|
return openId;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createSessionId(accountId, registerTime, secretKey) {
|
||||||
|
const nowTime = getUtcTime();
|
||||||
|
const rand = randRange(1, 1000000000);
|
||||||
|
const sessionId = '' +
|
||||||
|
nowTime + '_' +
|
||||||
|
registerTime + '_' +
|
||||||
|
rand + '_' +
|
||||||
|
md5Str('' + accountId + secretKey + registerTime + nowTime);
|
||||||
|
|
||||||
|
return sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
function md5Str(data) {
|
||||||
|
const hash = crypto.createHash('md5');
|
||||||
|
return hash.update(data).digest('hex');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVal(obj, key, defVal = null) {
|
||||||
|
if (!obj){
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
return key in obj ? obj[key] : defVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.rspErr = rspErr;
|
||||||
|
exports.rspOk = rspOk;
|
||||||
|
exports.rspData = rspData;
|
||||||
|
exports.readJsonFromFile = readJsonFromFile;
|
||||||
|
exports.sleep = sleep;
|
||||||
|
exports.emptyReplace = emptyReplace;
|
||||||
|
exports.throwError = throwError;
|
||||||
|
exports.isOnlineEnv = isOnlineEnv;
|
||||||
|
exports.getUtcTime = getUtcTime;
|
||||||
|
exports.formatDate = formatDate;
|
||||||
|
exports.pad = pad;
|
||||||
|
exports.randRange = randRange;
|
||||||
|
exports.jsonEncode = jsonEncode;
|
||||||
|
exports.isArray = isArray;
|
||||||
|
exports.isObject = isObject;
|
||||||
|
exports.crc32Str = crc32Str;
|
||||||
|
exports.createAccountId = createAccountId;
|
||||||
|
exports.extractChannel = extractChannel;
|
||||||
|
exports.extractGameId = extractGameId;
|
||||||
|
exports.extractOpenId = extractOpenId;
|
||||||
|
exports.createSessionId = createSessionId;
|
||||||
|
exports.md5Str = md5Str;
|
||||||
|
exports.getVal = getVal;
|
Loading…
x
Reference in New Issue
Block a user