@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
@@ -0,0 +1,23 @@
1
+ import createForm from './create-form/create-form.vue';
2
+ import editForm from './edit-form/edit-form.vue';
3
+ import detailPanel from './detail-panel/detail-panel.vue';
4
+
5
+ // 业务扩展 component 配置
6
+ import BusinessComponentConfig from '$businessComponentConfig';
7
+
8
+ const ComponentConfig = {
9
+ createForm: {
10
+ component: createForm,
11
+ },
12
+ editForm: {
13
+ component: editForm,
14
+ },
15
+ detailPanel: {
16
+ component: detailPanel,
17
+ },
18
+ };
19
+
20
+ export default {
21
+ ...BusinessComponentConfig,
22
+ ...ComponentConfig,
23
+ };
@@ -0,0 +1,86 @@
1
+ <template>
2
+ <el-drawer v-model="isShow" direction="rtl" :destroy-on-close="true" :size="550">
3
+ <template #header>
4
+ <h3>{{ title }}</h3>
5
+ </template>
6
+ <template #default>
7
+ <schema-form ref="schemaFormRef" v-loading="loading" :schema="components[name]?.schema" />
8
+ </template>
9
+ <template #footer>
10
+ <el-button type="primary" @click="save">{{ saveBtnText }}</el-button>
11
+ </template>
12
+ </el-drawer>
13
+ </template>
14
+
15
+ <script setup>
16
+ import SchemaForm from '$elpisWidgets/schema-form/schema-form.vue';
17
+
18
+ import { ref, inject } from 'vue';
19
+ import { ElNotification } from 'element-plus';
20
+ import { tableDataPort } from '$elpisCommon/api/business-api';
21
+
22
+ const { api, components } = inject('schemaViewData');
23
+
24
+ const emits = defineEmits(['command']);
25
+
26
+ // name 提供给外面匹配
27
+ const name = ref('createForm');
28
+
29
+ const schemaFormRef = ref(null);
30
+ const loading = ref(false);
31
+ const isShow = ref(false);
32
+ const title = ref('');
33
+ const saveBtnText = ref('');
34
+ const show = function () {
35
+ const { config } = components.value[name.value];
36
+
37
+ title.value = config.title;
38
+ saveBtnText.value = config.saveBtnText;
39
+
40
+ isShow.value = true;
41
+ };
42
+
43
+ const close = () => {
44
+ isShow.value = false;
45
+ };
46
+
47
+ const save = async () => {
48
+ if (loading.value) return;
49
+
50
+ if (!schemaFormRef.value.validate()) return;
51
+
52
+ loading.value = true;
53
+
54
+ try {
55
+ const res = await tableDataPort({
56
+ method: 'post',
57
+ url: api.value,
58
+ data: {
59
+ ...schemaFormRef.value.getValue(),
60
+ },
61
+ });
62
+
63
+ if (!res || !res.success) return;
64
+
65
+ ElNotification({
66
+ title: '创建成功',
67
+ message: '创建成功',
68
+ type: 'success',
69
+ });
70
+
71
+ close();
72
+ emits('command', {
73
+ event: 'loadTableData',
74
+ });
75
+ } finally {
76
+ loading.value = false;
77
+ }
78
+ };
79
+
80
+ defineExpose({
81
+ name,
82
+ show,
83
+ });
84
+ </script>
85
+
86
+ <style lang="less" scoped></style>
@@ -0,0 +1,82 @@
1
+ <template>
2
+ <el-drawer v-model="isShow" direction="rtl" :destroy-on-close="true" :size="550">
3
+ <template #header>
4
+ <h3>{{ title }}</h3>
5
+ </template>
6
+ <template #default>
7
+ <schema-form
8
+ ref="schemaFormRef"
9
+ v-loading="loading"
10
+ :schema="components[name]?.schema"
11
+ :model="dtoModel"
12
+ />
13
+ </template>
14
+ <template #footer>
15
+ <el-button type="primary" @click="save">{{ saveBtnText }}</el-button>
16
+ </template>
17
+ </el-drawer>
18
+ </template>
19
+ <script setup>
20
+ import SchemaForm from '$elpisWidgets/schema-form/schema-form.vue';
21
+
22
+ import { ref, inject } from 'vue';
23
+ import { tableDataPort } from '$elpisCommon/api/business-api';
24
+
25
+ const { api, components } = inject('schemaViewData');
26
+
27
+ const schemaFormRef = ref(null);
28
+ const name = ref('detailPanel');
29
+ const loading = ref(false);
30
+ const isShow = ref(false);
31
+ const title = ref('');
32
+ const saveBtnText = ref('');
33
+ const mainKey = ref('');
34
+ const mainValue = ref(undefined);
35
+ const dtoModel = ref({});
36
+
37
+ const show = (rowData) => {
38
+ const { config } = components.value[name.value];
39
+ title.value = config.title;
40
+ saveBtnText.value = config.saveBtnText;
41
+ mainKey.value = config.mainKey; // 表单主键
42
+ mainValue.value = rowData[config.mainKey]; // 表单主键值
43
+
44
+ isShow.value = true;
45
+
46
+ ferchFormData();
47
+ };
48
+
49
+ const close = () => {
50
+ isShow.value = false;
51
+ };
52
+
53
+ const ferchFormData = async () => {
54
+ if (loading.value) return;
55
+
56
+ loading.value = true;
57
+ try {
58
+ const res = await tableDataPort({
59
+ method: 'get',
60
+ url: api.value,
61
+ params: {
62
+ [mainKey.value]: mainValue.value,
63
+ },
64
+ });
65
+
66
+ if (!res || !res.data || !res.success) return;
67
+ dtoModel.value = res.data;
68
+ } finally {
69
+ loading.value = false;
70
+ }
71
+ };
72
+
73
+ const save = () => {
74
+ close();
75
+ };
76
+
77
+ defineExpose({
78
+ name,
79
+ show,
80
+ });
81
+ </script>
82
+ <style lang="less" scoped></style>
@@ -0,0 +1,115 @@
1
+ <template>
2
+ <el-drawer v-model="isShow" direction="rtl" :destroy-on-close="true" :size="550">
3
+ <template #header>
4
+ <h3>{{ title }}</h3>
5
+ </template>
6
+ <template #default>
7
+ <schema-form
8
+ ref="schemaFormRef"
9
+ v-loading="loading"
10
+ :schema="components[name]?.schema"
11
+ :model="dtoModel"
12
+ />
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 SchemaForm from '$elpisWidgets/schema-form/schema-form.vue';
22
+
23
+ import { ref, inject } from 'vue';
24
+ import { ElNotification } from 'element-plus';
25
+ import { tableDataPort } from '$elpisCommon/api/business-api';
26
+
27
+ const { api, components } = inject('schemaViewData');
28
+
29
+ const emits = defineEmits(['command']);
30
+ const schemaFormRef = ref(null);
31
+ const name = ref('editForm');
32
+ const loading = ref(false);
33
+ const isShow = ref(false);
34
+ const title = ref('');
35
+ const saveBtnText = ref('');
36
+ const mainKey = ref('');
37
+ const mainValue = ref(undefined);
38
+ const dtoModel = ref({});
39
+
40
+ const show = (rowData) => {
41
+ const { config } = components.value[name.value];
42
+ title.value = config.title;
43
+ saveBtnText.value = config.saveBtnText;
44
+ mainKey.value = config.mainKey; // 表单主键
45
+ mainValue.value = rowData[config.mainKey]; // 表单主键值
46
+
47
+ isShow.value = true;
48
+
49
+ ferchFormData();
50
+ };
51
+
52
+ const close = () => {
53
+ isShow.value = false;
54
+ };
55
+
56
+ const ferchFormData = async () => {
57
+ if (loading.value) return;
58
+
59
+ loading.value = true;
60
+ try {
61
+ const res = await tableDataPort({
62
+ method: 'get',
63
+ url: api.value,
64
+ params: {
65
+ [mainKey.value]: mainValue.value,
66
+ },
67
+ });
68
+
69
+ if (!res || !res.data || !res.success) return;
70
+ dtoModel.value = res.data;
71
+ } finally {
72
+ loading.value = false;
73
+ }
74
+ };
75
+
76
+ const save = async () => {
77
+ if (loading.value) return;
78
+
79
+ if (!schemaFormRef.value.validate()) return;
80
+
81
+ loading.value = true;
82
+ try {
83
+ const res = await tableDataPort({
84
+ method: 'put',
85
+ url: api.value,
86
+ data: {
87
+ [mainKey.value]: mainValue.value,
88
+ ...schemaFormRef.value.getValue(),
89
+ },
90
+ });
91
+
92
+ if (!res || !res.success) return;
93
+
94
+ ElNotification({
95
+ title: '修改成功',
96
+ message: '修改成功',
97
+ type: 'success',
98
+ });
99
+
100
+ close(); // 关闭弹窗
101
+ emits('command', {
102
+ event: 'loadTableData',
103
+ }); // 发送事件,请求表格
104
+ } finally {
105
+ loading.value = false;
106
+ }
107
+ };
108
+
109
+ defineExpose({
110
+ name,
111
+ show,
112
+ });
113
+ </script>
114
+
115
+ <style lang="less" scoped></style>
@@ -0,0 +1,135 @@
1
+ import { ref, watch, onMounted, nextTick } from 'vue';
2
+ import { useRoute } from 'vue-router';
3
+ import { useMenuStore } from '$elpisStore/menu';
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(undefined);
12
+ const searchSchema = ref({});
13
+ const searchConfig = ref(undefined);
14
+ const components = ref({});
15
+
16
+ // 构造 schemaConfig 相关配置,输送给 schemaView 解析。
17
+ const buildData = function () {
18
+ const { key, sider_key: siderKey } = route.query;
19
+
20
+ const menuItem = menuStore.findMenuItem({
21
+ key: 'key',
22
+ value: siderKey ?? key,
23
+ });
24
+
25
+ if (menuItem && menuItem.schemaConfig) {
26
+ const { schemaConfig } = menuItem;
27
+ const sConfig = schemaConfig?.schema;
28
+ const configScheam = JSON.parse(JSON.stringify(sConfig));
29
+ api.value = schemaConfig.api ?? '';
30
+
31
+ tableSchema.value = {};
32
+ tableConfig.value = undefined;
33
+
34
+ searchSchema.value = {};
35
+ searchConfig.value = undefined;
36
+
37
+ components.value = {};
38
+
39
+ nextTick(() => {
40
+ // 构造 tableSchema 和 tableConfig
41
+ tableSchema.value = buildDtoSchema(configScheam, 'table');
42
+ tableConfig.value = sConfig?.tableConfig ?? {};
43
+
44
+ // 构造 searchSchema 和 searchConfig
45
+ const dtoSchearSchema = buildDtoSchema(configScheam, 'search');
46
+ // 给默认参数 defalut 填充上路由参数值
47
+ for (const key in dtoSchearSchema?.properties ?? {}) {
48
+ if (route.query[key] !== undefined) {
49
+ dtoSchearSchema.properties[key].option.default = route.query[key];
50
+ }
51
+ }
52
+ searchSchema.value = dtoSchearSchema;
53
+ searchConfig.value = sConfig?.searchConfig ?? {};
54
+
55
+ // 构造 components = { key: { schema: {}, config: {} } }
56
+ const { componentConfig } = sConfig;
57
+
58
+ if (componentConfig && Object.keys(componentConfig).length > 0) {
59
+ const dtoComponents = {};
60
+
61
+ for (const comName in componentConfig) {
62
+ dtoComponents[comName] = {
63
+ schema: buildDtoSchema(configScheam, comName),
64
+ config: componentConfig[comName],
65
+ };
66
+ }
67
+
68
+ components.value = dtoComponents;
69
+ }
70
+ });
71
+ }
72
+ };
73
+
74
+ // 通用构建方法
75
+ const buildDtoSchema = function (_schema, comName) {
76
+ if (!_schema?.properties) return {};
77
+
78
+ const dtoSchema = {
79
+ type: 'object',
80
+ properties: {},
81
+ };
82
+
83
+ // 提取有效 schema 字段信息
84
+ for (const key in _schema.properties) {
85
+ const props = _schema.properties[key];
86
+ // tableOption schearBarOption form Option
87
+ if (props[`${comName}Option`]) {
88
+ let dtoProps = {};
89
+ for (const pKey in props) {
90
+ // 提取 props 非 option 的部分,存放到 dtoProps 中
91
+ if (pKey.indexOf('Option') < 0) {
92
+ dtoProps[pKey] = props[pKey];
93
+ }
94
+ }
95
+ // 处理 comName Option
96
+ dtoProps = Object.assign({}, dtoProps, {
97
+ option: props[`${comName}Option`],
98
+ });
99
+
100
+ // 处理 required 字段
101
+ const { required } = _schema;
102
+
103
+ if (required && required.find((pk) => pk === key)) {
104
+ dtoProps.option.required = true;
105
+ }
106
+
107
+ dtoSchema.properties[key] = dtoProps;
108
+ }
109
+ }
110
+
111
+ return dtoSchema;
112
+ };
113
+
114
+ // 用户切换菜单时,重新构建 schemaConfig 相关配置。
115
+ watch(
116
+ [() => route.query.key, () => route.query.sider_key, () => menuStore.menuList],
117
+ () => {
118
+ buildData();
119
+ },
120
+ { deep: true }
121
+ );
122
+
123
+ onMounted(() => {
124
+ buildData();
125
+ });
126
+
127
+ return {
128
+ api,
129
+ tableSchema,
130
+ tableConfig,
131
+ searchSchema,
132
+ searchConfig,
133
+ components,
134
+ };
135
+ };
@@ -0,0 +1,93 @@
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
+ />
7
+ <table-panel ref="tablePanelRef" @operate="onTableOperate" />
8
+ <component
9
+ :is="ComponentConfig[key]?.component"
10
+ v-for="(item, key) in components"
11
+ :key="key"
12
+ ref="comListRef"
13
+ @command="onComponentCommand"
14
+ />
15
+ </el-row>
16
+ </template>
17
+
18
+ <script setup>
19
+ import SearchPanel from './complex-view/search-panel/search-panel.vue';
20
+ import TablePanel from './complex-view/table-panel/table-panel.vue';
21
+
22
+ import { provide, ref } from 'vue';
23
+ import { useSchema } from './hook/schema';
24
+ import ComponentConfig from './components/component-config';
25
+
26
+ const { api, tableSchema, tableConfig, searchSchema, searchConfig, components } = useSchema();
27
+ const apiParams = ref({});
28
+
29
+ provide('schemaViewData', {
30
+ api,
31
+ apiParams,
32
+ tableSchema,
33
+ tableConfig,
34
+ searchSchema,
35
+ searchConfig,
36
+ components,
37
+ });
38
+
39
+ const tablePanelRef = ref(null);
40
+ const comListRef = ref([]);
41
+
42
+ const onSearch = (searchValObj) => {
43
+ apiParams.value = searchValObj;
44
+ };
45
+
46
+ // table 事件映射
47
+ const EventHandleMap = {
48
+ showComponent: showComponent,
49
+ };
50
+ function onTableOperate({ btnConfig, rowData }) {
51
+ const { eventKey } = btnConfig;
52
+
53
+ if (EventHandleMap[eventKey]) {
54
+ EventHandleMap[eventKey]({ btnConfig, rowData });
55
+ }
56
+ }
57
+
58
+ // showComponent 展示动态组件
59
+ function showComponent({ btnConfig, rowData }) {
60
+ const { comName } = btnConfig?.eventOption;
61
+
62
+ if (!comName) {
63
+ console.error('没有配置组件');
64
+ return;
65
+ }
66
+
67
+ const comRef = comListRef.value.find((item) => item.name === comName);
68
+ // name & show 是组件内部 defineExpose 暴露出来的
69
+ if (!comRef || typeof comRef.show !== 'function') {
70
+ console.error(`找不: ${comName} 组件`);
71
+ return;
72
+ }
73
+
74
+ comRef.show(rowData);
75
+ }
76
+
77
+ // 响应组件事件
78
+ function onComponentCommand(data) {
79
+ const { event } = data;
80
+ if (event === 'loadTableData') {
81
+ tablePanelRef.value.loadTableData();
82
+ }
83
+ }
84
+ </script>
85
+
86
+ <style lang="less" scoped>
87
+ .schema-view {
88
+ display: flex;
89
+ flex-direction: column;
90
+ width: 100%;
91
+ height: 100%;
92
+ }
93
+ </style>
@@ -0,0 +1,21 @@
1
+ <template>
2
+ <el-sub-menu :index="menuItem.key">
3
+ <template #title>
4
+ {{ menuItem.name }}
5
+ </template>
6
+ <div v-for="item in menuItem.subMenu" :key="item.key">
7
+ <!-- 存在 subMenu 递归调用自己-->
8
+ <sub-menu v-if="item.subMenu && item.subMenu.length > 0" :menu-item="item" />
9
+ <!-- 否则使用el-menu-item -->
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
+ defineProps({
17
+ menuItem: Object,
18
+ });
19
+ </script>
20
+
21
+ <style lang="less" scoped></style>
@@ -0,0 +1,115 @@
1
+ <template>
2
+ <sider-container>
3
+ <template #menu-content>
4
+ <el-menu :default-active="activeKey" :ellipsis="false" @select="onMenuSelect">
5
+ <template v-for="item in menuList">
6
+ <!-- group 的情况 -->
7
+ <sub-menu v-if="item.subMenu && item.subMenu.length > 0" :menu-item="item" />
8
+ <!-- module 的情况 -->
9
+ <el-menu-item v-else :index="item.key">{{ item.name }}</el-menu-item>
10
+ </template>
11
+ </el-menu>
12
+ </template>
13
+ <template #main-content>
14
+ <router-view />
15
+ </template>
16
+ </sider-container>
17
+ </template>
18
+
19
+ <script setup>
20
+ import siderContainer from '$elpisPages/widgets/sider-container/sider-container.vue';
21
+ import SubMenu from './complex-view/sub-menu/sub-menu.vue';
22
+
23
+ import { ref, watch, onMounted } from 'vue';
24
+ import { useRoute, useRouter } from 'vue-router';
25
+ import { useMenuStore } from '$elpisStore/menu';
26
+
27
+ const router = useRouter();
28
+ const route = useRoute();
29
+ const menuStore = useMenuStore();
30
+
31
+ const menuList = ref([]);
32
+ const setMenuList = function () {
33
+ const menuItem = menuStore.findMenuItem({
34
+ key: 'key',
35
+ value: route.query.key,
36
+ });
37
+ if (menuItem && menuItem.siderConfig && menuItem.siderConfig.menu) {
38
+ menuList.value = menuItem.siderConfig.menu;
39
+ }
40
+ };
41
+
42
+ const activeKey = ref('');
43
+ const setActiveKey = function () {
44
+ let siderMenuItem = menuStore.findMenuItem({
45
+ key: 'key',
46
+ value: route.query.sider_key,
47
+ });
48
+
49
+ // 如果首次加载 sider-view
50
+ if (!siderMenuItem) {
51
+ const hMenuItem = menuStore.findMenuItem({
52
+ key: 'key',
53
+ value: route.query.key,
54
+ });
55
+
56
+ if (hMenuItem && hMenuItem.siderConfig && hMenuItem.siderConfig.menu) {
57
+ const siderMenuList = hMenuItem.siderConfig.menu;
58
+ siderMenuItem = menuStore.findFirstMenuItem(siderMenuList); // 找出左侧菜单中的第一个
59
+
60
+ if (siderMenuItem) {
61
+ handleMenuSelect(siderMenuItem.key);
62
+ }
63
+ }
64
+ }
65
+
66
+ activeKey.value = siderMenuItem?.key;
67
+ };
68
+
69
+ watch(
70
+ [() => route.query.key, () => menuStore.menuList],
71
+ () => {
72
+ setMenuList();
73
+ setActiveKey();
74
+ },
75
+ { deep: true }
76
+ );
77
+
78
+ onMounted(() => {
79
+ setMenuList();
80
+ setActiveKey();
81
+ });
82
+
83
+ const onMenuSelect = function (menuKey) {
84
+ handleMenuSelect(menuKey);
85
+ };
86
+
87
+ const handleMenuSelect = function (menuKey) {
88
+ const menuItem = menuStore.findMenuItem({
89
+ key: 'key',
90
+ value: menuKey,
91
+ });
92
+
93
+ const { moduleType, key, customConfig } = menuItem;
94
+
95
+ // 如果是当前页面,不处理
96
+ if (key === route.query.sider_key) return;
97
+
98
+ const pathMap = {
99
+ iframe: '/iframe',
100
+ schema: '/schema',
101
+ custom: customConfig?.path,
102
+ };
103
+
104
+ router.push({
105
+ path: `/view/dashboard/sider${pathMap[moduleType]}`,
106
+ query: {
107
+ key: route.query.key,
108
+ sider_key: key,
109
+ proj_key: route.query.proj_key,
110
+ },
111
+ });
112
+ };
113
+ </script>
114
+
115
+ <style lang="less" scoped></style>