@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.
Files changed (84) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc +56 -0
  3. package/README.md +6 -0
  4. package/app/controller/base.js +43 -0
  5. package/app/controller/business.js +121 -0
  6. package/app/controller/project.js +75 -0
  7. package/app/controller/view.js +24 -0
  8. package/app/extend/logger.js +37 -0
  9. package/app/middleware/api-params-verify.js +70 -0
  10. package/app/middleware/api-sign-verify.js +31 -0
  11. package/app/middleware/error-handler.js +32 -0
  12. package/app/middleware/project-handler.js +28 -0
  13. package/app/middleware.js +44 -0
  14. package/app/pages/asserts/custom.css +12 -0
  15. package/app/pages/boot.js +45 -0
  16. package/app/pages/common/curl.js +96 -0
  17. package/app/pages/common/utils.js +2 -0
  18. package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu.vue +22 -0
  19. package/app/pages/dashboard/complex-view/header-view/header-view.vue +106 -0
  20. package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +45 -0
  21. package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +33 -0
  22. package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +105 -0
  23. package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +23 -0
  24. package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +85 -0
  25. package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +90 -0
  26. package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +113 -0
  27. package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +109 -0
  28. package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +66 -0
  29. package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +17 -0
  30. package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +116 -0
  31. package/app/pages/dashboard/dashboard.vue +96 -0
  32. package/app/pages/dashboard/entry.dashboard.js +45 -0
  33. package/app/pages/store/index.js +3 -0
  34. package/app/pages/store/menu.js +60 -0
  35. package/app/pages/store/project.js +17 -0
  36. package/app/pages/widgets/header-container/asserts/logo.png +0 -0
  37. package/app/pages/widgets/header-container/asserts/user.png +0 -0
  38. package/app/pages/widgets/header-container/header-container.vue +105 -0
  39. package/app/pages/widgets/schema-form/complex-view/input/input.vue +120 -0
  40. package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +121 -0
  41. package/app/pages/widgets/schema-form/complex-view/select/select.vue +106 -0
  42. package/app/pages/widgets/schema-form/form-item-config.js +20 -0
  43. package/app/pages/widgets/schema-form/schema-form.vue +122 -0
  44. package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +42 -0
  45. package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +55 -0
  46. package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +37 -0
  47. package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +41 -0
  48. package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +109 -0
  49. package/app/pages/widgets/schema-search-bar/search-item-config.js +23 -0
  50. package/app/pages/widgets/schema-table/schema.table.vue +191 -0
  51. package/app/pages/widgets/sider-container/sider-container.vue +34 -0
  52. package/app/public/static/logo.png +0 -0
  53. package/app/public/static/normalize.css +240 -0
  54. package/app/router/business.js +9 -0
  55. package/app/router/project.js +6 -0
  56. package/app/router/view.js +13 -0
  57. package/app/router-schema/business.js +82 -0
  58. package/app/router-schema/project.js +31 -0
  59. package/app/service/base.js +13 -0
  60. package/app/service/project.js +40 -0
  61. package/app/view/entry.tpl +25 -0
  62. package/app/webpack/config/webpack.base.js +204 -0
  63. package/app/webpack/config/webpack.dev.js +56 -0
  64. package/app/webpack/config/webpack.prod.js +116 -0
  65. package/app/webpack/dev.js +52 -0
  66. package/app/webpack/libs/blank.js +1 -0
  67. package/app/webpack/prod.js +17 -0
  68. package/config/config.default.js +3 -0
  69. package/docs/dashboard-model.js +143 -0
  70. package/elpis-core/env.js +23 -0
  71. package/elpis-core/index.js +93 -0
  72. package/elpis-core/loader/config.js +52 -0
  73. package/elpis-core/loader/controller.js +61 -0
  74. package/elpis-core/loader/extend.js +52 -0
  75. package/elpis-core/loader/middleware.js +61 -0
  76. package/elpis-core/loader/router-schema.js +46 -0
  77. package/elpis-core/loader/router.js +43 -0
  78. package/elpis-core/loader/service.js +61 -0
  79. package/index.js +38 -0
  80. package/model/buiness/model.js +200 -0
  81. package/model/index.js +93 -0
  82. package/npminstall-debug.log +218 -0
  83. package/package.json +92 -0
  84. 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
+