up
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
const Koa = require("koa")
|
||||
const load = require("./load")
|
||||
const path = require('path')
|
||||
const xe = require("xe-utils")
|
||||
const EventEmitter = require('events');
|
||||
const Router = require("koa-router");
|
||||
const Parameter = require('parameter');
|
||||
const error = require('./errorException');
|
||||
const log4js = require("log4js");
|
||||
const Smf = require('./smf/smf');
|
||||
|
||||
module.exports = class Bamboo extends Koa {
|
||||
constructor() {
|
||||
super();
|
||||
this.init()
|
||||
}
|
||||
|
||||
path(args) {
|
||||
return this.isPath + '/' + (args || "")
|
||||
}
|
||||
|
||||
isPath(args) {
|
||||
return path.resolve('./' + (args || ""))
|
||||
}
|
||||
|
||||
get xe() {
|
||||
return xe
|
||||
}
|
||||
|
||||
async init() {
|
||||
this.config = {}
|
||||
await this.loadConfig()
|
||||
this.event = new EventEmitter()
|
||||
this.parameter = new Parameter();
|
||||
this.error = error;
|
||||
this.smf = new Smf()
|
||||
log4js.configure(this.config['log']);
|
||||
this.logger = log4js.getLogger();
|
||||
// await this.loadEvent()
|
||||
// await this.loadStatus()
|
||||
// await this.loadMiddleware()
|
||||
// await this.loadController()
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载配置
|
||||
*/
|
||||
async loadConfig() {
|
||||
this.config = {}
|
||||
const config = await load(this.isPath(), "config")
|
||||
config.forEach(item => {
|
||||
this.config[item.file_name] = item.res
|
||||
})
|
||||
}
|
||||
//
|
||||
// /**
|
||||
// * 加载事件
|
||||
// */
|
||||
// async loadEvent() {
|
||||
// const event = await load(this.isPath(), "event")
|
||||
// event.forEach(item => {
|
||||
// Object.keys(item.res).forEach(key => {
|
||||
// this.event.on(key, item.res[key])
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 加载状态
|
||||
// */
|
||||
// async loadStatus() {
|
||||
// const status = await load(this.isPath(), "status")
|
||||
// const setSmfDataList = []
|
||||
// status.forEach(item => {
|
||||
// setSmfDataList.push(item.res)
|
||||
// })
|
||||
// this.smf.setSmfDataList(setSmfDataList)
|
||||
// //监听流程变更
|
||||
// this.smf.on((e, paras) => {
|
||||
// this.event.emit(e.currentState, paras)
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 加载控制器路由
|
||||
// */
|
||||
// async loadController() {
|
||||
// const controller = await load(this.isPath(), "controller")
|
||||
// const router = new Router();
|
||||
// controller.forEach(item => {
|
||||
// item.res.method.forEach(method => {
|
||||
// router[method](item.res.path, async (ctx, next) => {
|
||||
// const validate = this.parameter.validate(item.res.params, ctx.request.body);
|
||||
// if (validate) {
|
||||
// console.error(validate);
|
||||
// this.error.ParameterException(validate);
|
||||
// }
|
||||
// else {
|
||||
// await item.res.fun(ctx, this.application)
|
||||
// await next();
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 加载中间件
|
||||
// */
|
||||
// async loadMiddleware() {
|
||||
// const middleware = await load(this.isPath(), "middleware")
|
||||
// let hashList = xe.toArray(middleware)
|
||||
// hashList = xe.orderBy(hashList, "fun.sort")
|
||||
// hashList = hashList.filter(item => item.res.use)
|
||||
// hashList.forEach(item => {
|
||||
// this.use(async (ctx, next) => {
|
||||
// ctx['logger'] = this.logger
|
||||
// return await item.res.fun(ctx, next, this.application)
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
class HttpException extends Error {
|
||||
// message为异常信息,code 为错误码(开发人员内部约定),status 为HTTP状态码
|
||||
constructor(message, code, status) {
|
||||
super()
|
||||
this.status = status || 500
|
||||
this.code = code || 500
|
||||
this.message = message || '服务器异常'
|
||||
}
|
||||
}
|
||||
|
||||
class ParameterException extends HttpException {
|
||||
constructor(message, code, status) {
|
||||
super()
|
||||
this.status = status || 402
|
||||
this.code = code
|
||||
this.message = message || '参数错误'
|
||||
}
|
||||
}
|
||||
|
||||
class NotFound extends HttpException {
|
||||
constructor(message, code, status) {
|
||||
super()
|
||||
this.status = status || 404
|
||||
this.code = 404
|
||||
this.message = message || '资源未找到'
|
||||
}
|
||||
}
|
||||
|
||||
class AuthFailed extends HttpException {
|
||||
constructor(message, code, status) {
|
||||
super()
|
||||
this.status = status || 401
|
||||
this.message = message || '授权失败'
|
||||
this.code = 401
|
||||
}
|
||||
}
|
||||
|
||||
class Forbidden extends HttpException {
|
||||
constructor(message, code, status) {
|
||||
super()
|
||||
this.status = status || 403
|
||||
this.message = message || '禁止访问'
|
||||
this.code = 403
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
HttpException: (message, code, status) => {throw new HttpException(message, code, status)},
|
||||
ParameterException: (message, code, status) => {throw new ParameterException(message, code, status)},
|
||||
NotFound: (message, code, status) => {throw new NotFound(message, code, status)},
|
||||
AuthFailed: (message, code, status) => {throw new AuthFailed(message, code, status)},
|
||||
Forbidden: (message, code, status) => {throw new Forbidden(message, code, status)},
|
||||
}
|
||||
+22
-14
@@ -92,7 +92,7 @@ module.exports = class Bamboo extends Koa {
|
||||
registeredError() {
|
||||
console.log('注册 错误');
|
||||
this.errorException = {}
|
||||
const hash = requireDirectory(module, this.path('app/err'), {
|
||||
const hash = requireDirectory(module, this.path('lib/bamboo/err'), {
|
||||
visit: (obj) => {
|
||||
for (let key of Object.keys(obj)) {
|
||||
this.errorException[key] = (message, code) => {
|
||||
@@ -308,9 +308,8 @@ module.exports = class Bamboo extends Koa {
|
||||
const parse = path.parse(filename);
|
||||
// super.on(parse.name, obj);
|
||||
for (let key of Object.keys(obj)) {
|
||||
this.event.on(`${parse.name}.${key}`, obj[key]);
|
||||
this.event.on(`${parse.name}.${key}`, e[key]);
|
||||
}
|
||||
|
||||
return obj
|
||||
}
|
||||
});
|
||||
@@ -338,18 +337,27 @@ module.exports = class Bamboo extends Koa {
|
||||
console.log('注册 middleware');
|
||||
const hash = requireDirectory(module, this.path('app/middleware'), {
|
||||
visit: (obj, joined, filename) => {
|
||||
console.log(obj, joined, filename);
|
||||
const parse = path.parse(filename);
|
||||
const config = this.config.middleware[parse.name]
|
||||
// super.use(obj(config || {}))
|
||||
super.use(async (ctx, next) => {
|
||||
ctx['logger'] = this.logger
|
||||
return await obj(ctx, next, this.application)
|
||||
})
|
||||
// console.log(obj, joined, filename);
|
||||
// const parse = path.parse(filename);
|
||||
// const config = this.config.middleware[parse.name]
|
||||
// // super.use(obj(config || {}))
|
||||
// super.use(async (ctx, next) => {
|
||||
// ctx['logger'] = this.logger
|
||||
// return await obj.fun(ctx, next, this.application)
|
||||
// })
|
||||
return obj
|
||||
}
|
||||
});
|
||||
// console.log(hash);
|
||||
let hashList = xe.toArray(hash)
|
||||
hashList = xe.orderBy(hashList,"sort")
|
||||
hashList = hashList.filter(item=>item.use)
|
||||
hashList.forEach(item=>{
|
||||
super.use(async (ctx, next) => {
|
||||
ctx['logger'] = this.logger
|
||||
return await item.fun(ctx, next, this.application)
|
||||
})
|
||||
})
|
||||
console.log(hashList);
|
||||
}
|
||||
|
||||
//注册 utils
|
||||
@@ -938,7 +946,7 @@ module.exports = class Bamboo extends Koa {
|
||||
const tkKeys = Object.keys(tk)
|
||||
for (let key of tkKeys) {
|
||||
if (key === "as") { continue; }
|
||||
if (key === "where"||key === "data") {
|
||||
if (key === "where" || key === "data") {
|
||||
const findJsonRes = this.findJsonValue(tk[key], (n) => {
|
||||
if (typeof n === "string") {
|
||||
// console.log(tk[key],n);
|
||||
@@ -996,7 +1004,7 @@ module.exports = class Bamboo extends Koa {
|
||||
}
|
||||
path = path || []
|
||||
// 获取所有的子节点,并遍历
|
||||
if (typeof n ==="object") {
|
||||
if (typeof n === "object") {
|
||||
const nkeys = Object.keys(n)
|
||||
for (let k of nkeys) {
|
||||
// concat() 方法用于连接两个或多个数组
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
const glob = require("glob")
|
||||
const path = require('path')
|
||||
/**
|
||||
* 项目文件加载
|
||||
*/
|
||||
const list = {
|
||||
"event" : "app/*/event/*.js",
|
||||
"status" : "app/*/status/*.js",
|
||||
"controller": "app/*/controller/*.js",
|
||||
"model" : "app/*/model/*.js",
|
||||
"middleware": "middleware/*.js",
|
||||
"extend" : "extend/*.js",
|
||||
"schedule" : "schedule/*.js",
|
||||
"sqlite" : "sqlite/model/*.js",
|
||||
"config" : "config/*.js",
|
||||
}
|
||||
|
||||
module.exports = function load(directory, key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const options = {
|
||||
root: directory
|
||||
}
|
||||
glob(list[key], options, function (er, files) {
|
||||
if (er) { reject(er) }
|
||||
console.log(files);
|
||||
files = files.map(item => {
|
||||
const parse = path.parse(item);
|
||||
return {
|
||||
dir : parse.dir,
|
||||
file_name: parse.name,
|
||||
res : require(path.resolve(directory + "/" + item))
|
||||
}
|
||||
})
|
||||
resolve(files)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
const xe = require("xe-utils")
|
||||
/**
|
||||
* 状态机-编排复杂的流程状态业务
|
||||
* @param {string} listName 列名.
|
||||
*/
|
||||
module.exports = class Status {
|
||||
constructor(listName, status, data) {
|
||||
this.data = data
|
||||
this.status = status
|
||||
this.listName = listName
|
||||
this.list = []
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回上个状态
|
||||
*/
|
||||
back() {
|
||||
let index = this.getStatusIndex(this.listName, this.status)
|
||||
const res = this.getList(this.listName)
|
||||
if ((index - 1) < 0) {
|
||||
return null
|
||||
}
|
||||
const status = res.status[index - 1]
|
||||
if (res.listName && status.name) {
|
||||
this.go(res.listName, status.name)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* 下一个状态
|
||||
*/
|
||||
next() {
|
||||
let index = this.getStatusIndex(this.listName, this.status)
|
||||
const res = this.getList(this.listName)
|
||||
if (res.status.length <= (index + 1)) {
|
||||
return null
|
||||
}
|
||||
const status = res.status[index + 1]
|
||||
if (res.listName && status.name) {
|
||||
this.go(res.listName, status.name)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发成功事件
|
||||
*/
|
||||
success() {
|
||||
const index = this.getStatusIndex(this.listName, this.status)
|
||||
const res = this.getList(this.listName)
|
||||
const status = res.status[index]
|
||||
if (status.success.event) { this.emitEvent(status.success.event) }
|
||||
if (status.success.listName && status.success.status) {
|
||||
this.go(status.success.listName, status.success.status)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
emitEvent(eventName) {
|
||||
console.log("emitEvent:", eventName);
|
||||
}
|
||||
|
||||
fail() {
|
||||
const index = this.getStatusIndex(this.listName, this.status)
|
||||
const res = this.getList(this.listName)
|
||||
const status = res.status[index]
|
||||
if (status.fail.event) { this.emitEvent(status.fail.event) }
|
||||
if (status.fail.listName && status.fail.status) {
|
||||
this.go(status.fail.listName, status.fail.status)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
go(listName, status) {
|
||||
this.status = status
|
||||
this.listName = listName
|
||||
return this
|
||||
}
|
||||
|
||||
getStatusIndex(listName, status) {
|
||||
const res = this.getList(listName)
|
||||
let index = xe.findKey(res.status, item => item.name === status)
|
||||
return index ? Number(index) : null
|
||||
}
|
||||
|
||||
getList(listName) {
|
||||
const res = this.list.filter(item => item.listName === listName)
|
||||
if (res.length <= 0) { return false }
|
||||
return res[0]
|
||||
}
|
||||
|
||||
push({status, success, fail}) {
|
||||
const res = this.getList(this.listName)
|
||||
if (res) {
|
||||
success = success || {}
|
||||
success["listName"] = success["listName"] || ""
|
||||
success["status"] = success["status"] || ""
|
||||
success["event"] = success["event"] || ""
|
||||
fail = fail || {}
|
||||
fail["listName"] = fail["listName"] || ""
|
||||
fail["status"] = fail["status"] || ""
|
||||
fail["event"] = fail["event"] || ""
|
||||
|
||||
res.status.push({
|
||||
name : status,
|
||||
success: success,
|
||||
fail : fail,
|
||||
})
|
||||
}
|
||||
else {return false}
|
||||
return this
|
||||
}
|
||||
|
||||
create(listName) {
|
||||
if (!listName) { return false }
|
||||
const res = this.getList(listName)
|
||||
if (res) { return false }
|
||||
this.list.push({
|
||||
listName: listName,
|
||||
status : []
|
||||
})
|
||||
this.listName = listName
|
||||
return this
|
||||
}
|
||||
}
|
||||
//
|
||||
// const s = new Status()
|
||||
//
|
||||
// s.create("ord")
|
||||
// .push({
|
||||
// status : "start",
|
||||
// success: {
|
||||
// listName: "ord", //成功后切换到的listName
|
||||
// status : "pay", //成功后切换到的status
|
||||
// event : "ord.start",
|
||||
// },
|
||||
// fail : {
|
||||
// listName: "", //失败后切换到的listName
|
||||
// status : "", //失败后切换到的status
|
||||
// event : "",
|
||||
// },
|
||||
// })
|
||||
// .push({
|
||||
// status : "pay",
|
||||
// success: {
|
||||
// listName: "ord", //成功后切换到的listName
|
||||
// status : "end", //成功后切换到的status
|
||||
// event : "ord.pay",
|
||||
// },
|
||||
// fail : {
|
||||
// listName: "refund", //失败后切换到的listName
|
||||
// status : "start", //失败后切换到的status
|
||||
// event : "",
|
||||
// },
|
||||
// })
|
||||
// .push({
|
||||
// status : "end",
|
||||
// success: {
|
||||
// listName: "", //成功后切换到的listName
|
||||
// status : "", //成功后切换到的status
|
||||
// event : "ord.end",
|
||||
// },
|
||||
// fail : {
|
||||
// listName: "", //失败后切换到的listName
|
||||
// status : "", //失败后切换到的status
|
||||
// event : "",
|
||||
// },
|
||||
// })
|
||||
// s.create("refund")
|
||||
// .push({
|
||||
// status : "start",
|
||||
// success: {
|
||||
// listName: "refund", //成功后切换到的listName
|
||||
// status : "ret", //成功后切换到的status
|
||||
// event : "refund.start",
|
||||
// },
|
||||
// fail : {
|
||||
// listName: "", //失败后切换到的listName
|
||||
// status : "", //失败后切换到的status
|
||||
// event : "",
|
||||
// },
|
||||
// })
|
||||
// .push({
|
||||
// status : "ret",
|
||||
// success: {
|
||||
// listName: "refund", //成功后切换到的listName
|
||||
// status : "end", //成功后切换到的status
|
||||
// event : "refund.ret",
|
||||
// },
|
||||
// fail : {
|
||||
// listName: "", //失败后切换到的listName
|
||||
// status : "", //失败后切换到的status
|
||||
// event : "",
|
||||
// },
|
||||
// })
|
||||
// .push({
|
||||
// status : "end",
|
||||
// success: {
|
||||
// listName: "", //成功后切换到的listName
|
||||
// status : "", //成功后切换到的status
|
||||
// event : "refund.end",
|
||||
// },
|
||||
// fail : {
|
||||
// listName: "", //失败后切换到的listName
|
||||
// status : "", //失败后切换到的status
|
||||
// event : "",
|
||||
// },
|
||||
// })
|
||||
// // console.log(s);
|
||||
//
|
||||
// s.go("ord", "start")
|
||||
// console.log(s.listName, s.status);
|
||||
// s.success()
|
||||
// console.log(s.listName, s.status);
|
||||
// s.fail()
|
||||
// console.log(s.listName, s.status);
|
||||
// s.success()
|
||||
// console.log(s.listName, s.status);
|
||||
// s.success()
|
||||
// console.log(s.listName, s.status);
|
||||
// s.success()
|
||||
// console.log(s.listName, s.status);
|
||||
// s.next()
|
||||
// console.log(s.listName, s.status);
|
||||
|
||||
|
||||
+1
-1
@@ -13,6 +13,6 @@ require('@babel/register')({
|
||||
]
|
||||
})
|
||||
require('@babel/polyfill')
|
||||
const bamboo = require('./bamboo/index')
|
||||
const bamboo = require('./bamboo/bamboo')
|
||||
const app = new bamboo();
|
||||
// app.listen(3000);
|
||||
|
||||
Reference in New Issue
Block a user