befly-admin-ui 1.9.9 → 1.9.10

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.
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="page-table-detail page-table">
2
+ <div :class="['page-table-detail', 'page-table', { 'page-table--with-pagination': props.isPagination }]">
3
3
  <div class="main-tool">
4
4
  <div class="left">
5
5
  <slot name="toolLeft" :reload="reload" :current-row="$Data.currentRow"></slot>
@@ -32,7 +32,7 @@
32
32
  </div>
33
33
  </div>
34
34
 
35
- <div class="main-page">
35
+ <div v-if="props.isPagination" class="main-page">
36
36
  <TPagination :current-page="$Data.pager.currentPage" :page-size="$Data.pager.limit" :total="$Data.pager.total" align="right" :layout="paginationLayout" @current-change="onPageChange" @page-size-change="onPageSizeChange" />
37
37
  </div>
38
38
 
@@ -1,58 +1,57 @@
1
1
  <template>
2
2
  <div class="layout-wrapper">
3
- <!-- 左侧边栏:Logo + 菜单 + 底部操作 -->
3
+ <!-- 左侧边栏:菜单面板 + 用户面板 -->
4
4
  <div class="layout-sidebar">
5
- <!-- Logo 区域 -->
6
- <div class="sidebar-logo">
7
- <div class="logo-icon">
8
- <AppIcon style="width: 24px; height: 24px; color: var(--primary-color)" />
5
+ <div class="sidebar-menu-panel">
6
+ <!-- Logo 区域 -->
7
+ <div class="sidebar-logo">
8
+ <div class="logo-icon">
9
+ <AppIcon style="width: 24px; height: 24px; color: var(--primary-color)" />
10
+ </div>
11
+ <h2>{{ $Config.appTitle }}</h2>
9
12
  </div>
10
- <h2>{{ $Config.appTitle }}</h2>
11
- </div>
12
13
 
13
- <!-- 菜单区域 -->
14
- <div class="sidebar-menu">
15
- <t-menu v-model:value="$Data.currentMenuKey" v-model:expanded="$Data.expandedKeys" width="220px" @change="onMenuClick">
16
- <template v-for="menu in $Data.userMenus" :key="menu.id">
17
- <!-- 无子菜单 -->
18
- <t-menu-item v-if="!menu.children || menu.children.length === 0" :value="menu.path">
19
- <template #icon>
20
- <HomeIcon v-if="menu.path === '/dashboard' || menu.path === '/core/' || menu.path === '/core'" style="margin-right: 8px" />
21
- <ControlPlatformIcon v-else style="margin-right: 8px" />
22
- </template>
23
- {{ menu.name }}
24
- </t-menu-item>
25
- <!-- 有子菜单 -->
26
- <t-submenu v-else :value="String(menu.id)" :title="menu.name">
27
- <template #icon>
28
- <AppIcon style="margin-right: 8px" />
29
- </template>
30
- <t-menu-item v-for="child in menu.children" :key="child.id" :value="child.path">
14
+ <!-- 菜单区域 -->
15
+ <div class="sidebar-menu">
16
+ <t-menu v-model:value="$Data.currentMenuKey" v-model:expanded="$Data.expandedKeys" width="220px" @change="onMenuClick">
17
+ <template v-for="menu in $Data.userMenus" :key="menu.id">
18
+ <!-- 无子菜单 -->
19
+ <t-menu-item v-if="!menu.children || menu.children.length === 0" :value="menu.path">
31
20
  <template #icon>
32
- <ControlPlatformIcon style="margin-right: 8px" />
21
+ <HomeIcon v-if="menu.path === '/dashboard' || menu.path === '/core/' || menu.path === '/core'" style="margin-right: 8px" />
22
+ <ControlPlatformIcon v-else style="margin-right: 8px" />
33
23
  </template>
34
- {{ child.name }}
24
+ {{ menu.name }}
35
25
  </t-menu-item>
36
- </t-submenu>
37
- </template>
38
- </t-menu>
26
+ <!-- 有子菜单 -->
27
+ <t-submenu v-else :value="String(menu.id)" :title="menu.name">
28
+ <template #icon>
29
+ <AppIcon style="margin-right: 8px" />
30
+ </template>
31
+ <t-menu-item v-for="child in menu.children" :key="child.id" :value="child.path">
32
+ <template #icon>
33
+ <ControlPlatformIcon style="margin-right: 8px" />
34
+ </template>
35
+ {{ child.name }}
36
+ </t-menu-item>
37
+ </t-submenu>
38
+ </template>
39
+ </t-menu>
40
+ </div>
39
41
  </div>
40
- </div>
41
42
 
42
- <!-- 右侧内容区域 -->
43
- <div class="layout-main">
44
- <div class="main-toolbar">
45
- <TDropdown trigger="click" placement="bottom-right" @click="onUserDropdownAction">
46
- <div class="toolbar-user">
47
- <div class="toolbar-user-avatar">
43
+ <div class="sidebar-user-panel">
44
+ <TDropdown class="sidebar-user-dropdown" trigger="click" placement="top-right" @click="onUserDropdownAction">
45
+ <div class="sidebar-user">
46
+ <div class="sidebar-user-avatar">
48
47
  <img v-if="$Data.userInfo.avatar" :src="$Data.userInfo.avatar" alt="avatar" />
49
48
  <UserIcon v-else style="width: 16px; height: 16px; color: #fff" />
50
49
  </div>
51
- <div class="toolbar-user-info">
50
+ <div class="sidebar-user-info">
52
51
  <span class="user-name">{{ $Data.userInfo.nickname || "管理员" }}</span>
53
52
  <span class="user-role">{{ $Data.userInfo.role || "超级管理员" }}</span>
54
53
  </div>
55
- <ChevronDownIcon class="toolbar-user-arrow" style="width: 16px; height: 16px" />
54
+ <ChevronDownIcon class="sidebar-user-arrow" style="width: 16px; height: 16px" />
56
55
  </div>
57
56
  <TDropdownMenu slot="dropdown">
58
57
  <TDropdownItem value="password">
@@ -66,7 +65,10 @@
66
65
  </TDropdownMenu>
67
66
  </TDropdown>
68
67
  </div>
68
+ </div>
69
69
 
70
+ <!-- 右侧内容区域 -->
71
+ <div class="layout-main">
70
72
  <div class="main-content">
71
73
  <RouterView />
72
74
  </div>
@@ -385,87 +387,60 @@ watch(
385
387
  .layout-sidebar {
386
388
  width: var(--sidebar-width);
387
389
  flex-shrink: 0;
390
+ min-height: 0;
388
391
  display: flex;
389
392
  flex-direction: column;
390
- background: var(--bg-color-container);
391
- border-radius: var(--border-radius-large);
392
- box-shadow: var(--shadow-1);
393
- overflow: hidden;
393
+ gap: var(--layout-gap);
394
394
 
395
- // Logo 区域
396
- .sidebar-logo {
395
+ .sidebar-menu-panel {
396
+ flex: 1;
397
+ min-height: 0;
397
398
  display: flex;
398
- align-items: center;
399
- gap: var(--spacing-sm);
400
- padding: var(--spacing-md) var(--spacing-md);
401
- border-bottom: 1px solid var(--border-color-light);
399
+ flex-direction: column;
400
+ background: var(--bg-color-container);
401
+ border-radius: var(--border-radius-large);
402
+ box-shadow: var(--shadow-1);
403
+ overflow: hidden;
402
404
 
403
- .logo-icon {
404
- width: 36px;
405
- height: 36px;
406
- min-width: 36px;
405
+ .sidebar-logo {
407
406
  display: flex;
408
407
  align-items: center;
409
- justify-content: center;
410
- background: var(--primary-color-light);
411
- border-radius: var(--border-radius);
412
- }
408
+ gap: var(--spacing-sm);
409
+ padding: var(--spacing-md) var(--spacing-md);
410
+ border-bottom: 1px solid var(--border-color-light);
411
+
412
+ .logo-icon {
413
+ width: 36px;
414
+ height: 36px;
415
+ min-width: 36px;
416
+ display: flex;
417
+ align-items: center;
418
+ justify-content: center;
419
+ background: var(--primary-color-light);
420
+ border-radius: var(--border-radius);
421
+ }
413
422
 
414
- h2 {
415
- margin: 0;
416
- font-size: var(--font-size-md);
417
- font-weight: var(--font-weight-semibold);
418
- color: var(--text-primary);
419
- white-space: nowrap;
420
- overflow: hidden;
423
+ h2 {
424
+ margin: 0;
425
+ font-size: var(--font-size-md);
426
+ font-weight: var(--font-weight-semibold);
427
+ color: var(--text-primary);
428
+ white-space: nowrap;
429
+ overflow: hidden;
430
+ }
421
431
  }
422
- }
423
432
 
424
- // 菜单区域
425
- .sidebar-menu {
426
- flex: 1;
427
- overflow-y: auto;
428
- padding: var(--spacing-xs) 0;
433
+ .sidebar-menu {
434
+ flex: 1;
435
+ min-height: 0;
436
+ overflow-y: auto;
437
+ padding: var(--spacing-xs) 0;
429
438
 
430
- :deep(.t-menu) {
431
- border-right: none;
432
- background: transparent;
439
+ :deep(.t-menu) {
440
+ border-right: none;
441
+ background: transparent;
433
442
 
434
- // 子菜单项(非父级的菜单项)
435
- .t-menu__item {
436
- border-radius: var(--border-radius);
437
- transition: all var(--transition-fast);
438
- position: relative;
439
-
440
- &:hover {
441
- background-color: var(--bg-color-hover);
442
- }
443
-
444
- &.t-is-active {
445
- background-color: var(--primary-color-light);
446
- color: var(--primary-color);
447
- font-weight: var(--font-weight-medium);
448
-
449
- &::before {
450
- content: "";
451
- position: absolute;
452
- left: 0;
453
- top: 50%;
454
- transform: translateY(-50%);
455
- width: var(--menu-active-indicator);
456
- height: 60%;
457
- background-color: var(--primary-color);
458
- border-radius: 0 2px 2px 0;
459
- }
460
- }
461
- }
462
-
463
- // 父级菜单样式(有子菜单的)
464
- .t-submenu {
465
- // 父级菜单的 header(不显示指示条)
466
- > .t-menu__item,
467
- > .t-submenu__header {
468
- // margin: 2px var(--spacing-sm);
443
+ .t-menu__item {
469
444
  border-radius: var(--border-radius);
470
445
  transition: all var(--transition-fast);
471
446
  position: relative;
@@ -474,44 +449,70 @@ watch(
474
449
  background-color: var(--bg-color-hover);
475
450
  }
476
451
 
477
- // 父级菜单不显示指示条和背景
478
- &::before {
479
- display: none !important;
452
+ &.t-is-active {
453
+ background-color: var(--primary-color-light);
454
+ color: var(--primary-color);
455
+ font-weight: var(--font-weight-medium);
456
+
457
+ &::before {
458
+ content: "";
459
+ position: absolute;
460
+ left: 0;
461
+ top: 50%;
462
+ transform: translateY(-50%);
463
+ width: var(--menu-active-indicator);
464
+ height: 60%;
465
+ background-color: var(--primary-color);
466
+ border-radius: 0 2px 2px 0;
467
+ }
480
468
  }
469
+ }
481
470
 
482
- &.t-is-active {
483
- background-color: transparent !important;
471
+ .t-submenu {
472
+ > .t-menu__item,
473
+ > .t-submenu__header {
474
+ border-radius: var(--border-radius);
475
+ transition: all var(--transition-fast);
476
+ position: relative;
477
+
478
+ &:hover {
479
+ background-color: var(--bg-color-hover);
480
+ }
481
+
482
+ &::before {
483
+ display: none !important;
484
+ }
485
+
486
+ &.t-is-active {
487
+ background-color: transparent !important;
488
+ }
484
489
  }
485
490
  }
486
491
  }
487
492
  }
488
493
  }
489
- }
490
494
 
491
- // 右侧主内容区域
492
- .layout-main {
493
- flex: 1;
494
- min-width: 0;
495
- display: flex;
496
- flex-direction: column;
497
- gap: var(--layout-gap);
498
- overflow: hidden;
499
-
500
- .main-toolbar {
495
+ .sidebar-user-panel {
501
496
  flex-shrink: 0;
497
+ height: var(--pagination-height);
502
498
  display: flex;
503
- justify-content: flex-end;
504
499
  align-items: center;
505
- padding: var(--spacing-sm) var(--spacing-md);
500
+ padding: 0 var(--spacing-md);
506
501
  background: var(--bg-color-container);
507
502
  border-radius: var(--border-radius-large);
508
503
  box-shadow: var(--shadow-1);
509
504
 
510
- .toolbar-user {
505
+ .sidebar-user-dropdown {
506
+ display: block;
507
+ width: 100%;
508
+ }
509
+
510
+ .sidebar-user {
511
+ width: 100%;
511
512
  display: flex;
512
513
  align-items: center;
513
514
  gap: var(--spacing-sm);
514
- padding: 4px 8px;
515
+ padding: var(--spacing-xs);
515
516
  border-radius: var(--border-radius);
516
517
  cursor: pointer;
517
518
  transition: background-color var(--transition-fast);
@@ -521,7 +522,7 @@ watch(
521
522
  }
522
523
  }
523
524
 
524
- .toolbar-user-avatar {
525
+ .sidebar-user-avatar {
525
526
  width: 36px;
526
527
  height: 36px;
527
528
  min-width: 36px;
@@ -531,7 +532,6 @@ watch(
531
532
  background: var(--primary-color);
532
533
  border-radius: 50%;
533
534
  overflow: hidden;
534
- flex-shrink: 0;
535
535
 
536
536
  img {
537
537
  width: 100%;
@@ -540,7 +540,8 @@ watch(
540
540
  }
541
541
  }
542
542
 
543
- .toolbar-user-info {
543
+ .sidebar-user-info {
544
+ flex: 1;
544
545
  min-width: 0;
545
546
  display: flex;
546
547
  flex-direction: column;
@@ -551,6 +552,8 @@ watch(
551
552
  color: var(--text-primary);
552
553
  line-height: 1.3;
553
554
  white-space: nowrap;
555
+ overflow: hidden;
556
+ text-overflow: ellipsis;
554
557
  }
555
558
 
556
559
  .user-role {
@@ -558,14 +561,25 @@ watch(
558
561
  color: var(--text-placeholder);
559
562
  line-height: 1.3;
560
563
  white-space: nowrap;
564
+ overflow: hidden;
565
+ text-overflow: ellipsis;
561
566
  }
562
567
  }
563
568
 
564
- .toolbar-user-arrow {
569
+ .sidebar-user-arrow {
565
570
  color: var(--text-placeholder);
566
571
  flex-shrink: 0;
567
572
  }
568
573
  }
574
+ }
575
+
576
+ // 右侧主内容区域
577
+ .layout-main {
578
+ flex: 1;
579
+ min-width: 0;
580
+ display: flex;
581
+ flex-direction: column;
582
+ overflow: hidden;
569
583
 
570
584
  .main-content {
571
585
  flex: 1;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "befly-admin-ui",
3
- "version": "1.9.9",
4
- "gitHead": "990aee4744b2c52e24c1a8c7a6cbee06b7d31833",
3
+ "version": "1.9.10",
4
+ "gitHead": "50fca5a7f581822abfdc886fcd77f2fce3db47ca",
5
5
  "private": false,
6
6
  "description": "Befly - 管理后台功能组件",
7
7
  "keywords": [
@@ -45,5 +45,11 @@
45
45
  "dev": "vite",
46
46
  "build": "vite build",
47
47
  "preview": "vite preview"
48
+ },
49
+ "dependencies": {
50
+ "tdesign-icons-vue-next": "^0.4.4",
51
+ "tdesign-vue-next": "^1.19.2",
52
+ "vue": "^3.5.34",
53
+ "vue-router": "^5.0.6"
48
54
  }
49
55
  }
@@ -108,10 +108,10 @@ import { withDefaultColumns } from "befly-admin-ui/utils/withDefaultColumns";
108
108
 
109
109
  const $Data = reactive({
110
110
  columns: withDefaultColumns([
111
- { colKey: "productName", title: "产品名称", fixed: "left", width: 160 },
111
+ { colKey: "productName", title: "产品名称" },
112
112
  { colKey: "productCode", title: "产品代号", width: 150 },
113
113
  { colKey: "productVersion", title: "产品版本", width: 130 },
114
- { colKey: "pageName", title: "页面名称", fixed: "left", width: 160 },
114
+ { colKey: "pageName", title: "页面名称" },
115
115
  { colKey: "pagePath", title: "页面路径", width: 220, ellipsis: true },
116
116
  { colKey: "errorType", title: "错误类型", width: 120 },
117
117
  { colKey: "deviceType", title: "设备类型", width: 110 },
@@ -25,9 +25,7 @@
25
25
  </template>
26
26
 
27
27
  <template #thumbnail="{ row }">
28
- <div class="image-cell">
29
- <TImage class="image-thumb" :src="row.url" :alt="row.fileName" fit="cover" gallery overlay-trigger="hover" />
30
- </div>
28
+ <TImage class="table-image" :src="row.url" :alt="row.fileName" fit="cover" shape="round" gallery overlay-trigger="hover" />
31
29
  </template>
32
30
 
33
31
  <template #fileSize="{ row }">
@@ -101,7 +99,7 @@ const $Data = reactive({
101
99
  keyword: "",
102
100
  columns: withDefaultColumns([
103
101
  { colKey: "thumbnail", title: "缩略图", width: 96 },
104
- { colKey: "fileName", title: "文件名", fixed: "left", minWidth: 220 },
102
+ { colKey: "fileName", title: "文件名" },
105
103
  { colKey: "fileExt", title: "扩展名", width: 100, format: formatFileExt },
106
104
  { colKey: "fileSize", title: "大小", width: 110 },
107
105
  { colKey: "isImage", title: "类型", width: 90 },
@@ -214,20 +212,6 @@ function onUploadSuccess(res, reload) {
214
212
  }
215
213
  }
216
214
 
217
- .image-cell {
218
- display: flex;
219
- align-items: center;
220
- width: 100%;
221
- }
222
-
223
- .image-thumb {
224
- width: 100%;
225
- height: 56px;
226
- border-radius: 10px;
227
- overflow: hidden;
228
- background: #f3f6fb;
229
- }
230
-
231
215
  .gallery-detail {
232
216
  display: flex;
233
217
  flex-direction: column;