vue3-admin-gpt 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 (118) hide show
  1. package/.env.development +14 -0
  2. package/.env.production +14 -0
  3. package/LICENSE +21 -0
  4. package/README.en.md +106 -0
  5. package/README.md +104 -0
  6. package/build-zip.cjs +53 -0
  7. package/cli.js +110 -0
  8. package/jsconfig.json +9 -0
  9. package/package.json +92 -0
  10. package/public/index.html +20 -0
  11. package/public/robots.txt +2 -0
  12. package/rspack.config.js +282 -0
  13. package/rspack.js +162 -0
  14. package/src/App.vue +9 -0
  15. package/src/api/icon.js +9 -0
  16. package/src/api/router.js +9 -0
  17. package/src/api/table.js +25 -0
  18. package/src/api/tree.js +9 -0
  19. package/src/api/user.js +34 -0
  20. package/src/assets/error_images/401.png +0 -0
  21. package/src/assets/error_images/404.png +0 -0
  22. package/src/assets/error_images/cloud.png +0 -0
  23. package/src/assets/login_images/background.jpg +0 -0
  24. package/src/assets/logo.png +0 -0
  25. package/src/assets/qr_logo/lqr_logo.png +0 -0
  26. package/src/assets/vuejs-fill.svg +4 -0
  27. package/src/components/VabPageHeader/index.vue +133 -0
  28. package/src/config/index.js +7 -0
  29. package/src/config/net.config.js +20 -0
  30. package/src/config/permission.js +136 -0
  31. package/src/config/setting.config.js +62 -0
  32. package/src/config/settings.js +6 -0
  33. package/src/config/theme.config.js +14 -0
  34. package/src/layouts/EmptyLayout.vue +3 -0
  35. package/src/layouts/components/VabAppMain/index.vue +109 -0
  36. package/src/layouts/components/VabAvatar/index.vue +255 -0
  37. package/src/layouts/components/VabBreadcrumb/index.vue +61 -0
  38. package/src/layouts/components/VabFullScreen/index.vue +61 -0
  39. package/src/layouts/components/VabLogo/index.vue +94 -0
  40. package/src/layouts/components/VabNav/index.vue +176 -0
  41. package/src/layouts/components/VabSide/components/VabMenuItem.vue +80 -0
  42. package/src/layouts/components/VabSide/components/VabSideItem.vue +100 -0
  43. package/src/layouts/components/VabSide/components/VabSubmenu.vue +56 -0
  44. package/src/layouts/components/VabSide/index.vue +123 -0
  45. package/src/layouts/components/VabTabs/index.vue +500 -0
  46. package/src/layouts/components/VabTheme/index.vue +603 -0
  47. package/src/layouts/components/VabTop/index.vue +286 -0
  48. package/src/layouts/export.js +29 -0
  49. package/src/layouts/index.vue +339 -0
  50. package/src/main.js +40 -0
  51. package/src/plugins/echarts.js +4 -0
  52. package/src/plugins/index.js +44 -0
  53. package/src/plugins/support.js +16 -0
  54. package/src/router/index.js +400 -0
  55. package/src/store/index.js +26 -0
  56. package/src/store/modules/errorLog.js +27 -0
  57. package/src/store/modules/routes.js +60 -0
  58. package/src/store/modules/settings.js +73 -0
  59. package/src/store/modules/table.js +22 -0
  60. package/src/store/modules/tabsBar.js +109 -0
  61. package/src/store/modules/user.js +131 -0
  62. package/src/styles/element-variables.scss +13 -0
  63. package/src/styles/loading.scss +345 -0
  64. package/src/styles/nav-icons.scss +52 -0
  65. package/src/styles/normalize.scss +353 -0
  66. package/src/styles/spinner/dots.css +68 -0
  67. package/src/styles/spinner/gauge.css +104 -0
  68. package/src/styles/spinner/inner-circles.css +51 -0
  69. package/src/styles/spinner/plus.css +341 -0
  70. package/src/styles/themes/default.scss +1 -0
  71. package/src/styles/transition.scss +18 -0
  72. package/src/styles/vab.scss +476 -0
  73. package/src/styles/variables.scss +69 -0
  74. package/src/utils/accessToken.js +56 -0
  75. package/src/utils/eventBus.js +8 -0
  76. package/src/utils/handleRoutes.js +100 -0
  77. package/src/utils/index.js +231 -0
  78. package/src/utils/message.js +67 -0
  79. package/src/utils/pageTitle.js +11 -0
  80. package/src/utils/password.js +43 -0
  81. package/src/utils/permission.js +19 -0
  82. package/src/utils/request.js +187 -0
  83. package/src/utils/static.js +81 -0
  84. package/src/utils/vab.js +218 -0
  85. package/src/utils/validate.js +48 -0
  86. package/src/views/401.vue +302 -0
  87. package/src/views/404.vue +302 -0
  88. package/src/views/demo/index.vue +591 -0
  89. package/src/views/index/index.vue +1489 -0
  90. package/src/views/login/index.vue +456 -0
  91. package/src/views/register/index.vue +524 -0
  92. package/src/views/vab/calendar.vue +488 -0
  93. package/src/views/vab/campaign.vue +1006 -0
  94. package/src/views/vab/chart.vue +189 -0
  95. package/src/views/vab/customer.vue +666 -0
  96. package/src/views/vab/editor.vue +84 -0
  97. package/src/views/vab/form.vue +151 -0
  98. package/src/views/vab/help.vue +390 -0
  99. package/src/views/vab/icon.vue +113 -0
  100. package/src/views/vab/knowledge.vue +820 -0
  101. package/src/views/vab/nested/menu1/menu2/menu3.vue +29 -0
  102. package/src/views/vab/nested/menu1/menu2.vue +33 -0
  103. package/src/views/vab/nested/menu1.vue +33 -0
  104. package/src/views/vab/nested.vue +97 -0
  105. package/src/views/vab/notification.vue +416 -0
  106. package/src/views/vab/order.vue +507 -0
  107. package/src/views/vab/permissions.vue +214 -0
  108. package/src/views/vab/product.vue +724 -0
  109. package/src/views/vab/project.vue +559 -0
  110. package/src/views/vab/settings.vue +319 -0
  111. package/src/views/vab/statistics.vue +431 -0
  112. package/src/views/vab/table.vue +110 -0
  113. package/src/views/vab/task.vue +613 -0
  114. package/src/views/vab/team.vue +662 -0
  115. package/src/views/vab/tree.vue +44 -0
  116. package/src/views/vab/upload.vue +180 -0
  117. package/src/views/vab/vue3Demo/index.vue +103 -0
  118. package/src/views/vab/workflow.vue +863 -0
@@ -0,0 +1,286 @@
1
+ <template>
2
+ <div class="top-container">
3
+ <div class="vab-main">
4
+ <el-row :gutter="15">
5
+ <el-col :lg="6" :md="6" :sm="6" :xl="6" :xs="6">
6
+ <vab-logo />
7
+ </el-col>
8
+ <el-col :lg="12" :md="12" :sm="12" :xl="12" :xs="12">
9
+ <el-menu
10
+ active-text-color=" hsla(0, 0%, 100%, 0.95)"
11
+ background-color="#21252b"
12
+ :collapse="collapse"
13
+ :collapse-transition="false"
14
+ :default-active="activeMenu"
15
+ :default-openeds="defaultOpens"
16
+ text-color=" hsla(0, 0%, 100%, 0.95)"
17
+ menu-trigger="hover"
18
+ mode="horizontal"
19
+ >
20
+ <template v-for="route in routes">
21
+ <vab-side-item
22
+ v-if="!route.hidden"
23
+ :key="route.path"
24
+ :full-path="route.path"
25
+ :item="route"
26
+ />
27
+ </template>
28
+ </el-menu>
29
+ </el-col>
30
+ <el-col :lg="6" :md="6" :sm="6" :xl="6" :xs="6">
31
+ <div class="right-panel">
32
+ <div class="right-menu">
33
+ <vab-full-screen @refresh="refreshRoute" />
34
+ <vab-theme class="hidden-md-and-down" />
35
+ <el-icon
36
+ :class="{ 'is-pulsing': pulse }"
37
+ title="重载路由"
38
+ @click="refreshRoute"
39
+ >
40
+ <Refresh />
41
+ </el-icon>
42
+ </div>
43
+ <vab-avatar />
44
+ </div>
45
+ </el-col>
46
+ </el-row>
47
+ </div>
48
+ </div>
49
+ </template>
50
+
51
+ <script setup>
52
+ import { ref, computed, onBeforeUnmount } from "vue";
53
+ import { useStore } from "vuex";
54
+ import { useRoute } from "vue-router";
55
+ import variables from "@/styles/variables.scss";
56
+ import { Refresh } from "@element-plus/icons-vue";
57
+
58
+ defineOptions({
59
+ name: "VabTop",
60
+ });
61
+
62
+ const store = useStore();
63
+ const route = useRoute();
64
+
65
+ // 响应式数据
66
+ const pulse = ref(false);
67
+ const menuTrigger = ref("hover");
68
+ let timeOutID = null;
69
+
70
+ // 计算属性
71
+ const routes = computed(() => store.getters["routes/routes"]);
72
+ const visitedRoutes = computed(() => store.getters["tabsBar/visitedRoutes"]);
73
+ const collapse = computed(() => store.getters["settings/collapse"]);
74
+ const defaultOpens = computed(() => []);
75
+
76
+ const activeMenu = computed(() => {
77
+ const { meta, path } = route;
78
+ if (meta.activeMenu) {
79
+ return meta.activeMenu;
80
+ }
81
+ return path;
82
+ });
83
+
84
+ // 方法
85
+ const refreshRoute = async () => {
86
+ window.$eventBus.emit("reload-router-view");
87
+ pulse.value = true;
88
+ timeOutID = setTimeout(() => {
89
+ pulse.value = false;
90
+ }, 1000);
91
+ };
92
+
93
+ // 生命周期钩子
94
+ onBeforeUnmount(() => {
95
+ clearTimeout(timeOutID);
96
+ });
97
+ </script>
98
+
99
+ <style lang="scss" scoped>
100
+ .top-container {
101
+ display: flex;
102
+ align-items: center;
103
+ justify-items: flex-end;
104
+ height: $base-top-bar-height;
105
+ background: $base-menu-background;
106
+ width: 100%;
107
+
108
+ .is-pulsing {
109
+ animation: pulse 1s infinite;
110
+ }
111
+
112
+ @keyframes pulse {
113
+ 0% {
114
+ transform: scale(1);
115
+ }
116
+ 50% {
117
+ transform: scale(1.2);
118
+ }
119
+ 100% {
120
+ transform: scale(1);
121
+ }
122
+ }
123
+
124
+ .vab-main {
125
+ background: $base-menu-background;
126
+ width: 100%;
127
+ padding: 0 15px;
128
+
129
+ :deep() {
130
+ .el-menu {
131
+ &.el-menu--horizontal {
132
+ display: flex;
133
+ align-items: center;
134
+ justify-content: center;
135
+ height: $base-top-bar-height;
136
+ border-bottom: 0 solid transparent !important;
137
+
138
+ .el-menu-item,
139
+ .el-submenu__title {
140
+ padding: 0 15px;
141
+ }
142
+
143
+ @media only screen and (max-width: 767px) {
144
+ .el-menu-item,
145
+ .el-submenu__title {
146
+ padding: 0 8px;
147
+ }
148
+
149
+ li:nth-child(4),
150
+ li:nth-child(5) {
151
+ display: none !important;
152
+ }
153
+ }
154
+
155
+ > .el-menu-item {
156
+ height: $base-top-bar-height;
157
+ line-height: $base-top-bar-height;
158
+ }
159
+
160
+ > .el-submenu {
161
+ .el-submenu__title {
162
+ height: $base-top-bar-height;
163
+ line-height: $base-top-bar-height;
164
+ }
165
+ }
166
+ }
167
+
168
+ svg {
169
+ width: 1rem;
170
+ margin-right: 3px;
171
+ }
172
+
173
+ &--horizontal {
174
+ .el-menu {
175
+ .el-menu-item,
176
+ .el-submenu__title {
177
+ height: $base-menu-item-height;
178
+ line-height: $base-menu-item-height;
179
+ }
180
+ }
181
+
182
+ .el-submenu,
183
+ .el-menu-item {
184
+ &.is-active {
185
+ background-color: $base-color-blue !important;
186
+ border-bottom: 0 solid transparent !important;
187
+
188
+ .el-submenu__title {
189
+ border-bottom: 0 solid transparent !important;
190
+ }
191
+ }
192
+ }
193
+
194
+ > .el-menu-item {
195
+ .el-tag {
196
+ margin-top: calc(#{$base-top-bar-height} / 2 - 7.5px);
197
+ margin-left: 5px;
198
+ }
199
+
200
+ @media only screen and (max-width: 1199px) {
201
+ .el-tag {
202
+ display: none;
203
+ }
204
+ }
205
+
206
+ &.is-active {
207
+ background-color: transparent !important;
208
+ border-bottom: 3px solid $base-color-blue !important;
209
+ }
210
+ }
211
+ }
212
+ }
213
+ }
214
+ }
215
+
216
+ .right-panel {
217
+ display: flex;
218
+ align-items: center;
219
+ justify-content: flex-end;
220
+ height: $base-top-bar-height;
221
+ width: 100%;
222
+
223
+ .right-menu {
224
+ display: flex;
225
+ align-items: center;
226
+ margin-right: 10px;
227
+ }
228
+
229
+ :deep() {
230
+ .username,
231
+ .user-role {
232
+ color: rgba($base-color-white, 0.9);
233
+ }
234
+
235
+ .username + i {
236
+ color: rgba($base-color-white, 0.9);
237
+ }
238
+
239
+ svg {
240
+ width: 1em;
241
+ height: 1em;
242
+ margin-right: 15px;
243
+ font-size: $base-font-size-big;
244
+ color: rgba($base-color-white, 0.9);
245
+ cursor: pointer;
246
+ fill: rgba($base-color-white, 0.9);
247
+ }
248
+
249
+ button {
250
+ svg {
251
+ margin-right: 0;
252
+ color: rgba($base-color-white, 0.9);
253
+ cursor: pointer;
254
+ fill: rgba($base-color-white, 0.9);
255
+ }
256
+ }
257
+
258
+ .el-badge {
259
+ margin-right: 15px;
260
+ }
261
+ }
262
+ }
263
+ }
264
+
265
+ @media (max-width: 992px) {
266
+ .top-container {
267
+ .vab-main {
268
+ .el-menu--horizontal {
269
+ justify-content: flex-start;
270
+ }
271
+ }
272
+
273
+ .right-panel {
274
+ .right-menu {
275
+ margin-right: 5px;
276
+ }
277
+
278
+ :deep() {
279
+ svg {
280
+ margin-right: 8px;
281
+ }
282
+ }
283
+ }
284
+ }
285
+ }
286
+ </style>
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @description 公共布局及样式自动引入
3
+ */
4
+
5
+ // 使用 require.context 自动导入主题文件
6
+ const requireThemes = require.context("@/styles/themes", true, /\.scss$/);
7
+ requireThemes.keys().forEach((fileName) => {
8
+ requireThemes(fileName);
9
+ });
10
+
11
+ // 预加载组件,但不立即注册
12
+ // 这些组件将在main.js中被注册
13
+ const components = {};
14
+ const requireComponents = require.context("./components", true, /\.vue$/);
15
+ requireComponents.keys().forEach((fileName) => {
16
+ const componentConfig = requireComponents(fileName);
17
+ const component = componentConfig.default || componentConfig;
18
+ if (component.name) {
19
+ components[component.name] = component;
20
+ }
21
+ });
22
+
23
+ // 创建一个注册函数,接收app实例
24
+ export function registerLayoutComponents(app) {
25
+ // 注册所有布局组件
26
+ Object.entries(components).forEach(([name, component]) => {
27
+ app.component(name, component);
28
+ });
29
+ }
@@ -0,0 +1,339 @@
1
+ <template>
2
+ <div :class="classObj" class="vue-admin-better-wrapper">
3
+ <div
4
+ v-if="'horizontal' === layout"
5
+ :class="{
6
+ fixed: header === 'fixed',
7
+ 'no-tabs-bar': tabsBar === 'false' || tabsBar === false,
8
+ }"
9
+ class="layout-container-horizontal"
10
+ >
11
+ <div :class="header === 'fixed' ? 'fixed-header' : ''">
12
+ <vab-top />
13
+ <div
14
+ v-if="tabsBar === 'true' || tabsBar === true"
15
+ :class="{ 'tag-view-show': tabsBar }"
16
+ >
17
+ <el-scrollbar>
18
+ <vab-tabs />
19
+ </el-scrollbar>
20
+ </div>
21
+ </div>
22
+ <div class="vab-main main-padding">
23
+ <vab-app-main />
24
+ </div>
25
+ </div>
26
+ <div
27
+ v-else
28
+ :class="{
29
+ fixed: header === 'fixed',
30
+ 'no-tabs-bar': tabsBar === 'false' || tabsBar === false,
31
+ }"
32
+ class="layout-container-vertical"
33
+ >
34
+ <div
35
+ v-if="device === 'mobile' && collapse === false"
36
+ class="mask"
37
+ @click="handleFoldSideBar"
38
+ />
39
+ <vab-side />
40
+ <div :class="collapse ? 'is-collapse-main' : ''" class="vab-main">
41
+ <div :class="header === 'fixed' ? 'fixed-header' : ''">
42
+ <vab-nav />
43
+ <vab-tabs v-if="tabsBar === 'true' || tabsBar === true" />
44
+ </div>
45
+ <vab-app-main />
46
+ </div>
47
+ </div>
48
+ <el-backtop />
49
+ </div>
50
+ </template>
51
+
52
+ <script setup>
53
+ import { ref, computed, onBeforeMount, onBeforeUnmount, onMounted, nextTick } from "vue";
54
+ import { useStore } from "vuex";
55
+ import { tokenName } from "@/config";
56
+ import { debounce } from "lodash";
57
+
58
+ const store = useStore();
59
+
60
+ const oldLayout = ref("");
61
+ const controller = ref(new window.AbortController());
62
+ let timeOutID = null;
63
+
64
+ const layout = computed(() => store.getters["settings/layout"]);
65
+ const tabsBar = computed(() => store.getters["settings/tabsBar"]);
66
+ const collapse = computed(() => store.getters["settings/collapse"]);
67
+ const header = computed(() => store.getters["settings/header"]);
68
+ const device = computed(() => store.getters["settings/device"]);
69
+
70
+ const classObj = computed(() => {
71
+ return {
72
+ mobile: device.value === "mobile",
73
+ };
74
+ });
75
+
76
+ const handleFoldSideBar = () => {
77
+ store.dispatch("settings/foldSideBar");
78
+ };
79
+
80
+ const handleIsMobile = () => {
81
+ return document.body.getBoundingClientRect().width - 1 < 992;
82
+ };
83
+
84
+ const handleResize = debounce(() => {
85
+ if (!document.hidden) {
86
+ const isMobile = handleIsMobile();
87
+ if (isMobile) {
88
+ //横向布局时如果是手机端访问那么改成纵向版
89
+ store.dispatch("settings/changeLayout", "vertical");
90
+ } else {
91
+ store.dispatch("settings/changeLayout", oldLayout.value);
92
+ }
93
+
94
+ store.dispatch("settings/toggleDevice", isMobile ? "mobile" : "desktop");
95
+ }
96
+ }, 100);
97
+
98
+ onBeforeMount(() => {
99
+ window.addEventListener("resize", handleResize);
100
+
101
+ // 页面加载时检查是否有保存的路由信息
102
+ const savedRoute = sessionStorage.getItem('currentRoute');
103
+ if (savedRoute) {
104
+ try {
105
+ const routeInfo = JSON.parse(savedRoute);
106
+ // 这里可以添加恢复路由状态的逻辑,比如重新设置Vuex中的路由状态
107
+ console.log('恢复保存的路由信息:', routeInfo);
108
+ // 清除保存的路由信息
109
+ sessionStorage.removeItem('currentRoute');
110
+ } catch (e) {
111
+ console.error('解析保存的路由信息失败:', e);
112
+ }
113
+ }
114
+ });
115
+
116
+ // 页面刷新前保存当前路由信息
117
+ const handleBeforeUnload = () => {
118
+ // 保存当前路由到 sessionStorage
119
+ sessionStorage.setItem('currentRoute', JSON.stringify({
120
+ path: window.location.hash.replace('#', ''),
121
+ fullPath: window.location.href
122
+ }));
123
+ };
124
+
125
+ // 监听页面可见性变化,处理页面切换
126
+ const handleVisibilityChange = () => {
127
+ if (document.hidden) {
128
+ // 页面隐藏时保存路由信息
129
+ handleBeforeUnload();
130
+ }
131
+ };
132
+
133
+ onMounted(() => {
134
+ window.addEventListener('beforeunload', handleBeforeUnload);
135
+ document.addEventListener('visibilitychange', handleVisibilityChange);
136
+ });
137
+
138
+ onBeforeUnmount(() => {
139
+ window.removeEventListener("resize", handleResize);
140
+ window.removeEventListener('beforeunload', handleBeforeUnload);
141
+ document.removeEventListener('visibilitychange', handleVisibilityChange);
142
+ controller.value.abort();
143
+ clearTimeout(timeOutID);
144
+ });
145
+
146
+ // 相当于mounted
147
+ oldLayout.value = layout.value;
148
+ const isMobile = handleIsMobile();
149
+ if (isMobile) {
150
+ //横向布局时如果是手机端访问那么改成纵向版
151
+ store.dispatch("settings/changeLayout", "vertical");
152
+ } else {
153
+ store.dispatch("settings/changeLayout", oldLayout.value);
154
+ }
155
+ store.dispatch("settings/toggleDevice", isMobile ? "mobile" : "desktop");
156
+ if (isMobile) {
157
+ timeOutID = setTimeout(() => {
158
+ store.dispatch("settings/foldSideBar");
159
+ }, 2000);
160
+ } else {
161
+ store.dispatch("settings/openSideBar");
162
+ }
163
+
164
+ nextTick(() => {
165
+ window.addEventListener(
166
+ "storage",
167
+ (e) => {
168
+ if (e.key === tokenName || e.key === null) window.location.reload();
169
+ if (e.key === tokenName && e.value === null) window.location.reload();
170
+ },
171
+ {
172
+ capture: false,
173
+ signal: controller.value?.signal,
174
+ }
175
+ );
176
+ });
177
+ </script>
178
+
179
+ <style lang="scss" scoped>
180
+ @mixin fix-header {
181
+ position: fixed;
182
+ top: 0;
183
+ right: 0;
184
+ left: 0;
185
+ z-index: $base-z-index - 2;
186
+ width: 100%;
187
+ overflow: hidden;
188
+ }
189
+
190
+ .vue-admin-better-wrapper {
191
+ position: relative;
192
+ width: 100%;
193
+ height: 100%;
194
+
195
+ .layout-container-horizontal {
196
+ position: relative;
197
+
198
+ &.fixed {
199
+ padding-top: calc(#{$base-top-bar-height} + #{$base-tabs-bar-height});
200
+ }
201
+
202
+ &.fixed.no-tabs-bar {
203
+ padding-top: $base-top-bar-height;
204
+ }
205
+
206
+ :deep() {
207
+ .vab-main {
208
+ width: 88%;
209
+ margin: auto;
210
+ }
211
+
212
+ .fixed-header {
213
+ @include fix-header;
214
+ }
215
+
216
+ .tag-view-show {
217
+ background: $base-color-white;
218
+ box-shadow: $base-box-shadow;
219
+ }
220
+
221
+ .nav-container {
222
+ .fold-unfold {
223
+ display: none;
224
+ }
225
+ }
226
+
227
+ .main-padding {
228
+ .app-main-container {
229
+ margin-top: $base-padding;
230
+ margin-bottom: $base-padding;
231
+ background: $base-color-white;
232
+ }
233
+ }
234
+ }
235
+ }
236
+
237
+ .layout-container-vertical {
238
+ position: relative;
239
+
240
+ .mask {
241
+ position: fixed;
242
+ top: 0;
243
+ right: 0;
244
+ bottom: 0;
245
+ left: 0;
246
+ z-index: $base-z-index - 1;
247
+ width: 100%;
248
+ height: 100vh;
249
+ overflow: hidden;
250
+ background: #000;
251
+ opacity: 0.5;
252
+ }
253
+
254
+ &.fixed {
255
+ padding-top: calc(#{$base-nav-bar-height} + #{$base-tabs-bar-height});
256
+ }
257
+
258
+ &.fixed.no-tabs-bar {
259
+ padding-top: $base-nav-bar-height;
260
+ }
261
+
262
+ .vab-main {
263
+ position: relative;
264
+ min-height: 100%;
265
+ margin-left: $base-left-menu-width;
266
+ background: #f6f8f9;
267
+ transition: $base-transition;
268
+
269
+ :deep() {
270
+ .fixed-header {
271
+ @include fix-header;
272
+
273
+ left: $base-left-menu-width;
274
+ width: $base-right-content-width;
275
+ box-shadow: $base-box-shadow;
276
+ transition: $base-transition;
277
+ }
278
+
279
+ .nav-container {
280
+ position: relative;
281
+ box-sizing: border-box;
282
+ }
283
+
284
+ .tabs-container {
285
+ box-sizing: border-box;
286
+ }
287
+
288
+ .app-main-container {
289
+ width: calc(100% - #{$base-padding} - #{$base-padding});
290
+ margin: $base-padding auto;
291
+ background: $base-color-white;
292
+ border-radius: $base-border-radius;
293
+ }
294
+ }
295
+
296
+ &.is-collapse-main {
297
+ margin-left: $base-left-menu-width-min;
298
+
299
+ :deep() {
300
+ .fixed-header {
301
+ left: $base-left-menu-width-min;
302
+ width: calc(100% - 65px);
303
+ }
304
+ }
305
+ }
306
+ }
307
+ }
308
+
309
+ /* 手机端开始 */
310
+ &.mobile {
311
+ :deep() {
312
+ .el-pager,
313
+ .el-pagination__jump {
314
+ display: none;
315
+ }
316
+
317
+ .layout-container-vertical {
318
+ .el-scrollbar.side-container.is-collapse {
319
+ width: 0;
320
+ }
321
+
322
+ .vab-main {
323
+ width: 100%;
324
+ margin-left: 0;
325
+ }
326
+ }
327
+
328
+ .vab-main {
329
+ .fixed-header {
330
+ left: 0 !important;
331
+ width: 100% !important;
332
+ }
333
+ }
334
+ }
335
+ }
336
+
337
+ /* 手机端结束 */
338
+ }
339
+ </style>
package/src/main.js ADDED
@@ -0,0 +1,40 @@
1
+ import { createApp } from "vue";
2
+ import App from "./App.vue";
3
+ import router from "./router";
4
+ import store from "@/store"; // 导入Vuex store
5
+ import plugins from "./plugins";
6
+ // 导入布局组件注册函数
7
+ import { registerLayoutComponents } from "@/layouts/export";
8
+ // 导入事件总线
9
+ import eventBus from "@/utils/eventBus";
10
+ // 导入配置
11
+ import { title } from "@/config";
12
+
13
+
14
+ // 创建应用实例
15
+ const app = createApp(App);
16
+
17
+ // 使用Vuex
18
+ app.use(store);
19
+
20
+ app.use(router);
21
+
22
+ // 初始化所有插件
23
+ plugins(app);
24
+
25
+ // 注册所有布局组件
26
+ registerLayoutComponents(app);
27
+
28
+ // 添加事件总线到全局属性
29
+ app.config.globalProperties.$eventBus = eventBus;
30
+
31
+ // 添加全局标题
32
+ app.config.globalProperties.$baseTitle = title;
33
+
34
+ // 使全局属性在window上也可用
35
+ window.$eventBus = eventBus;
36
+ window.$baseTitle = title;
37
+
38
+
39
+ // 挂载应用
40
+ app.mount("#app");
@@ -0,0 +1,4 @@
1
+ import 'echarts'
2
+ import VabChart from 'vue-echarts'
3
+
4
+ export default VabChart