Authored by xuqi

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

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