@jiangliffey/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 +55 -0
- package/CLAUDE.md +81 -0
- package/README.md +200 -0
- package/app/controller/base.js +38 -0
- package/app/controller/project.js +74 -0
- package/app/controller/view.js +22 -0
- package/app/extend/logger.js +35 -0
- package/app/middleware/api-params-verify.js +81 -0
- package/app/middleware/api-sign-verify.js +35 -0
- package/app/middleware/error-handler.js +33 -0
- package/app/middleware/project-handler.js +27 -0
- package/app/middleware.js +37 -0
- package/app/pages/asserts/custom.css +12 -0
- package/app/pages/boot.js +50 -0
- package/app/pages/common/curl.js +89 -0
- package/app/pages/common/utils.js +2 -0
- package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +21 -0
- package/app/pages/dashboard/complex-view/header-view/header-view.vue +123 -0
- package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +43 -0
- package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +40 -0
- package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +124 -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 +87 -0
- package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +100 -0
- package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +118 -0
- package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +124 -0
- package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +80 -0
- package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +21 -0
- package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +135 -0
- package/app/pages/dashboard/dashboard.vue +96 -0
- package/app/pages/dashboard/entry.dashboard.js +45 -0
- package/app/pages/dashboard/todo/todo.vue +11 -0
- package/app/pages/store/index.js +4 -0
- package/app/pages/store/menu.js +58 -0
- package/app/pages/store/project.js +14 -0
- package/app/pages/widgets/header-container/asserts/avatar.png +0 -0
- package/app/pages/widgets/header-container/asserts/logo.png +0 -0
- package/app/pages/widgets/header-container/header-container.vue +106 -0
- package/app/pages/widgets/schema-form/complex-view/input/input.vue +134 -0
- package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +136 -0
- package/app/pages/widgets/schema-form/complex-view/select/select.vue +116 -0
- package/app/pages/widgets/schema-form/form-item-config.js +23 -0
- package/app/pages/widgets/schema-form/schema-form.vue +135 -0
- package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +50 -0
- package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +67 -0
- package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +44 -0
- package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +51 -0
- package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +129 -0
- package/app/pages/widgets/schema-search-bar/search-item-config.js +27 -0
- package/app/pages/widgets/schema-table/schema-table.vue +235 -0
- package/app/pages/widgets/sider-container/sider-container.vue +31 -0
- package/app/public/static/logo.png +0 -0
- package/app/public/static/normalize.css +239 -0
- package/app/router/project.js +6 -0
- package/app/router/view.js +8 -0
- package/app/router-schema/project.js +30 -0
- package/app/service/base.js +11 -0
- package/app/service/project.js +56 -0
- package/app/view/entry.tpl +26 -0
- package/app/webpack/config/webpack.base.js +203 -0
- package/app/webpack/config/webpack.dev.js +59 -0
- package/app/webpack/config/webpack.prod.js +107 -0
- package/app/webpack/dev.js +53 -0
- package/app/webpack/libs/blank.js +3 -0
- package/app/webpack/prod.js +17 -0
- package/config/config.default.js +3 -0
- package/docs/dashboard-model.js +153 -0
- package/elpis-core/env.js +23 -0
- package/elpis-core/index.js +96 -0
- package/elpis-core/loader/config.js +50 -0
- package/elpis-core/loader/controller.js +54 -0
- package/elpis-core/loader/extend.js +49 -0
- package/elpis-core/loader/middleware.js +53 -0
- package/elpis-core/loader/router-schema.js +41 -0
- package/elpis-core/loader/router.js +45 -0
- package/elpis-core/loader/service.js +54 -0
- package/index.js +40 -0
- package/model/index.js +99 -0
- package/package.json +92 -0
- package/test/controller/project.test.js +225 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
const assert = require('assert');
|
|
2
|
+
const supertest = require('supertest');
|
|
3
|
+
const md5 = require('md5');
|
|
4
|
+
const elpisCore = require('../../elpis-core');
|
|
5
|
+
|
|
6
|
+
const signKey = 'dftgyh84adsuh462wef46ef5s6d4fiop';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 设置接口签名请求头
|
|
10
|
+
* 每次请求动态生成 s_t,避免时间戳过期
|
|
11
|
+
*/
|
|
12
|
+
function setSignHeaders(req) {
|
|
13
|
+
const st = Date.now();
|
|
14
|
+
|
|
15
|
+
return req
|
|
16
|
+
.set('s_t', st)
|
|
17
|
+
.set('s_sign', md5(`${signKey}_${st}`));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
describe('测试 project 相关接口', function() {
|
|
21
|
+
this.timeout(60000);
|
|
22
|
+
|
|
23
|
+
let modelList;
|
|
24
|
+
const projectList = [];
|
|
25
|
+
|
|
26
|
+
let request;
|
|
27
|
+
|
|
28
|
+
// it('启动服务', async () => {
|
|
29
|
+
// const app = await elpisCore.start();
|
|
30
|
+
// request = supertest(app.listen());
|
|
31
|
+
// });
|
|
32
|
+
before('启动服务',async function () {
|
|
33
|
+
console.log('---- 启动服务');
|
|
34
|
+
const app = await elpisCore.start();
|
|
35
|
+
modelList = require('../../model/index.js')(app);
|
|
36
|
+
modelList.forEach(modelItem => {
|
|
37
|
+
const { project } = modelItem;
|
|
38
|
+
for(const pKey in project) {
|
|
39
|
+
projectList.push(project[pKey]);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
// 使用 app.callback(),避免真正监听端口
|
|
43
|
+
request = supertest(app.callback());
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('GET /api/project without proj_key', async function () {
|
|
47
|
+
const res = await setSignHeaders(
|
|
48
|
+
request.get('/api/project')
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const resBody = res.body;
|
|
52
|
+
assert.strictEqual(resBody.success, false);
|
|
53
|
+
assert.strictEqual(resBody.code, 442);
|
|
54
|
+
assert.ok(
|
|
55
|
+
resBody.message.includes(`data should have required property 'proj_key'`)
|
|
56
|
+
);
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('GET /api/project fail', async function () {
|
|
60
|
+
const res = await setSignHeaders(
|
|
61
|
+
request.get('/api/project').query({
|
|
62
|
+
proj_key: 'not_exist_project'
|
|
63
|
+
})
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const resBody = res.body;
|
|
67
|
+
assert.strictEqual(resBody.success, false);
|
|
68
|
+
assert.strictEqual(resBody.code, 50000);
|
|
69
|
+
assert.strictEqual(resBody.message, '获取项目异常');
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('GET /api/project with proj_key', async function () {
|
|
73
|
+
for(let i = 0; i < projectList.length; i++) {
|
|
74
|
+
const projItem = projectList[i];
|
|
75
|
+
const { key: projKey } = projItem;
|
|
76
|
+
|
|
77
|
+
console.log(`--------GET /api/project with proj_key: ${projKey}`);
|
|
78
|
+
|
|
79
|
+
const res = await setSignHeaders(
|
|
80
|
+
request.get('/api/project').query({
|
|
81
|
+
proj_key: projKey
|
|
82
|
+
})
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
assert.strictEqual(res.body.success, true);
|
|
86
|
+
const resData = res.body.data;
|
|
87
|
+
assert.strictEqual(resData.key, projKey);
|
|
88
|
+
assert.ok(resData.modelKey);
|
|
89
|
+
assert.ok(resData.name);
|
|
90
|
+
assert.ok(resData.desc !== undefined);
|
|
91
|
+
assert.ok(resData.homePage !== undefined);
|
|
92
|
+
|
|
93
|
+
const { menu } = resData;
|
|
94
|
+
menu.forEach(menuItem => {
|
|
95
|
+
checkMenuItem(menuItem);
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 校验 menu 菜单
|
|
100
|
+
function checkMenuItem (menuItem) {
|
|
101
|
+
console.log('--------GET /api/project with proj_key - menuKey:', menuItem.key);
|
|
102
|
+
assert.ok(menuItem.key);
|
|
103
|
+
assert.ok(menuItem.name);
|
|
104
|
+
assert.ok(menuItem.menuType);
|
|
105
|
+
|
|
106
|
+
if(menuItem.menuType === 'group') {
|
|
107
|
+
assert.ok(menuItem.subMenu !== undefined);
|
|
108
|
+
menuItem.subMenu.forEach(subMenuItem => {
|
|
109
|
+
checkMenuItem(subMenuItem);
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if(menuItem.menuType === 'module') {
|
|
114
|
+
checkModule(menuItem);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 校验 module 菜单配置
|
|
119
|
+
function checkModule (menuItem) {
|
|
120
|
+
const { moduleType } = menuItem;
|
|
121
|
+
assert(moduleType);
|
|
122
|
+
|
|
123
|
+
if(moduleType === 'sider') {
|
|
124
|
+
const { siderConfig } = menuItem;
|
|
125
|
+
assert.ok(siderConfig);
|
|
126
|
+
assert.ok(Array.isArray(siderConfig.menu));
|
|
127
|
+
siderConfig.menu.forEach(siderMenuItem => {
|
|
128
|
+
checkMenuItem(siderMenuItem);
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if(moduleType === 'iframe') {
|
|
133
|
+
const { iframeConfig } = menuItem;
|
|
134
|
+
assert.ok(iframeConfig);
|
|
135
|
+
assert.ok(iframeConfig.path !== undefined);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if(moduleType === 'custom') {
|
|
139
|
+
const { customConfig } = menuItem;
|
|
140
|
+
assert.ok(customConfig);
|
|
141
|
+
assert.ok(customConfig.path !== undefined);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if(moduleType === 'schema') {
|
|
145
|
+
const { schemaConfig } = menuItem;
|
|
146
|
+
assert.ok(schemaConfig);
|
|
147
|
+
assert.ok(schemaConfig.api !== undefined);
|
|
148
|
+
assert.ok(schemaConfig.schema);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('GET /api/project/list without proj_key', async function () {
|
|
155
|
+
const res = await setSignHeaders(
|
|
156
|
+
request.get('/api/project/list')
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
assert.strictEqual(res.body.success, true);
|
|
160
|
+
|
|
161
|
+
const resData = res.body.data;
|
|
162
|
+
assert.strictEqual(resData.length, projectList.length);
|
|
163
|
+
for(let i = 0; i < resData.length; i++) {
|
|
164
|
+
// modelKey, key, name, desc, homePage
|
|
165
|
+
const item = resData[i];
|
|
166
|
+
assert.ok(item.modelKey);
|
|
167
|
+
assert.ok(item.key);
|
|
168
|
+
assert.ok(item.name);
|
|
169
|
+
assert.ok(item.desc !== undefined);
|
|
170
|
+
assert.ok(item.homePage !== undefined);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('GET /api/project/list with proj_key', async function () {
|
|
175
|
+
const { key: projKey } = projectList[Math.floor(Math.random() * projectList.length)];
|
|
176
|
+
const { modelKey } = projectList.find(item => item.key == projKey );
|
|
177
|
+
// 和当前 projKey 属于同一个 modelKey 的项目列表
|
|
178
|
+
const expectedProjectList = projectList.filter(item => {
|
|
179
|
+
return item.modelKey === modelKey;
|
|
180
|
+
});
|
|
181
|
+
const res = await setSignHeaders(
|
|
182
|
+
request.get('/api/project/list').query({
|
|
183
|
+
proj_key: projKey
|
|
184
|
+
})
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
assert.strictEqual(res.body.success, true);
|
|
188
|
+
|
|
189
|
+
const resData = res.body.data;
|
|
190
|
+
assert.strictEqual(resData.length, expectedProjectList.length);
|
|
191
|
+
for(let i = 0; i < resData.length; i++) {
|
|
192
|
+
// modelKey, key, name, desc, homePage
|
|
193
|
+
const item = resData[i];
|
|
194
|
+
assert.strictEqual(item.modelKey, modelKey);
|
|
195
|
+
assert.ok(item.key);
|
|
196
|
+
assert.ok(item.name);
|
|
197
|
+
assert.ok(item.desc !== undefined);
|
|
198
|
+
assert.ok(item.homePage !== undefined);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('GET /api/project/model_list', async function () {
|
|
203
|
+
const res = await setSignHeaders(
|
|
204
|
+
request.get('/api/project/model_list')
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
assert.strictEqual(res.body.success, true);
|
|
208
|
+
|
|
209
|
+
const resData = res.body.data;
|
|
210
|
+
assert.ok(resData.length > 0);
|
|
211
|
+
|
|
212
|
+
for(let i = 0; i < resData.length; i++) {
|
|
213
|
+
const item = resData[i];
|
|
214
|
+
assert.ok(item.model);
|
|
215
|
+
assert.ok(item.model.key);
|
|
216
|
+
assert.ok(item.model.name);
|
|
217
|
+
assert.ok(item.project);
|
|
218
|
+
for(const projKey in item.project) {
|
|
219
|
+
const project = item.project[projKey];
|
|
220
|
+
assert.ok(project.key);
|
|
221
|
+
assert.ok(project.name);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
})
|
|
225
|
+
});
|