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,603 @@
1
+ <template>
2
+ <span v-if="themeBar">
3
+ <!-- 直接使用图标组件,不再包裹在el-icon中 -->
4
+ <Brush class="nav-icon" title="主题配置" @click="handleOpenTheme" />
5
+
6
+ <el-drawer
7
+ v-model="drawerVisible"
8
+ append-to-body
9
+ direction="rtl"
10
+ size="300px"
11
+ title="主题配置"
12
+ >
13
+ <el-scrollbar style="height: 80vh; overflow: hidden">
14
+ <div class="el-drawer__body">
15
+ <div class="theme-config-container">
16
+ <div class="config-section">
17
+ <div class="section-header">
18
+ <el-icon><Picture /></el-icon>
19
+ <span>主题风格</span>
20
+ </div>
21
+ <div class="theme-options">
22
+ <div
23
+ class="theme-option"
24
+ :class="{ active: theme.name === 'default' }"
25
+ @click="
26
+ theme.name = 'default';
27
+ handleSaveTheme();
28
+ "
29
+ >
30
+ <div class="theme-preview default-theme">
31
+ <div class="preview-header"></div>
32
+ <div class="preview-sidebar"></div>
33
+ <div class="preview-content"></div>
34
+ </div>
35
+ <span class="theme-name">默认主题</span>
36
+ </div>
37
+ <div
38
+ class="theme-option"
39
+ :class="{ active: theme.name === 'green' }"
40
+ @click="
41
+ theme.name = 'green';
42
+ handleSaveTheme();
43
+ "
44
+ >
45
+ <div class="theme-preview green-theme">
46
+ <div class="preview-header"></div>
47
+ <div class="preview-sidebar"></div>
48
+ <div class="preview-content"></div>
49
+ </div>
50
+ <span class="theme-name">绿荫草场</span>
51
+ </div>
52
+ <div
53
+ class="theme-option"
54
+ :class="{ active: theme.name === 'glory' }"
55
+ @click="
56
+ theme.name = 'glory';
57
+ handleSaveTheme();
58
+ "
59
+ >
60
+ <div class="theme-preview glory-theme">
61
+ <div class="preview-header"></div>
62
+ <div class="preview-sidebar"></div>
63
+ <div class="preview-content"></div>
64
+ </div>
65
+ <span class="theme-name">荣耀典藏</span>
66
+ </div>
67
+ </div>
68
+ </div>
69
+
70
+ <div class="config-section">
71
+ <div class="section-header">
72
+ <el-icon><Grid /></el-icon>
73
+ <span>布局设置</span>
74
+ </div>
75
+ <div class="layout-options">
76
+ <div
77
+ class="layout-option"
78
+ :class="{ active: theme.layout === 'vertical' }"
79
+ @click="
80
+ theme.layout = 'vertical';
81
+ handleSaveTheme();
82
+ "
83
+ >
84
+ <div class="layout-preview vertical-layout">
85
+ <div class="preview-header"></div>
86
+ <div class="preview-sidebar"></div>
87
+ <div class="preview-content"></div>
88
+ </div>
89
+ <span class="layout-name">纵向布局</span>
90
+ </div>
91
+ <div
92
+ class="layout-option"
93
+ :class="{ active: theme.layout === 'horizontal' }"
94
+ @click="
95
+ theme.layout = 'horizontal';
96
+ handleSaveTheme();
97
+ "
98
+ >
99
+ <div class="layout-preview horizontal-layout">
100
+ <div class="preview-header"></div>
101
+ <div class="preview-main">
102
+ <div class="preview-sidebar"></div>
103
+ <div class="preview-content"></div>
104
+ </div>
105
+ </div>
106
+ <span class="layout-name">横向布局</span>
107
+ </div>
108
+ </div>
109
+ </div>
110
+
111
+ <div class="config-section">
112
+ <div class="section-header">
113
+ <el-icon><Setting /></el-icon>
114
+ <span>功能设置</span>
115
+ </div>
116
+ <div class="feature-options">
117
+ <div class="feature-item">
118
+ <div class="feature-info">
119
+ <span class="feature-name">固定头部</span>
120
+ <span class="feature-desc">头部始终固定在页面顶部</span>
121
+ </div>
122
+ <el-switch
123
+ v-model="theme.header"
124
+ active-value="fixed"
125
+ inactive-value="noFixed"
126
+ @change="handleSaveTheme"
127
+ />
128
+ </div>
129
+ <div class="feature-item">
130
+ <div class="feature-info">
131
+ <span class="feature-name">多标签页</span>
132
+ <span class="feature-desc">开启页面标签页功能</span>
133
+ </div>
134
+ <el-switch
135
+ v-model="theme.tabsBar"
136
+ active-value="true"
137
+ inactive-value="false"
138
+ @change="handleSaveTheme"
139
+ />
140
+ </div>
141
+ </div>
142
+ </div>
143
+ </div>
144
+ </div>
145
+ </el-scrollbar>
146
+
147
+ <template #footer>
148
+ <el-button type="primary" @click="handleSaveTheme">保存设置</el-button>
149
+ <el-button @click="drawerVisible = false">取消</el-button>
150
+ </template>
151
+ </el-drawer>
152
+ </span>
153
+ </template>
154
+
155
+ <script>
156
+ import { mapActions, mapGetters } from "vuex";
157
+ import { layout as defaultLayout } from "@/config";
158
+ import { Brush, Picture, Grid, Setting } from "@element-plus/icons-vue";
159
+
160
+ export default {
161
+ name: "VabTheme",
162
+ components: {
163
+ Brush,
164
+ Picture,
165
+ Grid,
166
+ Setting,
167
+ },
168
+ data() {
169
+ return {
170
+ drawerVisible: false,
171
+ theme: {
172
+ name: "default",
173
+ layout: "",
174
+ header: "fixed",
175
+ tabsBar: "",
176
+ },
177
+ };
178
+ },
179
+ computed: {
180
+ ...mapGetters({
181
+ layout: "settings/layout",
182
+ header: "settings/header",
183
+ tabsBar: "settings/tabsBar",
184
+ themeBar: "settings/themeBar",
185
+ }),
186
+ },
187
+ created() {
188
+ // 在created钩子中初始化主题
189
+ // 不再使用事件总线 ($baseEventBus)
190
+ const theme = localStorage.getItem("vue3-admin-theme");
191
+ if (null !== theme) {
192
+ this.theme = JSON.parse(theme);
193
+ this.handleSaveTheme();
194
+ } else {
195
+ this.theme.layout = this.layout;
196
+ this.theme.header = this.header;
197
+ this.theme.tabsBar = this.tabsBar;
198
+ }
199
+ },
200
+ methods: {
201
+ ...mapActions({
202
+ changeLayout: "settings/changeLayout",
203
+ changeHeader: "settings/changeHeader",
204
+ changeTabsBar: "settings/changeTabsBar",
205
+ }),
206
+ handleIsMobile() {
207
+ return document.body.getBoundingClientRect().width - 1 < 992;
208
+ },
209
+ handleOpenTheme() {
210
+ this.drawerVisible = true;
211
+ },
212
+ handleSaveTheme() {
213
+ let { name, layout, header, tabsBar } = this.theme;
214
+ localStorage.setItem(
215
+ "vue3-admin-theme",
216
+ `{
217
+ "name":"${name}",
218
+ "layout":"${layout}",
219
+ "header":"${header}",
220
+ "tabsBar":"${tabsBar}"
221
+ }`
222
+ );
223
+ if (!this.handleIsMobile()) this.changeLayout(layout);
224
+ this.changeHeader(header);
225
+ this.changeTabsBar(tabsBar);
226
+ document.getElementsByTagName(
227
+ "body"
228
+ )[0].className = `vue3-admin-theme-${name}`;
229
+ this.drawerVisible = false;
230
+ },
231
+ // handleGetCode() {
232
+ // const url =
233
+ // "https://github.com/zxwk1998/vue-admin-better/tree/master/src/views";
234
+ // let path = this.$route.path + "/index.vue";
235
+ // if (path === "/vab/menu1/menu1-1/menu1-1-1/index.vue") {
236
+ // path = "/vab/nested/menu1/menu1-1/menu1-1-1/index.vue";
237
+ // }
238
+ // if (path === "/vab/icon/awesomeIcon/index.vue") {
239
+ // path = "/vab/icon/index.vue";
240
+ // }
241
+ // if (path === "/vab/icon/colorfulIcon/index.vue") {
242
+ // path = "/vab/icon/colorfulIcon.vue";
243
+ // }
244
+ // window.open(url + path);
245
+ // },
246
+ },
247
+ };
248
+ </script>
249
+
250
+ <style lang="scss" scoped>
251
+ /* 移除自定义主题图标样式,使用VabNav中定义的统一样式 */
252
+
253
+ @mixin right-bar {
254
+ position: fixed;
255
+ right: 0;
256
+ z-index: $base-z-index;
257
+ width: 60px;
258
+ min-height: 60px;
259
+ text-align: center;
260
+ cursor: pointer;
261
+ background: $base-color-blue;
262
+ border-radius: $base-border-radius;
263
+
264
+ > div {
265
+ padding-top: 10px;
266
+ border-bottom: 0 !important;
267
+
268
+ &:hover {
269
+ opacity: 0.9;
270
+ }
271
+
272
+ & + div {
273
+ border-top: 1px solid $base-color-white;
274
+ }
275
+
276
+ p {
277
+ padding: 0;
278
+ margin: 0;
279
+ font-size: $base-font-size-small;
280
+ line-height: 30px;
281
+ color: $base-color-white;
282
+ }
283
+ }
284
+ }
285
+
286
+ .theme-setting {
287
+ @include right-bar;
288
+
289
+ top: calc((100vh - 110px) / 2);
290
+
291
+ :deep() {
292
+ svg:not(:root).svg-inline--fa {
293
+ display: block;
294
+ margin-right: auto;
295
+ margin-left: auto;
296
+ color: $base-color-white;
297
+ }
298
+
299
+ .svg-icon {
300
+ display: block;
301
+ margin-right: auto;
302
+ margin-left: auto;
303
+ font-size: 20px;
304
+ color: $base-color-white;
305
+ fill: $base-color-white;
306
+ }
307
+ }
308
+ }
309
+
310
+ .el-drawer__body {
311
+ padding: 20px;
312
+ }
313
+
314
+ .el-drawer__footer {
315
+ border-top: 1px solid #dedede;
316
+ position: fixed;
317
+ bottom: 0;
318
+ width: 100%;
319
+ padding: 10px 0 0 20px;
320
+ height: 50px;
321
+ }
322
+
323
+ .theme-config-container {
324
+ .config-section {
325
+ margin-bottom: 30px;
326
+
327
+ .section-header {
328
+ display: flex;
329
+ align-items: center;
330
+ margin-bottom: 16px;
331
+ padding-bottom: 8px;
332
+ border-bottom: 1px solid #f0f0f0;
333
+
334
+ i {
335
+ margin-right: 8px;
336
+ font-size: 16px;
337
+ color: #409EFF;
338
+ }
339
+
340
+ span {
341
+ font-size: 16px;
342
+ font-weight: 600;
343
+ color: #333;
344
+ }
345
+ }
346
+
347
+ .theme-options {
348
+ display: flex;
349
+ flex-direction: column;
350
+ gap: 12px;
351
+
352
+ .theme-option {
353
+ display: flex;
354
+ align-items: center;
355
+ padding: 12px;
356
+ border: 2px solid #f0f0f0;
357
+ border-radius: 8px;
358
+ cursor: pointer;
359
+ transition: all 0.3s ease;
360
+
361
+ &:hover {
362
+ border-color: #409EFF;
363
+ transform: translateY(-1px);
364
+ box-shadow: 0 4px 12px rgba(64, 158, 255, 0.1);
365
+ }
366
+
367
+ &.active {
368
+ border-color: #409EFF;
369
+ background: rgba(64, 158, 255, 0.05);
370
+ box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
371
+ }
372
+
373
+ .theme-preview {
374
+ width: 60px;
375
+ height: 40px;
376
+ margin-right: 12px;
377
+ border-radius: 4px;
378
+ overflow: hidden;
379
+ position: relative;
380
+
381
+ .preview-header {
382
+ height: 8px;
383
+ background: #f0f0f0;
384
+ }
385
+
386
+ .preview-sidebar {
387
+ position: absolute;
388
+ left: 0;
389
+ top: 8px;
390
+ width: 12px;
391
+ height: 32px;
392
+ background: #e0e0e0;
393
+ }
394
+
395
+ .preview-content {
396
+ position: absolute;
397
+ left: 12px;
398
+ top: 8px;
399
+ width: 48px;
400
+ height: 32px;
401
+ background: #fafafa;
402
+ }
403
+
404
+ &.default-theme {
405
+ .preview-header {
406
+ background: #409eff;
407
+ }
408
+ .preview-sidebar {
409
+ background: #2c3e50;
410
+ }
411
+ .preview-content {
412
+ background: #ffffff;
413
+ }
414
+ }
415
+
416
+ &.green-theme {
417
+ .preview-header {
418
+ background: #67c23a;
419
+ }
420
+ .preview-sidebar {
421
+ background: #2d5a27;
422
+ }
423
+ .preview-content {
424
+ background: #f0f9ff;
425
+ }
426
+ }
427
+
428
+ &.glory-theme {
429
+ .preview-header {
430
+ background: #e6a23c;
431
+ }
432
+ .preview-sidebar {
433
+ background: #8b4513;
434
+ }
435
+ .preview-content {
436
+ background: #fff8e1;
437
+ }
438
+ }
439
+ }
440
+
441
+ .theme-name {
442
+ font-size: 14px;
443
+ font-weight: 500;
444
+ color: #333;
445
+ }
446
+ }
447
+ }
448
+
449
+ .layout-options {
450
+ display: flex;
451
+ flex-direction: column;
452
+ gap: 12px;
453
+
454
+ .layout-option {
455
+ display: flex;
456
+ align-items: center;
457
+ padding: 12px;
458
+ border: 2px solid #f0f0f0;
459
+ border-radius: 8px;
460
+ cursor: pointer;
461
+ transition: all 0.3s ease;
462
+
463
+ &:hover {
464
+ border-color: #409EFF;
465
+ transform: translateY(-1px);
466
+ box-shadow: 0 4px 12px rgba(64, 158, 255, 0.1);
467
+ }
468
+
469
+ &.active {
470
+ border-color: #409EFF;
471
+ background: rgba(64, 158, 255, 0.05);
472
+ box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
473
+ }
474
+
475
+ .layout-preview {
476
+ width: 60px;
477
+ height: 40px;
478
+ margin-right: 12px;
479
+ border-radius: 4px;
480
+ overflow: hidden;
481
+ position: relative;
482
+
483
+ .preview-header {
484
+ height: 8px;
485
+ background: #409EFF;
486
+ }
487
+
488
+ .preview-main {
489
+ position: absolute;
490
+ left: 0;
491
+ top: 8px;
492
+ width: 100%;
493
+ height: 32px;
494
+ display: flex;
495
+
496
+ .preview-sidebar {
497
+ background: #2c3e50;
498
+ }
499
+
500
+ .preview-content {
501
+ background: #ffffff;
502
+ }
503
+ }
504
+
505
+ &.vertical-layout {
506
+ .preview-header {
507
+ height: 8px;
508
+ background: #409EFF;
509
+ }
510
+
511
+ .preview-sidebar {
512
+ position: absolute;
513
+ left: 0;
514
+ top: 8px;
515
+ width: 12px;
516
+ height: 32px;
517
+ background: #2c3e50;
518
+ }
519
+
520
+ .preview-content {
521
+ position: absolute;
522
+ left: 12px;
523
+ top: 8px;
524
+ width: 48px;
525
+ height: 32px;
526
+ background: #ffffff;
527
+ }
528
+ }
529
+
530
+ &.horizontal-layout {
531
+ .preview-main {
532
+ .preview-sidebar {
533
+ width: 100%;
534
+ height: 8px;
535
+ }
536
+ .preview-content {
537
+ width: 100%;
538
+ height: 24px;
539
+ margin-top: 8px;
540
+ }
541
+ }
542
+ }
543
+ }
544
+
545
+ .layout-name {
546
+ font-size: 14px;
547
+ font-weight: 500;
548
+ color: #333;
549
+ }
550
+ }
551
+ }
552
+
553
+ .feature-options {
554
+ .feature-item {
555
+ display: flex;
556
+ justify-content: space-between;
557
+ align-items: center;
558
+ padding: 16px 0;
559
+ border-bottom: 1px solid #f0f0f0;
560
+
561
+ &:last-child {
562
+ border-bottom: none;
563
+ }
564
+
565
+ .feature-info {
566
+ flex: 1;
567
+ margin-right: 16px;
568
+
569
+ .feature-name {
570
+ display: block;
571
+ font-size: 14px;
572
+ font-weight: 500;
573
+ color: #333;
574
+ margin-bottom: 4px;
575
+ }
576
+
577
+ .feature-desc {
578
+ display: block;
579
+ font-size: 12px;
580
+ color: #999;
581
+ line-height: 1.4;
582
+ }
583
+ }
584
+ }
585
+ }
586
+ }
587
+ }
588
+ </style>
589
+ <style lang="scss">
590
+ .el-drawer__wrapper {
591
+ outline: none !important;
592
+
593
+ * {
594
+ outline: none !important;
595
+ }
596
+ }
597
+
598
+ .vab-color-picker {
599
+ .el-color-dropdown__link-btn {
600
+ display: none;
601
+ }
602
+ }
603
+ </style>