@befly-addon/admin 1.2.8 → 1.2.12
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/index.vue +0 -1
- package/adminViews/config/dictType/index.vue +0 -1
- package/adminViews/config/system/index.vue +0 -1
- package/adminViews/log/email/index.vue +0 -1
- package/adminViews/log/login/index.vue +0 -1
- package/adminViews/log/operate/index.vue +0 -1
- package/adminViews/people/admin/index.vue +0 -1
- package/adminViews/permission/api/index.vue +0 -1
- package/adminViews/permission/menu/index.vue +0 -1
- package/adminViews/permission/role/components/api.vue +1 -72
- package/adminViews/permission/role/components/menu.vue +198 -10
- package/adminViews/permission/role/index.vue +14 -3
- package/package.json +5 -5
|
@@ -101,7 +101,6 @@ const $Data = $ref({
|
|
|
101
101
|
searchTypeCode: "",
|
|
102
102
|
searchKeyword: "",
|
|
103
103
|
columns: withDefaultColumns([
|
|
104
|
-
{ colKey: "id", title: "ID" },
|
|
105
104
|
{ colKey: "typeName", title: "类型名称" },
|
|
106
105
|
{ colKey: "typeCode", title: "类型代码" },
|
|
107
106
|
{ colKey: "label", title: "标签" },
|
|
@@ -106,7 +106,6 @@ const $Data = $ref({
|
|
|
106
106
|
loading: false,
|
|
107
107
|
columns: withDefaultColumns([
|
|
108
108
|
{ colKey: "name", title: "配置名称", fixed: "left", width: 150 },
|
|
109
|
-
{ colKey: "id", title: "序号", width: 80 },
|
|
110
109
|
{ colKey: "code", title: "配置代码", ellipsis: true },
|
|
111
110
|
{ colKey: "value", title: "配置值", ellipsis: true, width: 200 },
|
|
112
111
|
{ colKey: "valueType", title: "值类型", width: 100 },
|
|
@@ -107,7 +107,6 @@ const $Data = $ref({
|
|
|
107
107
|
loading: false,
|
|
108
108
|
columns: withDefaultColumns([
|
|
109
109
|
{ colKey: "username", title: "发送人", fixed: "left" },
|
|
110
|
-
{ colKey: "id", title: "序号" },
|
|
111
110
|
{ colKey: "toEmail", title: "收件人" },
|
|
112
111
|
{ colKey: "subject", title: "主题" },
|
|
113
112
|
{ colKey: "sendTime", title: "发送时间" },
|
|
@@ -69,7 +69,6 @@ const $Data = $ref({
|
|
|
69
69
|
loading: false,
|
|
70
70
|
columns: withDefaultColumns([
|
|
71
71
|
{ colKey: "username", title: "用户名", fixed: "left" },
|
|
72
|
-
{ colKey: "id", title: "序号" },
|
|
73
72
|
{ colKey: "ip", title: "登录IP" },
|
|
74
73
|
{ colKey: "browserName", title: "浏览器" },
|
|
75
74
|
{ colKey: "osName", title: "操作系统" },
|
|
@@ -89,7 +89,6 @@ const $Data = $ref({
|
|
|
89
89
|
loading: false,
|
|
90
90
|
columns: withDefaultColumns([
|
|
91
91
|
{ colKey: "username", title: "操作人", fixed: "left", width: 100 },
|
|
92
|
-
{ colKey: "id", title: "序号", width: 80 },
|
|
93
92
|
{ colKey: "module", title: "模块", width: 100 },
|
|
94
93
|
{ colKey: "action", title: "操作", width: 80 },
|
|
95
94
|
{ colKey: "path", title: "请求路径", ellipsis: true },
|
|
@@ -94,7 +94,6 @@ const $Data = $ref({
|
|
|
94
94
|
loading: false,
|
|
95
95
|
columns: withDefaultColumns([
|
|
96
96
|
{ colKey: "username", title: "用户名", fixed: "left" },
|
|
97
|
-
{ colKey: "id", title: "序号" },
|
|
98
97
|
{ colKey: "nickname", title: "昵称" },
|
|
99
98
|
{ colKey: "roleCode", title: "角色" },
|
|
100
99
|
{ colKey: "state", title: "状态" },
|
|
@@ -73,7 +73,6 @@ const $Data = $ref({
|
|
|
73
73
|
searchKeyword: "",
|
|
74
74
|
columns: withDefaultColumns([
|
|
75
75
|
{ colKey: "name", title: "接口名称" },
|
|
76
|
-
{ colKey: "id", title: "序号" },
|
|
77
76
|
{ colKey: "path", title: "接口路径" },
|
|
78
77
|
{ colKey: "method", title: "请求方法" },
|
|
79
78
|
{ colKey: "addonName", title: "所属组件" }
|
|
@@ -60,7 +60,6 @@ const $Data = $ref({
|
|
|
60
60
|
loading: false,
|
|
61
61
|
columns: withDefaultColumns([
|
|
62
62
|
{ colKey: "name", title: "菜单名称" },
|
|
63
|
-
{ colKey: "id", title: "序号" },
|
|
64
63
|
{ colKey: "path", title: "路由路径" },
|
|
65
64
|
{ colKey: "parentPath", title: "父级路径" },
|
|
66
65
|
{ colKey: "sort", title: "排序" },
|
|
@@ -19,13 +19,8 @@
|
|
|
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">
|
|
22
|
-
<div class="api-name" :title="api.name">{{ api.name }}</div>
|
|
23
|
-
<div class="api-path" :title="api.path">{{ api.path }}</div>
|
|
22
|
+
<div class="api-name" :title="api.path ? `${api.name}\n${api.path}` : api.name">{{ api.name }}</div>
|
|
24
23
|
</div>
|
|
25
|
-
|
|
26
|
-
<span class="api-copy" title="复制路径" @click.stop="$Method.copyApiPath(api.path)">
|
|
27
|
-
<ILucideCopy :size="14" />
|
|
28
|
-
</span>
|
|
29
24
|
</div>
|
|
30
25
|
</TCheckbox>
|
|
31
26
|
</TCheckboxGroup>
|
|
@@ -47,7 +42,6 @@
|
|
|
47
42
|
|
|
48
43
|
<script setup>
|
|
49
44
|
import { Dialog as TDialog, Input as TInput, CheckboxGroup as TCheckboxGroup, Checkbox as TCheckbox, Button as TButton, MessagePlugin } from "tdesign-vue-next";
|
|
50
|
-
import ILucideCopy from "~icons/lucide/copy";
|
|
51
45
|
import ILucideSearch from "~icons/lucide/search";
|
|
52
46
|
import { $Http } from "@/plugins/http";
|
|
53
47
|
|
|
@@ -164,47 +158,6 @@ const $Method = {
|
|
|
164
158
|
.filter((group) => group.apis.length > 0);
|
|
165
159
|
},
|
|
166
160
|
|
|
167
|
-
async copyApiPath(path) {
|
|
168
|
-
if (typeof path !== "string" || path.trim().length === 0) {
|
|
169
|
-
MessagePlugin.warning("路径为空");
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const value = path.trim();
|
|
174
|
-
|
|
175
|
-
try {
|
|
176
|
-
if (navigator && navigator.clipboard && navigator.clipboard.writeText) {
|
|
177
|
-
await navigator.clipboard.writeText(value);
|
|
178
|
-
MessagePlugin.success("已复制");
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
} catch (error) {
|
|
182
|
-
// ignore and fallback
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
const textarea = document.createElement("textarea");
|
|
187
|
-
textarea.value = value;
|
|
188
|
-
textarea.setAttribute("readonly", "readonly");
|
|
189
|
-
textarea.style.position = "fixed";
|
|
190
|
-
textarea.style.left = "-9999px";
|
|
191
|
-
textarea.style.top = "-9999px";
|
|
192
|
-
document.body.appendChild(textarea);
|
|
193
|
-
textarea.select();
|
|
194
|
-
const ok = document.execCommand("copy");
|
|
195
|
-
document.body.removeChild(textarea);
|
|
196
|
-
|
|
197
|
-
if (ok) {
|
|
198
|
-
MessagePlugin.success("已复制");
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
MessagePlugin.error("复制失败");
|
|
203
|
-
} catch (error) {
|
|
204
|
-
MessagePlugin.error("复制失败");
|
|
205
|
-
}
|
|
206
|
-
},
|
|
207
|
-
|
|
208
161
|
// 提交表单
|
|
209
162
|
async onSubmit() {
|
|
210
163
|
try {
|
|
@@ -329,30 +282,6 @@ $Method.initData();
|
|
|
329
282
|
white-space: nowrap;
|
|
330
283
|
}
|
|
331
284
|
|
|
332
|
-
.api-path {
|
|
333
|
-
max-width: 100%;
|
|
334
|
-
overflow: hidden;
|
|
335
|
-
text-overflow: ellipsis;
|
|
336
|
-
white-space: nowrap;
|
|
337
|
-
opacity: 0.7;
|
|
338
|
-
font-size: 12px;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
.api-copy {
|
|
342
|
-
flex: 0 0 auto;
|
|
343
|
-
display: inline-flex;
|
|
344
|
-
align-items: center;
|
|
345
|
-
justify-content: center;
|
|
346
|
-
width: 24px;
|
|
347
|
-
height: 24px;
|
|
348
|
-
border-radius: 6px;
|
|
349
|
-
cursor: pointer;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
.api-copy:hover {
|
|
353
|
-
background: rgba(0, 0, 0, 0.06);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
285
|
.dialog-footer {
|
|
357
286
|
width: 100%;
|
|
358
287
|
display: flex;
|
|
@@ -1,17 +1,48 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<TDialog v-model:visible="$Data.visible" title="菜单权限" width="
|
|
2
|
+
<TDialog v-model:visible="$Data.visible" title="菜单权限" width="900px" :append-to-body="true" :show-footer="true" top="5vh" @close="$Method.onClose">
|
|
3
3
|
<div class="comp-role-menu">
|
|
4
|
-
|
|
4
|
+
<!-- 搜索框 -->
|
|
5
|
+
<div class="search-box">
|
|
6
|
+
<TInput v-model="$Data.searchText" placeholder="搜索菜单名称或路径" clearable @change="$Method.onSearch">
|
|
7
|
+
<template #prefix-icon>
|
|
8
|
+
<ILucideSearch />
|
|
9
|
+
</template>
|
|
10
|
+
</TInput>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<div class="menu-container">
|
|
14
|
+
<div class="menu-group" v-for="group in $Data.filteredMenuGroups" :key="group.name">
|
|
15
|
+
<div class="group-header">{{ group.title }}</div>
|
|
16
|
+
<div class="menu-checkbox-list">
|
|
17
|
+
<TCheckboxGroup v-model="$Data.checkedMenuPaths">
|
|
18
|
+
<TCheckbox v-for="menu in group.menus" :key="menu.value" :value="menu.value">
|
|
19
|
+
<div class="menu-checkbox-label">
|
|
20
|
+
<div class="menu-label-main">
|
|
21
|
+
<div class="menu-name" :title="menu.path ? `${menu.name}\n${menu.path}` : menu.name">
|
|
22
|
+
{{ menu.name }}
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</TCheckbox>
|
|
27
|
+
</TCheckboxGroup>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
5
31
|
</div>
|
|
6
32
|
<template #footer>
|
|
7
|
-
<
|
|
8
|
-
|
|
33
|
+
<div class="dialog-footer">
|
|
34
|
+
<t-space>
|
|
35
|
+
<TButton theme="default" @click="$Method.onClose">取消</TButton>
|
|
36
|
+
<TButton theme="primary" :loading="$Data.submitting" @click="$Method.onSubmit">保存</TButton>
|
|
37
|
+
</t-space>
|
|
38
|
+
</div>
|
|
9
39
|
</template>
|
|
10
40
|
</TDialog>
|
|
11
41
|
</template>
|
|
12
42
|
|
|
13
43
|
<script setup>
|
|
14
|
-
import { Dialog as TDialog,
|
|
44
|
+
import { Dialog as TDialog, CheckboxGroup as TCheckboxGroup, Checkbox as TCheckbox, Button as TButton, Input as TInput, MessagePlugin } from "tdesign-vue-next";
|
|
45
|
+
import ILucideSearch from "~icons/lucide/search";
|
|
15
46
|
import { $Http } from "@/plugins/http";
|
|
16
47
|
import { arrayToTree } from "befly-shared/utils/arrayToTree";
|
|
17
48
|
|
|
@@ -31,14 +62,17 @@ const $Emit = defineEmits(["update:modelValue", "success"]);
|
|
|
31
62
|
const $Data = $ref({
|
|
32
63
|
visible: false,
|
|
33
64
|
submitting: false,
|
|
34
|
-
|
|
35
|
-
|
|
65
|
+
searchText: "",
|
|
66
|
+
menuGroups: [],
|
|
67
|
+
filteredMenuGroups: [],
|
|
68
|
+
checkedMenuPaths: []
|
|
36
69
|
});
|
|
37
70
|
|
|
38
71
|
// 方法集合
|
|
39
72
|
const $Method = {
|
|
40
73
|
async initData() {
|
|
41
74
|
await Promise.all([$Method.apiMenuAll(), $Method.apiRoleMenuDetail()]);
|
|
75
|
+
$Data.filteredMenuGroups = $Data.menuGroups;
|
|
42
76
|
$Method.onShow();
|
|
43
77
|
},
|
|
44
78
|
|
|
@@ -62,7 +96,45 @@ const $Method = {
|
|
|
62
96
|
const lists = Array.isArray(res?.data?.lists) ? res.data.lists : [];
|
|
63
97
|
|
|
64
98
|
const treeResult = arrayToTree(lists, "path", "parentPath", "children", "sort");
|
|
65
|
-
|
|
99
|
+
const roots = Array.isArray(treeResult?.tree) ? treeResult.tree : [];
|
|
100
|
+
|
|
101
|
+
const groups = [];
|
|
102
|
+
for (const root of roots) {
|
|
103
|
+
const rootPath = typeof root?.path === "string" ? root.path : "";
|
|
104
|
+
const rootName = typeof root?.name === "string" ? root.name : "";
|
|
105
|
+
|
|
106
|
+
const menus = [];
|
|
107
|
+
|
|
108
|
+
const walk = (node, depth) => {
|
|
109
|
+
const name = typeof node?.name === "string" ? node.name : "";
|
|
110
|
+
const path = typeof node?.path === "string" ? node.path : "";
|
|
111
|
+
if (path.length > 0) {
|
|
112
|
+
menus.push({
|
|
113
|
+
value: path,
|
|
114
|
+
name: name,
|
|
115
|
+
path: path,
|
|
116
|
+
depth: depth,
|
|
117
|
+
label: `${name} ${path}`.trim()
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const children = Array.isArray(node?.children) ? node.children : [];
|
|
122
|
+
for (const child of children) {
|
|
123
|
+
walk(child, depth + 1);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
walk(root, 0);
|
|
128
|
+
|
|
129
|
+
const groupTitle = rootName.length > 0 ? rootName : rootPath;
|
|
130
|
+
groups.push({
|
|
131
|
+
name: rootPath.length > 0 ? rootPath : groupTitle,
|
|
132
|
+
title: groupTitle.length > 0 ? groupTitle : "未命名菜单",
|
|
133
|
+
menus: menus
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
$Data.menuGroups = groups;
|
|
66
138
|
} catch (error) {
|
|
67
139
|
MessagePlugin.error("加载菜单失败");
|
|
68
140
|
}
|
|
@@ -78,12 +150,38 @@ const $Method = {
|
|
|
78
150
|
});
|
|
79
151
|
|
|
80
152
|
// menus 返回的 data 直接就是菜单 path 数组
|
|
81
|
-
$Data.
|
|
153
|
+
$Data.checkedMenuPaths = Array.isArray(res.data) ? res.data : [];
|
|
82
154
|
} catch (error) {
|
|
83
155
|
MessagePlugin.error("加载数据失败");
|
|
84
156
|
}
|
|
85
157
|
},
|
|
86
158
|
|
|
159
|
+
// 搜索过滤(按“名称 + 路径”匹配;展示结构与接口弹框一致)
|
|
160
|
+
onSearch() {
|
|
161
|
+
const kw = typeof $Data.searchText === "string" ? $Data.searchText.trim().toLowerCase() : "";
|
|
162
|
+
if (kw.length === 0) {
|
|
163
|
+
$Data.filteredMenuGroups = $Data.menuGroups;
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
$Data.filteredMenuGroups = $Data.menuGroups
|
|
168
|
+
.map((group) => {
|
|
169
|
+
const menus = Array.isArray(group?.menus)
|
|
170
|
+
? group.menus.filter((menu) => {
|
|
171
|
+
const label = typeof menu?.label === "string" ? menu.label : "";
|
|
172
|
+
return label.toLowerCase().includes(kw);
|
|
173
|
+
})
|
|
174
|
+
: [];
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
name: group.name,
|
|
178
|
+
title: group.title,
|
|
179
|
+
menus: menus
|
|
180
|
+
};
|
|
181
|
+
})
|
|
182
|
+
.filter((group) => Array.isArray(group.menus) && group.menus.length > 0);
|
|
183
|
+
},
|
|
184
|
+
|
|
87
185
|
// 提交表单
|
|
88
186
|
async onSubmit() {
|
|
89
187
|
try {
|
|
@@ -91,7 +189,7 @@ const $Method = {
|
|
|
91
189
|
|
|
92
190
|
const res = await $Http("/addon/admin/role/menuSave", {
|
|
93
191
|
roleCode: $Prop.rowData.code,
|
|
94
|
-
menuPaths: $Data.
|
|
192
|
+
menuPaths: $Data.checkedMenuPaths
|
|
95
193
|
});
|
|
96
194
|
|
|
97
195
|
if (res.code === 0) {
|
|
@@ -114,5 +212,95 @@ $Method.initData();
|
|
|
114
212
|
|
|
115
213
|
<style scoped lang="scss">
|
|
116
214
|
.comp-role-menu {
|
|
215
|
+
height: 60vh;
|
|
216
|
+
display: flex;
|
|
217
|
+
flex-direction: column;
|
|
218
|
+
gap: 12px;
|
|
219
|
+
|
|
220
|
+
.menu-container {
|
|
221
|
+
flex: 1;
|
|
222
|
+
overflow-y: auto;
|
|
223
|
+
|
|
224
|
+
.menu-group {
|
|
225
|
+
margin-bottom: 16px;
|
|
226
|
+
border: 1px solid var(--border-color);
|
|
227
|
+
border-radius: var(--border-radius-small);
|
|
228
|
+
overflow: hidden;
|
|
229
|
+
|
|
230
|
+
&:last-child {
|
|
231
|
+
margin-bottom: 0;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.group-header {
|
|
235
|
+
padding: 12px 16px;
|
|
236
|
+
background-color: var(--bg-color-hover);
|
|
237
|
+
font-weight: 500;
|
|
238
|
+
font-size: var(--font-size-sm);
|
|
239
|
+
color: var(--text-primary);
|
|
240
|
+
display: flex;
|
|
241
|
+
align-items: center;
|
|
242
|
+
gap: 8px;
|
|
243
|
+
|
|
244
|
+
&::before {
|
|
245
|
+
content: "";
|
|
246
|
+
width: 8px;
|
|
247
|
+
height: 8px;
|
|
248
|
+
border-radius: 50%;
|
|
249
|
+
background-color: var(--primary-color);
|
|
250
|
+
opacity: 0.3;
|
|
251
|
+
flex-shrink: 0;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.menu-checkbox-list {
|
|
256
|
+
padding: 10px;
|
|
257
|
+
|
|
258
|
+
:deep(.t-checkbox-group) {
|
|
259
|
+
display: flex;
|
|
260
|
+
flex-wrap: wrap;
|
|
261
|
+
gap: 12px;
|
|
262
|
+
width: 100%;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
:deep(.t-checkbox) {
|
|
266
|
+
flex: 0 0 calc(33.333% - 8px);
|
|
267
|
+
margin: 0;
|
|
268
|
+
min-width: 0;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
:deep(.t-checkbox__label) {
|
|
272
|
+
min-width: 0;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.menu-checkbox-label {
|
|
280
|
+
width: 100%;
|
|
281
|
+
display: flex;
|
|
282
|
+
align-items: center;
|
|
283
|
+
justify-content: space-between;
|
|
284
|
+
gap: 8px;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.menu-label-main {
|
|
288
|
+
min-width: 0;
|
|
289
|
+
display: flex;
|
|
290
|
+
flex-direction: column;
|
|
291
|
+
gap: 2px;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.menu-name {
|
|
295
|
+
max-width: 100%;
|
|
296
|
+
overflow: hidden;
|
|
297
|
+
text-overflow: ellipsis;
|
|
298
|
+
white-space: nowrap;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.dialog-footer {
|
|
302
|
+
width: 100%;
|
|
303
|
+
display: flex;
|
|
304
|
+
justify-content: center;
|
|
117
305
|
}
|
|
118
306
|
</style>
|
|
@@ -33,6 +33,12 @@
|
|
|
33
33
|
<TTag v-else-if="row.state === 2" shape="round" theme="warning" variant="light-outline">禁用</TTag>
|
|
34
34
|
<TTag v-else shape="round" theme="danger" variant="light-outline">已删除</TTag>
|
|
35
35
|
</template>
|
|
36
|
+
<template #menuCount="{ row }">
|
|
37
|
+
{{ $Method.getPathCount(row.menus) }}
|
|
38
|
+
</template>
|
|
39
|
+
<template #apiCount="{ row }">
|
|
40
|
+
{{ $Method.getPathCount(row.apis) }}
|
|
41
|
+
</template>
|
|
36
42
|
<template #operation="{ row }">
|
|
37
43
|
<TDropdown trigger="click" placement="bottom-right" @click="(data) => $Method.onAction(data.value, row)">
|
|
38
44
|
<TButton theme="primary" size="small">
|
|
@@ -112,12 +118,13 @@ const $Data = $ref({
|
|
|
112
118
|
activeRowKeys: [],
|
|
113
119
|
currentRow: null,
|
|
114
120
|
columns: withDefaultColumns([
|
|
115
|
-
{ colKey: "id", title: "ID" },
|
|
116
121
|
{ colKey: "name", title: "角色名称" },
|
|
117
|
-
{ colKey: "code", title: "角色代码" },
|
|
118
|
-
{ colKey: "
|
|
122
|
+
{ colKey: "code", title: "角色代码",width:150 },
|
|
123
|
+
{ colKey: "menuCount", title: "菜单数量", align: "center",width:100 },
|
|
124
|
+
{ colKey: "apiCount", title: "接口数量", align: "center",width:100 },
|
|
119
125
|
{ colKey: "sort", title: "排序" },
|
|
120
126
|
{ colKey: "state", title: "状态" },
|
|
127
|
+
{ colKey: "description", title: "描述" },
|
|
121
128
|
{ colKey: "operation", title: "操作" }
|
|
122
129
|
]),
|
|
123
130
|
pagerConfig: {
|
|
@@ -136,6 +143,10 @@ const $Data = $ref({
|
|
|
136
143
|
|
|
137
144
|
// 方法
|
|
138
145
|
const $Method = {
|
|
146
|
+
getPathCount(value) {
|
|
147
|
+
if (!Array.isArray(value)) return 0;
|
|
148
|
+
return value.filter((p) => typeof p === "string" && p.trim().length > 0).length;
|
|
149
|
+
},
|
|
139
150
|
async initData() {
|
|
140
151
|
await $Method.apiRoleList();
|
|
141
152
|
},
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@befly-addon/admin",
|
|
3
|
-
"version": "1.2.
|
|
4
|
-
"gitHead": "
|
|
3
|
+
"version": "1.2.12",
|
|
4
|
+
"gitHead": "9c9fd0cd8165bb5b4025e538a3c5fb228acb39cd",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Befly - 管理后台功能组件",
|
|
7
7
|
"keywords": [
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"preview": "vite preview"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"befly": "^3.10.
|
|
51
|
-
"befly-shared": "^1.3.
|
|
52
|
-
"befly-vite": "^1.2.
|
|
50
|
+
"befly": "^3.10.12",
|
|
51
|
+
"befly-shared": "^1.3.8",
|
|
52
|
+
"befly-vite": "^1.2.9",
|
|
53
53
|
"nodemailer": "^7.0.12",
|
|
54
54
|
"ua-parser-js": "^2.0.7"
|
|
55
55
|
},
|