@pixel-shell/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 (80) hide show
  1. package/.eslintgnore +1 -0
  2. package/.eslintrc +55 -0
  3. package/README.md +194 -0
  4. package/app/controller/base.js +40 -0
  5. package/app/controller/project.js +56 -0
  6. package/app/controller/view.js +18 -0
  7. package/app/extend/logger.js +37 -0
  8. package/app/middleware/api-params-verify.js +71 -0
  9. package/app/middleware/api-sign-verify.js +32 -0
  10. package/app/middleware/error-handler.js +33 -0
  11. package/app/middleware/project-handler.js +27 -0
  12. package/app/middleware.js +31 -0
  13. package/app/pages/asserts/custom.css +12 -0
  14. package/app/pages/boot.js +47 -0
  15. package/app/pages/common/curl.js +88 -0
  16. package/app/pages/common/utils.js +2 -0
  17. package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +17 -0
  18. package/app/pages/dashboard/complex-view/header-view/header-view.vue +129 -0
  19. package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +43 -0
  20. package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +37 -0
  21. package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +114 -0
  22. package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +22 -0
  23. package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +85 -0
  24. package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +92 -0
  25. package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +106 -0
  26. package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +123 -0
  27. package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +88 -0
  28. package/app/pages/dashboard/complex-view/sider-view/complex-view/sub-menu/sub-menu.vue +18 -0
  29. package/app/pages/dashboard/complex-view/sider-view/sider-view.vue +117 -0
  30. package/app/pages/dashboard/dashboard.vue +89 -0
  31. package/app/pages/dashboard/entry.dashboard.js +42 -0
  32. package/app/pages/store/index.js +5 -0
  33. package/app/pages/store/menu.js +57 -0
  34. package/app/pages/store/project.js +15 -0
  35. package/app/pages/widgets/header-container/asserts/avatar.png +0 -0
  36. package/app/pages/widgets/header-container/asserts/logo.png +0 -0
  37. package/app/pages/widgets/header-container/header-container.vue +102 -0
  38. package/app/pages/widgets/schema-form/complex-view/input/input.vue +129 -0
  39. package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +130 -0
  40. package/app/pages/widgets/schema-form/complex-view/select/select.vue +116 -0
  41. package/app/pages/widgets/schema-form/form-item-config.js +23 -0
  42. package/app/pages/widgets/schema-form/schema-form.vue +121 -0
  43. package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +41 -0
  44. package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +51 -0
  45. package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +34 -0
  46. package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +36 -0
  47. package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +121 -0
  48. package/app/pages/widgets/schema-search-bar/search-item-config.js +27 -0
  49. package/app/pages/widgets/schema-table/schema-table.vue +227 -0
  50. package/app/pages/widgets/sider-container/sider-container.vue +29 -0
  51. package/app/public/static/logo.png +0 -0
  52. package/app/public/static/normalize.css +241 -0
  53. package/app/router/project.js +6 -0
  54. package/app/router/view.js +8 -0
  55. package/app/router-schema/project.js +30 -0
  56. package/app/service/base.js +10 -0
  57. package/app/service/project.js +40 -0
  58. package/app/view/entry.tpl +25 -0
  59. package/app/webpack/build.js +18 -0
  60. package/app/webpack/config/webpack.base.js +234 -0
  61. package/app/webpack/config/webpack.dev.js +58 -0
  62. package/app/webpack/config/webpack.prod.js +113 -0
  63. package/app/webpack/dev.js +60 -0
  64. package/app/webpack/libs/blank.js +1 -0
  65. package/app/webpack/prod.js +22 -0
  66. package/config/config.default.js +3 -0
  67. package/docs/dashboard-mode.js +141 -0
  68. package/elpis-core/env.js +16 -0
  69. package/elpis-core/index.js +70 -0
  70. package/elpis-core/loader/config.js +51 -0
  71. package/elpis-core/loader/controller.js +71 -0
  72. package/elpis-core/loader/extend.js +61 -0
  73. package/elpis-core/loader/middleware.js +69 -0
  74. package/elpis-core/loader/roter-schema.js +54 -0
  75. package/elpis-core/loader/router.js +42 -0
  76. package/elpis-core/loader/service.js +70 -0
  77. package/index.js +35 -0
  78. package/model/index.js +86 -0
  79. package/package.json +92 -0
  80. package/test/controller/project.test.js +194 -0
@@ -0,0 +1,106 @@
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
13
+ ref="schemaFormRef"
14
+ v-loading="loading"
15
+ :schema="components[name]?.schema"
16
+ :model="dtoModel"
17
+ ></schema-form>
18
+ </template>
19
+ <template #footer>
20
+ <el-button type="primary" @click="save">{{ saveBtnText }}</el-button>
21
+ </template>
22
+ </el-drawer>
23
+ </template>
24
+
25
+ <script setup>
26
+ import { ref, inject } from "vue";
27
+ import { ElNotification } from "element-plus";
28
+ import $curl from "$elpisCommon/curl";
29
+ import SchemaForm from "$elpisWidgets/schema-form/schema-form.vue";
30
+
31
+ const { api, components } = inject("schemaViewData");
32
+
33
+ const emit = defineEmits(["command"]);
34
+
35
+ const name = ref("editForm");
36
+ const schemaFormRef = ref(null);
37
+ const loading = ref(false);
38
+ const isShow = ref(false);
39
+ const title = ref("");
40
+ const saveBtnText = ref("");
41
+ const mainKey = ref("");
42
+ const mainValue = ref();
43
+ const dtoModel = ref({});
44
+
45
+ const show = (rowData) => {
46
+ const { config } = components.value[name.value];
47
+ title.value = config.title;
48
+ saveBtnText.value = config.saveBtnText;
49
+ mainKey.value = config.mainKey; // 表单主键
50
+ mainValue.value = rowData[config.mainKey]; // 表单主键值
51
+ dtoModel.value = {};
52
+ isShow.value = true;
53
+
54
+ fetchFormData();
55
+ };
56
+
57
+ const close = () => {
58
+ isShow.value = false;
59
+ }
60
+
61
+ const fetchFormData = async () => {
62
+ if (loading.value) return;
63
+ loading.value = true;
64
+ const res = await $curl({
65
+ method: "GET",
66
+ url: api.value,
67
+ query: {
68
+ [mainKey.value]: mainValue.value,
69
+ },
70
+ });
71
+ loading.value = false;
72
+ if (!res || !res.success || !res.data) return;
73
+ dtoModel.value = res.data;
74
+ };
75
+
76
+ const save = async () => {
77
+ if(loading.value) return;
78
+ if(!schemaFormRef.value.validate()) return;
79
+ loading.value = true;
80
+ const res = await $curl({
81
+ method: "PUT",
82
+ url: api.value,
83
+ data: {
84
+ [mainKey.value]: mainValue.value,
85
+ ...schemaFormRef.value.getValue(),
86
+ }
87
+ })
88
+ loading.value = false;
89
+ if(!res || !res.success) return;
90
+ ElNotification.success({
91
+ title: "修改成功",
92
+ message: "修改成功",
93
+ type: "success",
94
+ });
95
+ close();
96
+ emit("command", {
97
+ event: "loadTableData"
98
+ });
99
+ };
100
+ defineExpose({
101
+ name,
102
+ show,
103
+ });
104
+ </script>
105
+
106
+ <style lang="less" scoped></style>
@@ -0,0 +1,123 @@
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 = () => {
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
+ const components = ref({});
15
+ // 构造 schemaConfig 相关配置, 输送给 schemaView 解析
16
+ const buildData = () => {
17
+ const { key, sider_key: siderKey } = route.query;
18
+
19
+ const mItem = menuStore.findMenuItem({
20
+ key: "key",
21
+ value: siderKey ?? key,
22
+ });
23
+ if (mItem && mItem.schemaConfig) {
24
+ const { schemaConfig: sConfig } = mItem;
25
+ const configSchema = JSON.parse(JSON.stringify(sConfig.schema));
26
+ api.value = sConfig.api ?? "";
27
+ tableSchema.value = {};
28
+ tableConfig.value = undefined;
29
+ searchSchema.value = {};
30
+ searchConfig.value = undefined;
31
+ components.value = {};
32
+ nextTick(() => {
33
+ // 构造tableSchema 和 tableConfig
34
+ tableSchema.value = buildDtoSchema(configSchema, "table");
35
+ tableConfig.value = sConfig.tableConfig;
36
+
37
+ // 构造searchSchema 和 searchConfig
38
+ const dtoSearchSchema = buildDtoSchema(configSchema, "search");
39
+ for (const key in dtoSearchSchema.properties) {
40
+ if (route.query[key] !== undefined) {
41
+ dtoSearchSchema.properties[key].option.default = route.query[key];
42
+ }
43
+ }
44
+ searchSchema.value = dtoSearchSchema;
45
+ searchConfig.value = sConfig.searchConfig;
46
+
47
+ // 构造components = { key: { schema, config} }
48
+ const { componentConfig } = sConfig;
49
+ if (componentConfig && Object.keys(componentConfig).length > 0) {
50
+ const dtoComponents = {};
51
+ for (const comName in componentConfig) {
52
+ dtoComponents[comName] = {
53
+ schema: buildDtoSchema(configSchema, comName),
54
+ config: componentConfig[comName],
55
+ };
56
+ }
57
+ components.value = dtoComponents;
58
+ }
59
+ });
60
+ }
61
+ };
62
+
63
+ // 通用构建 schema 方法
64
+ const buildDtoSchema = (_schema, comName) => {
65
+ if (!_schema?.properties) return {};
66
+
67
+ const dtoSchema = {
68
+ type: "object",
69
+ properties: {},
70
+ };
71
+
72
+ // 提取有效 schema 字段信息
73
+ for (const key in _schema.properties) {
74
+ const props = _schema.properties[key];
75
+ if (props[`${comName}Option`]) {
76
+ let dtoProps = {};
77
+ // 提取 props 中的非 option 字段,存放到 dtoProps 中
78
+ for (const pKey in props) {
79
+ if (pKey.indexOf("option") < 0) {
80
+ dtoProps[pKey] = props[pKey];
81
+ }
82
+ }
83
+ // 处理 comName Option
84
+ dtoProps = Object.assign({}, dtoProps, {
85
+ option: props[`${comName}Option`],
86
+ });
87
+
88
+ // 处理 required 字段
89
+ const { required } = _schema;
90
+ if (required && required.find((pk) => pk === key)) {
91
+ dtoProps.option.required = true;
92
+ }
93
+ dtoSchema.properties[key] = dtoProps;
94
+ }
95
+ }
96
+ return dtoSchema;
97
+ };
98
+
99
+ watch(
100
+ [
101
+ () => route.query.key,
102
+ () => route.query.sider_key,
103
+ () => menuStore.menuList,
104
+ ],
105
+ () => {
106
+ buildData();
107
+ },
108
+ { deep: true },
109
+ );
110
+
111
+ onMounted(() => {
112
+ buildData();
113
+ });
114
+
115
+ return {
116
+ api,
117
+ tableSchema,
118
+ tableConfig,
119
+ searchSchema,
120
+ searchConfig,
121
+ components,
122
+ };
123
+ };
@@ -0,0 +1,88 @@
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
+ <table-panel ref="tablePanelRef" @operate="onTableOperate"></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 { ref } from "vue";
23
+ import { provide } from "vue";
24
+ import TablePanel from "./complex-view/table-panel/table-panel.vue";
25
+ import SearchPanel from "./complex-view/search-panel/search-panel.vue";
26
+ import ComponentConfig from "./components/component-config.js";
27
+ import { useSchema } from "./hook/schema";
28
+
29
+ const {
30
+ api,
31
+ tableSchema,
32
+ tableConfig,
33
+ searchConfig,
34
+ searchSchema,
35
+ components,
36
+ } = useSchema();
37
+
38
+ const apiParams = ref({});
39
+ provide("schemaViewData", {
40
+ api,
41
+ apiParams,
42
+ tableSchema,
43
+ tableConfig,
44
+ searchSchema,
45
+ searchConfig,
46
+ components,
47
+ });
48
+ const tablePanelRef = ref(null);
49
+ const comListRef = ref([]);
50
+ const onSearch = (searchValObj) => {
51
+ apiParams.value = searchValObj;
52
+ };
53
+ // table事件映射
54
+ const EventHandlerMap = {
55
+ showComponent: showComponent,
56
+ };
57
+ const onTableOperate = ({ btnConfig, rowData }) => {
58
+ const { eventKey } = btnConfig;
59
+ if (EventHandlerMap[eventKey]) {
60
+ EventHandlerMap[eventKey]({ btnConfig, rowData });
61
+ }
62
+ };
63
+ // showComponent 展示动态组件
64
+ function showComponent({ btnConfig, rowData }) {
65
+ const { comName } = btnConfig.eventOption;
66
+ if (!comName) return;
67
+ const comRef = comListRef.value.find((item) => item.name === comName);
68
+ if (!comRef || typeof comRef.show !== "function") return;
69
+ comRef.show(rowData);
70
+ }
71
+
72
+ // 响应组件事件
73
+ const onComponentCommand = (data) => {
74
+ const { event } = data;
75
+ if (event === "loadTableData") {
76
+ tablePanelRef.value.loadTableData();
77
+ }
78
+ };
79
+ </script>
80
+
81
+ <style lang="less" scoped>
82
+ .schema-view {
83
+ display: flex;
84
+ flex-direction: column;
85
+ height: 100%;
86
+ width: 100%;
87
+ }
88
+ </style>
@@ -0,0 +1,18 @@
1
+ <template>
2
+ <el-sub-menu :index="menuItem.key">
3
+ <template #title>{{ menuItem.name }}</template>
4
+ <div :key="item.key" v-for="item in menuItem.subMenu">
5
+ <sub-menu
6
+ v-if="item.subMenu && item.subMenu.length > 0"
7
+ :menu-item="item"
8
+ ></sub-menu>
9
+ <el-menu-item v-else :index="item.key">{{ item.name }}</el-menu-item>
10
+ </div>
11
+ </el-sub-menu>
12
+ </template>
13
+
14
+ <script setup>
15
+ const { menuItem } = defineProps(["menuItem"]);
16
+ </script>
17
+
18
+ <style lang="scss" scoped></style>
@@ -0,0 +1,117 @@
1
+ <template>
2
+ <sider-container>
3
+ <template #sider-content>
4
+ <el-menu
5
+ :default-active="activeKey"
6
+ :ellipsis="false"
7
+ @select="onMenuSelect"
8
+ >
9
+ <template v-for="item in menuList">
10
+ <sub-menu
11
+ v-if="item.subMenu && item.subMenu.length > 0"
12
+ :menu-item="item"
13
+ ></sub-menu>
14
+ <el-menu-item v-else :index="item.key">{{item.name}}</el-menu-item>
15
+ </template>
16
+ </el-menu>
17
+ </template>
18
+ <template #main-content>
19
+ <router-view></router-view>
20
+ </template>
21
+ </sider-container>
22
+ </template>
23
+
24
+ <script setup>
25
+ import { ref, watch, onMounted } from "vue";
26
+ import { useRouter, useRoute } from "vue-router";
27
+ import { useMenuStore } from "$elpisStore/menu.js";
28
+ import SiderContainer from "$elpisWidgets/sider-container/sider-container.vue";
29
+ import SubMenu from "./complex-view/sub-menu/sub-menu.vue";
30
+
31
+ const router = useRouter();
32
+ const route = useRoute();
33
+ const menuStore = useMenuStore();
34
+
35
+ onMounted(() => {
36
+ setMenuList();
37
+ setActiveKey();
38
+ });
39
+
40
+ const menuList = ref([]);
41
+ const setMenuList = () => {
42
+ const menuItem = menuStore.findMenuItem({
43
+ key: "key",
44
+ value: route.query.key,
45
+ });
46
+ if (menuItem && menuItem.siderConfig && menuItem.siderConfig.menu) {
47
+ menuList.value = menuItem.siderConfig.menu;
48
+ }
49
+ };
50
+
51
+ const activeKey = ref("");
52
+ const setActiveKey = () => {
53
+ let siderMenuItem = menuStore.findMenuItem({
54
+ key: "key",
55
+ value: route.query.sider_key,
56
+ });
57
+ // 首次加载没有选中左侧菜单时默认选中第一个
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
+ handleMenuSelect(siderMenuItem.key);
68
+ }
69
+ }
70
+ }
71
+ activeKey.value = siderMenuItem?.key;
72
+ };
73
+
74
+ const onMenuSelect = (menuKey) => {
75
+ handleMenuSelect(menuKey);
76
+ };
77
+
78
+ const handleMenuSelect = (menuKey) => {
79
+ const menuItem = menuStore.findMenuItem({
80
+ key: "key",
81
+ value: menuKey,
82
+ });
83
+ const { moduleType, key, customConfig } = menuItem;
84
+ if (key === route.query.sider_key) return;
85
+ const pathMap = {
86
+ iframe: "/iframe",
87
+ schema: "/schema",
88
+ custom: customConfig?.path,
89
+ };
90
+ router.push({
91
+ path: `/view/dashboard/sider${pathMap[moduleType]}`,
92
+ query: {
93
+ key: route.query.key,
94
+ sider_key: key,
95
+ proj_key: route.query.proj_key,
96
+ },
97
+ });
98
+ };
99
+
100
+ watch(
101
+ () => route.query.key,
102
+ () => {
103
+ setMenuList();
104
+ setActiveKey();
105
+ },
106
+ );
107
+ watch(
108
+ () => menuStore.menuList,
109
+ () => {
110
+ setMenuList();
111
+ setActiveKey();
112
+ },
113
+ { deep: true }
114
+ );
115
+ </script>
116
+
117
+ <style lang="less" scoped></style>
@@ -0,0 +1,89 @@
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 { useRoute, useRouter } from "vue-router";
14
+ import zhCn from "element-plus/es/locale/lang/zh-cn";
15
+ import HeaderView from "./complex-view/header-view/header-view.vue";
16
+ import $curl from "$elpisCommon/curl.js";
17
+ import { useProjectStore } from "$elpisStore/project.js";
18
+ import { useMenuStore } from "$elpisStore/menu.js";
19
+
20
+ const route = useRoute();
21
+ const router = useRouter();
22
+ const menuStore = useMenuStore();
23
+ const projectStore = useProjectStore();
24
+ const projName = ref("");
25
+ onMounted(() => {
26
+ getProjectList();
27
+ getProjectConfig();
28
+ });
29
+ // 请求 /api/project/list 接口
30
+ const getProjectList = async () => {
31
+ const res = await $curl({
32
+ method: "GET",
33
+ url: "/api/project/list",
34
+ query: {
35
+ proj_key: route.query.proj_key,
36
+ },
37
+ errorMessage: "获取项目列表失败",
38
+ });
39
+ if (!res || !res.data || !res.success) {
40
+ return;
41
+ }
42
+ projectStore.setProjectList(res.data);
43
+ };
44
+ // 请求 /api/project 接口
45
+ const getProjectConfig = async () => {
46
+ const res = await $curl({
47
+ method: "GET",
48
+ url: "/api/project",
49
+ query: {
50
+ proj_key: route.query.proj_key,
51
+ },
52
+ errorMessage: "获取项目配置失败",
53
+ });
54
+ if (!res || !res.data || !res.success) {
55
+ return;
56
+ }
57
+ projName.value = res.data.name;
58
+ menuStore.setMenuList(res.data.menu);
59
+ };
60
+ // 处理菜单点击事件
61
+ const onMenuSelect = (menuItem) => {
62
+ const {moduleType,key,customConfig} = menuItem;
63
+ // 如果是当前页面,不处理
64
+ if(key === route.query.key) {
65
+ return;
66
+ }
67
+
68
+ const pathMap = {
69
+ sider: '/sider',
70
+ iframe: '/iframe',
71
+ schema: '/schema',
72
+ custom: customConfig?.path,
73
+ }
74
+
75
+ router.push({
76
+ path: `/view/dashboard${pathMap[moduleType]}`,
77
+ query: {
78
+ key,
79
+ proj_key: route.query.proj_key,
80
+ }
81
+ })
82
+ };
83
+ </script>
84
+
85
+ <style lang="less" scoped>
86
+ :deep(.el-main){
87
+ padding: 0;
88
+ }
89
+ </style>
@@ -0,0 +1,42 @@
1
+ import boot from "$elpisPages/boot.js";
2
+ import dashboard from "./dashboard.vue";
3
+ import businessDashboardRouterConfig from "$businessDashboardRouterConfig";
4
+
5
+ const routes = [];
6
+ // 头部菜单路由
7
+ routes.push({
8
+ path: "/view/dashboard/iframe",
9
+ component: () => import("./complex-view/iframe-view/iframe-view.vue"),
10
+ });
11
+ routes.push({
12
+ path: "/view/dashboard/schema",
13
+ component: () => import("./complex-view/schema-view/schema-view.vue"),
14
+ });
15
+
16
+ const siderRoutes = [
17
+ {
18
+ path: "iframe",
19
+ component: () => import("./complex-view/iframe-view/iframe-view.vue"),
20
+ },
21
+ {
22
+ path: "schema",
23
+ component: () => import("./complex-view/schema-view/schema-view.vue"),
24
+ },
25
+ ];
26
+ // 侧边栏路由
27
+ routes.push({
28
+ path: "/view/dashboard/sider",
29
+ component: () => import("./complex-view/sider-view/sider-view.vue"),
30
+ children: siderRoutes,
31
+ });
32
+ // 业务拓展路由
33
+ if(typeof businessDashboardRouterConfig === "function") {
34
+ businessDashboardRouterConfig({routes, siderRoutes});
35
+ }
36
+ // 侧边栏兜底策略
37
+ routes.push({
38
+ path: "/view/dashboard/sider/:chapters+",
39
+ component: () => import("./complex-view/sider-view/sider-view.vue"),
40
+ });
41
+
42
+ boot(dashboard, { routes });
@@ -0,0 +1,5 @@
1
+ import { createPinia } from 'pinia';
2
+
3
+ export const pinia = createPinia();
4
+
5
+ export default pinia;
@@ -0,0 +1,57 @@
1
+ import { defineStore } from "pinia";
2
+ import { ref } from "vue";
3
+
4
+ export const useMenuStore = defineStore("menu", () => {
5
+ // 菜单列表
6
+ const menuList = ref([]);
7
+
8
+ // 设置菜单列表
9
+ const setMenuList = (list) => {
10
+ menuList.value = list;
11
+ };
12
+
13
+ /**
14
+ * 查找菜单项
15
+ * @param {key} 搜索字段
16
+ * @param {value} 搜索值
17
+ * @param {mList} 菜单列表
18
+ */
19
+ const findMenuItem = ({key, value}, mList = menuList.value) => {
20
+ for (let i = 0; i < mList.length; i++) {
21
+ const menuItem = mList[i];
22
+ if(!menuItem){continue;}
23
+ const{menuType, moduleType} = menuItem;
24
+ if(menuItem[key] === value){
25
+ return menuItem;
26
+ }
27
+ if(menuType === "group" && menuItem.subMenu){
28
+ const mItem = findMenuItem({key, value}, menuItem.subMenu);
29
+ if(mItem){return mItem;}
30
+ }
31
+ if(moduleType === "sider" && menuItem.siderConfig && menuItem.siderConfig.menu){
32
+ const mItem = findMenuItem({key, value}, menuItem.siderConfig.menu);
33
+ if(mItem){return mItem;}
34
+ }
35
+ }
36
+ };
37
+
38
+ /**
39
+ * 查找第一个菜单项
40
+ * @param {mList} 菜单列表
41
+ */
42
+ const findFirstMenuItem = (mList = menuList.value) => {
43
+ if(!mList || !mList[0]){return;}
44
+ let firstMenuItem = mList[0];
45
+ if(firstMenuItem.subMenu) {
46
+ firstMenuItem = findFirstMenuItem(firstMenuItem.subMenu);
47
+ }
48
+ return firstMenuItem;
49
+ }
50
+
51
+ return {
52
+ menuList,
53
+ setMenuList,
54
+ findMenuItem,
55
+ findFirstMenuItem
56
+ };
57
+ });
@@ -0,0 +1,15 @@
1
+ import { defineStore } from "pinia";
2
+ import { ref } from "vue";
3
+
4
+ export const useProjectStore = defineStore("project", () => {
5
+ // 项目列表
6
+ const projList = ref([]);
7
+ // 设置项目列表
8
+ const setProjectList = (list) => {
9
+ projList.value = list;
10
+ };
11
+ return {
12
+ projList,
13
+ setProjectList,
14
+ };
15
+ });