befly-admin 3.12.6 → 3.12.8

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,7 +1,7 @@
1
1
  {
2
2
  "name": "befly-admin",
3
- "version": "3.12.6",
4
- "gitHead": "607fe5ea9c06653ec6da8a9e4175d1f9c7b98c13",
3
+ "version": "3.12.8",
4
+ "gitHead": "c30de9bab631596341b6bc28490579a9923c87d6",
5
5
  "private": false,
6
6
  "description": "Befly Admin - 基于 Vue3 + TDesign Vue Next 的后台管理系统",
7
7
  "files": [
@@ -23,16 +23,16 @@
23
23
  "registry": "https://registry.npmjs.org"
24
24
  },
25
25
  "scripts": {
26
- "dev": "vite",
27
- "build": "vite build",
28
- "preview": "vite preview"
26
+ "dev": "bunx --bun vite",
27
+ "build": "bunx --bun vite build",
28
+ "preview": "bunx --bun vite preview"
29
29
  },
30
30
  "dependencies": {
31
31
  "@befly-addon/admin": "^1.8.5",
32
32
  "@iconify-json/lucide": "^1.2.86",
33
33
  "axios": "^1.13.2",
34
34
  "befly-shared": "^1.4.5",
35
- "befly-vite": "^1.4.8",
35
+ "befly-vite": "^1.4.9",
36
36
  "pinia": "^3.0.4",
37
37
  "tdesign-vue-next": "^1.18.0",
38
38
  "vite": "^8.0.0-beta.8",
@@ -30,7 +30,7 @@
30
30
  </div>
31
31
 
32
32
  <div class="main-page">
33
- <TPagination :current-page="$Data.pager.currentPage" :page-size="$Data.pager.limit" :total="$Data.pager.total" :align="paginationAlign" :layout="paginationLayout" @current-change="onPageChange" @page-size-change="onPageSizeChange" />
33
+ <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" />
34
34
  </div>
35
35
 
36
36
  <slot name="dialogs" :reload="reload" :current-row="$Data.currentRow"></slot>
@@ -64,6 +64,11 @@ type DeleteConfirmContent = {
64
64
  status?: "warning" | "danger" | "info" | "success";
65
65
  };
66
66
 
67
+ type ConfirmDialogInstance = {
68
+ destroy?: () => void;
69
+ setConfirmLoading?: (loading: boolean) => void;
70
+ };
71
+
67
72
  type DeleteEndpoint<Row extends TableRowData> = {
68
73
  path: string;
69
74
  idKey?: string;
@@ -100,25 +105,19 @@ type LoadListOptions = {
100
105
  const props = withDefaults(
101
106
  defineProps<{
102
107
  columns: PagedTableCol[];
103
- detailFields?: PrimaryTableCol[];
104
- detailColumns?: PrimaryTableCol[];
105
108
  rowKey?: string;
106
109
  tableHeight?: string;
107
110
  pageSize?: number;
108
111
  endpoints?: Endpoints<TableRowData>;
109
- paginationAlign?: "left" | "center" | "right";
110
112
  paginationLayout?: string;
111
113
  autoLoad?: boolean;
112
114
  tableSlotNames?: string[];
113
115
  }>(),
114
116
  {
115
- detailFields: undefined,
116
- detailColumns: undefined,
117
117
  rowKey: "id",
118
118
  tableHeight: "calc(100vh - var(--search-height) - var(--pagination-height) - var(--layout-gap) * 4)",
119
119
  pageSize: 30,
120
120
  endpoints: undefined,
121
- paginationAlign: "right",
122
121
  paginationLayout: "total, prev, pager, next, jumper",
123
122
  autoLoad: true,
124
123
  tableSlotNames: undefined
@@ -219,18 +218,9 @@ const tableColumns = computed(() => {
219
218
  });
220
219
 
221
220
  const detailFields = computed(() => {
222
- // A:完全自定义(兼容存量)
223
- if (props.detailFields && Array.isArray(props.detailFields)) {
224
- return filterValidColumns(props.detailFields);
225
- }
226
-
227
- // B:表格列只展示关键字段,详情列 = columns(关键字段) + detailColumns(其他字段)
228
- if (props.detailColumns && Array.isArray(props.detailColumns)) {
229
- const extras = filterValidColumns(props.detailColumns);
230
- return mergeDetailColumns(tableColumns.value, extras);
231
- }
232
-
233
- // C:单列定义:只维护一个 columns:detail 字段为详情专属列,详情 = 表格列(在前) + 详情列(在后)
221
+ // 只维护一个 columns:
222
+ // - detail: false(默认)=> 表格展示(同时也会出现在详情里,且顺序靠前)
223
+ // - detail: true => 仅在详情展示(顺序靠后)
234
224
  const extras: PagedTableCol[] = [];
235
225
  const cols = filterValidColumns(props.columns) as PagedTableCol[];
236
226
  for (const col of cols) {
@@ -242,7 +232,7 @@ const detailFields = computed(() => {
242
232
  return mergeDetailColumns(tableColumns.value, extras);
243
233
  }
244
234
 
245
- // D:默认复用表格列
235
+ // 默认复用表格列
246
236
  return tableColumns.value;
247
237
  });
248
238
 
@@ -388,7 +378,7 @@ async function loadList(options?: LoadListOptions): Promise<void> {
388
378
  if (seq !== requestSeq) {
389
379
  return;
390
380
  }
391
- void showMessageError("加载数据失败");
381
+ void MessagePlugin.error("加载数据失败");
392
382
  } finally {
393
383
  if (seq === requestSeq) {
394
384
  $Data.loading = false;
@@ -466,7 +456,7 @@ function getDeleteConfirmContent(ep: DeleteEndpoint<TableRowData>, row: TableRow
466
456
  async function deleteRow(row: TableRowData): Promise<void> {
467
457
  const ep = props.endpoints?.delete;
468
458
  if (!ep) {
469
- await showMessageError("未配置删除接口");
459
+ MessagePlugin.error("未配置删除接口");
470
460
  return;
471
461
  }
472
462
 
@@ -475,13 +465,13 @@ async function deleteRow(row: TableRowData): Promise<void> {
475
465
  const rawId = record[idKey];
476
466
 
477
467
  if (rawId === null || rawId === undefined || rawId === "") {
478
- await showMessageError("删除失败:缺少主键");
468
+ MessagePlugin.error("删除失败:缺少主键");
479
469
  return;
480
470
  }
481
471
 
482
472
  const confirmContent = getDeleteConfirmContent(ep, row);
483
473
 
484
- let dialog: { destroy?: () => void; setConfirmLoading?: (v: boolean) => void } | null = null;
474
+ let dialog: ConfirmDialogInstance | null = null;
485
475
  let destroyed = false;
486
476
 
487
477
  const destroy = () => {
@@ -492,7 +482,7 @@ async function deleteRow(row: TableRowData): Promise<void> {
492
482
  }
493
483
  };
494
484
 
495
- dialog = await openConfirmDialog({
485
+ dialog = DialogPlugin.confirm({
496
486
  header: confirmContent.header,
497
487
  body: confirmContent.body,
498
488
  status: confirmContent.status || "warning",
@@ -521,12 +511,12 @@ async function deleteRow(row: TableRowData): Promise<void> {
521
511
  dropKeyValue: ep.dropKeyValue
522
512
  });
523
513
 
524
- await showMessageSuccess("删除成功");
514
+ MessagePlugin.success("删除成功");
525
515
  destroy();
526
516
  emit("deleted", { row: row });
527
517
  await reload({ keepSelection: true });
528
518
  } catch (error) {
529
- await showMessageError("删除失败");
519
+ MessagePlugin.error("删除失败");
530
520
  } finally {
531
521
  if (dialog && typeof dialog.setConfirmLoading === "function") {
532
522
  dialog.setConfirmLoading(false);
@@ -206,7 +206,7 @@ async function fetchUserMenus() {
206
206
  $Data.userMenus = treeResult.tree;
207
207
  setActiveMenu();
208
208
  } catch (error) {
209
- void showMessageError("获取用户菜单失败");
209
+ void MessagePlugin.error("获取用户菜单失败");
210
210
  }
211
211
  }
212
212
 
@@ -265,7 +265,7 @@ async function handleLogout() {
265
265
  }
266
266
  };
267
267
 
268
- dialog = await openConfirmDialog({
268
+ dialog = DialogPlugin.confirm({
269
269
  header: "确认退出登录",
270
270
  body: "确定要退出登录吗?",
271
271
  status: "warning",
@@ -277,10 +277,10 @@ async function handleLogout() {
277
277
  try {
278
278
  $Storage.local.remove("token");
279
279
  await router.push(loginPath);
280
- await showMessageSuccess("退出成功");
280
+ MessagePlugin.success("退出成功");
281
281
  destroy();
282
282
  } catch (error) {
283
- await showMessageError("退出失败");
283
+ MessagePlugin.error("退出失败");
284
284
  destroy();
285
285
  } finally {
286
286
  if (dialog && typeof dialog.setConfirmLoading === "function") {
@@ -301,7 +301,7 @@ function handleSettings() {
301
301
  function onAvatarUploadSuccess(res) {
302
302
  if (res.response?.code === 0 && res.response?.data?.url) {
303
303
  $Data.userInfo.avatar = res.response.data.url;
304
- void showMessageSuccess("头像上传成功");
304
+ void MessagePlugin.success("头像上传成功");
305
305
  }
306
306
  }
307
307
 
package/src/main.ts CHANGED
@@ -3,7 +3,7 @@ import "tdesign-vue-next/es/style/index.css";
3
3
  // 引入 addonAdmin 的 CSS 变量
4
4
  import "@befly-addon/admin/styles/variables.scss";
5
5
  // 引入全局基础样式(reset、通用类、滚动条等)
6
- import "./styles/global.scss";
6
+ import "@/styles/global.scss";
7
7
  import App from "./App.vue";
8
8
 
9
9
  const app = createApp(App);
@@ -73,7 +73,7 @@ function isNormalizedHttpError(value: unknown): value is HttpError {
73
73
  async function showNetworkErrorToast(): Promise<void> {
74
74
  try {
75
75
  // 在测试/非浏览器环境下,提示组件可能不可用;仅在需要展示提示时再加载。
76
- await showMessageError("网络连接失败");
76
+ MessagePlugin.error("网络连接失败");
77
77
  } catch {
78
78
  // ignore
79
79
  }
@@ -59,7 +59,6 @@ declare global {
59
59
  const onUnmounted: typeof import('vue').onUnmounted
60
60
  const onUpdated: typeof import('vue').onUpdated
61
61
  const onWatcherCleanup: typeof import('vue').onWatcherCleanup
62
- const openConfirmDialog: typeof import('../utils/tdesignPlugins').openConfirmDialog
63
62
  const provide: typeof import('vue').provide
64
63
  const reactive: typeof import('vue').reactive
65
64
  const readonly: typeof import('vue').readonly
@@ -71,9 +70,6 @@ declare global {
71
70
  const shallowReactive: typeof import('vue').shallowReactive
72
71
  const shallowReadonly: typeof import('vue').shallowReadonly
73
72
  const shallowRef: typeof import('vue').shallowRef
74
- const showMessageError: typeof import('../utils/tdesignPlugins').showMessageError
75
- const showMessageSuccess: typeof import('../utils/tdesignPlugins').showMessageSuccess
76
- const showMessageWarning: typeof import('../utils/tdesignPlugins').showMessageWarning
77
73
  const storeToRefs: typeof import('pinia').storeToRefs
78
74
  const toRaw: typeof import('vue').toRaw
79
75
  const toRef: typeof import('vue').toRef
@@ -102,9 +98,6 @@ declare global {
102
98
  export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, ShallowRef, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
103
99
  import('vue')
104
100
  // @ts-ignore
105
- export type { ConfirmDialogStatus, ConfirmDialogOptions, ConfirmDialogInstance } from '../utils/tdesignPlugins'
106
- import('../utils/tdesignPlugins')
107
- // @ts-ignore
108
101
  export type { BeflyAdminConfig } from '../plugins/config'
109
102
  import('../plugins/config')
110
103
  // @ts-ignore
@@ -166,7 +159,6 @@ declare module 'vue' {
166
159
  readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
167
160
  readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
168
161
  readonly onWatcherCleanup: UnwrapRef<typeof import('vue')['onWatcherCleanup']>
169
- readonly openConfirmDialog: UnwrapRef<typeof import('../utils/tdesignPlugins')['openConfirmDialog']>
170
162
  readonly provide: UnwrapRef<typeof import('vue')['provide']>
171
163
  readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
172
164
  readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
@@ -177,9 +169,6 @@ declare module 'vue' {
177
169
  readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
178
170
  readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
179
171
  readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
180
- readonly showMessageError: UnwrapRef<typeof import('../utils/tdesignPlugins')['showMessageError']>
181
- readonly showMessageSuccess: UnwrapRef<typeof import('../utils/tdesignPlugins')['showMessageSuccess']>
182
- readonly showMessageWarning: UnwrapRef<typeof import('../utils/tdesignPlugins')['showMessageWarning']>
183
172
  readonly storeToRefs: UnwrapRef<typeof import('pinia')['storeToRefs']>
184
173
  readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
185
174
  readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
@@ -142,14 +142,7 @@
142
142
  </div>
143
143
  </template>
144
144
 
145
- <script setup lang="ts">
146
- definePage({
147
- meta: {
148
- title: "数据面板",
149
- layout: "default"
150
- }
151
- });
152
- </script>
145
+ <script setup lang="ts"></script>
153
146
 
154
147
  <style lang="scss" scoped>
155
148
  .dashboard {
@@ -1,3 +0,0 @@
1
- // 让 TypeScript 识别 unplugin-vue-router 的 definePage 宏
2
- // 注意:这不会在运行时引入任何代码,仅用于类型声明
3
- import "unplugin-vue-router/client";
@@ -1,57 +0,0 @@
1
- let messagePluginPromise: Promise<typeof import("tdesign-vue-next/es/message/plugin")> | null = null;
2
- let dialogPluginPromise: Promise<typeof import("tdesign-vue-next/es/dialog/plugin")> | null = null;
3
-
4
- export async function showMessageSuccess(content: string): Promise<void> {
5
- const mod = await getMessagePlugin();
6
- mod.MessagePlugin.success(content);
7
- }
8
-
9
- export async function showMessageError(content: string): Promise<void> {
10
- const mod = await getMessagePlugin();
11
- mod.MessagePlugin.error(content);
12
- }
13
-
14
- export async function showMessageWarning(content: string): Promise<void> {
15
- const mod = await getMessagePlugin();
16
- mod.MessagePlugin.warning(content);
17
- }
18
-
19
- export type ConfirmDialogStatus = "warning" | "danger" | "info" | "success";
20
-
21
- export type ConfirmDialogOptions = {
22
- header: string;
23
- body: string;
24
- status?: ConfirmDialogStatus;
25
- confirmBtn?: string;
26
- cancelBtn?: string;
27
- onConfirm?: () => void | Promise<void>;
28
- onClose?: () => void;
29
- };
30
-
31
- export type ConfirmDialogInstance = {
32
- destroy?: () => void;
33
- setConfirmLoading?: (loading: boolean) => void;
34
- };
35
-
36
- export async function openConfirmDialog(options: ConfirmDialogOptions): Promise<ConfirmDialogInstance> {
37
- const mod = await getDialogPlugin();
38
- return mod.DialogPlugin.confirm(options);
39
- }
40
-
41
- async function getMessagePlugin(): Promise<typeof import("tdesign-vue-next/es/message/plugin")> {
42
- if (messagePluginPromise) {
43
- return messagePluginPromise;
44
- }
45
-
46
- messagePluginPromise = import("tdesign-vue-next/es/message/plugin");
47
- return messagePluginPromise;
48
- }
49
-
50
- async function getDialogPlugin(): Promise<typeof import("tdesign-vue-next/es/dialog/plugin")> {
51
- if (dialogPluginPromise) {
52
- return dialogPluginPromise;
53
- }
54
-
55
- dialogPluginPromise = import("tdesign-vue-next/es/dialog/plugin");
56
- return dialogPluginPromise;
57
- }