@xujingquan/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 (90) hide show
  1. package/.browserslistrc +3 -0
  2. package/.eslintignore +4 -0
  3. package/.eslintrc +63 -0
  4. package/.husky/commit-msg +1 -0
  5. package/.husky/pre-commit +1 -0
  6. package/.prettierignore +16 -0
  7. package/.prettierrc +10 -0
  8. package/README.md +248 -0
  9. package/app/controller/base.js +41 -0
  10. package/app/controller/project.js +75 -0
  11. package/app/controller/view.js +28 -0
  12. package/app/extend/logger.js +39 -0
  13. package/app/middleware/api-params-verify.js +90 -0
  14. package/app/middleware/api-sign-veriyf.js +47 -0
  15. package/app/middleware/error-handler.js +33 -0
  16. package/app/middleware/project-handler.js +30 -0
  17. package/app/middleware.js +45 -0
  18. package/app/pages/asserts/custom.css +13 -0
  19. package/app/pages/boot.js +56 -0
  20. package/app/pages/common/api/business-api.js +19 -0
  21. package/app/pages/common/api/project-api.js +27 -0
  22. package/app/pages/common/request.js +119 -0
  23. package/app/pages/common/utils.js +2 -0
  24. package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +20 -0
  25. package/app/pages/dashboard/complex-view/header-view/header-view.vue +116 -0
  26. package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +44 -0
  27. package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +37 -0
  28. package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +122 -0
  29. package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +23 -0
  30. package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +86 -0
  31. package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +82 -0
  32. package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +115 -0
  33. package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +135 -0
  34. package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +93 -0
  35. package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +21 -0
  36. package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +115 -0
  37. package/app/pages/dashboard/dashboard.vue +93 -0
  38. package/app/pages/dashboard/entry.dashboard.js +45 -0
  39. package/app/pages/store/index.js +4 -0
  40. package/app/pages/store/menu.js +61 -0
  41. package/app/pages/store/project.js +17 -0
  42. package/app/pages/widgets/header-container/asserts/avatar.png +0 -0
  43. package/app/pages/widgets/header-container/asserts/logo.png +0 -0
  44. package/app/pages/widgets/header-container/header-container.vue +111 -0
  45. package/app/pages/widgets/schema-form/complex-view/input/input.vue +141 -0
  46. package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +142 -0
  47. package/app/pages/widgets/schema-form/complex-view/select/select.vue +119 -0
  48. package/app/pages/widgets/schema-form/form-item-config.js +23 -0
  49. package/app/pages/widgets/schema-form/schema-form.vue +130 -0
  50. package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +50 -0
  51. package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +62 -0
  52. package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +40 -0
  53. package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +48 -0
  54. package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +121 -0
  55. package/app/pages/widgets/schema-search-bar/search-item-config.js +27 -0
  56. package/app/pages/widgets/schema-table/schema-table.vue +243 -0
  57. package/app/pages/widgets/sider-container/sider-container.vue +26 -0
  58. package/app/public/static/logo.png +0 -0
  59. package/app/public/static/md5.js +950 -0
  60. package/app/public/static/normalize.css +267 -0
  61. package/app/router/project.js +11 -0
  62. package/app/router/view.js +13 -0
  63. package/app/router-schema/project.js +33 -0
  64. package/app/service/base.js +14 -0
  65. package/app/service/project.js +43 -0
  66. package/app/view/entry.tpl +27 -0
  67. package/app/webpack/config/utils.js +49 -0
  68. package/app/webpack/config/webpack-dev.js +55 -0
  69. package/app/webpack/config/webpack-prod.js +192 -0
  70. package/app/webpack/config/webpack.base.js +273 -0
  71. package/app/webpack/dev.js +60 -0
  72. package/app/webpack/libs/blank.js +1 -0
  73. package/app/webpack/prod.js +27 -0
  74. package/babel.config.js +15 -0
  75. package/commitlint.config.js +3 -0
  76. package/config/config.default.js +4 -0
  77. package/elpis-core/env.js +20 -0
  78. package/elpis-core/index.js +86 -0
  79. package/elpis-core/loader/config.js +54 -0
  80. package/elpis-core/loader/controller.js +69 -0
  81. package/elpis-core/loader/extend.js +57 -0
  82. package/elpis-core/loader/middleware.js +66 -0
  83. package/elpis-core/loader/router-schema.js +49 -0
  84. package/elpis-core/loader/router.js +50 -0
  85. package/elpis-core/loader/service.js +69 -0
  86. package/index.js +47 -0
  87. package/jsconfig.json +19 -0
  88. package/model/index.js +103 -0
  89. package/package.json +105 -0
  90. package/test/controller/project.test.js +200 -0
package/package.json ADDED
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "@xujingquan/elpis",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://git.code.tencent.com/xujingquan/Elpis.git"
8
+ },
9
+ "license": "ISC",
10
+ "author": "xujingquan",
11
+ "main": "index.js",
12
+ "scripts": {
13
+ "lint": "eslint --quiet --ext js,vue .",
14
+ "prepare": "husky || true",
15
+ "test": "_ENV='local' mocha 'test/**/*.js'"
16
+ },
17
+ "lint-staged": {
18
+ "*.{js,jsx,vue,ts,tsx}": [
19
+ "npm run lint"
20
+ ]
21
+ },
22
+ "dependencies": {
23
+ "@babel/core": "^7.24.0",
24
+ "@babel/plugin-transform-runtime": "^7.1.0",
25
+ "@babel/preset-env": "^7.4.5",
26
+ "@element-plus/icons-vue": "^2.3.2",
27
+ "@types/koa": "^3.0.1",
28
+ "@types/node": "^25.4.0",
29
+ "ajv": "^6.10.2",
30
+ "axios": "^0.19.2",
31
+ "babel-loader": "^8.0.4",
32
+ "clean-webpack-plugin": "^0.1.19",
33
+ "compression-webpack-plugin": "^12.0.0",
34
+ "consoler": "^0.2.0",
35
+ "core-js": "^3.49.0",
36
+ "cross-env": "^10.1.0",
37
+ "css-loader": "^0.23.1",
38
+ "css-minimizer-webpack-plugin": "^5.0.1",
39
+ "directory-named-webpack-plugin": "^4.0.1",
40
+ "echarts": "^5.5.0",
41
+ "element-plus": "^2.3.7",
42
+ "express": "^4.18.2",
43
+ "file-loader": "^6.2.0",
44
+ "generate-password": "^1.7.1",
45
+ "glob": "^7.1.4",
46
+ "happypack": "^5.0.1",
47
+ "html-webpack-inject-attributes-plugin": "^1.0.1",
48
+ "html-webpack-plugin": "^5.5.3",
49
+ "jsonwebtoken": "^9.0.2",
50
+ "knex": "^0.19.0",
51
+ "koa": "2.7.0",
52
+ "koa-bodyparser": "^4.2.1",
53
+ "koa-nunjucks-2": "^3.0.2",
54
+ "koa-router": "^7.4.0",
55
+ "koa-static": "^5.0.0",
56
+ "koa-useragent": "2.0.0",
57
+ "koa2-cors": "^2.0.6",
58
+ "less": "^3.8.1",
59
+ "less-loader": "^11.1.3",
60
+ "lint-staged": "^15.5.2",
61
+ "lodash": "^4.17.21",
62
+ "log4js": "^6.9.1",
63
+ "md5": "^2.2.1",
64
+ "mini-css-extract-plugin": "^2.7.6",
65
+ "moment": "^2.29.4",
66
+ "mysql": "^2.18.1",
67
+ "node-schedule": "^2.1.1",
68
+ "nodemon": "^1.19.2",
69
+ "path": "^0.12.7",
70
+ "pinia": "^2.1.6",
71
+ "postcss": "^8.5.8",
72
+ "postcss-loader": "^8.2.1",
73
+ "postcss-preset-env": "^7.8.3",
74
+ "purgecss-webpack-plugin": "^8.0.0",
75
+ "speed-measure-webpack-plugin": "^1.5.0",
76
+ "style-loader": "^0.14.1",
77
+ "superagent": "^8.1.2",
78
+ "terser-webpack-plugin": "^5.4.0",
79
+ "thread-loader": "^4.0.4",
80
+ "vue": "^3.3.4",
81
+ "vue-eslint-parser": "^7.8.0",
82
+ "vue-json-viewer": "^3.0.4",
83
+ "vue-loader": "^17.2.2",
84
+ "vue-router": "^4.2.4",
85
+ "vue-style-loader": "^4.1.2",
86
+ "vuex": "^4.1.0",
87
+ "webpack": "^5.88.1",
88
+ "webpack-bundle-analyzer": "^5.2.0",
89
+ "webpack-dev-middleware": "^6.1.1",
90
+ "webpack-hot-middleware": "^2.25.4",
91
+ "webpack-merge": "^4.2.1"
92
+ },
93
+ "devDependencies": {
94
+ "@commitlint/cli": "^20.4.3",
95
+ "@commitlint/config-conventional": "^20.4.3",
96
+ "assert": "^2.0.0",
97
+ "babel-eslint": "^10.0.2",
98
+ "eslint": "^7.32.0",
99
+ "eslint-plugin-import": "^2.28.1",
100
+ "eslint-plugin-vue": "^9.17.0",
101
+ "husky": "^9.1.7",
102
+ "mocha": "^6.1.4",
103
+ "supertest": "^4.0.2"
104
+ }
105
+ }
@@ -0,0 +1,200 @@
1
+ const assert = require('assert');
2
+ const supertest = require('supertest');
3
+ const md5 = require('md5');
4
+ const eplisCore = require('../../elpis-core');
5
+
6
+ const signKey = 'da98fc11-295c-a64f-5b31-d6dc4055dd06';
7
+ const st = Date.now();
8
+
9
+ describe('测试 project 相关接口', function () {
10
+ this.timeout(60000);
11
+
12
+ let modelList;
13
+ const projectList = [];
14
+
15
+ let request;
16
+
17
+ it('启动服务', async () => {
18
+ const app = await eplisCore.start();
19
+ modelList = require('../../model/index.js')(app);
20
+ modelList.forEach((modelItem) => {
21
+ const { project } = modelItem;
22
+ for (const pKey in project) {
23
+ projectList.push(project[pKey]);
24
+ }
25
+ });
26
+ request = supertest(app.listen());
27
+ });
28
+
29
+ // 没传 proj_key
30
+ it('GET /api/project without proj_key', async () => {
31
+ let tmpRequest = request.get('/api/project');
32
+ tmpRequest = tmpRequest.set('s_t', st);
33
+ tmpRequest = tmpRequest.set('s_sign', md5(`${signKey}_${st}`));
34
+ const res = await tmpRequest;
35
+ assert(res.body.success === false);
36
+ const resBody = res.body;
37
+ assert(resBody.code === 442);
38
+ assert(resBody.message.indexOf('request validate fail') > -1);
39
+ });
40
+
41
+ // proj_key 不存在
42
+ it('GET /api/project fail', async () => {
43
+ let tmpRequest = request.get('/api/project');
44
+ tmpRequest = tmpRequest.set('s_t', st);
45
+ tmpRequest = tmpRequest.set('s_sign', md5(`${signKey}_${st}`));
46
+ tmpRequest = tmpRequest.query({
47
+ proj_key: '不存在的key',
48
+ });
49
+ const res = await tmpRequest;
50
+ assert(res.body.success === false);
51
+ const resBody = res.body;
52
+ assert(resBody.code === 50000);
53
+ assert(resBody.message === '获取项目异常');
54
+ });
55
+
56
+ it('GET /api/project with proj_key', async () => {
57
+ for (let i = 0; i < projectList.length; i++) {
58
+ const projItem = projectList[i];
59
+ const { key: projKey } = projItem;
60
+ console.log(`--------GET /api/project with proj_key:${projKey}`);
61
+ let tmpRequest = request.get('/api/project');
62
+ tmpRequest = tmpRequest.set('s_t', st);
63
+ tmpRequest = tmpRequest.set('s_sign', md5(`${signKey}_${st}`));
64
+ tmpRequest = tmpRequest.query({
65
+ proj_key: projKey,
66
+ });
67
+ const res = await tmpRequest;
68
+ assert(res.body.success === true);
69
+
70
+ const resData = res.body.data;
71
+ assert(resData.key === projKey);
72
+ assert(resData.modelKey);
73
+ assert(resData.name);
74
+ assert(resData.desc !== undefined);
75
+ assert(resData.homePage !== undefined);
76
+
77
+ const { menu } = resData;
78
+ menu.forEach((menuItem) => {
79
+ checkMenuItem(menuItem);
80
+ });
81
+ }
82
+
83
+ // 递归校验 menu 菜单
84
+ function checkMenuItem(menuItem) {
85
+ console.log(`--------GET /api/project with proj_key menuKey:${menuItem.key}`);
86
+ assert(menuItem.key);
87
+ assert(menuItem.name);
88
+ assert(menuItem.menuType);
89
+
90
+ if (menuItem.menuType === 'group') {
91
+ assert(menuItem.subMenu !== undefined);
92
+ menuItem.subMenu.forEach((subMenuItem) => {
93
+ checkMenuItem(subMenuItem);
94
+ });
95
+ }
96
+
97
+ if (menuItem.menuType === 'module') {
98
+ checkModule(menuItem);
99
+ }
100
+ }
101
+
102
+ // 检查 module 菜单配置
103
+ function checkModule(menuItem) {
104
+ const { moduleType } = menuItem;
105
+ assert(moduleType);
106
+
107
+ if (moduleType === 'sider') {
108
+ const { siderConfig } = menuItem;
109
+ assert(siderConfig);
110
+ assert(siderConfig.menu);
111
+ siderConfig.menu.forEach((siderMenuItem) => {
112
+ checkMenuItem(siderMenuItem);
113
+ });
114
+ }
115
+
116
+ if (moduleType === 'iframe') {
117
+ const { iframeConfig } = menuItem;
118
+ assert(iframeConfig);
119
+ assert(iframeConfig.path !== undefined);
120
+ }
121
+
122
+ if (moduleType === 'custom') {
123
+ const { customConfig } = menuItem;
124
+ assert(customConfig);
125
+ assert(customConfig.path !== undefined);
126
+ }
127
+
128
+ if (moduleType === 'scheam') {
129
+ const { scheamConfig } = menuItem;
130
+ assert(scheamConfig);
131
+ assert(scheamConfig.api !== undefined);
132
+ assert(scheamConfig.scheam);
133
+ }
134
+ }
135
+ });
136
+
137
+ it('GET /api/project/list without proj_key', async () => {
138
+ let tmpRequest = request.get('/api/project/list');
139
+ tmpRequest = tmpRequest.set('s_t', st);
140
+ tmpRequest = tmpRequest.set('s_sign', md5(`${signKey}_${st}`));
141
+ const res = await tmpRequest;
142
+ assert(res.body.success === true);
143
+ const resData = res.body.data;
144
+ assert(resData.length === projectList.length);
145
+ for (let i = 0; i < resData.length; i++) {
146
+ const item = resData[i];
147
+ assert(item.modelKey);
148
+ assert(item.key);
149
+ assert(item.name);
150
+ assert(item.desc !== undefined);
151
+ assert(item.homePage !== undefined);
152
+ }
153
+ });
154
+
155
+ it('GET /api/project/list with proj_key', async () => {
156
+ const { key: projKey } = projectList[Math.floor(Math.random() * projectList.length)];
157
+ const { modelKey } = projectList.find((item) => item.key === projKey);
158
+
159
+ let tmpRequest = request.get('/api/project/list');
160
+ tmpRequest = tmpRequest.set('s_t', st);
161
+ tmpRequest = tmpRequest.set('s_sign', md5(`${signKey}_${st}`));
162
+ tmpRequest = tmpRequest.query({
163
+ proj_key: projKey,
164
+ });
165
+ const res = await tmpRequest;
166
+ assert(res.body.success === true);
167
+
168
+ const resData = res.body.data;
169
+ assert(projectList.filter((item) => item.modelKey === modelKey).length === resData.length);
170
+ for (let i = 0; i < resData.length; i++) {
171
+ const item = resData[i];
172
+ assert(item.modelKey);
173
+ assert(item.key);
174
+ assert(item.name);
175
+ assert(item.desc !== undefined);
176
+ assert(item.homePage !== undefined);
177
+ }
178
+ });
179
+
180
+ it('GET /api/project/model_list', async () => {
181
+ let tmpRequest = request.get('/api/project/model_list');
182
+ tmpRequest = tmpRequest.set('s_t', st);
183
+ tmpRequest = tmpRequest.set('s_sign', md5(`${signKey}_${st}`));
184
+ const res = await tmpRequest;
185
+ assert(res.body.success === true);
186
+ const resData = res.body.data;
187
+ assert(resData.length > 0);
188
+ for (let i = 0; i < resData.length; i++) {
189
+ const item = resData[i];
190
+ assert(item.model);
191
+ assert(item.model.key);
192
+ assert(item.model.name);
193
+ assert(item.project);
194
+ for (const projKey in item.project) {
195
+ assert(item.project[projKey].key);
196
+ assert(item.project[projKey].name);
197
+ }
198
+ }
199
+ });
200
+ });