<|start_filename|>src/client/utils/WebUtils.js<|end_filename|>
exports.findObjInArray = function(list, key, value) {
    for (let one of list) {
        if (one[key] == value) {
            return one
        }
    }
    return null
}
exports.findMultiInArray = function(list, key, value) {
    let objs=[]
    for (let one of list) {
        if (one[key] == value) {
            objs.push(one)
           
        }
    }
    return objs
}
exports.convertDot = function(str) {
    if (str) {
        return str.replace(/\./g, "_")
    }
    return str
}
exports.convertDotBack = function(str) {
    if (str) {
        return str.replace(/\@/g, ".")
    }
    return str
}

<|start_filename|>src/server/controllers/downloadTemp.js<|end_filename|>
const send = require('koa-send')
const pathUtil=require("path")
const fs=require("fs")

let { utility, ApiError, ApiErrorNames, config, services, baseDao } = require('../include');


let path = "/downloadTemp/:path*";


async function doRequest(ctx, next) {
    console.log("------------downloadTemp",ctx.params)
    let { path } = ctx.params;
    let absPath = pathUtil.join(process.cwd(), config.dataDir)
    let filePath=pathUtil.join(absPath,path)
    console.log(filePath)
    if(fs.existsSync(filePath)) {
        await send(ctx, path, { root: absPath })   
        return
    }  
    ctx.status = 404

}

export { path, doRequest };

<|start_filename|>src/shared/meta/index.js<|end_filename|>
let metaFiles=require("./metaFiles")
let map = {};

/*--start--*/
for(let one of Object.keys(metaFiles)) {
   load(one,metaFiles[one])
}

/*load("./company/Employee")
load("./example/Input")
load("./example/SetThemeColor")
load("./example/Tree")
load("./sys/Role")
load("./sys/User")*/
/*--end--*/


function load(path,modu) {    
     modu.columnsMap = {};
        modu.subPermissions=[]
        if (modu.columnsDef) {
            for (let one of modu.columnsDef) {
                modu.columnsMap[one.prop] = one;
                if(one.input && one.input.ajax && one.input.ajax.path) {
                   modu.subPermissions.push( one.input.ajax.path) 
                }
            }
        }

       if(modu.loadDatas) {
        modu.loadDatas.forEach(function(item){
            modu.subPermissions.push(item.ajax.path)
        })
       }

      map[path ] = modu;        
      console.log("loaded:" +  path);

}

module.exports = map; 

<|start_filename|>test/test.js<|end_filename|>
var MongoClient = require('mongodb').MongoClient;

async function e() {

	try {
	  let x=await open('mongodb://192.168.1.20:27017/authSource=quickVueAdmin',{},'quickVueAdmin')
	   let client=await MongoClient.connect('mongodb://192.168.1.20:27017/authSource=quickVueAdmin',{})
	    let db=client.db('quickVueAdmin')
		console.log("success"+db)
    } catch(err) {
    	  error(err)
    }


}

function open(uri,options,dbname) {
	 console.log("---connect db",uri,options,dbname)
	return new Promise(function(resolve,reject){
		 console.log("---connect db open")
		 options.reconnectTries=Number.MAX_VALUE
		 MongoClient.connect(uri, options,function(err,client){
		 	 console.log("---connect 2",err)
		 	 if(err){
		 	  error(err)
		 	  reject(err)
		 	  return
		 	}
		 	 let db=client.db(dbname)
		 	 resolve(db)
		 })
	})
}
function error(error) {
    var errorMsg = error.stack || error.message || error || 'unknow error';
    console.log(errorMsg);
}

e()

<|start_filename|>config/server/index.js<|end_filename|>
var development_env = require("./development");
var product_env = require("./product");

//根据不同的NODE_ENV，输出不同的配置对象，默认输出development的配置对象
module.exports = {
    development: development_env,
    product: product_env,
}[process.env.NODE_ENV || 'product']

<|start_filename|>src/server/middlewares/encrypt.js<|end_filename|>
const rc4encry = require('../utils/Rc4Encrypt.js');



function decrypt(ctx) {
    var encrypt = ctx.header['encrypt'];
    console.log("encrypt:" + encrypt);
    console.log("beore decode:", ctx.request.rawBody, ctx.request.body, ctx.body);
    if (encrypt == "true") {

        if (ctx.request.rawBody) {
            var ss = rc4encry.rc4Decode(ctx.request.rawBody);
            console.log("decode:" + ss);
            ctx.request.body = JSON.parse(ss);
        }
    }
}



function encrypt(ctx) {
    let encrypt = ctx.header['encrypt'];
    if (encrypt == "true") {
        ctx.set("content-type", "html/text");
        if (ctx.body) {
            ctx.body = rc4encry.rc4Encrypt(ctx.body.replace(/\r\n/g, ""));
        }
    }
}
var url_filter = (pattern) => {

    return async(ctx, next) => {

        var reg = new RegExp(pattern);
        let isFit = reg.test(ctx.originalUrl)
        if (isFit) {
            decrypt(ctx);
        }
        await next();
        if (isFit) {
            encrypt(ctx);
        }
    }
}

// module.exports = response_formatter;
module.exports = url_filter;

<|start_filename|>src/client/components/extend/index.js<|end_filename|>
/**
 功能区扩展按钮组件声明
*/
import department_buttons from './department/index.vue';


/**
  组件列表:组件名:组件对象
  组件名是在通用元配置文件里的extendActionButtons定义
*/
let components = {
  "department_buttons": department_buttons,
};

export default components;

<|start_filename|>src/server/schedule/DeleteAdminLog.js<|end_filename|>
const moment = require('moment');
const config=require("../config")

const fs = require('fs')
const path = require('path')
/**
删除日志：/logs/admin/response_2018-08-07.log (只保留最近天数的日志文件)
*/
exports.exeuteTask = async function() {  
  var today = moment()
     let dir=path.join(process.cwd(),"/logs/admin")

     deleteLogFile(dir)

     let dir2=path.join(process.cwd(),"/logs/api")

     deleteLogFile(dir2)
}


function deleteLogFile(dir) {
	 let dirList = fs.readdirSync(dir);     
     for(let fileName of dirList) {
            console.log("--",fileName)              
           let names=path.basename(fileName,'.log').split("_")
           console.log(names,names.length)
           if(names.length>1) {                   	 
           	  let date=moment(names[1],'YYYY-MM-DD')           	  
           	  if(today.diff(date,'days')>config.logKeepDays) { 
                 var curPath = path.join(dir,fileName);                 
                  fs.unlinkSync(curPath);
                  console.log("--delete log file",curPath)
           	  } 	 	
           }
     }
}




<|start_filename|>bin/Main.js<|end_filename|>
#!/usr/bin/env node
require('babel-register');
var http = require('http');
var app = require('../src/server/app');
let port = require('../config/server').port;

console.log("process.env.NODE_ENV=" + process.env.NODE_ENV);

let server =null
app.init().then((callback)=>{    
    server=http.createServer(callback);
    server.listen(port);   
    server.on('listening', ()=>{ console.log('Listening on ' + server.address().port)});
})





<|start_filename|>src/server/routers/api/admin/index.js<|end_filename|>
var router = require('koa-router')();

var request_checkNeedParams = require('../../../middlewares/request_checkNeedParams');


import * as login from '../../../controllers/admin/login';
register(login);
import * as logout from '../../../controllers/admin/logout';
register(logout);


import * as pageAdmin from '../../../controllers/admin/pageAdmin';
register(pageAdmin);


function register(action) {
	console.log("register:"+action.path);
  router.post(action.path, action.doRequest);
  router.get(action.path, action.doRequest);
  request_checkNeedParams.register(action.path,action.needParams);
}


export   {router};




<|start_filename|>config/client/provinceAndCityTree.js<|end_filename|>
const provinceCity =require("./provinceCity.json")


let pc=[]

for(let one of Object.keys(provinceCity) ) {
	let oneProvince={}
	oneProvince.label=one
	if(provinceCity[one].length>0) {
		oneProvince.city=[]
		for(let c of provinceCity[one]) {
			oneProvince.city.push({label:c})
		}
	}
	
	pc.push(oneProvince)
}
module.exports=[{label:'全部',city:pc}]

<|start_filename|>src/server/include.js<|end_filename|>
let utility = require('utility');
let ApiError = require('./error/ApiError');
let ApiErrorNames = require('./error/ApiErrorNames');

let config = require('../../config/server');
let services = require('./services');


let CommonUtils = require('../shared/utils/CommonUtils');

var { nav_menu,pwdmd5 } = require('../../config/shared/nav_menu');

var metaIndex = require('../shared/meta');
var metaIndexServer = require('./meta/indexServer');



module.exports = { utility, ApiError, ApiErrorNames, config, services, CommonUtils,nav_menu,pwdmd5,metaIndex ,metaIndexServer};

<|start_filename|>src/client/api/PageAdminApi.js<|end_filename|>
import axios from 'axios';

let base = '/api/admin';

var ajax=function(action) {
	return (params, key) => callAjax(params, key, action);
}

export const callBatchRemove = ajax('batchremove')
export const callAdd =ajax('add')
export const callEdit =ajax('edit')
export const callListPage =ajax('listpage')
export const callList =ajax('list')
export const callTreeRemove =ajax('removeTree')
export const addTree =ajax('addTree')
export const updateTree =ajax('updateTree')


/*export const callBatchRemove = (params, key) => callAjax(params, key, 'batchremove');
export const callAdd = (params, key) => callAjax(params, key, 'add');
export const callEdit = (params, key) => callAjax(params, key, 'edit');
export const callListPage = (params, key) => callAjax(params, key, 'listpage');
export const callList = (params, key) => callAjax(params, key, 'list');
export const callTreeRemove = (params, key) => callAjax(params, key, 'removeTree');
export const addTree = (params, key) => callAjax(params, key, 'addTree');
export const updateTree = (params, key) => callAjax(params, key, 'updateTree');
*/


export const callAjax = (params, key, action) => {
    let config = null;
    if (params instanceof FormData) {
        config = { headers: { 'Content-Type': 'multipart/form-data' } };

    }
    return axios.post(`${base}${key}/${action}`, params, config);
};

<|start_filename|>src/shared/meta/sys/User.js<|end_filename|>
var utility = require('../../utils/CommonUtils');
var dateFormat = require('dateformat');
var pathUtil = require('path');

//实体名定义，也是mongodb的数据保存集合名
let entityName = "user";

let data = {};
let typeNames = {
    'root': '管理员',
    'admin': '普通用户'
};
let methods = {
    formatType: function(row, column) {
        let value = row[column.property];
        if (value) {
            if (typeNames[value]) return typeNames[value];
        }
        return value;
    },
    formatBool: function(row, column) {
        if (row[column.property]) {
            return "启用";
        }
        return "禁用";
    },
    formatRoles: function(row, column) {
        let res = "";
        if (row[column.property]) {
            let roleids = row[column.property];
            if (roleids.length > 0) {
                for (let id of roleids) {
                    res = res + id + ",";
                }
            }
            if (res.endsWith(",")) {
                res = res.substring(0, res.length - 1);
            }

        }
        return res;
    }
};


function getSelectOptions(names) {
    let options = [];
    for (let key of Object.keys(names)) {
        options.push({
            label: names[key],
            value: key
        });
    }
    return options;
}
//列定义
/**
  inputType支持类型：1）text 2）twoText 3）radio 4）checbox
*/
let columnsDef = [{
        prop: 'username',
        label: '用户名',
        width: 250,
        input: { type: 'text', rule: 'required' },
        filter: true,
        index:{options:{unique:true}}
    }, {
        prop: 'password',
        label: '密码',
        width: 200,
        input: 'text'
    }, {
        prop: 'type',
        label: '类型',
        width: 200,
        input: { type: 'select', options: getSelectOptions(typeNames), rule: 'required' },
        formatter: methods.formatType
    }, {
        prop: 'roles',
        label: '所属角色',
        width: 250,
        input: {
            type: 'select',
            multiple:true,
            ajax: {
                    path: "/sys/Role",
                    params: {},
                    label: 'name',
                    value: '_id'
                }
        },
        formatter: methods.formatRoles
    }, {
        prop: 'enable',
        label: '状态',
        width: 150,
        input: {
            type: 'radioGroup',
            options: [{
                label: '启用',
                value: true
            }, {
                label: '禁用',
                value: false
            }]
        },
        formatter: methods.formatBool
    }, {
        prop: 'memo',
        label: '备注',
        width: 200,
        input: 'text'
    }

];



let serverHook = {
    pathSaveToProp: 'filePath', //文件信息保存字段： { path, md5, size,fileName }
    fileSavePath: 'data/apk', //文件保存在本地哪个位置 （相对项目目录）
    fileName: function(oldName) { //文件名取名
        return dateFormat(new Date(), "yyyymmddHHMMssl") + pathUtil.extname(oldName);
    },
    beforeAdd: function(doc) {
        doc.addTime = utility.YYYYMMDDHHmmss();

        return doc;
    },
    beforeUpdate: function(doc) {
        doc.updateTime = utility.YYYYMMDDHHmmss();
        return doc;
    }

};

exports.entityName = entityName;
exports.columnsDef = columnsDef;
exports.serverHook = serverHook;
exports.methods = methods;

<|start_filename|>src/server/utils/log_util.js<|end_filename|>
var log4js = require('log4js');

var log_config = require('../../../config/server/log_config');

//加载配置文件
log4js.configure(log_config);

var logUtil = {};

var sdk_errorLogger = log4js.getLogger('androidTouchsdk.errorLogger');
var sdk_resLogger = log4js.getLogger('androidTouchsdk.resLogger');

var admin_errorLogger = log4js.getLogger('androidTouchadmin.errorLogger');
var admin_resLogger = log4js.getLogger('androidTouchadmin.resLogger');

var loggerMap = {};
loggerMap.androidTouchsdk = { error: sdk_errorLogger, res: sdk_resLogger };
loggerMap.androidTouchadmin = { error: admin_errorLogger, res: admin_resLogger };
loggerMap.default = { error: admin_errorLogger, res: admin_resLogger };

function getLogger(module, type) {
    return loggerMap[module][type];
}
function getErrorLogger(ctx) {
    let moduleName = getModuleName(ctx.path);
    return loggerMap[moduleName].error;
}
function getResLogger(ctx) {
    let moduleName = getModuleName(ctx.path);
    return loggerMap[moduleName].res;
}
function getModuleName(path) {
    if (path.startsWith("/api/androidTouchsdk")) {
        return "androidTouchsdk";
    }
    if (path.startsWith("/api/androidTouchadmin")) {
        return "androidTouchadmin";
    }
    return "default";
}
//封装错误日志
logUtil.logError = function (ctx, error, resTime) {
    if (ctx && error) {
        getErrorLogger(ctx).error(formatError(ctx, error, resTime));
    }
};

//封装响应日志
logUtil.logResponse = function (ctx, resTime) {
    if (ctx) {
        getResLogger(ctx).info(formatRes(ctx, resTime));
    }
};

//格式化响应日志
var formatRes = function (ctx, resTime) {
    var logText = new String();

    //响应日志开始
    logText += "\n" + "*************** response log start ***************" + "\n";

    //添加请求日志
    logText += formatReqLog(ctx.request, resTime);

    //响应状态码
    logText += "response status: " + ctx.status + "\n";

    //响应内容
    logText += "response body: " + "\n" + JSON.stringify(ctx.body) + "\n";

    //响应日志结束
    logText += "*************** response log end ***************" + "\n";

    return logText;

}

//格式化错误日志
var formatError = function (ctx, err, resTime) {
    var logText = new String();

    //错误信息开始
    logText += "\n" + "*************** error log start ***************" + "\n";

    //添加请求日志
    logText += formatReqLog(ctx.request, resTime);

    //错误名称
    logText += "err name: " + err.name + "\n";
    //错误信息
    logText += "err message: " + err.message + "\n";
    if (err.other) {
        //额外错误信息
        logText += "err other message: " + err.other + "\n";
    }
    //错误详情
    logText += "err stack: " + err.stack + "\n";

    //错误信息结束
    logText += "*************** error log end ***************" + "\n";

    return logText;
};

//格式化请求日志
var formatReqLog = function (req, resTime) {

    var logText = new String();

    var method = req.method;
    //访问方法
    logText += "request method: " + method + "\n";
    logText += "request conentType: " + req.header['content-type'] + "\n";
    //请求原始地址
    logText += "request originalUrl:  " + req.originalUrl + "\n";

    //客户端ip
    logText += "request client ip:  " + req.ip + "\n";

    //开始时间
    var startTime;
    //请求参数
    if (method === 'GET') {
        logText += "request query:  " + JSON.stringify(req.query) + "\n";
        // startTime = req.query.requestStartTime;
    } else {
        logText += "request body: " + "\n" + JSON.stringify(req.body) + "\n";
        // startTime = req.body.requestStartTime;
    }
    //服务器响应时间
    logText += "response time: " + resTime + "\n";

    return logText;
}

module.exports = logUtil;


<|start_filename|>bin/Run.js<|end_filename|>
#!/usr/bin/env node
let init =require("./Init")

init().then(function(){
	var current_path = process.cwd();
    require(current_path + '/bin/Main')
})


<|start_filename|>src/shared/utils/CommonUtils.js<|end_filename|>
var dateFormat = require('dateformat');
var utility = require('utility');

//2013-04-17 14:43:02
exports.YYYYMMDDHHmmss = function() {
    var now = new Date();
    return dateFormat(now, "yyyy-mm-dd HH:MM:ss");
};
exports.YYYYMMDDHHmmssl = function() {
    var now = new Date();
    return dateFormat(now, "yyyymmddHHMMssl");
};
exports.YYYYMMDDHHmm = function() {
    var now = new Date();
    return dateFormat(now, "yyyymmddHHMM");
};
exports.print = function(msg) {
    console.log(utility.logDate() + ":" + msg)
}
exports.errorMsg = function(error) {
    let msg = ""
    if (typeof error == 'object') {
        if (error.name) msg = msg + "    Error.name:" + error.name + "\n"
        if (error.message) msg = msg + "    Error.message:" + error.message + "\n"
        if (error.stack) msg = msg + "    Error.stack:" + error.stack + "\n"
    } else {
        msg = error
    }
    return msg
}

exports.printError = function(error, title) {
    if (!error) return
    let msg = "Error:\n"
    if (title) {
        msg = msg + ",title=" + title
    }
    msg = msg + "," + exports.errorMsg(error)
    console.error(utility.logDate() + ":" + msg)
}
exports.findObjInArray = function(list, key, value) {
    for (let one of list) {
        if (one[key] == value) {
            return one
        }
    }
    return null
}
exports.convertDot = function(str) {
    if (str) {
        return str.replace(/\./g, "@")
    }
    return str
}
exports.convertDotBack = function(str) {
    if (str) {
        return str.replace(/\@/g, ".")
    }
    return str
}

exports.clone=function(obj) {    
    if(typeof obj==='object') {
     if(Array.isArray(obj)) {
        return exports.cloneArray(obj)
     } else {
       return exports.cloneObject(obj)
     }
    } else {
        return obj
    }
}
exports.cloneArray=function(obj) {
    let c=[]
    for(let one of obj) {
        c.push(exports.clone(one))
    }
    return c
}
exports.cloneObject=function(obj) {
    let c={}
    for(let one of Object.keys(obj)) {
        c[one]=exports.clone(obj[one])
    }
    return c
}

exports.findObjInArray = function(list, key, value) {
    for (let one of list) {
        if (one[key] == value) {
            return one
        }
    }
    return null
}


<|start_filename|>src/shared/meta/metaFiles.js<|end_filename|>
module.exports={
'/company/Department':require('./company/Department'),
'/company/Employee':require('./company/Employee'),
'/example/index':require('./example/index'),
'/example/Input':require('./example/Input'),
'/example/SetThemeColor':require('./example/SetThemeColor'),
'/example/Tree':require('./example/Tree'),
'/sys/Role':require('./sys/Role'),
'/sys/User':require('./sys/User'),
}

<|start_filename|>src/server/middlewares/ApiRequestLog.js<|end_filename|>
//log工具
const logUtil = require('../utils/log_util');

var ApiError = require('../error/ApiError');


var url_filter = (pattern) => {

    return async(ctx, next) => {
        //响应开始时间
        const start = new Date();
        //响应间隔时间
        var ms;

        var reg = new RegExp(pattern);

        try {
            //先去执行路由
            await next();
        } catch (error) {
            ctx.status = 200;
            //如果异常类型是API异常并且通过正则验证的url，将错误信息添加到响应体中返回。
            if (error instanceof ApiError && reg.test(ctx.originalUrl)) {
                ms = new Date() - start;
                //记录异常日志
                logUtil.logError(ctx, error, ms);

                ctx.body = {
                    status: {
                        code: error.code.toString(),
                        msg: error.message,
                        other:error.other
                    }
                }
            } else {
                let code = 'unknow';
                let msg = error.name + ":" + error.message;
                ctx.body = { status: { code, msg } };
            }
            //继续抛，让外层中间件处理日志
            //throw error;
        }

        //通过正则的url进行格式化处理
        if (reg.test(ctx.originalUrl)) {
            ms = new Date() - start;
            //记录响应日志
            logUtil.logResponse(ctx, ms);
        }
    }
}


// module.exports = response_formatter;
module.exports = url_filter;

<|start_filename|>src/shared/i18n/en.json<|end_filename|>
{
	"add":"Add",
	"modify":"Modify",
	"delete":"Delete",
	"cancel":"cancel",
	"submit":"Submit",	
	"submitSuccess":"Submit Success",
	"submitFail":"Submit fail:{msg}",
	"uploadFile_illegalPrompt":"Illegal file,only '{fileType}' file",
	"inputPrompt":"Enter {label}",
    "deleteConfirm":"Are you sure you want to delete selected records?",
    "prompt":"Prompt",
    "deleteSuccess":"Delete success",
    "deleteFail":"Delete fail:{msg}",

       "meta":{
    	"role":{
    		"roleName":"Role Name",
    		"memo":"Memo"
    	}
    }
}

<|start_filename|>src/shared/meta/GenerateMetaFiles.js<|end_filename|>

const fs=require("fs")
const dir = require('node-dir');

async function subdir() {
	return new Promise(function(resolve,reject){
		dir.subdirs(__dirname, function(err, subdirs) {
	     if (err) throw err;
	     	resolve(subdirs)
	    })
	})
}
module.exports=async function() {	
		let subdirs=await subdir()	    
	    let paths=[]
	    for(let oneDir of subdirs) {
			let files=dir.files(oneDir,{sync:true})
			for(let f of files) {
				let p=f.replace(__dirname,"").replace(/\\/g, "/")
				paths.push(p.substring(0,p.length-3))
			}
	    }	   
	    let content="module.exports={"
	    for(let one of paths) {
	    	content=content+"\n'"+one+"':"+"require('."+one+"'),"
	    }
	    content=content+"\n}"
        fs.writeFileSync(__dirname+"/metaFiles.js",content)        
	   return
}

<|start_filename|>src/server/utils/Rc4Encrypt.js<|end_filename|>
var utility = require('utility');

const KEY = "<KEY>";

// function rc4Encrypt( data){
//     return utility.base64encode(encodeHex(rc4(data,KEY)));

// }

// function rc4Decode( data){
//     var des=rc4(decodeHex(utility.base64decode(data)),KEY);
//     //var des=rc4(utility.base64decode(data),KEY);
//     return des;    
// }

function rc4Encrypt(data) {
    return encodeHex(rc4(utility.base64encode(data), KEY));
}

function rc4Decode(data) {
    console.log("rc4Decode:",data)
    console.log("rc4DecodeKey:",KEY)
    var des = utility.base64decode(rc4(decodeHex(data), KEY));
     console.log("result:",des)
    return des;
}

function encodeHex(str) {
    var HEX = "0123456789abcdef";
    let radix = 16;
    let len = str.length;
    let retStr = "";
    for (var i = 0; i < len; i++) {
        var num = str.charCodeAt(i);
        retStr += HEX.charAt((num >>> 4) & 0x0F);
        retStr += HEX.charAt(num & 0x0F);
    }
    return retStr;
}

function decodeHex(str) {
    var map = { "0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "a": 10, "b": 11, "c": 12, "d": 13, "e": 14, "f": 15, };
    let len = str.length;
    let retStr = "";
    for (var i = 0; i < len / 2; i++) {
        var ha = str[2 * i];
        var h = map[ha];
        var l = map[str[2 * i + 1]];
        retStr += String.fromCharCode((h << 4) | l);
    }
    return retStr;


}



function rc4(data, key) {
    var iS = Array(256);
    var iK = Array(256);
    for (var i = 0; i < 256; i++) {
        iS[i] = i;
    }

    var j = 1;
    for (var i = 0; i < 256; i++) {
        iK[i] = key.charCodeAt((i % key.length));
    }
    var j = 0;
    for (var i = 0; i < 256; i++) {
        j = (j + iS[i] + iK[i]) % 256;
        var temp = iS[i];
        iS[i] = iS[j];
        iS[j] = temp;
    }
    var i = 0;
    var j = 0;
    var encodeStr = "";
    var das = Array(data.length);
    for (var x = 0; x < data.length; x++) {
        var i = (i + 1) % 256;
        var j = (j + iS[i]) % 256;
        var temp = iS[i];
        iS[i] = iS[j];
        iS[j] = temp;
        var t = (iS[i] + (iS[j] % 256)) % 256;
        var iY = iS[t]
        das[x] = String.fromCharCode(data.charCodeAt(x) ^ iY);
    }
    return das.join('');
}

exports.rc4Encrypt = rc4Encrypt;
exports.rc4Decode = rc4Decode;
// var d="";
let a = { payInfo: { orderIdGm: '123123', orderIdWl: '1_ssabc' } }
let src = JSON.stringify(a)
let dec = rc4Encrypt(src)
console.log(dec);
console.log(src);
console.log(rc4Decode(dec));


/*let query = {
    "appinfo": {
        "apkm5": "e1bef82222114f84d52fb0c63175c658",
        "appid": "20180614001",
        "appkg": "cn.m4399.adsample",
        "appnm": "SGJTZGs=",
        "appph": "L2RhdGEvYXBwL2NuLm00Mzk5LmFkc2FtcGxlLTEuYXBr",
        "appsnm5": "8e0871a4e699510903e17f0fa396bf87",
        "appvc": "1",
        "appvn": "1.1",
        "issysap": "false"
    },
    "chnlinfo": {
        "cnid": "1",
        "cpid": "2",
        "gnid": "1000",
        "scnid": "1"
    },
    "eventid": "ccecc5898ffd4e9d9d396dd81a162d5c",
    "loc_info": {
        "is_update_location_info": "y",
        "locationInfo": ""
    },
    "ph_detailinfo": {
        "ph_brand": "Z29vZ2xl",
        "ph_build_id": "KTU84P",
        "ph_cpu_abi": "armeabi-v7a",
        "ph_cpuhardware": "hammerhead",
        "ph_desity": "480",
        "ph_manufact": "LGE",
        "ph_model": "TmV4dXMgNQ==",
        "ph_oritantion": "v",
        "ph_platform": "msm8974",
        "ph_product": "hammerhead",
        "ph_release_ver": "4.4.4",
        "ph_rom_id": "KTU84P",
        "ph_scrnsize": "1080X1776",
        "ph_sysvc": "19"
    },
    "ph_netinfo": {
        "ph_availmem": "867MB",
        "ph_country": "CN",
        "ph_date": "2018-06-23 07:15:10",
        "ph_language": "zh",
        "ph_latitude": "uk",
        "ph_longitude": "uk",
        "ph_runtime": "364326846",
        "ph_time_zone": "中国标准时间",
        "ph_totalmem": "1855MB",
        "ph_wifi_mac": "d4:ee:07:2d:b7:c0",
        "ph_wifi_name": "Ik1hcnMtWXl6eCI=",
        "ph_wifi_pip": "192.168.3.11",
        "ph_wifi_pmac": "00:90:4c:f6:c3:3a"
    },
    "phsiminfo": {
        "androidid": "234",
        "imei": "358240058093147",
        "imsi": "error_absent",
        "mcc": "uk",
        "mnc": "uk",
        "simcn": "uk",
        "simformat": "uk",
        "simoprt": "error_absent",
        "simoprtnm": "uk",
        "snwcn": "uk",
        "snwoprt": "error_absent",
        "snwoprtnm": "uk"
    },
    "sign_info": "5904d2e016450da505619cc7d500caed",
    "ssdkinfo": {
        "sdks": [
            {
                "midsn": "20180604",
                "midvc": "1.0",
                "sdknm": "Gdt",
                "sdkvc": "4.15.559"
            },
            {
                "midsn": "20180604",
                "midvc": "1.0",
                "sdknm": "Baidu",
                "sdkvc": "4.6"
            },
            {
                "midsn": "20180620",
                "midvc": "1.0",
                "sdknm": "Sisanjiujiu",
                "sdkvc": "1.0.3"
            },
            {
                "midsn": "20180620",
                "midvc": "1.0",
                "sdknm": "Chance",
                "sdkvc": "5.3.9"
            },
            {
                "midsn": "20180620",
                "midvc": "1.0",
                "sdknm": "Youmi",
                "sdkvc": "7.5.1"
            },
            {
                "midsn": "20180621",
                "midvc": "1.0",
                "sdknm": "Oppo",
                "sdkvc": "249"
            }
        ],
        "shellsn": "20180604",
        "shellvc": "1.0"
    }
}
<<<<<<< .mine



let ss=rc4Encrypt(JSON.stringify(query))
console.log("test--------------")
console.log(ss)
console.log("dss",rc4Decode(ss))

let s2="e5775f68138abfc9f69041b107061fc8f8c0a9904ec13489c0559092519547c8fadbc217fb187976b993d3c48e37c3b2c47577634ba27aa1a6337c0bf10743697ac52782deb4050228ef64f52316d4ad88cdf8fc8a"
console.log(s2)
console.log(ss)

console.log(s2==22)

console.log(rc4Decode(s2))


||||||| .r337

console.log(rc4Encrypt(JSON.stringify(query)))=======
*/
//console.log("rc4Encrypt:"+rc4Encrypt(JSON.stringify(query)))>>>>>>> .r347


<|start_filename|>src/shared/meta/example/Input.js<|end_filename|>

const dateFormat = require('dateformat');
const pathUtil = require('path');
const provinceAndCityData=require("../../../../config/client/provinceAndCityTree")

let methods = {
    
    fileName: function(oldName) {
        return dateFormat(new Date(), "yyyymmddHHMMssl") + pathUtil.extname(oldName);
    } ,
    formatEnable: function (row, column,cellValue) {
        return cellValue? "启用" : "禁用"
    }
};

module.exports = {
    entityName: 'Example',    
    columnsDef: [{
            prop: 'text',
            label: '文本框',
            width: 240,
            filter: true,
            input: { type: 'text', rule: 'required' }
        },
        {
            prop: 'textarea',
            label: '多行文本框',
            width: 240,
            filter: true,
            input: { type: 'textarea', rule: 'required' }
        },        
        {
            prop: 'select',
            label: '选择框',
            width: 150,
            input:{type:'select',filterable:true,allowCreate:true,clearable:true,options:[{label:'黄色',value:'黄色'},{label:'白色',value:'色色'}]}
        },
        {
            prop: 'select_ajax',
            label: '动态选择框',
            width: 150,
            input:{type:'select',ajax:{path:'/company/Department',label:'name',value:'_id'}}                   
        },     
        {
            prop: 'radioGroup',
            label: '单选框',
            width: 150,
            input:{type:'radioGroup',options:[{label:'启用',value:true},{label:'禁用',value:false}]},
            formatter:methods.formatEnable
        },        
        {
            prop: 'checkbox',
            label: '多选框',
            width: 150,
            input:{type:'checkbox'}
        } ,
        {
            prop: 'checkboxGroup',
            label: '多选框组',
            width: 150,
            input:{type:'checkboxGroup',options:[{label:'北京',value:'bj'},{label:'深圳',value:'sz'},{label:'广州',value:'gz'}]}
        },
        {
            prop: 'date',
            label: '日期',
            width: 150,

            input:{type:'date',subType:'date',format:'yyyy 年 MM 月 dd 日',valueFormat:'yyyyMMdd'}
        } 
        ,
        {
            prop: 'time',
            label: '时间',
            width: 150,
            input:{type:'time'}
        },
        {
            prop: 'datetime',
            label: '日期时间',
            width: 150,
            input:{type:'date',subType:'datetime'}
        },        
        {
            prop: 'daterange',
            label: '日期范围',
            width: 150,
            input:{type:'date',subType:'daterange',rangeSeparator:'至',startPlaceholder:'开始日期',endPlaceholder:'结束日期'}
        } ,
                                {
            prop: 'datetimerange',
            label: '日期时间范围',
            width: 150,
            input:{type:'date',subType:'datetimerange',rangeSeparator:'至',startPlaceholder:'开始日期',endPlaceholder:'结束日期'}
        },
        {
        prop: 'fileInfo',
        label: '文件',
        width: 240,
        filter: false,
        input: { type: 'file', savePath: 'example', fileName: methods.fileName, ext: "txt"},
        download:true
      },
      {
        prop:'tree',
        label:'树',
          width:200,
        edit:true,
        add:true,    
        input: {            
            type: 'tree',
            data:provinceAndCityData,
            props:{label:'label',children:'city'},
            nodeKey:'label'

        }
    },   
    {
        prop:'addTime',
        label:'创建时间',
         width:150,
        add:false,
        edit:false
    }   
    ]
}

<|start_filename|>src/server/error/ApiErrorNames.js<|end_filename|>
/**
 * API错误名称
 */
var ApiErrorNames = {};

ApiErrorNames.UNKNOW_ERROR = "unknowError";
ApiErrorNames.ILLEGAL_PARAM = "illegal param";
ApiErrorNames.ILLEGAL_GUN = "illegal gun";
ApiErrorNames.LOGIN_FAIL = "login_fail";
ApiErrorNames.FAIL = "fail";
ApiErrorNames.DUPLICATE_KEY = "duplicate";

ApiErrorNames.ENTITY_NOFIND = "entity_nofind";
ApiErrorNames.NO_LOGIN = "no_LOGIN";
ApiErrorNames.NORIGHT = "no_right";
ApiErrorNames.NOFILE = "no_file";
ApiErrorNames.EMPTY_INPUT = "empty_input";
ApiErrorNames.NO_URL = "no_url";
ApiErrorNames.MATCHING_ERROR = "matching_error";

ApiErrorNames.SDKFILE_DUPLICATE="SDKFILE_DUPLICATE"


/**
 * API错误名称对应的错误信息
 */
const error_map = new Map();

error_map.set(ApiErrorNames.UNKNOW_ERROR, { code: -1, message: '未知错误' });
error_map.set(ApiErrorNames.ILLEGAL_PARAM, { code: 101, message: '非法参数' });
error_map.set(ApiErrorNames.ILLEGAL_GUN, { code: 102, message: '非法枪支' });
error_map.set(ApiErrorNames.LOGIN_FAIL, { code: 103, message: '登陆失败：错误的用户名或密码' });
error_map.set(ApiErrorNames.FAIL, { code: 104, message: '失败' });
error_map.set(ApiErrorNames.ENTITY_NOFIND, { code: 105, message: '实体没找到' });
error_map.set(ApiErrorNames.NO_LOGIN, { code: 106, message: '没有登陆' });
error_map.set(ApiErrorNames.NORIGHT, { code: 107, message: '缺乏权限' });
error_map.set(ApiErrorNames.NOFILE, { code: 108, message: '缺少文件上传' });
error_map.set(ApiErrorNames.EMPTY_INPUT, { code: 109, message: '选项不能为空' });

error_map.set(ApiErrorNames.DUPLICATE_KEY, { code: 110, message: '数据已存在' });

error_map.set(ApiErrorNames.SDKFILE_DUPLICATE, { code: 111, message: 'SDK文件重复' });

//根据错误名称获取错误信息
ApiErrorNames.getErrorInfo = (error_name) => {

    var error_info;

    if (error_name) {
        error_info = error_map.get(error_name);
        console.log(error_name);
        console.log(error_map);
    }

    //如果没有对应的错误信息，默认'未知错误'
    if (!error_info) {
        error_name = UNKNOW_ERROR;
        error_info = error_map.get(error_name);
    }

    return error_info;
}

module.exports = ApiErrorNames;
error_map.set(ApiErrorNames.FAIL, { code: 104, message: '失败' });

<|start_filename|>bin/Init.js<|end_filename|>
let generateMetaFiles=require("../src/shared/meta/GenerateMetaFiles")
var logConfig = require('../config/server/log_config');
var fs = require('fs')

module.exports=async function() {
	await generateMetaFiles()
	initLogPath();
}


/**
 * 确定目录是否存在，如果不存在则创建目录
 */
var confirmPath = function(pathStr) {
    if (!fs.existsSync(pathStr)) {
        fs.mkdirSync(pathStr);
        console.log('createPath: ' + pathStr);
    }
}

/**
 * 初始化log相关目录
 */
var initLogPath = function() {
    //创建log的根目录'logs'
    if (logConfig.baseLogPath) {
        confirmPath(logConfig.baseLogPath)
        //根据不同的logType创建不同的文件目录
        for (var i = 0, len = logConfig.appenders.length; i < len; i++) {
            if (logConfig.appenders[i].path) {
                confirmPath(logConfig.baseLogPath + logConfig.appenders[i].path);
            }
        }
    }
}



<|start_filename|>src/server/controllers/download.js<|end_filename|>
const send = require('koa-send')
const pathUtil=require("path")
const fs=require("fs")


let {metaIndex,metaIndexServer} = require('../include');



let path = "/download/:path*";


async function doRequest(ctx, next) {
    let { path } = ctx.params;
    let metaData = metaIndex["/" + path];
    let metaDataServer = metaIndexServer["/" + path+"_server"];    
    let entityName = metaIndex.entityName;
    let { _id, prop } = ctx.query    
    if (_id && prop) {
        let record = await baseDao.queryOne(ctx.db, entityName, _id);
        if (record) {
            let fileInfo = record[prop]
            if (fileInfo && fileInfo.path && fileInfo.srcName) {
                console.log("----------attachment", fileInfo.srcName)
                ctx.attachment(fileInfo.srcName)
                let absPath = pathUtil.join(process.cwd(), config.dataDir)
                console.log("downloadFile:",absPath)
                let filePath=pathUtil.join(absPath,fileInfo.path)
                if(fs.existsSync(filePath)) {
                  await send(ctx, fileInfo.path, { root: absPath })   
                  return
                }else {
                    console.log("file not found:",filePath)
                }     
            }
        }
    }
    ctx.status = 404
}

export { path, doRequest };

<|start_filename|>src/server/controllers/admin/logout.js<|end_filename|>


let path = "/logout";
let needParams = [];

async function doRequest(ctx, next) {
    ctx.session=null;   
    console.log("unSetSession：");
}


export {
    path,
    needParams,
    doRequest
};

<|start_filename|>src/shared/meta/company/Employee.js<|end_filename|>
let methods = {
    
    formatSex: function (row, column,cellValue) {
        return cellValue? "男" : "女"
    },
    formatDepartment:function(row, column,cellValue) {
        if(data.DepartmentList) {
          for (let item of data.DepartmentList) {
            if (cellValue == item._id) return item.name;
          }
        }

    }
};

let loadDatas = [{
    name: 'DepartmentList',
    ajax: {
        path: '/company/Department',
        projects:{_id:1,name:1}
    }
}]

let data = {}


module.exports = {
    entityName: 'employee',   
    loadDatas,
    data:data,
    columnsDef: [{
            prop: 'name',
            label: '姓名',
            width: 240,
            filter: true,
            input: { type: 'text', rule: 'required' },
            index:true
        },
        {
            prop: 'sex',
            label: '性别',
            width: 150,
            input:{type:'radioGroup',options:[{label:'男',value:true},{label:'女',value:false}]},
            formatter:methods.formatSex
        },   
        {
            prop: 'department',
            label: '部门',
            width: 150,
            input:{type:'select',ajax:{path:'/company/Department',label:'name',value:'_id',projects:{_id:1,name:1}}},
            formatter:methods.formatDepartment,
            autoRef:true
        },       
        {
            prop: 'memo',
            label: '备注',
            width: 150,
            input: 'text'
        }
    ]
}

<|start_filename|>src/shared/i18n/index.js<|end_filename|>
/*import locale from 'element-ui/lib/locale/lang/en'

function detectLocale() {
 var JsSrc =(navigator.language || navigator.browserLanguage).toLowerCase();
 if(JsSrc.indexOf('zh')>=0) return 'en'
 return 'en'
}


exports.load = function(Vue,ElementUI) {
	Vue.i18n.add("en",require("./en.json"))
	Vue.i18n.add("zh",require("./zh.json"))
	let lang=detectLocale()
	Vue.i18n.set(lang)
	if(Vue.i18n.locale()=='en') {    
      Vue.use(ElementUI,{ locale });
    } else {
      Vue.use(ElementUI); 
    }
zzzz
    Vue.config.lang = 'zh-cn'
Vue.locale('zh-cn', zhLocale)
Vue.locale('en', enLocale)
}
*/

import enLocale from 'element-ui/lib/locale/lang/en'
import zhLocale from 'element-ui/lib/locale/lang/zh-CN'

module.exports={
	zh:{...require("./zh.json"),
	     ...zhLocale
       },
	en:{...require("./en.json"),
	    ...enLocale
       }
}

<|start_filename|>src/client/components/PageUtil.js<|end_filename|>
exports.toSelectOptions = function(datas, label, value) {
    //console.log("toSelectOptionsbef:" + JSON.stringify(datas));
    if (!label && !value) return datas;
    if (!label) label = 'label';
    if (!value) value = 'value';
    let res = [];
    if (datas && datas.length > 0) {
        for (let one of datas) {
            if(typeof label=='string') {
               if (one[label] && one[value]) {                
                res.push({ label: one[label], value: one[value] });
              } 
            } else if(typeof label=='function') {
                 res.push({ label: label(one), value: one[value] });
            } 
            
        }
    }
    //console.log("toSelectOptionsRes:"+JSON.stringify(res));
    return res;
}


exports.convertDot = function(str) {
    if (str) {
        return str.replace(/\./g, "@")
    }
    return str
}
exports.convertDotBack = function(str) {
    if (str) {
        return str.replace(/\@/g, ".")
    }
    return str
}

exports.checkPermission=function(id,action) {
      let user = JSON.parse(sessionStorage.getItem("user"));
      console.log("checkPermission",user,id,action)
      if(user.type=='root') return true
      if(user.right) {
        return user.right[id] && user.right[id][action]
      }
      return false
}

<|start_filename|>config/shared/nav_menu.js<|end_filename|>
module.exports = {
    title: 'HR系统',
    pwdmd5:'<PASSWORD>',
    nav_menu: [{
            id:100,
            path: '/',
            name: '功能',
            iconCls: 'el-icon-menu', //图标样式class       
            children: [
                {id:101, path: '/company/Department', name: '部门' },
                {id:102, path: '/company/Employee', name: '员工' },

            ]
        },              
        {
            id:200,
            path: '/',
            name: '样例',
            iconCls: 'el-icon-menu',    
            children: [
                { id:201,path: '/example/Input', name: '输入大全' },
                { id:202,path: '/example/Tree', name: '树之CRUD' }, // 
                { id:203,path: '/example/SetThemeColor', name: '设置主题颜色' } // 
            ]
        }
    ]
};

<|start_filename|>src/server/middlewares/request_checkNeedParams.js<|end_filename|>



var ApiError = require('../error/ApiError');
var ApiErrorNames = require('../error/ApiErrorNames');

var CHECK_MAP = {
};

var checkNeedParams = (ctx, pattern) => {
    var path = ctx.originalUrl.replace(pattern, "");
    var needParams = [];

    for (let key of Object.keys(CHECK_MAP)) {
       if(path.endsWith(key)) {
             needParams = CHECK_MAP[key];
             break;
       }
    }

    var data = ctx.request.body;
    if(ctx.request.body.fields) {
        data=ctx.request.body.fields;
    }
    if (data) {
        for (let i = 0; i < needParams.length; i++) {
            let paramNames = needParams[i];
            let names = paramNames.split(".");
            let current={};
            for (let x = 0; x < names.length; x++) {
                if(x==0) {
                     if (!data[names[x]]) {
                         throw new ApiError(ApiErrorNames.ILLEGAL_PARAM,"no param:" + toStrs(names,x));
                         
                     } else {
                         current=data[names[x]];
                     }
                } else {
                     if (!current[names[x]]) {
                        throw new ApiError(ApiErrorNames.ILLEGAL_PARAM,"no param:" + toStrs(names,x));                         
                     } else {
                         current=current[names[x]];
                     }
                }
            }

        }
    }

}
function toStrs(names,x) {
    var str="";
    for(let i=0;i<names.length;i++) {
      if(i<=x) {
          str=str+names[i];
      }
      if(i<x) {
          str=str+".";
      }
    }
    return str;
}
var check = (pattern) => {

    return async (ctx, next) => {

        var reg = new RegExp("^" + pattern);
        //通过正则的url进行参数检查
        if (reg.test(ctx.originalUrl)) {
            checkNeedParams(ctx, pattern);
            await next();
        } else {
            await next();
        }


    }
}

var register = (pattern, fun) => {
    CHECK_MAP[pattern] = fun;
}
// module.exports = response_formatter;

exports.check = check;
exports.register = register;



<|start_filename|>src/server/routers/download/index.js<|end_filename|>
var router = require('koa-router')();



import * as download from './../../controllers/download';
import * as downloadTemp from './../../controllers/downloadTemp';




router.get(download.path, download.doRequest);


router.get(downloadTemp.path, downloadTemp.doRequest);

export { router };

<|start_filename|>src/client/main.js<|end_filename|>
import babelpolyfill from "babel-polyfill";
import Vue from "vue";

import App from "./App.vue";
import ElementUI from "element-ui";


import "element-ui/lib/theme-chalk/index.css";
//import "./assets/theme/theme-green/index.css"
import VueRouter from "vue-router";
import store from "./vuex/store";
import Vuex from "vuex";

import VueI18n from 'vue-i18n'
//import NProgress from "nprogress"
//import "nprogress/nprogress.css"
import { routes } from "./routes";

//Mock.bootstrap();
import "font-awesome/css/font-awesome.min.css";
import TableAdmin from './components/TableAdmin.vue';
import TreeAdmin from './components/TreeAdmin.vue';
import messages from './../shared/i18n';

import LoadCustomPage from './components/custom/'

import { generateRoutes } from "./routes";


//i18n_res.load(Vue,ElementUI)

function detectLocale() {
 var JsSrc =(navigator.language || navigator.browserLanguage).toLowerCase();
 if(JsSrc.indexOf('zh')>=0) return 'zh'
 return 'en'
}
Vue.use(VueI18n)
const i18n = new VueI18n({
  locale: detectLocale(), // set locale
  messages, // set locale messages
})


Vue.use(ElementUI, {
  i18n: (key, value) => i18n.t(key, value)
})

Vue.use(VueRouter);
Vue.use(Vuex);
Vue.component('table-admin', TableAdmin);
Vue.component('tree-admin', TreeAdmin);

LoadCustomPage.load(Vue)

//NProgress.configure({ showSpinner: false });
console.log(routes);
const router = new VueRouter({
    routes
})
//解决登录后刷新空白问题：因为刷新后所以东西都重新加载，login动态加载的routes也丢失了，这里再次加载
router.addRoutes(generateRoutes());
router.beforeEach((to, from, next) => {
    //NProgress.start();
    console.log("beforeEach:" + JSON.stringify(sessionStorage));
    if (to.path == "/login") {
        sessionStorage.removeItem("user");
    }
    let user = JSON.parse(sessionStorage.getItem("user"));
    if (!user && to.path != "/login") {
        next({ path: "/login" })
    } else {
        console.log("routerTo:"+to.path)
        next()
        console.log("routerOk:",to)
    }
})
router.onError(function(err){
    console.err(err)
})



new Vue({
    i18n,
    router, 
    render: h => h(App)
}).$mount("#app")

<|start_filename|>src/client/components/custom/index.js<|end_filename|>

import ThemeColor from './ThemeColor.vue'

exports.load = function(Vue) {	
    Vue.component('set-theme-color', ThemeColor)

    
}

<|start_filename|>config/server/log_config.js<|end_filename|>
/**
 * log4js 配置文件
 * 
 * 日志等级由低到高
 * ALL TRACE DEBUG INFO WARN ERROR FATAL OFF. 
 * 
 * 关于log4js的appenders的配置说明
 * https://github.com/nomiddlename/log4js-node/wiki/Appenders
 */

var path = require('path');
//日志根目录
var baseLogPath = path.resolve(__dirname, '../../logs')

//错误日志目录
var androidTouchsdk_errorPath = "/api/";
var androidTouchadmin_errorPath = "/admin/";
//错误日志文件名
var errorFileName = "error";
//错误日志输出完整路径
var androidTouchsdk_errorLogPath = baseLogPath + androidTouchsdk_errorPath + "/" + errorFileName;
var androidTouchadmin_errorLogPath = baseLogPath + androidTouchadmin_errorPath + "/" + errorFileName;

// var errorLogPath = path.resolve(__dirname, "../logs/error/error");


//响应日志目录
var androidTouchsdk_responsePath = "/api/";
var androidTouchadmin_responsePath = "/admin/";
//响应日志文件名
var responseFileName = "response";
//响应日志输出完整路径
var androidTouchsdk_responseLogPath = baseLogPath + androidTouchsdk_responsePath + "/" + responseFileName;
var androidTouchadmin_responseLogPath = baseLogPath + androidTouchadmin_responsePath + "/" + responseFileName;
// var responseLogPath = path.resolve(__dirname, "../logs/response/response");

module.exports = {
    "appenders": [
        { type: 'console' },
        //错误日志
        {
            "category": "androidTouchsdk.errorLogger", //logger名称
            "type": "dateFile", //日志类型
            "filename": androidTouchsdk_errorLogPath, //日志输出位置
            "alwaysIncludePattern": true, //是否总是有后缀名
            "pattern": "-yyyy-MM-dd.log", //后缀，每天创建一个新的日志文件
            "path": androidTouchsdk_errorPath //自定义属性，错误日志的根目录
        },
        //响应日志
        {
            "category": "androidTouchsdk.resLogger",
            "type": "dateFile",
            "filename": androidTouchsdk_responseLogPath,
            "alwaysIncludePattern": true,
            "pattern": "-yyyy-MM-dd.log",
            "path": androidTouchsdk_responsePath
        },
        //错误日志
        {
            "category": "androidTouchadmin.errorLogger", //logger名称
            "type": "dateFile", //日志类型
            "filename": androidTouchadmin_errorLogPath, //日志输出位置
            "alwaysIncludePattern": true, //是否总是有后缀名
            "pattern": "-yyyy-MM-dd.log", //后缀，每天创建一个新的日志文件
            "path": androidTouchadmin_errorPath //自定义属性，错误日志的根目录
        },
        //响应日志
        {
            "category": "androidTouchadmin.resLogger",
            "type": "dateFile",
            "filename": androidTouchadmin_responseLogPath,
            "alwaysIncludePattern": true,
            "pattern": "-yyyy-MM-dd.log",
            "path": androidTouchadmin_responsePath
        }
    ],
    "levels": //设置logger名称对应的的日志等级
    {
        "sdk.errorLogger": "ERROR",
        "sdk.resLogger": "ALL",
        "admin.resLogger": "ERROR",
        "admin.resLogger": "ALL"
    },
    "baseLogPath": baseLogPath //logs根目录
}

<|start_filename|>src/server/routers/api/index.js<|end_filename|>
var router = require('koa-router')();


import { router as adminRouter } from './admin';


router.use('/admin', adminRouter.routes(), adminRouter.allowedMethods());





export { router };

<|start_filename|>src/shared/i18n/zh.json<|end_filename|>
{
	"add":"增加",
	"modify":"编辑",
	"delete":"删除",
	"cancel":"取消",
    "submit":"提交",	
	"submitSuccess":"提交成功",
	"submitFail":"提交失败:{msg}",
	"uploadFile_illegalPrompt":"文件非法，只能是:'{fileType}'文件'",
    "inputPrompt":"请输入{label}",
    "deleteConfirm":"确认删除选中记录吗？",
    "prompt":"提示",
    "deleteSuccess":"删除成功",
    "deleteFail":"删除失败:{msg}",

    "meta":{
    	"role":{
    		"roleName":"角色名",
    		"memo":"备注",
    		"permission":"权限"
    	}
    }
}

<|start_filename|>src/server/meta/indexServer.js<|end_filename|>
var dir = require('node-dir');
const path=require("path")

let map = {};

dir.subdirs(__dirname, function(err, subdirs) {
    if (err) throw err;
    for(let oneDir of subdirs) {
        let dirName=path.basename(oneDir)        
        loadDir(dirName,path.join(__dirname,dirName))        
    }
});

function loadDir(moduleName,dirPath) {
    dir.files(dirPath, function(err, files) {
     if (err) throw err;
     for(let oneFile of files) {        
        let key=path.basename(oneFile,".js")        
          console.log("server loaded:" + "/" + moduleName + "/" + key);
           map["/" + moduleName + "/" + key] = require(oneFile)
        
    }
});
}

module.exports = map;

<|start_filename|>src/server/controllers/admin/login.js<|end_filename|>

let { utility, ApiError, ApiErrorNames, config, services, baseDao ,pwdmd5,metaIndex} = require('../../include')


let path = "/login";
let needParams = ["username", "password"];


async function doRequest(ctx, next) {
    if(ctx.session.lastTime) {
        if((new Date().getTime()-ctx.session.lastTime)<2*1000) {
             ctx.session.lastTime=new Date().getTime()
             console.log("--登录太频繁--")
              throw new ApiError(ApiErrorNames.LOGIN_FAIL);
        }           
    }
    ctx.session.lastTime=new Date().getTime()
    var username = ctx.request.body.username;
    var password = ctx.request.body.password;
    if (!username) username = ctx.request.query.username;
    if (!password) password = ctx.request.query.password;
    if (!username) username = "unknow";
    if (!password) password = "<PASSWORD>";        
    let user=await ctx.db("user").findOne({username})
    console.log(user);
    let pmd5=utility.md5(user.password+pwdmd5)
    if(pmd5!=password) {
        throw new ApiError(ApiErrorNames.LOGIN_FAIL);
    }

    if (user) {
        user.right = {};
        if (user.type!='root') {    
         if(user.enable==false) throw new ApiError(ApiErrorNames.LOGIN_FAIL);
        if(user.roles && user.roles.length > 0)       {
            let roles = await findRoles(ctx.db, user.roles);  

            for (let role of roles) {
                if (role.right) {
                    user.right = Object.assign(user.right, role.right);
                }
            }     
            let subPermissions=[]
            for(let key of Object.keys(user.right))  {
                 for(let path of Object.keys(metaIndex))  {
                    if(metaIndex[path].id==key) {
                        if(metaIndex[path].subPermissions) {
                            subPermissions=subPermissions.concat(metaIndex[path].subPermissions)
                        }
                        break;
                    }
                 }
                
            }
            for(let one of subPermissions) {
                 for(let path of Object.keys(metaIndex))  {
                    if(one==path) {
                        if(!user.right[metaIndex[one].id]) {
                            user.right[metaIndex[one].id]=true
                        }
                    }
                 }
            }
        }
    }

        ctx.session.user = user;
        user.password = <PASSWORD>;
        ctx.body = {
            user
        };

    } else {        
        throw new ApiError(ApiErrorNames.LOGIN_FAIL);
    }
}


async function findRoles(db, roleIds) {        
        let findDocs=await db("role").find({ _id: { $in: roleIds } })
        let docs=await findDocs.toArray()
        return docs
}


export {
    path,
    needParams,
    doRequest
};

<|start_filename|>src/server/error/ApiError.js<|end_filename|>
const ApiErrorNames = require('./ApiErrorNames');


/**
 * 自定义Api异常
 */
class ApiError extends Error{
    
    //构造方法 other:附加信息只会记录在日志里
    constructor(error_name,other){
        super();
    
        var error_info = ApiErrorNames.getErrorInfo(error_name);

        this.name = error_name;
        this.code = error_info.code;
        this.message = error_info.message;
        if(other) {
            this.other=other;
        }
    }
}



module.exports = ApiError;

<|start_filename|>src/client/api/api.js<|end_filename|>
import axios from 'axios';

let base = '/api/admin';

export const requestLogin = params => { return axios.post(`${base}/login`, params).then(res => res.data); };
export const requestLogout = params => { return axios.post(`${base}/logout`, params).then(res => res.data); };


export const getUserList = params => { return axios.get(`${base}/user/list`, { params: params }); };

export const getUserListPage = params => { return axios.get(`${base}/sys/user/listpage`, { params: params }); };

export const removeUser = params => { return axios.get(`${base}/sys/user/remove`, { params: params }); };

export const batchRemoveUser = params => { return axios.get(`${base}/sys/user/batchremove`, { params: params }); };

export const editUser = params => { return axios.get(`${base}/sys/user/edit`, { params: params }); };

export const addUser = params => { return axios.get(`${base}/sys/user/add`, { params: params }); };






<|start_filename|>src/server/middlewares/logger.js<|end_filename|>
//log工具
const logUtil = require('../utils/log_util');

module.exports=async (ctx, next) => {   
  //响应开始时间
  const start = new Date();
  //响应间隔时间
  var ms;
  try {
    //开始进入到下一个中间件
  
    await next();
 
    ms = new Date() - start;
    //记录响应日志
    logUtil.logResponse(ctx, ms);

  } catch (error) {
     console.log("---catch error in logger"+error.message);
    ms = new Date() - start;

    //记录异常日志
    logUtil.logError(ctx, error, ms);
    //返回错误信息    
    ctx.body = { status: { code: "1", msg: error.name + ":" + error.message } };

  }
}

<|start_filename|>src/server/services/index.js<|end_filename|>

const dateFormat = require('dateformat');
const path = require('path');
const os = require('os');


const metaIndex=require("../../shared/meta")

let { utility, ApiError, ApiErrorNames, config, CommonUtils,baseDao} = require('../include');



const tmpDir = os.tmpdir();



exports.getGloblConfigValue=async function(db,key) {
    let oneConfig =await baseDao.queryOneByCondition(db,"globalConfig",{key:key})
    if(oneConfig) {
     return oneConfig.value
    } else {
      return null
    }
}
exports.ensureMongoDbIndex=async function(db) {   
   for(let v of Object.values(metaIndex)) {      
      if(!v.columnsDef) continue      
      for(let oneDef of v.columnsDef) {
          if(oneDef.index) {              
              let index=oneDef.index 
              let fields={}
              fields[oneDef.prop]=1
              if(index.sortOrder) {
                 fields[oneDef.prop]=index.sortOrder
              }                          
              db(v.entityName).createIndex(fields,index.options,function(err,reply){
                if(err) {
                  console.log(err)
                  throw err
                } else {
                  console.log(reply)
                }             
              })

          }
      }
   }
}

exports.initAdminAccount=async function(db) {       
        let find=await db("user").findOne({ username:'admin' })        
        if(!find) {           
           db("user").insert({username:'admin',password:'<PASSWORD>',type:'root',enable:true},{},function(x){console.log("insert admin",x)})
        }
}


<|start_filename|>src/server/middlewares/response_formatter.js<|end_filename|>
var ApiError = require('../error/ApiError');

/**
 * 在app.use(router)之前调用
 */
var response_formatter = (ctx) => {
    //如果有返回数据，将返回数据添加到data中
    let res = {
        status: {
            code: "0",
            msg: 'success'
        }
    }
    if (ctx.body) {
        res.data = ctx.body;
    }
    ctx.body = res;
}

var url_filter = (pattern) => {

    return async(ctx, next) => {

        var reg = new RegExp(pattern);
        let fit=reg.test(ctx.originalUrl)
        if(fit) {
        try {
            //先去执行路由
            await next();
        } catch (error) {
            //如果异常类型是API异常并且通过正则验证的url，将错误信息添加到响应体中返回。
            console.log("---catch error in response_formatter");
            console.log(error);
            if (reg.test(ctx.originalUrl)) {
                let code = '';
                let msg = '';
                let other=null
                if (error instanceof ApiError) {
                    code = error.code.toString();
                    msg = error.message;
                    if(error.other) other=error.other
                } else {
                    code = 'unknow';
                    msg = error.name + ":" + error.message;
                }
                ctx.status = 200;
                ctx.body = { status: { code, msg,other } };
            }


            //继续抛，让外层中间件处理日志
            throw error;
        }
        //通过正则的url进行格式化处理       

            response_formatter(ctx);
        } else {
             await next();
        }
    }
}

// module.exports = response_formatter;
module.exports = url_filter;

<|start_filename|>src/server/schedule/index.js<|end_filename|>

var schedule = require("node-schedule");


var task1 = require("./DeleteTable.js")
var task2 = require("./DeleteAdminLog.js")

console.log("---load schedule")

var rule = new schedule.RecurrenceRule();
rule.hour=16
rule.minute =36
rule.second=10
//每天凌晨2点触发
var s1 = schedule.scheduleJob(rule, function () {
    console.log("execute-----")    
    task1.exeuteTask();
    task2.exeuteTask();
});
    task1.exeuteTask();
    task2.exeuteTask();

<|start_filename|>src/shared/meta/example/SetThemeColor.js<|end_filename|>

module.exports ={
	pageAdminComponent:'set-theme-color'
}

<|start_filename|>src/client/include.js<|end_filename|>
import { nav_menu,title,pwdmd5 } from "../../config/shared/nav_menu";

import metaMap from "./../shared/meta";


var md5 = require('md5');
 
export { nav_menu, metaMap,md5,title,pwdmd5 }

<|start_filename|>src/server/meta/example/Input.js<|end_filename|>
var utility = require('utility');

module.exports = {
	beforeAdd(doc,ctx) {
		doc.addTime=utility.YYYYMMDDHHmmss()
		return doc 
	}
}

<|start_filename|>src/shared/meta/company/Department.js<|end_filename|>
module.exports = {
    entityName: 'department',    
    columnsDef: [{
            prop: 'name',
            label: '部门名称',
            width: 240,
            filter: true,
            input: { type: 'text', rule: 'required' },
            index:true
        },
                {
            prop: 'config',
            label: '人数设置',
            width: 150,
            add:false,
            edit:false            
        },
        {
            prop: 'memo',
            label: '备注',
            width: 150,
            input: 'text'
        }
    ],
    extendActionButtons:"department_buttons"
}


<|start_filename|>src/shared/meta/example/Tree.js<|end_filename|>
module.exports = {
    pageAdminComponent:'tree-admin',
    entityName:'category',
    columnsDef: [{
        prop: '_id',
        label: '编码',        
        edit: false,
        width: 200,
        input: { type: 'text', required: true },
        add:true
    },
    {
        prop: 'name',
        label: '名称',
        width: 200,
        input: { type: 'text', required: true }        
    }
   ],

   treeProps:{ label: 'name', children: 'sub' }
}


<|start_filename|>src/server/utils/ZipUtil.js<|end_filename|>
const fs=require("fs")
const os=require("os")
const unzip = require("unzip");
const path = require("path");
const cpFile = require('cp-file');
const archiver = require('archiver');


exports.addFileToZip=async function(filePath,zipFilePath,copyToPath,outPutPath) {
	if(!outPutPath) {
		outPutPath=zipFilePath
	}
	if(fs.existsSync(zipFilePath)) {
	  let folder=fs.mkdtempSync(os.tmpdir());
	  await exports.unzip(zipFilePath,folder)
	  await cpFile(filePath, path.join(folder,copyToPath,path.basename(filePath)));	 

	  return await exports.zipDirectory(folder,outPutPath)	  	 
    } else {    	
    	return null
    }
}
exports.unzip=function(zipFilePath,directory) {
    return new Promise((resolve) => {
    	fs.createReadStream(zipFilePath).pipe(unzip.Extract({ path: directory })).on('close',function(){
	 	  resolve(directory)
	   });
        	
    });
}
exports.zipDirectory=function(directory,outputPath) {
    return new Promise((resolve) => {
    	  var output = fs.createWriteStream(outputPath);
    	  var archive = archiver('zip');
    	  archive.on('error', function(err){
				    throw err;
				});
    	  output.on('close', function() {
    	  	resolve(outputPath)
		});
    	  archive.pipe(output);
    	  archive.directory(directory+'/', false);
    	  archive.finalize();
    });
}

<|start_filename|>src/client/routes.js<|end_filename|>
import Login from './views/Login.vue'
import NotFound from './views/404.vue'
import Home from './views/Home.vue'
import Main from './views/Main.vue'

import Vue from "vue";


let { nav_menu, metaMap } = require("./include")




function hasRight(user, menuItem) {
    if (!user) return false;
    if (user && user.type && user.type == 'root') return true;
    if (!user.right || user.right == '' || user.right.length == 0) return false;
    let ids = [];
    ids.push(menuItem.id);
    if (menuItem.children) {
        for (let child of menuItem.children) {
            ids.push(child.id);
        }
    }

    if (user.right) {
        for (let one of ids) {
            if (user.right[one] && user.right[one]!=true) return true;
        }
    }

    return false;
}

function createComponent(name,id) {
    if (name == '/') return Home;
    let metaData = metaMap[name];

    //console.log(metaMap);
    if (metaData == null) {
        console.log("no found:" + name);
        return NotFound;
    }
    metaData.id=id
    metaData.path = name;
    if (name.includes("/")) {
        name = name.replace(/\//g, '');
    }
    let pageAdmin = metaData.pageAdminComponent ? metaData.pageAdminComponent : "table-admin";
    console.log("create compoent:" + name + ":" + pageAdmin);
    return Vue.component(name, {
        template: '<' + pageAdmin + '  :init="metaData" ></' + pageAdmin + '>',
        data() {
            return {
                metaData
            }
        }
    });


}

function generateRoutes() {
    let otherRoutes = [];
    let session_user = JSON.parse(sessionStorage.getItem("user"));
    for (let menu of nav_menu) {
        let menuOne = {};
        if (hasRight(session_user, menu)) {
            menuOne = Object.assign({}, menu);
            menuOne.children = [];
            for (let childMenu of menu.children) {
                if (hasRight(session_user, childMenu)) {
                    menuOne.children.push(childMenu);
                }
            }
            otherRoutes.push(menuOne);
        }
    }
    otherRoutes.push({
        path: '*',
        hidden: true,
        redirect: {
            path: '/404'
        }
    });
    for (let item of otherRoutes) {
        if (!item.component) {
            item.component = createComponent(item.path,item.id);
        }
        if (item.children) {
            for (let one of item.children) {
                if (!one.component) {
                    one.component = createComponent(one.path,one.id);
                } else {
                    console.log("EXIT", one.path, one.component)
                }
            }
        }
    }
    if (session_user && session_user.type && session_user.type == 'root') {
        otherRoutes.push({
            path: '/',
            component: Home,
            name: '系统',
            iconCls: 'el-icon-star-on',
            children: [{
                path: '/sys/User',
                component: createComponent('/sys/User'),
                name: '用户'
            }, {
                path: '/sys/Role',
                component: createComponent('/sys/Role'),
                name: '角色'
            }]
        });
    }
    console.log("otherRoutes", otherRoutes)
    return otherRoutes
}

let routes = [{
    path: '/login',
    component: Login,
    name: '',
    hidden: true
}, {
    path: '/404',
    component: NotFound,
    name: '',
    hidden: true
}];



//export default routes;
export { routes, generateRoutes }

<|start_filename|>src/server/controllers/admin/pageAdmin.js<|end_filename|>
const R = require('ramda')
var fs = require('fs')
const os = require('os');
const pathUtil = require('path');
var dateFormat = require('dateformat');
const makeDir = require('make-dir');
const md5File = require('md5-file')


let { utility, ApiError, ApiErrorNames, config, services, baseDao,nav_menu,metaIndex,metaIndexServer} = require('../../include');

import actionMap from "./pageActions";

let moduleMap = metaIndex;



for (let oneMenu of nav_menu) {
    if (oneMenu.children) {
        for (let om of oneMenu.children) {
            if (metaIndex[om.path]) {                
                metaIndex[om.path].id=om.id
            }
        }
    }
}


let path = "/:path*/:actionName";

let needParams = [];







function hasRight(user, path, actionName) {
    if (user.type == 'root') return true;
    let mid = metaIndex["/"+path].id;
    if (!mid) {
        console.log("---hasRight:no find mid:" + path);
        return false;
    }
    console.log("---mid:" + mid);
    let right = user.right;
    if (!right || !right[mid]) return false;
    if (actionName == 'listpage' || actionName == 'list') return true; //默认都有list权限
    if (actionName == 'batchremove') actionName = 'remove'; //batchremove 等同于remove
    if (!right[mid][actionName]) return false;
    return true;
}
async function doRequest(ctx, next) {
    console.log("pageAdminUser:" + JSON.stringify(ctx.session.user));
    if (!ctx.session.user) {
        throw new ApiError(ApiErrorNames.NO_LOGIN);
    }
    console.log("--doRequest:params" + JSON.stringify(ctx.params));
    let {
        path,
        actionName
    } = ctx.params;
    console.log("--doRequest:pageAdmin：" + path);
    let metaData = moduleMap["/" + path];
    if (!hasRight(ctx.session.user, path, actionName)) {
        console.log("noright--" + path + ":" + actionName);
        throw new ApiError(ApiErrorNames.NORIGHT, actionName);
    }

    console.log("--doRequest:1");
    if (metaData) {
        console.log("findServer:","/" + path)
        let serverMetaData = metaIndexServer["/" + path];
        if(serverMetaData) {
            console.log("findServerRes:",serverMetaData)
            metaData.serverMeta=serverMetaData
        }
        let entityName = metaData.entityName;
        console.log("--doRequest:2" + entityName);
        checkNeedParams(path, actionName, metaData.columnsDef, ctx.request.body);
        console.log("--doRequest:2" + entityName);
        //  try {
        let result = await exec(entityName, actionName, metaData, ctx);
        console.log("--doRequest:3" + entityName + ",result=" + JSON.stringify(result));
        if (!result) {
            throw new ApiError(ApiErrorNames.UNKNOW_ERROR);
        }

    } else {

        throw new ApiError(ApiErrorNames.ENTITY_NOFIND, path);
    }
}

async function exec(entityName, actionName, metaData, ctx) {

    let amethod = actionMap[actionName];
    let serverHook=metaData.serverHook
    if(metaData.serverMeta &&　metaData.serverMeta) {
        console.log("exec",actionName,"serverMeta use serverHook")
        serverHook=metaData.serverMeta
    }
    let result = await amethod(ctx, entityName, serverHook, metaData);
    return result;
}


function getAddRequireProps(columnsDef) {
    let props = [];
    if (columnsDef) {        
        let find=R.compose(R.map(R.prop('prop')),R.filter(R.propEq('required', true)))
        props=find(columnsDef)
        //props=R.insertAll(1,find(columnsDef),props)
    }    
    return props;
}

function getEditRequireProps(columnsDef) {
    let props = getAddRequireProps(columnsDef);   
    props.push('_id')
    return props;
}

function checkNeedParams(path, actionName, columnsDef, requestBody) {
    let needParams = {
        add: getAddRequireProps(columnsDef),
        edit: getEditRequireProps(columnsDef),
        batchremove: ['ids'],
        remove: ['id'],
        listpage: ['pageSize', 'page']
    };
    let data = requestBody;
    if (requestBody.fields) {
        data = requestBody.fields;
    }
    if (needParams[actionName]) {
        for (let item of needParams[actionName]) {
            if (!data[item] || data[item] == '') {
                throw new ApiError(ApiErrorNames.ILLEGAL_PARAM, "缺少" + item + "在" + path + "的" + actionName + "请求");
            }
        }
    }
}

export {
    path,
    needParams,
    doRequest
};

<|start_filename|>src/server/schedule/DeleteTable.js<|end_filename|>
const utility = require('utility');

const moment = require('moment');
const dateMath=require("date-arithmetic")
const config=require("../config")
const mongoDbStat = require('../utils/MongoDbStat');


/**
删除数据库：tcAdStat，表名为：名称_日期，固定天数之前的表(只保留最近天数的表)
*/
exports.exeuteTask = async function() {  
  var today = moment()
  mongoDbStat.db.listCollections(function(names){  	 
  	 for(let name of names) {
  	 	let name_date=name.name.split("_")  	 	
  	 	if(name_date.length>1) {  	 		
  	 		let date=moment(name_date[1],'YYYYMMDD')  	 		  	 	
  	 		if(today.diff(date,'days')>config.dbKeepDays) {  	 			  	 		
  	 			mongoDbStat.db.dropCollection(name.name,{},function(err,ret){
  	 				console.log("--deleteCollection:"+name.name,ret,err)
  	 			})
  	 			
  	 		}

  	 	}
  	 }

  })
}


<|start_filename|>src/shared/meta/sys/Role.js<|end_filename|>
var utility = require('../../utils/CommonUtils');
var nav_menu = require('../../../../config/shared/nav_menu');
//实体名定义，也是mongodb的数据保存集合名
let entityName = "role";
let methods = {
    submitCheck: function(para, vum) {
        console.log("------submitCheck");
        //console.log("refs",tableAdmin.$refs);
        let checkRights = vum.$refs.right[0].getCheckedKeys();
        para.right = {};
        for (let oneid of checkRights) {
            let oneRight = {};    
            console.log('p' + oneid + 'add')
            console.log(document.getElementById('p' + oneid + 'add'));
            let add=document.getElementById('p' + oneid + 'add')
            if (add && add.checked) {
                oneRight.add = 1;
            }
            let edit=document.getElementById('p' + oneid + 'edit')
            if (edit && edit.checked) {
                oneRight.edit = 1;
            }
              let remove=document.getElementById('p' + oneid + 'remove')
            if (remove && remove.checked) {
                oneRight.remove = 1;
            }
            para.right[oneid] = oneRight
        }
        return para;
    },
    formatRight: function(row, column) {
        return "...";
    },
    onShowEdit: function(addForm, vum) {
        let right = addForm.right;
        if (!right) return
        if (!vum.$refs.right) return
        let ids = Object.keys(right);            
        vum.$refs.right[0].setCheckedKeys(ids);
        setTimeout(()=>{
                 for (let id of ids) {  
                   let actions = right[id];                 
                   if (document.getElementById('p' + id + 'add')) {                   
                    document.getElementById('p' + id + 'add').checked =(actions.add==1)
                    document.getElementById('p' + id + 'edit').checked = (actions.edit==1)
                    document.getElementById('p' + id + 'remove').checked = (actions.remove==1)
                  }                 
                }
        },200)        
        
    },
    onShowAdd: function(addForm, tableAdmin) {
        if (tableAdmin.$refs.tree instanceof Array) {
            tableAdmin.$refs.tree[0].setCheckedKeys([]);
        }
    },
    renderContent: function(h, { node, data, store }) {
        if (data.path == '/') {
            return (<span>{node.label}</span>)
        } else {

           return (
          <span style="flex: 1;display: flex;align-items: center;justify-content: space-between;font-size: 14px;padding-right: 8px;">
            <span>{node.label}</span>
            <span id={'p'+data.id} style="display:none">
              <input type="checkbox"  id={'p'+data.id+'add'}/>新增&nbsp;&nbsp;
              <input type="checkbox"  id={'p'+data.id+'edit'}/>修改&nbsp;&nbsp;
              <input type="checkbox"  id={'p'+data.id+'remove'}/>删除
              
            </span>
          </span>)
        }
    },
    checkChange: function(data, isCheck) {
        if (data.path != '/') {
            let id = data.id;
            if( document.getElementById('p' + id)) {
             document.getElementById('p' + id).style.display = isCheck ? "" : "none";
            }
            if (document.getElementById('p' + id + 'add')) {
                document.getElementById('p' + id + 'add').checked = isCheck;
            }
            if (document.getElementById('p' + id + 'edit')){
                document.getElementById('p' + id + 'edit').checked = isCheck;
            }
            if (document.getElementById('p' + id + 'remove')) {
                console.log("--checkChange set move",isCheck)
                document.getElementById('p' + id + 'remove').checked = isCheck;
            }
        }
    }
};


function loadTreeData() {
    let ops = {};
   
    ops.data = nav_menu.nav_menu;
    return ops.data;
}
//列定义
/**
  inputType支持类型：1）text 2）twoText 3）radio 4）checbox
*/
let columnsDef = [{
        prop: 'name',
        label: '{roleName}',
        width: 250,
        input: { type: 'text', rule: 'required' },        
        filter: true,
        index:{options:{unique:true}}
    },
    {
        prop: 'memo',
        label: '{memo}',
        width: 200,
        input: 'text'
    },
    {
        prop: 'right',
        label: '{permission}',
        width: 200,
        input: { type: 'tree',expandAll:true, nodeKey:'id',renderContent:methods.renderContent, props:{ label: 'name', children: 'children' },data: loadTreeData(),checkChange:methods.checkChange },
        formatter: methods.formatRight
    }
];



let api = {
    beforeAdd: function(doc) {
        doc.addTime = utility.YYYYMMDDHHmmss();
        return doc;
    },
    beforeUpdate: function(doc) {
        doc.updateTime = utility.YYYYMMDDHHmmss();
        return doc;
    }

};
exports.entityName = entityName;
exports.columnsDef = columnsDef;
exports.api = api;
exports.methods = methods;
exports.hook={
    submitCheck:methods.submitCheck,
    onShowEdit:methods.onShowEdit,
    onShowAdd:methods.onShowAdd
}

<|start_filename|>src/server/db/MongoDb.js<|end_filename|>
const R = require('ramda')
const f = require('util').format;
var MongoClient = require('mongodb').MongoClient;

exports.connect = async function(dbConfig) {
    let { user, pass, host, port, dbname, poolSize } = dbConfig
    let uri = null
    if (user && pass) {
        uri = f('mongodb://%s:%s@%s:%s/?authMechanism=%s&authSource=%s', user, pass, host, port, 'SCRAM-SHA-1', dbname);
    } else {
        uri = f('mongodb://%s:%s/authSource=%s', host, port, dbname);
    }
    try {
        let client = await MongoClient.connect(uri, { poolSize, reconnectTries: Number.MAX_VALUE })
        let db = client.db(dbname)

        return wrapperDb(db)
    } catch (err) {
        error(err)
    }
}
let testDb = async function(db) {
    let collection = db.collection("user")
    let findX = collection.findOne
    let result = await findX.bind(collection)({})
    console.log("-----findOnexxxxxxx", result)
}

function error(error) {
    var errorMsg = error.stack || error.message || error || 'unknow error';
    console.log(errorMsg);
}

let collectionMap = {}

function wrapperDb(db) {
    return {
        collection: function(collName) {
            if (!collectionMap[collName]) collectionMap[collName] = wrapperCollectin(db, collName)
            return collectionMap[collName]
        }
    }

}




const FNAMES = ['aggregate',
    'bulkWrite',
    'count',
    //'countDocuments',
    'createIndex',
    //'createIndexes',
    'deleteMany',
    'deleteOne',
    'distinct',
    'drop',
   //'dropAllIndexes',
    //'dropIndex',
    //'dropIndexes',
    //'ensureIndex',
    //'estimatedDocumentCount',
    'find',
    'findAndModify',
    'findAndRemove',
    'findOne',
    'findOneAndDelete',
    'findOneAndReplace',
    'findOneAndUpdate',
    //'geoHaystackSearch',
    'group',
    //'indexes',
    //'indexExists',
    //'indexInformation',
   // 'initializeOrderedBulkOp',
    //'initializeUnorderedBulkOp',
    'insert',
    'insertMany',
    'insertOne',
    //'isCapped',
    //'listIndexes',
    //'mapReduce',
    //'options',
    //'parallelCollectionScan',
    //'reIndex',
    'remove',
    'rename',
    'replaceOne',
    'save',
    //'stats',
    'update',
    'updateMany',
    'updateOne',
    //'watch'
]

function bindCollFn(coll) {    
    var toAll = (result, fnName) => {
        result[fnName] = coll[fnName].bind(coll)
        return result;
    };
    return R.reduce(toAll, {})(FNAMES)
}

function wrapperCollectin(db, collName) {
    let coll = db.collection(collName)    
    return R.merge(bindCollFn(coll),{insert: R.partial(insertWithAutoIncrement, [db, coll, collName])})
}

//自动生成_id,如果不需要可设置options.autoincrement=false
async function insertWithAutoIncrement(db, coll, collName, docs, options, callback) {

    if (!docs._id && (!options || (options && 　options.autoincrement != false))) {
        docs._id = await nextSeq(db, collName)
    }
    return coll.insert(docs, options, callback)
}
async function nextSeq(db, collname) {
    let reply = await db.collection("id_sequence").findAndModify({ coll: collname }, null, { $inc: { id: 1 } }, { upsert: true, new: true })
    if (reply.ok == 1) {
        return reply.value.id.toString()
    } else {
        return null
    }
}