Browse Source

first commit

HonorLee 7 years ago
commit
4da94734ee
12 changed files with 425 additions and 0 deletions
  1. 6 0
      .gitignore
  2. 1 0
      README.md
  3. 32 0
      config.js
  4. 24 0
      master.js
  5. 33 0
      package.json
  6. 38 0
      server_worker.js
  7. 72 0
      system/core.js
  8. 22 0
      system/lib/core/logger.js
  9. 49 0
      system/lib/core/router.js
  10. 45 0
      system/lib/core/session.js
  11. 93 0
      system/lib/extra/mysql-pool.js
  12. 10 0
      system/lib/helper/mysqldb.js

+ 6 - 0
.gitignore

@@ -0,0 +1,6 @@
+/node_modules
+npm-debug.log
+/log
+.idea
+.DS_Store
+/temp

+ 1 - 0
README.md

@@ -0,0 +1 @@
+Report!

+ 32 - 0
config.js

@@ -0,0 +1,32 @@
+global.Config = {
+    //Session ExpireTime min.
+    SessionExpire : 30,
+    //WhiteList
+    WhiteList : {
+        Static  : /static|images|robots\.txt|crossdomain\.xml|favicon\.ico/,
+        Handler : /index|report/
+    },
+    //Mysql config
+    mysql_on : false,
+    mysql_cfg : {
+        host:'localhost',
+        port:3389,
+        user:'root',
+        password:'',
+        database:''
+    },
+    //Mongodb config
+    mongodb_on : false,
+    mongodb_cfg : {
+        host:'localhost',
+        port:27017,
+        user:null,
+        password:'',
+        database:''
+    },
+    //If Debug on,log && info logs will output in console;except Error!
+    debug:true,
+    //if write file on,logs will write in log files
+    write_log_file:true,
+    write_error_file:true
+};

+ 24 - 0
master.js

@@ -0,0 +1,24 @@
+/*
+NodeJS-MVC 1.0
+--------------------
+HonorLee
+http://honorlee.me
+dev@honorlee.me
+*/
+
+'use strict';
+
+//Master Process
+//DO NOT CHANGE ANYTHING IN THIS FILE!
+
+//Max number of worker,'auto' would be fine
+let max_child_process   = 2;
+//If turn loadBalancing on,master process will forward all request to child process.Recommend NGINX for instant.
+let loadBalancing       = false;
+let child_port_start    = 8000;
+// let socketIO     = require('socket.io')(socketServer);
+
+let childNumber = max_child_process=='auto'?require('os').cpus().length:Number(max_child_process);
+for(let i = 0; i<max_child_process; i++){
+    require('child_process').fork('./server_worker.js',['-p',child_port_start+i]);
+}

+ 33 - 0
package.json

@@ -0,0 +1,33 @@
+{
+  "name": "DJJ-Report",
+  "version": "0.1.0",
+  "description": "DJJ-Report System",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "dependencies": {
+    "async": "^2.0.0-rc.5",
+    "cheerio": "^0.20.0",
+    "colors": "^1.1.2",
+    "commander": "^2.9.0",
+    "cron": "^1.1.0",
+    "date-format": "0.0.2",
+    "ejs": "^2.4.2",
+    "fs-extra": "^0.30.0",
+    "js-base64": "^2.1.9",
+    "md5": "^2.2.1",
+    "mime-types": "^2.1.11",
+    "mysql": "^2.11.1",
+    "querystring": "^0.2.0",
+    "request": "^2.72.0",
+    "tracer": "^0.8.3"
+  },
+  "engines": {
+    "node": ">=0.12.5"
+  },
+  "repository": {
+    "private": true
+  },
+  "author": "HonorLee",
+  "license": "ISC"
+}

+ 38 - 0
server_worker.js

@@ -0,0 +1,38 @@
+/*
+* NodeJS-MVC 1.0
+* --------------------
+* HonorLee
+* http://honorlee.me
+* dev@honorlee.me
+ */
+
+/*
+* Worker Process
+  DO NOT CHANGE ANYTHING IN THIS FILE!
+ */
+global.ROOTPATH = __dirname;
+require('./config.js');
+require('./system/core.js');
+Commander
+    .version('1.0.0')
+    .option('-p, --port [type]', 'server port')
+    .parse(process.argv);
+
+let serverPort = Number(Commander.port);
+if(!serverPort || serverPort==0){
+    LOGGER.error('Child Server start faile port ['+serverPort+'] | '+DateFormat('yyyy/MM/dd hh:mm:ss',new Date()));
+}
+
+require('http').createServer(serverHandler).listen(serverPort);
+LOGGER.info('Child Server start at port [' + serverPort + '] | ' + DateFormat('yyyy/MM/dd hh:mm:ss', new Date()));
+
+function serverHandler(req,res){
+    // var COOKIE = {};
+    // req.headers.cookie && req.headers.cookie.split(';').forEach(function(Cookie){
+    //     let parts = Cookie.split('=');
+    //     COOKIE[parts[0].trim()] = (parts[1]||'').trim();
+    // });
+    // req.cookie = COOKIE;
+    // ROUTER.go(res,req);
+    console.log(serverPort);
+}

+ 72 - 0
system/core.js

@@ -0,0 +1,72 @@
+'use strict';
+global.Core = {};
+
+//Global Path
+global.Core.Path = {
+    System      : ROOTPATH + '/system',
+    CoreLib     : ROOTPATH + '/system/lib/core',
+    ExtraLib    : ROOTPATH + '/system/lib/extra',
+    Helper      : ROOTPATH + '/system/lib/helper',
+    Work        : ROOTPATH + '/app',
+    Module      : ROOTPATH + '/app/modules',
+    Handler     : ROOTPATH + '/app/handlers',
+    View        : ROOTPATH + '/app/view',
+    Static      : ROOTPATH + '/app/static',
+    Temp        : ROOTPATH + '/temp',
+    Session     : ROOTPATH + '/temp/session',
+    Log         : ROOTPATH + '/log'
+
+};
+
+//Global Extension Require
+global.Commander    = require('commander');
+global.URL          = require('url');
+global.FILE         = require('fs-extra');
+global.EJS          = require('ejs');
+global.ASYNC        = require('async');
+global.Base64       = require('js-base64');
+global.MD5          = require('md5');
+global.DateFormat   = require('date-format');
+global.Tracer       = require('tracer').dailyfile({root:Core.Path.Log,format : "{{timestamp}} <{{title}}> {{file}}:{{line}} {{message}}", dateformat : "HH:MM:ss.L"});
+
+//System Library load
+let CoreLibFiles = FILE.readdirSync(Core.Path.CoreLib);
+CoreLibFiles.forEach(function(filename){
+    let nameWithOutMimeType = (filename.split('.')[0]).toUpperCase();
+    try {
+        global[nameWithOutMimeType] = require(Core.Path.CoreLib + '/' + filename);
+    }catch(e){
+        console.log('[Core] Core library file ['+filename+'] load error!');
+        Tracer.error('[Core] Core library file ['+filename+'] load error!');
+    }
+});
+//System Library load end
+
+
+//Core Setting,just change it if necessary!
+global.Core.Setting = {
+    //Mysql connect pool setting
+    mysql_pool:{
+        name: 'NMVCPOOL',
+        maxconn: 5
+    }
+};
+
+//If Mysql on,load Mysql Extension
+if(Config && Config.mysql_on && Config.mysql_cfg){
+    let mysqlConfig = {
+        pool:Core.Setting.mysql_pool,
+        db:Config.mysql_cfg
+    };
+    global.MysqlPool  = require(Core.Path.ExtraLib + '/mysql-pool.js').instance(mysqlConfig);
+    global.MysqlDB    = require(Core.Path.Helper + '/mysqldb.js');
+}
+
+//Check File Paths
+for(let path in global.Core.Path){
+    try{
+        FILE.statSync(global.Core.Path[path]);
+    }catch(e){
+        FILE.mkdirsSync(global.Core.Path[path]);
+    }
+}

+ 22 - 0
system/lib/core/logger.js

@@ -0,0 +1,22 @@
+/** Logger **/
+const colors = require('colors');
+
+var Logger = {
+    log:function(msg){
+        if(Config.debug) console.log(('[LOG] '+msg).yellow);
+        if(Config.write_log_file) this.out('log',msg);
+    },
+    info:function(msg){
+        if(Config.debug) console.log(('[INF] '+msg).green);
+        if(Config.write_log_file) this.out('info',msg);
+    },
+    error:function(msg){
+        console.log(('[ERR] '+msg).red);
+        if(Config.write_error_file) this.out('error',msg);
+    },
+    out:function(level,msg){
+        Tracer[level](msg);
+    }
+};
+
+module.exports = Logger;

+ 49 - 0
system/lib/core/router.js

@@ -0,0 +1,49 @@
+'use strict'
+var Router ={
+    go:function(res,req){
+        let url = req.url=='/'?'/index':req.url;
+        let URLParse = URL.parse(url,true);
+        let URLArr = URLParse.pathname.split('/');
+        let query = URLParse.query;
+        let enterURI = String(URLArr[1]);
+        if(enterURI=='') enterURI='index';
+
+        if(enterURI.match(WhiteList.HandlerRules)){
+            return Router.getHandler(url,res,req);
+        }else if(enterURI.match(WhiteList.StaticRules)){
+            return STATIC.load(ROOTPATH+URLParse.pathname,query,res);
+        }else{
+            Router._error('Router Go ERROR:'+url,res);
+            Logger.error(url+' WhiteList Check error!');
+        }
+    },
+    getHandler:function(url,res,req){
+        let URLParse = URL.parse(HANDLERPATH+url,true);
+        let URLArr = URLParse.pathname.split('/');
+        if(URLArr[URLArr.length-1]=='') URLArr[URLArr.length-1]='index';
+        let FileName = URLArr.join('/')+'.js';
+        let mod,call='index';
+        if(!FILE.existsSync(FileName)){
+            call = URLArr.pop();
+            FileName = URLArr.join('/')+'.js';
+        }
+        try{
+            mod = require(FileName);
+            if(mod['__construct']){
+                let cons = mod['__construct'](res,req,URLParse.query);
+                if(cons && cons.status=='error') Router._error('Router Go ERROR:'+cons.msg,res);
+            }
+            mod[call](res,req,URLParse.query);
+        }catch(err){
+            Logger.error(err);
+            res.writeHead(404, {'Content-Type': 'text/html'});
+            res.end('404');
+        }
+    },
+    _error:function(log,res,req){
+        res.writeHead(404, {'Content-Type': 'text/html'});
+        res.end('404');
+    }
+};
+
+module.exports = Router;

+ 45 - 0
system/lib/core/session.js

@@ -0,0 +1,45 @@
+'use strict';
+var Session = {
+    set:function(key,value,sessionid){
+        if(!key || !value) return null;
+
+        let sessionData;
+        if(sessionid){
+            try{
+                sessionData = JSON.parse(FILE.readFileSync(Core.Path.Session + 'sessionid','UTF-8'));
+            }catch(e){
+                sessionid = '';
+            }
+        }
+        if(!sessionid){
+            sessionid = MD5(new Date().getTime()+''+Math.floor(Math.random()*9000+1000));
+            sessionData = {id:sessionid,expire:(new Date().getTime()+Config.SessionExpire*60000)};
+        }
+
+        sessionData[key]=value;
+
+        FILE.writeFileSync(Core.Path.Session + sessionid,JSON.stringify(sessionData),'UTF-8');
+        return sessionid;
+    },
+    get:function(sessionid){
+        if(!sessionid) return null;
+        let sessionData;
+        try{
+            sessionData = JSON.parse(FILE.readFileSync(Core.Path.Session + 'sessionid','UTF-8'));
+            if(sessionData.expire < new Date().getTime()){
+                sessionData = null;
+                Session.clear(sessionid);
+            }
+        }catch(e){
+            sessionData = null;
+        }
+        return sessionData;
+    },
+    clear:function(sessionid){
+        if(!sessionid) return;
+        try{
+            FILE.rmdirSync(Core.Path.Session + 'sessionid');
+        }catch(e){}
+    }
+};
+module.exports = Session;

+ 93 - 0
system/lib/extra/mysql-pool.js

@@ -0,0 +1,93 @@
+/**
+ * Created with JetBrains WebStorm.
+ * User: Gary
+ * Date: 12-11-30
+ * Time: 上午10:38
+ * To change this template use File | Settings | File Templates.
+ */
+var Mysql = require('mysql');  
+// var config = MysqlConfig;
+var pool = function(config){  
+    this.free = [];//空闲连接集合
+    this.used = 0; //已使用连接集合
+    for(var key in config.pool)
+        this[key] = config.pool[key];
+    this.newConnection = function(){
+        var con = Mysql.createConnection(config.db);
+        this.free.push(con);
+        return con;
+    };
+    this.getConnection = function(){
+        var con = null;
+        if(this.used < this.maxconn){
+            if(this.free.length > 0){
+                con = this.free[0];
+                this.free.splice(0,1);
+                if(!con)
+                    con = this.getConnection();
+            }else{
+                con = this.newConnection();
+            }
+            this.used++;
+            // console.log('当前使用连接: ' + this.used + ' 空闲连接: ' + this.free.length);
+        }
+        return con;
+    };
+    this.freeConnection = function(con){
+        this.free.push(con);
+        this.used--;
+    };
+    this.freeAll = function(){
+        this.used = 0;
+        for(var i = 0; i < this.free.length; i++){
+            this.free[i].end();
+        }
+        this.free = [];
+    };
+};
+var client = {  
+    pools: [],
+    /**
+     * 得到一个数据库连接
+     * @param name 数据库pool名字name
+     * @return {*}
+     */
+    getConnection: function(name){
+        var pool = this.pools[name];
+        return pool ? pool.getConnection() : null;
+    },
+    /**
+     * 释放一个数据库连接
+     * @param name 数据库pool名字name
+     * @param con 连接
+     */
+    freeConnection: function(name,con){
+        var pool = this.pools[name];
+        if(pool)
+            pool.freeConnection(con);
+    },
+    /**
+     * 释放一个数据库所有连接
+     * @param name 数据库pool名字name
+     */
+    freePool: function(name){
+        var pool = this.pools[name];
+        if(pool)
+            pool.freeAll();
+    },
+    /**
+     * 释放所有数据库的所有连接
+     */
+    freeAll: function(){
+        for(var key in this.pools)
+            this.pools[key].freeAll();
+    }
+};
+exports.instance = function(config){
+    if(client.pools.length < 1){
+        // for(var i = 0; i < config.length; i++){
+            client.pools[config.pool.name] = new pool(config);
+        // }
+    }
+    return client;
+};

+ 10 - 0
system/lib/helper/mysqldb.js

@@ -0,0 +1,10 @@
+'use strict'
+module.exports={
+    query:function(query,callback){
+        let mysql = MysqlPool.getConnection(Core.Setting.mysql_pool.name);
+        mysql.query(query,function(err, results, fields) {  
+            callback(err,results,fields);
+            MysqlPool.freeConnection(mysql);
+        });
+    }
+};