Authored by xuqi

Merge branch 'develop' of http://git.dev.yoho.cn/opentech/yo into develop

1 -node_modules/  
2 -dist/  
3 -npm-debug.log  
  1 +node_modules/
  2 +dist/
  3 +npm-debug.log
  1 +
  2 +function ContModel(app){
  3 + /*
  4 + get 方法总结
  5 + 参数 router,views,apis,callback
  6 + 规则 router+(views|apis|callback)
  7 + */
  8 +
  9 + /*打开一个页面*/
  10 + app.get("/1","module.index");
  11 +
  12 + /*根据数据接口 渲染一个页面*/
  13 + app.get("/2","module.index","User-login");
  14 +
  15 + /*接口 类型为数组或者字符串 返回值区别 */
  16 + app.get("/3","module.index",["User-login"]);
  17 +
  18 +
  19 + /*适配器*/
  20 + app.get("/4","module.index",["User-login"],function(key1){
  21 + key1.message="我修改了适配器";
  22 + return key1;
  23 + });
  24 +
  25 + /*express 基本功能*/
  26 + app.get("/5",function(req,res){
  27 + /*注意 render 的View*/
  28 + res.render("moduleA.index",{});
  29 + });
  30 +
  31 + /**/
  32 + app.get("/6/:id",["User-login"],function(key1,req,res){
  33 + /*注意 render 的View*/
  34 + res.end(req.param("id"));
  35 + });
  36 +
  37 + /*
  38 + POST 方法总结
  39 + 参数 router,apis,callback
  40 + 规则 router+(apis|callback)
  41 + */
  42 +
  43 +
  44 + /*过滤器*/
  45 + // app.filters("/*","*",["UserA-login"],function(key1,req,res,next){
  46 +
  47 + // });
  48 +}
  49 +module.exports=ContModel;
  1 + module.exports={
  2 + namespace:"Role",
  3 + apis:{
  4 + "getrole":{
  5 + url:"/supplier/supplier/getSupplier",
  6 + method:"POST",
  7 + params:[
  8 + {name:"id",type:"Number"}
  9 + ],
  10 + output:{
  11 + code:"我是桩数据"
  12 + }
  13 + }
  14 + }
  15 + }
  1 + module.exports={
  2 + namespace:"User",
  3 + apis:{
  4 + "login":{
  5 + url:"/supplier/supplier/getSupplier",
  6 + method:"POST",
  7 + params:[
  8 + {name:"id",type:"Number"}
  9 + ],
  10 + output:{
  11 + code:"我是桩数据=code",
  12 + message:"我是桩数据=messsage"
  13 + }
  14 + }
  15 + }
  16 + }
  1 +<!DOCTYPE html>
  2 +<html>
  3 +<head>
  4 + <title></title>
  5 +</head>
  6 +<body>
  7 +<h1>Hello word 你所打开的是module模块下views index.html</h1>
  8 +<h1>User-login.code:{{User-login.code}}</h1>
  9 +<div><strong>part</strong> {{>part}}</div>
  10 +<div><strong>layout/A</strong> {{>layout/A}}</div>
  11 +<div><strong>../../moduleA/views/index</strong>===> {{>../../moduleA/views/index}}</div>
  12 +</body>
  13 +</html>
  1 +
  2 +<strong>../../../moduleA/views/index</strong> ===> {{>../../../moduleA/views/index}}
  3 +
  1 +message 输出 {{message}}
  1 + module.exports={
  2 + namespace:"RoleA",
  3 + apis:{
  4 + "getrole":{
  5 + url:"/supplier/supplier/getSupplier",
  6 + method:"POST",
  7 + params:[
  8 + {name:"id",type:"Number"}
  9 + ]
  10 + }
  11 + }
  12 + }
  1 + module.exports={
  2 + namespace:"UserA",
  3 + apis:{
  4 + "login":{
  5 + url:"/supplier/supplier/getSupplier",
  6 + method:"POST",
  7 + params:[
  8 + {name:"id",type:"Number"}
  9 + ]
  10 + }
  11 + }
  12 + }
  1 +<strong>../../module/view/part</strong>===> {{> ../../module/views/part}}
  1 +
  2 +module.exports=function(Filter){
  3 + Filter.define("\/5","get",function(req,res,next){
  4 + res.end("please login...");
  5 + // next();
  6 + });
  7 +};
  1 +'use strict';
  2 +
  3 +/*下载最新node v5.10.1*/
  4 +var path = require('path');
  5 +
  6 +/*获取配置接口信息*/
  7 +var apiCofig={
  8 + root:__dirname,
  9 + apps:path.join(__dirname,"apps"),
  10 + domain:"http://192.168.102.202:8088/platform",
  11 + port:3000,
  12 + log:{
  13 + consoles:["log"],
  14 + src:""
  15 + },
  16 + mock:true,
  17 + baseUrl:'/',
  18 + MVC:{//__dirname+"/apps/{.*}/interfaces/{.*}.js"
  19 + Interfacer:path.join(__dirname,"apps/0/interfaces/1.js").replace(/0|1/g,'{.*}'),
  20 + Controller:path.join(__dirname,"apps/0/controllers/1.js").replace(/0|1/g,'{.*}'),
  21 + filters:path.join(__dirname,"filters.js")
  22 + },
  23 + use:function(app){
  24 +
  25 + }
  26 +}
  27 +module.exports = require('./libs/App')(apiCofig);
  1 +var path = require('path');
  2 +
  3 +var express = require('express');
  4 +var App = express();
  5 +var bodyParser = require('body-parser');
  6 +var multer = require('multer');
  7 +
  8 +
  9 +var Router = express.Router();
  10 +
  11 +var Scan=require("./Scan");
  12 +
  13 +
  14 +module.exports=function(apiCofig){
  15 +
  16 + // 记录下当前文档的路径
  17 + global.apps=apiCofig.apps;
  18 +
  19 + /*日志配置和Console*/
  20 + var Console=require("./Console");
  21 + Console(apiCofig.log);
  22 + console.log("YOHO!");
  23 +
  24 + /*接口层*/
  25 + var Interfacer=require("./Interfacer");
  26 + var InterRegisters= new Interfacer(apiCofig);
  27 + apiCofig.MVC.Interfacer&&
  28 + Scan(apiCofig.MVC.Interfacer).forEach(function(src){
  29 + InterRegisters.register(require(src));
  30 + });
  31 +
  32 + /*过滤器*/
  33 + var Filter=require("./Filter");
  34 + var FilterRegisters= new Filter(InterRegisters);
  35 + apiCofig.MVC.filters&&
  36 + Scan(apiCofig.MVC.filters).forEach(function(src){
  37 + require(src)(FilterRegisters);
  38 + });
  39 +
  40 +
  41 +
  42 + /*控制器层*/
  43 + var Controller=require("./Controller");
  44 + var ContRegisters=new Controller(InterRegisters);
  45 + apiCofig.MVC.Controller&&
  46 + Scan(apiCofig.MVC.Controller).forEach(function(src){
  47 + require(src)(ContRegisters);
  48 + });
  49 +
  50 + /*内置中间件 对Http请求解析*/
  51 + App.use(bodyParser.json()); // for parsing application/json
  52 + App.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
  53 + // App.use(multer()); // for parsing multipart/form-data
  54 +
  55 + /*路由控制*/
  56 + var KLH=function(obj,method,guid){
  57 + return function(req,res){
  58 + obj[method].call(obj,guid,req,res);
  59 + }
  60 + }
  61 + ContRegisters.routers.forEach(function(router){
  62 + var ROU=Router.route([router.url]);
  63 + var args=FilterRegisters.use(router.url,router.method).
  64 + concat(KLH(ContRegisters,"emit",router.guid));
  65 + ROU[router.method].apply(ROU,args);
  66 + });
  67 +
  68 + App.use(apiCofig.baseUrl, Router);
  69 +
  70 +
  71 + /*View 设置*/
  72 + var Viewer=require("./Viewer");
  73 + var Viewer=new Viewer(App,require("handlebars"));
  74 + App.set('view engine', 'html');
  75 + App.engine('html', Viewer.engine);
  76 +
  77 + /*加载中间间*/
  78 + apiCofig.use&&apiCofig.use(App);
  79 +
  80 +
  81 + var server = App.listen(apiCofig.port, function () {
  82 + var host = server.address().address;
  83 + var port = server.address().port;
  84 + });
  85 +
  86 +}
  1 +/*
  2 +*重写Console 包含日志
  3 +*logsConfig 包含之日相关设置
  4 + logsConfig:{
  5 + consoles:["log"]//选择启动console的选择方法,
  6 + src:"日志输出"
  7 + }
  8 +*/
  9 +module.exports=function(logsConfig){
  10 + var Consoles=['log', 'info', 'warn', 'error', 'dir', 'assert'];
  11 + var log=console.log,
  12 + info=console.info,
  13 + warn=console.warn,
  14 + error=console.error,
  15 + dir=console.dir,
  16 + assert=console.assert;
  17 +
  18 + /*重写console方法*/
  19 + console.log = function(){
  20 + var args=[].slice.call(arguments, 0);
  21 + args[0]="log:"+args[0];
  22 + log.apply(console, args);
  23 + };
  24 + console.error = function(){
  25 + var args=[].slice.call(arguments, 0);
  26 + args[0]="error:"+args[0];
  27 + error.apply(console, args);
  28 + };
  29 +
  30 +
  31 +
  32 +
  33 +
  34 +
  35 +
  36 + function difference(array1,array2){
  37 + return array1.filter(function(item,value){
  38 + return !(array2.indexOf(item)>-1);
  39 + });
  40 + }
  41 + logsConfig.consoles=logsConfig.consoles||[];
  42 + if(logsConfig.consoles){
  43 + var invalidCons=difference(Consoles,logsConfig.consoles);
  44 + invalidCons.forEach(function (f) {
  45 + console[f] = function () {
  46 + };
  47 + return false;
  48 + });
  49 + return false;
  50 + }
  51 +}
  1 +var path=require('path');
  2 +var util = require('util');
  3 +var md5 = require('md5');
  4 +var Emitter=require('events');
  5 +/*重写控制器*/
  6 +
  7 +var toString= Object.prototype.toString;
  8 +
  9 +var Controller=function(interfaces){
  10 + this.interfaces=interfaces;
  11 + this.routers=[];
  12 +
  13 + Emitter.call(this);
  14 +};
  15 +util.inherits(Controller,Emitter);
  16 +
  17 +/*解析 req 规则*/
  18 +Controller.prototype.__parseReq=function(req){
  19 +
  20 + return{
  21 + defRes:req.xhr?"json":"render"
  22 + }
  23 +}
  24 +
  25 +Controller.prototype.__define=function(method,router,view,apis,callback){
  26 + var me=this,isObj=false;
  27 + if(typeof apis=="string"){
  28 + apis=[apis];
  29 + isObj=true;
  30 + }
  31 + /*参数验证*/
  32 + var guid=md5(router+":"+method)
  33 +
  34 + me.on(guid,function(){
  35 + var args=[].slice.call(arguments, 0);
  36 + var req=args[0],res=args[1];
  37 + /*如果接口不存在 就实现express 原来的方法*/
  38 + if(!apis.length){
  39 + if(callback){
  40 + callback.apply({},args);
  41 + }else{
  42 + res.render(view);
  43 + }
  44 + return;
  45 + }
  46 + args.push(function(err,interfaces,names){
  47 + //callback
  48 + var model={};
  49 + if(typeof callback=="function"){
  50 + model=callback.apply({},interfaces.concat(args));
  51 +
  52 + }else{
  53 + interfaces.forEach(function(item,index){
  54 + if(isObj){
  55 + model=item;
  56 + }else{
  57 + model[names[index]]=item;
  58 + }
  59 + });
  60 + }
  61 + if(model){
  62 + if(view&&method=="get"&&!req.xhr){
  63 + res.render(view,model);
  64 + }else{
  65 + res.json(model);
  66 + }
  67 + }
  68 + });
  69 + //调用接口获取数据
  70 + me.interfaces.require.apply(me.interfaces,[apis].concat(args));
  71 + });
  72 +
  73 + me.routers.push({
  74 + guid:guid,
  75 + url:router,
  76 + method:method
  77 + });
  78 +}
  79 +Controller.prototype.get=function(router,views,apis,callback){
  80 + var me=this;
  81 + if(!(typeof views=="string"&&views.indexOf('.')>-1)){
  82 + callback=apis;
  83 + apis=views;
  84 + views=null;
  85 + }
  86 + if(typeof apis =='function'){
  87 + callback=apis;
  88 + apis=[];
  89 + }
  90 + apis=apis||[];
  91 + me.__define("get",router,views,apis,callback);
  92 +}
  93 +Controller.prototype.post=function(router,apis,callback){
  94 + var me=this;
  95 + if(typeof apis=="function"){
  96 + callback=apis;
  97 + apis=[];
  98 + }
  99 + me.__define("post",router,null,apis,callback);
  100 +}
  101 +
  102 +
  103 +module.exports= Controller;
  1 +var path=require('path');
  2 +var util = require('util');
  3 +var md5 = require('md5');
  4 +var Emitter=require('events');
  5 +
  6 +var Filter=function(interfaces){
  7 + this.rules=[];
  8 + this.interfaces=interfaces;
  9 + Emitter.call(this);
  10 +};
  11 +util.inherits(Filter,Emitter);
  12 +
  13 +Filter.prototype.define = function(router,method,apis,callback) {
  14 + var me=this,guid=md5(router+":"+method);
  15 +
  16 + if(typeof apis=="function"){
  17 + callback=apis;
  18 + apis=[];
  19 + }
  20 +
  21 + me.rules.push({
  22 + guid:guid,
  23 + router:router,
  24 + method:method
  25 + });
  26 +
  27 + me.on(guid,function(){
  28 + var args=[].slice.call(arguments, 0);
  29 + var req=args[0],res=args[1];
  30 + if(!apis.length){
  31 + callback.apply({},args);
  32 + return;
  33 + }
  34 + args.push(function(err,interfaces,names){
  35 + callback.apply({},interfaces.concat(args));
  36 + });
  37 +
  38 + me.interfaces.require.apply(me.interfaces,[apis].concat(args));
  39 + });
  40 +};
  41 +
  42 +Filter.prototype.use=function(router,method){
  43 + var me=this,rules=[],func=[];
  44 + rules=me.rules.filter(function(rule,index){
  45 + return new RegExp(rule.router,'g').test(router)
  46 + &&new RegExp(rule.method,'ig').test(method);
  47 + });
  48 + rules.forEach(function(rule){
  49 + func.push(function(req,res,next){
  50 + me.emit(rule.guid,req,res,next);
  51 + });
  52 + });
  53 + return func;
  54 +}
  55 +
  56 +
  57 +
  58 +
  59 +module.exports= Filter;
  60 +
  1 +var util = require('util');
  2 +var Emitter=require('events');
  3 +var Request = require('request');
  4 +var async=require('async');
  5 +/*接口*/
  6 +
  7 +
  8 +var Interfacer=function(config){
  9 + this.config=config;
  10 + this.apis={};
  11 + Emitter.call(this);
  12 +};
  13 +
  14 +util.inherits(Interfacer,Emitter);
  15 +
  16 +Interfacer.prototype.register = function(mos) {
  17 + var me=this,name=mos.namespace;
  18 + for(var key in mos.apis){
  19 + /*需要进行验证判断*/
  20 + me.apis[name+"-"+key]=mos.apis[key];
  21 + }
  22 +};
  23 +function __requestApi(config,apiOpt,req,callback){
  24 + var data={};
  25 + apiOpt.params.forEach(function(param){
  26 + data[param.name]=req.param(param.name)||"1454";
  27 + });
  28 + var options={
  29 + url:config.domain+apiOpt.url,
  30 + method:apiOpt.method,
  31 + //数据组装
  32 + qs:apiOpt.method.toUpperCase()=="GET"?data:undefined,
  33 + // form:apiOpt.method.toUpperCase()=="GET"?undefined:data//,
  34 + body:apiOpt.method.toUpperCase()=="GET"?undefined:JSON.stringify(data),
  35 +
  36 + headers: apiOpt.headers||{
  37 + 'Content-Type' : 'application/json'
  38 + }
  39 + };
  40 + Request(options,function(error, response, body){
  41 + if(error){
  42 + return callback(error,null);
  43 + }
  44 + return callback(null,JSON.parse(body));
  45 + });
  46 +}
  47 +/*
  48 +* {mos} 接口key 数组 比如[key1,key2] 后面可能要兼容字符串 比如 传key1
  49 +*/
  50 +Interfacer.prototype.require=function(mos,req,res,cb){
  51 + var me=this,funcs=[],names=[];
  52 +
  53 + mos.forEach(function(name){
  54 +
  55 + if(me.apis.hasOwnProperty(name)){
  56 + names.push(name);
  57 + if(me.config.mock){
  58 + funcs.push(me.apis[name].output);
  59 + }else{
  60 + funcs.push(function(callback){
  61 + __requestApi(me.config,me.apis[name],req,callback);
  62 + });
  63 + }
  64 + }
  65 + });
  66 +
  67 + if(funcs.length!=mos.length){
  68 + return {err:"某个key 可能不存在!"};
  69 + }
  70 + if(me.config.mock){
  71 + cb(null,funcs,names);
  72 + return;
  73 + }
  74 + async.parallel(funcs, function(err, results){
  75 + if(err){
  76 + return cb(err,null,names);
  77 + }
  78 + cb(null,results,names);
  79 + });
  80 +};
  81 +
  82 +
  83 +module.exports= Interfacer;
  1 +/*桩数据规则*/
  1 +var fs = require('fs');
  2 +var path = require('path');
  3 +
  4 +module.exports=function(url){
  5 + var tokens=[],files=[],dir="";
  6 + url.split(/\{|\}/).forEach(function(item,index) {
  7 + if(item){
  8 + tokens.push({
  9 + value:item,
  10 + expr:index%2?true:false
  11 + });
  12 + }
  13 + });
  14 +
  15 + function scanFolder(src) {
  16 + var stats,fileList = [],
  17 + folderList = [],
  18 + walk = function (src, fileList, folderList) {
  19 +
  20 + files = fs.readdirSync(src);
  21 + files.forEach(function (item) {
  22 + var tmpPath = path.join(src, item);
  23 +
  24 + stats = fs.statSync(tmpPath);
  25 +
  26 + if (stats.isDirectory()) {
  27 + walk(tmpPath, fileList, folderList);
  28 + folderList.push(tmpPath);
  29 + } else {
  30 + fileList.push(tmpPath);
  31 + }
  32 + });
  33 + };
  34 +
  35 + walk(src, fileList, folderList);
  36 +
  37 + return {
  38 + 'files': fileList,
  39 + 'folders': folderList
  40 + }
  41 + }
  42 +
  43 +
  44 + if(fs.statSync(tokens[0].value).isFile()){
  45 + return [path.normalize(tokens[0].value)];
  46 + }
  47 +
  48 + url=url.replace(/^\W+/g,'').replace(/\\/g,'\\\\').replace(/\{/g,'(').replace(/\}/g,'?)');
  49 + var regex = new RegExp("^"+url+"$");
  50 +
  51 + var obj=scanFolder(tokens[0].value),result=[];
  52 + if(path.extname(url)){
  53 + result=obj.files.filter(function(item){
  54 + return regex.test(item);
  55 + });
  56 + }
  57 + return result;
  58 +
  59 +}
  1 +/* 验证JS*/
  2 +一期定下规则
  3 +二期实现功能
  1 +var fs = require('fs');
  2 +var path=require('path');
  3 +var util = require('util');
  4 +var md5 = require('md5');
  5 +var Emitter=require('events');
  6 +/*重写控制器*/
  7 +
  8 +
  9 +var Viewer=function(app,tempEngine){
  10 + this.tempEngine=tempEngine;
  11 + this.cache={};
  12 + this.overrideExp(app);
  13 + this.engine=this.overrideEngine.bind(this);
  14 + Emitter.call(this);
  15 +};
  16 +util.inherits(Viewer,Emitter);
  17 +
  18 +Viewer.prototype.overrideExp=function(app){
  19 + app.render=(function(render){
  20 + return function(view, options, callback) {
  21 + if(typeof options=="function"){
  22 + callback=options;
  23 + options={};
  24 + }
  25 + var views=view.split('.');
  26 + var _module=views.shift();
  27 + var filePath=path.resolve(global.apps,_module,"views/"+views.join('/'));
  28 + return render.call(this, filePath, options, callback);
  29 + };
  30 + })(app.render);
  31 +}
  32 +
  33 +
  34 +
  35 +var __parsefile = function(fileKey,filePath,dataModel,callback){
  36 + var me=this,cache=this.cache;
  37 + /*判断catch 是否存在*/
  38 + var template = cache[fileKey];
  39 + if(template){
  40 + return callback(null,template(dataModel))
  41 + }
  42 + /*如果catch不存在就去读取 file*/
  43 + fs.readFile(filePath, 'utf8', function(err, str){
  44 + if(err){
  45 + return callback(err);
  46 + }
  47 + /*需要排除<!--{{}}-->*/
  48 + if(/\{\{>[^}]*\}\}/g.test(str)){
  49 + str=__parseLayout(filePath,str);
  50 + }
  51 + template =me.tempEngine.compile(str);
  52 + cache[fileKey]=template;
  53 + try{
  54 + var res = template(dataModel);
  55 + /*注册*/
  56 + return callback(null,res);
  57 + }
  58 + catch(err){
  59 + err.message = filePath + ': ' + err.message;
  60 + return callback(null,err.message);
  61 + }
  62 + });
  63 +}
  64 +
  65 +var __parseLayout=function(form,str){
  66 + var layouts=str.match(/\{\{>[^}]*\}\}/g);
  67 + return str.replace(/\{\{>[^}]*\}\}/g,function($0){
  68 + var name=path.resolve(path.dirname(form),$0.match(/\{\{>\s*([^}]*)\s*\}\}/m)[1].replace(/\s/g,'')+".html");
  69 + var html=fs.readFileSync(name,'utf8');
  70 + if(/\{\{>[^}]*\}\}/g.test(html)){
  71 + html=__parseLayout(name,html);
  72 + }
  73 + return html;
  74 + });
  75 +
  76 +}
  77 +
  78 +Viewer.prototype.overrideEngine=function(filepath, options, callback){
  79 + var me=this,cache=this.cache;
  80 + /*每一个文件对应一个Key*/
  81 + var fileKey=md5(filepath),args=[].slice.call(arguments, 0);
  82 +
  83 + return __parsefile.apply(this,[fileKey].concat(args));
  84 +}
  85 +
  86 +
  87 +module.exports= Viewer;
@@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
5 "main": "app.js", 5 "main": "app.js",
6 "devDependencies": { 6 "devDependencies": {
7 "autoprefixer": "^6.3.6", 7 "autoprefixer": "^6.3.6",
  8 + "express": "^4.13.4",
8 "gulp": "^3.9.1", 9 "gulp": "^3.9.1",
9 "gulp-cssnano": "^2.1.2", 10 "gulp-cssnano": "^2.1.2",
10 "gulp-postcss": "^6.1.0", 11 "gulp-postcss": "^6.1.0",
@@ -28,6 +29,11 @@ @@ -28,6 +29,11 @@
28 "webpack-stream": "^3.1.0" 29 "webpack-stream": "^3.1.0"
29 }, 30 },
30 "dependencies": { 31 "dependencies": {
31 - "lodash": "^4.11.1" 32 + "async": "^2.0.0-rc.3",
  33 + "express": "^4.13.4",
  34 + "lodash": "^4.11.1",
  35 + "md5": "^2.1.0",
  36 + "multer": "^1.1.0",
  37 + "request": "^2.72.0"
32 } 38 }
33 } 39 }