@befly-addon/admin 1.5.2 → 1.6.1
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/permission/api/index.vue +2 -2
- package/adminViews/permission/role/components/api.vue +77 -28
- package/adminViews/permission/role/components/edit.vue +0 -5
- package/apis/admin/ins.ts +3 -3
- package/apis/admin/upd.ts +10 -5
- package/apis/api/list.ts +1 -1
- package/apis/auth/login.ts +11 -3
- package/apis/dict/ins.ts +2 -2
- package/apis/dict/items.ts +1 -1
- package/apis/dict/upd.ts +4 -4
- package/apis/dictType/del.ts +2 -2
- package/apis/email/config.ts +1 -1
- package/apis/menu/all.ts +10 -4
- package/apis/role/apiSave.ts +4 -3
- package/apis/sysConfig/get.ts +6 -1
- package/apis/sysConfig/ins.ts +1 -1
- package/package.json +2 -2
- package/tables/api.json +8 -1
- package/utils/fieldClear.ts +1 -1
|
@@ -75,7 +75,7 @@ const $Data = $ref({
|
|
|
75
75
|
columns: withDefaultColumns([
|
|
76
76
|
{ colKey: "name", title: "接口名称" },
|
|
77
77
|
{ colKey: "auth", title: "登录" },
|
|
78
|
-
{ colKey: "
|
|
78
|
+
{ colKey: "path", title: "接口路径" },
|
|
79
79
|
{ colKey: "method", title: "请求方法" },
|
|
80
80
|
{ colKey: "addonName", title: "所属组件" }
|
|
81
81
|
]),
|
|
@@ -125,7 +125,7 @@ const $Method = {
|
|
|
125
125
|
return;
|
|
126
126
|
}
|
|
127
127
|
const keyword = $Data.searchKeyword.toLowerCase();
|
|
128
|
-
$Data.tableData = $Data.allData.filter((item) => item.name?.toLowerCase().includes(keyword) || item.
|
|
128
|
+
$Data.tableData = $Data.allData.filter((item) => item.name?.toLowerCase().includes(keyword) || item.path?.toLowerCase().includes(keyword));
|
|
129
129
|
},
|
|
130
130
|
|
|
131
131
|
// 高亮行变化
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
|
|
13
13
|
<!-- 接口分组列表 -->
|
|
14
14
|
<div class="api-container">
|
|
15
|
-
<
|
|
16
|
-
<div class="group-
|
|
17
|
-
|
|
18
|
-
<
|
|
15
|
+
<TCheckboxGroup v-model="$Data.checkedApiPaths">
|
|
16
|
+
<div class="api-group" v-for="group in $Data.filteredApiData" :key="group.name">
|
|
17
|
+
<div class="group-header">{{ group.title }}</div>
|
|
18
|
+
<div class="api-checkbox-list">
|
|
19
19
|
<TCheckbox v-for="api in group.apis" :key="api.value" :value="api.value">
|
|
20
20
|
<div class="api-checkbox-label">
|
|
21
21
|
<div class="api-label-main">
|
|
@@ -23,25 +23,25 @@
|
|
|
23
23
|
</div>
|
|
24
24
|
</div>
|
|
25
25
|
</TCheckbox>
|
|
26
|
-
</
|
|
26
|
+
</div>
|
|
27
27
|
</div>
|
|
28
|
-
</
|
|
28
|
+
</TCheckboxGroup>
|
|
29
29
|
</div>
|
|
30
30
|
</div>
|
|
31
31
|
|
|
32
32
|
<template #footer>
|
|
33
33
|
<div class="dialog-footer">
|
|
34
|
-
<
|
|
34
|
+
<TSpace>
|
|
35
35
|
<TButton theme="default" @click="$Method.onClose">取消</TButton>
|
|
36
36
|
<TButton theme="primary" :loading="$Data.submitting" @click="$Method.onSubmit">保存</TButton>
|
|
37
|
-
</
|
|
37
|
+
</TSpace>
|
|
38
38
|
</div>
|
|
39
39
|
</template>
|
|
40
40
|
</TDialog>
|
|
41
41
|
</template>
|
|
42
42
|
|
|
43
43
|
<script setup lang="ts">
|
|
44
|
-
import { Dialog as TDialog, Input as TInput, CheckboxGroup as TCheckboxGroup, Checkbox as TCheckbox, Button as TButton, MessagePlugin } from "tdesign-vue-next";
|
|
44
|
+
import { Dialog as TDialog, Input as TInput, CheckboxGroup as TCheckboxGroup, Checkbox as TCheckbox, Button as TButton, Space as TSpace, MessagePlugin } from "tdesign-vue-next";
|
|
45
45
|
import ILucideSearch from "~icons/lucide/search";
|
|
46
46
|
import { $Http } from "@/plugins/http";
|
|
47
47
|
|
|
@@ -85,7 +85,8 @@ const $Method = {
|
|
|
85
85
|
const apis = group && group.apis;
|
|
86
86
|
const list = Array.isArray(apis) ? apis : [];
|
|
87
87
|
for (const api of list) {
|
|
88
|
-
|
|
88
|
+
const isPublic = api && (api.auth === 0 || api.auth === "0" || api.auth === false);
|
|
89
|
+
if (isPublic && typeof api.value === "string" && api.value) {
|
|
89
90
|
merged.add(api.value);
|
|
90
91
|
}
|
|
91
92
|
}
|
|
@@ -113,32 +114,54 @@ const $Method = {
|
|
|
113
114
|
try {
|
|
114
115
|
const res = await $Http("/addon/admin/api/all");
|
|
115
116
|
|
|
116
|
-
// 将接口列表按
|
|
117
|
+
// 将接口列表按 parentPath 分组展示(routePath 已迁移为 path)
|
|
117
118
|
const apiMap = new Map();
|
|
118
119
|
|
|
119
|
-
res.data.lists
|
|
120
|
-
|
|
121
|
-
const
|
|
120
|
+
const lists = res && res.data && Array.isArray(res.data.lists) ? res.data.lists : [];
|
|
121
|
+
for (const api of lists) {
|
|
122
|
+
const apiPath = api && typeof api.path === "string" ? api.path : "";
|
|
123
|
+
if (!apiPath) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const parentPath = api && typeof api.parentPath === "string" ? api.parentPath : "";
|
|
128
|
+
const groupKey = parentPath || "(未分组)";
|
|
122
129
|
|
|
123
|
-
if (!apiMap.has(
|
|
124
|
-
apiMap.set(
|
|
125
|
-
name:
|
|
126
|
-
title:
|
|
130
|
+
if (!apiMap.has(groupKey)) {
|
|
131
|
+
apiMap.set(groupKey, {
|
|
132
|
+
name: groupKey,
|
|
133
|
+
title: groupKey,
|
|
127
134
|
apis: []
|
|
128
135
|
});
|
|
129
136
|
}
|
|
130
137
|
|
|
131
|
-
apiMap.get(
|
|
132
|
-
value:
|
|
133
|
-
name: api.name
|
|
134
|
-
path:
|
|
135
|
-
label: `${api.name || ""} ${
|
|
136
|
-
description: api.description,
|
|
137
|
-
auth: api.auth
|
|
138
|
+
apiMap.get(groupKey).apis.push({
|
|
139
|
+
value: apiPath,
|
|
140
|
+
name: (api && typeof api.name === "string" ? api.name : "") || apiPath,
|
|
141
|
+
path: apiPath,
|
|
142
|
+
label: `${(api && typeof api.name === "string" ? api.name : "") || ""} ${apiPath ? `(${apiPath})` : ""}`.trim(),
|
|
143
|
+
description: api ? api.description : undefined,
|
|
144
|
+
auth: api ? api.auth : undefined,
|
|
145
|
+
parentPath: parentPath
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const groups = Array.from(apiMap.values());
|
|
150
|
+
for (const group of groups) {
|
|
151
|
+
group.apis.sort((a, b) => {
|
|
152
|
+
const ap = typeof a.path === "string" ? a.path : "";
|
|
153
|
+
const bp = typeof b.path === "string" ? b.path : "";
|
|
154
|
+
return ap.localeCompare(bp);
|
|
138
155
|
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
groups.sort((a, b) => {
|
|
159
|
+
const at = typeof a.title === "string" ? a.title : "";
|
|
160
|
+
const bt = typeof b.title === "string" ? b.title : "";
|
|
161
|
+
return at.localeCompare(bt);
|
|
139
162
|
});
|
|
140
163
|
|
|
141
|
-
$Data.apiData =
|
|
164
|
+
$Data.apiData = groups;
|
|
142
165
|
} catch (error) {
|
|
143
166
|
MessagePlugin.error("加载接口失败");
|
|
144
167
|
}
|
|
@@ -169,7 +192,12 @@ const $Method = {
|
|
|
169
192
|
const searchLower = $Data.searchText.toLowerCase();
|
|
170
193
|
$Data.filteredApiData = $Data.apiData
|
|
171
194
|
.map((group) => {
|
|
172
|
-
const apis = group.apis.filter((api) =>
|
|
195
|
+
const apis = group.apis.filter((api) => {
|
|
196
|
+
const label = api && typeof api.label === "string" ? api.label : "";
|
|
197
|
+
const name = api && typeof api.name === "string" ? api.name : "";
|
|
198
|
+
const path = api && typeof api.path === "string" ? api.path : "";
|
|
199
|
+
return label.toLowerCase().includes(searchLower) || name.toLowerCase().includes(searchLower) || path.toLowerCase().includes(searchLower);
|
|
200
|
+
});
|
|
173
201
|
return {
|
|
174
202
|
name: group.name,
|
|
175
203
|
title: group.title,
|
|
@@ -218,6 +246,12 @@ $Method.initData();
|
|
|
218
246
|
flex: 1;
|
|
219
247
|
overflow-y: auto;
|
|
220
248
|
|
|
249
|
+
/* CheckboxGroup 默认可能是 inline 布局,容易被内容撑开;这里强制占满容器宽度 */
|
|
250
|
+
:deep(.t-checkbox-group) {
|
|
251
|
+
display: block;
|
|
252
|
+
width: 100%;
|
|
253
|
+
}
|
|
254
|
+
|
|
221
255
|
.api-group {
|
|
222
256
|
margin-bottom: 16px;
|
|
223
257
|
border: 1px solid var(--border-color);
|
|
@@ -225,7 +259,22 @@ $Method.initData();
|
|
|
225
259
|
overflow: hidden;
|
|
226
260
|
|
|
227
261
|
.api-checkbox-list {
|
|
228
|
-
padding:
|
|
262
|
+
padding: 12px 16px;
|
|
263
|
+
display: flex;
|
|
264
|
+
flex-wrap: wrap;
|
|
265
|
+
gap: 12px;
|
|
266
|
+
|
|
267
|
+
:deep(.t-checkbox) {
|
|
268
|
+
margin: 0;
|
|
269
|
+
flex: 0 0 calc(33.333% - 8px);
|
|
270
|
+
min-width: 0;
|
|
271
|
+
|
|
272
|
+
.t-checkbox__label {
|
|
273
|
+
white-space: nowrap;
|
|
274
|
+
overflow: hidden;
|
|
275
|
+
text-overflow: ellipsis;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
229
278
|
}
|
|
230
279
|
|
|
231
280
|
&:last-child {
|
package/apis/admin/ins.ts
CHANGED
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
required: ["username", "password", "roleCode"],
|
|
7
7
|
handler: async (befly, ctx) => {
|
|
8
8
|
// 检查用户名是否已存在
|
|
9
|
-
const existingByUsername = await befly.db.getOne({
|
|
9
|
+
const existingByUsername = await befly.db.getOne<{ id: number }>({
|
|
10
10
|
table: "addon_admin_admin",
|
|
11
11
|
where: { username: ctx.body.username }
|
|
12
12
|
});
|
|
@@ -17,7 +17,7 @@ export default {
|
|
|
17
17
|
|
|
18
18
|
// 检查昵称是否已存在
|
|
19
19
|
if (ctx.body.nickname) {
|
|
20
|
-
const existingByNickname = await befly.db.getOne({
|
|
20
|
+
const existingByNickname = await befly.db.getOne<{ id: number }>({
|
|
21
21
|
table: "addon_admin_admin",
|
|
22
22
|
where: { nickname: ctx.body.nickname }
|
|
23
23
|
});
|
|
@@ -28,7 +28,7 @@ export default {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
// 查询角色信息
|
|
31
|
-
const roleData = await befly.db.getOne({
|
|
31
|
+
const roleData = await befly.db.getOne<{ id: number }>({
|
|
32
32
|
table: "addon_admin_role",
|
|
33
33
|
where: { code: ctx.body.roleCode }
|
|
34
34
|
});
|
package/apis/admin/upd.ts
CHANGED
|
@@ -8,7 +8,12 @@ export default {
|
|
|
8
8
|
const { id, username, nickname, roleCode, ...updateData } = ctx.body;
|
|
9
9
|
|
|
10
10
|
// 检查管理员是否存在
|
|
11
|
-
const admin = await befly.db.getOne
|
|
11
|
+
const admin = await befly.db.getOne<{
|
|
12
|
+
id: number;
|
|
13
|
+
username?: string;
|
|
14
|
+
nickname?: string;
|
|
15
|
+
roleCode?: string;
|
|
16
|
+
}>({
|
|
12
17
|
table: "addon_admin_admin",
|
|
13
18
|
where: { id }
|
|
14
19
|
});
|
|
@@ -19,7 +24,7 @@ export default {
|
|
|
19
24
|
|
|
20
25
|
// 检查用户名是否已被其他管理员使用
|
|
21
26
|
if (username && username !== admin.data.username) {
|
|
22
|
-
const existingUsername = await befly.db.getOne({
|
|
27
|
+
const existingUsername = await befly.db.getOne<{ id: number }>({
|
|
23
28
|
table: "addon_admin_admin",
|
|
24
29
|
where: { username, id: { $ne: id } }
|
|
25
30
|
});
|
|
@@ -30,7 +35,7 @@ export default {
|
|
|
30
35
|
|
|
31
36
|
// 检查昵称是否已被其他管理员使用
|
|
32
37
|
if (nickname && nickname !== admin.data.nickname) {
|
|
33
|
-
const existingNickname = await befly.db.getOne({
|
|
38
|
+
const existingNickname = await befly.db.getOne<{ id: number }>({
|
|
34
39
|
table: "addon_admin_admin",
|
|
35
40
|
where: { nickname, id: { $ne: id } }
|
|
36
41
|
});
|
|
@@ -41,7 +46,7 @@ export default {
|
|
|
41
46
|
|
|
42
47
|
// 检查角色是否存在
|
|
43
48
|
if (roleCode && roleCode !== admin.data.roleCode) {
|
|
44
|
-
const role = await befly.db.getOne({
|
|
49
|
+
const role = await befly.db.getOne<{ id: number }>({
|
|
45
50
|
table: "addon_admin_role",
|
|
46
51
|
where: { code: roleCode }
|
|
47
52
|
});
|
|
@@ -51,7 +56,7 @@ export default {
|
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
// 构建更新数据
|
|
54
|
-
const dataToUpdate: Record<string,
|
|
59
|
+
const dataToUpdate: Record<string, unknown> = { ...updateData };
|
|
55
60
|
if (username) dataToUpdate.username = username;
|
|
56
61
|
if (nickname) dataToUpdate.nickname = nickname;
|
|
57
62
|
if (roleCode) dataToUpdate.roleCode = roleCode;
|
package/apis/api/list.ts
CHANGED
|
@@ -11,7 +11,7 @@ export default {
|
|
|
11
11
|
const result = await befly.db.getList({
|
|
12
12
|
table: "addon_admin_api",
|
|
13
13
|
where: {
|
|
14
|
-
$or: ctx.body.keyword ? [{ name$like: `%${ctx.body.keyword}%` }, {
|
|
14
|
+
$or: ctx.body.keyword ? [{ name$like: `%${ctx.body.keyword}%` }, { path$like: `%${ctx.body.keyword}%` }] : undefined
|
|
15
15
|
},
|
|
16
16
|
orderBy: ["id#ASC"],
|
|
17
17
|
page: ctx.body.page,
|
package/apis/auth/login.ts
CHANGED
|
@@ -47,7 +47,7 @@ export default {
|
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
// 根据登录类型构建查询条件
|
|
50
|
-
const whereCondition: Record<string,
|
|
50
|
+
const whereCondition: Record<string, unknown> = {};
|
|
51
51
|
if (ctx.body.loginType === "username") {
|
|
52
52
|
whereCondition.username = ctx.body.account;
|
|
53
53
|
} else if (ctx.body.loginType === "email") {
|
|
@@ -57,7 +57,15 @@ export default {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
// 查询管理员
|
|
60
|
-
const admin = await befly.db.getOne
|
|
60
|
+
const admin = await befly.db.getOne<{
|
|
61
|
+
id: number;
|
|
62
|
+
username: string;
|
|
63
|
+
nickname?: string;
|
|
64
|
+
password: string;
|
|
65
|
+
state?: number;
|
|
66
|
+
roleCode?: string;
|
|
67
|
+
roleType?: string;
|
|
68
|
+
}>({
|
|
61
69
|
table: "addon_admin_admin",
|
|
62
70
|
where: whereCondition
|
|
63
71
|
});
|
|
@@ -81,7 +89,7 @@ export default {
|
|
|
81
89
|
await befly.db.insData({ table: "addon_admin_login_log", data: logData });
|
|
82
90
|
return befly.tool.No("账号或密码错误");
|
|
83
91
|
}
|
|
84
|
-
} catch (error:
|
|
92
|
+
} catch (error: unknown) {
|
|
85
93
|
befly.logger.error({ err: error, msg: "密码验证失败" });
|
|
86
94
|
logData.failReason = "密码格式错误";
|
|
87
95
|
await befly.db.insData({ table: "addon_admin_login_log", data: logData });
|
package/apis/dict/ins.ts
CHANGED
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
required: ["typeCode", "key", "label"],
|
|
7
7
|
handler: async (befly, ctx) => {
|
|
8
8
|
// 验证 typeCode 是否存在
|
|
9
|
-
const dictType = await befly.db.getOne({
|
|
9
|
+
const dictType = await befly.db.getOne<{ id: number }>({
|
|
10
10
|
table: "addon_admin_dict_type",
|
|
11
11
|
where: { code: ctx.body.typeCode }
|
|
12
12
|
});
|
|
@@ -16,7 +16,7 @@ export default {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
// 检查 typeCode+key 是否已存在
|
|
19
|
-
const existing = await befly.db.getOne({
|
|
19
|
+
const existing = await befly.db.getOne<{ id: number }>({
|
|
20
20
|
table: "addon_admin_dict",
|
|
21
21
|
where: {
|
|
22
22
|
typeCode: ctx.body.typeCode,
|
package/apis/dict/items.ts
CHANGED
|
@@ -6,7 +6,7 @@ export default {
|
|
|
6
6
|
required: ["typeCode"],
|
|
7
7
|
handler: async (befly, ctx) => {
|
|
8
8
|
// 验证 typeCode 是否存在
|
|
9
|
-
const dictType = await befly.db.getOne({
|
|
9
|
+
const dictType = await befly.db.getOne<{ id: number }>({
|
|
10
10
|
table: "addon_admin_dict_type",
|
|
11
11
|
where: { code: ctx.body.typeCode }
|
|
12
12
|
});
|
package/apis/dict/upd.ts
CHANGED
|
@@ -12,7 +12,7 @@ export default {
|
|
|
12
12
|
|
|
13
13
|
// 如果更新了 typeCode,验证其是否存在
|
|
14
14
|
if (typeCode) {
|
|
15
|
-
const dictType = await befly.db.getOne({
|
|
15
|
+
const dictType = await befly.db.getOne<{ id: number }>({
|
|
16
16
|
table: "addon_admin_dict_type",
|
|
17
17
|
where: { code: typeCode }
|
|
18
18
|
});
|
|
@@ -24,7 +24,7 @@ export default {
|
|
|
24
24
|
|
|
25
25
|
// 如果更新了 typeCode 或 key,检查唯一性
|
|
26
26
|
if (typeCode || key) {
|
|
27
|
-
const current = await befly.db.getOne({
|
|
27
|
+
const current = await befly.db.getOne<{ typeCode?: string; key?: string }>({
|
|
28
28
|
table: "addon_admin_dict",
|
|
29
29
|
where: { id: id }
|
|
30
30
|
});
|
|
@@ -32,7 +32,7 @@ export default {
|
|
|
32
32
|
const checkTypeCode = typeCode || current.data?.typeCode;
|
|
33
33
|
const checkKey = key || current.data?.key;
|
|
34
34
|
|
|
35
|
-
const existing = await befly.db.getOne({
|
|
35
|
+
const existing = await befly.db.getOne<{ id: number }>({
|
|
36
36
|
table: "addon_admin_dict",
|
|
37
37
|
where: {
|
|
38
38
|
typeCode: checkTypeCode,
|
|
@@ -46,7 +46,7 @@ export default {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
const updateData: Record<string,
|
|
49
|
+
const updateData: Record<string, unknown> = {};
|
|
50
50
|
if (typeCode !== undefined) updateData.typeCode = typeCode;
|
|
51
51
|
if (key !== undefined) updateData.key = key;
|
|
52
52
|
if (label !== undefined) updateData.label = label;
|
package/apis/dictType/del.ts
CHANGED
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
handler: async (befly, ctx) => {
|
|
6
6
|
const { id } = ctx.body;
|
|
7
7
|
|
|
8
|
-
const dictType = await befly.db.getOne({
|
|
8
|
+
const dictType = await befly.db.getOne<{ code?: string }>({
|
|
9
9
|
table: "addon_admin_dict_type",
|
|
10
10
|
where: { id: id }
|
|
11
11
|
});
|
|
@@ -15,7 +15,7 @@ export default {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
// 检查是否有字典项引用此类型
|
|
18
|
-
const dictItems = await befly.db.getOne({
|
|
18
|
+
const dictItems = await befly.db.getOne<{ id: number }>({
|
|
19
19
|
table: "addon_admin_dict",
|
|
20
20
|
where: {
|
|
21
21
|
typeCode: dictType.data.code
|
package/apis/email/config.ts
CHANGED
package/apis/menu/all.ts
CHANGED
|
@@ -12,7 +12,7 @@ export default {
|
|
|
12
12
|
handler: async (befly, ctx) => {
|
|
13
13
|
try {
|
|
14
14
|
// 2. 查询角色信息获取菜单权限(使用 roleCode 而非 roleId)
|
|
15
|
-
const role = await befly.db.getOne({
|
|
15
|
+
const role = await befly.db.getOne<{ id: number; menus?: unknown }>({
|
|
16
16
|
table: "addon_admin_role",
|
|
17
17
|
where: { code: ctx.user.roleCode }
|
|
18
18
|
});
|
|
@@ -23,7 +23,7 @@ export default {
|
|
|
23
23
|
|
|
24
24
|
// 3. 解析菜单路径列表(menu.path 数组,array_text)
|
|
25
25
|
const rawMenuPaths = Array.isArray(role.data.menus) ? role.data.menus : [];
|
|
26
|
-
const menuPaths = rawMenuPaths.map((p:
|
|
26
|
+
const menuPaths = rawMenuPaths.map((p: unknown) => (typeof p === "string" ? p.trim() : "")).filter((p: string) => p.length > 0);
|
|
27
27
|
|
|
28
28
|
if (menuPaths.length === 0) {
|
|
29
29
|
return befly.tool.Yes("菜单为空", { lists: [] });
|
|
@@ -46,11 +46,17 @@ export default {
|
|
|
46
46
|
|
|
47
47
|
// 5. 根据角色权限过滤菜单(按 menu.path)
|
|
48
48
|
const menuPathSet = new Set<string>(menuPaths);
|
|
49
|
-
const authorizedMenus = allMenus.filter((menu:
|
|
49
|
+
const authorizedMenus = allMenus.filter((menu: unknown) => {
|
|
50
|
+
if (typeof menu !== "object" || menu === null) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const path = (menu as { path?: unknown }).path;
|
|
54
|
+
return typeof path === "string" && menuPathSet.has(path);
|
|
55
|
+
});
|
|
50
56
|
|
|
51
57
|
// 6. 返回一维数组(由前端构建树形结构)
|
|
52
58
|
return befly.tool.Yes("获取菜单成功", { lists: authorizedMenus });
|
|
53
|
-
} catch (error:
|
|
59
|
+
} catch (error: unknown) {
|
|
54
60
|
befly.logger.error({ err: error, msg: "获取用户菜单失败" });
|
|
55
61
|
return befly.tool.No("获取菜单失败");
|
|
56
62
|
}
|
package/apis/role/apiSave.ts
CHANGED
|
@@ -11,12 +11,13 @@ export default {
|
|
|
11
11
|
let apiPaths: string[] = [];
|
|
12
12
|
try {
|
|
13
13
|
apiPaths = normalizePathnameListInput(ctx.body.apiPaths, "apiPaths", true);
|
|
14
|
-
} catch (error:
|
|
15
|
-
|
|
14
|
+
} catch (error: unknown) {
|
|
15
|
+
const msg = error instanceof Error ? error.message : "未知错误";
|
|
16
|
+
return befly.tool.No(`参数不合法:${msg}`);
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
// 查询角色是否存在
|
|
19
|
-
const role = await befly.db.getOne({
|
|
20
|
+
const role = await befly.db.getOne<{ id: number; code: string }>({
|
|
20
21
|
table: "addon_admin_role",
|
|
21
22
|
where: { code: ctx.body.roleCode }
|
|
22
23
|
});
|
package/apis/sysConfig/get.ts
CHANGED
|
@@ -5,7 +5,12 @@ export default {
|
|
|
5
5
|
code: { name: "配置代码", type: "string", min: 1, max: 50 }
|
|
6
6
|
},
|
|
7
7
|
handler: async (befly, ctx) => {
|
|
8
|
-
const config = await befly.db.getOne
|
|
8
|
+
const config = await befly.db.getOne<{
|
|
9
|
+
id: number;
|
|
10
|
+
code: string;
|
|
11
|
+
value: string;
|
|
12
|
+
valueType: string;
|
|
13
|
+
}>({
|
|
9
14
|
table: "addon_admin_sys_config",
|
|
10
15
|
where: { code: ctx.body.code }
|
|
11
16
|
});
|
package/apis/sysConfig/ins.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@befly-addon/admin",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"gitHead": "
|
|
3
|
+
"version": "1.6.1",
|
|
4
|
+
"gitHead": "f836a457a4b5936d566051b629ed80eb264d6bf8",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Befly - 管理后台功能组件",
|
|
7
7
|
"keywords": [
|
package/tables/api.json
CHANGED
|
@@ -14,13 +14,20 @@
|
|
|
14
14
|
"default": 1,
|
|
15
15
|
"detail": "0=免登录,1=需登录"
|
|
16
16
|
},
|
|
17
|
-
"
|
|
17
|
+
"path": {
|
|
18
18
|
"name": "接口路径",
|
|
19
19
|
"type": "string",
|
|
20
20
|
"min": 1,
|
|
21
21
|
"max": 200,
|
|
22
22
|
"index": true
|
|
23
23
|
},
|
|
24
|
+
"parentPath": {
|
|
25
|
+
"name": "父级路径",
|
|
26
|
+
"type": "string",
|
|
27
|
+
"min": 1,
|
|
28
|
+
"max": 200,
|
|
29
|
+
"index": true
|
|
30
|
+
},
|
|
24
31
|
"addonName": {
|
|
25
32
|
"name": "所属插件",
|
|
26
33
|
"type": "string",
|
package/utils/fieldClear.ts
CHANGED
|
@@ -38,7 +38,7 @@ export function fieldClear<T = any>(data: T | T[], options: FieldClearOptions =
|
|
|
38
38
|
const value = obj[key];
|
|
39
39
|
|
|
40
40
|
// 1. keepMap 优先
|
|
41
|
-
if (keepMap && Object.
|
|
41
|
+
if (keepMap && Object.hasOwn(keepMap, key)) {
|
|
42
42
|
if (Object.is(keepMap[key], value)) {
|
|
43
43
|
result[key] = value;
|
|
44
44
|
continue;
|