befly-admin-ui 1.10.1 → 1.10.5

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 (35) hide show
  1. package/components/detailPanel.vue +52 -54
  2. package/components/pageDialog.vue +131 -117
  3. package/components/pageTableDetail.vue +381 -402
  4. package/layouts/default.vue +212 -215
  5. package/package.json +2 -2
  6. package/views/config/dict/components/edit.vue +83 -60
  7. package/views/config/dict/index.vue +51 -55
  8. package/views/config/dictType/components/edit.vue +81 -57
  9. package/views/config/dictType/index.vue +37 -39
  10. package/views/config/system/components/edit.vue +97 -86
  11. package/views/config/system/index.vue +35 -37
  12. package/views/index/components/addonList.vue +14 -11
  13. package/views/index/components/environmentInfo.vue +25 -22
  14. package/views/index/components/operationLogs.vue +20 -16
  15. package/views/index/components/performanceMetrics.vue +24 -21
  16. package/views/index/components/serviceStatus.vue +26 -22
  17. package/views/index/components/systemNotifications.vue +24 -19
  18. package/views/index/components/systemOverview.vue +368 -385
  19. package/views/index/components/systemResources.vue +22 -19
  20. package/views/index/components/userInfo.vue +56 -56
  21. package/views/log/email/index.vue +96 -85
  22. package/views/log/error/index.vue +111 -117
  23. package/views/log/login/index.vue +15 -13
  24. package/views/log/operate/index.vue +31 -31
  25. package/views/login_1/index.vue +50 -32
  26. package/views/people/admin/components/edit.vue +1 -1
  27. package/views/people/admin/index.vue +27 -28
  28. package/views/permission/api/index.vue +44 -45
  29. package/views/permission/menu/index.vue +35 -35
  30. package/views/permission/role/components/api.vue +143 -144
  31. package/views/permission/role/components/edit.vue +74 -52
  32. package/views/permission/role/components/menu.vue +119 -121
  33. package/views/permission/role/index.vue +47 -49
  34. package/views/resource/gallery/index.vue +77 -78
  35. package/LICENSE +0 -201
@@ -2,7 +2,7 @@
2
2
  <div class="detail-panel">
3
3
  <div class="detail-content">
4
4
  <div v-if="data">
5
- <div v-for="field in normalizedFields" :key="field.colKey" class="detail-item">
5
+ <div v-for="field in $Computed.normalizedFields" :key="field.colKey" class="detail-item">
6
6
  <div class="detail-label">{{ field.title }}</div>
7
7
  <div class="detail-value">
8
8
  <!-- 状态字段特殊处理 -->
@@ -31,11 +31,11 @@
31
31
  </template>
32
32
 
33
33
  <script setup>
34
- import { computed } from "vue";
34
+ import { computed, reactive } from "vue";
35
35
  import { Tag as TTag } from "tdesign-vue-next";
36
36
  import { formatFieldValue } from "../utils/formatFieldValue.js";
37
37
 
38
- const props = defineProps({
38
+ const $Prop = defineProps({
39
39
  /**
40
40
  * 当前行数据
41
41
  */
@@ -67,61 +67,59 @@ const props = defineProps({
67
67
  }
68
68
  });
69
69
 
70
- /**
71
- * 标准化字段配置(仅 columns:colKey/title)
72
- * 注意:模板对“嵌套 ref(对象属性里的 computed/ref)”不会自动解包,
73
- * 所以这里必须暴露为顶层 computed,避免 v-for 误迭代 computed 对象本身。
74
- */
75
- const normalizedFields = computed(() => {
76
- const row = props.data && typeof props.data === "object" ? props.data : null;
77
- const dataId = row && Object.hasOwn(row, "id") ? row.id : undefined;
78
-
79
- const rawFields = props.fields;
80
- const inputFields = Array.isArray(rawFields) ? rawFields : [];
81
- const excludeKeys = Array.isArray(props.excludeKeys) ? props.excludeKeys : [];
82
-
83
- const fields = inputFields
84
- .filter((item) => {
85
- return Boolean(item) && typeof item === "object";
86
- })
87
- .map((item) => {
88
- const colKey = item.colKey;
89
- if (item.colKey.length === 0) {
90
- return null;
91
- }
92
- if (excludeKeys.includes(item.colKey)) {
93
- return null;
94
- }
95
-
96
- return {
97
- colKey: item.colKey,
98
- title: item.title || item.colKey,
99
- default: item.default,
100
- format: item.format
101
- };
102
- })
103
- .filter((item) => {
104
- return Boolean(item);
105
- });
70
+ const $Method = {
71
+ buildNormalizedFields() {
72
+ const row = $Prop.data && typeof $Prop.data === "object" ? $Prop.data : null;
73
+ const dataId = row && Object.hasOwn(row, "id") ? row.id : undefined;
74
+
75
+ const rawFields = $Prop.fields;
76
+ const inputFields = Array.isArray(rawFields) ? rawFields : [];
77
+ const excludeKeys = Array.isArray($Prop.excludeKeys) ? $Prop.excludeKeys : [];
78
+
79
+ const fields = inputFields
80
+ .filter((item) => {
81
+ return Boolean(item) && typeof item === "object";
82
+ })
83
+ .map((item) => {
84
+ const colKey = item.colKey;
85
+ if (item.colKey.length === 0) {
86
+ return null;
87
+ }
88
+ if (excludeKeys.includes(item.colKey)) {
89
+ return null;
90
+ }
91
+
92
+ return {
93
+ colKey: item.colKey,
94
+ title: item.title || item.colKey,
95
+ default: item.default,
96
+ format: item.format
97
+ };
98
+ })
99
+ .filter((item) => {
100
+ return Boolean(item);
101
+ });
102
+
103
+ if (typeof dataId !== "undefined" && !fields.some((field) => field.colKey === "id")) {
104
+ fields.unshift({
105
+ colKey: "id",
106
+ title: "ID",
107
+ default: "-",
108
+ format: undefined
109
+ });
110
+ }
106
111
 
107
- // 约定:页面表格不展示 id,但右侧详情始终展示 id(如果 data.id 存在)
108
- if (typeof dataId !== "undefined" && !fields.some((f) => f.colKey === "id")) {
109
- fields.unshift({
110
- colKey: "id",
111
- title: "ID",
112
- default: "-",
113
- format: undefined
112
+ return fields.filter((item) => {
113
+ if (!item || typeof item !== "object") {
114
+ return false;
115
+ }
116
+ return item.colKey?.length > 0;
114
117
  });
115
118
  }
119
+ };
116
120
 
117
- const safeFields = fields.filter((item) => {
118
- if (!item || typeof item !== "object") {
119
- return false;
120
- }
121
- return item.colKey?.length > 0;
122
- });
123
-
124
- return safeFields;
121
+ const $Computed = reactive({
122
+ normalizedFields: computed(() => $Method.buildNormalizedFields())
125
123
  });
126
124
  </script>
127
125
 
@@ -1,19 +1,34 @@
1
1
  <template>
2
- <TDialog v-model:visible="innerVisible" :header="props.title === '' ? true : props.title" :width="props.width" :dialog-class-name="props.dialogClassName" placement="center" attach="body" :close-btn="false" :footer="true" :confirm-loading="props.confirmLoading" :close-on-overlay-click="false" :close-on-esc-keydown="false" @close="onDialogClose" @confirm="onDialogConfirm" @cancel="onDialogCancel">
2
+ <TDialog
3
+ v-model:visible="$Data.innerVisible"
4
+ :header="$Prop.title === '' ? true : $Prop.title"
5
+ :width="$Prop.width"
6
+ :dialog-class-name="$Prop.dialogClassName"
7
+ placement="center"
8
+ attach="body"
9
+ :close-btn="false"
10
+ :footer="true"
11
+ :confirm-loading="$Prop.confirmLoading"
12
+ :close-on-overlay-click="false"
13
+ :close-on-esc-keydown="false"
14
+ @close="$Method.onDialogClose"
15
+ @confirm="$Method.onDialogConfirm"
16
+ @cancel="$Method.onDialogCancel"
17
+ >
3
18
  <template #footer>
4
19
  <div class="dialog-footer">
5
- <TButton variant="outline" @click="onFooterClose">关闭</TButton>
6
- <TButton v-if="props.isConfirm" theme="primary" :loading="props.confirmLoading" @click="onFooterConfirm">确定</TButton>
20
+ <TButton variant="outline" @click="$Method.onFooterClose">关闭</TButton>
21
+ <TButton v-if="$Prop.isConfirm" theme="primary" :loading="$Prop.confirmLoading" @click="$Method.onFooterConfirm">确定</TButton>
7
22
  </div>
8
23
  </template>
9
24
  <div class="dialog-wrapper">
10
- <slot :visible="innerVisible" :open="open" :close="close" :toggle="toggle" />
25
+ <slot :visible="$Data.innerVisible" :open="$Method.open" :close="$Method.close" :toggle="$Method.toggle" />
11
26
  </div>
12
27
  </TDialog>
13
28
  </template>
14
29
 
15
30
  <script setup>
16
- import { onBeforeUnmount, onMounted, ref, watch } from "vue";
31
+ import { onBeforeUnmount, onMounted, reactive, watch } from "vue";
17
32
 
18
33
  import { Button as TButton, Dialog as TDialog } from "tdesign-vue-next";
19
34
 
@@ -21,10 +36,12 @@ defineOptions({
21
36
  inheritAttrs: false
22
37
  });
23
38
 
24
- const openDelay = 100;
25
- const closeDelay = 300;
39
+ const $Const = {
40
+ openDelay: 100,
41
+ closeDelay: 300
42
+ };
26
43
 
27
- const props = defineProps({
44
+ const $Prop = defineProps({
28
45
  modelValue: {
29
46
  type: Boolean,
30
47
  default: undefined
@@ -51,139 +68,136 @@ const props = defineProps({
51
68
  }
52
69
  });
53
70
 
54
- const emit = defineEmits(["update:modelValue", "close", "confirm", "cancel"]);
71
+ const $Emit = defineEmits(["update:modelValue", "close", "confirm", "cancel"]);
55
72
 
56
- let openDelayTimer = null;
57
- let closeDelayTimer = null;
73
+ const $From = {
74
+ openDelayTimer: null,
75
+ closeDelayTimer: null
76
+ };
58
77
 
59
- function clearTimer(timer) {
60
- if (timer) {
61
- clearTimeout(timer);
62
- }
63
- return null;
64
- }
65
-
66
- // 所有弹框约定:始终使用 v-if + v-model(modelValue)
67
- const innerVisible = ref(false);
68
-
69
- function open() {
70
- emit("update:modelValue", true);
71
- }
72
-
73
- function close() {
74
- openDelayTimer = clearTimer(openDelayTimer);
75
- closeDelayTimer = clearTimer(closeDelayTimer);
76
-
77
- innerVisible.value = false;
78
- // 延迟通知上层关闭:配合 v-if,保证离场动画播完再卸载
79
- closeDelayTimer = setTimeout(() => {
80
- emit("update:modelValue", false);
81
- closeDelayTimer = null;
82
- }, closeDelay);
83
- }
84
-
85
- function toggle() {
86
- if (innerVisible.value) {
87
- close();
88
- return;
89
- }
90
- open();
91
- }
78
+ const $Data = reactive({
79
+ innerVisible: false
80
+ });
92
81
 
93
- function createEventContext(trigger) {
94
- return {
95
- trigger: trigger,
96
- visible: innerVisible.value,
97
- open: open,
98
- close: close,
99
- toggle: toggle,
100
- getVisible: () => innerVisible.value
101
- };
102
- }
82
+ const $Method = {
83
+ clearTimer(timer) {
84
+ if (timer) {
85
+ clearTimeout(timer);
86
+ }
87
+ return null;
88
+ },
89
+ open() {
90
+ $Emit("update:modelValue", true);
91
+ },
92
+ close() {
93
+ $From.openDelayTimer = $Method.clearTimer($From.openDelayTimer);
94
+ $From.closeDelayTimer = $Method.clearTimer($From.closeDelayTimer);
95
+
96
+ $Data.innerVisible = false;
97
+ // 延迟通知上层关闭:配合 v-if,保证离场动画播完再卸载
98
+ $From.closeDelayTimer = setTimeout(() => {
99
+ $Emit("update:modelValue", false);
100
+ $From.closeDelayTimer = null;
101
+ }, $Const.closeDelay);
102
+ },
103
+ toggle() {
104
+ if ($Data.innerVisible) {
105
+ $Method.close();
106
+ return;
107
+ }
108
+ $Method.open();
109
+ },
110
+ createEventContext(trigger) {
111
+ return {
112
+ trigger: trigger,
113
+ visible: $Data.innerVisible,
114
+ open: $Method.open,
115
+ close: $Method.close,
116
+ toggle: $Method.toggle,
117
+ getVisible: () => $Data.innerVisible
118
+ };
119
+ },
120
+ applyModelValue(value) {
121
+ if (value) {
122
+ // 关键点:先渲染为 false,再延迟 true,保证 v-if + 初次 visible=true 时也能触发进入动画
123
+ $From.openDelayTimer = $Method.clearTimer($From.openDelayTimer);
124
+ $Data.innerVisible = false;
125
+ $From.openDelayTimer = setTimeout(() => {
126
+ $Data.innerVisible = true;
127
+ $From.openDelayTimer = null;
128
+ }, $Const.openDelay);
129
+ return;
130
+ }
103
131
 
104
- function applyModelValue(value) {
105
- if (value) {
106
- // 关键点:先渲染为 false,再延迟 true,保证 v-if + 初次 visible=true 时也能触发进入动画
107
- openDelayTimer = clearTimer(openDelayTimer);
108
- innerVisible.value = false;
109
- openDelayTimer = setTimeout(() => {
110
- innerVisible.value = true;
111
- openDelayTimer = null;
112
- }, openDelay);
113
- return;
132
+ $From.openDelayTimer = $Method.clearTimer($From.openDelayTimer);
133
+ $Data.innerVisible = false;
134
+ },
135
+ closeByTrigger(trigger) {
136
+ // 固定交互:confirm 不自动关闭(等待异步提交成功后由调用侧 context.close() 决定关闭)
137
+ if (trigger === "confirm") {
138
+ return;
139
+ }
140
+ // cancel/close 自动关闭
141
+ $Method.close();
142
+ },
143
+ onDialogClose() {
144
+ const context = $Method.createEventContext("close");
145
+ $Method.closeByTrigger("close");
146
+ $Emit("close", context);
147
+ },
148
+ onDialogConfirm() {
149
+ const context = $Method.createEventContext("confirm");
150
+ $Emit("confirm", context);
151
+ $Method.closeByTrigger("confirm");
152
+ },
153
+ onDialogCancel() {
154
+ const context = $Method.createEventContext("cancel");
155
+ $Emit("cancel", context);
156
+ $Method.closeByTrigger("cancel");
157
+ },
158
+ onFooterConfirm() {
159
+ const context = $Method.createEventContext("confirm");
160
+ $Emit("confirm", context);
161
+ $Method.closeByTrigger("confirm");
162
+ },
163
+ onFooterClose() {
164
+ const context = $Method.createEventContext("cancel");
165
+ $Emit("cancel", context);
166
+ $Method.closeByTrigger("cancel");
167
+ },
168
+ getVisible() {
169
+ return $Data.innerVisible;
114
170
  }
115
-
116
- openDelayTimer = clearTimer(openDelayTimer);
117
- innerVisible.value = false;
118
- }
171
+ };
119
172
 
120
173
  onMounted(() => {
121
- if (props.modelValue === true) {
122
- applyModelValue(true);
174
+ if ($Prop.modelValue === true) {
175
+ $Method.applyModelValue(true);
123
176
  }
124
177
  });
125
178
 
126
179
  onBeforeUnmount(() => {
127
- openDelayTimer = clearTimer(openDelayTimer);
128
- closeDelayTimer = clearTimer(closeDelayTimer);
180
+ $From.openDelayTimer = $Method.clearTimer($From.openDelayTimer);
181
+ $From.closeDelayTimer = $Method.clearTimer($From.closeDelayTimer);
129
182
  });
130
183
 
131
184
  watch(
132
- () => props.modelValue,
185
+ () => $Prop.modelValue,
133
186
  (value) => {
134
187
  if (value !== true && value !== false) {
135
188
  return;
136
189
  }
137
190
 
138
- applyModelValue(value);
191
+ $Method.applyModelValue(value);
139
192
  },
140
193
  { immediate: false }
141
194
  );
142
195
 
143
- function closeByTrigger(trigger) {
144
- // 固定交互:confirm 不自动关闭(等待异步提交成功后由调用侧 context.close() 决定关闭)
145
- if (trigger === "confirm") {
146
- return;
147
- }
148
- // cancel/close 自动关闭
149
- close();
150
- }
151
-
152
- function onDialogClose() {
153
- const context = createEventContext("close");
154
- closeByTrigger("close");
155
- emit("close", context);
156
- }
157
-
158
- function onDialogConfirm() {
159
- const context = createEventContext("confirm");
160
- emit("confirm", context);
161
- closeByTrigger("confirm");
162
- }
163
-
164
- function onDialogCancel() {
165
- const context = createEventContext("cancel");
166
- emit("cancel", context);
167
- closeByTrigger("cancel");
168
- }
169
-
170
- function onFooterConfirm() {
171
- const context = createEventContext("confirm");
172
- emit("confirm", context);
173
- closeByTrigger("confirm");
174
- }
175
-
176
- function onFooterClose() {
177
- const context = createEventContext("cancel");
178
- emit("cancel", context);
179
- closeByTrigger("cancel");
180
- }
181
-
182
196
  defineExpose({
183
- open: open,
184
- close: close,
185
- toggle: toggle,
186
- getVisible: () => innerVisible.value
197
+ open: $Method.open,
198
+ close: $Method.close,
199
+ toggle: $Method.toggle,
200
+ getVisible: $Method.getVisible
187
201
  });
188
202
  </script>
189
203