befly-admin 3.5.37 → 3.6.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.
package/package.json CHANGED
@@ -1,35 +1,41 @@
1
1
  {
2
2
  "name": "befly-admin",
3
- "version": "3.5.37",
3
+ "version": "3.6.0",
4
+ "gitHead": "faa8189c7d23cf45885c03d1425cba8f5bf45df9",
4
5
  "private": false,
5
6
  "description": "Befly Admin - 基于 Vue3 + TDesign Vue Next 的后台管理系统",
6
- "type": "module",
7
7
  "files": [
8
8
  ".env",
9
9
  ".env.development",
10
10
  ".env.production",
11
11
  ".gitignore",
12
- "README.md",
13
12
  "bunfig.toml",
14
13
  "index.html",
15
14
  "public",
15
+ "README.md",
16
16
  "src",
17
17
  "vite.config.js"
18
18
  ],
19
+ "type": "module",
20
+ "publishConfig": {
21
+ "access": "public",
22
+ "registry": "https://registry.npmjs.org"
23
+ },
19
24
  "scripts": {
20
25
  "dev": "vite",
21
26
  "build": "vite build",
22
27
  "preview": "vite preview"
23
28
  },
24
29
  "dependencies": {
25
- "@befly-addon/admin": "^1.1.35",
26
- "@iconify-json/lucide": "^1.2.80",
30
+ "@befly-addon/admin": "^1.2.0",
31
+ "@iconify-json/lucide": "^1.2.82",
27
32
  "axios": "^1.13.2",
28
- "befly-vite": "^1.1.13",
33
+ "befly-shared": "1.0.0",
34
+ "befly-vite": "^1.2.0",
29
35
  "pinia": "^3.0.4",
30
36
  "tdesign-vue-next": "^1.17.7",
31
37
  "unplugin-vue-router": "^0.19.0",
32
- "vite": "^8.0.0-beta.3",
38
+ "vite": "^8.0.0-beta.5",
33
39
  "vue": "^3.5.26",
34
40
  "vue-router": "^4.6.4"
35
41
  },
@@ -37,10 +43,5 @@
37
43
  "bun": ">=1.3.0",
38
44
  "node": ">=24.0.0",
39
45
  "pnpm": ">=10.0.0"
40
- },
41
- "publishConfig": {
42
- "access": "public",
43
- "registry": "https://registry.npmjs.org"
44
- },
45
- "gitHead": "3a0df4a847cf3da97bb2d09455fabba62027e6c0"
46
+ }
46
47
  }
@@ -75,9 +75,8 @@
75
75
  </template>
76
76
 
77
77
  <script setup>
78
- import { arrayToTree } from "befly-vite/utils/arrayToTree";
79
-
80
78
  import { DialogPlugin } from "tdesign-vue-next";
79
+ import { arrayToTree } from "befly-shared/utils/arrayToTree";
81
80
 
82
81
  const router = useRouter();
83
82
  const route = useRoute();
@@ -94,6 +93,26 @@ const normalizePath = (path) => {
94
93
  return normalized.length === 0 ? "/" : normalized;
95
94
  };
96
95
 
96
+ // parentPath 的归一化规则与 path 不同:
97
+ // - parentPath 为空/"/" 视为根节点(空字符串)
98
+ // - 避免把所有一级菜单挂到 "/"(首页)下面
99
+ const normalizeParentPath = (parentPath) => {
100
+ if (typeof parentPath !== "string") {
101
+ return "";
102
+ }
103
+
104
+ const normalized = parentPath.replace(/\/+$/, "");
105
+ if (normalized.length === 0) {
106
+ return "";
107
+ }
108
+
109
+ if (normalized === "/") {
110
+ return "";
111
+ }
112
+
113
+ return normalized;
114
+ };
115
+
97
116
  const $From = {
98
117
  treeMenuRef: null
99
118
  };
@@ -152,7 +171,7 @@ const $Method = {
152
171
 
153
172
  bizMenus.push({
154
173
  id: `biz_${path.replace(/[^a-zA-Z0-9]+/g, "_")}`,
155
- pid: "biz",
174
+ parentPath: "__biz__",
156
175
  name: title,
157
176
  path: path
158
177
  });
@@ -165,23 +184,30 @@ const $Method = {
165
184
  ? [
166
185
  {
167
186
  id: "biz",
168
- pid: 0,
187
+ parentPath: "",
169
188
  name: "业务",
170
- path: ""
189
+ path: "__biz__",
190
+ sort: 2
171
191
  }
172
- ].concat(bizMenus)
192
+ ].concat(
193
+ bizMenus.map((m) => {
194
+ return Object.assign({}, m, { sort: 2 });
195
+ })
196
+ )
173
197
  : [];
174
198
 
175
199
  const normalizedLists = lists.map((menu) => {
176
200
  const menuPath = normalizePath(menu?.path);
177
- return Object.assign({}, menu, { path: menuPath });
201
+ const menuParentPath = normalizeParentPath(menu?.parentPath);
202
+ return Object.assign({}, menu, { path: menuPath, parentPath: menuParentPath });
178
203
  });
179
204
 
180
205
  const mergedLists = bizMenusFlat.concat(normalizedLists);
181
206
 
182
- // 保存一维数据(data { lists: [] } 格式)
183
- $Data.userMenusFlat = mergedLists;
184
- $Data.userMenus = arrayToTree(mergedLists);
207
+ const treeResult = arrayToTree(mergedLists, "path", "parentPath", "children", "sort");
208
+
209
+ $Data.userMenusFlat = treeResult.flat;
210
+ $Data.userMenus = treeResult.tree;
185
211
  $Method.setActiveMenu();
186
212
  } catch (error) {
187
213
  MessagePlugin.error("获取用户菜单失败");
@@ -208,15 +234,21 @@ const $Method = {
208
234
  const expandedKeys = [];
209
235
  let menu = currentMenu;
210
236
 
211
- // 向上查找所有父级
212
- while (menu.pid) {
213
- const parent = $Data.userMenusFlat.find((m) => m.id === menu.pid);
237
+ // 向上查找所有父级(通过 parentPath 关联)
238
+ while (typeof menu.parentPath === "string" && menu.parentPath.length > 0) {
239
+ const parent = $Data.userMenusFlat.find((m) => {
240
+ const parentMenuPath = normalizePath(m?.path);
241
+ const currentParentPath = normalizeParentPath(menu?.parentPath);
242
+ return parentMenuPath === currentParentPath;
243
+ });
244
+
214
245
  if (parent) {
215
246
  expandedKeys.unshift(String(parent.id));
216
247
  menu = parent;
217
- } else {
218
- break;
248
+ continue;
219
249
  }
250
+
251
+ break;
220
252
  }
221
253
 
222
254
  // 设置展开的父级和当前激活的菜单
@@ -21,7 +21,7 @@ export const $Config = {
21
21
  loginPath: import.meta.env.VITE_LOGIN_PATH || "/addon/admin/login",
22
22
 
23
23
  /** 首页路径(可通过 VITE_HOME_PATH 覆盖) */
24
- homePath: import.meta.env.VITE_HOME_PATH || "/dashboard",
24
+ homePath: import.meta.env.VITE_HOME_PATH || "/addon/admin",
25
25
  /** 是否开发环境 */
26
26
  isDev: import.meta.env.DEV,
27
27
  /** 是否生产环境 */
@@ -142,13 +142,6 @@ declare module 'vue-router/auto-routes' {
142
142
  Record<never, never>,
143
143
  | never
144
144
  >,
145
- '/dashboard/': RouteRecordInfo<
146
- '/dashboard/',
147
- '/dashboard',
148
- Record<never, never>,
149
- Record<never, never>,
150
- | never
151
- >,
152
145
  '/index2': RouteRecordInfo<
153
146
  '/index2',
154
147
  '/index2',
@@ -169,114 +162,108 @@ declare module 'vue-router/auto-routes' {
169
162
  * @internal
170
163
  */
171
164
  export interface _RouteFileInfoMap {
172
- '../addonAdmin/views/index/index.vue': {
165
+ '../addonAdmin/adminViews/index/index.vue': {
173
166
  routes:
174
167
  | '/addon/admin//'
175
168
  views:
176
169
  | never
177
170
  }
178
- '../addonAdmin/views/403_1/index.vue': {
171
+ '../addonAdmin/adminViews/403_1/index.vue': {
179
172
  routes:
180
173
  | '/addon/admin/403_1/'
181
174
  views:
182
175
  | never
183
176
  }
184
- '../addonAdmin/views/config/index.vue': {
177
+ '../addonAdmin/adminViews/config/index.vue': {
185
178
  routes:
186
179
  | '/addon/admin/config/'
187
180
  views:
188
181
  | never
189
182
  }
190
- '../addonAdmin/views/config/dict/index.vue': {
183
+ '../addonAdmin/adminViews/config/dict/index.vue': {
191
184
  routes:
192
185
  | '/addon/admin/config/dict/'
193
186
  views:
194
187
  | never
195
188
  }
196
- '../addonAdmin/views/config/dictType/index.vue': {
189
+ '../addonAdmin/adminViews/config/dictType/index.vue': {
197
190
  routes:
198
191
  | '/addon/admin/config/dictType/'
199
192
  views:
200
193
  | never
201
194
  }
202
- '../addonAdmin/views/config/system/index.vue': {
195
+ '../addonAdmin/adminViews/config/system/index.vue': {
203
196
  routes:
204
197
  | '/addon/admin/config/system/'
205
198
  views:
206
199
  | never
207
200
  }
208
- '../addonAdmin/views/log/index.vue': {
201
+ '../addonAdmin/adminViews/log/index.vue': {
209
202
  routes:
210
203
  | '/addon/admin/log/'
211
204
  views:
212
205
  | never
213
206
  }
214
- '../addonAdmin/views/log/email/index.vue': {
207
+ '../addonAdmin/adminViews/log/email/index.vue': {
215
208
  routes:
216
209
  | '/addon/admin/log/email/'
217
210
  views:
218
211
  | never
219
212
  }
220
- '../addonAdmin/views/log/login/index.vue': {
213
+ '../addonAdmin/adminViews/log/login/index.vue': {
221
214
  routes:
222
215
  | '/addon/admin/log/login/'
223
216
  views:
224
217
  | never
225
218
  }
226
- '../addonAdmin/views/log/operate/index.vue': {
219
+ '../addonAdmin/adminViews/log/operate/index.vue': {
227
220
  routes:
228
221
  | '/addon/admin/log/operate/'
229
222
  views:
230
223
  | never
231
224
  }
232
- '../addonAdmin/views/login_1/index.vue': {
225
+ '../addonAdmin/adminViews/login_1/index.vue': {
233
226
  routes:
234
227
  | '/addon/admin/login_1/'
235
228
  views:
236
229
  | never
237
230
  }
238
- '../addonAdmin/views/people/index.vue': {
231
+ '../addonAdmin/adminViews/people/index.vue': {
239
232
  routes:
240
233
  | '/addon/admin/people/'
241
234
  views:
242
235
  | never
243
236
  }
244
- '../addonAdmin/views/people/admin/index.vue': {
237
+ '../addonAdmin/adminViews/people/admin/index.vue': {
245
238
  routes:
246
239
  | '/addon/admin/people/admin/'
247
240
  views:
248
241
  | never
249
242
  }
250
- '../addonAdmin/views/permission/index.vue': {
243
+ '../addonAdmin/adminViews/permission/index.vue': {
251
244
  routes:
252
245
  | '/addon/admin/permission/'
253
246
  views:
254
247
  | never
255
248
  }
256
- '../addonAdmin/views/permission/api/index.vue': {
249
+ '../addonAdmin/adminViews/permission/api/index.vue': {
257
250
  routes:
258
251
  | '/addon/admin/permission/api/'
259
252
  views:
260
253
  | never
261
254
  }
262
- '../addonAdmin/views/permission/menu/index.vue': {
255
+ '../addonAdmin/adminViews/permission/menu/index.vue': {
263
256
  routes:
264
257
  | '/addon/admin/permission/menu/'
265
258
  views:
266
259
  | never
267
260
  }
268
- '../addonAdmin/views/permission/role/index.vue': {
261
+ '../addonAdmin/adminViews/permission/role/index.vue': {
269
262
  routes:
270
263
  | '/addon/admin/permission/role/'
271
264
  views:
272
265
  | never
273
266
  }
274
- 'src/views/dashboard/index.vue': {
275
- routes:
276
- | '/dashboard/'
277
- views:
278
- | never
279
- }
280
267
  'src/views/index2.vue': {
281
268
  routes:
282
269
  | '/index2'
@@ -1,117 +0,0 @@
1
- <template>
2
- <div class="dashboard">
3
- <div class="header">
4
- <div class="title">工作台</div>
5
- <div class="desc">这里是业务首页(admin 自有页面),系统管理功能仍在 /addon/admin/*。</div>
6
- </div>
7
-
8
- <div class="cards">
9
- <TCard class="card" title="今日概览" :bordered="false">
10
- <div class="kv">
11
- <div class="item">
12
- <div class="k">新增用户</div>
13
- <div class="v">—</div>
14
- </div>
15
- <div class="item">
16
- <div class="k">新增订单</div>
17
- <div class="v">—</div>
18
- </div>
19
- <div class="item">
20
- <div class="k">待处理事项</div>
21
- <div class="v">—</div>
22
- </div>
23
- </div>
24
- </TCard>
25
-
26
- <TCard class="card" title="快捷入口" :bordered="false">
27
- <div class="quick">
28
- <TButton theme="primary" variant="base" @click="$Method.goSystem">进入系统管理</TButton>
29
- <TButton theme="default" variant="outline" @click="$Method.refresh">刷新</TButton>
30
- </div>
31
- </TCard>
32
- </div>
33
- </div>
34
- </template>
35
-
36
- <script setup>
37
- import { Button as TButton, Card as TCard } from "tdesign-vue-next";
38
-
39
- definePage({
40
- meta: {
41
- title: "工作台",
42
- layout: "default"
43
- }
44
- });
45
-
46
- const router = useRouter();
47
-
48
- const $Method = {
49
- goSystem() {
50
- router.push("/addon/admin");
51
- },
52
- refresh() {
53
- window.location.reload();
54
- }
55
- };
56
- </script>
57
-
58
- <style scoped lang="scss">
59
- .dashboard {
60
- padding: 16px;
61
- }
62
-
63
- .header {
64
- padding: 12px 0;
65
-
66
- .title {
67
- font-size: 18px;
68
- font-weight: 600;
69
- color: var(--text-primary);
70
- margin-bottom: 6px;
71
- }
72
-
73
- .desc {
74
- font-size: 12px;
75
- color: var(--text-secondary);
76
- }
77
- }
78
-
79
- .cards {
80
- display: grid;
81
- grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
82
- gap: 12px;
83
- }
84
-
85
- .card {
86
- border-radius: var(--border-radius-large);
87
- }
88
-
89
- .kv {
90
- display: grid;
91
- grid-template-columns: repeat(3, minmax(0, 1fr));
92
- gap: 12px;
93
-
94
- .item {
95
- padding: 10px 12px;
96
- border-radius: var(--border-radius);
97
- background: var(--bg-color-page);
98
-
99
- .k {
100
- font-size: 12px;
101
- color: var(--text-secondary);
102
- margin-bottom: 8px;
103
- }
104
-
105
- .v {
106
- font-size: 18px;
107
- font-weight: 600;
108
- color: var(--text-primary);
109
- }
110
- }
111
- }
112
-
113
- .quick {
114
- display: flex;
115
- gap: 10px;
116
- }
117
- </style>