@befly-addon/admin 1.8.6 → 1.8.7
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/adminViews/config/dict/components/edit.vue +16 -8
- package/adminViews/config/dict/index.vue +3 -3
- package/adminViews/config/dictType/components/edit.vue +16 -8
- package/adminViews/config/dictType/index.vue +2 -1
- package/adminViews/config/system/components/edit.vue +17 -9
- package/adminViews/config/system/index.vue +2 -1
- package/adminViews/index/components/addonList.vue +10 -2
- package/adminViews/index/components/environmentInfo.vue +12 -2
- package/adminViews/index/components/operationLogs.vue +16 -2
- package/adminViews/index/components/performanceMetrics.vue +9 -3
- package/adminViews/index/components/serviceStatus.vue +11 -4
- package/adminViews/index/components/systemNotifications.vue +13 -2
- package/adminViews/index/components/systemOverview.vue +3 -2
- package/adminViews/index/components/systemResources.vue +10 -3
- package/adminViews/index/components/userInfo.vue +19 -5
- package/adminViews/log/email/index.vue +21 -12
- package/adminViews/log/login/index.vue +2 -1
- package/adminViews/log/operate/index.vue +2 -1
- package/adminViews/login_1/index.vue +11 -8
- package/adminViews/people/admin/components/edit.vue +17 -9
- package/adminViews/people/admin/index.vue +2 -1
- package/adminViews/permission/api/index.vue +3 -2
- package/adminViews/permission/menu/index.vue +3 -2
- package/adminViews/permission/role/components/api.vue +5 -5
- package/adminViews/permission/role/components/edit.vue +16 -8
- package/adminViews/permission/role/components/menu.vue +5 -5
- package/adminViews/permission/role/index.vue +2 -1
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<PageDialog v-model="visible" :title="actionType === 'add' ? '添加字典项' : '编辑字典项'" @confirm="handleSubmit">
|
|
3
|
-
<TForm :data="$Data.formData" :rules="$Data.rules" label-width="100px"
|
|
3
|
+
<TForm :data="$Data.formData" :rules="$Data.rules" label-width="100px" ref="formRef">
|
|
4
4
|
<TFormItem label="字典类型" name="typeCode">
|
|
5
5
|
<TSelect v-model="$Data.formData.typeCode" placeholder="请选择字典类型" filterable>
|
|
6
6
|
<TOption v-for="item in typeList" :key="item.code" :value="item.code" :label="item.name" />
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
</template>
|
|
24
24
|
|
|
25
25
|
<script setup lang="ts">
|
|
26
|
-
import { computed } from "vue";
|
|
26
|
+
import { computed, reactive, ref } from "vue";
|
|
27
27
|
|
|
28
28
|
import { Form as TForm, FormItem as TFormItem, Input as TInput, Select as TSelect, Option as TOption, Textarea as TTextarea, InputNumber as TInputNumber, MessagePlugin } from "tdesign-vue-next";
|
|
29
29
|
import PageDialog from "@/components/pageDialog.vue";
|
|
@@ -46,11 +46,13 @@ const visible = computed({
|
|
|
46
46
|
set: (val) => $Emit("update:modelValue", val)
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
49
|
+
type TDesignFormInstance = {
|
|
50
|
+
validate: () => Promise<unknown>;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const formRef = ref<TDesignFormInstance | null>(null);
|
|
52
54
|
|
|
53
|
-
const $Data =
|
|
55
|
+
const $Data = reactive({
|
|
54
56
|
formData: {
|
|
55
57
|
typeCode: "",
|
|
56
58
|
key: "",
|
|
@@ -67,7 +69,13 @@ const $Data = $ref({
|
|
|
67
69
|
|
|
68
70
|
async function handleSubmit(): Promise<void> {
|
|
69
71
|
try {
|
|
70
|
-
const
|
|
72
|
+
const form = formRef.value;
|
|
73
|
+
if (!form) {
|
|
74
|
+
MessagePlugin.warning("表单未就绪");
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const valid = await form.validate();
|
|
71
79
|
if (valid !== true) return;
|
|
72
80
|
const apiUrl = props.actionType === "add" ? "/addon/admin/dict/ins" : "/addon/admin/dict/upd";
|
|
73
81
|
const params: Record<string, unknown> = {
|
|
@@ -90,7 +98,7 @@ async function handleSubmit(): Promise<void> {
|
|
|
90
98
|
} else {
|
|
91
99
|
MessagePlugin.error(res.msg || "操作失败");
|
|
92
100
|
}
|
|
93
|
-
} catch (
|
|
101
|
+
} catch (_error) {
|
|
94
102
|
MessagePlugin.error("操作失败");
|
|
95
103
|
}
|
|
96
104
|
}
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
</template>
|
|
51
51
|
|
|
52
52
|
<script setup lang="ts">
|
|
53
|
-
import { onMounted } from "vue";
|
|
53
|
+
import { onMounted, reactive } from "vue";
|
|
54
54
|
|
|
55
55
|
import { Button as TButton, Dropdown as TDropdown, DropdownItem as TDropdownItem, DropdownMenu as TDropdownMenu, Input as TInput, Option as TOption, Select as TSelect, MessagePlugin } from "tdesign-vue-next";
|
|
56
56
|
import ILucidePlus from "~icons/lucide/plus";
|
|
@@ -64,7 +64,7 @@ import { $Http } from "@/plugins/http";
|
|
|
64
64
|
import PagedTableDetail from "@/components/pagedTableDetail.vue";
|
|
65
65
|
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
66
66
|
|
|
67
|
-
const $Data =
|
|
67
|
+
const $Data = reactive({
|
|
68
68
|
typeList: [],
|
|
69
69
|
searchTypeCode: "",
|
|
70
70
|
searchKeyword: "",
|
|
@@ -128,7 +128,7 @@ async function apiDictTypeAll(): Promise<void> {
|
|
|
128
128
|
}
|
|
129
129
|
);
|
|
130
130
|
$Data.typeList = res.data.lists || [];
|
|
131
|
-
} catch (
|
|
131
|
+
} catch (_error) {
|
|
132
132
|
MessagePlugin.error("加载数据失败");
|
|
133
133
|
}
|
|
134
134
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<PageDialog v-model="visible" :title="actionType === 'add' ? '添加字典类型' : '编辑字典类型'" @confirm="handleSubmit">
|
|
3
|
-
<TForm :data="$Data.formData" :rules="$Data.rules" label-width="100px"
|
|
3
|
+
<TForm :data="$Data.formData" :rules="$Data.rules" label-width="100px" ref="formRef">
|
|
4
4
|
<TFormItem label="类型代码" name="code">
|
|
5
5
|
<TInput v-model="$Data.formData.code" placeholder="请输入类型代码(英文/数字/下划线)" :disabled="actionType === 'upd'" />
|
|
6
6
|
</TFormItem>
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
</template>
|
|
19
19
|
|
|
20
20
|
<script setup lang="ts">
|
|
21
|
-
import { computed } from "vue";
|
|
21
|
+
import { computed, reactive, ref } from "vue";
|
|
22
22
|
|
|
23
23
|
import { Form as TForm, FormItem as TFormItem, Input as TInput, Textarea as TTextarea, InputNumber as TInputNumber, MessagePlugin } from "tdesign-vue-next";
|
|
24
24
|
import PageDialog from "@/components/pageDialog.vue";
|
|
@@ -40,11 +40,13 @@ const visible = computed({
|
|
|
40
40
|
set: (val) => $Emit("update:modelValue", val)
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
43
|
+
type TDesignFormInstance = {
|
|
44
|
+
validate: () => Promise<unknown>;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const formRef = ref<TDesignFormInstance | null>(null);
|
|
46
48
|
|
|
47
|
-
const $Data =
|
|
49
|
+
const $Data = reactive({
|
|
48
50
|
formData: {
|
|
49
51
|
code: "",
|
|
50
52
|
name: "",
|
|
@@ -58,7 +60,13 @@ const $Data = $ref({
|
|
|
58
60
|
});
|
|
59
61
|
|
|
60
62
|
async function handleSubmit(): Promise<void> {
|
|
61
|
-
const
|
|
63
|
+
const form = formRef.value;
|
|
64
|
+
if (!form) {
|
|
65
|
+
MessagePlugin.warning("表单未就绪");
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const valid = await form.validate();
|
|
62
70
|
if (valid !== true) return;
|
|
63
71
|
|
|
64
72
|
try {
|
|
@@ -82,7 +90,7 @@ async function handleSubmit(): Promise<void> {
|
|
|
82
90
|
} else {
|
|
83
91
|
MessagePlugin.error(res.msg || "操作失败");
|
|
84
92
|
}
|
|
85
|
-
} catch (
|
|
93
|
+
} catch (_error) {
|
|
86
94
|
MessagePlugin.error("操作失败");
|
|
87
95
|
}
|
|
88
96
|
}
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
</template>
|
|
48
48
|
|
|
49
49
|
<script setup lang="ts">
|
|
50
|
+
import { reactive } from "vue";
|
|
50
51
|
import { Button as TButton, Dropdown as TDropdown, DropdownItem as TDropdownItem, DropdownMenu as TDropdownMenu, Input as TInput } from "tdesign-vue-next";
|
|
51
52
|
import ILucidePlus from "~icons/lucide/plus";
|
|
52
53
|
import ILucideRotateCw from "~icons/lucide/rotate-cw";
|
|
@@ -58,7 +59,7 @@ import EditDialog from "./components/edit.vue";
|
|
|
58
59
|
import PagedTableDetail from "@/components/pagedTableDetail.vue";
|
|
59
60
|
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
60
61
|
|
|
61
|
-
const $Data =
|
|
62
|
+
const $Data = reactive({
|
|
62
63
|
searchKeyword: "",
|
|
63
64
|
columns: withDefaultColumns([
|
|
64
65
|
{ colKey: "code", title: "类型代码" },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<PageDialog v-model="dialogVisible" :title="$Prop.actionType === 'upd' ? '编辑配置' : '添加配置'" :confirm-loading="$Data.submitting" @confirm="onSubmit">
|
|
3
|
-
<TForm :model="$Data.formData" label-width="120px" label-position="left" :rules="$Data2.formRules"
|
|
3
|
+
<TForm :model="$Data.formData" label-width="120px" label-position="left" :rules="$Data2.formRules" ref="formRef">
|
|
4
4
|
<TFormItem label="配置名称" prop="name">
|
|
5
5
|
<TInput v-model="$Data.formData.name" placeholder="请输入配置名称" :disabled="$Data.isSystem" />
|
|
6
6
|
</TFormItem>
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
</template>
|
|
42
42
|
|
|
43
43
|
<script setup lang="ts">
|
|
44
|
-
import { computed } from "vue";
|
|
44
|
+
import { computed, reactive, ref } from "vue";
|
|
45
45
|
|
|
46
46
|
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
47
|
import PageDialog from "@/components/pageDialog.vue";
|
|
@@ -72,9 +72,11 @@ type PageDialogEventContext = {
|
|
|
72
72
|
};
|
|
73
73
|
|
|
74
74
|
// 表单引用
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
75
|
+
type TDesignFormInstance = {
|
|
76
|
+
validate: () => Promise<unknown>;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const formRef = ref<TDesignFormInstance | null>(null);
|
|
78
80
|
|
|
79
81
|
const dialogVisible = computed({
|
|
80
82
|
get: () => $Prop.modelValue,
|
|
@@ -83,7 +85,7 @@ const dialogVisible = computed({
|
|
|
83
85
|
}
|
|
84
86
|
});
|
|
85
87
|
|
|
86
|
-
const $Data =
|
|
88
|
+
const $Data = reactive({
|
|
87
89
|
submitting: false,
|
|
88
90
|
isSystem: false,
|
|
89
91
|
formData: {
|
|
@@ -99,7 +101,7 @@ const $Data = $ref({
|
|
|
99
101
|
}
|
|
100
102
|
});
|
|
101
103
|
|
|
102
|
-
const $Data2 =
|
|
104
|
+
const $Data2 = reactive({
|
|
103
105
|
formRules: {
|
|
104
106
|
name: [{ required: true, message: "请输入配置名称", trigger: "blur" }],
|
|
105
107
|
code: [
|
|
@@ -146,7 +148,13 @@ function onShow(): void {
|
|
|
146
148
|
}
|
|
147
149
|
|
|
148
150
|
async function onSubmit(context?: PageDialogEventContext): Promise<void> {
|
|
149
|
-
const
|
|
151
|
+
const form = formRef.value;
|
|
152
|
+
if (!form) {
|
|
153
|
+
MessagePlugin.warning("表单未就绪");
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const valid = await form.validate();
|
|
150
158
|
if (valid !== true) return;
|
|
151
159
|
|
|
152
160
|
$Data.submitting = true;
|
|
@@ -163,7 +171,7 @@ async function onSubmit(context?: PageDialogEventContext): Promise<void> {
|
|
|
163
171
|
} else {
|
|
164
172
|
MessagePlugin.error(res.msg || "操作失败");
|
|
165
173
|
}
|
|
166
|
-
} catch (
|
|
174
|
+
} catch (_error) {
|
|
167
175
|
MessagePlugin.error("操作失败");
|
|
168
176
|
} finally {
|
|
169
177
|
$Data.submitting = false;
|
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
</template>
|
|
76
76
|
|
|
77
77
|
<script setup lang="ts">
|
|
78
|
+
import { reactive } from "vue";
|
|
78
79
|
import { Button as TButton, Dropdown as TDropdown, DropdownItem as TDropdownItem, DropdownMenu as TDropdownMenu, Option as TOption, Select as TSelect, Tag as TTag } from "tdesign-vue-next";
|
|
79
80
|
import ILucidePlus from "~icons/lucide/plus";
|
|
80
81
|
import ILucideRotateCw from "~icons/lucide/rotate-cw";
|
|
@@ -87,7 +88,7 @@ import PagedTableDetail from "@/components/pagedTableDetail.vue";
|
|
|
87
88
|
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
88
89
|
|
|
89
90
|
// 响应式数据
|
|
90
|
-
const $Data =
|
|
91
|
+
const $Data = reactive({
|
|
91
92
|
columns: withDefaultColumns([
|
|
92
93
|
{ colKey: "name", title: "配置名称", fixed: "left", width: 150 },
|
|
93
94
|
{ colKey: "code", title: "配置代码", ellipsis: true },
|
|
@@ -24,10 +24,18 @@
|
|
|
24
24
|
</template>
|
|
25
25
|
|
|
26
26
|
<script setup lang="ts">
|
|
27
|
+
import { reactive } from "vue";
|
|
27
28
|
import { $Http } from "@/plugins/http";
|
|
28
29
|
|
|
30
|
+
type AddonListItem = {
|
|
31
|
+
name: string;
|
|
32
|
+
title: string;
|
|
33
|
+
version: string;
|
|
34
|
+
description: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
29
37
|
// 组件内部数据
|
|
30
|
-
const addonList =
|
|
38
|
+
const addonList = reactive<AddonListItem[]>([]);
|
|
31
39
|
|
|
32
40
|
// 获取数据
|
|
33
41
|
const fetchData = async () => {
|
|
@@ -40,7 +48,7 @@ const fetchData = async () => {
|
|
|
40
48
|
}
|
|
41
49
|
);
|
|
42
50
|
addonList.splice(0, addonList.length, ...data);
|
|
43
|
-
} catch (
|
|
51
|
+
} catch (_error) {
|
|
44
52
|
// 静默失败:不阻断页面展示
|
|
45
53
|
}
|
|
46
54
|
};
|
|
@@ -36,11 +36,21 @@
|
|
|
36
36
|
</template>
|
|
37
37
|
|
|
38
38
|
<script setup lang="ts">
|
|
39
|
+
import { reactive } from "vue";
|
|
39
40
|
import ILucideServer from "~icons/lucide/server";
|
|
40
41
|
import { $Http } from "@/plugins/http";
|
|
41
42
|
|
|
43
|
+
type EnvironmentInfo = {
|
|
44
|
+
os: string;
|
|
45
|
+
server: string;
|
|
46
|
+
nodeVersion: string;
|
|
47
|
+
database: string;
|
|
48
|
+
cache: string;
|
|
49
|
+
timezone: string;
|
|
50
|
+
};
|
|
51
|
+
|
|
42
52
|
// 组件内部数据
|
|
43
|
-
const environmentInfo =
|
|
53
|
+
const environmentInfo = reactive<EnvironmentInfo>({
|
|
44
54
|
os: "",
|
|
45
55
|
server: "",
|
|
46
56
|
nodeVersion: "",
|
|
@@ -60,7 +70,7 @@ const fetchData = async () => {
|
|
|
60
70
|
}
|
|
61
71
|
);
|
|
62
72
|
Object.assign(environmentInfo, data);
|
|
63
|
-
} catch (
|
|
73
|
+
} catch (_error) {
|
|
64
74
|
// 静默失败:不阻断页面展示
|
|
65
75
|
}
|
|
66
76
|
};
|
|
@@ -34,8 +34,22 @@
|
|
|
34
34
|
</template>
|
|
35
35
|
|
|
36
36
|
<script setup lang="ts">
|
|
37
|
+
import { reactive } from "vue";
|
|
38
|
+
|
|
39
|
+
type OperationLogStatus = "success" | "failed";
|
|
40
|
+
|
|
41
|
+
type OperationLogItem = {
|
|
42
|
+
id: number;
|
|
43
|
+
userName: string;
|
|
44
|
+
action: string;
|
|
45
|
+
module: string;
|
|
46
|
+
ip: string;
|
|
47
|
+
status: OperationLogStatus;
|
|
48
|
+
createdAt: number;
|
|
49
|
+
};
|
|
50
|
+
|
|
37
51
|
// 组件内部数据
|
|
38
|
-
const operationLogs =
|
|
52
|
+
const operationLogs = reactive<OperationLogItem[]>([
|
|
39
53
|
{ id: 1, userName: "管理员", action: "创建角色", module: "权限管理", ip: "192.168.1.100", status: "success", createdAt: Date.now() - 120000 },
|
|
40
54
|
{ id: 2, userName: "张三", action: "修改菜单", module: "系统设置", ip: "192.168.1.101", status: "success", createdAt: Date.now() - 900000 },
|
|
41
55
|
{ id: 3, userName: "李四", action: "删除接口", module: "接口管理", ip: "192.168.1.102", status: "failed", createdAt: Date.now() - 3600000 },
|
|
@@ -43,7 +57,7 @@ const operationLogs = $ref([
|
|
|
43
57
|
{ id: 5, userName: "王五", action: "登录系统", module: "系统", ip: "192.168.1.103", status: "success", createdAt: Date.now() - 10800000 }
|
|
44
58
|
]);
|
|
45
59
|
|
|
46
|
-
const formatTime = (timestamp) => {
|
|
60
|
+
const formatTime = (timestamp: number): string => {
|
|
47
61
|
const date = new Date(timestamp);
|
|
48
62
|
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
49
63
|
const day = String(date.getDate()).padStart(2, "0");
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
</template>
|
|
54
54
|
|
|
55
55
|
<script setup lang="ts">
|
|
56
|
+
import { reactive } from "vue";
|
|
56
57
|
import ILucideActivity from "~icons/lucide/activity";
|
|
57
58
|
import ILucideClock from "~icons/lucide/clock";
|
|
58
59
|
import ILucideTrendingUp from "~icons/lucide/trending-up";
|
|
@@ -60,13 +61,18 @@ import ILucideAlertCircle from "~icons/lucide/alert-circle";
|
|
|
60
61
|
import ILucideAlertTriangle from "~icons/lucide/alert-triangle";
|
|
61
62
|
import { $Http } from "@/plugins/http";
|
|
62
63
|
|
|
64
|
+
type SlowestApiInfo = {
|
|
65
|
+
path: string;
|
|
66
|
+
time: number;
|
|
67
|
+
};
|
|
68
|
+
|
|
63
69
|
// 组件内部数据
|
|
64
|
-
const performanceMetrics =
|
|
70
|
+
const performanceMetrics = reactive({
|
|
65
71
|
avgResponseTime: 0,
|
|
66
72
|
qps: 0,
|
|
67
73
|
errorRate: 0,
|
|
68
74
|
activeConnections: 0,
|
|
69
|
-
slowestApi: null
|
|
75
|
+
slowestApi: null as SlowestApiInfo | null
|
|
70
76
|
});
|
|
71
77
|
|
|
72
78
|
// 获取数据
|
|
@@ -80,7 +86,7 @@ const fetchData = async () => {
|
|
|
80
86
|
}
|
|
81
87
|
);
|
|
82
88
|
Object.assign(performanceMetrics, data);
|
|
83
|
-
} catch (
|
|
89
|
+
} catch (_error) {
|
|
84
90
|
// 静默失败:不阻断页面展示
|
|
85
91
|
}
|
|
86
92
|
};
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
</template>
|
|
36
36
|
|
|
37
37
|
<script setup lang="ts">
|
|
38
|
+
import { reactive } from "vue";
|
|
38
39
|
import ILucideCheckCircle from "~icons/lucide/check-circle";
|
|
39
40
|
import ILucideDatabase from "~icons/lucide/database";
|
|
40
41
|
import ILucideZap from "~icons/lucide/zap";
|
|
@@ -46,8 +47,14 @@ import ILucideXCircle from "~icons/lucide/x-circle";
|
|
|
46
47
|
import ILucideAlertCircle from "~icons/lucide/alert-circle";
|
|
47
48
|
import { $Http } from "@/plugins/http";
|
|
48
49
|
|
|
50
|
+
type ServiceStatusItem = {
|
|
51
|
+
name: string;
|
|
52
|
+
status: string;
|
|
53
|
+
responseTime?: string;
|
|
54
|
+
};
|
|
55
|
+
|
|
49
56
|
// 组件内部数据
|
|
50
|
-
const services =
|
|
57
|
+
const services = reactive<ServiceStatusItem[]>([]);
|
|
51
58
|
|
|
52
59
|
// 获取数据
|
|
53
60
|
const fetchData = async () => {
|
|
@@ -60,7 +67,7 @@ const fetchData = async () => {
|
|
|
60
67
|
}
|
|
61
68
|
);
|
|
62
69
|
services.splice(0, services.length, ...data.services);
|
|
63
|
-
} catch (
|
|
70
|
+
} catch (_error) {
|
|
64
71
|
// 静默失败:不阻断页面展示
|
|
65
72
|
}
|
|
66
73
|
};
|
|
@@ -68,7 +75,7 @@ const fetchData = async () => {
|
|
|
68
75
|
fetchData();
|
|
69
76
|
|
|
70
77
|
// 工具函数
|
|
71
|
-
const getStatusColor = (status) => {
|
|
78
|
+
const getStatusColor = (status: string): string => {
|
|
72
79
|
const colors = {
|
|
73
80
|
running: "success",
|
|
74
81
|
stopped: "error",
|
|
@@ -77,7 +84,7 @@ const getStatusColor = (status) => {
|
|
|
77
84
|
return colors[status] || "default";
|
|
78
85
|
};
|
|
79
86
|
|
|
80
|
-
const getStatusText = (status) => {
|
|
87
|
+
const getStatusText = (status: string): string => {
|
|
81
88
|
const texts = {
|
|
82
89
|
running: "正常",
|
|
83
90
|
stopped: "停止",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
</template>
|
|
27
27
|
|
|
28
28
|
<script setup lang="ts">
|
|
29
|
+
import { reactive } from "vue";
|
|
29
30
|
import { Tag as TTag } from "tdesign-vue-next";
|
|
30
31
|
import ILucideBell from "~icons/lucide/bell";
|
|
31
32
|
import ILucideInfo from "~icons/lucide/info";
|
|
@@ -33,15 +34,25 @@ import ILucideCheckCircle from "~icons/lucide/check-circle";
|
|
|
33
34
|
import ILucideAlertTriangle from "~icons/lucide/alert-triangle";
|
|
34
35
|
import ILucideXCircle from "~icons/lucide/x-circle";
|
|
35
36
|
|
|
37
|
+
type NotificationType = "info" | "success" | "warning" | "error" | "other";
|
|
38
|
+
|
|
39
|
+
type NotificationItem = {
|
|
40
|
+
id: number;
|
|
41
|
+
type: NotificationType;
|
|
42
|
+
title: string;
|
|
43
|
+
isRead: boolean;
|
|
44
|
+
createdAt: number;
|
|
45
|
+
};
|
|
46
|
+
|
|
36
47
|
// 组件内部数据
|
|
37
|
-
const notifications =
|
|
48
|
+
const notifications = reactive<NotificationItem[]>([
|
|
38
49
|
{ id: 1, type: "warning", title: "系统更新提醒 - v1.1.0 版本已发布", isRead: false, createdAt: Date.now() - 3600000 },
|
|
39
50
|
{ id: 2, type: "info", title: "数据备份完成 - 今日凌晨自动备份成功", isRead: true, createdAt: Date.now() - 21600000 },
|
|
40
51
|
{ id: 3, type: "error", title: "SSL证书即将过期 - 请及时更新证书", isRead: false, createdAt: Date.now() - 86400000 },
|
|
41
52
|
{ id: 4, type: "success", title: "性能优化完成 - 响应速度提升30%", isRead: true, createdAt: Date.now() - 172800000 }
|
|
42
53
|
]);
|
|
43
54
|
|
|
44
|
-
const formatTime = (timestamp) => {
|
|
55
|
+
const formatTime = (timestamp: number): string => {
|
|
45
56
|
const date = new Date(timestamp);
|
|
46
57
|
const now = Date.now();
|
|
47
58
|
const diff = now - timestamp;
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
</template>
|
|
36
36
|
|
|
37
37
|
<script setup lang="ts">
|
|
38
|
+
import { reactive } from "vue";
|
|
38
39
|
import ILucideInfo from "~icons/lucide/info";
|
|
39
40
|
import ILucideMenu from "~icons/lucide/menu";
|
|
40
41
|
import ILucideWebhook from "~icons/lucide/webhook";
|
|
@@ -42,7 +43,7 @@ import ILucideUsers from "~icons/lucide/users";
|
|
|
42
43
|
import { $Http } from "@/plugins/http";
|
|
43
44
|
|
|
44
45
|
// 组件内部数据
|
|
45
|
-
const permissionStats =
|
|
46
|
+
const permissionStats = reactive({
|
|
46
47
|
menuCount: 0,
|
|
47
48
|
apiCount: 0,
|
|
48
49
|
roleCount: 0
|
|
@@ -59,7 +60,7 @@ const fetchData = async () => {
|
|
|
59
60
|
}
|
|
60
61
|
);
|
|
61
62
|
Object.assign(permissionStats, data);
|
|
62
|
-
} catch (
|
|
63
|
+
} catch (_error) {
|
|
63
64
|
// 静默失败:不阻断页面展示
|
|
64
65
|
}
|
|
65
66
|
};
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
</template>
|
|
40
40
|
|
|
41
41
|
<script setup lang="ts">
|
|
42
|
+
import { reactive } from "vue";
|
|
42
43
|
import { Progress as TProgress } from "tdesign-vue-next";
|
|
43
44
|
import ILucideActivity from "~icons/lucide/activity";
|
|
44
45
|
import ILucideCpu from "~icons/lucide/cpu";
|
|
@@ -46,8 +47,14 @@ import ILucideHardDrive from "~icons/lucide/hard-drive";
|
|
|
46
47
|
import ILucideDisc from "~icons/lucide/disc";
|
|
47
48
|
import { $Http } from "@/plugins/http";
|
|
48
49
|
|
|
50
|
+
type SystemResourcesInfo = {
|
|
51
|
+
cpu: { usage: number; cores: number };
|
|
52
|
+
memory: { used: number; total: number; percentage: number };
|
|
53
|
+
disk: { used: number; total: number; percentage: number };
|
|
54
|
+
};
|
|
55
|
+
|
|
49
56
|
// 组件内部数据
|
|
50
|
-
const systemResources =
|
|
57
|
+
const systemResources = reactive<SystemResourcesInfo>({
|
|
51
58
|
cpu: { usage: 0, cores: 0 },
|
|
52
59
|
memory: { used: 0, total: 0, percentage: 0 },
|
|
53
60
|
disk: { used: 0, total: 0, percentage: 0 }
|
|
@@ -64,7 +71,7 @@ const fetchData = async () => {
|
|
|
64
71
|
}
|
|
65
72
|
);
|
|
66
73
|
Object.assign(systemResources, data);
|
|
67
|
-
} catch (
|
|
74
|
+
} catch (_error) {
|
|
68
75
|
// 静默失败:不阻断页面展示
|
|
69
76
|
}
|
|
70
77
|
};
|
|
@@ -72,7 +79,7 @@ const fetchData = async () => {
|
|
|
72
79
|
fetchData();
|
|
73
80
|
|
|
74
81
|
// 工具函数
|
|
75
|
-
const getProgressColor = (percentage) => {
|
|
82
|
+
const getProgressColor = (percentage: number): string => {
|
|
76
83
|
if (percentage < 50) return "success";
|
|
77
84
|
if (percentage < 80) return "warning";
|
|
78
85
|
return "danger";
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
</template>
|
|
40
40
|
|
|
41
41
|
<script setup lang="ts">
|
|
42
|
+
import { reactive } from "vue";
|
|
42
43
|
import { Button as TButton, MessagePlugin } from "tdesign-vue-next";
|
|
43
44
|
import ILucideUser from "~icons/lucide/user";
|
|
44
45
|
import ILucideMail from "~icons/lucide/mail";
|
|
@@ -47,9 +48,22 @@ import ILucideClock from "~icons/lucide/clock";
|
|
|
47
48
|
import ILucideRotateCw from "~icons/lucide/rotate-cw";
|
|
48
49
|
import { $Http } from "@/plugins/http";
|
|
49
50
|
|
|
51
|
+
type UserInfo = {
|
|
52
|
+
nickname?: string;
|
|
53
|
+
name?: string;
|
|
54
|
+
username?: string;
|
|
55
|
+
role?: {
|
|
56
|
+
name?: string;
|
|
57
|
+
};
|
|
58
|
+
roleCode?: string;
|
|
59
|
+
email?: string;
|
|
60
|
+
phone?: string;
|
|
61
|
+
lastLoginTime?: number | string;
|
|
62
|
+
};
|
|
63
|
+
|
|
50
64
|
// 响应式数据
|
|
51
|
-
const $Data =
|
|
52
|
-
userInfo: {},
|
|
65
|
+
const $Data = reactive({
|
|
66
|
+
userInfo: {} as UserInfo,
|
|
53
67
|
refreshing: false
|
|
54
68
|
});
|
|
55
69
|
|
|
@@ -62,8 +76,8 @@ async function fetchData(): Promise<void> {
|
|
|
62
76
|
dropValues: [""]
|
|
63
77
|
}
|
|
64
78
|
);
|
|
65
|
-
Object.assign($Data.userInfo, data);
|
|
66
|
-
} catch (
|
|
79
|
+
Object.assign($Data.userInfo, data as UserInfo);
|
|
80
|
+
} catch (_error) {
|
|
67
81
|
MessagePlugin.error("获取用户信息失败");
|
|
68
82
|
}
|
|
69
83
|
}
|
|
@@ -93,7 +107,7 @@ async function handleRefreshCache(): Promise<void> {
|
|
|
93
107
|
} else {
|
|
94
108
|
MessagePlugin.warning(result.msg || "部分缓存刷新失败");
|
|
95
109
|
}
|
|
96
|
-
} catch (
|
|
110
|
+
} catch (_error) {
|
|
97
111
|
MessagePlugin.error("刷新缓存失败,请稍后重试");
|
|
98
112
|
} finally {
|
|
99
113
|
$Data.refreshing = false;
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
</template>
|
|
25
25
|
|
|
26
26
|
<template #sendResult="{ row }">
|
|
27
|
-
<TTag v-if="row.sendResult === 1" shape="round" theme="success" variant="light-outline"
|
|
28
|
-
<TTag v-else shape="round" theme="danger" variant="light-outline"
|
|
27
|
+
<TTag v-if="row.sendResult === 1" shape="round" theme="success" variant="light-outline"> 成功 </TTag>
|
|
28
|
+
<TTag v-else shape="round" theme="danger" variant="light-outline"> 失败 </TTag>
|
|
29
29
|
</template>
|
|
30
30
|
|
|
31
31
|
<template #sendTime="{ row }">
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
<template #detail="scope">
|
|
36
36
|
<DetailPanel :data="scope.row" :fields="$Data.columns">
|
|
37
37
|
<template #sendResult="slotScope">
|
|
38
|
-
<TTag v-if="slotScope.value === 1" shape="round" theme="success" variant="light-outline"
|
|
39
|
-
<TTag v-else shape="round" theme="danger" variant="light-outline"
|
|
38
|
+
<TTag v-if="slotScope.value === 1" shape="round" theme="success" variant="light-outline"> 成功 </TTag>
|
|
39
|
+
<TTag v-else shape="round" theme="danger" variant="light-outline"> 失败 </TTag>
|
|
40
40
|
</template>
|
|
41
41
|
<template #sendTime="slotScope">
|
|
42
42
|
{{ formatTime(slotScope.value) }}
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
|
|
50
50
|
<template #dialogs="scope">
|
|
51
51
|
<PageDialog v-model="$Data.sendDialogVisible" title="发送邮件" :confirm-loading="$Data.sending" @confirm="(context) => onSend(scope.reload, context)" @cancel="onCancelSend" @close="onCancelSend">
|
|
52
|
-
<TForm
|
|
52
|
+
<TForm ref="sendFormRef" :data="$Data.sendForm" :rules="$Data.sendRules" label-width="80px">
|
|
53
53
|
<TFormItem label="收件人" name="to">
|
|
54
54
|
<TInput v-model="$Data.sendForm.to" placeholder="请输入收件人邮箱" />
|
|
55
55
|
</TFormItem>
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
</template>
|
|
70
70
|
|
|
71
71
|
<script setup lang="ts">
|
|
72
|
+
import { reactive, ref } from "vue";
|
|
72
73
|
import { Button as TButton, Form as TForm, FormItem as TFormItem, Input as TInput, MessagePlugin, Space as TSpace, Tag as TTag, Textarea as TTextarea } from "tdesign-vue-next";
|
|
73
74
|
import ILucideRotateCw from "~icons/lucide/rotate-cw";
|
|
74
75
|
import ILucideSend from "~icons/lucide/send";
|
|
@@ -79,12 +80,14 @@ import { $Http } from "@/plugins/http";
|
|
|
79
80
|
import PagedTableDetail from "@/components/pagedTableDetail.vue";
|
|
80
81
|
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
83
|
+
type TDesignFormInstance = {
|
|
84
|
+
validate: () => Promise<unknown>;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const sendFormRef = ref<TDesignFormInstance | null>(null);
|
|
85
88
|
|
|
86
89
|
// 响应式数据
|
|
87
|
-
const $Data =
|
|
90
|
+
const $Data = reactive({
|
|
88
91
|
columns: withDefaultColumns([
|
|
89
92
|
{ colKey: "username", title: "发送人", fixed: "left" },
|
|
90
93
|
{ colKey: "toEmail", title: "收件人" },
|
|
@@ -142,7 +145,13 @@ type PageDialogEventContext = {
|
|
|
142
145
|
};
|
|
143
146
|
|
|
144
147
|
async function onSend(reload: ((options: { keepSelection?: boolean; resetPage?: boolean }) => void) | null, context?: PageDialogEventContext): Promise<void> {
|
|
145
|
-
const
|
|
148
|
+
const form = sendFormRef.value;
|
|
149
|
+
if (!form) {
|
|
150
|
+
MessagePlugin.warning("表单未就绪");
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const valid = await form.validate();
|
|
146
155
|
if (valid !== true) return;
|
|
147
156
|
|
|
148
157
|
$Data.sending = true;
|
|
@@ -168,7 +177,7 @@ async function onSend(reload: ((options: { keepSelection?: boolean; resetPage?:
|
|
|
168
177
|
} else {
|
|
169
178
|
MessagePlugin.error(res.msg || "发送失败");
|
|
170
179
|
}
|
|
171
|
-
} catch (
|
|
180
|
+
} catch (_error) {
|
|
172
181
|
MessagePlugin.error("发送失败");
|
|
173
182
|
} finally {
|
|
174
183
|
$Data.sending = false;
|
|
@@ -183,7 +192,7 @@ async function onVerify(): Promise<void> {
|
|
|
183
192
|
} else {
|
|
184
193
|
MessagePlugin.error(res.msg || "配置异常");
|
|
185
194
|
}
|
|
186
|
-
} catch (
|
|
195
|
+
} catch (_error) {
|
|
187
196
|
MessagePlugin.error("验证失败");
|
|
188
197
|
}
|
|
189
198
|
}
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
</template>
|
|
40
40
|
|
|
41
41
|
<script setup lang="ts">
|
|
42
|
+
import { reactive } from "vue";
|
|
42
43
|
import { Button as TButton, Tag as TTag } from "tdesign-vue-next";
|
|
43
44
|
import ILucideRotateCw from "~icons/lucide/rotate-cw";
|
|
44
45
|
import DetailPanel from "@/components/detailPanel.vue";
|
|
@@ -46,7 +47,7 @@ import PagedTableDetail from "@/components/pagedTableDetail.vue";
|
|
|
46
47
|
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
47
48
|
|
|
48
49
|
// 响应式数据
|
|
49
|
-
const $Data =
|
|
50
|
+
const $Data = reactive({
|
|
50
51
|
columns: withDefaultColumns([
|
|
51
52
|
{ colKey: "username", title: "用户名", fixed: "left" },
|
|
52
53
|
{ colKey: "ip", title: "登录IP" },
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
</template>
|
|
63
63
|
|
|
64
64
|
<script setup lang="ts">
|
|
65
|
+
import { reactive } from "vue";
|
|
65
66
|
import { Button as TButton, Option as TOption, Select as TSelect, Tag as TTag } from "tdesign-vue-next";
|
|
66
67
|
import ILucideRotateCw from "~icons/lucide/rotate-cw";
|
|
67
68
|
import DetailPanel from "@/components/detailPanel.vue";
|
|
@@ -69,7 +70,7 @@ import PagedTableDetail from "@/components/pagedTableDetail.vue";
|
|
|
69
70
|
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
70
71
|
|
|
71
72
|
// 响应式数据
|
|
72
|
-
const $Data =
|
|
73
|
+
const $Data = reactive({
|
|
73
74
|
columns: withDefaultColumns([
|
|
74
75
|
{ colKey: "username", title: "操作人", fixed: "left", width: 100 },
|
|
75
76
|
{ colKey: "module", title: "模块", width: 100 },
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
<p class="login-subtitle">请登录您的账户</p>
|
|
22
22
|
</div>
|
|
23
23
|
|
|
24
|
-
<TForm :model="$Data.formData" :rules="$Data.formRules"
|
|
24
|
+
<TForm :model="$Data.formData" :rules="$Data.formRules" ref="formRef" class="login-form" :show-message="false" label-width="0">
|
|
25
25
|
<TFormItem prop="account">
|
|
26
26
|
<TInputAdornment>
|
|
27
27
|
<template #prepend>
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
|
|
50
50
|
<div class="form-options">
|
|
51
51
|
<TCheckbox v-model="$Data.rememberMe">记住我</TCheckbox>
|
|
52
|
-
<a href="#" class="link-text"
|
|
52
|
+
<a href="#" class="link-text"> 忘记密码? </a>
|
|
53
53
|
</div>
|
|
54
54
|
|
|
55
55
|
<TButton theme="primary" class="login-btn" size="large" block :loading="$Data.loading" @click="apiLogin"> 登录 </TButton>
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
</template>
|
|
65
65
|
|
|
66
66
|
<script setup lang="ts">
|
|
67
|
+
import { reactive, ref } from "vue";
|
|
67
68
|
import { useRouter } from "vue-router";
|
|
68
69
|
import { Form as TForm, FormItem as TFormItem, Input as TInput, Button as TButton, Checkbox as TCheckbox, InputAdornment as TInputAdornment, Select as TSelect, Option as TOption, MessagePlugin } from "tdesign-vue-next";
|
|
69
70
|
import ILucideUser from "~icons/lucide/user";
|
|
@@ -74,13 +75,10 @@ import { hashPassword } from "befly-shared/utils/hashPassword";
|
|
|
74
75
|
|
|
75
76
|
const router = useRouter();
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
const $From = $shallowRef({
|
|
79
|
-
form: null
|
|
80
|
-
});
|
|
78
|
+
const formRef = ref<null | { validate: () => Promise<boolean> }>(null);
|
|
81
79
|
|
|
82
80
|
// 数据定义
|
|
83
|
-
const $Data =
|
|
81
|
+
const $Data = reactive({
|
|
84
82
|
loading: false,
|
|
85
83
|
rememberMe: false,
|
|
86
84
|
formRules: {
|
|
@@ -96,7 +94,12 @@ const $Data = $ref({
|
|
|
96
94
|
|
|
97
95
|
async function apiLogin(): Promise<void> {
|
|
98
96
|
try {
|
|
99
|
-
|
|
97
|
+
if (formRef.value === null) {
|
|
98
|
+
MessagePlugin.error("表单未就绪");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
await formRef.value.validate();
|
|
100
103
|
|
|
101
104
|
$Data.loading = true;
|
|
102
105
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<PageDialog v-model="dialogVisible" :title="$Prop.actionType === 'upd' ? '编辑管理员' : '添加管理员'" :confirm-loading="$Data.submitting" @confirm="onSubmit">
|
|
3
3
|
<div class="dialog-wrapper">
|
|
4
|
-
<TForm :model="$Data.formData" label-width="80px" label-position="left" label-align="left" :rules="$Data2.formRules"
|
|
4
|
+
<TForm :model="$Data.formData" label-width="80px" label-position="left" label-align="left" :rules="$Data2.formRules" ref="formRef">
|
|
5
5
|
<TFormItem label="角色" prop="roleCode">
|
|
6
6
|
<TSelect v-model="$Data.formData.roleCode" :options="$Data.allRoleLists" :keys="$Data.keys" placeholder="请选择角色" />
|
|
7
7
|
</TFormItem>
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
</template>
|
|
27
27
|
|
|
28
28
|
<script setup lang="ts">
|
|
29
|
-
import { computed } from "vue";
|
|
29
|
+
import { computed, reactive, ref } from "vue";
|
|
30
30
|
|
|
31
31
|
import {
|
|
32
32
|
//
|
|
@@ -68,9 +68,11 @@ type PageDialogEventContext = {
|
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
// 表单引用
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
71
|
+
type TDesignFormInstance = {
|
|
72
|
+
validate: () => Promise<unknown>;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const formRef = ref<TDesignFormInstance | null>(null);
|
|
74
76
|
|
|
75
77
|
const dialogVisible = computed({
|
|
76
78
|
get: () => $Prop.modelValue,
|
|
@@ -79,7 +81,7 @@ const dialogVisible = computed({
|
|
|
79
81
|
}
|
|
80
82
|
});
|
|
81
83
|
|
|
82
|
-
const $Data =
|
|
84
|
+
const $Data = reactive({
|
|
83
85
|
submitting: false,
|
|
84
86
|
allRoleLists: [],
|
|
85
87
|
keys: {
|
|
@@ -96,7 +98,7 @@ const $Data = $ref({
|
|
|
96
98
|
}
|
|
97
99
|
});
|
|
98
100
|
|
|
99
|
-
const $Data2 =
|
|
101
|
+
const $Data2 = reactive({
|
|
100
102
|
formRules: {
|
|
101
103
|
username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
|
|
102
104
|
password: [
|
|
@@ -125,14 +127,20 @@ async function apiRoleLists(): Promise<void> {
|
|
|
125
127
|
}
|
|
126
128
|
);
|
|
127
129
|
$Data.allRoleLists = result.data || [];
|
|
128
|
-
} catch (
|
|
130
|
+
} catch (_error) {
|
|
129
131
|
MessagePlugin.error("加载角色列表失败");
|
|
130
132
|
}
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
async function onSubmit(context?: PageDialogEventContext): Promise<void> {
|
|
134
136
|
try {
|
|
135
|
-
const
|
|
137
|
+
const form = formRef.value;
|
|
138
|
+
if (!form) {
|
|
139
|
+
MessagePlugin.warning("表单未就绪");
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const valid = await form.validate();
|
|
136
144
|
if (!valid) return;
|
|
137
145
|
|
|
138
146
|
$Data.submitting = true;
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
</template>
|
|
49
49
|
|
|
50
50
|
<script setup lang="ts">
|
|
51
|
+
import { reactive } from "vue";
|
|
51
52
|
import { Button as TButton, Dropdown as TDropdown, DropdownItem as TDropdownItem, DropdownMenu as TDropdownMenu, Tag as TTag } from "tdesign-vue-next";
|
|
52
53
|
import ILucidePlus from "~icons/lucide/plus";
|
|
53
54
|
import ILucideRotateCw from "~icons/lucide/rotate-cw";
|
|
@@ -59,7 +60,7 @@ import PagedTableDetail from "@/components/pagedTableDetail.vue";
|
|
|
59
60
|
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
60
61
|
|
|
61
62
|
// 响应式数据
|
|
62
|
-
const $Data =
|
|
63
|
+
const $Data = reactive({
|
|
63
64
|
columns: withDefaultColumns([
|
|
64
65
|
{ colKey: "username", title: "用户名", fixed: "left" },
|
|
65
66
|
{ colKey: "nickname", title: "昵称" },
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
</template>
|
|
60
60
|
|
|
61
61
|
<script setup lang="ts">
|
|
62
|
+
import { reactive } from "vue";
|
|
62
63
|
import { Button as TButton, Table as TTable, Tag as TTag, Input as TInput, MessagePlugin } from "tdesign-vue-next";
|
|
63
64
|
import ILucideRotateCw from "~icons/lucide/rotate-cw";
|
|
64
65
|
import ILucideSearch from "~icons/lucide/search";
|
|
@@ -67,7 +68,7 @@ import { $Http } from "@/plugins/http";
|
|
|
67
68
|
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
68
69
|
|
|
69
70
|
// 响应式数据
|
|
70
|
-
const $Data =
|
|
71
|
+
const $Data = reactive({
|
|
71
72
|
tableData: [],
|
|
72
73
|
allData: [],
|
|
73
74
|
loading: false,
|
|
@@ -108,7 +109,7 @@ async function loadApiAll(): Promise<void> {
|
|
|
108
109
|
$Data.currentRow = null;
|
|
109
110
|
$Data.activeRowKeys = [];
|
|
110
111
|
}
|
|
111
|
-
} catch (
|
|
112
|
+
} catch (_error) {
|
|
112
113
|
MessagePlugin.error("加载数据失败");
|
|
113
114
|
} finally {
|
|
114
115
|
$Data.loading = false;
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
</template>
|
|
41
41
|
|
|
42
42
|
<script setup lang="ts">
|
|
43
|
+
import { reactive } from "vue";
|
|
43
44
|
import { Button as TButton, Table as TTable, Tag as TTag, MessagePlugin } from "tdesign-vue-next";
|
|
44
45
|
import ILucideRotateCw from "~icons/lucide/rotate-cw";
|
|
45
46
|
import DetailPanel from "@/components/detailPanel.vue";
|
|
@@ -48,7 +49,7 @@ import { arrayToTree } from "befly-shared/utils/arrayToTree";
|
|
|
48
49
|
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
49
50
|
|
|
50
51
|
// 响应式数据
|
|
51
|
-
const $Data =
|
|
52
|
+
const $Data = reactive({
|
|
52
53
|
tableData: [],
|
|
53
54
|
loading: false,
|
|
54
55
|
columns: withDefaultColumns([
|
|
@@ -89,7 +90,7 @@ async function apiMenuList(): Promise<void> {
|
|
|
89
90
|
$Data.currentRow = null;
|
|
90
91
|
$Data.activeRowKeys = [];
|
|
91
92
|
}
|
|
92
|
-
} catch (
|
|
93
|
+
} catch (_error) {
|
|
93
94
|
MessagePlugin.error("加载数据失败");
|
|
94
95
|
} finally {
|
|
95
96
|
$Data.loading = false;
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
</template>
|
|
33
33
|
|
|
34
34
|
<script setup lang="ts">
|
|
35
|
-
import { computed } from "vue";
|
|
35
|
+
import { computed, reactive } from "vue";
|
|
36
36
|
|
|
37
37
|
import { Input as TInput, CheckboxGroup as TCheckboxGroup, Checkbox as TCheckbox, MessagePlugin } from "tdesign-vue-next";
|
|
38
38
|
import ILucideSearch from "~icons/lucide/search";
|
|
@@ -66,7 +66,7 @@ const dialogVisible = computed({
|
|
|
66
66
|
}
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
-
const $Data =
|
|
69
|
+
const $Data = reactive({
|
|
70
70
|
submitting: false,
|
|
71
71
|
apiData: [],
|
|
72
72
|
filteredApiData: [],
|
|
@@ -164,7 +164,7 @@ async function apiApiAll(): Promise<void> {
|
|
|
164
164
|
});
|
|
165
165
|
|
|
166
166
|
$Data.apiData = groups as never;
|
|
167
|
-
} catch (
|
|
167
|
+
} catch (_error) {
|
|
168
168
|
MessagePlugin.error("加载接口失败");
|
|
169
169
|
}
|
|
170
170
|
}
|
|
@@ -186,7 +186,7 @@ async function apiRoleApiDetail(): Promise<void> {
|
|
|
186
186
|
const resRecord = res && typeof res === "object" ? (res as Record<string, unknown>) : null;
|
|
187
187
|
const resData = resRecord && resRecord["data"] && typeof resRecord["data"] === "object" ? (resRecord["data"] as Record<string, unknown>) : null;
|
|
188
188
|
$Data.checkedApiPaths = resData && Array.isArray(resData["apiPaths"]) ? (resData["apiPaths"] as never) : ([] as never);
|
|
189
|
-
} catch (
|
|
189
|
+
} catch (_error) {
|
|
190
190
|
MessagePlugin.error("加载数据失败");
|
|
191
191
|
}
|
|
192
192
|
}
|
|
@@ -236,7 +236,7 @@ async function onSubmit(context?: PageDialogEventContext): Promise<void> {
|
|
|
236
236
|
} else {
|
|
237
237
|
MessagePlugin.error(res.msg || "保存失败");
|
|
238
238
|
}
|
|
239
|
-
} catch (
|
|
239
|
+
} catch (_error) {
|
|
240
240
|
MessagePlugin.error("保存失败");
|
|
241
241
|
} finally {
|
|
242
242
|
$Data.submitting = false;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<PageDialog v-model="dialogVisible" :title="$Prop.actionType === 'upd' ? '更新角色' : '添加角色'" :confirm-loading="$Data.submitting" @confirm="onSubmit">
|
|
3
3
|
<div class="comp-role-edit">
|
|
4
|
-
<TForm :model="$Data.formData" label-width="120px" label-position="left" :rules="$Data2.formRules"
|
|
4
|
+
<TForm :model="$Data.formData" label-width="120px" label-position="left" :rules="$Data2.formRules" ref="formRef">
|
|
5
5
|
<TFormItem label="角色名称" prop="name">
|
|
6
6
|
<TInput v-model="$Data.formData.name" placeholder="请输入角色名称" />
|
|
7
7
|
</TFormItem>
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
</template>
|
|
27
27
|
|
|
28
28
|
<script setup lang="ts">
|
|
29
|
-
import { computed } from "vue";
|
|
29
|
+
import { computed, reactive, ref } from "vue";
|
|
30
30
|
|
|
31
31
|
import {
|
|
32
32
|
//
|
|
@@ -68,13 +68,15 @@ type PageDialogEventContext = {
|
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
// 表单引用
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
71
|
+
type TDesignFormInstance = {
|
|
72
|
+
validate: () => Promise<unknown>;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const formRef = ref<TDesignFormInstance | null>(null);
|
|
74
76
|
|
|
75
77
|
const $Computed = {};
|
|
76
78
|
|
|
77
|
-
const $Data =
|
|
79
|
+
const $Data = reactive({
|
|
78
80
|
submitting: false,
|
|
79
81
|
formData: {
|
|
80
82
|
id: 0,
|
|
@@ -86,7 +88,7 @@ const $Data = $ref({
|
|
|
86
88
|
}
|
|
87
89
|
});
|
|
88
90
|
|
|
89
|
-
const $Data2 =
|
|
91
|
+
const $Data2 = reactive({
|
|
90
92
|
formRules: {
|
|
91
93
|
name: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
|
|
92
94
|
code: [
|
|
@@ -112,7 +114,13 @@ const dialogVisible = computed({
|
|
|
112
114
|
|
|
113
115
|
async function onSubmit(context?: PageDialogEventContext): Promise<void> {
|
|
114
116
|
try {
|
|
115
|
-
const
|
|
117
|
+
const form = formRef.value;
|
|
118
|
+
if (!form) {
|
|
119
|
+
MessagePlugin.warning("表单未就绪");
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const valid = await form.validate();
|
|
116
124
|
if (!valid) return;
|
|
117
125
|
|
|
118
126
|
$Data.submitting = true;
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
</template>
|
|
34
34
|
|
|
35
35
|
<script setup lang="ts">
|
|
36
|
-
import { computed } from "vue";
|
|
36
|
+
import { computed, reactive } from "vue";
|
|
37
37
|
|
|
38
38
|
import { CheckboxGroup as TCheckboxGroup, Checkbox as TCheckbox, Input as TInput, MessagePlugin } from "tdesign-vue-next";
|
|
39
39
|
import ILucideSearch from "~icons/lucide/search";
|
|
@@ -68,7 +68,7 @@ const dialogVisible = computed({
|
|
|
68
68
|
}
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
-
const $Data =
|
|
71
|
+
const $Data = reactive({
|
|
72
72
|
submitting: false,
|
|
73
73
|
searchText: "",
|
|
74
74
|
menuGroups: [],
|
|
@@ -134,7 +134,7 @@ async function apiMenuAll(): Promise<void> {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
$Data.menuGroups = groups as never;
|
|
137
|
-
} catch (
|
|
137
|
+
} catch (_error) {
|
|
138
138
|
MessagePlugin.error("加载菜单失败");
|
|
139
139
|
}
|
|
140
140
|
}
|
|
@@ -154,7 +154,7 @@ async function apiRoleMenuDetail(): Promise<void> {
|
|
|
154
154
|
);
|
|
155
155
|
|
|
156
156
|
$Data.checkedMenuPaths = Array.isArray(res.data) ? res.data : [];
|
|
157
|
-
} catch (
|
|
157
|
+
} catch (_error) {
|
|
158
158
|
MessagePlugin.error("加载数据失败");
|
|
159
159
|
}
|
|
160
160
|
}
|
|
@@ -204,7 +204,7 @@ async function onSubmit(context?: PageDialogEventContext): Promise<void> {
|
|
|
204
204
|
} else {
|
|
205
205
|
MessagePlugin.error(res.msg || "保存失败");
|
|
206
206
|
}
|
|
207
|
-
} catch (
|
|
207
|
+
} catch (_error) {
|
|
208
208
|
MessagePlugin.error("保存失败");
|
|
209
209
|
} finally {
|
|
210
210
|
$Data.submitting = false;
|
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
</template>
|
|
72
72
|
|
|
73
73
|
<script setup lang="ts">
|
|
74
|
+
import { reactive } from "vue";
|
|
74
75
|
import { Button as TButton, Dropdown as TDropdown, DropdownItem as TDropdownItem, DropdownMenu as TDropdownMenu, Tag as TTag } from "tdesign-vue-next";
|
|
75
76
|
import ILucidePlus from "~icons/lucide/plus";
|
|
76
77
|
import ILucideRotateCw from "~icons/lucide/rotate-cw";
|
|
@@ -86,7 +87,7 @@ import PagedTableDetail from "@/components/pagedTableDetail.vue";
|
|
|
86
87
|
import { withDefaultColumns } from "befly-shared/utils/withDefaultColumns";
|
|
87
88
|
|
|
88
89
|
// 响应式数据
|
|
89
|
-
const $Data =
|
|
90
|
+
const $Data = reactive({
|
|
90
91
|
columns: withDefaultColumns([
|
|
91
92
|
{ colKey: "name", title: "角色名称" },
|
|
92
93
|
{ colKey: "code", title: "角色代码", width: 150 },
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@befly-addon/admin",
|
|
3
|
-
"version": "1.8.
|
|
4
|
-
"gitHead": "
|
|
3
|
+
"version": "1.8.7",
|
|
4
|
+
"gitHead": "f9f6bca0385e275961720d686bab20b2e2167f87",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Befly - 管理后台功能组件",
|
|
7
7
|
"keywords": [
|