@wanglindoc/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 +2 -0
- package/.eslintrc +52 -0
- package/.idea/codeStyles/Project.xml +14 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/elpis.iml +12 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/prettier.xml +7 -0
- package/.idea/vcs.xml +6 -0
- package/README.md +232 -0
- package/app/controller/base.js +42 -0
- package/app/controller/project.js +76 -0
- package/app/controller/view.js +19 -0
- package/app/extend/logger.js +42 -0
- package/app/middleware/api-params-verify.js +81 -0
- package/app/middleware/api-sign-verify.js +45 -0
- package/app/middleware/error-handler.js +41 -0
- package/app/middleware/project-handler.js +30 -0
- package/app/middleware.js +42 -0
- package/app/pages/assets/custom.css +14 -0
- package/app/pages/boot.js +51 -0
- package/app/pages/common/curl.js +91 -0
- package/app/pages/common/utils.js +7 -0
- package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +18 -0
- package/app/pages/dashboard/complex-view/header-view/header-view.vue +154 -0
- package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +46 -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 +127 -0
- package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +22 -0
- package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +95 -0
- package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +104 -0
- package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +129 -0
- package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +137 -0
- package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +102 -0
- package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu.vue +21 -0
- package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +141 -0
- package/app/pages/dashboard/dashboard.vue +96 -0
- package/app/pages/dashboard/entry.dashboard.js +53 -0
- package/app/pages/dashboard/todo/todo.vue +6 -0
- package/app/pages/store/index.js +5 -0
- package/app/pages/store/menu.js +73 -0
- package/app/pages/store/project.js +15 -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 +137 -0
- package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +135 -0
- package/app/pages/widgets/schema-form/complex-view/select/select.vue +119 -0
- package/app/pages/widgets/schema-form/form-item-config.js +20 -0
- package/app/pages/widgets/schema-form/schema-form.vue +145 -0
- package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +52 -0
- package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +65 -0
- package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +42 -0
- package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +49 -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 +24 -0
- package/app/pages/widgets/schema-table/schema-table.vue +212 -0
- package/app/pages/widgets/sider-container/sider-container.vue +26 -0
- package/app/public/output/entry.page1.tpl +55 -0
- package/app/public/output/entry.page2.tpl +11 -0
- package/app/public/static/favicon.ico +0 -0
- package/app/public/static/normalize.css +267 -0
- package/app/router/project.js +14 -0
- package/app/router/view.js +9 -0
- package/app/router-schema/project.js +32 -0
- package/app/service/base.js +15 -0
- package/app/service/project.js +48 -0
- package/app/view/entry.tpl +22 -0
- package/app/webpack/build-dev.js +64 -0
- package/app/webpack/build-prod.js +29 -0
- package/app/webpack/config/webpack.base.js +352 -0
- package/app/webpack/config/webpack.dev.js +59 -0
- package/app/webpack/config/webpack.prod.js +145 -0
- package/app/webpack/libs/blank.js +1 -0
- package/config/config.default.js +4 -0
- package/elpis-core/env.js +20 -0
- package/elpis-core/index.js +106 -0
- package/elpis-core/loader/config.js +62 -0
- package/elpis-core/loader/controller.js +79 -0
- package/elpis-core/loader/extend.js +67 -0
- package/elpis-core/loader/middleware.js +77 -0
- package/elpis-core/loader/router-schema.js +57 -0
- package/elpis-core/loader/router.js +57 -0
- package/elpis-core/loader/service.js +76 -0
- package/index.js +39 -0
- package/model/index.js +128 -0
- package/package.json +90 -0
- package/test/controller/project.test.js +243 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-drawer
|
|
3
|
+
v-model="isShow"
|
|
4
|
+
direction="rtl"
|
|
5
|
+
:destory-on-close="true"
|
|
6
|
+
:size="550"
|
|
7
|
+
>
|
|
8
|
+
<template #header>
|
|
9
|
+
<h3>{{ title }}</h3>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<template #default>
|
|
13
|
+
<schema-form
|
|
14
|
+
ref="schemaFormRef"
|
|
15
|
+
v-loading="loading"
|
|
16
|
+
:schema="components[name]?.schema"
|
|
17
|
+
></schema-form>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<template #footer>
|
|
21
|
+
<el-button type="primary" @click="save">
|
|
22
|
+
{{ saveBtnText }}
|
|
23
|
+
</el-button>
|
|
24
|
+
</template>
|
|
25
|
+
</el-drawer>
|
|
26
|
+
</template>
|
|
27
|
+
|
|
28
|
+
<script setup>
|
|
29
|
+
import { ref, inject } from "vue";
|
|
30
|
+
import SchemaForm from "$elpisWidgets/schema-form/schema-form.vue";
|
|
31
|
+
import $curl from "$elpisCommon/curl.js";
|
|
32
|
+
import { ElNotification } from "element-plus";
|
|
33
|
+
|
|
34
|
+
const { api, components } = inject("schemaViewData");
|
|
35
|
+
const emits = defineEmits(["command"]);
|
|
36
|
+
|
|
37
|
+
const name = ref("createForm");
|
|
38
|
+
const isShow = ref(false);
|
|
39
|
+
const title = ref("");
|
|
40
|
+
const saveBtnText = ref("");
|
|
41
|
+
const loading = ref(false);
|
|
42
|
+
const schemaFormRef = ref(null);
|
|
43
|
+
|
|
44
|
+
const show = (rowData) => {
|
|
45
|
+
const { config } = components.value[name.value];
|
|
46
|
+
title.value = config.title;
|
|
47
|
+
saveBtnText.value = config.saveBtnText;
|
|
48
|
+
|
|
49
|
+
isShow.value = true;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const save = async () => {
|
|
53
|
+
if (loading.value) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 校验表单
|
|
58
|
+
if (!schemaFormRef.value?.validate()) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
loading.value = true;
|
|
63
|
+
|
|
64
|
+
const res = await $curl({
|
|
65
|
+
method: "post",
|
|
66
|
+
url: api.value,
|
|
67
|
+
data: {
|
|
68
|
+
...schemaFormRef.value.getValue(),
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
loading.value = false;
|
|
73
|
+
|
|
74
|
+
if (!res || !res.success) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
ElNotification({
|
|
79
|
+
title: "创建成功",
|
|
80
|
+
message: "创建成功",
|
|
81
|
+
type: "success",
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
isShow.value = false;
|
|
85
|
+
|
|
86
|
+
emits("command", { event: "loadTableData" });
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
defineExpose({
|
|
90
|
+
name,
|
|
91
|
+
show,
|
|
92
|
+
});
|
|
93
|
+
</script>
|
|
94
|
+
|
|
95
|
+
<style lang="less" scoped></style>
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-drawer
|
|
3
|
+
v-model="isShow"
|
|
4
|
+
direction="rtl"
|
|
5
|
+
:destory-on-close="true"
|
|
6
|
+
:size="550"
|
|
7
|
+
>
|
|
8
|
+
<template #header>
|
|
9
|
+
<h3>{{ title }}</h3>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<template #default>
|
|
13
|
+
<el-card v-loading="loading" shadow="always" class="detail-panel">
|
|
14
|
+
<el-row
|
|
15
|
+
v-for="(item, key) in components[name]?.schema?.properties"
|
|
16
|
+
:key="key"
|
|
17
|
+
type="flex"
|
|
18
|
+
align="middle"
|
|
19
|
+
class="row-item"
|
|
20
|
+
>
|
|
21
|
+
<el-row class="item-label">{{ item.label }}:</el-row>
|
|
22
|
+
<el-row class="item-value">{{ dtoModel[key] }}</el-row>
|
|
23
|
+
</el-row>
|
|
24
|
+
</el-card>
|
|
25
|
+
</template>
|
|
26
|
+
</el-drawer>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<script setup>
|
|
30
|
+
import { ref, inject } from "vue";
|
|
31
|
+
import $curl from "$elpisCommon/curl.js";
|
|
32
|
+
|
|
33
|
+
const { api, components } = inject("schemaViewData");
|
|
34
|
+
|
|
35
|
+
const name = ref("detailPanel");
|
|
36
|
+
|
|
37
|
+
const isShow = ref(false);
|
|
38
|
+
const title = ref("");
|
|
39
|
+
const mainKey = ref("");
|
|
40
|
+
const mainValue = ref();
|
|
41
|
+
const loading = ref(false);
|
|
42
|
+
const dtoModel = ref({});
|
|
43
|
+
|
|
44
|
+
const show = (rowData) => {
|
|
45
|
+
const { config } = components.value[name.value];
|
|
46
|
+
title.value = config.title;
|
|
47
|
+
mainKey.value = config.mainKey;
|
|
48
|
+
mainValue.value = rowData[config.mainKey];
|
|
49
|
+
|
|
50
|
+
isShow.value = true;
|
|
51
|
+
|
|
52
|
+
fetchFormData();
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const fetchFormData = async () => {
|
|
56
|
+
if (loading.value) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
loading.value = true;
|
|
61
|
+
|
|
62
|
+
const res = await $curl({
|
|
63
|
+
method: "get",
|
|
64
|
+
url: api.value,
|
|
65
|
+
query: {
|
|
66
|
+
[mainKey.value]: mainValue.value,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
loading.value = false;
|
|
71
|
+
|
|
72
|
+
if (!res || !res.success || !res.data) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
dtoModel.value = res.data;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
defineExpose({
|
|
80
|
+
name,
|
|
81
|
+
show,
|
|
82
|
+
});
|
|
83
|
+
</script>
|
|
84
|
+
|
|
85
|
+
<style scoped lang="less">
|
|
86
|
+
.detail-panel {
|
|
87
|
+
padding: 20px;
|
|
88
|
+
|
|
89
|
+
.row-item {
|
|
90
|
+
height: 40px;
|
|
91
|
+
line-height: 40px;
|
|
92
|
+
font-size: 20px;
|
|
93
|
+
|
|
94
|
+
.item-label {
|
|
95
|
+
margin-right: 20px;
|
|
96
|
+
width: 120px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.item-value {
|
|
100
|
+
color: #999999;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
</style>
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-drawer
|
|
3
|
+
v-model="isShow"
|
|
4
|
+
direction="rtl"
|
|
5
|
+
:destory-on-close="true"
|
|
6
|
+
:size="550"
|
|
7
|
+
>
|
|
8
|
+
<template #header>
|
|
9
|
+
<h3>{{ title }}</h3>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<template #default>
|
|
13
|
+
<schema-form
|
|
14
|
+
ref="schemaFormRef"
|
|
15
|
+
v-loading="loading"
|
|
16
|
+
:schema="components[name]?.schema"
|
|
17
|
+
:model="dtoModel"
|
|
18
|
+
></schema-form>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<template #footer>
|
|
22
|
+
<el-button type="primary" @click="save">
|
|
23
|
+
{{ saveBtnText }}
|
|
24
|
+
</el-button>
|
|
25
|
+
</template>
|
|
26
|
+
</el-drawer>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<script setup>
|
|
30
|
+
import { ref, inject } from "vue";
|
|
31
|
+
import SchemaForm from "$elpisWidgets/schema-form/schema-form.vue";
|
|
32
|
+
import $curl from "$elpisCommon/curl.js";
|
|
33
|
+
import { ElNotification } from "element-plus";
|
|
34
|
+
|
|
35
|
+
const { api, components } = inject("schemaViewData");
|
|
36
|
+
const emits = defineEmits(["command"]);
|
|
37
|
+
|
|
38
|
+
const name = ref("editForm");
|
|
39
|
+
|
|
40
|
+
const isShow = ref(false);
|
|
41
|
+
const title = ref("");
|
|
42
|
+
const saveBtnText = ref("");
|
|
43
|
+
const mainKey = ref("");
|
|
44
|
+
const mainValue = ref();
|
|
45
|
+
const loading = ref(false);
|
|
46
|
+
const dtoModel = ref({});
|
|
47
|
+
const schemaFormRef = ref(null);
|
|
48
|
+
|
|
49
|
+
const show = (rowData) => {
|
|
50
|
+
const { config } = components.value[name.value];
|
|
51
|
+
title.value = config.title;
|
|
52
|
+
saveBtnText.value = config.saveBtnText;
|
|
53
|
+
mainKey.value = config.mainKey;
|
|
54
|
+
mainValue.value = rowData[config.mainKey];
|
|
55
|
+
|
|
56
|
+
isShow.value = true;
|
|
57
|
+
|
|
58
|
+
fetchFormData();
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const fetchFormData = async () => {
|
|
62
|
+
if (loading.value) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
loading.value = true;
|
|
67
|
+
|
|
68
|
+
const res = await $curl({
|
|
69
|
+
method: "get",
|
|
70
|
+
url: api.value,
|
|
71
|
+
query: {
|
|
72
|
+
[mainKey.value]: mainValue.value,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
loading.value = false;
|
|
77
|
+
|
|
78
|
+
if (!res || !res.success || !res.data) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
dtoModel.value = res.data;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const save = () => {
|
|
86
|
+
if (loading.value) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (!schemaFormRef.value.validate()) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
loading.value = true;
|
|
94
|
+
|
|
95
|
+
const res = $curl({
|
|
96
|
+
method: "put",
|
|
97
|
+
url: api.value,
|
|
98
|
+
data: {
|
|
99
|
+
[mainKey.value]: mainValue.value,
|
|
100
|
+
...schemaFormRef.value.getValue(),
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
loading.value = false;
|
|
105
|
+
|
|
106
|
+
if (!res || !res.success) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
ElNotification({
|
|
111
|
+
title: "修改成功",
|
|
112
|
+
message: "修改成功",
|
|
113
|
+
type: "success",
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
isShow.value = false;
|
|
117
|
+
|
|
118
|
+
emits("command", {
|
|
119
|
+
event: "loadTableData",
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
defineExpose({
|
|
124
|
+
name,
|
|
125
|
+
show,
|
|
126
|
+
});
|
|
127
|
+
</script>
|
|
128
|
+
|
|
129
|
+
<style scoped lang="less"></style>
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { ref, watch, onMounted, nextTick } from "vue";
|
|
2
|
+
import { useRoute } from "vue-router";
|
|
3
|
+
import { useMenuStore } from "$elpisStore/menu.js";
|
|
4
|
+
|
|
5
|
+
export const useSchema = function () {
|
|
6
|
+
const route = useRoute();
|
|
7
|
+
const menuStore = useMenuStore();
|
|
8
|
+
|
|
9
|
+
const api = ref("");
|
|
10
|
+
const tableSchema = ref({});
|
|
11
|
+
const tableConfig = ref();
|
|
12
|
+
const searchSchema = ref({});
|
|
13
|
+
const searchConfig = ref();
|
|
14
|
+
|
|
15
|
+
const components = ref({});
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 构造 schemaConfig 相关配置,输送给 schemaView 解释
|
|
19
|
+
*/
|
|
20
|
+
const buildData = function () {
|
|
21
|
+
const { key, sider_key: siderKey } = route.query;
|
|
22
|
+
|
|
23
|
+
const mItem = menuStore.findMenuItem({
|
|
24
|
+
key: "key",
|
|
25
|
+
value: siderKey ?? key,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (mItem && mItem.schemaConfig) {
|
|
29
|
+
const { schemaConfig } = mItem;
|
|
30
|
+
|
|
31
|
+
const configSchema = JSON.parse(JSON.stringify(schemaConfig.schema));
|
|
32
|
+
|
|
33
|
+
api.value = schemaConfig.api ?? "";
|
|
34
|
+
tableSchema.value = {};
|
|
35
|
+
tableConfig.value = undefined;
|
|
36
|
+
searchSchema.value = {};
|
|
37
|
+
searchConfig.value = undefined;
|
|
38
|
+
|
|
39
|
+
components.value = {};
|
|
40
|
+
|
|
41
|
+
nextTick(() => {
|
|
42
|
+
// 构造 tableSchema 和 tableConfig
|
|
43
|
+
tableSchema.value = buildDtoSchema(configSchema, "table");
|
|
44
|
+
tableConfig.value = schemaConfig.tableConfig;
|
|
45
|
+
|
|
46
|
+
// 构造 searchSchema 和 searchConfig
|
|
47
|
+
const dtoSearchSchema = buildDtoSchema(configSchema, "search");
|
|
48
|
+
for (const key in dtoSearchSchema.properties) {
|
|
49
|
+
if (route.query[key] !== undefined) {
|
|
50
|
+
dtoSearchSchema.properties[key].option.default = route.query[key];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
searchSchema.value = dtoSearchSchema;
|
|
54
|
+
searchConfig.value = schemaConfig.searchConfig;
|
|
55
|
+
|
|
56
|
+
// 构造 components { componentKey: { schema, config } }
|
|
57
|
+
const { componentConfig } = schemaConfig;
|
|
58
|
+
|
|
59
|
+
if (componentConfig && Object.keys(componentConfig.length > 0)) {
|
|
60
|
+
const dtoComponents = {};
|
|
61
|
+
for (const comName in componentConfig) {
|
|
62
|
+
dtoComponents[comName] = {
|
|
63
|
+
schema: buildDtoSchema(configSchema, comName),
|
|
64
|
+
config: componentConfig[comName],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
components.value = dtoComponents;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 通用构建 schema 方法
|
|
76
|
+
* @returns
|
|
77
|
+
*/
|
|
78
|
+
const buildDtoSchema = (_schema, comName) => {
|
|
79
|
+
if (!_schema?.properties) {
|
|
80
|
+
return {};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const dtoSchema = {
|
|
84
|
+
type: "object",
|
|
85
|
+
properties: {},
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
for (let key in _schema.properties) {
|
|
89
|
+
const props = _schema.properties[key];
|
|
90
|
+
|
|
91
|
+
if (props[`${comName}Option`]) {
|
|
92
|
+
let dtoProps = {};
|
|
93
|
+
|
|
94
|
+
for (let pKey in props) {
|
|
95
|
+
if (pKey.indexOf("Option" < 0)) {
|
|
96
|
+
dtoProps[pKey] = props[pKey];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
dtoProps = Object.assign({}, dtoProps, {
|
|
101
|
+
option: props[`${comName}Option`],
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// 处理 required 字段
|
|
105
|
+
const { required } = _schema;
|
|
106
|
+
if (required && required.find((pk) => pk === key)) {
|
|
107
|
+
dtoProps.option.required = true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
dtoSchema.properties[key] = dtoProps;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return dtoSchema;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
watch(
|
|
118
|
+
[
|
|
119
|
+
() => route.query.key,
|
|
120
|
+
() => route.query.sider_key,
|
|
121
|
+
() => menuStore.menuList,
|
|
122
|
+
],
|
|
123
|
+
() => buildData(),
|
|
124
|
+
{ deep: true },
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
onMounted(() => buildData());
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
api,
|
|
131
|
+
tableSchema,
|
|
132
|
+
tableConfig,
|
|
133
|
+
searchSchema,
|
|
134
|
+
searchConfig,
|
|
135
|
+
components,
|
|
136
|
+
};
|
|
137
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-row class="schema-view">
|
|
3
|
+
<search-panel
|
|
4
|
+
v-if="
|
|
5
|
+
searchSchema?.properties &&
|
|
6
|
+
Object.keys(searchSchema.properties).length > 0
|
|
7
|
+
"
|
|
8
|
+
@search="onSearch"
|
|
9
|
+
></search-panel>
|
|
10
|
+
|
|
11
|
+
<table-panel ref="tablePanelRef" @operate="onTableOperate"></table-panel>
|
|
12
|
+
|
|
13
|
+
<component
|
|
14
|
+
v-for="(item, key) in components"
|
|
15
|
+
:key="key"
|
|
16
|
+
:is="ComponentsConfig[key]?.component"
|
|
17
|
+
ref="comListRef"
|
|
18
|
+
@command="onComponentCommand"
|
|
19
|
+
></component>
|
|
20
|
+
</el-row>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script setup>
|
|
24
|
+
import { provide, ref } from "vue";
|
|
25
|
+
import SearchPanel from "./complex-view/search-panel/search-panel.vue";
|
|
26
|
+
import TablePanel from "./complex-view/table-panel/table-panel.vue";
|
|
27
|
+
import { useSchema } from "./hook/schema.js";
|
|
28
|
+
import ComponentsConfig from "./components/component-config.js";
|
|
29
|
+
|
|
30
|
+
const {
|
|
31
|
+
api,
|
|
32
|
+
tableSchema,
|
|
33
|
+
tableConfig,
|
|
34
|
+
searchSchema,
|
|
35
|
+
searchConfig,
|
|
36
|
+
components,
|
|
37
|
+
} = useSchema();
|
|
38
|
+
|
|
39
|
+
const apiParams = ref({});
|
|
40
|
+
provide("schemaViewData", {
|
|
41
|
+
api,
|
|
42
|
+
apiParams,
|
|
43
|
+
tableSchema,
|
|
44
|
+
tableConfig,
|
|
45
|
+
searchSchema,
|
|
46
|
+
searchConfig,
|
|
47
|
+
components,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const comListRef = ref([]);
|
|
51
|
+
const tablePanelRef = ref(null);
|
|
52
|
+
|
|
53
|
+
const onSearch = (searchValueObj) => {
|
|
54
|
+
apiParams.value = searchValueObj;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const EventHandlerMap = {
|
|
58
|
+
showComponent: showComponent,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const onTableOperate = ({ btnConfig, rowData }) => {
|
|
62
|
+
const { eventKey } = btnConfig;
|
|
63
|
+
if (EventHandlerMap[eventKey]) {
|
|
64
|
+
EventHandlerMap[eventKey]({ btnConfig, rowData });
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// showComponent 展示动态组件
|
|
69
|
+
function showComponent({ btnConfig, rowData }) {
|
|
70
|
+
const { comName } = btnConfig.eventOption;
|
|
71
|
+
if (!comName) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const comRef = comListRef.value.find((item) => item.name === comName);
|
|
76
|
+
|
|
77
|
+
if (!comRef || typeof comRef.show !== "function") {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
comRef.show(rowData);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 响应组件事件
|
|
86
|
+
*/
|
|
87
|
+
const onComponentCommand = (data) => {
|
|
88
|
+
const { event } = data;
|
|
89
|
+
if (event === "loadTableData") {
|
|
90
|
+
tablePanelRef.value.loadTableData();
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
</script>
|
|
94
|
+
|
|
95
|
+
<style scoped lang="less">
|
|
96
|
+
.schema-view {
|
|
97
|
+
display: flex;
|
|
98
|
+
flex-direction: column;
|
|
99
|
+
width: 100%;
|
|
100
|
+
height: 100%;
|
|
101
|
+
}
|
|
102
|
+
</style>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-sub-menu :index="menuItem.key">
|
|
3
|
+
<template #title>{{ menuItem.name }}</template>
|
|
4
|
+
|
|
5
|
+
<div v-for="item in menuItem.subMenu" :key="item.key">
|
|
6
|
+
<sub-menu
|
|
7
|
+
v-if="item.subMenu && item.subMenu.length > 0"
|
|
8
|
+
:menu-item="item"
|
|
9
|
+
>
|
|
10
|
+
</sub-menu>
|
|
11
|
+
|
|
12
|
+
<el-menu-item v-else :index="item.key">{{ item.name }}</el-menu-item>
|
|
13
|
+
</div>
|
|
14
|
+
</el-sub-menu>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script setup>
|
|
18
|
+
const { menuItem } = defineProps(["menuItem"]);
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<style scoped lang="less"></style>
|