@misstalor17/elpis 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +3 -0
- package/.eslintrc +56 -0
- package/README.md +6 -0
- package/app/controller/base.js +43 -0
- package/app/controller/business.js +121 -0
- package/app/controller/project.js +75 -0
- package/app/controller/view.js +24 -0
- package/app/extend/logger.js +37 -0
- package/app/middleware/api-params-verify.js +70 -0
- package/app/middleware/api-sign-verify.js +31 -0
- package/app/middleware/error-handler.js +32 -0
- package/app/middleware/project-handler.js +28 -0
- package/app/middleware.js +44 -0
- package/app/pages/asserts/custom.css +12 -0
- package/app/pages/boot.js +45 -0
- package/app/pages/common/curl.js +96 -0
- package/app/pages/common/utils.js +2 -0
- package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu.vue +22 -0
- package/app/pages/dashboard/complex-view/header-view/header-view.vue +106 -0
- package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +45 -0
- package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +33 -0
- package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +105 -0
- package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +23 -0
- package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +85 -0
- package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +90 -0
- package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +113 -0
- package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +109 -0
- package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +66 -0
- package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +17 -0
- package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +116 -0
- package/app/pages/dashboard/dashboard.vue +96 -0
- package/app/pages/dashboard/entry.dashboard.js +45 -0
- package/app/pages/store/index.js +3 -0
- package/app/pages/store/menu.js +60 -0
- package/app/pages/store/project.js +17 -0
- package/app/pages/widgets/header-container/asserts/logo.png +0 -0
- package/app/pages/widgets/header-container/asserts/user.png +0 -0
- package/app/pages/widgets/header-container/header-container.vue +105 -0
- package/app/pages/widgets/schema-form/complex-view/input/input.vue +120 -0
- package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +121 -0
- package/app/pages/widgets/schema-form/complex-view/select/select.vue +106 -0
- package/app/pages/widgets/schema-form/form-item-config.js +20 -0
- package/app/pages/widgets/schema-form/schema-form.vue +122 -0
- package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +42 -0
- package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +55 -0
- package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +37 -0
- package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +41 -0
- package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +109 -0
- package/app/pages/widgets/schema-search-bar/search-item-config.js +23 -0
- package/app/pages/widgets/schema-table/schema.table.vue +191 -0
- package/app/pages/widgets/sider-container/sider-container.vue +34 -0
- package/app/public/static/logo.png +0 -0
- package/app/public/static/normalize.css +240 -0
- package/app/router/business.js +9 -0
- package/app/router/project.js +6 -0
- package/app/router/view.js +13 -0
- package/app/router-schema/business.js +82 -0
- package/app/router-schema/project.js +31 -0
- package/app/service/base.js +13 -0
- package/app/service/project.js +40 -0
- package/app/view/entry.tpl +25 -0
- package/app/webpack/config/webpack.base.js +204 -0
- package/app/webpack/config/webpack.dev.js +56 -0
- package/app/webpack/config/webpack.prod.js +116 -0
- package/app/webpack/dev.js +52 -0
- package/app/webpack/libs/blank.js +1 -0
- package/app/webpack/prod.js +17 -0
- package/config/config.default.js +3 -0
- package/docs/dashboard-model.js +143 -0
- package/elpis-core/env.js +23 -0
- package/elpis-core/index.js +93 -0
- package/elpis-core/loader/config.js +52 -0
- package/elpis-core/loader/controller.js +61 -0
- package/elpis-core/loader/extend.js +52 -0
- package/elpis-core/loader/middleware.js +61 -0
- package/elpis-core/loader/router-schema.js +46 -0
- package/elpis-core/loader/router.js +43 -0
- package/elpis-core/loader/service.js +61 -0
- package/index.js +38 -0
- package/model/buiness/model.js +200 -0
- package/model/index.js +93 -0
- package/npminstall-debug.log +218 -0
- package/package.json +92 -0
- package/test/controller/project.test.js +194 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
const { ElButton } = require("element-plus");
|
|
2
|
+
|
|
3
|
+
const document = {
|
|
4
|
+
mode: 'dashboard',//模版类型,不同模版类型对应不一样的模版数据结构
|
|
5
|
+
name: '',//名称
|
|
6
|
+
desc: '',//描述
|
|
7
|
+
icon: '',//图标
|
|
8
|
+
homePage: '',// 首页(项目配置)
|
|
9
|
+
menu: [{
|
|
10
|
+
key: '',//菜单唯一描述
|
|
11
|
+
name: '',//菜单名称
|
|
12
|
+
menuType: '',//菜单类型,枚举值:group / module
|
|
13
|
+
|
|
14
|
+
//当 menuType === group 时,可填
|
|
15
|
+
subMenu: [{
|
|
16
|
+
// 可递归 menuItem
|
|
17
|
+
}],
|
|
18
|
+
|
|
19
|
+
//当 当 menuType === module 时,可填
|
|
20
|
+
moduleType: '', // 枚举值:sider/iframe/custom/schema
|
|
21
|
+
|
|
22
|
+
//当 moduleType === sider 时
|
|
23
|
+
siderConfig: {
|
|
24
|
+
menu: [{
|
|
25
|
+
// 可递归 menuItem(除moduleType === sider)
|
|
26
|
+
}]
|
|
27
|
+
},
|
|
28
|
+
//当 moduleType === iframe 时
|
|
29
|
+
iframeConfig: {
|
|
30
|
+
path: '', // ifema路径
|
|
31
|
+
},
|
|
32
|
+
//当 moduleType === custom 时
|
|
33
|
+
customConfig: {
|
|
34
|
+
path: '',//自定义路由路径
|
|
35
|
+
},
|
|
36
|
+
//当 moduleType === schema 时
|
|
37
|
+
schemaConfig: {
|
|
38
|
+
api: '',//数据源API(遵循 RESTFUL 规范)
|
|
39
|
+
schema: {//板块数据结构
|
|
40
|
+
type: 'object',
|
|
41
|
+
properties: {
|
|
42
|
+
key: {
|
|
43
|
+
...schema,//标准 scheam 配置
|
|
44
|
+
type: '',//字段类型
|
|
45
|
+
label: '',//字段中文名
|
|
46
|
+
//字段在 table-bar 中的配置
|
|
47
|
+
tableOption: {
|
|
48
|
+
...elTableColumnConfig,//标准 el-table-column 配置
|
|
49
|
+
toFixed: 0,//保留几位小数
|
|
50
|
+
visible: true,//默认为true(false时,表示不再表单中显示)
|
|
51
|
+
},//字段在 table中的相关配置
|
|
52
|
+
//字段在 search-bar 中的配置
|
|
53
|
+
searchOption: {
|
|
54
|
+
...elComponentConfig,//标准 el-form 配置
|
|
55
|
+
comType: '',//配置组件类型
|
|
56
|
+
default: '',//默认值
|
|
57
|
+
|
|
58
|
+
//comType === 'select'
|
|
59
|
+
enumList: [],
|
|
60
|
+
//comType === 'dynamicSelect'
|
|
61
|
+
api: ''
|
|
62
|
+
},
|
|
63
|
+
//字段在不同动态 component 中的相关配置,前缀对应 componentConfig 中的键值
|
|
64
|
+
//如 componConfig。createForm,这里对应createFormOption
|
|
65
|
+
//字段在 createForm 中的相关配置
|
|
66
|
+
createFormOption: {
|
|
67
|
+
...elTableColumnConfig,//标准 el-component 配置
|
|
68
|
+
comType: '',//控件类型 input/select
|
|
69
|
+
visible: true,//是否展示
|
|
70
|
+
disabled: false,//是否禁用
|
|
71
|
+
default: '',//默认值
|
|
72
|
+
|
|
73
|
+
//comType === 'select'
|
|
74
|
+
enumList: [],
|
|
75
|
+
},
|
|
76
|
+
//字段在 editForm 中的相关配置
|
|
77
|
+
editFormOption: {
|
|
78
|
+
...elTableColumnConfig,//标准 el-component 配置
|
|
79
|
+
comType: '',//控件类型 input/select
|
|
80
|
+
visible: true,//是否展示
|
|
81
|
+
disabled: false,//是否禁用
|
|
82
|
+
default: '',//默认值
|
|
83
|
+
//comType === 'select'
|
|
84
|
+
enumList: [],
|
|
85
|
+
},
|
|
86
|
+
detailPanelOption:{
|
|
87
|
+
...elTableColumnConfig,//标准 el-component 配置
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
required: [],//标记哪些字段是必填项
|
|
92
|
+
},
|
|
93
|
+
tableConfig: {
|
|
94
|
+
headerButtons: [{
|
|
95
|
+
label: '',//按钮中文名
|
|
96
|
+
eventKey: '',//按钮事件名
|
|
97
|
+
//按钮事件具体配置
|
|
98
|
+
eventOption: {
|
|
99
|
+
//当 eventKey === ‘showComponent’
|
|
100
|
+
comName: '' //组件名称
|
|
101
|
+
},
|
|
102
|
+
...elButtonConfig //标准 el-button配置
|
|
103
|
+
}, {}],//可以多个配置
|
|
104
|
+
rowButtons: [{
|
|
105
|
+
label: '',//按钮中文名
|
|
106
|
+
eventKey: '',//按钮事件名
|
|
107
|
+
eventOption: {
|
|
108
|
+
//当 eventKey === ‘showComponent’
|
|
109
|
+
comName: '', //组件名称
|
|
110
|
+
//当 eventKey === ‘remove’
|
|
111
|
+
params: {
|
|
112
|
+
//paramKey = 参数的键值
|
|
113
|
+
//rowValueKey = 参数值,格式为schema::tableKey ,到table 中找相应的字段
|
|
114
|
+
paramKey: rowValueKey
|
|
115
|
+
}
|
|
116
|
+
},//按钮事件具体配置
|
|
117
|
+
...elButtonConfig //标准 el-button配置
|
|
118
|
+
}, {}],//可以多个配置
|
|
119
|
+
},//table 相关配置
|
|
120
|
+
searchConfig: {},//search-bar相关配置
|
|
121
|
+
//动态组件相关配置
|
|
122
|
+
componentConfig: {
|
|
123
|
+
// create-form 表单相关配置
|
|
124
|
+
createForm: {
|
|
125
|
+
title: '',// 表单标题
|
|
126
|
+
saveBtnText: '',//保存按钮文案
|
|
127
|
+
},
|
|
128
|
+
// edit-form 表单相关配置
|
|
129
|
+
editForm: {
|
|
130
|
+
mainKey: '',//表单主键,用于唯一标识要修改的数据对象
|
|
131
|
+
title: '',// 表单标题
|
|
132
|
+
saveBtnText: '',//保存按钮文案
|
|
133
|
+
},
|
|
134
|
+
// detaul-panel表单相关配置
|
|
135
|
+
detailPanel: {
|
|
136
|
+
mainKey: '',//表单主键,用于唯一标识要修改的数据对象
|
|
137
|
+
title: '',// 表单标题
|
|
138
|
+
}
|
|
139
|
+
//...支持用户动态扩展
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}]
|
|
143
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module.exports = (app) => {
|
|
2
|
+
return {
|
|
3
|
+
//判断是否本地环境
|
|
4
|
+
isLocal(){
|
|
5
|
+
return process.env._ENV === 'local'
|
|
6
|
+
},
|
|
7
|
+
|
|
8
|
+
//判读是否测试环境
|
|
9
|
+
isBeta(){
|
|
10
|
+
return process.env._ENV === 'beta'
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
//判断是否生产环境
|
|
14
|
+
isProduction(){
|
|
15
|
+
return process.env._ENV === 'production'
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
//获取当前环境
|
|
19
|
+
get(){
|
|
20
|
+
return process.env._ENV ?? 'local'
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
const Koa = require('koa')
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { sep } = path //兼容不同操作系统的斜杠
|
|
4
|
+
|
|
5
|
+
const env = require('./env')
|
|
6
|
+
|
|
7
|
+
//引入中间件
|
|
8
|
+
const middlewareLoader = require('./loader/middleware')
|
|
9
|
+
const routerSchemaLoader = require('./loader/router-schema')
|
|
10
|
+
const routerLoader = require('./loader/router')
|
|
11
|
+
const controllerLoader = require('./loader/controller')
|
|
12
|
+
const serviceLoader = require('./loader/service')
|
|
13
|
+
const configLoader = require('./loader/config')
|
|
14
|
+
const extendLoader = require('./loader/extend')
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
/**
|
|
18
|
+
* 启动项目
|
|
19
|
+
* @params options 项目配置
|
|
20
|
+
*
|
|
21
|
+
* options = {
|
|
22
|
+
* name //项目名称
|
|
23
|
+
* } homePath //项目首页
|
|
24
|
+
*/
|
|
25
|
+
start(options = {}) {
|
|
26
|
+
//创建 koa实例
|
|
27
|
+
const app = new Koa();
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
//应用配置
|
|
31
|
+
app.options = options
|
|
32
|
+
|
|
33
|
+
//基础路径
|
|
34
|
+
app.baseDir = process.cwd()
|
|
35
|
+
|
|
36
|
+
//业务文件路径
|
|
37
|
+
app.businessPath = path.resolve(app.baseDir, `.${sep}app`) //此处.{sep}app代表./app,为了兼容不同操作系统
|
|
38
|
+
|
|
39
|
+
//初始化环境设置
|
|
40
|
+
app.env = env()
|
|
41
|
+
console.log(`-- [start] env: ${app.env.get()} --`); //打印当前环境
|
|
42
|
+
|
|
43
|
+
//加载middleware
|
|
44
|
+
middlewareLoader(app)
|
|
45
|
+
console.log(`-- [start] loader middleware done --`);
|
|
46
|
+
//加载mrouterSchema
|
|
47
|
+
routerSchemaLoader(app)
|
|
48
|
+
console.log(`-- [start] loader routerSchema done --`);
|
|
49
|
+
//加载controller
|
|
50
|
+
controllerLoader(app)
|
|
51
|
+
console.log(`-- [start] loader controller done --`);
|
|
52
|
+
//加载service
|
|
53
|
+
serviceLoader(app)
|
|
54
|
+
console.log(`-- [start] loader service done --`);
|
|
55
|
+
//加载config
|
|
56
|
+
configLoader(app)
|
|
57
|
+
console.log(`-- [start] loader config done --`);
|
|
58
|
+
//加载extend
|
|
59
|
+
extendLoader(app)
|
|
60
|
+
console.log(`-- [start] loader extend done --`);
|
|
61
|
+
|
|
62
|
+
//注册elpis中间件
|
|
63
|
+
const elpisMiddlewarePath = path.resolve(__dirname,`..${sep}app${sep}middleware.js`)
|
|
64
|
+
const elpisMiddleware = require(elpisMiddlewarePath)
|
|
65
|
+
elpisMiddleware(app)
|
|
66
|
+
console.log(`-- [start] loader global elpis middleware done --`);
|
|
67
|
+
//注册全局中间件
|
|
68
|
+
try {
|
|
69
|
+
require(`${app.businessPath}${sep}middleware.js`)(app)
|
|
70
|
+
console.log(`-- [start] loader global business middleware done --`);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.log('[exception] there is no global business middleware file.');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
//注册路由
|
|
76
|
+
routerLoader(app)
|
|
77
|
+
console.log(`-- [start] loader router done --`);
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
//启动服务(node index.js)
|
|
81
|
+
try {
|
|
82
|
+
const port = process.env.PORT || 8080;
|
|
83
|
+
const host = process.env.IP || '0.0.0.0'
|
|
84
|
+
app.listen(port, host)
|
|
85
|
+
console.log(`Server runnin on port: ${port}`);
|
|
86
|
+
} catch (e) {
|
|
87
|
+
console.error(e);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return app;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { sep } = path //兼容不同操作系统的斜杠
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* config loader
|
|
6
|
+
* @param {object} app koa 实例
|
|
7
|
+
*
|
|
8
|
+
* 配置区分 本地/测试/生产,通过env环境读取不同文件配置 env.config
|
|
9
|
+
* 通过env.config 覆盖 default.config 加载到 app。config中
|
|
10
|
+
*
|
|
11
|
+
* 目录下对应的 config 配置
|
|
12
|
+
* 默认配置 config/config.default.js
|
|
13
|
+
* 默认配置 config/config.local.js
|
|
14
|
+
* 默认配置 config/config.beta.js
|
|
15
|
+
* 默认配置 config/config.prod.js
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
module.exports = (app) => {
|
|
21
|
+
//elpis config 目录及相关文件
|
|
22
|
+
const elpisConfigPath = path.resolve(__dirname,`..${sep}..${sep}config`)
|
|
23
|
+
let defaultConfig = require(path.resolve(elpisConfigPath,`.${sep}config.default.js`))
|
|
24
|
+
//业务 config 目录及相关文件
|
|
25
|
+
const businessConfigPath = path.resolve(process.cwd(), `.${sep}config`)
|
|
26
|
+
try {
|
|
27
|
+
defaultConfig = {
|
|
28
|
+
...defaultConfig,
|
|
29
|
+
...require(path.resolve(businessConfigPath, `.${sep}config.default.js`))
|
|
30
|
+
}
|
|
31
|
+
} catch (e) {
|
|
32
|
+
console.log('[exception] there is no default.config file');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//获取 env.config
|
|
36
|
+
let envConfig = {}
|
|
37
|
+
try {
|
|
38
|
+
if (app.env.isLocal()) { //本地环境
|
|
39
|
+
envConfig = require(path.resolve(businessConfigPath, `.${sep}config.local.js`))
|
|
40
|
+
} else if (app.env.isBeta()) { //测试环境
|
|
41
|
+
envConfig = require(path.resolve(businessConfigPath, `.${sep}config.beta.js`))
|
|
42
|
+
} else if (app.env.isProduction()) { //生产环境
|
|
43
|
+
envConfig = require(path.resolve(businessConfigPath, `.${sep}config.prod.js`))
|
|
44
|
+
}
|
|
45
|
+
} catch (e) {
|
|
46
|
+
console.log('[exception] there is no env.config file');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
//覆盖并加载 config 配置
|
|
50
|
+
app.config = Object.assign({}, defaultConfig, envConfig);
|
|
51
|
+
|
|
52
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const glob = require('glob');
|
|
3
|
+
const { sep } = path //兼容不同操作系统的斜杠
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* controller loader
|
|
7
|
+
* @param {object} app Koa 实例
|
|
8
|
+
*
|
|
9
|
+
* 加载所有 controller,可通过‘app。controller.${目录}.${文件}’ 访问
|
|
10
|
+
*
|
|
11
|
+
* 举例:
|
|
12
|
+
* app/controller
|
|
13
|
+
* |
|
|
14
|
+
* | -- custom-module
|
|
15
|
+
* |
|
|
16
|
+
* | -- custom-controller.js
|
|
17
|
+
* => app.controller.customModule.customcCntroller
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
module.exports = (app) => {
|
|
21
|
+
const controller = {}
|
|
22
|
+
//读取 elpis/app/controller/**/**.js 下所有的文件
|
|
23
|
+
const elpisControllerPath = path.resolve(__dirname,`..${sep}..${sep}app${sep}controller`)
|
|
24
|
+
const elpisFileList = glob.sync(path.resolve(elpisControllerPath, `.${sep}**${sep}**.js`))
|
|
25
|
+
elpisFileList.forEach(file => {
|
|
26
|
+
handleFile(file)
|
|
27
|
+
});
|
|
28
|
+
//读取 业务app/controller/**/**.js 下所有的文件
|
|
29
|
+
const businessControllerPath = path.resolve(app.businessPath, `.${sep}controller`)
|
|
30
|
+
const businessFileList = glob.sync(path.resolve(businessControllerPath, `.${sep}**${sep}**.js`))
|
|
31
|
+
businessFileList.forEach(file => {
|
|
32
|
+
handleFile(file)
|
|
33
|
+
});
|
|
34
|
+
//把内容加载到 app.controller 下
|
|
35
|
+
function handleFile (file) {
|
|
36
|
+
// 提取文件名称
|
|
37
|
+
let name = path.resolve(file)
|
|
38
|
+
//街区路径 app/controller/custom-module/custom-controller.js => custom-module/custom-controller
|
|
39
|
+
name = name.substring(name.lastIndexOf(`controller${sep}`) + `controller${sep}`.length, name.lastIndexOf('.'))
|
|
40
|
+
// 把 '-'统一替换成驼峰 ustom-module/custom-controller.js => custommodule.customController
|
|
41
|
+
name = name.replace(/[_-][a-z]/ig, (s) => s.substring(1).toUpperCase())
|
|
42
|
+
|
|
43
|
+
// 挂载 controller 到内存app对象中
|
|
44
|
+
let tempController = controller;
|
|
45
|
+
const names = name.split(sep);
|
|
46
|
+
|
|
47
|
+
for (let i = 0, len = names.length; i < len; i++) {
|
|
48
|
+
if (i === len - 1) {
|
|
49
|
+
const controllerMoule = require(path.resolve(file))(app)
|
|
50
|
+
tempController[names[i]] = new controllerMoule()
|
|
51
|
+
} else {
|
|
52
|
+
if (!tempController[names[i]]) {
|
|
53
|
+
tempController[names[i]] = {}
|
|
54
|
+
}
|
|
55
|
+
tempController = tempController[names[i]]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
app.controller = controller
|
|
61
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const glob = require('glob');
|
|
3
|
+
const { sep } = path //兼容不同操作系统的斜杠
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* extend loader
|
|
7
|
+
* @param {object} app Koa 实例
|
|
8
|
+
*
|
|
9
|
+
* 加载所有 extend,可通过‘app.extend.${文件}’ 访问
|
|
10
|
+
*
|
|
11
|
+
* 举例:
|
|
12
|
+
* app/extend
|
|
13
|
+
* |
|
|
14
|
+
* | -- custom-extend.js
|
|
15
|
+
* => app.extend.customExtend 访问
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
module.exports = (app) => {
|
|
19
|
+
//读取 elpis/app/extend/**.js 下所有的文件
|
|
20
|
+
const elpisExtendPath = path.resolve(__dirname,`..${sep}..${sep}app${sep}extend`)
|
|
21
|
+
const elpisFileList = glob.sync(path.resolve(elpisExtendPath, `.${sep}**${sep}**.js`))
|
|
22
|
+
elpisFileList.forEach(file => {
|
|
23
|
+
handleFile(file)
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
//读取 业务app/extend/**.js 下所有的文件
|
|
27
|
+
const businessExtendPath = path.resolve(app.businessPath, `.${sep}extend`)
|
|
28
|
+
const bussinessFileList = glob.sync(path.resolve(businessExtendPath, `.${sep}**${sep}**.js`))
|
|
29
|
+
bussinessFileList.forEach(file => {
|
|
30
|
+
handleFile(file)
|
|
31
|
+
});
|
|
32
|
+
//把内容加载到 app.extend 下
|
|
33
|
+
function handleFile (file) {
|
|
34
|
+
// 提取文件名称
|
|
35
|
+
let name = path.resolve(file)
|
|
36
|
+
//街区路径 app/extend/custom-extend.js => custom-extend
|
|
37
|
+
name = name.substring(name.lastIndexOf(`extend${sep}`) + `extend${sep}`.length, name.lastIndexOf('.'))
|
|
38
|
+
// 把 '-'统一替换成驼峰 custom-extend.js => customExtend
|
|
39
|
+
name = name.replace(/[_-][a-z]/ig, (s) => s.substring(1).toUpperCase())
|
|
40
|
+
|
|
41
|
+
for (const key in app) {
|
|
42
|
+
if (key === name) {
|
|
43
|
+
console.log(`[extend load error] name:${name} is already in app`);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//挂载 extend 到 app 上
|
|
48
|
+
app[name] = require(path.resolve(file))(app)
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
// app.extend = fileList
|
|
52
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const glob = require('glob');
|
|
3
|
+
const { sep } = path //兼容不同操作系统的斜杠
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* middleware loader
|
|
7
|
+
* @param {object} app Koa 实例
|
|
8
|
+
*
|
|
9
|
+
* 加载所有 middleware,可通过‘app。middlewares.${目录}.${文件}’ 访问
|
|
10
|
+
*
|
|
11
|
+
* 举例:
|
|
12
|
+
* app/middleware
|
|
13
|
+
* |
|
|
14
|
+
* | -- custom-module
|
|
15
|
+
* |
|
|
16
|
+
* | -- custom-middleware.js
|
|
17
|
+
* => app.middlewares.customModule.customMiddleware
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
module.exports = (app) => {
|
|
21
|
+
const middlewares = {}
|
|
22
|
+
//读取 /elpis/app/middleware/**/**.js 下所有的文件
|
|
23
|
+
const elpisMiddlewarePath = path.resolve(__dirname,`..${sep}..${sep}app${sep}middleware`)
|
|
24
|
+
const elpisFileList = glob.sync(path.resolve(elpisMiddlewarePath,`.${sep}**${sep}**.js`))
|
|
25
|
+
elpisFileList.forEach(file => {
|
|
26
|
+
handleFile(file)
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
//读取 业务根目录/app/middleware/**/**.js 下所有的文件
|
|
30
|
+
const businessMiddlewarePath = path.resolve(app.businessPath,`.${sep}middleware`)
|
|
31
|
+
const bussinessFileList = glob.sync(path.resolve(businessMiddlewarePath,`.${sep}**${sep}**.js`))
|
|
32
|
+
bussinessFileList.forEach(file => {
|
|
33
|
+
handleFile(file)
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
//把内容加载到 app.middlewares 下
|
|
37
|
+
|
|
38
|
+
function handleFile(file){
|
|
39
|
+
// 提取文件名称
|
|
40
|
+
let name = path.resolve(file)
|
|
41
|
+
//街区路径 app/middleware/custom-module/custom-middleware.js => custom-module/custom-middleware
|
|
42
|
+
name = name.substring(name.lastIndexOf(`middleware${sep}`) + `middleware${sep}`.length,name.lastIndexOf('.'))
|
|
43
|
+
// 把 '-'统一替换成驼峰 ustom-module/custom-middleware.js => custommodule.customMiddleware
|
|
44
|
+
name = name.replace(/[_-][a-z]/ig, (s) => s.substring(1).toUpperCase())
|
|
45
|
+
|
|
46
|
+
// 挂载 middleware 到内存app对象中
|
|
47
|
+
let tempMiddleware = middlewares;
|
|
48
|
+
const names = name.split(sep);
|
|
49
|
+
for(let i = 0,len = names.length; i < len; i++){
|
|
50
|
+
if(i === len - 1){ //文件
|
|
51
|
+
tempMiddleware[names[i]] = require(path.resolve(file))(app)
|
|
52
|
+
}else{ // 文件夹
|
|
53
|
+
if(!tempMiddleware[name[i]]){
|
|
54
|
+
tempMiddleware[name[i]] = {}
|
|
55
|
+
}
|
|
56
|
+
tempMiddleware = tempMiddleware[name[i]]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
app.middlewares = middlewares
|
|
61
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const glob = require('glob');
|
|
3
|
+
const { sep } = path //兼容不同操作系统的斜杠
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* router-schema loader
|
|
7
|
+
* @param {object} app koa 实例
|
|
8
|
+
*
|
|
9
|
+
* 通过‘json-schema & ajv 对 API 规则进行约束,配合 api-params-verify’
|
|
10
|
+
*
|
|
11
|
+
* app/router-schema/**.js
|
|
12
|
+
*
|
|
13
|
+
* 输出:
|
|
14
|
+
* app.routerSchema = {
|
|
15
|
+
* '${app1}':${jsonSchema},
|
|
16
|
+
* '${app2}':${jsonSchema},
|
|
17
|
+
* '${app3}':${jsonSchema},
|
|
18
|
+
* '${app4}':${jsonSchema},
|
|
19
|
+
* }
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
module.exports = (app) => {
|
|
23
|
+
let routerSchema = {}
|
|
24
|
+
//读取 elpis/app/router-schema/**/**.js 下所有的文件
|
|
25
|
+
const elpisRouterSchemaPath = path.resolve(__dirname, `..${sep}..${sep}app${sep}router-schema`)
|
|
26
|
+
const elpisFileList = glob.sync(path.resolve(elpisRouterSchemaPath, `.${sep}**${sep}**.js`))
|
|
27
|
+
elpisFileList.forEach(file => {
|
|
28
|
+
handleFile(file)
|
|
29
|
+
})
|
|
30
|
+
//读取 业务app/router-schema/**/**.js 下所有的文件
|
|
31
|
+
const bussinessRouterSchemaPath = path.resolve(app.businessPath, `.${sep}router-schema`)
|
|
32
|
+
const bussinessFileList = glob.sync(path.resolve(bussinessRouterSchemaPath, `.${sep}**${sep}**.js`))
|
|
33
|
+
bussinessFileList.forEach(file => {
|
|
34
|
+
handleFile(file)
|
|
35
|
+
})
|
|
36
|
+
//注册所有 routerSchema,使得可以 ‘app.routerSchema’ 这样访问
|
|
37
|
+
function handleFile(file) {
|
|
38
|
+
routerSchema = {
|
|
39
|
+
...routerSchema,
|
|
40
|
+
...require(path.resolve(file))
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
app.routerSchema = routerSchema
|
|
45
|
+
|
|
46
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const glob = require('glob')
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { sep } = path //兼容不同操作系统的斜杠
|
|
4
|
+
const KoaRouter = require('koa-router')
|
|
5
|
+
/**
|
|
6
|
+
* router loader
|
|
7
|
+
* @param {object} app koa 实例
|
|
8
|
+
*
|
|
9
|
+
* 解析所有 app/router 下所有 js 文件,加载到 KoaRouter 下
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
module.exports = (app) => {
|
|
14
|
+
//实例化 KoaRouter
|
|
15
|
+
const router = new KoaRouter()
|
|
16
|
+
|
|
17
|
+
// 找到epis路由文件路径
|
|
18
|
+
const elpisRouterPath = path.resolve(__dirname,`..${sep}..${sep}app${sep}router`)
|
|
19
|
+
//注册所有路由
|
|
20
|
+
const elpisFileList = glob.sync(path.resolve(elpisRouterPath, `.${sep}**${sep}**.js`))
|
|
21
|
+
elpisFileList.forEach(file => {
|
|
22
|
+
require(path.resolve(file))(app, router)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
// 找到业务路由文件路径
|
|
26
|
+
const businessRouterPath = path.resolve(app.businessPath, `.${sep}router`)
|
|
27
|
+
//注册所有路由
|
|
28
|
+
const businessFileList = glob.sync(path.resolve(businessRouterPath, `.${sep}**${sep}**.js`))
|
|
29
|
+
businessFileList.forEach(file => {
|
|
30
|
+
require(path.resolve(file))(app, router)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
//路由兜底(健壮性考虑)
|
|
34
|
+
router.get('*', async (ctx, next) => {
|
|
35
|
+
ctx.status = 302 //临时重定向
|
|
36
|
+
ctx.redirect(`${app?.options?.homePage ?? '/'}`)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
//路由注册到 app 上
|
|
40
|
+
app.use(router.routes())
|
|
41
|
+
app.use(router.allowedMethods())
|
|
42
|
+
|
|
43
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const glob = require('glob');
|
|
3
|
+
const { sep } = path //兼容不同操作系统的斜杠
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* service loader
|
|
7
|
+
* @param {object} app Koa 实例
|
|
8
|
+
*
|
|
9
|
+
* 加载所有 service,可通过‘app。service.${目录}.${文件}’ 访问
|
|
10
|
+
*
|
|
11
|
+
* 举例:
|
|
12
|
+
* app/service
|
|
13
|
+
* |
|
|
14
|
+
* | -- custom-module
|
|
15
|
+
* |
|
|
16
|
+
* | -- custom-service.js
|
|
17
|
+
* => app.service.customModule.customcService
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
module.exports = (app) => {
|
|
21
|
+
const service = {}
|
|
22
|
+
//读取 elpis/app/service/**/**.js 下所有的文件
|
|
23
|
+
const elpisServicePath = path.resolve(__dirname,`..${sep}..${sep}app${sep}service`)
|
|
24
|
+
const elpisFileList = glob.sync(path.resolve(elpisServicePath, `.${sep}**${sep}**.js`))
|
|
25
|
+
elpisFileList.forEach(file => {
|
|
26
|
+
handleFile(file)
|
|
27
|
+
});
|
|
28
|
+
//读取 业务app/service/**/**.js 下所有的文件
|
|
29
|
+
const businessServicePath = path.resolve(app.businessPath, `.${sep}service`)
|
|
30
|
+
const businessFileList = glob.sync(path.resolve(businessServicePath, `.${sep}**${sep}**.js`))
|
|
31
|
+
businessFileList.forEach(file => {
|
|
32
|
+
handleFile(file)
|
|
33
|
+
});
|
|
34
|
+
//把内容加载到 app.service 下
|
|
35
|
+
function handleFile (file) {
|
|
36
|
+
// 提取文件名称
|
|
37
|
+
let name = path.resolve(file)
|
|
38
|
+
//街区路径 app/service/custom-module/custom-service.js => custom-module/custom-service
|
|
39
|
+
name = name.substring(name.lastIndexOf(`service${sep}`) + `service${sep}`.length, name.lastIndexOf('.'))
|
|
40
|
+
// 把 '-'统一替换成驼峰 ustom-module/custom-service.js => custommodule.customService
|
|
41
|
+
name = name.replace(/[_-][a-z]/ig, (s) => s.substring(1).toUpperCase())
|
|
42
|
+
|
|
43
|
+
// 挂载 service 到内存app对象中
|
|
44
|
+
let tempService = service;
|
|
45
|
+
const names = name.split(sep);
|
|
46
|
+
|
|
47
|
+
for (let i = 0, len = names.length; i < len; i++) {
|
|
48
|
+
if (i === len - 1) {
|
|
49
|
+
const serviceMoule = require(path.resolve(file))(app)
|
|
50
|
+
tempService[names[i]] = new serviceMoule()
|
|
51
|
+
} else {
|
|
52
|
+
if (!tempService[names[i]]) {
|
|
53
|
+
tempService[names[i]] = {}
|
|
54
|
+
}
|
|
55
|
+
tempService = tempService[names[i]]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
app.service = service
|
|
61
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//引入 eplis-core
|
|
2
|
+
const ElpisCore = require('./elpis-core')
|
|
3
|
+
//引入前端工程化构建方法
|
|
4
|
+
const FEBuildDev = require('./app/webpack/dev')
|
|
5
|
+
const FEBuildProd = require('./app/webpack/prod')
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
/**
|
|
9
|
+
* 服务端基础
|
|
10
|
+
*/
|
|
11
|
+
Controller: {
|
|
12
|
+
Base: require('./app/controller/base')
|
|
13
|
+
},
|
|
14
|
+
Service: {
|
|
15
|
+
Base: require('./app/service/base')
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 编译构建前端工程
|
|
20
|
+
* @params env 环境变量 local/production
|
|
21
|
+
*/
|
|
22
|
+
frontendBuild(env) {
|
|
23
|
+
if (env === 'local') {
|
|
24
|
+
FEBuildDev()
|
|
25
|
+
} else if (env === 'production') {
|
|
26
|
+
FEBuildProd()
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
/**
|
|
30
|
+
* 启动 elpis
|
|
31
|
+
* @param options 项目配置,透传到 elpis-core
|
|
32
|
+
*/
|
|
33
|
+
serverStart(options = {}) {
|
|
34
|
+
const app = ElpisCore.start(options)
|
|
35
|
+
return app;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|