befly-admin 3.4.29 → 3.4.31

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.
package/bunfig.toml CHANGED
@@ -1,4 +1,2 @@
1
1
  [install]
2
2
  linker = "isolated"
3
-
4
- publicHoistPattern = ["@types*", "*eslint*", "@opentiny/*"]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "befly-admin",
3
- "version": "3.4.29",
3
+ "version": "3.4.31",
4
4
  "description": "Befly Admin - 基于 Vue3 + OpenTiny Vue 的后台管理系统",
5
5
  "type": "module",
6
6
  "private": false,
@@ -29,39 +29,14 @@
29
29
  "sync:admin": "bunx befly sync:admin"
30
30
  },
31
31
  "dependencies": {
32
- "@opentiny/vue-button": "~3.27.0",
33
- "@opentiny/vue-checkbox": "~3.27.0",
34
- "@opentiny/vue-checkbox-group": "~3.27.0",
35
- "@opentiny/vue-dialog-box": "~3.27.0",
36
- "@opentiny/vue-dropdown": "~3.27.0",
37
- "@opentiny/vue-dropdown-item": "~3.27.0",
38
- "@opentiny/vue-dropdown-menu": "~3.27.0",
39
- "@opentiny/vue-form": "~3.27.0",
40
- "@opentiny/vue-form-item": "~3.27.0",
41
- "@opentiny/vue-grid": "~3.27.0",
42
- "@opentiny/vue-grid-column": "~3.27.0",
43
- "@opentiny/vue-icon": "~3.27.0",
44
- "@opentiny/vue-input": "~3.27.0",
45
- "@opentiny/vue-loading": "~3.27.0",
46
- "@opentiny/vue-message": "~3.27.0",
47
- "@opentiny/vue-modal": "~3.27.0",
48
- "@opentiny/vue-notify": "~3.27.0",
49
- "@opentiny/vue-numeric": "~3.27.0",
50
- "@opentiny/vue-pager": "~3.27.0",
51
- "@opentiny/vue-progress": "~3.27.0",
52
- "@opentiny/vue-radio": "~3.27.0",
53
- "@opentiny/vue-radio-group": "~3.27.0",
54
- "@opentiny/vue-search": "~3.27.0",
55
- "@opentiny/vue-select": "~3.27.0",
56
- "@opentiny/vue-tag": "~3.27.0",
57
- "@opentiny/vue-tree": "~3.27.0",
32
+ "@befly-addon/admin": "1.0.33",
58
33
  "axios": "^1.13.2",
59
34
  "pinia": "^3.0.4",
35
+ "tdesign-vue-next": "^1.10.6",
60
36
  "vue": "^3.5.22",
61
37
  "vue-router": "^4.6.3"
62
38
  },
63
39
  "devDependencies": {
64
- "@befly-addon/admin": "1.0.31",
65
40
  "@iconify-json/lucide": "^1.2.72",
66
41
  "@unocss/preset-attributify": "^66.5.6",
67
42
  "@unocss/preset-uno": "^66.5.6",
@@ -82,5 +57,5 @@
82
57
  "node": ">=24.0.0",
83
58
  "pnpm": ">=10.0.0"
84
59
  },
85
- "gitHead": "f279b3e03931a8f13ac1c559e545d18052ce2b87"
60
+ "gitHead": "e4130ff7b23ea4f0913969220c6374d550d2acc5"
86
61
  }
@@ -9,26 +9,43 @@
9
9
  <div class="user-info-bar">
10
10
  <div class="user-text">
11
11
  <span class="user-name">{{ $Data.userInfo.nickname || '管理员' }}</span>
12
- <tiny-tag type="info" size="small">{{ $Data.userInfo.role || '超级管理员' }}</tiny-tag>
12
+ <t-tag theme="primary" size="small" variant="light">{{ $Data.userInfo.role || '超级管理员' }}</t-tag>
13
13
  </div>
14
- <tiny-button size="medium" :icon="iconClose()" @click="$Method.handleLogout" />
14
+ <t-button variant="text" size="medium" @click="$Method.handleLogout">
15
+ <template #icon>
16
+ <i-lucide:x />
17
+ </template>
18
+ </t-button>
15
19
  </div>
16
20
  </div>
17
21
  </div>
18
22
 
19
23
  <!-- 菜单栏 -->
20
24
  <div class="layout-menu">
21
- <tiny-tree-menu :ref="(el) => ($From.treeMenuRef = el)" :data="$Data.userMenus" :props="{ label: 'name' }" node-key="id" :node-height="40" :show-filter="false" :default-expanded-keys="$Data.expandedKeys" style="height: 100%" only-check-children width-adapt @node-click="$Method.onMenuClick">
22
- <template #default="{ data }">
23
- <span class="menu-item">
24
- <!-- 根据路径和是否有子节点显示不同图标 -->
25
- <i-lucide:home v-if="data.path === '/addon/admin/'" />
26
- <i-lucide:folder v-else-if="data.children && data.children.length > 0" />
27
- <i-lucide:file-text v-else />
28
- <span>{{ data.name }}</span>
29
- </span>
25
+ <t-menu :value="$Data.currentMenuKey" :expanded="$Data.expandedKeys" style="height: 100%" @change="$Method.onMenuClick" @expand="(value) => ($Data.expandedKeys = value)">
26
+ <template v-for="menu in $Data.userMenus" :key="menu.id">
27
+ <!-- 无子菜单 -->
28
+ <t-menu-item v-if="!menu.children || menu.children.length === 0" :value="menu.path">
29
+ <template #icon>
30
+ <i-lucide:home v-if="menu.path === '/addon/admin/'" />
31
+ <i-lucide:file-text v-else />
32
+ </template>
33
+ {{ menu.name }}
34
+ </t-menu-item>
35
+ <!-- 有子菜单 -->
36
+ <t-submenu v-else :value="String(menu.id)" :title="menu.name">
37
+ <template #icon>
38
+ <i-lucide:folder />
39
+ </template>
40
+ <t-menu-item v-for="child in menu.children" :key="child.id" :value="child.path">
41
+ <template #icon>
42
+ <i-lucide:file-text />
43
+ </template>
44
+ {{ child.name }}
45
+ </t-menu-item>
46
+ </t-submenu>
30
47
  </template>
31
- </tiny-tree-menu>
48
+ </t-menu>
32
49
  </div>
33
50
 
34
51
  <!-- 内容区域 -->
@@ -40,7 +57,6 @@
40
57
 
41
58
  <script setup>
42
59
  import { arrayToTree } from '@/utils';
43
- import { iconClose } from '@opentiny/vue-icon';
44
60
 
45
61
  const router = useRouter();
46
62
  const route = useRoute();
@@ -55,7 +71,7 @@ const $Data = $ref({
55
71
  userMenus: [],
56
72
  userMenusFlat: [], // 一维菜单数据
57
73
  expandedKeys: [],
58
- currentNodeKey: 0,
74
+ currentMenuKey: '',
59
75
  userInfo: {
60
76
  nickname: '管理员',
61
77
  role: '超级管理员'
@@ -96,7 +112,7 @@ const $Method = {
96
112
  while (menu.pid) {
97
113
  const parent = $Data.userMenusFlat.find((m) => m.id === menu.pid);
98
114
  if (parent) {
99
- expandedKeys.unshift(parent.id);
115
+ expandedKeys.unshift(String(parent.id));
100
116
  menu = parent;
101
117
  } else {
102
118
  break;
@@ -106,29 +122,26 @@ const $Method = {
106
122
  // 使用 nextTick 确保 DOM 更新后再设置高亮
107
123
  nextTick(() => {
108
124
  $Data.expandedKeys = expandedKeys;
109
- // 使用 setCurrentKey 方法设置当前高亮节点
110
- if ($From.treeMenuRef) {
111
- $From.treeMenuRef.setCurrentKey(currentMenu.id);
112
- }
125
+ $Data.currentMenuKey = currentPath;
113
126
  });
114
127
  },
115
128
 
116
129
  // 处理菜单点击
117
- onMenuClick(data) {
118
- if (data.path) {
119
- router.push(data.path);
130
+ onMenuClick(path) {
131
+ if (path) {
132
+ router.push(path);
120
133
  }
121
134
  },
122
135
 
123
136
  // 处理退出登录
124
137
  handleLogout() {
125
- Modal.confirm({
126
- message: '确定要退出登录吗?',
127
- title: '确认',
138
+ DialogPlugin.confirm({
139
+ body: '确定要退出登录吗?',
140
+ header: '确认',
128
141
  onConfirm: () => {
129
142
  $Storage.local.remove('token');
130
143
  router.push('/internal/login');
131
- Message.success('退出成功');
144
+ MessagePlugin.success('退出成功');
132
145
  }
133
146
  });
134
147
  }
@@ -223,22 +236,6 @@ $Method.fetchUserMenus();
223
236
  padding: 16px 12px;
224
237
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
225
238
  border: 1px solid #e8eaed;
226
-
227
- .tiny-tree-menu:before {
228
- display: none;
229
- }
230
-
231
- .menu-item {
232
- display: flex;
233
- align-items: center;
234
- width: 100%;
235
- padding: 2px 0;
236
- transition: all 0.2s ease;
237
-
238
- &:hover {
239
- color: #0052d9;
240
- }
241
- }
242
239
  }
243
240
 
244
241
  .layout-main {
package/src/main.js CHANGED
@@ -1,5 +1,8 @@
1
1
  import App from './App.vue';
2
2
 
3
+ // 引入 TDesign 样式
4
+ import 'tdesign-vue-next/es/style/index.css';
5
+
3
6
  // 引入 UnoCSS 样式
4
7
  import 'virtual:uno.css';
5
8
 
@@ -1,5 +1,5 @@
1
1
  import axios from 'axios';
2
- import Modal from '@opentiny/vue-modal';
2
+ import { MessagePlugin } from 'tdesign-vue-next';
3
3
  import { $Storage } from './storage';
4
4
 
5
5
  /**
@@ -49,17 +49,14 @@ request.interceptors.response.use(
49
49
 
50
50
  // 如果code不是0,说明业务失败
51
51
  if (res.code !== 0) {
52
- Modal.message({
53
- message: res.msg || '请求失败',
54
- status: 'error'
55
- });
52
+ MessagePlugin.error(res.msg || '请求失败');
56
53
  return Promise.reject(res.data);
57
54
  }
58
55
 
59
56
  return res;
60
57
  },
61
58
  (error) => {
62
- Modal.message({ message: '网络连接失败', status: 'error' });
59
+ MessagePlugin.error('网络连接失败');
63
60
  return Promise.reject(error);
64
61
  }
65
62
  );
@@ -9,12 +9,9 @@ declare global {
9
9
  const $Config: typeof import('../config/index.js').$Config
10
10
  const $Http: typeof import('../plugins/http.js').$Http
11
11
  const $Storage: typeof import('../plugins/storage.js').$Storage
12
+ const DialogPlugin: typeof import('tdesign-vue-next').DialogPlugin
12
13
  const EffectScope: typeof import('vue').EffectScope
13
- const Loading: typeof import('@opentiny/vue-loading').default
14
- const Message: typeof import('@opentiny/vue-message').default
15
- const MessageBox: typeof import('@opentiny/vue-modal').default
16
- const Modal: typeof import('@opentiny/vue-modal').default
17
- const Notify: typeof import('@opentiny/vue-notify').default
14
+ const MessagePlugin: typeof import('tdesign-vue-next').MessagePlugin
18
15
  const acceptHMRUpdate: typeof import('pinia').acceptHMRUpdate
19
16
  const arrayToTree: typeof import('../utils/index.js').arrayToTree
20
17
  const computed: typeof import('vue').computed
@@ -23,7 +20,6 @@ declare global {
23
20
  const customRef: typeof import('vue').customRef
24
21
  const defineAsyncComponent: typeof import('vue').defineAsyncComponent
25
22
  const defineComponent: typeof import('vue').defineComponent
26
- const definePage: typeof import('unplugin-vue-router/runtime').definePage
27
23
  const defineStore: typeof import('pinia').defineStore
28
24
  const effectScope: typeof import('vue').effectScope
29
25
  const getActivePinia: typeof import('pinia').getActivePinia
@@ -107,12 +103,9 @@ declare module 'vue' {
107
103
  readonly $Config: UnwrapRef<typeof import('../config/index.js')['$Config']>
108
104
  readonly $Http: UnwrapRef<typeof import('../plugins/http.js')['$Http']>
109
105
  readonly $Storage: UnwrapRef<typeof import('../plugins/storage.js')['$Storage']>
106
+ readonly DialogPlugin: UnwrapRef<typeof import('tdesign-vue-next')['DialogPlugin']>
110
107
  readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
111
- readonly Loading: UnwrapRef<typeof import('@opentiny/vue-loading')['default']>
112
- readonly Message: UnwrapRef<typeof import('@opentiny/vue-message')['default']>
113
- readonly MessageBox: UnwrapRef<typeof import('@opentiny/vue-modal')['default']>
114
- readonly Modal: UnwrapRef<typeof import('@opentiny/vue-modal')['default']>
115
- readonly Notify: UnwrapRef<typeof import('@opentiny/vue-notify')['default']>
108
+ readonly MessagePlugin: UnwrapRef<typeof import('tdesign-vue-next')['MessagePlugin']>
116
109
  readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
117
110
  readonly arrayToTree: UnwrapRef<typeof import('../utils/index.js')['arrayToTree']>
118
111
  readonly computed: UnwrapRef<typeof import('vue')['computed']>
@@ -14,7 +14,30 @@ declare module 'vue' {
14
14
  'ILucide:fileText': typeof import('~icons/lucide/file-text')['default']
15
15
  'ILucide:folder': typeof import('~icons/lucide/folder')['default']
16
16
  'ILucide:home': typeof import('~icons/lucide/home')['default']
17
+ 'ILucide:x': typeof import('~icons/lucide/x')['default']
17
18
  RouterLink: typeof import('vue-router')['RouterLink']
18
19
  RouterView: typeof import('vue-router')['RouterView']
20
+ TButton: typeof import('tdesign-vue-next')['Button']
21
+ TDialog: typeof import('tdesign-vue-next')['Dialog']
22
+ TDivider: typeof import('tdesign-vue-next')['Divider']
23
+ TDropdown: typeof import('tdesign-vue-next')['Dropdown']
24
+ TDropdownItem: typeof import('tdesign-vue-next')['DropdownItem']
25
+ TDropdownMenu: typeof import('tdesign-vue-next')['DropdownMenu']
26
+ TForm: typeof import('tdesign-vue-next')['Form']
27
+ TFormItem: typeof import('tdesign-vue-next')['FormItem']
28
+ TInput: typeof import('tdesign-vue-next')['Input']
29
+ TInputNumber: typeof import('tdesign-vue-next')['InputNumber']
30
+ TLink: typeof import('tdesign-vue-next')['Link']
31
+ TMenu: typeof import('tdesign-vue-next')['Menu']
32
+ TMenuItem: typeof import('tdesign-vue-next')['MenuItem']
33
+ TPagination: typeof import('tdesign-vue-next')['Pagination']
34
+ TRadio: typeof import('tdesign-vue-next')['Radio']
35
+ TRadioGroup: typeof import('tdesign-vue-next')['RadioGroup']
36
+ TSelect: typeof import('tdesign-vue-next')['Select']
37
+ TSpace: typeof import('tdesign-vue-next')['Space']
38
+ TSubmenu: typeof import('tdesign-vue-next')['Submenu']
39
+ TTable: typeof import('tdesign-vue-next')['Table']
40
+ TTag: typeof import('tdesign-vue-next')['Tag']
41
+ TTree: typeof import('tdesign-vue-next')['Tree']
19
42
  }
20
43
  }
@@ -31,7 +31,7 @@ const $Method = {
31
31
  async handleLogin() {
32
32
  // 模拟登录
33
33
  $Storage.local.set('token', 'mock-token-123');
34
- Modal.message({ message: '登录成功', status: 'success' });
34
+ MessagePlugin.success('登录成功');
35
35
  router.push('/');
36
36
  }
37
37
  };
@@ -12,13 +12,10 @@
12
12
  </template>
13
13
 
14
14
  <script setup>
15
- // 无需导入,已自动导入:Modal, Message, Notify, MessageBox, Loading
15
+ // 无需导入,已自动导入:MessagePlugin, DialogPlugin, NotificationPlugin, LoadingPlugin
16
16
 
17
17
  const testModal = () => {
18
- Modal.message({
19
- message: '这是一个成功提示',
20
- status: 'success'
21
- });
18
+ MessagePlugin.success('这是一个成功提示');
22
19
  };
23
20
 
24
21
  const testMessage = () => {
package/vite.config.js CHANGED
@@ -5,6 +5,7 @@ import { VueRouterAutoImports } from 'unplugin-vue-router';
5
5
  import VueDevTools from 'vite-plugin-vue-devtools';
6
6
  import AutoImport from 'unplugin-auto-import/vite';
7
7
  import Components from 'unplugin-vue-components/vite';
8
+ import { TDesignResolver } from 'unplugin-vue-components/resolvers';
8
9
  import Icons from 'unplugin-icons/vite';
9
10
  import IconsResolver from 'unplugin-icons/resolver';
10
11
  import ReactivityTransform from '@vue-macros/reactivity-transform/vite';
@@ -47,19 +48,11 @@ export default defineConfig({
47
48
 
48
49
  // API 自动导入
49
50
  AutoImport({
50
- imports: [
51
- 'vue',
52
- 'pinia',
53
- VueRouterAutoImports,
54
- {
55
- '@opentiny/vue-modal': [
56
- ['default', 'Modal'],
57
- ['default', 'MessageBox']
58
- ],
59
- '@opentiny/vue-notify': [['default', 'Notify']],
60
- '@opentiny/vue-message': [['default', 'Message']],
61
- '@opentiny/vue-loading': [['default', 'Loading']]
62
- }
51
+ imports: ['vue', 'pinia', VueRouterAutoImports],
52
+ resolvers: [
53
+ TDesignResolver({
54
+ library: 'vue-next'
55
+ })
63
56
  ],
64
57
  dts: 'src/types/auto-imports.d.ts',
65
58
  dirs: ['src/utils', 'src/plugins', 'src/config'],
@@ -68,7 +61,12 @@ export default defineConfig({
68
61
 
69
62
  // 组件自动导入
70
63
  Components({
71
- resolvers: [IconsResolver({})],
64
+ resolvers: [
65
+ TDesignResolver({
66
+ library: 'vue-next'
67
+ }),
68
+ IconsResolver({})
69
+ ],
72
70
  dirs: ['src/components'],
73
71
  deep: true,
74
72
  dts: 'src/types/components.d.ts'
@@ -77,7 +75,7 @@ export default defineConfig({
77
75
  // 图标
78
76
  Icons({
79
77
  compiler: 'vue3',
80
- autoInstall: true,
78
+ autoInstall: false,
81
79
  defaultClass: 'icon-befly',
82
80
  defaultStyle: 'margin-right: 8px; vertical-align: middle;'
83
81
  })
@@ -124,33 +122,9 @@ export default defineConfig({
124
122
  return 'framework-pinia';
125
123
  }
126
124
 
127
- // TinyVue 细粒度拆分
128
- if (id.includes('@opentiny/vue-renderless/src/grid')) {
129
- return 'tiny-grid';
130
- }
131
- if (id.includes('@opentiny/vue-renderless/src/table')) {
132
- return 'tiny-table';
133
- }
134
- if (id.includes('@opentiny/vue-renderless/src/tree')) {
135
- return 'tiny-tree';
136
- }
137
- if (id.includes('@opentiny/vue-renderless/src/form')) {
138
- return 'tiny-form';
139
- }
140
- if (id.includes('node_modules/@opentiny/vue-renderless/')) {
141
- return 'tiny-renderless';
142
- }
143
- if (id.includes('node_modules/@opentiny/vue-theme/')) {
144
- return 'tiny-theme';
145
- }
146
- if (id.includes('node_modules/@opentiny/vue-locale/')) {
147
- return 'tiny-locale';
148
- }
149
- if (id.includes('node_modules/@opentiny/vue-common/')) {
150
- return 'tiny-common';
151
- }
152
- if (id.includes('node_modules/@opentiny/vue-icon/')) {
153
- return 'tiny-icon';
125
+ // TDesign Vue Next
126
+ if (id.includes('node_modules/tdesign-vue-next/') || id.includes('node_modules/.bun/tdesign-vue-next')) {
127
+ return 'tdesign';
154
128
  }
155
129
 
156
130
  // 工具库(独立文件)
@@ -163,7 +137,7 @@ export default defineConfig({
163
137
  return 'lib-lodash';
164
138
  }
165
139
 
166
- // echarts 及相关库(TinyVue 图表组件依赖)
140
+ // echarts 及相关库
167
141
  if (id.includes('node_modules/echarts/') || id.includes('node_modules/.bun/echarts')) {
168
142
  return 'lib-echarts';
169
143
  }
@@ -182,7 +156,7 @@ export default defineConfig({
182
156
  }
183
157
 
184
158
  // befly-addon
185
- if (id.includes('@befly-addon/')) {
159
+ if (id.includes('@befly-addon/') || id.includes('packages/addonAdmin/') || id.includes('packages\\addonAdmin\\')) {
186
160
  return 'befly-addon';
187
161
  }
188
162
 
@@ -208,6 +182,15 @@ export default defineConfig({
208
182
 
209
183
  // 优化配置
210
184
  optimizeDeps: {
211
- include: ['vue', 'vue-router', 'pinia', 'axios', 'vue-macros/macros']
185
+ include: [
186
+ // Vue 核心框架
187
+ 'vue',
188
+ 'vue-router',
189
+ 'pinia',
190
+ 'axios',
191
+ 'vue-macros/macros',
192
+ // TDesign Vue Next(按需加载,无需预配置)
193
+ 'tdesign-vue-next'
194
+ ]
212
195
  }
213
196
  });