xto-fronted 0.4.71 → 0.4.73

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 (97) hide show
  1. package/dist/assets/404-CrBiLyvr.js +1 -0
  2. package/dist/assets/404-Cw_4ZCL6.css +1 -0
  3. package/dist/assets/_plugin-vue_export-helper-DlAUqK2U.js +1 -0
  4. package/dist/assets/index-9XqWtCGs.js +1 -0
  5. package/dist/assets/index-BBGKF0l-.js +1 -0
  6. package/dist/assets/index-BRR97dc6.js +1 -0
  7. package/dist/assets/index-BlRslYYI.css +1 -0
  8. package/dist/assets/index-BudArKxR.css +1 -0
  9. package/dist/assets/index-CFhWBbxk.css +1 -0
  10. package/dist/assets/index-CRJFI4iz.js +2 -0
  11. package/dist/assets/index-CmknWHK0.js +1 -0
  12. package/dist/assets/index-D7epoF1g.js +1 -0
  13. package/dist/assets/index-D9XBi20Y.css +1 -0
  14. package/dist/assets/index-DkkuYBgT.css +1 -0
  15. package/dist/assets/index-O9wpAB3Q.js +1 -0
  16. package/dist/assets/index-_aYxnqzF.css +1 -0
  17. package/dist/assets/index-rfC7s9zA.js +1 -0
  18. package/dist/assets/index-vfvEFrCH.css +1 -0
  19. package/dist/assets/vendor-42ANG6Sg.js +6 -0
  20. package/dist/assets/vue-vendor-D8SAgT8u.js +29 -0
  21. package/dist/assets/xto-base-BD3OH0V6.js +1 -0
  22. package/dist/assets/xto-base-CojW9IFO.css +1 -0
  23. package/dist/assets/xto-business--V1F5Gwb.css +1 -0
  24. package/dist/assets/xto-core-Boim7B0B.js +1 -0
  25. package/dist/assets/xto-data-CnAQAQH2.css +1 -0
  26. package/dist/assets/xto-data-DuG2QJrr.js +1 -0
  27. package/dist/assets/xto-feedback-C-ESp-Y1.css +1 -0
  28. package/dist/assets/xto-feedback-XZPSQcJN.js +1 -0
  29. package/dist/assets/xto-form-BmTGLIm_.js +1 -0
  30. package/dist/assets/xto-form-CrsyAjyr.css +1 -0
  31. package/dist/assets/xto-layout-D1stVnJI.css +1 -0
  32. package/dist/assets/xto-navigation-BRzSCpAw.css +1 -0
  33. package/dist/assets/xto-navigation-nPmjRi-J.js +1 -0
  34. package/dist/index.html +28 -0
  35. package/package.json +90 -87
  36. package/src/App.vue +30 -1
  37. package/src/assets/styles/_root.scss +141 -97
  38. package/src/assets/styles/_variables.scss +44 -19
  39. package/src/assets/styles/index.scss +267 -42
  40. package/src/components/Layout/Sidebar.vue +29 -10
  41. package/src/views/dashboard/index.vue +417 -155
  42. package/src/views/error/403.vue +251 -56
  43. package/src/views/error/404.vue +253 -56
  44. package/src/views/login/index.vue +586 -194
  45. package/src/views/system/menu/index.vue +403 -94
  46. package/src/views/system/role/index.vue +348 -69
  47. package/src/views/system/user/index.vue +402 -73
  48. package/dist/App.vue.d.ts +0 -2
  49. package/dist/api/auth.d.ts +0 -8
  50. package/dist/api/system.d.ts +0 -16
  51. package/dist/api/user.d.ts +0 -13
  52. package/dist/components/Layout/Footer.vue.d.ts +0 -2
  53. package/dist/components/Layout/Header.vue.d.ts +0 -5
  54. package/dist/components/Layout/MixTopMenu.vue.d.ts +0 -5
  55. package/dist/components/Layout/Sidebar.vue.d.ts +0 -11
  56. package/dist/components/Layout/SidebarMenuItem.vue.d.ts +0 -5
  57. package/dist/components/Layout/Tabs.vue.d.ts +0 -2
  58. package/dist/components/Layout/TopMenu.vue.d.ts +0 -5
  59. package/dist/components/Layout/index.vue.d.ts +0 -2
  60. package/dist/composables/useApp.d.ts +0 -29
  61. package/dist/composables/useAuth.d.ts +0 -6
  62. package/dist/composables/useForm.d.ts +0 -20
  63. package/dist/composables/useTable.d.ts +0 -29
  64. package/dist/directives/permission.d.ts +0 -4
  65. package/dist/enums/index.d.ts +0 -32
  66. package/dist/index-BgbSp2mz.js +0 -372
  67. package/dist/index-By874kXD.js +0 -142
  68. package/dist/index-COz0Cbj7.js +0 -345
  69. package/dist/index-CgbSCzIp.js +0 -3159
  70. package/dist/index-CzOd0mGb.js +0 -475
  71. package/dist/index.d.ts +0 -54
  72. package/dist/index.es.js +0 -91
  73. package/dist/index.umd.js +0 -1
  74. package/dist/main.d.ts +0 -0
  75. package/dist/router/dynamicRoutes.d.ts +0 -30
  76. package/dist/router/guards.d.ts +0 -17
  77. package/dist/router/index.d.ts +0 -6
  78. package/dist/router/layoutRoute.d.ts +0 -18
  79. package/dist/router/staticRoutes.d.ts +0 -2
  80. package/dist/stores/app.d.ts +0 -93
  81. package/dist/stores/auth.d.ts +0 -41
  82. package/dist/stores/index.d.ts +0 -9
  83. package/dist/stores/menu.d.ts +0 -77
  84. package/dist/stores/user.d.ts +0 -92
  85. package/dist/style.css +0 -1
  86. package/dist/utils/auth.d.ts +0 -27
  87. package/dist/utils/config.d.ts +0 -30
  88. package/dist/utils/permission.d.ts +0 -18
  89. package/dist/utils/request.d.ts +0 -24
  90. package/dist/utils/storage.d.ts +0 -24
  91. package/dist/views/dashboard/index.vue.d.ts +0 -2
  92. package/dist/views/error/403.vue.d.ts +0 -2
  93. package/dist/views/error/404.vue.d.ts +0 -2
  94. package/dist/views/login/index.vue.d.ts +0 -4
  95. package/dist/views/system/menu/index.vue.d.ts +0 -4
  96. package/dist/views/system/role/index.vue.d.ts +0 -4
  97. package/dist/views/system/user/index.vue.d.ts +0 -4
@@ -15,7 +15,7 @@
15
15
  @use 'dark';
16
16
 
17
17
  // ==============================================
18
- // 全局通用样式
18
+ // 全局通用样式(企业级增强)
19
19
  // ==============================================
20
20
 
21
21
  // 文字截断
@@ -33,6 +33,13 @@
33
33
  overflow: hidden;
34
34
  }
35
35
 
36
+ .text-ellipsis-3 {
37
+ display: -webkit-box;
38
+ -webkit-line-clamp: 3;
39
+ -webkit-box-orient: vertical;
40
+ overflow: hidden;
41
+ }
42
+
36
43
  // Flex 布局
37
44
  .flex {
38
45
  display: flex;
@@ -50,6 +57,18 @@
50
57
  justify-content: space-between;
51
58
  }
52
59
 
60
+ .flex-start {
61
+ display: flex;
62
+ align-items: center;
63
+ justify-content: flex-start;
64
+ }
65
+
66
+ .flex-end {
67
+ display: flex;
68
+ align-items: center;
69
+ justify-content: flex-end;
70
+ }
71
+
53
72
  .flex-wrap {
54
73
  flex-wrap: wrap;
55
74
  }
@@ -58,6 +77,31 @@
58
77
  flex: 1;
59
78
  }
60
79
 
80
+ .flex-shrink-0 {
81
+ flex-shrink: 0;
82
+ }
83
+
84
+ // 方向
85
+ .flex-col {
86
+ display: flex;
87
+ flex-direction: column;
88
+ }
89
+
90
+ .flex-col-center {
91
+ display: flex;
92
+ flex-direction: column;
93
+ align-items: center;
94
+ }
95
+
96
+ // Gap 间距(8px 网格系统)
97
+ .gap-4 { gap: 4px; }
98
+ .gap-8 { gap: 8px; }
99
+ .gap-12 { gap: 12px; }
100
+ .gap-16 { gap: 16px; }
101
+ .gap-20 { gap: 20px; }
102
+ .gap-24 { gap: 24px; }
103
+ .gap-32 { gap: 32px; }
104
+
61
105
  // 文字对齐
62
106
  .text-left {
63
107
  text-align: left;
@@ -92,6 +136,14 @@
92
136
  color: var(--color-info);
93
137
  }
94
138
 
139
+ .text-secondary {
140
+ color: var(--color-text-secondary);
141
+ }
142
+
143
+ .text-placeholder {
144
+ color: var(--color-text-placeholder);
145
+ }
146
+
95
147
  // 背景
96
148
  .bg-primary {
97
149
  background-color: var(--color-primary);
@@ -109,81 +161,254 @@
109
161
  background-color: var(--color-danger);
110
162
  }
111
163
 
112
- // 间距
113
- .mt-10 {
114
- margin-top: 10px;
115
- }
116
-
117
- .mt-20 {
118
- margin-top: 20px;
119
- }
120
-
121
- .mb-10 {
122
- margin-bottom: 10px;
164
+ .bg-page {
165
+ background-color: var(--bg-color-page);
123
166
  }
124
167
 
125
- .mb-20 {
126
- margin-bottom: 20px;
127
- }
128
-
129
- .ml-10 {
130
- margin-left: 10px;
131
- }
132
-
133
- .mr-10 {
134
- margin-right: 10px;
168
+ .bg-card {
169
+ background-color: var(--bg-color);
135
170
  }
136
171
 
137
- .p-10 {
138
- padding: 10px;
139
- }
172
+ // 间距(8px 网格系统)
173
+ .mt-4 { margin-top: 4px; }
174
+ .mt-8 { margin-top: 8px; }
175
+ .mt-12 { margin-top: 12px; }
176
+ .mt-16 { margin-top: 16px; }
177
+ .mt-20 { margin-top: 20px; }
178
+ .mt-24 { margin-top: 24px; }
179
+ .mt-32 { margin-top: 32px; }
180
+
181
+ .mb-4 { margin-bottom: 4px; }
182
+ .mb-8 { margin-bottom: 8px; }
183
+ .mb-12 { margin-bottom: 12px; }
184
+ .mb-16 { margin-bottom: 16px; }
185
+ .mb-20 { margin-bottom: 20px; }
186
+ .mb-24 { margin-bottom: 24px; }
187
+ .mb-32 { margin-bottom: 32px; }
188
+
189
+ .ml-4 { margin-left: 4px; }
190
+ .ml-8 { margin-left: 8px; }
191
+ .ml-12 { margin-left: 12px; }
192
+ .ml-16 { margin-left: 16px; }
193
+
194
+ .mr-4 { margin-right: 4px; }
195
+ .mr-8 { margin-right: 8px; }
196
+ .mr-12 { margin-right: 12px; }
197
+ .mr-16 { margin-right: 16px; }
198
+
199
+ .p-4 { padding: 4px; }
200
+ .p-8 { padding: 8px; }
201
+ .p-12 { padding: 12px; }
202
+ .p-16 { padding: 16px; }
203
+ .p-20 { padding: 20px; }
204
+ .p-24 { padding: 24px; }
205
+ .p-32 { padding: 32px; }
206
+
207
+ .px-4 { padding-left: 4px; padding-right: 4px; }
208
+ .px-8 { padding-left: 8px; padding-right: 8px; }
209
+ .px-12 { padding-left: 12px; padding-right: 12px; }
210
+ .px-16 { padding-left: 16px; padding-right: 16px; }
211
+ .px-24 { padding-left: 24px; padding-right: 24px; }
212
+
213
+ .py-4 { padding-top: 4px; padding-bottom: 4px; }
214
+ .py-8 { padding-top: 8px; padding-bottom: 8px; }
215
+ .py-12 { padding-top: 12px; padding-bottom: 12px; }
216
+ .py-16 { padding-top: 16px; padding-bottom: 16px; }
217
+ .py-24 { padding-top: 24px; padding-bottom: 24px; }
218
+
219
+ // 卡片容器(企业级)
220
+ .card {
221
+ background-color: var(--bg-color);
222
+ border-radius: var(--border-radius-large);
223
+ box-shadow: var(--box-shadow-card);
224
+ padding: var(--spacing-lg);
225
+ transition: box-shadow 0.3s ease;
140
226
 
141
- .p-20 {
142
- padding: 20px;
227
+ &:hover {
228
+ box-shadow: var(--box-shadow-card-hover);
229
+ }
143
230
  }
144
231
 
145
- // 卡片容器
146
- .card {
232
+ .card-flat {
147
233
  background-color: var(--bg-color);
148
- border-radius: var(--border-radius-base);
149
- box-shadow: var(--box-shadow-light);
150
- padding: var(--spacing-md);
234
+ border-radius: var(--border-radius-large);
235
+ padding: var(--spacing-lg);
236
+ border: 1px solid var(--color-border-lighter);
151
237
  }
152
238
 
153
239
  // 页面容器
154
240
  .page-container {
155
- padding: var(--spacing-md);
241
+ padding: var(--spacing-lg);
156
242
  min-height: 100%;
243
+ background: var(--bg-color-page);
157
244
  }
158
245
 
159
- // 搜索栏
246
+ // 搜索栏(企业级)
160
247
  .search-bar {
161
248
  display: flex;
162
249
  flex-wrap: wrap;
163
- gap: var(--spacing-sm);
164
- margin-bottom: var(--spacing-md);
250
+ gap: var(--spacing-md);
251
+ margin-bottom: var(--spacing-lg);
252
+ padding: var(--spacing-lg);
253
+ background: var(--bg-color);
254
+ border-radius: var(--border-radius-large);
255
+ box-shadow: var(--box-shadow-card);
165
256
  }
166
257
 
167
- // 工具栏
258
+ // 工具栏(企业级)
168
259
  .toolbar {
169
260
  display: flex;
170
261
  align-items: center;
171
262
  justify-content: space-between;
172
- margin-bottom: var(--spacing-md);
263
+ padding: var(--spacing-md) var(--spacing-lg);
264
+ border-bottom: 1px solid var(--color-border-lighter);
265
+ }
266
+
267
+ .toolbar-left {
268
+ display: flex;
269
+ align-items: center;
270
+ gap: var(--spacing-sm);
271
+ }
272
+
273
+ .toolbar-right {
274
+ display: flex;
275
+ align-items: center;
276
+ gap: var(--spacing-sm);
173
277
  }
174
278
 
175
- // 表格容器
279
+ // 表格容器(企业级)
176
280
  .table-container {
177
281
  background-color: var(--bg-color);
178
- border-radius: var(--border-radius-base);
179
- padding: var(--spacing-md);
282
+ border-radius: var(--border-radius-large);
283
+ box-shadow: var(--box-shadow-card);
284
+ overflow: hidden;
180
285
  }
181
286
 
182
287
  // 分页容器
183
288
  .pagination-container {
184
289
  display: flex;
185
290
  justify-content: flex-end;
186
- margin-top: var(--spacing-md);
291
+ padding: var(--spacing-md) var(--spacing-lg);
292
+ border-top: 1px solid var(--color-border-lighter);
293
+ }
294
+
295
+ // 标签徽章
296
+ .badge {
297
+ display: inline-flex;
298
+ align-items: center;
299
+ justify-content: center;
300
+ min-width: 20px;
301
+ height: 20px;
302
+ padding: 0 6px;
303
+ font-size: 12px;
304
+ font-weight: 500;
305
+ border-radius: 10px;
306
+ background: var(--color-fill);
307
+ color: var(--color-text-secondary);
308
+ }
309
+
310
+ .badge-primary {
311
+ background: var(--color-primary-light-6);
312
+ color: var(--color-primary);
313
+ }
314
+
315
+ .badge-success {
316
+ background: var(--color-success-lighter);
317
+ color: var(--color-success);
318
+ }
319
+
320
+ .badge-warning {
321
+ background: var(--color-warning-lighter);
322
+ color: var(--color-warning);
323
+ }
324
+
325
+ .badge-danger {
326
+ background: var(--color-danger-lighter);
327
+ color: var(--color-danger);
328
+ }
329
+
330
+ // 分隔线
331
+ .divider {
332
+ height: 1px;
333
+ background: var(--color-border-lighter);
334
+ margin: var(--spacing-md) 0;
335
+ }
336
+
337
+ .divider-vertical {
338
+ width: 1px;
339
+ height: 100%;
340
+ background: var(--color-border-lighter);
341
+ margin: 0 var(--spacing-md);
342
+ }
343
+
344
+ // 空状态
345
+ .empty-state {
346
+ display: flex;
347
+ flex-direction: column;
348
+ align-items: center;
349
+ justify-content: center;
350
+ padding: 60px 20px;
351
+ color: var(--color-text-placeholder);
352
+
353
+ .empty-icon {
354
+ width: 64px;
355
+ height: 64px;
356
+ margin-bottom: 16px;
357
+ opacity: 0.5;
358
+ }
359
+
360
+ .empty-text {
361
+ font-size: 14px;
362
+ }
363
+ }
364
+
365
+ // 加载状态
366
+ .loading-state {
367
+ display: flex;
368
+ flex-direction: column;
369
+ align-items: center;
370
+ justify-content: center;
371
+ padding: 60px 20px;
372
+
373
+ .loading-spinner {
374
+ width: 32px;
375
+ height: 32px;
376
+ border: 3px solid var(--color-border-lighter);
377
+ border-top-color: var(--color-primary);
378
+ border-radius: 50%;
379
+ animation: spin 0.8s linear infinite;
380
+ }
381
+
382
+ .loading-text {
383
+ margin-top: 16px;
384
+ font-size: 14px;
385
+ color: var(--color-text-secondary);
386
+ }
387
+ }
388
+
389
+ @keyframes spin {
390
+ to { transform: rotate(360deg); }
391
+ }
392
+
393
+ // 链接样式
394
+ .link {
395
+ color: var(--color-primary);
396
+ text-decoration: none;
397
+ transition: color 0.2s ease;
398
+
399
+ &:hover {
400
+ color: var(--color-primary-dark-1);
401
+ }
402
+ }
403
+
404
+ .link-underline {
405
+ color: var(--color-primary);
406
+ text-decoration: underline;
407
+ text-underline-offset: 2px;
408
+
409
+ &:hover {
410
+ color: var(--color-primary-dark-1);
411
+ }
187
412
  }
188
413
 
189
414
  // ==============================================
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { computed, ref, watch, onMounted } from 'vue'
2
+ import { computed, ref, watch } from 'vue'
3
3
  import { useRoute, useRouter } from 'vue-router'
4
4
  import { useMenuStore } from '@/stores/menu'
5
5
  import { useUserStore } from '@/stores/user'
@@ -43,19 +43,38 @@ watch(openedMenus, (val) => {
43
43
  local.set(OPENED_MENUS_KEY, val)
44
44
  }, { deep: true })
45
45
 
46
- // 根据当前路由自动展开父菜单
47
- onMounted(() => {
48
- const path = route.path
49
- // 找到当前路由对应的父菜单并展开
50
- for (const menu of displayMenuList.value) {
46
+ // 递归查找当前路由对应的父菜单并展开
47
+ const findAndOpenParentMenus = (menus: any[], path: string, parentUrls: string[] = []) => {
48
+ for (const menu of menus) {
51
49
  if (menu.children?.length) {
52
- const hasActiveChild = menu.children.some((child: any) => path.startsWith(child.menuUrl))
53
- if (hasActiveChild && !openedMenus.value.includes(menu.menuUrl)) {
54
- openedMenus.value.push(menu.menuUrl)
50
+ // 检查当前菜单的直接子菜单是否匹配
51
+ const hasDirectMatch = menu.children.some((child: any) => path === child.menuUrl || path.startsWith(child.menuUrl + '/'))
52
+
53
+ if (hasDirectMatch) {
54
+ // 找到匹配,展开所有父菜单
55
+ for (const parentUrl of parentUrls) {
56
+ if (!openedMenus.value.includes(parentUrl)) {
57
+ openedMenus.value.push(parentUrl)
58
+ }
59
+ }
60
+ // 展开当前菜单
61
+ if (!openedMenus.value.includes(menu.menuUrl)) {
62
+ openedMenus.value.push(menu.menuUrl)
63
+ }
55
64
  }
65
+
66
+ // 递归查找更深层级
67
+ findAndOpenParentMenus(menu.children, path, [...parentUrls, menu.menuUrl])
56
68
  }
57
69
  }
58
- })
70
+ }
71
+
72
+ // 监听路由变化和菜单列表变化
73
+ watch([() => route.path, displayMenuList], ([path, menus]) => {
74
+ if (menus.length > 0) {
75
+ findAndOpenParentMenus(menus, path)
76
+ }
77
+ }, { immediate: true })
59
78
 
60
79
  // 菜单主题相关
61
80
  const menuBgColor = computed(() => appStore.isDark ? '#1d1e1f' : '#fff')