소스 검색

init repo

Sand 8 년 전
커밋
ee3f17f969
31개의 변경된 파일1994개의 추가작업 그리고 0개의 파일을 삭제
  1. 2 0
      .gitignore
  2. 81 0
      app.js
  3. 91 0
      bin/www
  4. 62 0
      config.js
  5. 39 0
      config_pro.js
  6. 39 0
      config_test.js
  7. 14 0
      db/mysql_im.js
  8. 14 0
      db/mysql_wlyy.js
  9. 54 0
      db/mysqldb.js
  10. 62 0
      models/msg_group.js
  11. 37 0
      models/msg_p2p.js
  12. 223 0
      models/msg_statistic.js
  13. 14 0
      models/msg_system.js
  14. 14 0
      models/push_notify.js
  15. 50 0
      models/user.js
  16. 79 0
      mysql_db/im.sql
  17. 18 0
      package.json
  18. 8 0
      public/stylesheets/style.css
  19. 48 0
      routes/index.js
  20. 240 0
      routes/msg_group.js
  21. 199 0
      routes/msg_p2p.js
  22. 220 0
      routes/msg_statistic.js
  23. 111 0
      routes/msg_system.js
  24. 90 0
      routes/user.js
  25. 32 0
      server.js
  26. 123 0
      util/log.js
  27. 1 0
      views/error.html
  28. 6 0
      views/error.jade
  29. 11 0
      views/index.html
  30. 5 0
      views/index.jade
  31. 7 0
      views/layout.jade

+ 2 - 0
.gitignore

@ -0,0 +1,2 @@
.idea/*
node_modules/*

+ 81 - 0
app.js

@ -0,0 +1,81 @@
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var user = require('./routes/user');
var msg_group = require('./routes/msg_group');
var msg_p2p = require('./routes/msg_p2p');
var msg_system = require('./routes/msg_system');
var msg_statistic = require('./routes/msg_statistic');
var config = require('./config');
var app = express();
var startDate = new Date();
console.log('==============================================');
console.log('');
console.log('Push Server started on ' + startDate.toLocaleString());
console.log('Version: ' + config.version);
console.log('');
console.log('==============================================');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/user', user);
app.use('/group', msg_group);
app.use('/p2p', msg_p2p);
app.use('/system', msg_system);
app.use('/statistic', msg_statistic);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});
process.on('uncaughtException', function (err) {
  console.log(err);
  console.log(err.stack);
});
module.exports = app;

+ 91 - 0
bin/www

@ -0,0 +1,91 @@
#!/usr/bin/env node
/**
 * Module dependencies.
 */
var app = require('../app');
var debug = require('debug')('app_ldap:server');
var http = require('http');
var config = require('../config');
/**
 * Get port from environment and store in Express.
 */
var port = normalizePort(process.env.PORT || config.http_port);
app.set('port', port);
/**
 * Create HTTP server.
 */
var server = http.createServer(app);
/**
 * Listen on provided port, on all network interfaces.
 */
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
 * Normalize a port into a number, string, or false.
 */
function normalizePort(val) {
  var port = parseInt(val, 10);
  if (isNaN(port)) {
    // named pipe
    return val;
  }
  if (port >= 0) {
    // port number
    return port;
  }
  return false;
}
/**
 * Event listener for HTTP server "error" event.
 */
function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }
  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;
  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}
/**
 * Event listener for HTTP server "listening" event.
 */
function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}

+ 62 - 0
config.js

@ -0,0 +1,62 @@
"use strict";
var mysql_wlyy_cfg =
{
	host : '172.19.103.77',
	user : 'root',
	password : '123456',
	database : 'wlyy',
	connectionLimit : '50'
};
var mysql_im_cfg =
{
	host : '172.19.103.77',
	user : 'root',
	password : '123456',
	database : 'im_new',
	connectionLimit : '50'
};
//企业版的推送App配置
var getui_cfg =
{
	//http
	//HOST : 'http://sdk.open.api.igexin.com/apiex.htm',
	//https
	HOST : 'https://api.getui.com/apiex.htm',
	APPID : 'qWmRh2X88l7HuE36z3qBe8',
	APPKEY : 'EzERfV8c849lBkZqHWzQG1',
	MASTERSECRET : 'veXiajQrId6iojy7Qv8kZ2'
};
//AppStore版的推送App配置
var getui_appstore_cfg =
{
	//http
	//HOST : 'http://sdk.open.api.igexin.com/apiex.htm',
	//https
	HOST : 'https://api.getui.com/apiex.htm',
	APPID : 'H6FYbDejks6VjMmW3uH7V6',
	APPKEY : '0PFWlKmLBN9YzhCfFWVgYA',
	MASTERSECRET : 'pvjCGtRZJx9SRVODkxc816'
};
var app_serer_cfg =
{
	hostname: '172.19.103.87',
	port: 9090,
	path: '/wlyy/doctor/message/amount',
	method: 'POST'
};
exports.app = 'push_server';
exports.version = '1.0.5.20160922';
exports.debug = true;
exports.http_port = 3000;
exports.session_expire = 1800;// s
exports.mysql_wlyy_cfg = mysql_wlyy_cfg;
exports.mysql_im_cfg = mysql_im_cfg;
exports.getui_cfg = getui_cfg;
exports.getui_appstore_cfg = getui_appstore_cfg;
exports.app_serer_cfg = app_serer_cfg;

+ 39 - 0
config_pro.js

@ -0,0 +1,39 @@
"use strict";
var mysql_wlyy_cfg =
{
	host : '59.61.92.94',
	user : 'wlyy',
	password : 'jkzlehr@123',
	database : 'wlyy',
	connectionLimit : '100'
};
var mysql_im_cfg =
{
	host : 'localhost',
	user : 'root',
	password : '19991120',
	database : 'im_new',
	connectionLimit : '100'
};
var getui_cfg =
{
	//http
	//HOST : 'http://sdk.open.api.igexin.com/apiex.htm',
	//https
	HOST : 'https://api.getui.com/apiex.htm',
	APPID : 'qWmRh2X88l7HuE36z3qBe8',
	APPKEY : 'EzERfV8c849lBkZqHWzQG1',
	MASTERSECRET : 'veXiajQrId6iojy7Qv8kZ2'
};
exports.app = 'push_server';
exports.version = '1.0.2.20160805';
exports.debug = true;
exports.http_port = 3000;
exports.session_expire = 1800;// s
exports.mysql_wlyy_cfg = mysql_wlyy_cfg;
exports.mysql_im_cfg = mysql_im_cfg;
exports.getui_cfg = getui_cfg;

+ 39 - 0
config_test.js

@ -0,0 +1,39 @@
"use strict";
var mysql_wlyy_cfg =
{
	host : '120.41.251.85',
	user : 'root',
	password : 't_s_6_7$1',
	database : 'wlyy_test',
	connectionLimit : '100'
};
var mysql_im_cfg =
{
	host : 'localhost',
	user : 'root',
	password : '19991120',
	database : 'im_test',
	connectionLimit : '100'
};
var getui_cfg =
{
	//http
	//HOST : 'http://sdk.open.api.igexin.com/apiex.htm',
	//https
	HOST : 'https://api.getui.com/apiex.htm',
	APPID : 'qWmRh2X88l7HuE36z3qBe8',
	APPKEY : 'EzERfV8c849lBkZqHWzQG1',
	MASTERSECRET : 'veXiajQrId6iojy7Qv8kZ2'
};
exports.app = 'push_server';
exports.version = '1.0.2.20160805';
exports.debug = true;
exports.http_port = 3030;
exports.session_expire = 1800;// s
exports.mysql_wlyy_cfg = mysql_wlyy_cfg;
exports.mysql_im_cfg = mysql_im_cfg;
exports.getui_cfg = getui_cfg;

+ 14 - 0
db/mysql_im.js

@ -0,0 +1,14 @@
"use strict";
var mysql = require('mysql');
var mysqldb = require('./mysqldb');
var config = require('../config');
var pool = mysql.createPool(config.mysql_im_cfg);
/**
 * 执行查询
 */
exports.execQuery = function(options) {
	mysqldb.execQuery(pool, options);
};

+ 14 - 0
db/mysql_wlyy.js

@ -0,0 +1,14 @@
"use strict";
var mysql = require('mysql');
var mysqldb = require('./mysqldb');
var config = require('../config');
var pool = mysql.createPool(config.mysql_wlyy_cfg);
/**
 * 执行查询
 */
exports.execQuery = function(options) {
	mysqldb.execQuery(pool, options);
};

+ 54 - 0
db/mysqldb.js

@ -0,0 +1,54 @@
"use strict";
var config = require('../config');
var log = require('../util/log');
/**
 * 执行查询
 */
exports.execQuery = function(pool, options) {
	pool.getConnection(function(err, connection) {
		// 查询参数
		var sql = options['sql'];
		var args = options['args'];
		var handler = options['handler'];
		
		if(err) {
			log.error('db-getConnection err:' + err);
			handler(err, 'db-getConnection');
			return;
		}
		// 执行查询
		if (!args) {
			var query = connection.query(sql, function(err, results) {
				if(err) {
					log.error('db-query err:' + err);
					handler(err, results);
					return;
				}
				// 处理结果
				handler(err, results);
			});
		}else {
			var query = connection.query(sql, args, function(err, results) {
				if(err) {
					log.error('db-query err:' + err);
					handler(err, results);
					return;
				}
				// 处理结果
				handler(err, results);
			});
		}
		// 返回连接池
		connection.release(function(err) {
			if(error) {
				log.error('db-release err:' + err);
			}
		});
	});
};

+ 62 - 0
models/msg_group.js

@ -0,0 +1,62 @@
"use strict";
var log = require('../util/log');
var mysql_wlyy = require("../db/mysql_wlyy");
var mysql_im = require("../db/mysql_im");
function isGroupUser(user_id, group_id, group_type, handler) {
	if (group_type == 1) {
		mysql_wlyy.execQuery({
			"sql": "SELECT doctor_code from wlyy_admin_team_member WHERE team_id=? and doctor_code=?",
			"args": [group_id, user_id],
			"handler": handler
		});
	} else {
		mysql_wlyy.execQuery({
			"sql": "SELECT member_code from wlyy_talk_group_member WHERE group_code=? and member_code=?",
			"args": [group_id, user_id],
			"handler": handler
		});
	}
}
function getGroupUsers(group_id, group_type, handler) {
	if (group_type == 1) {
		mysql_wlyy.execQuery({
			"sql": "SELECT doctor_code from wlyy_admin_team_member WHERE team_id=?",
			"args": [group_id],
			"handler": handler
		});
	} else {
		mysql_wlyy.execQuery({
			"sql": "SELECT member_code from wlyy_talk_group_member WHERE group_code=?",
			"args": [group_id],
			"handler": handler
		});
	}
}
function saveGroupMsg(user_id, group_id, at_uid, type, content, handler) {
	mysql_im.execQuery({
		"sql": "INSERT INTO msg_group (to_gid,from_uid,at_uid,type,content) VALUES (?,?,?,?,?)",
		"args": [group_id, user_id, at_uid, type, content],
		"handler": handler
	});
}
function getGroupMsg(group_id, start, count, handler) {
	var sql = "SELECT from_uid,at_uid,type,content,timestamp from msg_group WHERE to_gid = ? GROUP BY timestamp DESC LIMIT ";
	sql += start;
	sql += ",";
	sql += count;
	mysql_im.execQuery({
		"sql": sql,
		"args": [group_id],
		"handler": handler
	});
}
exports.isGroupUser = isGroupUser;
exports.getGroupUsers = getGroupUsers;
exports.saveGroupMsg = saveGroupMsg;
exports.getGroupMsg = getGroupMsg;

+ 37 - 0
models/msg_p2p.js

@ -0,0 +1,37 @@
"use strict";
var log = require('../util/log');
var mysql_wlyy = require("../db/mysql_wlyy");
var mysql_im = require("../db/mysql_im");
function isUserExist(to_uid, handler) {
	mysql_wlyy.execQuery({
		"sql": "SELECT count(*) from wlyy_doctor WHERE code=?",
		"args": [to_uid],
		"handler": handler
	});
}
function saveP2PMsg(to_uid, from_uid, type, content, handler) {
	mysql_im.execQuery({
		"sql": "INSERT INTO msg_p2p (to_uid,from_uid,type,content) VALUES (?,?,?,?)",
		"args": [to_uid, from_uid, type, content],
		"handler": handler
	});
}
function getP2PMsg(to_uid, from_uid, start, count, handler) {
	var sql = "SELECT to_uid,from_uid,type,content,timestamp from msg_p2p WHERE (to_uid=? AND from_uid=?) OR (to_uid=? AND from_uid=?) GROUP BY timestamp DESC LIMIT ";
	sql += start;
	sql += ",";
	sql += count;
	mysql_im.execQuery({
		"sql": sql,
		"args": [to_uid, from_uid, from_uid, to_uid],
		"handler": handler
	});
}
exports.isUserExist = isUserExist;
exports.saveP2PMsg = saveP2PMsg;
exports.getP2PMsg = getP2PMsg;

+ 223 - 0
models/msg_statistic.js

@ -0,0 +1,223 @@
"use strict";
var log = require('../util/log');
var mysql_wlyy = require("../db/mysql_wlyy");
var mysql_im = require("../db/mysql_im");
var config = require("../config");
var http = require('http');
var qs = require('querystring');
var async = require('async');
function updateGroupChatInfo(user_id, group_id, from_uid, at_me, type, content, msg_count_plus_one, handler) {
	var uuid = user_id + '_' + group_id;
    if (msg_count_plus_one) {
        mysql_im.execQuery({
            "sql": "INSERT INTO msg_statistic (uid,uuid,from_uid,from_gid,at_me,msg_type,last_content_type,last_content,new_msg_count) VALUES (?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE from_uid=?,at_me=?,last_content_type=?,last_content=?,new_msg_count=new_msg_count+1",
            "args": [user_id, uuid, from_uid, group_id, at_me, 2, type, content, 1, from_uid, at_me, type, content],
            "handler": handler
        });
    } else {
        mysql_im.execQuery({
            "sql": "INSERT INTO msg_statistic (uid,uuid,from_uid,from_gid,at_me,msg_type,last_content_type,last_content,new_msg_count) VALUES (?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE from_uid=?,at_me=?,last_content_type=?,last_content=?",
            "args": [user_id, uuid, from_uid, group_id, at_me, 2, type, content, 0, from_uid, at_me, type, content],
            "handler": handler
        });
    }
}
function updateP2PChatInfo(user_id, peer_uid, from_uid, type, content, handler) {
    var uuid = user_id + '_' + peer_uid;
    if (user_id == from_uid) {
        // 更新自身的统计信息
        mysql_im.execQuery({
            "sql": "INSERT INTO msg_statistic (uid,uuid,from_uid,peer_uid,msg_type,last_content_type,last_content,new_msg_count) VALUES (?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE peer_uid=?,last_content_type=?,last_content=?",
            "args": [user_id, uuid, from_uid, peer_uid, 1, type, content, 0, peer_uid, type, content],
            "handler": handler
        });
    } else {
        // 更新对端的统计信息
        mysql_im.execQuery({
            "sql": "INSERT INTO msg_statistic (uid,uuid,from_uid,peer_uid,msg_type,last_content_type,last_content,new_msg_count) VALUES (?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE peer_uid=?,last_content_type=?,last_content=?,new_msg_count=new_msg_count+1",
            "args": [user_id, uuid, from_uid, peer_uid, 1, type, content, 1, peer_uid, type, content],
            "handler": handler
        });
    }
}
function clearGroupChatInfo(user_id, group_id, handler) {
	var uuid = user_id + '_' + group_id;
	mysql_im.execQuery({
		"sql": "UPDATE msg_statistic SET new_msg_count='0' WHERE uuid=?",
		"args": [uuid],
		"handler": handler
	});
}
function clearP2PChatInfo(user_id, peer_uid, handler) {
	var uuid = user_id + '_' + peer_uid;
	mysql_im.execQuery({
		"sql": "UPDATE msg_statistic SET new_msg_count='0' WHERE uuid=?",
		"args": [uuid],
		"handler": handler
	});
}
function getGroupChatInfo(user_id, group_id, handler) {
	var uuid = user_id + '_' + group_id;
	mysql_im.execQuery({
		"sql": "SELECT uid,from_uid,from_gid,at_me,last_content_type,last_content,new_msg_count,timestamp from msg_statistic WHERE uuid = ?",
		"args": [uuid],
		"handler": handler
	});
}
function getP2PChatInfo(user_id, peer_uid, handler) {
	var uuid = user_id + '_' + peer_uid;
	mysql_im.execQuery({
		"sql": "SELECT uid,from_uid,last_content_type,last_content,new_msg_count,timestamp from msg_statistic WHERE uuid = ?",
		"args": [uuid],
		"handler": handler
	});
}
function getChatList(user_id, handler) {
    mysql_im.execQuery({
        "sql": "SELECT uid,from_uid,from_gid,peer_uid,at_me,msg_type,last_content_type,last_content,new_msg_count,timestamp from msg_statistic WHERE uid = ?",
        "args": [user_id],
        "handler": handler
    });
}
function getGroupChatAllUnRead(user_id, handler) {
	mysql_im.execQuery({
		"sql": "SELECT new_msg_count from msg_statistic WHERE uid=? AND msg_type=2 AND new_msg_count>0",
		"args": [user_id],
		"handler": handler
	});
}
function getP2PChatAllUnRead(user_id, handler) {
	mysql_im.execQuery({
		"sql": "SELECT new_msg_count from msg_statistic WHERE uid=? AND msg_type=1 AND new_msg_count>0",
		"args": [user_id],
		"handler": handler
	});
}
function getChatAllUnRead(user_id, handler) {
	mysql_im.execQuery({
		"sql": "SELECT new_msg_count from msg_statistic WHERE uid=? AND new_msg_count>0",
		"args": [user_id],
		"handler": handler
	});
}
function getAppMsgAmount(user_id, handler) {
    mysql_wlyy.execQuery({
        "sql": "SELECT imei,token from wlyy_token WHERE user=?",
        "args": [user_id],
        "handler": function(err, result) {
            if (err) {
                handler(null, 0);
                return;
            }
            if (result.length == 0) {
                handler(null, 0);
                return;
            }
            var options = {
                hostname: config.app_serer_cfg.hostname,
                port: config.app_serer_cfg.port,
                path: config.app_serer_cfg.path,
                method: config.app_serer_cfg.method,
                headers: {
                    'userAgent': '{"token":"'+ result[0].token +'","uid":"'+ user_id +'","imei":"'+ result[0].imei +'"}'
                }
            };
            var req = http.request(options, function (res) {
                res.setEncoding('utf8');
                res.on('data', function (chunk) {
                    console.log('BODY: ' + chunk);
                    var data = JSON.parse(chunk);
                    handler(null, data);
                });
            });
            req.on('error', function (e) {
                console.log('problem with request: ' + e.message);
                handler(e, null);
            });
            req.end();
        }
    });
}
function getBadgeNumber(user_id, handler) {
    async.parallel([
            function(callback) {
                // 此版本app界面未显示im的未读条数
                callback(null, 0);
                /*
                getChatAllUnRead(user_id, function(err, result) {
                    if (err) {
                        callback(null, 0);
                        return;
                    }
                    if (result.length == 0) {
                        callback(null, 0);
                        return;
                    }
                    var count = 0;
                    var index = 0;
                    var length = result.length;
                    for (; index < length; index++) {
                        count += result[index].new_msg_count;
                    }
                    callback(null, count);
                });
                */
            },
            function(callback) {
                getAppMsgAmount(user_id, function(err, result) {
                    if (err) {
                        callback(null, 0);
                    } else {
                        var count = 0;
                        try {
                            count += result.data.healthIndex;
                            count += result.data.sign;
                            count += result.data.consultTeam;
                            callback(null, count);
                        } catch (e) {
                            callback(null, 0);
                        }
                    }
                });
            }],
        function(err, results) {
            var badge = 0;
            for (var index = 0; index < results.length; index++) {
                badge += results[index];
            }
            handler(null, badge);
        });
}
exports.updateGroupChatInfo = updateGroupChatInfo;
exports.updateP2PChatInfo = updateP2PChatInfo;
exports.clearGroupChatInfo = clearGroupChatInfo;
exports.clearP2PChatInfo = clearP2PChatInfo;
exports.getGroupChatInfo = getGroupChatInfo;
exports.getP2PChatInfo = getP2PChatInfo;
exports.getChatList = getChatList;
exports.getGroupChatAllUnRead = getGroupChatAllUnRead;
exports.getP2PChatAllUnRead = getP2PChatAllUnRead;
exports.getChatAllUnRead = getChatAllUnRead;
exports.getAppMsgAmount = getAppMsgAmount;
exports.getBadgeNumber = getBadgeNumber;

+ 14 - 0
models/msg_system.js

@ -0,0 +1,14 @@
"use strict";
var log = require('../util/log');
var mysql_im = require("../db/mysql_im");
function saveSystemMsg(to_uid, type, title, content, data, handler) {
    mysql_im.execQuery({
        "sql": "INSERT INTO msg_system (to_uid,type,title,content,data) VALUES (?,?,?,?,?)",
        "args": [to_uid, type, title, content, data],
        "handler": handler
    });
}
exports.saveSystemMsg = saveSystemMsg;

+ 14 - 0
models/push_notify.js

@ -0,0 +1,14 @@
"use strict";
var log = require('../util/log');
var mysql_im = require("../db/mysql_im");
function savePushNotify(to_uid, type, title, content, data, has_pushed, handler) {
    mysql_im.execQuery({
        "sql": "INSERT INTO push_notify (to_uid,type,title,content,data,has_pushed) VALUES (?,?,?,?,?,?)",
        "args": [to_uid, type, title, content, data, has_pushed],
        "handler": handler
    });
}
exports.savePushNotify = savePushNotify;

+ 50 - 0
models/user.js

@ -0,0 +1,50 @@
"use strict";
var log = require('../util/log');
var mysql_im = require("../db/mysql_im");
function login(user_id, token, client_id, platform, handler) {
    mysql_im.execQuery({
        "sql": "INSERT INTO user (user_id,token,client_id,platform,is_online,status) VALUES (?,?,?,?,1,1) ON DUPLICATE KEY UPDATE token=?,client_id=?,platform=?,is_online=1,status=1",
        "args": [user_id, token, client_id, platform, token, client_id, platform],
        "handler": handler
    });
}
function logout(user_id, handler) {
    mysql_im.execQuery({
        "sql": "UPDATE user SET is_online='0',status='0' WHERE user_id=?",
        "args": [user_id],
        "handler": handler
    });
}
function getUserbyID(user_id, handler) {
    mysql_im.execQuery({
        "sql": "SELECT platform,token,client_id,is_online,status from user WHERE user_id = ?",
        "args": [user_id],
        "handler": handler
    });
}
function deleteToken(token, handler) {
    mysql_im.execQuery({
        "sql": "DELETE FROM user WHERE token=?",
        "args": [token],
        "handler": handler
    });
}
function updateStatus(user_id, status, handler) {
    mysql_im.execQuery({
        "sql": "UPDATE user SET status=? WHERE user_id=?",
        "args": [status, user_id],
        "handler": handler
    });
}
exports.login = login;
exports.logout = logout;
exports.getUserbyID = getUserbyID;
exports.deleteToken = deleteToken;
exports.updateStatus = updateStatus;

+ 79 - 0
mysql_db/im.sql

@ -0,0 +1,79 @@
/*
Navicat MySQL Data Transfer
Source Server         : wjw(im)
Source Server Version : 50549
Source Host           : localhost:3306
Source Database       : im
Target Server Type    : MYSQL
Target Server Version : 50549
File Encoding         : 65001
Date: 2016-07-19 20:56:59
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `group_msg`
-- ----------------------------
DROP TABLE IF EXISTS `group_msg`;
CREATE TABLE `group_msg` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `group_id` varchar(255) NOT NULL COMMENT '组ID',
  `from_uid` varchar(255) NOT NULL COMMENT '消息发送者ID',
  `type` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '消息类型:1文本,2图片,3语音',
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '消息发送时间',
  `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '消息内容',
  PRIMARY KEY (`id`),
  KEY `group_id` (`group_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=77 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of group_msg
-- ----------------------------
-- ----------------------------
-- Table structure for `push_notify`
-- ----------------------------
DROP TABLE IF EXISTS `push_notify`;
CREATE TABLE `push_notify` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` varchar(255) NOT NULL COMMENT '用户ID',
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '推送消息时间戳',
  `type` varchar(255) NOT NULL DEFAULT '' COMMENT '消息类',
  `title` varchar(255) NOT NULL COMMENT '消息标题',
  `content` varchar(255) NOT NULL COMMENT '消息内容',
  `data` varchar(255) NOT NULL DEFAULT '' COMMENT '消息内容',
  `has_pushed` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否已经推送:0未推送,1已推送',
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=186 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of push_notify
-- ----------------------------
INSERT INTO `push_notify` VALUES ('183', 'D20160322000002', '2016-07-19 20:56:05', 'D_CT_01', '指定咨询', '您有新的指定咨询', 'e0370b70f3d74a8ea4aa40e0010cdca2', '0');
INSERT INTO `push_notify` VALUES ('184', 'D20160322000002', '2016-07-19 20:56:25', 'D_CT_02', '指定咨询', '您有新的消息', 'e0370b70f3d74a8ea4aa40e0010cdca2', '0');
INSERT INTO `push_notify` VALUES ('185', 'D20160322000002', '2016-07-19 20:56:42', 'D_CT_02', '指定咨询', '您有新的消息', 'e0370b70f3d74a8ea4aa40e0010cdca2', '0');
-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` varchar(255) NOT NULL COMMENT '用户ID',
  `platform` tinyint(1) NOT NULL DEFAULT '0' COMMENT '平台:0为ios,1为android',
  `token` varchar(255) NOT NULL DEFAULT '' COMMENT '个推的token',
  `client_id` varchar(255) NOT NULL DEFAULT '' COMMENT '个推的clientid',
  `is_online` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否在线:0离线,1在线',
  `timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=69 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------

+ 18 - 0
package.json

@ -0,0 +1,18 @@
{
  "name": "app_ldap",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "body-parser": "~1.12.4",
    "cookie-parser": "~1.3.5",
    "debug": "~2.2.0",
    "express": "~4.12.4",
    "jade": "~1.9.2",
    "morgan": "~1.5.3",
    "serve-favicon": "~2.2.1",
    "async": "~2.0.1"
  }
}

+ 8 - 0
public/stylesheets/style.css

@ -0,0 +1,8 @@
body {
  padding: 50px;
  font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a {
  color: #00B7FF;
}

+ 48 - 0
routes/index.js

@ -0,0 +1,48 @@
var express = require('express');
var router = express.Router();
var log = require('../util/log');
var mysql_wlyy = require("../db/mysql_wlyy");
var mysql_im = require("../db/mysql_im");
function getWlyyTables(handler) {
  mysql_wlyy.execQuery({
    "sql": "SELECT table_name FROM information_schema.TABLES",
    "args": [],
    "handler": handler
  });
}
function getImTables(handler) {
  mysql_im.execQuery({
    "sql": "SELECT table_name FROM information_schema.TABLES",
    "args": [],
    "handler": handler
  });
}
/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});
router.get('/wlyy_db.im', function(req, res, next) {
  getWlyyTables(function(err, result) {
    if (err) {
      res.send({errno: -1, errmsg: 'open wlyy db error'});
    } else {
      res.send({errno: 0, errmsg: 'open wlyy db success'});
    }
  });
});
router.get('/im_db.im', function(req, res, next) {
  getImTables(function(err, result) {
    if (err) {
      res.send({errno: -1, errmsg: 'open im db error'});
    } else {
      res.send({errno: 0, errmsg: 'open im db success'});
    }
  });
});
module.exports = router;

+ 240 - 0
routes/msg_group.js

@ -0,0 +1,240 @@
var express = require('express');
var router = express.Router();
var msg_group = require("../models/msg_group");
var msg_statistic = require("../models/msg_statistic");
var user = require("../models/user");
var push = require("../models/push_notify");
var http = require('http');
var qs = require('querystring');
var getui = require('getui');
/**
 * 群组消息:group/sendmsg.im?from_uid=x&to_gid=xx&content=xxx&type=1&at_uid=xxxx&group_type
 * 参数:
 * from_uid:发送者id
 * to_gid:群组id
 * content:消息内容
 * type:消息类型:1文本,2图片,3语音
 * at_uid:@用户id:1为行政组,null或者其他值为自定义组
 * group_type:区分是行政组还是自定义组,从不同表中查找组成员
 */
router.get('/sendmsg.im', function (req, res, next) {
    if (req.query.from_uid == null
        || req.query.to_gid == null
        || req.query.content == null
        || req.query.type == null) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    msg_group.isGroupUser(req.query.from_uid, req.query.to_gid, req.query.group_type, function (err, result) {
        if (err) {
            res.send({errno: 1, errmsg: 'get users from db error'});
            return;
        }
        if (result.length == 0) {
            res.send({errno: 2, errmsg: 'no receive users'});
            return;
        }
        var at_uid = '';
        if (req.query.at_uid != null) {
            at_uid = req.query.at_uid;
        }
        // 保存群组消息
        msg_group.saveGroupMsg(req.query.from_uid, req.query.to_gid, at_uid, req.query.type, req.query.content, function (err, result) {
            if (err) {
                res.send({errno: 3, errmsg: 'save msg to db error'});
                return;
            }
            res.send({errno: 0, errmsg: 'send group msg success'});
            // 统计信息
            msg_statistic.updateGroupChatInfo(req.query.from_uid,
                req.query.to_gid,
                req.query.from_uid,
                0,
                req.query.type,
                req.query.content,
                false,
                function (err, result) {
                    if (err) {
                        console.log(err);
                    }
                });
            // 推送通知消息给群组各成员
            msg_group.getGroupUsers(req.query.to_gid, req.query.group_type, function (err, result) {
                if (err) {
                    console.log('get users from db error');
                    return;
                }
                if (result.length == 0) {
                    console.log('no receive users');
                    return;
                }
                // 推送通知
                for (var nIndex = 0; nIndex < result.length; nIndex++) {
                    if (result[nIndex].member_code == req.query.from_uid) {
                        continue;
                    }
                    (function () {
                        var toUserID = result[nIndex].member_code;
                        user.getUserbyID(toUserID, function (err, result) {
                            var tmp = toUserID;
                            if (err) {
                                console.log('group msg:get user by id from db failed');
                                return;
                            }
                            var title = '';
                            var content = '';
                            if (req.query.type == 1) {
                                title = '群组消息';
                                content = req.query.content;
                            } else if (req.query.type == 2) {
                                title = '群组消息';
                                content = '接收到 [图片]';
                            } else if (req.query.type == 3) {
                                title = '群组消息';
                                content = '接收到 [语音]';
                            } else {
                                title = '群组消息';
                                content = '接收到一条新消息';
                            }
                            var bMustPush = 0;
                            var data;
                            if (result.length > 0) {
                                data = result[0];
                                if (data.is_online) {
                                    bMustPush = 1;
                                }
                            }
                            var push_data = JSON.stringify({
                                type:'group_msg',
                                gid:req.query.to_gid
                            });
                            // 保存通知到数据库中
                            push.savePushNotify(toUserID,
                                req.query.type,
                                title,
                                content,
                                push_data,
                                bMustPush,
                                function (err, result) {
                                    if (err) {
                                        // 保存失败
                                        console.log('save msg to db failed');
                                    } else {
                                        console.log('save msg to db success');
                                        if (bMustPush == true) {
                                            if (data.platform == 0) {// iOS
                                                getui.pushAPN(toUserID,
                                                    data.token,
                                                    req.query.type,
                                                    title,
                                                    content,
                                                    push_data,
                                                    function (err, result) {
                                                        if (err != null) {
                                                            console.log(err);
                                                        } else {
                                                            console.log(result);
                                                        }
                                                    });
                                            } else {// Android
                                                getui.pushAndroid(data.client_id,
                                                    req.query.type,
                                                    title,
                                                    content,
                                                    push_data,
                                                    data.status,
                                                    function (err, result) {
                                                        if (err != null) {
                                                            console.log(err);
                                                        } else {
                                                            console.log(result);
                                                        }
                                                    });
                                            }
                                        }
                                    }
                                });
                        });
                        // 统计信息
                        var at_me = 0;
                        if (at_uid == toUserID) {
                            at_me = 1;
                        }
                        msg_statistic.updateGroupChatInfo(toUserID,
                            req.query.to_gid,
                            req.query.from_uid,
                            at_me,
                            req.query.type,
                            req.query.content,
                            true,
                            function (err, result) {
                                if (err) {
                                    console.log(err);
                                }
                            });
                    })();
                }
            });
        });
    });
});
/**
 * 群组消息:group/getmsg.im?uid=x&gid=xx&start=0&count=20
 * 参数:
 * uid:用户id
 * gid:群组id
 * start;分页查询起始条目
 * count:查询条数
 * 备注:按时间倒序
 */
router.get('/getmsg.im', function (req, res, next) {
    if (req.query.uid == null
        || req.query.gid == null
        || req.query.start == null
        || req.query.count == null) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    msg_group.getGroupMsg(req.query.gid, req.query.start, req.query.count, function (err, result) {
        if (err) {
            res.send({errno: 1, errmsg: 'get group msg from db error'});
            return;
        }
        var data = {};
        data.start = parseInt(req.query.start);
        data.count = result.length;
        data.list = new Array();
        for (var nIndex = 0; nIndex < result.length; nIndex++) {
            result[nIndex].timestamp = Date.parse(new Date(result[nIndex].timestamp));
            data.list.push(result[nIndex]);
        }
        res.send(data);
        // 清空统计信息
        msg_statistic.clearGroupChatInfo(req.query.uid,
            req.query.gid,
            function (err, result) {
                if (err) {
                    console.log(err);
                }
            });
    });
});
module.exports = router;

+ 199 - 0
routes/msg_p2p.js

@ -0,0 +1,199 @@
var express = require('express');
var router = express.Router();
var msg_p2p = require("../models/msg_p2p");
var msg_statistic = require("../models/msg_statistic");
var user = require("../models/user");
var push = require("../models/push_notify");
var getui = require('getui');
/**
 * 一对一消息:p2p/sendmsg.im?from_uid=x&to_uid=xx&content=xxx&type=1
 * 参数:
 * from_uid:发送者id
 * to_uid:接收者id
 * content:消息内容
 * type:消息类型:1文本,2图片,3语音
 */
router.get('/sendmsg.im', function (req, res, next) {
    if (req.query.from_uid == null
        || req.query.to_uid == null
        || req.query.content == null
        || req.query.type == null) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    msg_p2p.isUserExist(req.query.to_uid, function (err, result) {
        if (err) {
            res.send({errno: 1, errmsg: 'get users from db error'});
            return;
        }
        if (result.length == 0) {
            res.send({errno: 2, errmsg: 'no receive users'});
            return;
        }
        // 保存一对一消息
        msg_p2p.saveP2PMsg(req.query.to_uid, req.query.from_uid, req.query.type, req.query.content, function (err, result) {
            if (err) {
                res.send({errno: 3, errmsg: 'save msg to db error'});
                return;
            }
            res.send({errno: 0, errmsg: 'send p2p msg success'});
            // 更新自身的聊天统计信息
            msg_statistic.updateP2PChatInfo(req.query.from_uid,
                req.query.to_uid,
                req.query.from_uid,
                req.query.type,
                req.query.content,
                function (err, result) {
                    if (err) {
                        console.log(err);
                    }
                });
            // 更新对端的聊天统计信息
            msg_statistic.updateP2PChatInfo(req.query.to_uid,
                req.query.from_uid,
                req.query.from_uid,
                req.query.type,
                req.query.content,
                function (err, result) {
                    if (err) {
                        console.log(err);
                    }
                });
            // 推送通知消息给对端
            user.getUserbyID(req.query.to_uid, function (err, result) {
                if (err) {
                    console.log('group msg:get user by id from db failed');
                    return;
                }
                var title = '';
                var content = '';
                if (req.query.type == 1) {
                    title = '新消息';
                    content = req.query.content;
                } else if (req.query.type == 2) {
                    title = '新消息';
                    content = '接收到 [图片]';
                } else if (req.query.type == 3) {
                    title = '新消息';
                    content = '接收到 [语音]';
                } else {
                    title = '新消息';
                    content = '接收到一条新消息';
                }
                var bMustPush = 0;
                var data;
                if (result.length > 0) {
                    data = result[0];
                    if (data.is_online) {
                        bMustPush = 1;
                    }
                }
                var push_data = JSON.stringify({
                    type:'p2p_msg',
                    from_uid:req.query.from_uid
                });
                // 保存通知到数据库中
                push.savePushNotify(req.query.to_uid,
                    req.query.type,
                    title,
                    content,
                    push_data,
                    bMustPush,
                    function (err, result) {
                        if (err) {
                            // 保存失败
                            console.log('save msg to db failed');
                        } else {
                            console.log('save msg to db success');
                            if (bMustPush == true) {
                                if (data.platform == 0) {// iOS
                                    getui.pushAPN(req.query.to_uid,
                                        data.token,
                                        req.query.type,
                                        title,
                                        content,
                                        push_data,
                                        function (err, result) {
                                            if (err != null) {
                                                console.log(err);
                                            } else {
                                                console.log(result);
                                            }
                                        });
                                } else {// Android
                                    getui.pushAndroid(data.client_id,
                                        req.query.type,
                                        title,
                                        content,
                                        push_data,
                                        data.status,
                                        function (err, result) {
                                            if (err != null) {
                                                console.log(err);
                                            } else {
                                                console.log(result);
                                            }
                                        });
                                }
                            }
                        }
                    });
            });
        });
    });
});
/**
 * 一对一消息:p2p/getmsg.im?uid=x&peer_uid=xx&start=0&count=20
 * 参数:
 * uid:用户id
 * peer_uid:对端id
 * start;分页查询起始条目
 * count:查询条数
 * 备注:按时间倒序
 */
router.get('/getmsg.im', function (req, res, next) {
    if (req.query.uid == null
        || req.query.peer_uid == null
        || req.query.start == null
        || req.query.count == null) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    msg_p2p.getP2PMsg(req.query.uid, req.query.peer_uid, req.query.start, req.query.count, function (err, result) {
        if (err) {
            res.send({errno: 1, errmsg: 'get group msg from db error'});
            return;
        }
        var data = {};
        data.start = parseInt(req.query.start);
        data.count = result.length;
        data.list = new Array();
        for (var nIndex = 0; nIndex < result.length; nIndex++) {
            result[nIndex].timestamp = Date.parse(new Date(result[nIndex].timestamp));
            data.list.push(result[nIndex]);
        }
        res.send(data);
        // 清空统计信息
        msg_statistic.clearP2PChatInfo(req.query.uid,
            req.query.peer_uid,
            function (err, result) {
                if (err) {
                    console.log(err);
                }
            });
    });
});
module.exports = router;

+ 220 - 0
routes/msg_statistic.js

@ -0,0 +1,220 @@
var express = require('express');
var router = express.Router();
var msg_statistic = require("../models/msg_statistic");
/**
 * 群组消息统计:statistic/getgroupchatinfo.im?uid=x&gid=xx
 * 参数:
 * uid:信息所有者id
 * gid:群组id
 */
router.get('/getgroupchatinfo.im', function (req, res, next) {
    if (req.query.uid == null
        || req.query.gid == null) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    msg_statistic.getGroupChatInfo(req.query.uid, req.query.gid, function (err, result) {
        if (err) {
            res.send({errno: 1, errmsg: 'get statistic from db error'});
            return;
        }
        if (result.length == 0) {
            var data = {"uid":req.query.uid,"from_uid":"","from_gid":req.query.gid,"at_me":0,"last_content_type":1,"last_content":"","new_msg_count":0,"timestamp":0};
            res.send(data);
            return;
        }
        result[0].timestamp = Date.parse(new Date(result[0].timestamp));
        res.send(result[0]);
    });
});
/**
 * 一对一聊天消息统计:statistic/getp2pchatinfo.im?uid=x&peer_uid=xx
 * 参数:
 * uid:信息所有者id
 * peer_uid:聊天对端id
 */
router.get('/getp2pchatinfo.im', function (req, res, next) {
    if (req.query.uid == null
        || req.query.peer_uid == null) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    msg_statistic.getP2PChatInfo(req.query.uid, req.query.peer_uid, function (err, result) {
        if (err) {
            res.send({errno: 1, errmsg: 'get statistic from db error'});
            return;
        }
        if (result.length == 0) {
            var data = {"uid":req.query.uid,"from_uid":req.query.peer_uid,"last_content_type":1,"last_content":"","new_msg_count":0,"timestamp":0};
            res.send(data);
            return;
        }
        result[0].timestamp = Date.parse(new Date(result[0].timestamp));
        res.send(result[0]);
    });
});
/**
 * 获取聊天列表:statistic/getchatlist.im?uid=x
 * 参数:
 * uid:信息所有者id
 */
router.get('/getchatlist.im', function (req, res, next) {
    if (req.query.uid == null) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    msg_statistic.getChatList(req.query.uid, function (err, result) {
        if (err) {
            res.send({errno: 1, errmsg: 'get statistic from db error'});
            return;
        }
        if (result.length == 0) {
            var data = {"uid":req.query.uid,"from_uid":req.query.peer_uid,"last_content_type":1,"last_content":"","new_msg_count":0,"timestamp":0};
            res.send(data);
            return;
        }
        //result[0].timestamp = Date.parse(new Date(result[0].timestamp));
        for (var index = 0; index < result.length; index++) {
            result[index].timestamp = Date.parse(new Date(result[index].timestamp));
        }
        res.send(result);
    });
});
/**
 * 群组聊天消息所有未读数:statistic/getgroupunreadcount.im?uid=x
 * 参数:
 * uid:信息所有者id
 */
router.get('/getgroupunreadcount.im', function (req, res, next) {
    if (req.query.uid == null) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    msg_statistic.getGroupChatAllUnRead(req.query.uid, function (err, result) {
        if (err) {
            res.send({errno: 1, errmsg: 'get statistic from db error'});
            return;
        }
        var data = {"uid":req.query.uid,"msg_type":2,"new_msg_count":0};
        if (result.length == 0) {
            res.send(data);
            return;
        }
        var count = 0;
        var index = 0;
        var length = result.length;
        for (; index < length; index++) {
            count += result[index].new_msg_count;
        }
        data.new_msg_count = count;
        res.send(data);
    });
});
/**
 * 一对一聊天消息所有未读数:statistic/getp2punreadcount.im?uid=x
 * 参数:
 * uid:信息所有者id
 */
router.get('/getp2punreadcount.im', function (req, res, next) {
    if (req.query.uid == null) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    msg_statistic.getP2PChatAllUnRead(req.query.uid, function (err, result) {
        if (err) {
            res.send({errno: 1, errmsg: 'get statistic from db error'});
            return;
        }
        var data = {"uid":req.query.uid,"msg_type":1,"new_msg_count":0};
        if (result.length == 0) {
            res.send(data);
            return;
        }
        var count = 0;
        var index = 0;
        var length = result.length;
        for (; index < length; index++) {
            count += result[index].new_msg_count;
        }
        data.new_msg_count = count;
        res.send(data);
    });
});
/**
 * 所有聊天消息未读数:statistic/getallunreadmsgcount.im?uid=x
 * 参数:
 * uid:信息所有者id
 */
router.get('/getallunreadmsgcount.im', function (req, res, next) {
    if (req.query.uid == null) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    msg_statistic.getChatAllUnRead(req.query.uid, function (err, result) {
        if (err) {
            res.send({errno: 1, errmsg: 'get statistic from db error'});
            return;
        }
        var data = {"uid":req.query.uid,"msg_type":0,"new_msg_count":0};
        if (result.length == 0) {
            res.send(data);
            return;
        }
        var count = 0;
        var index = 0;
        var length = result.length;
        for (; index < length; index++) {
            count += result[index].new_msg_count;
        }
        data.new_msg_count = count;
        res.send(data);
    });
});
/**
 * 获取角标数:statistic/getbadgenum.im?uid=x
 * 参数:
 * uid:用户id
 */
router.get('/getbadgenum.im', function (req, res, next) {
    if (req.query.uid == null) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    msg_statistic.getBadgeNumber(req.query.uid, function (err, result) {
        if (err) {
            res.send({errno: 1, errmsg: 'get badge error'});
            return;
        }
        var data = {"uid":req.query.uid,"badge":result};
        res.send(data);
    });
});
module.exports = router;

+ 111 - 0
routes/msg_system.js

@ -0,0 +1,111 @@
var express = require('express');
var router = express.Router();
var user = require("../models/user");
var msg_system = require("../models/msg_system");
var push = require("../models/push_notify");
var http = require('http');
var qs = require('querystring');
var getui = require('getui');
/**
 * 推送消息:system/sendmsg.im?to_uid=x&type=xx&title=xxx&content=xxxx&data=xxxxx
 * 参数:
 * to_uid:消息接收者ID
 * type:消息类型
 * title:消息标题
 * content:推送消息提示内容
 * data:推送消息内容
 */
router.get('/sendmsg.im', function (req, res, next) {
    if (req.query.to_uid == null
        || req.query.title == null
        || req.query.type == null
        || req.query.content == null
        || req.query.data == null) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    user.getUserbyID(req.query.to_uid, function (err, result) {
        if (err) {
            res.send({errno: 1, errmsg: 'get user by id from db failed'});
            return;
        }
        var bMustPush = 0;
        var data;
        if (result.length > 0) {
            data = result[0];
            if (data.is_online) {
                bMustPush = 1;
            }
        }
        var push_data = JSON.stringify({
            type:req.query.type,
            data:req.query.data
        });
        // 保存该条推送信息
        msg_system.saveSystemMsg(req.query.to_uid,
            req.query.type,
            req.query.title,
            req.query.content,
            req.query.data,
            function (err, result) {
                if (err) {
                    // 保存失败
                    res.send({errno: 2, errmsg: 'save msg to db failed'});
                } else {
                    // 保存通知到数据库中
                    push.savePushNotify(req.query.to_uid,
                        req.query.type,
                        req.query.title,
                        req.query.content,
                        push_data,
                        bMustPush,
                        function (err, result) {
                            if (err) {
                                // 保存失败
                                res.send({errno: 3, errmsg: 'save msg to db failed'});
                            } else {
                                res.send({errno: 0, errmsg: 'save msg to db success'});
                                if (bMustPush == true) {
                                    if (data.platform == 0) {// iOS
                                        getui.pushAPN(req.query.to_uid,
                                            data.token,
                                            req.query.type,
                                            req.query.title,
                                            req.query.content,
                                            push_data,
                                            function (err, result) {
                                                if (err != null) {
                                                    console.log(err);
                                                } else {
                                                    console.log(result);
                                                }
                                            });
                                    } else {// Android
                                        getui.pushAndroid(data.client_id,
                                            req.query.type,
                                            req.query.title,
                                            req.query.content,
                                            push_data,
                                            data.status,
                                            function (err, result) {
                                                if (err != null) {
                                                    console.log(err);
                                                } else {
                                                    console.log(result);
                                                }
                                            });
                                    }
                                }
                            }
                        });
                }
            });
    });
});
module.exports = router;

+ 90 - 0
routes/user.js

@ -0,0 +1,90 @@
var express = require('express');
var router = express.Router();
var user = require("../models/user");
var http = require('http');
var qs = require('querystring');
/**
 * 登录:/user/login.im?user_id=x&token=xx&client_id=xxx&platform=0
 * 参数:
 * user_id:用户ID
 * token:个推的token
 * client_id:个推的clientid
 * platform:平台类型:0为ios,1为android
 */
router.get('/login.im', function (req, res, next) {
    if (req.query.user_id == null
        || req.query.token == null
        || req.query.client_id == null
        || req.query.platform == null) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    user.deleteToken(req.query.token, function (err, result) {
        if (err) {
            res.send({errno: 1, errmsg: 'delete token error'});
            return;
        }
        user.login(req.query.user_id,
            req.query.token,
            req.query.client_id,
            req.query.platform,
            function (err, result) {
                if (err) {
                    res.send({errno: 2, errmsg: 'update users status error'});
                    return;
                }
                res.send({errno: 0, errmsg: 'login successful'});
            });
        });
});
/**
 * 登出:/user/logout.im?user_id=x
 * 参数:
 * user_id:用户ID
 */
router.get('/logout.im', function (req, res, next) {
    if (req.query.user_id == null) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    user.logout(req.query.user_id,
        function (err, result) {
            if (err) {
                res.send({errno: 255, errmsg: 'update users status error'});
                return;
            }
            res.send({errno: 0, errmsg: 'logout successful'});
        });
});
/**
 * 更新app状态:/user/updatestatus.im?user_id=x&status=1
 * 参数:
 * user_id:用户ID
 * status:App状态,0在后台,1在前台
 */
router.get('/updatestatus.im', function (req, res, next) {
    if (req.query.user_id == null || (req.query.status != 0 && req.query.status != 1)) {
        res.send({errno: -1, errmsg: 'parameter error'});
        return;
    }
    user.updateStatus(req.query.user_id, req.query.status,
        function (err, result) {
            if (err) {
                res.send({errno: 255, errmsg: 'update users status error'});
                return;
            }
            res.send({errno: 0, errmsg: 'update status successful'});
        });
});
module.exports = router;

+ 32 - 0
server.js

@ -0,0 +1,32 @@
var cp = require('child_process'),
    worker;
function spawn(server) {
    //进行守护,开启IPC通道,双向通信
    worker = cp.spawn('node', [ server ], {
        stdio: [ 0, 1, 2, 'ipc' ]
    });
    //监视子进程,当其崩溃时处理
    worker.on('exit', function (code) {
        if (code !== 0) {
            console.log('worker is shut down, restarting...');
            spawn(server);//重启服务
        };
    });
    //收到子进程消息
    worker.on('message', function (msg) {
        console.log(msg);
    });
};
function main() {
    spawn('./bin/www'); //要守护的进程文件
    process.on('SIGTERM', function () {
        worker.kill();
        process.exit(0);
    });
};
main();

+ 123 - 0
util/log.js

@ -0,0 +1,123 @@
"use strict";
(function () {
    var util = require('util');
    // log level
    var LEVEL = {
        ALL:Infinity,
        INFO:3,
        WARN:2,
        ERROR:1,
        NONE:-Infinity
    };
    // log color
    var COLOR = {
        RESET:'\u001b[0m',
        INFO:'\u001b[32m', // green
        WARN:'\u001b[33m', // yellow
        ERROR:'\u001b[31m' // red
    }
    // global log level
    var globalLevel = LEVEL.ALL;
    // whether log output should be colored
    var coloredOutput = true;
    function setLevel(level) {
        globalLevel = level;
    }
    function setColoredOutput(bool) {
        coloredOutput = bool;
    }
    function info() {
        if (LEVEL.INFO <= globalLevel) {
            log(LEVEL.INFO, util.format.apply(this, arguments));
        }
    }
    function warn() {
        if (LEVEL.WARN <= globalLevel) {
            log(LEVEL.WARN, util.format.apply(this, arguments));
        }
    }
    function error() {
        if (LEVEL.ERROR <= globalLevel) {
            log(LEVEL.ERROR, util.format.apply(this, arguments));
        }
    }
    function newPrepareStackTrace(error, structuredStack) {
        return structuredStack;
    }
    // must not be called directly due to stack trace
    function log(level, message) {
        // get call stack and find the caller
        var oldPrepareStackTrace = Error.prepareStackTrace;
        Error.prepareStackTrace = newPrepareStackTrace;
        var structuredStack = new Error().stack;
        Error.prepareStackTrace = oldPrepareStackTrace;
        var caller = structuredStack[2];
        var lineSep = process.platform == 'win32' ? '\\' : '/';
        var fileNameSplited = caller.getFileName().split(lineSep);
        var fileName = fileNameSplited[fileNameSplited.length - 1];
        var lineNumber = caller.getLineNumber();
        var columnNumber = caller.getColumnNumber();
        // function name may be empty if it is a global call
        // var functionName = caller.getFunctionName();
        var levelString;
        switch (level) {
            case LEVEL.INFO:
                levelString = '[INFO]';
                break;
            case LEVEL.WARN:
                levelString = '[WARN]';
                break;
            case LEVEL.ERROR:
                levelString = '[ERROR]';
                break;
            default:
                levelString = '[]';
                break;
        }
        var output = util.format('%s %s(%d,%d): %s',
            levelString, fileName, lineNumber, columnNumber, message
        );
        if (!coloredOutput) {
            process.stdout.write(output + '\n');
        } else {
            switch (level) {
                case LEVEL.INFO:
                    process.stdout.write(COLOR.INFO + output + COLOR.RESET + '\n');
                    break;
                case LEVEL.WARN:
                    process.stdout.write(COLOR.WARN + output + COLOR.RESET + '\n');
                    break;
                case LEVEL.ERROR:
                    process.stdout.write(COLOR.ERROR + output + COLOR.RESET + '\n');
                    break;
                default:
                    break;
            }
        }
    }
    module.exports = {
        info:info,
        warn:warn,
        error:error,
        LEVEL:LEVEL,
        setLevel:setLevel,
        setColoredOutput:setColoredOutput
    };
}());

+ 1 - 0
views/error.html

@ -0,0 +1 @@
{"errno":"404"}

+ 6 - 0
views/error.jade

@ -0,0 +1,6 @@
extends layout
block content
  h1= message
  h2= error.status
  pre #{error.stack}

+ 11 - 0
views/index.html

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
  </body>
</html>

+ 5 - 0
views/index.jade

@ -0,0 +1,5 @@
extends layout
block content
  h1= title
  p Welcome to #{title}

+ 7 - 0
views/layout.jade

@ -0,0 +1,7 @@
doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    block content