befly-admin-ui 1.10.0 → 1.10.2
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/components/detailPanel.vue +52 -54
- package/components/pageDialog.vue +131 -117
- package/components/pageTableDetail.vue +381 -398
- package/layouts/default.vue +212 -215
- package/package.json +2 -2
- package/views/config/dict/components/edit.vue +83 -60
- package/views/config/dict/index.vue +53 -68
- package/views/config/dictType/components/edit.vue +81 -57
- package/views/config/dictType/index.vue +39 -51
- package/views/config/system/components/edit.vue +97 -86
- package/views/config/system/index.vue +37 -51
- package/views/index/components/addonList.vue +14 -11
- package/views/index/components/environmentInfo.vue +25 -22
- package/views/index/components/operationLogs.vue +20 -16
- package/views/index/components/performanceMetrics.vue +24 -21
- package/views/index/components/serviceStatus.vue +26 -22
- package/views/index/components/systemNotifications.vue +24 -19
- package/views/index/components/systemOverview.vue +368 -385
- package/views/index/components/systemResources.vue +22 -19
- package/views/index/components/userInfo.vue +56 -56
- package/views/log/email/index.vue +99 -100
- package/views/log/error/index.vue +112 -130
- package/views/log/login/index.vue +17 -28
- package/views/log/operate/index.vue +33 -46
- package/views/login_1/index.vue +50 -32
- package/views/people/admin/components/edit.vue +1 -1
- package/views/people/admin/index.vue +28 -29
- package/views/permission/api/index.vue +46 -58
- package/views/permission/menu/index.vue +46 -52
- package/views/permission/role/components/api.vue +143 -144
- package/views/permission/role/components/edit.vue +74 -52
- package/views/permission/role/components/menu.vue +119 -121
- package/views/permission/role/index.vue +49 -63
- package/views/resource/gallery/index.vue +78 -88
|
@@ -1,51 +1,43 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<PageTableDetail class="page-error-log page-table" :columns="$Data.columns" :endpoints="$Data.endpoints" :table-slot-names="['errorType', 'reportTime', 'firstReportTime', 'source', 'message', 'hitCount', 'deviceType']">
|
|
3
3
|
<template #toolLeft="scope">
|
|
4
|
-
<TInput v-model="$Data.filter.keyword" clearable placeholder="搜索页面/产品/消息/类型" style="width: 220px" @enter="handleFilter(scope.reload)" @clear="handleFilter(scope.reload)">
|
|
4
|
+
<TInput v-model="$Data.filter.keyword" clearable placeholder="搜索页面/产品/消息/类型" style="width: 220px" @enter="$Method.handleFilter(scope.reload)" @clear="$Method.handleFilter(scope.reload)">
|
|
5
5
|
<template #suffix-icon>
|
|
6
6
|
<SearchIcon />
|
|
7
7
|
</template>
|
|
8
8
|
</TInput>
|
|
9
|
-
<TSelect v-model="$Data.filter.errorType" clearable placeholder="错误类型" style="width: 150px" @change="handleFilter(scope.reload)">
|
|
9
|
+
<TSelect v-model="$Data.filter.errorType" clearable placeholder="错误类型" style="width: 150px" @change="$Method.handleFilter(scope.reload)">
|
|
10
10
|
<TOption label="Vue" value="vue" />
|
|
11
11
|
<TOption label="Window" value="window" />
|
|
12
12
|
<TOption label="Promise" value="promise" />
|
|
13
13
|
<TOption label="Unknown" value="unknown" />
|
|
14
14
|
</TSelect>
|
|
15
|
-
<TSelect v-model="$Data.filter.source" clearable placeholder="来源" style="width: 140px" @change="handleFilter(scope.reload)">
|
|
15
|
+
<TSelect v-model="$Data.filter.source" clearable placeholder="来源" style="width: 140px" @change="$Method.handleFilter(scope.reload)">
|
|
16
16
|
<TOption label="Admin" value="admin" />
|
|
17
17
|
</TSelect>
|
|
18
|
-
<TInput v-model="$Data.filter.productName" clearable placeholder="产品名称" style="width: 160px" @enter="handleFilter(scope.reload)" @clear="handleFilter(scope.reload)" />
|
|
19
|
-
<TInput v-model="$Data.filter.productCode" clearable placeholder="产品代号" style="width: 160px" @enter="handleFilter(scope.reload)" @clear="handleFilter(scope.reload)" />
|
|
20
|
-
<TInput v-model="$Data.filter.productVersion" clearable placeholder="产品版本" style="width: 160px" @enter="handleFilter(scope.reload)" @clear="handleFilter(scope.reload)" />
|
|
21
|
-
<TSelect v-model="$Data.filter.deviceType" clearable placeholder="设备类型" style="width: 140px" @change="handleFilter(scope.reload)">
|
|
18
|
+
<TInput v-model="$Data.filter.productName" clearable placeholder="产品名称" style="width: 160px" @enter="$Method.handleFilter(scope.reload)" @clear="$Method.handleFilter(scope.reload)" />
|
|
19
|
+
<TInput v-model="$Data.filter.productCode" clearable placeholder="产品代号" style="width: 160px" @enter="$Method.handleFilter(scope.reload)" @clear="$Method.handleFilter(scope.reload)" />
|
|
20
|
+
<TInput v-model="$Data.filter.productVersion" clearable placeholder="产品版本" style="width: 160px" @enter="$Method.handleFilter(scope.reload)" @clear="$Method.handleFilter(scope.reload)" />
|
|
21
|
+
<TSelect v-model="$Data.filter.deviceType" clearable placeholder="设备类型" style="width: 140px" @change="$Method.handleFilter(scope.reload)">
|
|
22
22
|
<TOption label="桌面端" value="desktop" />
|
|
23
23
|
<TOption label="移动端" value="mobile" />
|
|
24
24
|
<TOption label="平板" value="tablet" />
|
|
25
25
|
<TOption label="电视" value="smarttv" />
|
|
26
26
|
</TSelect>
|
|
27
|
-
<TInput v-model="$Data.filter.browserName" clearable placeholder="浏览器" style="width: 160px" @enter="handleFilter(scope.reload)" @clear="handleFilter(scope.reload)" />
|
|
28
|
-
<TInput v-model="$Data.filter.osName" clearable placeholder="操作系统" style="width: 160px" @enter="handleFilter(scope.reload)" @clear="handleFilter(scope.reload)" />
|
|
29
|
-
</template>
|
|
30
|
-
|
|
31
|
-
<template #toolRight="scope">
|
|
32
|
-
<TButton shape="circle" @click="onReload(scope.reload)">
|
|
33
|
-
<template #icon>
|
|
34
|
-
<RefreshIcon />
|
|
35
|
-
</template>
|
|
36
|
-
</TButton>
|
|
27
|
+
<TInput v-model="$Data.filter.browserName" clearable placeholder="浏览器" style="width: 160px" @enter="$Method.handleFilter(scope.reload)" @clear="$Method.handleFilter(scope.reload)" />
|
|
28
|
+
<TInput v-model="$Data.filter.osName" clearable placeholder="操作系统" style="width: 160px" @enter="$Method.handleFilter(scope.reload)" @clear="$Method.handleFilter(scope.reload)" />
|
|
37
29
|
</template>
|
|
38
30
|
|
|
39
31
|
<template #errorType="{ row }">
|
|
40
|
-
<TTag shape="round" :theme="getErrorTheme(row.errorType)" variant="light-outline">{{ formatErrorType(row.errorType) }}</TTag>
|
|
32
|
+
<TTag shape="round" :theme="$Method.getErrorTheme(row.errorType)" variant="light-outline">{{ $Method.formatErrorType(row.errorType) }}</TTag>
|
|
41
33
|
</template>
|
|
42
34
|
|
|
43
35
|
<template #reportTime="{ row }">
|
|
44
|
-
{{ formatTime(row.reportTime) }}
|
|
36
|
+
{{ $Method.formatTime(row.reportTime) }}
|
|
45
37
|
</template>
|
|
46
38
|
|
|
47
39
|
<template #firstReportTime="{ row }">
|
|
48
|
-
{{ formatTime(row.firstReportTime) }}
|
|
40
|
+
{{ $Method.formatTime(row.firstReportTime) }}
|
|
49
41
|
</template>
|
|
50
42
|
|
|
51
43
|
<template #source="{ row }">
|
|
@@ -57,7 +49,7 @@
|
|
|
57
49
|
</template>
|
|
58
50
|
|
|
59
51
|
<template #deviceType="{ row }">
|
|
60
|
-
<TTag shape="round" variant="light-outline">{{ formatDeviceType(row.deviceType) }}</TTag>
|
|
52
|
+
<TTag shape="round" variant="light-outline">{{ $Method.formatDeviceType(row.deviceType) }}</TTag>
|
|
61
53
|
</template>
|
|
62
54
|
|
|
63
55
|
<template #message="{ row }">
|
|
@@ -67,13 +59,13 @@
|
|
|
67
59
|
<template #detail="scope">
|
|
68
60
|
<DetailPanel :data="scope.row" :fields="$Data.columns">
|
|
69
61
|
<template #errorType="slotScope">
|
|
70
|
-
<TTag shape="round" :theme="getErrorTheme(slotScope.value)" variant="light-outline">{{ formatErrorType(slotScope.value) }}</TTag>
|
|
62
|
+
<TTag shape="round" :theme="$Method.getErrorTheme(slotScope.value)" variant="light-outline">{{ $Method.formatErrorType(slotScope.value) }}</TTag>
|
|
71
63
|
</template>
|
|
72
64
|
<template #reportTime="slotScope">
|
|
73
|
-
{{ formatTime(slotScope.value) }}
|
|
65
|
+
{{ $Method.formatTime(slotScope.value) }}
|
|
74
66
|
</template>
|
|
75
67
|
<template #firstReportTime="slotScope">
|
|
76
|
-
{{ formatTime(slotScope.value) }}
|
|
68
|
+
{{ $Method.formatTime(slotScope.value) }}
|
|
77
69
|
</template>
|
|
78
70
|
<template #source="slotScope">
|
|
79
71
|
<TTag shape="round" variant="light-outline">{{ slotScope.value || "admin" }}</TTag>
|
|
@@ -82,16 +74,16 @@
|
|
|
82
74
|
<TTag shape="round" theme="warning" variant="light-outline">{{ slotScope.value || 1 }} 次</TTag>
|
|
83
75
|
</template>
|
|
84
76
|
<template #deviceType="slotScope">
|
|
85
|
-
<TTag shape="round" variant="light-outline">{{ formatDeviceType(slotScope.value) }}</TTag>
|
|
77
|
+
<TTag shape="round" variant="light-outline">{{ $Method.formatDeviceType(slotScope.value) }}</TTag>
|
|
86
78
|
</template>
|
|
87
79
|
<template #detail="slotScope">
|
|
88
80
|
<div class="detail-actions">
|
|
89
|
-
<TButton theme="primary" variant="outline" size="small" @click="handleCopyDetail(scope.row.detail)">复制详情</TButton>
|
|
90
|
-
<TButton theme="default" variant="outline" size="small" @click="toggleDetailExpand(scope.row.id)">
|
|
91
|
-
{{ isDetailExpanded(scope.row.id) ? "收起详情" : "展开详情" }}
|
|
81
|
+
<TButton theme="primary" variant="outline" size="small" @click="$Method.handleCopyDetail(scope.row.detail)">复制详情</TButton>
|
|
82
|
+
<TButton theme="default" variant="outline" size="small" @click="$Method.toggleDetailExpand(scope.row.id)">
|
|
83
|
+
{{ $Method.isDetailExpanded(scope.row.id) ? "收起详情" : "展开详情" }}
|
|
92
84
|
</TButton>
|
|
93
85
|
</div>
|
|
94
|
-
<pre class="detail-content" :class="{ expanded: isDetailExpanded(scope.row.id) }">{{ formatDetail(slotScope.value) }}</pre>
|
|
86
|
+
<pre class="detail-content" :class="{ expanded: $Method.isDetailExpanded(scope.row.id) }">{{ $Method.formatDetail(slotScope.value) }}</pre>
|
|
95
87
|
</template>
|
|
96
88
|
</DetailPanel>
|
|
97
89
|
</template>
|
|
@@ -101,7 +93,7 @@
|
|
|
101
93
|
<script setup>
|
|
102
94
|
import { reactive } from "vue";
|
|
103
95
|
import { Button as TButton, Input as TInput, MessagePlugin, Option as TOption, Select as TSelect, Tag as TTag } from "tdesign-vue-next";
|
|
104
|
-
import {
|
|
96
|
+
import { SearchIcon } from "tdesign-icons-vue-next";
|
|
105
97
|
import DetailPanel from "befly-admin-ui/components/detailPanel.vue";
|
|
106
98
|
import PageTableDetail from "befly-admin-ui/components/pageTableDetail.vue";
|
|
107
99
|
import { withDefaultColumns } from "befly-admin-ui/utils/withDefaultColumns";
|
|
@@ -177,125 +169,115 @@ const $Data = reactive({
|
|
|
177
169
|
detailExpandedId: 0
|
|
178
170
|
});
|
|
179
171
|
|
|
180
|
-
|
|
181
|
-
reload
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
return Number($Data.detailExpandedId) === Number(id || 0);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
function toggleDetailExpand(id) {
|
|
193
|
-
const nextId = Number(id || 0);
|
|
194
|
-
|
|
195
|
-
if (Number($Data.detailExpandedId) === nextId) {
|
|
196
|
-
$Data.detailExpandedId = 0;
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
$Data.detailExpandedId = nextId;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
async function handleCopyDetail(value) {
|
|
204
|
-
const text = formatDetail(value);
|
|
205
|
-
if (text === "-") {
|
|
206
|
-
MessagePlugin.warning("暂无可复制的错误详情");
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
try {
|
|
211
|
-
await navigator.clipboard.writeText(text);
|
|
212
|
-
MessagePlugin.success("错误详情已复制");
|
|
213
|
-
} catch (_error) {
|
|
214
|
-
MessagePlugin.error("复制失败,请检查浏览器剪贴板权限");
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function getErrorTheme(errorType) {
|
|
219
|
-
if (errorType === "vue") {
|
|
220
|
-
return "danger";
|
|
221
|
-
}
|
|
172
|
+
const $Method = {
|
|
173
|
+
handleFilter(reload) {
|
|
174
|
+
reload({ keepSelection: false, resetPage: true });
|
|
175
|
+
},
|
|
176
|
+
isDetailExpanded(id) {
|
|
177
|
+
return Number($Data.detailExpandedId) === Number(id || 0);
|
|
178
|
+
},
|
|
179
|
+
toggleDetailExpand(id) {
|
|
180
|
+
const nextId = Number(id || 0);
|
|
222
181
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
182
|
+
if (Number($Data.detailExpandedId) === nextId) {
|
|
183
|
+
$Data.detailExpandedId = 0;
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
226
186
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
187
|
+
$Data.detailExpandedId = nextId;
|
|
188
|
+
},
|
|
189
|
+
async handleCopyDetail(value) {
|
|
190
|
+
const text = $Method.formatDetail(value);
|
|
191
|
+
if (text === "-") {
|
|
192
|
+
MessagePlugin.warning("暂无可复制的错误详情");
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
230
195
|
|
|
231
|
-
|
|
232
|
-
|
|
196
|
+
try {
|
|
197
|
+
await navigator.clipboard.writeText(text);
|
|
198
|
+
MessagePlugin.success("错误详情已复制");
|
|
199
|
+
} catch (_error) {
|
|
200
|
+
MessagePlugin.error("复制失败,请检查浏览器剪贴板权限");
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
getErrorTheme(errorType) {
|
|
204
|
+
if (errorType === "vue") {
|
|
205
|
+
return "danger";
|
|
206
|
+
}
|
|
233
207
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
208
|
+
if (errorType === "promise") {
|
|
209
|
+
return "warning";
|
|
210
|
+
}
|
|
238
211
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
212
|
+
if (errorType === "window") {
|
|
213
|
+
return "primary";
|
|
214
|
+
}
|
|
242
215
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
216
|
+
return "default";
|
|
217
|
+
},
|
|
218
|
+
formatErrorType(errorType) {
|
|
219
|
+
if (errorType === "vue") {
|
|
220
|
+
return "Vue";
|
|
221
|
+
}
|
|
246
222
|
|
|
247
|
-
|
|
248
|
-
|
|
223
|
+
if (errorType === "window") {
|
|
224
|
+
return "Window";
|
|
225
|
+
}
|
|
249
226
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
227
|
+
if (errorType === "promise") {
|
|
228
|
+
return "Promise";
|
|
229
|
+
}
|
|
254
230
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
231
|
+
return errorType || "Unknown";
|
|
232
|
+
},
|
|
233
|
+
formatDeviceType(deviceType) {
|
|
234
|
+
if (deviceType === "desktop") {
|
|
235
|
+
return "桌面端";
|
|
236
|
+
}
|
|
258
237
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
238
|
+
if (deviceType === "mobile") {
|
|
239
|
+
return "移动端";
|
|
240
|
+
}
|
|
262
241
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
242
|
+
if (deviceType === "tablet") {
|
|
243
|
+
return "平板";
|
|
244
|
+
}
|
|
266
245
|
|
|
267
|
-
|
|
268
|
-
|
|
246
|
+
if (deviceType === "smarttv") {
|
|
247
|
+
return "电视";
|
|
248
|
+
}
|
|
269
249
|
|
|
270
|
-
|
|
271
|
-
|
|
250
|
+
return deviceType || "Unknown";
|
|
251
|
+
},
|
|
252
|
+
formatTime(timestamp) {
|
|
253
|
+
const value = Number(timestamp || 0);
|
|
272
254
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
255
|
+
if (!value) {
|
|
256
|
+
return "-";
|
|
257
|
+
}
|
|
276
258
|
|
|
277
|
-
|
|
259
|
+
const date = new Date(value);
|
|
278
260
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
261
|
+
if (Number.isNaN(date.getTime())) {
|
|
262
|
+
return "-";
|
|
263
|
+
}
|
|
282
264
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
265
|
+
const year = date.getFullYear();
|
|
266
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
267
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
268
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
269
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
270
|
+
const seconds = String(date.getSeconds()).padStart(2, "0");
|
|
271
|
+
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
272
|
+
},
|
|
273
|
+
formatDetail(value) {
|
|
274
|
+
if (!value) {
|
|
275
|
+
return "-";
|
|
276
|
+
}
|
|
291
277
|
|
|
292
|
-
|
|
293
|
-
if (!value) {
|
|
294
|
-
return "-";
|
|
278
|
+
return String(value);
|
|
295
279
|
}
|
|
296
|
-
|
|
297
|
-
return String(value);
|
|
298
|
-
}
|
|
280
|
+
};
|
|
299
281
|
</script>
|
|
300
282
|
|
|
301
283
|
<style scoped lang="scss">
|
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<PageTableDetail class="page-login-log page-table" :columns="$Data.columns" :endpoints="$Data.endpoints" :table-slot-names="['loginResult', 'loginTime', 'deviceType']">
|
|
3
|
-
<template #toolRight="scope">
|
|
4
|
-
<TButton shape="circle" @click="onReload(scope.reload)">
|
|
5
|
-
<template #icon>
|
|
6
|
-
<RefreshIcon />
|
|
7
|
-
</template>
|
|
8
|
-
</TButton>
|
|
9
|
-
</template>
|
|
10
|
-
|
|
11
3
|
<template #loginResult="{ row }">
|
|
12
4
|
<TTag v-if="row.loginResult === 1" shape="round" theme="success" variant="light-outline">成功</TTag>
|
|
13
5
|
<TTag v-else shape="round" theme="danger" variant="light-outline">失败</TTag>
|
|
14
6
|
</template>
|
|
15
7
|
|
|
16
8
|
<template #loginTime="{ row }">
|
|
17
|
-
{{ formatTime(row.loginTime) }}
|
|
9
|
+
{{ $Method.formatTime(row.loginTime) }}
|
|
18
10
|
</template>
|
|
19
11
|
|
|
20
12
|
<template #deviceType="{ row }">
|
|
@@ -28,7 +20,7 @@
|
|
|
28
20
|
<TTag v-else shape="round" theme="danger" variant="light-outline">失败</TTag>
|
|
29
21
|
</template>
|
|
30
22
|
<template #loginTime="slotScope">
|
|
31
|
-
{{ formatTime(slotScope.value) }}
|
|
23
|
+
{{ $Method.formatTime(slotScope.value) }}
|
|
32
24
|
</template>
|
|
33
25
|
<template #deviceType="slotScope">
|
|
34
26
|
<TTag shape="round" variant="light-outline">{{ slotScope.value || "desktop" }}</TTag>
|
|
@@ -40,8 +32,7 @@
|
|
|
40
32
|
|
|
41
33
|
<script setup>
|
|
42
34
|
import { reactive } from "vue";
|
|
43
|
-
import {
|
|
44
|
-
import { RefreshIcon } from "tdesign-icons-vue-next";
|
|
35
|
+
import { Tag as TTag } from "tdesign-vue-next";
|
|
45
36
|
import DetailPanel from "befly-admin-ui/components/detailPanel.vue";
|
|
46
37
|
import PageTableDetail from "befly-admin-ui/components/pageTableDetail.vue";
|
|
47
38
|
import { withDefaultColumns } from "befly-admin-ui/utils/withDefaultColumns";
|
|
@@ -68,27 +59,25 @@ const $Data = reactive({
|
|
|
68
59
|
]),
|
|
69
60
|
endpoints: {
|
|
70
61
|
list: {
|
|
71
|
-
path: "/core/loginLog/
|
|
62
|
+
path: "/core/loginLog/select",
|
|
72
63
|
dropValues: [""]
|
|
73
64
|
}
|
|
74
65
|
}
|
|
75
66
|
});
|
|
76
67
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
91
|
-
}
|
|
68
|
+
const $Method = {
|
|
69
|
+
formatTime(timestamp) {
|
|
70
|
+
if (!timestamp) return "-";
|
|
71
|
+
const date = new Date(timestamp);
|
|
72
|
+
const year = date.getFullYear();
|
|
73
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
74
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
75
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
76
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
77
|
+
const seconds = String(date.getSeconds()).padStart(2, "0");
|
|
78
|
+
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
92
81
|
</script>
|
|
93
82
|
|
|
94
83
|
<style scoped lang="scss">
|
|
@@ -1,33 +1,25 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<PageTableDetail class="page-operate-log page-table" :columns="$Data.columns" :endpoints="$Data.endpoints" :table-slot-names="['result', 'operateTime', 'duration', 'action']">
|
|
3
3
|
<template #toolLeft="scope">
|
|
4
|
-
<TSelect v-model="$Data.filter.module" placeholder="操作模块" clearable style="width: 150px" @change="handleFilter(scope.reload)">
|
|
4
|
+
<TSelect v-model="$Data.filter.module" placeholder="操作模块" clearable style="width: 150px" @change="$Method.handleFilter(scope.reload)">
|
|
5
5
|
<TOption v-for="item in $Data.moduleOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
6
6
|
</TSelect>
|
|
7
|
-
<TSelect v-model="$Data.filter.action" placeholder="操作类型" clearable style="width: 150px" @change="handleFilter(scope.reload)">
|
|
7
|
+
<TSelect v-model="$Data.filter.action" placeholder="操作类型" clearable style="width: 150px" @change="$Method.handleFilter(scope.reload)">
|
|
8
8
|
<TOption v-for="item in $Data.actionOptions" :key="item.value" :label="item.label" :value="item.value" />
|
|
9
9
|
</TSelect>
|
|
10
|
-
<TSelect v-model="$Data.filter.result" placeholder="操作结果" clearable style="width: 120px" @change="handleFilter(scope.reload)">
|
|
10
|
+
<TSelect v-model="$Data.filter.result" placeholder="操作结果" clearable style="width: 120px" @change="$Method.handleFilter(scope.reload)">
|
|
11
11
|
<TOption label="成功" :value="1" />
|
|
12
12
|
<TOption label="失败" :value="0" />
|
|
13
13
|
</TSelect>
|
|
14
14
|
</template>
|
|
15
15
|
|
|
16
|
-
<template #toolRight="scope">
|
|
17
|
-
<TButton shape="circle" @click="onReload(scope.reload)">
|
|
18
|
-
<template #icon>
|
|
19
|
-
<RefreshIcon />
|
|
20
|
-
</template>
|
|
21
|
-
</TButton>
|
|
22
|
-
</template>
|
|
23
|
-
|
|
24
16
|
<template #result="{ row }">
|
|
25
17
|
<TTag v-if="row.result === 1" shape="round" theme="success" variant="light-outline">成功</TTag>
|
|
26
18
|
<TTag v-else shape="round" theme="danger" variant="light-outline">失败</TTag>
|
|
27
19
|
</template>
|
|
28
20
|
|
|
29
21
|
<template #operateTime="{ row }">
|
|
30
|
-
{{ formatTime(row.operateTime) }}
|
|
22
|
+
{{ $Method.formatTime(row.operateTime) }}
|
|
31
23
|
</template>
|
|
32
24
|
|
|
33
25
|
<template #duration="{ row }">
|
|
@@ -45,16 +37,16 @@
|
|
|
45
37
|
<TTag v-else shape="round" theme="danger" variant="light-outline">失败</TTag>
|
|
46
38
|
</template>
|
|
47
39
|
<template #operateTime="slotScope">
|
|
48
|
-
{{ formatTime(slotScope.value) }}
|
|
40
|
+
{{ $Method.formatTime(slotScope.value) }}
|
|
49
41
|
</template>
|
|
50
42
|
<template #duration="slotScope">
|
|
51
43
|
<TTag shape="round" :theme="slotScope.value > 1000 ? 'warning' : 'default'" variant="light-outline">{{ slotScope.value }}ms</TTag>
|
|
52
44
|
</template>
|
|
53
45
|
<template #params="slotScope">
|
|
54
|
-
<pre class="json-content">{{ formatJson(slotScope.value) }}</pre>
|
|
46
|
+
<pre class="json-content">{{ $Method.formatJson(slotScope.value) }}</pre>
|
|
55
47
|
</template>
|
|
56
48
|
<template #response="slotScope">
|
|
57
|
-
<pre class="json-content">{{ formatJson(slotScope.value) }}</pre>
|
|
49
|
+
<pre class="json-content">{{ $Method.formatJson(slotScope.value) }}</pre>
|
|
58
50
|
</template>
|
|
59
51
|
</DetailPanel>
|
|
60
52
|
</template>
|
|
@@ -63,8 +55,7 @@
|
|
|
63
55
|
|
|
64
56
|
<script setup>
|
|
65
57
|
import { reactive } from "vue";
|
|
66
|
-
import {
|
|
67
|
-
import { RefreshIcon } from "tdesign-icons-vue-next";
|
|
58
|
+
import { Option as TOption, Select as TSelect, Tag as TTag } from "tdesign-vue-next";
|
|
68
59
|
import DetailPanel from "befly-admin-ui/components/detailPanel.vue";
|
|
69
60
|
import PageTableDetail from "befly-admin-ui/components/pageTableDetail.vue";
|
|
70
61
|
import { withDefaultColumns } from "befly-admin-ui/utils/withDefaultColumns";
|
|
@@ -88,7 +79,7 @@ const $Data = reactive({
|
|
|
88
79
|
]),
|
|
89
80
|
endpoints: {
|
|
90
81
|
list: {
|
|
91
|
-
path: "/core/operateLog/
|
|
82
|
+
path: "/core/operateLog/select",
|
|
92
83
|
dropValues: [""],
|
|
93
84
|
dropKeyValue: {
|
|
94
85
|
module: [""],
|
|
@@ -123,35 +114,31 @@ const $Data = reactive({
|
|
|
123
114
|
]
|
|
124
115
|
});
|
|
125
116
|
|
|
126
|
-
|
|
127
|
-
reload
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const obj = typeof value === "string" ? JSON.parse(value) : value;
|
|
150
|
-
return JSON.stringify(obj, null, 2);
|
|
151
|
-
} catch {
|
|
152
|
-
return String(value);
|
|
117
|
+
const $Method = {
|
|
118
|
+
handleFilter(reload) {
|
|
119
|
+
reload({ keepSelection: false, resetPage: true });
|
|
120
|
+
},
|
|
121
|
+
formatTime(timestamp) {
|
|
122
|
+
if (!timestamp) return "-";
|
|
123
|
+
const date = new Date(timestamp);
|
|
124
|
+
const year = date.getFullYear();
|
|
125
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
126
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
127
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
128
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
129
|
+
const seconds = String(date.getSeconds()).padStart(2, "0");
|
|
130
|
+
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
131
|
+
},
|
|
132
|
+
formatJson(value) {
|
|
133
|
+
if (!value) return "-";
|
|
134
|
+
try {
|
|
135
|
+
const obj = typeof value === "string" ? JSON.parse(value) : value;
|
|
136
|
+
return JSON.stringify(obj, null, 2);
|
|
137
|
+
} catch {
|
|
138
|
+
return String(value);
|
|
139
|
+
}
|
|
153
140
|
}
|
|
154
|
-
}
|
|
141
|
+
};
|
|
155
142
|
</script>
|
|
156
143
|
|
|
157
144
|
<style scoped lang="scss">
|