@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.
Files changed (81) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc +55 -0
  3. package/CLAUDE.md +81 -0
  4. package/README.md +200 -0
  5. package/app/controller/base.js +38 -0
  6. package/app/controller/project.js +74 -0
  7. package/app/controller/view.js +22 -0
  8. package/app/extend/logger.js +35 -0
  9. package/app/middleware/api-params-verify.js +81 -0
  10. package/app/middleware/api-sign-verify.js +35 -0
  11. package/app/middleware/error-handler.js +33 -0
  12. package/app/middleware/project-handler.js +27 -0
  13. package/app/middleware.js +37 -0
  14. package/app/pages/asserts/custom.css +12 -0
  15. package/app/pages/boot.js +50 -0
  16. package/app/pages/common/curl.js +89 -0
  17. package/app/pages/common/utils.js +2 -0
  18. package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +21 -0
  19. package/app/pages/dashboard/complex-view/header-view/header-view.vue +123 -0
  20. package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +43 -0
  21. package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +40 -0
  22. package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +124 -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 +87 -0
  25. package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +100 -0
  26. package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +118 -0
  27. package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +124 -0
  28. package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +80 -0
  29. package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +21 -0
  30. package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +135 -0
  31. package/app/pages/dashboard/dashboard.vue +96 -0
  32. package/app/pages/dashboard/entry.dashboard.js +45 -0
  33. package/app/pages/dashboard/todo/todo.vue +11 -0
  34. package/app/pages/store/index.js +4 -0
  35. package/app/pages/store/menu.js +58 -0
  36. package/app/pages/store/project.js +14 -0
  37. package/app/pages/widgets/header-container/asserts/avatar.png +0 -0
  38. package/app/pages/widgets/header-container/asserts/logo.png +0 -0
  39. package/app/pages/widgets/header-container/header-container.vue +106 -0
  40. package/app/pages/widgets/schema-form/complex-view/input/input.vue +134 -0
  41. package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +136 -0
  42. package/app/pages/widgets/schema-form/complex-view/select/select.vue +116 -0
  43. package/app/pages/widgets/schema-form/form-item-config.js +23 -0
  44. package/app/pages/widgets/schema-form/schema-form.vue +135 -0
  45. package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +50 -0
  46. package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +67 -0
  47. package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +44 -0
  48. package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +51 -0
  49. package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +129 -0
  50. package/app/pages/widgets/schema-search-bar/search-item-config.js +27 -0
  51. package/app/pages/widgets/schema-table/schema-table.vue +235 -0
  52. package/app/pages/widgets/sider-container/sider-container.vue +31 -0
  53. package/app/public/static/logo.png +0 -0
  54. package/app/public/static/normalize.css +239 -0
  55. package/app/router/project.js +6 -0
  56. package/app/router/view.js +8 -0
  57. package/app/router-schema/project.js +30 -0
  58. package/app/service/base.js +11 -0
  59. package/app/service/project.js +56 -0
  60. package/app/view/entry.tpl +26 -0
  61. package/app/webpack/config/webpack.base.js +203 -0
  62. package/app/webpack/config/webpack.dev.js +59 -0
  63. package/app/webpack/config/webpack.prod.js +107 -0
  64. package/app/webpack/dev.js +53 -0
  65. package/app/webpack/libs/blank.js +3 -0
  66. package/app/webpack/prod.js +17 -0
  67. package/config/config.default.js +3 -0
  68. package/docs/dashboard-model.js +153 -0
  69. package/elpis-core/env.js +23 -0
  70. package/elpis-core/index.js +96 -0
  71. package/elpis-core/loader/config.js +50 -0
  72. package/elpis-core/loader/controller.js +54 -0
  73. package/elpis-core/loader/extend.js +49 -0
  74. package/elpis-core/loader/middleware.js +53 -0
  75. package/elpis-core/loader/router-schema.js +41 -0
  76. package/elpis-core/loader/router.js +45 -0
  77. package/elpis-core/loader/service.js +54 -0
  78. package/index.js +40 -0
  79. package/model/index.js +99 -0
  80. package/package.json +92 -0
  81. package/test/controller/project.test.js +225 -0
@@ -0,0 +1,100 @@
1
+ <template>
2
+ <el-drawer
3
+ v-model="isShow"
4
+ direction="rtl"
5
+ :destroy-on-close="true"
6
+ :size="550"
7
+ >
8
+ <template #header>
9
+ <h3>{{ title }}</h3>
10
+ </template>
11
+ <template #default>
12
+ <el-card v-loading="loading" shadow="always" class="detail-panel">
13
+ <el-row
14
+ v-for="(item, key) in components[name]?.schema?.properties"
15
+ :key="key"
16
+ type="flex"
17
+ align="middle"
18
+ class="row-item"
19
+ >
20
+ <el-row class="item-label">{{ item.label }}:</el-row>
21
+ <el-row class="item-value">{{ dtoModel[key] }}</el-row>
22
+ </el-row>
23
+ </el-card>
24
+ </template>
25
+ </el-drawer>
26
+ </template>
27
+
28
+ <script setup>
29
+ import { inject, ref } from 'vue';
30
+ import $curl from '$elpisCommon/curl.js';
31
+
32
+ const { api, components } = inject('schemaViewData');
33
+
34
+ const name = ref('detailPanel');
35
+
36
+ const isShow = ref(false);
37
+ const loading = ref(false);
38
+ const title = ref('');
39
+ const mainKey = ref('');
40
+ const mainValue = ref();
41
+ const dtoModel = ref({});
42
+
43
+ const show = (rowData) => {
44
+ const { config } = components.value[name.value];
45
+
46
+ title.value = config.title;
47
+ mainKey.value = config.mainKey; // 表单主键
48
+ mainValue.value = rowData[config.mainKey]; // 表单主键值
49
+ dtoModel.value = {};
50
+
51
+ isShow.value = true;
52
+
53
+ fetchFormData();
54
+ }
55
+
56
+ const fetchFormData = async() => {
57
+ if(loading.value) { return; }
58
+
59
+ loading.value = true;
60
+ const res = await $curl({
61
+ method: 'get',
62
+ url: api.value,
63
+ query: {
64
+ [mainKey.value]: mainValue.value
65
+ }
66
+ });
67
+ loading.value = false;
68
+
69
+ if(!res || !res.success || !res.data) {
70
+ return;
71
+ }
72
+
73
+ dtoModel.value = res.data;
74
+ }
75
+
76
+ defineExpose({ name, show })
77
+
78
+ </script>
79
+
80
+ <style lang="less" scoped>
81
+ .detail-panel {
82
+ border: 1px solid #a6a6a6;
83
+ padding: 30px;
84
+
85
+ .row-item {
86
+ height: 40px;
87
+ line-height: 40px;
88
+ font-size: 20px;
89
+
90
+ .item-label {
91
+ margin-right: 20px;
92
+ width: 120px;
93
+ color: white;
94
+ }
95
+ .item-value {
96
+ color: #d2dae4;
97
+ }
98
+ }
99
+ }
100
+ </style>
@@ -0,0 +1,118 @@
1
+ <template>
2
+ <el-drawer
3
+ v-model="isShow"
4
+ direction="rtl"
5
+ :destroy-on-close="true"
6
+ :size="550"
7
+ >
8
+ <template #header>
9
+ <h3>{{ title }}</h3>
10
+ </template>
11
+ <template #default>
12
+ <schema-form ref="schemaFormRef" v-loading="loading" :schema="components[name]?.schema" :model="dtoModel"></schema-form>
13
+ </template>
14
+ <template #footer>
15
+ <el-button type="primary" @click="save">{{ saveBtnText }}</el-button>
16
+ </template>
17
+ </el-drawer>
18
+ </template>
19
+
20
+ <script setup>
21
+ import { ref, inject } from 'vue';
22
+ import $curl from '$elpisCommon/curl.js';
23
+ import { ElNotification } from 'element-plus';
24
+ import SchemaForm from '$elpisWidgets/schema-form/schema-form.vue';
25
+
26
+ const { api, components } = inject('schemaViewData');
27
+
28
+ const emit = defineEmits([ 'command' ])
29
+
30
+ const name = ref('editForm');
31
+
32
+ const schemaFormRef = ref(null);
33
+ const isShow = ref(false);
34
+ const loading = ref(false);
35
+ const title = ref('');
36
+ const saveBtnText = ref('');
37
+ const mainKey = ref('');
38
+ const mainValue = ref();
39
+ const dtoModel = ref({});
40
+
41
+ const show = (rowData) => {
42
+ const { config } = components.value[name.value];
43
+
44
+ title.value = config.title;
45
+ saveBtnText.value = config.saveBtnText;
46
+ mainKey.value = config.mainKey; // 表单主键
47
+ mainValue.value = rowData[config.mainKey]; // 表单主键值
48
+ dtoModel.value = {};
49
+
50
+ isShow.value = true;
51
+
52
+ fetchFormData();
53
+ }
54
+
55
+ const fetchFormData = async() => {
56
+ if(loading.value) { return; }
57
+
58
+ loading.value = true;
59
+ const res = await $curl({
60
+ method: 'get',
61
+ url: api.value,
62
+ query: {
63
+ [mainKey.value]: mainValue.value
64
+ }
65
+ });
66
+ loading.value = false;
67
+
68
+ if(!res || !res.success || !res.data) {
69
+ return;
70
+ }
71
+
72
+ dtoModel.value = res.data;
73
+ }
74
+
75
+ const close = () => {
76
+ isShow.value = false;
77
+ }
78
+
79
+ const save = async() => {
80
+ if(loading.value) { return; }
81
+
82
+ if(!schemaFormRef.value.validate()) { return; }
83
+
84
+ loading.value = true;
85
+ const res = await $curl({
86
+ method: 'put',
87
+ url: api.value,
88
+ data: {
89
+ [mainKey.value]: mainValue.value,
90
+ ...schemaFormRef.value.getValue(),
91
+ },
92
+ });
93
+ loading.value = false;
94
+
95
+ if(res?.success) {
96
+ ElNotification.success({
97
+ title: '修改成功',
98
+ message: '修改成功'
99
+ });
100
+ isShow.value = false;
101
+ } else {
102
+ ElNotification.error({
103
+ title: '修改失败',
104
+ message: '修改失败'
105
+ });
106
+ }
107
+
108
+ close();
109
+
110
+ emit('command', {event: 'loadTableData'});
111
+ }
112
+
113
+ defineExpose({ name, show })
114
+ </script>
115
+
116
+ <style lang="less" scoped>
117
+
118
+ </style>
@@ -0,0 +1,124 @@
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 apiParams = ref({});
11
+ const tableSchema = ref({});
12
+ const tableConfig = ref();
13
+ const searchSchema = ref({});
14
+ const searchConfig = ref();
15
+ const components = ref({});
16
+
17
+ // 构造 schemaConfig 相关配置,输送给 schemaView 解释
18
+ const buildData = () => {
19
+ const { key, sider_key: siderKey } = route.query;
20
+
21
+ const mItem = menuStore.findMenuItem({
22
+ key: 'key',
23
+ value: siderKey ?? key
24
+ });
25
+
26
+ if(mItem && mItem.schemaConfig) {
27
+ const { schemaConfig: sConfig } = mItem;
28
+
29
+ const configSchema = JSON.parse(JSON.stringify(sConfig.schema));
30
+
31
+ api.value = sConfig.api ?? '';
32
+
33
+ tableSchema.value = {};
34
+ tableConfig.value = undefined;
35
+ searchSchema.value = {};
36
+ searchConfig.value = undefined;
37
+ components.value = {};
38
+ nextTick(() => {
39
+ // 构造 tableSchema 和 tableConfig
40
+ tableSchema.value = buildDtoSchema(configSchema, 'table');
41
+ tableConfig.value = sConfig.tableConfig;
42
+
43
+ // 构造 searchSchema 和 searchConfig
44
+ const dtoSearchSchema = buildDtoSchema(configSchema, 'search');
45
+ for(const key in dtoSearchSchema.properties) {
46
+ if(route.query[key] !== undefined) {
47
+ dtoSearchSchema.properties[key].option.default = route.query[key];
48
+ }
49
+ }
50
+ searchSchema.value = dtoSearchSchema;
51
+ searchConfig.value = sConfig.searchConfig;
52
+
53
+ // 构造 components = { comKey: { schema: {}, config: {} }}
54
+ const { componentConfig } = sConfig;
55
+ if(componentConfig && Object.keys(componentConfig).length > 0) {
56
+ const dtoComponents = {};
57
+
58
+ for(const comName in componentConfig){
59
+ dtoComponents[comName] = {
60
+ schema: buildDtoSchema(configSchema, comName),
61
+ config: componentConfig[comName]
62
+ }
63
+ }
64
+ components.value = dtoComponents;
65
+ }
66
+ })
67
+ }
68
+ }
69
+
70
+ // 通用构建 schema 方法(清除噪音 => 就是当前组件不需要关心的其他组件配置。)
71
+ const buildDtoSchema = (_schema, comName) => {
72
+ if(!_schema?.properties) { return; }
73
+
74
+ const dtoSchema = {
75
+ type: 'object',
76
+ properties: {}
77
+ }
78
+
79
+ // 提取有效 schema 字段信息
80
+ for(const key in _schema.properties) {
81
+ const props = _schema.properties[key];
82
+ if(props[`${comName}Option`]) {
83
+ let dtoProps = {};
84
+ // 提取 props 中非option的部分,存放到 dtoProps 中
85
+ for(const pKey in props) {
86
+ if(pKey.indexOf('Option') < 0) {
87
+ dtoProps[pKey] = props[pKey];
88
+ }
89
+ }
90
+ // 处理 comName Option(将当前组件的 xxxOption 统一改名为 option,方便组件内部统一读取)
91
+ dtoProps = Object.assign({}, dtoProps, { option: props[`${comName}Option`]});
92
+
93
+ // 处理 required 字段
94
+ const { required } = _schema;
95
+ if(required && required.find(pk => pk === key)) {
96
+ if(dtoProps.option) {
97
+ dtoProps.option.required = true;
98
+ }
99
+ }
100
+
101
+ dtoSchema.properties[key] = dtoProps;
102
+ }
103
+ }
104
+
105
+ return dtoSchema;
106
+ }
107
+
108
+ watch(
109
+ [() => route.query.key, () => route.query.sider_key, () => menuStore.menuList],
110
+ () => {
111
+ buildData();
112
+ },
113
+ {
114
+ immediate: true,
115
+ deep: true
116
+ }
117
+ );
118
+
119
+ // onMounted(() => {
120
+ // buildData();
121
+ // })
122
+
123
+ return { api, apiParams, tableSchema, tableConfig, searchSchema, searchConfig, components };
124
+ }
@@ -0,0 +1,80 @@
1
+ <template>
2
+ <el-row class="schema-view">
3
+ <search-panel
4
+ v-if="searchSchema?.properties && Object.keys(searchSchema.properties).length > 0"
5
+ @search="onSearch"
6
+ ></search-panel>
7
+ <table-panel
8
+ ref="tablePanelRef"
9
+ @operate="onTableOperate"
10
+ ></table-panel>
11
+ <component
12
+ v-for="(item, key) in components"
13
+ :key="key"
14
+ :is="ComponentConfig[key]?.component"
15
+ ref="comListRef"
16
+ @command="onComponentCommand"
17
+ ></component>
18
+ </el-row>
19
+ </template>
20
+
21
+ <script setup>
22
+ import { provide, ref } from 'vue';
23
+ import SearchPanel from './complex-view/search-panel/search-panel.vue';
24
+ import TablePanel from './complex-view/table-panel/table-panel.vue';
25
+ import ComponentConfig from './components/component-config.js';
26
+ import { useSchema } from './hook/schema.js';
27
+
28
+ const { api, apiParams, tableSchema, tableConfig, searchSchema, searchConfig, components } = useSchema();
29
+
30
+ provide('schemaViewData', {
31
+ api, apiParams, tableSchema, tableConfig, searchSchema, searchConfig, components
32
+ });
33
+
34
+ const tablePanelRef = ref(null);
35
+ const comListRef = ref([]);
36
+
37
+ const onSearch = (searchValObj) => {
38
+ apiParams.value = searchValObj;
39
+ }
40
+
41
+ // table 事件映射
42
+ const EventHandlerMap = {
43
+ showComponent: showComponent
44
+ }
45
+
46
+ const onTableOperate = ({ btnConfig, rowData }) => {
47
+ const { eventKey } = btnConfig;
48
+ if(EventHandlerMap[eventKey]) {
49
+ EventHandlerMap[eventKey]({ btnConfig, rowData });
50
+ }
51
+ }
52
+
53
+ // showComponent 展示动态组件
54
+ function showComponent ({ btnConfig, rowData }) {
55
+ const { comName } = btnConfig.eventOption;
56
+ if(!comName) { return; }
57
+
58
+ const comRef = comListRef.value.find(item => item.name === comName);
59
+ if(comRef) {
60
+ comRef.show(rowData);
61
+ }
62
+ }
63
+
64
+ // 响应组件事件
65
+ const onComponentCommand = (data) => {
66
+ const { event } = data;
67
+ if(event === 'loadTableData') {
68
+ tablePanelRef.value.loadTableData();
69
+ }
70
+ }
71
+ </script>
72
+
73
+ <style lang="less" scoped>
74
+ .schema-view {
75
+ display: flex;
76
+ flex-direction: column;
77
+ height: 100%;
78
+ width: 100%;
79
+ }
80
+ </style>
@@ -0,0 +1,21 @@
1
+ <template>
2
+ <el-sub-menu :index="menuItem.key">
3
+ <template #title>{{ menuItem.name }}</template>
4
+ <div v-for="item in menuItem.subMenu" :key="item.key">
5
+ <sub-menu
6
+ v-if="item.subMenu && item.subMenu.length > 0"
7
+ :menu-item="item"
8
+ >
9
+ </sub-menu>
10
+ <el-menu-item v-else :index="item.key">{{ item.name }}</el-menu-item>
11
+ </div>
12
+ </el-sub-menu>
13
+ </template>
14
+
15
+ <script setup>
16
+ const { menuItem } = defineProps([ 'menuItem' ]);
17
+ </script>
18
+
19
+ <style lang="less" scoped>
20
+
21
+ </style>
@@ -0,0 +1,135 @@
1
+ <template>
2
+ <sider-container>
3
+ <template #menu-content>
4
+ <el-menu
5
+ :key="activeKey"
6
+ :default-active="activeKey"
7
+ :ellipsis="false"
8
+ @select="onMenuSelect"
9
+ >
10
+ <template v-for="item in menuList" :key="item.key">
11
+ <!-- group -->
12
+ <sub-menu
13
+ v-if="item.subMenu && item.subMenu.length > 0"
14
+ :menu-item="item"
15
+ >
16
+ </sub-menu>
17
+ <!-- module -->
18
+ <el-menu-item v-else :index="item.key">{{ item.name }}</el-menu-item>
19
+ </template>
20
+ </el-menu>
21
+ </template>
22
+ <template #main-content>
23
+ <router-view></router-view>
24
+ </template>
25
+ </sider-container>
26
+ </template>
27
+
28
+ <script setup>
29
+ import { ref, onMounted, watch } from 'vue';
30
+ import { useRouter, useRoute } from 'vue-router';
31
+ import { useMenuStore } from '$elpisStore/menu.js';
32
+ import SiderContainer from '$elpisWidgets/sider-container/sider-container.vue';
33
+ import SubMenu from './complex-view/sub-menu/sub-menu.vue';
34
+
35
+ const router = useRouter();
36
+ const route = useRoute();
37
+ const menuStore = useMenuStore();
38
+
39
+ const menuList = ref([]);
40
+ const setMenuList = () => {
41
+ const menuItem = menuStore.findMenuItem({
42
+ key: 'key',
43
+ value: route.query.key
44
+ });
45
+ if(menuItem && menuItem.siderConfig && menuItem.siderConfig.menu) {
46
+ menuList.value = menuItem.siderConfig.menu;
47
+ }
48
+ }
49
+
50
+ const activeKey = ref('');
51
+ const setActiveKey = () => {
52
+ let siderMenuItem = menuStore.findMenuItem({
53
+ key: 'key',
54
+ value: route.query.sider_key
55
+ });
56
+
57
+ // 如果首次加载 sider-view,用户未选中左侧菜单,需要默认选中第一个
58
+ if(!siderMenuItem){
59
+ const hMenuItem = menuStore.findMenuItem({
60
+ key: 'key',
61
+ value: route.query.key
62
+ });
63
+ if(hMenuItem && hMenuItem.siderConfig && hMenuItem.siderConfig.menu) {
64
+ const siderMenuList = hMenuItem.siderConfig.menu;
65
+ siderMenuItem = menuStore.findFirstMenuItem(siderMenuList); // 找出左侧菜单中的第一项
66
+ if(siderMenuItem) {
67
+ // TODO: 处理选中菜单逻辑
68
+ handleMenuSelect(siderMenuItem.key);
69
+ }
70
+ }
71
+ }
72
+ activeKey.value = siderMenuItem?.key;
73
+ }
74
+
75
+ // watch(() => route.query.key, () => {
76
+ // setMenuList();
77
+ // setActiveKey();
78
+ // })
79
+ // watch(() => menuStore.menuList, () => {
80
+ // setMenuList();
81
+ // setActiveKey();
82
+ // },{ deep: true }
83
+ // )
84
+ // onMounted(() => {
85
+ // setMenuList();
86
+ // setActiveKey();
87
+ // })
88
+
89
+ const onMenuSelect = (menuKey) => {
90
+ handleMenuSelect(menuKey);
91
+ }
92
+
93
+ const handleMenuSelect = (menuKey) => {
94
+ const menuItem = menuStore.findMenuItem({
95
+ key: 'key',
96
+ value: menuKey
97
+ });
98
+
99
+ const { moduleType, key, customConfig } = menuItem;
100
+
101
+ // 如果是当前页面,不处理
102
+ if(key == route.query.sider_key) { return; }
103
+
104
+ const pathMap = {
105
+ iframe: '/iframe',
106
+ schema: '/schema',
107
+ custom: customConfig?.path,
108
+ }
109
+
110
+ router.push({
111
+ path: `/sider${pathMap[moduleType]}`,
112
+ query: {
113
+ key: route.query.key,
114
+ sider_key: menuKey,
115
+ proj_key: route.query.proj_key
116
+ }
117
+ })
118
+ }
119
+
120
+ watch(
121
+ [() => route.query.key, () => menuStore.menuList],
122
+ () => {
123
+ setMenuList();
124
+ setActiveKey();
125
+ },
126
+ {
127
+ immediate: true,
128
+ deep: true
129
+ }
130
+ );
131
+ </script>
132
+
133
+ <style lang="less" scoped>
134
+
135
+ </style>
@@ -0,0 +1,96 @@
1
+ <template>
2
+ <el-config-provider :locale="zhCn">
3
+ <header-view :proj-name="projName" @menu-select="onMenuSelect">
4
+ <template #main-content>
5
+ <router-view></router-view>
6
+ </template>
7
+ </header-view>
8
+ </el-config-provider>
9
+ </template>
10
+
11
+ <script setup>
12
+ import { ref, onMounted } from 'vue';
13
+ import { useRouter, useRoute } from 'vue-router';
14
+ import $curl from '$elpisCommon/curl.js'
15
+ import zhCn from 'element-plus/es/locale/lang/zh-cn'
16
+ import HeaderView from './complex-view/header-view/header-view.vue';
17
+ import { useMenuStore } from '$elpisStore/menu.js';
18
+ import { useProjectStore } from '$elpisStore/project.js';
19
+
20
+ const router = useRouter();
21
+ const route = useRoute();
22
+ const menuStore = useMenuStore();
23
+ const projectStore = useProjectStore();
24
+ const projName = ref('');
25
+
26
+ onMounted(() => {
27
+ getProjectList();
28
+ getProjectConfig();
29
+ })
30
+
31
+ // 请求 /api/project/list 接口,并缓存到 project-store 中
32
+ async function getProjectList() {
33
+ const res = await $curl({
34
+ method: 'get',
35
+ url: '/api/project/list',
36
+ query: {
37
+ proj_key: route.query.proj_key,
38
+ }
39
+ });
40
+
41
+ if(!res || !res.success || !res.data) {
42
+ return;
43
+ }
44
+
45
+ projectStore.setProjectList(res.data);
46
+ }
47
+
48
+ // 请求 /api/project 接口,并缓存到 menu-store 中
49
+ async function getProjectConfig() {
50
+ const res = await $curl({
51
+ method: 'get',
52
+ url: '/api/project',
53
+ query: {
54
+ proj_key: route.query.proj_key,
55
+ }
56
+ });
57
+
58
+ if(!res || !res.success || !res.data) {
59
+ return;
60
+ }
61
+
62
+ const { name, menu } = res.data;
63
+
64
+ projName.value = name;
65
+
66
+ menuStore.setMenuList(menu);
67
+ }
68
+
69
+ const onMenuSelect = (menuItem) => {
70
+ const { moduleType, key, customConfig } = menuItem;
71
+
72
+ // 如果是当前页面,不处理
73
+ if(key == route.query.key) { return; }
74
+
75
+ const pathMap = {
76
+ sider: '/sider',
77
+ iframe: '/iframe',
78
+ schema: '/schema',
79
+ custom: customConfig?.path,
80
+ }
81
+
82
+ router.push({
83
+ path: pathMap[moduleType],
84
+ query: {
85
+ key,
86
+ proj_key: route.query.proj_key
87
+ }
88
+ })
89
+ }
90
+ </script>
91
+
92
+ <style lang="less" scoped>
93
+ :deep(.el-main) {
94
+ padding: 0;
95
+ }
96
+ </style>