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.
- package/components/detailPanel.vue +52 -54
- package/components/pageDialog.vue +131 -117
- package/components/pageTableDetail.vue +381 -402
- 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 +51 -55
- package/views/config/dictType/components/edit.vue +81 -57
- package/views/config/dictType/index.vue +37 -39
- package/views/config/system/components/edit.vue +97 -86
- package/views/config/system/index.vue +35 -37
- 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 +96 -85
- package/views/log/error/index.vue +111 -117
- package/views/log/login/index.vue +15 -13
- package/views/log/operate/index.vue +31 -31
- package/views/login_1/index.vue +50 -32
- package/views/people/admin/components/edit.vue +1 -1
- package/views/people/admin/index.vue +27 -28
- package/views/permission/api/index.vue +44 -45
- package/views/permission/menu/index.vue +35 -35
- 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 +47 -49
- package/views/resource/gallery/index.vue +77 -78
- package/LICENSE +0 -201
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<PageDialog v-model="dialogVisible" :title="$
|
|
3
|
-
<TForm
|
|
2
|
+
<PageDialog v-model="$Computed.dialogVisible" :title="$Computed.dialogTitle" :confirm-loading="$Data.submitting" @confirm="$Method.onSubmit">
|
|
3
|
+
<TForm
|
|
4
|
+
:model="$Data.formData"
|
|
5
|
+
label-width="120px"
|
|
6
|
+
label-position="left"
|
|
7
|
+
:rules="$Const.formRules"
|
|
8
|
+
:ref="
|
|
9
|
+
(value) => {
|
|
10
|
+
$From.formRef = value;
|
|
11
|
+
}
|
|
12
|
+
"
|
|
13
|
+
>
|
|
4
14
|
<TFormItem label="配置名称" prop="name">
|
|
5
15
|
<TInput v-model="$Data.formData.name" placeholder="请输入配置名称" :disabled="$Data.isSystem" />
|
|
6
16
|
</TFormItem>
|
|
@@ -21,7 +31,7 @@
|
|
|
21
31
|
</TFormItem>
|
|
22
32
|
<TFormItem label="配置分组" prop="group">
|
|
23
33
|
<TSelect v-model="$Data.formData.group" placeholder="请选择分组" clearable :disabled="$Data.isSystem">
|
|
24
|
-
<TOption v-for="item in $
|
|
34
|
+
<TOption v-for="item in $Const.groupOptions" :key="item" :label="item" :value="item" />
|
|
25
35
|
</TSelect>
|
|
26
36
|
</TFormItem>
|
|
27
37
|
<TFormItem label="排序" prop="sort">
|
|
@@ -41,11 +51,11 @@
|
|
|
41
51
|
</template>
|
|
42
52
|
|
|
43
53
|
<script setup>
|
|
44
|
-
import { computed, reactive
|
|
54
|
+
import { computed, reactive } from "vue";
|
|
45
55
|
|
|
46
56
|
import { Form as TForm, FormItem as TFormItem, Input as TInput, Textarea as TTextarea, InputNumber as TInputNumber, Select as TSelect, Option as TOption, RadioGroup as TRadioGroup, Radio as TRadio, MessagePlugin } from "tdesign-vue-next";
|
|
47
57
|
import PageDialog from "befly-admin-ui/components/pageDialog.vue";
|
|
48
|
-
import { $Http } from "@/plugins/http";
|
|
58
|
+
import { $Http } from "@/plugins/http.js";
|
|
49
59
|
|
|
50
60
|
const $Prop = defineProps({
|
|
51
61
|
modelValue: {
|
|
@@ -64,33 +74,20 @@ const $Prop = defineProps({
|
|
|
64
74
|
|
|
65
75
|
const $Emit = defineEmits(["update:modelValue", "success"]);
|
|
66
76
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
id: 0,
|
|
82
|
-
name: "",
|
|
83
|
-
code: "",
|
|
84
|
-
value: "",
|
|
85
|
-
valueType: "string",
|
|
86
|
-
group: "",
|
|
87
|
-
sort: 0,
|
|
88
|
-
description: "",
|
|
89
|
-
state: 1
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
const $Data2 = reactive({
|
|
77
|
+
const $Const = {
|
|
78
|
+
createDefaultFormData() {
|
|
79
|
+
return {
|
|
80
|
+
id: 0,
|
|
81
|
+
name: "",
|
|
82
|
+
code: "",
|
|
83
|
+
value: "",
|
|
84
|
+
valueType: "string",
|
|
85
|
+
group: "",
|
|
86
|
+
sort: 0,
|
|
87
|
+
description: "",
|
|
88
|
+
state: 1
|
|
89
|
+
};
|
|
90
|
+
},
|
|
94
91
|
formRules: {
|
|
95
92
|
name: [{ required: true, message: "请输入配置名称", trigger: "blur" }],
|
|
96
93
|
code: [
|
|
@@ -101,69 +98,83 @@ const $Data2 = reactive({
|
|
|
101
98
|
valueType: [{ required: true, message: "请选择值类型", trigger: "change" }]
|
|
102
99
|
},
|
|
103
100
|
groupOptions: ["基础配置", "邮件配置", "存储配置", "安全配置", "其他"]
|
|
104
|
-
}
|
|
101
|
+
};
|
|
105
102
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
103
|
+
const $From = {
|
|
104
|
+
formRef: null
|
|
105
|
+
};
|
|
109
106
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
$Data.formData.code = row["code"] || "";
|
|
116
|
-
$Data.formData.value = row["value"] || "";
|
|
117
|
-
$Data.formData.valueType = row["valueType"] || "string";
|
|
118
|
-
$Data.formData.group = row["group"] || "";
|
|
119
|
-
$Data.formData.sort = row["sort"] || 0;
|
|
120
|
-
$Data.formData.description = row["description"] || "";
|
|
121
|
-
$Data.formData.state = row["state"] || 1;
|
|
122
|
-
$Data.isSystem = row["isSystem"] === 1;
|
|
123
|
-
} else {
|
|
124
|
-
$Data.formData = {
|
|
125
|
-
id: 0,
|
|
126
|
-
name: "",
|
|
127
|
-
code: "",
|
|
128
|
-
value: "",
|
|
129
|
-
valueType: "string",
|
|
130
|
-
group: "",
|
|
131
|
-
sort: 0,
|
|
132
|
-
description: "",
|
|
133
|
-
state: 1
|
|
134
|
-
};
|
|
135
|
-
$Data.isSystem = false;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
107
|
+
const $Data = reactive({
|
|
108
|
+
submitting: false,
|
|
109
|
+
isSystem: false,
|
|
110
|
+
formData: $Const.createDefaultFormData()
|
|
111
|
+
});
|
|
138
112
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
113
|
+
const $Computed = reactive({
|
|
114
|
+
dialogVisible: computed({
|
|
115
|
+
get: () => $Prop.modelValue,
|
|
116
|
+
set: (value) => {
|
|
117
|
+
$Emit("update:modelValue", value);
|
|
118
|
+
}
|
|
119
|
+
}),
|
|
120
|
+
dialogTitle: computed(() => ($Prop.actionType === "upd" ? "编辑配置" : "添加配置"))
|
|
121
|
+
});
|
|
145
122
|
|
|
146
|
-
|
|
147
|
-
|
|
123
|
+
const $Method = {
|
|
124
|
+
resetFormData() {
|
|
125
|
+
Object.assign($Data.formData, $Const.createDefaultFormData());
|
|
126
|
+
$Data.isSystem = false;
|
|
127
|
+
},
|
|
128
|
+
initData() {
|
|
129
|
+
$Method.onShow();
|
|
130
|
+
},
|
|
131
|
+
onShow() {
|
|
132
|
+
if ($Prop.actionType === "upd" && $Prop.rowData) {
|
|
133
|
+
const row = $Prop.rowData;
|
|
134
|
+
$Data.formData.id = row["id"] || 0;
|
|
135
|
+
$Data.formData.name = row["name"] || "";
|
|
136
|
+
$Data.formData.code = row["code"] || "";
|
|
137
|
+
$Data.formData.value = row["value"] || "";
|
|
138
|
+
$Data.formData.valueType = row["valueType"] || "string";
|
|
139
|
+
$Data.formData.group = row["group"] || "";
|
|
140
|
+
$Data.formData.sort = row["sort"] || 0;
|
|
141
|
+
$Data.formData.description = row["description"] || "";
|
|
142
|
+
$Data.formData.state = row["state"] || 1;
|
|
143
|
+
$Data.isSystem = row["isSystem"] === 1;
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
148
146
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
147
|
+
$Method.resetFormData();
|
|
148
|
+
},
|
|
149
|
+
async onSubmit(context) {
|
|
150
|
+
const form = $From.formRef;
|
|
151
|
+
if (!form) {
|
|
152
|
+
MessagePlugin.warning("表单未就绪");
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
153
155
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
const valid = await form.validate();
|
|
157
|
+
if (valid !== true) return;
|
|
158
|
+
|
|
159
|
+
$Data.submitting = true;
|
|
160
|
+
try {
|
|
161
|
+
const api = $Prop.actionType === "upd" ? "/core/sysConfig/update" : "/core/sysConfig/insert";
|
|
162
|
+
await $Http(api, $Data.formData);
|
|
163
|
+
|
|
164
|
+
MessagePlugin.success($Prop.actionType === "upd" ? "编辑成功" : "添加成功");
|
|
165
|
+
$Emit("success");
|
|
166
|
+
if (context && typeof context.close === "function") {
|
|
167
|
+
context.close();
|
|
168
|
+
}
|
|
169
|
+
} catch (error) {
|
|
170
|
+
MessagePlugin.error(error.msg || error.message || "操作失败");
|
|
171
|
+
} finally {
|
|
172
|
+
$Data.submitting = false;
|
|
158
173
|
}
|
|
159
|
-
} catch (error) {
|
|
160
|
-
MessagePlugin.error(error.msg || error.message || "操作失败");
|
|
161
|
-
} finally {
|
|
162
|
-
$Data.submitting = false;
|
|
163
174
|
}
|
|
164
|
-
}
|
|
175
|
+
};
|
|
165
176
|
|
|
166
|
-
initData();
|
|
177
|
+
$Method.initData();
|
|
167
178
|
</script>
|
|
168
179
|
|
|
169
180
|
<style scoped lang="scss"></style>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<PageTableDetail class="page-sys-config page-table" :columns="$Data.columns" :endpoints="$Data.endpoints" :table-slot-names="['isSystem', 'valueType', 'state']">
|
|
3
3
|
<template #toolLeft="scope">
|
|
4
|
-
<TButton theme="primary" @click="onAdd">
|
|
4
|
+
<TButton theme="primary" @click="$Method.onAdd">
|
|
5
5
|
<template #icon>
|
|
6
6
|
<AddIcon />
|
|
7
7
|
</template>
|
|
8
8
|
新增配置
|
|
9
9
|
</TButton>
|
|
10
|
-
<TSelect v-model="$Data.filter.group" placeholder="配置分组" clearable style="width: 150px" @change="handleFilter(scope.reload)">
|
|
10
|
+
<TSelect v-model="$Data.filter.group" placeholder="配置分组" clearable style="width: 150px" @change="$Method.handleFilter(scope.reload)">
|
|
11
11
|
<TOption v-for="item in $Data.groupOptions" :key="item" :label="item" :value="item" />
|
|
12
12
|
</TSelect>
|
|
13
13
|
</template>
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
</template>
|
|
28
28
|
|
|
29
29
|
<template #operation="{ row, deleteRow }">
|
|
30
|
-
<TDropdown trigger="click" placement="bottom-right" @click="onDropdownAction($event, row, deleteRow)">
|
|
30
|
+
<TDropdown trigger="click" placement="bottom-right" @click="$Method.onDropdownAction($event, row, deleteRow)">
|
|
31
31
|
<TButton theme="primary" size="small">
|
|
32
32
|
操作
|
|
33
33
|
<template #suffix><ChevronDownIcon /></template>
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
</template>
|
|
62
62
|
|
|
63
63
|
<template #dialogs="scope">
|
|
64
|
-
<EditDialog v-if="$Data.editVisible" v-model="$Data.editVisible" :action-type="$Data.actionType" :row-data="$Data.rowData" @success="onDialogSuccess(scope.reload)" />
|
|
64
|
+
<EditDialog v-if="$Data.editVisible" v-model="$Data.editVisible" :action-type="$Data.actionType" :row-data="$Data.rowData" @success="$Method.onDialogSuccess(scope.reload)" />
|
|
65
65
|
</template>
|
|
66
66
|
</PageTableDetail>
|
|
67
67
|
</template>
|
|
@@ -124,41 +124,39 @@ const $Data = reactive({
|
|
|
124
124
|
groupOptions: ["基础配置", "邮件配置", "存储配置", "安全配置", "其他"]
|
|
125
125
|
});
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
$Data.rowData = Object.assign({}, rowData);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (command === "add" || command === "upd") {
|
|
148
|
-
$Data.editVisible = true;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
127
|
+
const $Method = {
|
|
128
|
+
onAdd() {
|
|
129
|
+
$Method.onAction("add", {});
|
|
130
|
+
},
|
|
131
|
+
handleFilter(reload) {
|
|
132
|
+
reload({ keepSelection: false, resetPage: true });
|
|
133
|
+
},
|
|
134
|
+
onDialogSuccess(reload) {
|
|
135
|
+
reload({ keepSelection: true });
|
|
136
|
+
},
|
|
137
|
+
onAction(command, rowData) {
|
|
138
|
+
$Data.actionType = command;
|
|
139
|
+
if (command === "add") {
|
|
140
|
+
$Data.rowData = {};
|
|
141
|
+
} else {
|
|
142
|
+
$Data.rowData = Object.assign({}, rowData);
|
|
143
|
+
}
|
|
151
144
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
145
|
+
if (command === "add" || command === "upd") {
|
|
146
|
+
$Data.editVisible = true;
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
onDropdownAction(data, rowData, deleteRow) {
|
|
150
|
+
const record = data;
|
|
151
|
+
const rawValue = record && record["value"] ? record["value"] : "";
|
|
152
|
+
const cmd = rawValue ? String(rawValue) : "";
|
|
153
|
+
if (cmd === "del") {
|
|
154
|
+
deleteRow(rowData);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
$Method.onAction(cmd, rowData);
|
|
159
158
|
}
|
|
160
|
-
|
|
161
|
-
}
|
|
159
|
+
};
|
|
162
160
|
</script>
|
|
163
161
|
|
|
164
162
|
<style scoped lang="scss">
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
</div>
|
|
7
7
|
<div class="section-content">
|
|
8
8
|
<div class="addon-list">
|
|
9
|
-
<div v-for="addon in addonList" :key="addon.name" class="addon-item">
|
|
9
|
+
<div v-for="addon in $Data.addonList" :key="addon.name" class="addon-item">
|
|
10
10
|
<div class="addon-icon">
|
|
11
11
|
<SystemStorageIcon />
|
|
12
12
|
</div>
|
|
@@ -27,22 +27,25 @@
|
|
|
27
27
|
import { reactive } from "vue";
|
|
28
28
|
import { Tag as TTag } from "tdesign-vue-next";
|
|
29
29
|
import { MenuIcon, SystemStorageIcon } from "tdesign-icons-vue-next";
|
|
30
|
-
import { $Http } from "@/plugins/http";
|
|
30
|
+
import { $Http } from "@/plugins/http.js";
|
|
31
31
|
|
|
32
32
|
// 组件内部数据
|
|
33
|
-
const
|
|
33
|
+
const $Data = reactive({
|
|
34
|
+
addonList: []
|
|
35
|
+
});
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
const $Method = {
|
|
38
|
+
async fetchData() {
|
|
39
|
+
try {
|
|
40
|
+
const res = await $Http("/core/dashboard/addonList", {}, [""]);
|
|
41
|
+
$Data.addonList.splice(0, $Data.addonList.length, ...res.data);
|
|
42
|
+
} catch (_error) {
|
|
43
|
+
// 静默失败:不阻断页面展示
|
|
44
|
+
}
|
|
42
45
|
}
|
|
43
46
|
};
|
|
44
47
|
|
|
45
|
-
fetchData();
|
|
48
|
+
$Method.fetchData();
|
|
46
49
|
</script>
|
|
47
50
|
|
|
48
51
|
<style scoped lang="scss">
|
|
@@ -8,27 +8,27 @@
|
|
|
8
8
|
<div class="env-grid-compact">
|
|
9
9
|
<div class="env-compact-item">
|
|
10
10
|
<span class="env-label">操作系统</span>
|
|
11
|
-
<span class="env-value">{{ environmentInfo.os }}</span>
|
|
11
|
+
<span class="env-value">{{ $Data.environmentInfo.os }}</span>
|
|
12
12
|
</div>
|
|
13
13
|
<div class="env-compact-item">
|
|
14
14
|
<span class="env-label">服务器</span>
|
|
15
|
-
<span class="env-value">{{ environmentInfo.server }}</span>
|
|
15
|
+
<span class="env-value">{{ $Data.environmentInfo.server }}</span>
|
|
16
16
|
</div>
|
|
17
17
|
<div class="env-compact-item">
|
|
18
18
|
<span class="env-label">Node版本</span>
|
|
19
|
-
<span class="env-value">{{ environmentInfo.nodeVersion }}</span>
|
|
19
|
+
<span class="env-value">{{ $Data.environmentInfo.nodeVersion }}</span>
|
|
20
20
|
</div>
|
|
21
21
|
<div class="env-compact-item">
|
|
22
22
|
<span class="env-label">数据库</span>
|
|
23
|
-
<span class="env-value">{{ environmentInfo.database }}</span>
|
|
23
|
+
<span class="env-value">{{ $Data.environmentInfo.database }}</span>
|
|
24
24
|
</div>
|
|
25
25
|
<div class="env-compact-item">
|
|
26
26
|
<span class="env-label">缓存</span>
|
|
27
|
-
<span class="env-value">{{ environmentInfo.cache }}</span>
|
|
27
|
+
<span class="env-value">{{ $Data.environmentInfo.cache }}</span>
|
|
28
28
|
</div>
|
|
29
29
|
<div class="env-compact-item">
|
|
30
30
|
<span class="env-label">时区</span>
|
|
31
|
-
<span class="env-value">{{ environmentInfo.timezone }}</span>
|
|
31
|
+
<span class="env-value">{{ $Data.environmentInfo.timezone }}</span>
|
|
32
32
|
</div>
|
|
33
33
|
</div>
|
|
34
34
|
</div>
|
|
@@ -38,29 +38,32 @@
|
|
|
38
38
|
<script setup>
|
|
39
39
|
import { reactive } from "vue";
|
|
40
40
|
import { ServerIcon } from "tdesign-icons-vue-next";
|
|
41
|
-
import { $Http } from "@/plugins/http";
|
|
41
|
+
import { $Http } from "@/plugins/http.js";
|
|
42
42
|
|
|
43
43
|
// 组件内部数据
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
const $Data = reactive({
|
|
45
|
+
environmentInfo: {
|
|
46
|
+
os: "",
|
|
47
|
+
server: "",
|
|
48
|
+
nodeVersion: "",
|
|
49
|
+
database: "",
|
|
50
|
+
cache: "",
|
|
51
|
+
timezone: ""
|
|
52
|
+
}
|
|
51
53
|
});
|
|
52
54
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
const $Method = {
|
|
56
|
+
async fetchData() {
|
|
57
|
+
try {
|
|
58
|
+
const res = await $Http("/core/dashboard/environmentInfo", {}, [""]);
|
|
59
|
+
Object.assign($Data.environmentInfo, res.data);
|
|
60
|
+
} catch (_error) {
|
|
61
|
+
// 静默失败:不阻断页面展示
|
|
62
|
+
}
|
|
60
63
|
}
|
|
61
64
|
};
|
|
62
65
|
|
|
63
|
-
fetchData();
|
|
66
|
+
$Method.fetchData();
|
|
64
67
|
</script>
|
|
65
68
|
|
|
66
69
|
<style scoped lang="scss">
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
<span class="col-status">状态</span>
|
|
16
16
|
</div>
|
|
17
17
|
<div class="operation-body">
|
|
18
|
-
<div v-for="log in operationLogs" :key="log.id" class="operation-row">
|
|
19
|
-
<span class="col-time">{{ formatTime(log.createdAt) }}</span>
|
|
18
|
+
<div v-for="log in $Const.operationLogs" :key="log.id" class="operation-row">
|
|
19
|
+
<span class="col-time">{{ $Method.formatTime(log.createdAt) }}</span>
|
|
20
20
|
<span class="col-user">{{ log.userName }}</span>
|
|
21
21
|
<span class="col-action">{{ log.action }}</span>
|
|
22
22
|
<span class="col-module">{{ log.module }}</span>
|
|
@@ -39,21 +39,25 @@ import { Tag as TTag } from "tdesign-vue-next";
|
|
|
39
39
|
import { CodeIcon } from "tdesign-icons-vue-next";
|
|
40
40
|
|
|
41
41
|
// 组件内部数据
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
const $Const = {
|
|
43
|
+
operationLogs: [
|
|
44
|
+
{ id: 1, userName: "管理员", action: "创建角色", module: "权限管理", ip: "192.168.1.100", status: "success", createdAt: Date.now() - 120000 },
|
|
45
|
+
{ id: 2, userName: "张三", action: "修改菜单", module: "系统设置", ip: "192.168.1.101", status: "success", createdAt: Date.now() - 900000 },
|
|
46
|
+
{ id: 3, userName: "李四", action: "删除接口", module: "接口管理", ip: "192.168.1.102", status: "failed", createdAt: Date.now() - 3600000 },
|
|
47
|
+
{ id: 4, userName: "管理员", action: "同步数据库", module: "数据库", ip: "192.168.1.100", status: "success", createdAt: Date.now() - 7200000 },
|
|
48
|
+
{ id: 5, userName: "王五", action: "登录系统", module: "系统", ip: "192.168.1.103", status: "success", createdAt: Date.now() - 10800000 }
|
|
49
|
+
]
|
|
50
|
+
};
|
|
49
51
|
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
const $Method = {
|
|
53
|
+
formatTime(timestamp) {
|
|
54
|
+
const date = new Date(timestamp);
|
|
55
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
56
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
57
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
58
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
59
|
+
return `${month}-${day} ${hours}:${minutes}`;
|
|
60
|
+
}
|
|
57
61
|
};
|
|
58
62
|
</script>
|
|
59
63
|
|
|
@@ -9,32 +9,32 @@
|
|
|
9
9
|
<div class="perf-metric">
|
|
10
10
|
<div class="perf-info">
|
|
11
11
|
<div class="perf-label">平均响应</div>
|
|
12
|
-
<div class="perf-value">{{ performanceMetrics.avgResponseTime }}ms</div>
|
|
12
|
+
<div class="perf-value">{{ $Data.performanceMetrics.avgResponseTime }}ms</div>
|
|
13
13
|
</div>
|
|
14
14
|
</div>
|
|
15
15
|
<div class="perf-metric">
|
|
16
16
|
<div class="perf-info">
|
|
17
17
|
<div class="perf-label">QPS</div>
|
|
18
|
-
<div class="perf-value">{{ performanceMetrics.qps }}/s</div>
|
|
18
|
+
<div class="perf-value">{{ $Data.performanceMetrics.qps }}/s</div>
|
|
19
19
|
</div>
|
|
20
20
|
</div>
|
|
21
21
|
<div class="perf-metric">
|
|
22
22
|
<div class="perf-info">
|
|
23
23
|
<div class="perf-label">错误率</div>
|
|
24
|
-
<div class="perf-value">{{ performanceMetrics.errorRate }}%</div>
|
|
24
|
+
<div class="perf-value">{{ $Data.performanceMetrics.errorRate }}%</div>
|
|
25
25
|
</div>
|
|
26
26
|
</div>
|
|
27
27
|
<div class="perf-metric">
|
|
28
28
|
<div class="perf-info">
|
|
29
29
|
<div class="perf-label">活跃连接</div>
|
|
30
|
-
<div class="perf-value">{{ performanceMetrics.activeConnections }}</div>
|
|
30
|
+
<div class="perf-value">{{ $Data.performanceMetrics.activeConnections }}</div>
|
|
31
31
|
</div>
|
|
32
32
|
</div>
|
|
33
33
|
</div>
|
|
34
34
|
<!-- 最慢接口提示 -->
|
|
35
|
-
<div v-if="performanceMetrics.slowestApi" class="perf-slowest">
|
|
35
|
+
<div v-if="$Data.performanceMetrics.slowestApi" class="perf-slowest">
|
|
36
36
|
<ErrorTriangleIcon />
|
|
37
|
-
<span>最慢接口: {{ performanceMetrics.slowestApi.path }} ({{ performanceMetrics.slowestApi.time }}ms)</span>
|
|
37
|
+
<span>最慢接口: {{ $Data.performanceMetrics.slowestApi.path }} ({{ $Data.performanceMetrics.slowestApi.time }}ms)</span>
|
|
38
38
|
</div>
|
|
39
39
|
</div>
|
|
40
40
|
</div>
|
|
@@ -43,28 +43,31 @@
|
|
|
43
43
|
<script setup>
|
|
44
44
|
import { reactive } from "vue";
|
|
45
45
|
import { ChartIcon, ErrorTriangleIcon } from "tdesign-icons-vue-next";
|
|
46
|
-
import { $Http } from "@/plugins/http";
|
|
46
|
+
import { $Http } from "@/plugins/http.js";
|
|
47
47
|
|
|
48
48
|
// 组件内部数据
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
const $Data = reactive({
|
|
50
|
+
performanceMetrics: {
|
|
51
|
+
avgResponseTime: 0,
|
|
52
|
+
qps: 0,
|
|
53
|
+
errorRate: 0,
|
|
54
|
+
activeConnections: 0,
|
|
55
|
+
slowestApi: null
|
|
56
|
+
}
|
|
55
57
|
});
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
const $Method = {
|
|
60
|
+
async fetchData() {
|
|
61
|
+
try {
|
|
62
|
+
const res = await $Http("/core/dashboard/performanceMetrics", {}, [""]);
|
|
63
|
+
Object.assign($Data.performanceMetrics, res.data);
|
|
64
|
+
} catch (_error) {
|
|
65
|
+
// 静默失败:不阻断页面展示
|
|
66
|
+
}
|
|
64
67
|
}
|
|
65
68
|
};
|
|
66
69
|
|
|
67
|
-
fetchData();
|
|
70
|
+
$Method.fetchData();
|
|
68
71
|
</script>
|
|
69
72
|
|
|
70
73
|
<style scoped lang="scss">
|