@befly-addon/admin 1.0.52 → 1.0.55
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/apis/admin/cacheRefresh.ts +17 -14
- package/apis/api/all.ts +1 -1
- package/apis/api/list.ts +30 -0
- package/apis/auth/login.ts +2 -2
- package/apis/dashboard/configStatus.ts +0 -12
- package/apis/dashboard/serviceStatus.ts +2 -2
- package/apis/dashboard/systemResources.ts +1 -1
- package/apis/dict/all.ts +1 -1
- package/apis/dict/del.ts +1 -1
- package/apis/dict/detail.ts +2 -2
- package/apis/dict/ins.ts +1 -1
- package/apis/dict/upd.ts +1 -1
- package/apis/menu/all.ts +2 -2
- package/apis/menu/list.ts +1 -1
- package/apis/role/del.ts +2 -2
- package/apis/role/save.ts +2 -2
- package/package.json +3 -4
- package/styles/variables.scss +1 -1
- package/views/admin/components/edit.vue +9 -19
- package/views/admin/index.vue +33 -52
- package/views/api/index.vue +181 -0
- package/views/dict/components/edit.vue +7 -5
- package/views/dict/index.vue +93 -39
- package/views/menu/index.vue +127 -115
- package/views/role/components/api.vue +10 -14
- package/views/role/components/edit.vue +7 -9
- package/views/role/components/menu.vue +11 -15
- package/views/role/index.vue +98 -46
- package/apis/menu/del.ts +0 -31
- package/apis/menu/ins.ts +0 -19
- package/apis/menu/upd.ts +0 -27
- package/views/menu/components/edit.vue +0 -145
package/views/role/index.vue
CHANGED
|
@@ -16,41 +16,57 @@
|
|
|
16
16
|
</TButton>
|
|
17
17
|
</div>
|
|
18
18
|
</div>
|
|
19
|
-
<div class="main-
|
|
20
|
-
<
|
|
21
|
-
<
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
19
|
+
<div class="main-content">
|
|
20
|
+
<div class="main-table">
|
|
21
|
+
<TTable v-bind="withTableProps()" :data="$Data.tableData" :columns="$Data.columns" :loading="$Data.loading" :active-row-keys="$Data.activeRowKeys" @active-change="$Method.onActiveChange">
|
|
22
|
+
<template #state="{ row }">
|
|
23
|
+
<TTag v-if="row.state === 1" theme="success">正常</TTag>
|
|
24
|
+
<TTag v-else-if="row.state === 2" theme="warning">禁用</TTag>
|
|
25
|
+
<TTag v-else theme="danger">已删除</TTag>
|
|
26
|
+
</template>
|
|
27
|
+
<template #operation="{ row }">
|
|
28
|
+
<TDropdown trigger="click" min-column-width="120" @click="(data) => $Method.onAction(data.value, row)">
|
|
29
|
+
<TButton variant="text" size="small">操作</TButton>
|
|
30
|
+
<TDropdownMenu slot="dropdown">
|
|
31
|
+
<TDropdownItem value="upd">
|
|
32
|
+
<ILucidePencil />
|
|
33
|
+
编辑
|
|
34
|
+
</TDropdownItem>
|
|
35
|
+
<TDropdownItem value="menu">
|
|
36
|
+
<ILucideSettings />
|
|
37
|
+
菜单权限
|
|
38
|
+
</TDropdownItem>
|
|
39
|
+
<TDropdownItem value="api">
|
|
40
|
+
<ILucideCode />
|
|
41
|
+
接口权限
|
|
42
|
+
</TDropdownItem>
|
|
43
|
+
<TDropdownItem value="del" :divider="true">
|
|
44
|
+
<ILucideTrash2 style="width: 14px; height: 14px; margin-right: 6px" />
|
|
45
|
+
删除
|
|
46
|
+
</TDropdownItem>
|
|
47
|
+
</TDropdownMenu>
|
|
48
|
+
</TDropdown>
|
|
49
|
+
</template>
|
|
50
|
+
</TTable>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<div class="main-detail">
|
|
54
|
+
<DetailPanel
|
|
55
|
+
:data="$Data.currentRow"
|
|
56
|
+
:fields="[
|
|
57
|
+
{ key: 'id', label: 'ID' },
|
|
58
|
+
{ key: 'name', label: '角色名称' },
|
|
59
|
+
{ key: 'code', label: '角色代码' },
|
|
60
|
+
{ key: 'description', label: '描述' },
|
|
61
|
+
{ key: 'sort', label: '排序' },
|
|
62
|
+
{ key: 'state', label: '状态' }
|
|
63
|
+
]"
|
|
64
|
+
/>
|
|
65
|
+
</div>
|
|
50
66
|
</div>
|
|
51
67
|
|
|
52
68
|
<div class="main-page">
|
|
53
|
-
<TPagination :current-page="$Data.pagerConfig.currentPage" :page-size="$Data.pagerConfig.
|
|
69
|
+
<TPagination :current-page="$Data.pagerConfig.currentPage" :page-size="$Data.pagerConfig.limit" :total="$Data.pagerConfig.total" @current-change="$Method.onPageChange" @page-size-change="$Method.handleSizeChange" />
|
|
54
70
|
</div>
|
|
55
71
|
|
|
56
72
|
<!-- 编辑对话框组件 -->
|
|
@@ -75,23 +91,28 @@ import ILucideTrash2 from '~icons/lucide/trash-2';
|
|
|
75
91
|
import EditDialog from './components/edit.vue';
|
|
76
92
|
import MenuDialog from './components/menu.vue';
|
|
77
93
|
import ApiDialog from './components/api.vue';
|
|
94
|
+
import DetailPanel from '@/components/DetailPanel.vue';
|
|
78
95
|
import { $Http } from '@/plugins/http';
|
|
96
|
+
import { withDefaultColumns, withTableProps } from '@/utils';
|
|
79
97
|
|
|
80
98
|
// 响应式数据
|
|
81
99
|
const $Data = $ref({
|
|
82
100
|
tableData: [],
|
|
83
|
-
|
|
101
|
+
loading: false,
|
|
102
|
+
activeRowKeys: [],
|
|
103
|
+
currentRow: null,
|
|
104
|
+
columns: withDefaultColumns([
|
|
84
105
|
{ colKey: 'index', title: '序号', width: 100, align: 'center' },
|
|
85
106
|
{ colKey: 'name', title: '角色名称', width: 150 },
|
|
86
107
|
{ colKey: 'code', title: '角色代码', width: 150 },
|
|
87
|
-
{ colKey: 'description', title: '描述', minWidth: 150
|
|
108
|
+
{ colKey: 'description', title: '描述', minWidth: 150 },
|
|
88
109
|
{ colKey: 'sort', title: '排序', width: 80, align: 'center' },
|
|
89
|
-
{ colKey: 'state', title: '状态', width: 100, align: 'center' },
|
|
90
|
-
{ colKey: 'operation', title: '操作', width: 120, align: 'center', fixed: 'right' }
|
|
91
|
-
],
|
|
110
|
+
{ colKey: 'state', title: '状态', width: 100, align: 'center', ellipsis: false },
|
|
111
|
+
{ colKey: 'operation', title: '操作', width: 120, align: 'center', fixed: 'right', ellipsis: false }
|
|
112
|
+
]),
|
|
92
113
|
pagerConfig: {
|
|
93
114
|
currentPage: 1,
|
|
94
|
-
|
|
115
|
+
limit: 30,
|
|
95
116
|
total: 0,
|
|
96
117
|
align: 'right',
|
|
97
118
|
layout: 'total, prev, pager, next, jumper'
|
|
@@ -110,6 +131,7 @@ const $Method = {
|
|
|
110
131
|
},
|
|
111
132
|
// 加载角色列表
|
|
112
133
|
async apiRoleList() {
|
|
134
|
+
$Data.loading = true;
|
|
113
135
|
try {
|
|
114
136
|
const res = await $Http('/addon/admin/role/list', {
|
|
115
137
|
page: $Data.pagerConfig.currentPage,
|
|
@@ -117,12 +139,20 @@ const $Method = {
|
|
|
117
139
|
});
|
|
118
140
|
$Data.tableData = res.data.lists || [];
|
|
119
141
|
$Data.pagerConfig.total = res.data.total || 0;
|
|
142
|
+
|
|
143
|
+
// 自动选中并高亮第一行
|
|
144
|
+
if ($Data.tableData.length > 0) {
|
|
145
|
+
$Data.currentRow = $Data.tableData[0];
|
|
146
|
+
$Data.activeRowKeys = [$Data.tableData[0].id];
|
|
147
|
+
} else {
|
|
148
|
+
$Data.currentRow = null;
|
|
149
|
+
$Data.activeRowKeys = [];
|
|
150
|
+
}
|
|
120
151
|
} catch (error) {
|
|
121
152
|
console.error('加载角色列表失败:', error);
|
|
122
|
-
MessagePlugin.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
});
|
|
153
|
+
MessagePlugin.error('加载数据失败');
|
|
154
|
+
} finally {
|
|
155
|
+
$Data.loading = false;
|
|
126
156
|
}
|
|
127
157
|
},
|
|
128
158
|
|
|
@@ -130,20 +160,20 @@ const $Method = {
|
|
|
130
160
|
async apiRoleDel(row) {
|
|
131
161
|
DialogPlugin.confirm({
|
|
132
162
|
header: '确认删除',
|
|
133
|
-
body:
|
|
163
|
+
body: `确定要删除角色“${row.name}” 吗?`,
|
|
134
164
|
status: 'warning'
|
|
135
165
|
}).then(async () => {
|
|
136
166
|
try {
|
|
137
167
|
const res = await $Http('/addon/admin/role/del', { id: row.id });
|
|
138
168
|
if (res.code === 0) {
|
|
139
|
-
MessagePlugin.
|
|
169
|
+
MessagePlugin.success('删除成功');
|
|
140
170
|
$Method.apiRoleList();
|
|
141
171
|
} else {
|
|
142
|
-
MessagePlugin.
|
|
172
|
+
MessagePlugin.error(res.msg || '删除失败');
|
|
143
173
|
}
|
|
144
174
|
} catch (error) {
|
|
145
175
|
console.error('删除失败:', error);
|
|
146
|
-
MessagePlugin.
|
|
176
|
+
MessagePlugin.error('删除失败');
|
|
147
177
|
}
|
|
148
178
|
});
|
|
149
179
|
},
|
|
@@ -159,6 +189,28 @@ const $Method = {
|
|
|
159
189
|
$Method.apiRoleList();
|
|
160
190
|
},
|
|
161
191
|
|
|
192
|
+
// 每页条数改变
|
|
193
|
+
handleSizeChange({ pageSize }) {
|
|
194
|
+
$Data.pagerConfig.limit = pageSize;
|
|
195
|
+
$Data.pagerConfig.currentPage = 1;
|
|
196
|
+
$Method.apiRoleList();
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
// 高亮行变化(点击行选中)
|
|
200
|
+
onActiveChange(value, { activeRowData }) {
|
|
201
|
+
$Data.activeRowKeys = value;
|
|
202
|
+
// 更新当前高亮的行数据
|
|
203
|
+
if (activeRowData && activeRowData.length > 0) {
|
|
204
|
+
$Data.currentRow = activeRowData[0];
|
|
205
|
+
} else if ($Data.tableData.length > 0) {
|
|
206
|
+
// 如果取消高亮,默认显示第一行
|
|
207
|
+
$Data.currentRow = $Data.tableData[0];
|
|
208
|
+
$Data.activeRowKeys = [$Data.tableData[0].id];
|
|
209
|
+
} else {
|
|
210
|
+
$Data.currentRow = null;
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
|
|
162
214
|
// 操作菜单点击
|
|
163
215
|
onAction(command, rowData) {
|
|
164
216
|
$Data.actionType = command;
|
package/apis/menu/del.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
export default {
|
|
2
|
-
name: '删除菜单',
|
|
3
|
-
handler: async (befly, ctx) => {
|
|
4
|
-
try {
|
|
5
|
-
// 检查是否有子菜单(使用 getList 代替 getAll)
|
|
6
|
-
const childrenList = await befly.db.getList({
|
|
7
|
-
table: 'addon_admin_menu',
|
|
8
|
-
where: { pid: ctx.body.id }
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
if (childrenList.total > 0) {
|
|
12
|
-
return befly.tool.No('该菜单下有子菜单,无法删除');
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// 删除菜单
|
|
16
|
-
await befly.db.delData({
|
|
17
|
-
table: 'addon_admin_menu',
|
|
18
|
-
where: { id: ctx.body.id }
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
// 注意:菜单权限现在存储在 role.menus 字段中
|
|
22
|
-
// 如果需要从角色权限中移除此菜单,需要额外处理
|
|
23
|
-
// 这里暂时不处理,由管理员在角色管理界面手动调整
|
|
24
|
-
|
|
25
|
-
return befly.tool.Yes('操作成功');
|
|
26
|
-
} catch (error) {
|
|
27
|
-
befly.logger.error('删除菜单失败:', error);
|
|
28
|
-
return befly.tool.No('操作失败');
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
};
|
package/apis/menu/ins.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import adminMenuTable from '../../tables/menu.json';
|
|
2
|
-
|
|
3
|
-
export default {
|
|
4
|
-
name: '创建菜单',
|
|
5
|
-
fields: adminMenuTable,
|
|
6
|
-
handler: async (befly, ctx) => {
|
|
7
|
-
try {
|
|
8
|
-
const menuId = await befly.db.insData({
|
|
9
|
-
table: 'addon_admin_menu',
|
|
10
|
-
data: ctx.body
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
return befly.tool.Yes('操作成功', { id: menuId });
|
|
14
|
-
} catch (error) {
|
|
15
|
-
befly.logger.error('创建菜单失败:', error);
|
|
16
|
-
return befly.tool.No('操作失败');
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
};
|
package/apis/menu/upd.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import adminMenuTable from '../../tables/menu.json';
|
|
2
|
-
|
|
3
|
-
export default {
|
|
4
|
-
name: '更新菜单',
|
|
5
|
-
fields: adminMenuTable,
|
|
6
|
-
handler: async (befly, ctx) => {
|
|
7
|
-
try {
|
|
8
|
-
await befly.db.updData({
|
|
9
|
-
table: 'addon_admin_menu',
|
|
10
|
-
where: { id: ctx.body.id },
|
|
11
|
-
data: {
|
|
12
|
-
name: ctx.body.name,
|
|
13
|
-
path: ctx.body.path,
|
|
14
|
-
icon: ctx.body.icon,
|
|
15
|
-
sort: ctx.body.sort,
|
|
16
|
-
pid: ctx.body.pid
|
|
17
|
-
// state 字段不在此处更新,需要禁用/启用时单独处理
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
return befly.tool.Yes('操作成功');
|
|
22
|
-
} catch (error) {
|
|
23
|
-
befly.logger.error('更新菜单失败:', error);
|
|
24
|
-
return befly.tool.No('操作失败');
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
};
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<TDialog v-model:visible="$Data.visible" :title="$Prop.actionType === 'add' ? '添加菜单' : '编辑菜单'" width="600px" :append-to-body="true" :show-footer="true" top="10vh">
|
|
3
|
-
<TForm :model="$Data.formData" label-width="120px" label-position="left" :rules="$Data2.formRules" :ref="(el) => ($From.form = el)">
|
|
4
|
-
<TFormItem label="菜单名称" prop="name">
|
|
5
|
-
<TInput v-model="$Data.formData.name" placeholder="请输入菜单名称" />
|
|
6
|
-
</TFormItem>
|
|
7
|
-
<TFormItem label="菜单路径" prop="path">
|
|
8
|
-
<TInput v-model="$Data.formData.path" placeholder="请输入菜单路径,如:/user" />
|
|
9
|
-
</TFormItem>
|
|
10
|
-
<TFormItem label="图标" prop="icon">
|
|
11
|
-
<TInput v-model="$Data.formData.icon" placeholder="请输入图标名称,如:User" />
|
|
12
|
-
</TFormItem>
|
|
13
|
-
<TFormItem label="排序" prop="sort">
|
|
14
|
-
<TInputNumber v-model="$Data.formData.sort" :min="0" :max="9999" />
|
|
15
|
-
</TFormItem>
|
|
16
|
-
<TFormItem label="状态" prop="state">
|
|
17
|
-
<TRadioGroup v-model="$Data.formData.state">
|
|
18
|
-
<TRadio :label="1">正常</TRadio>
|
|
19
|
-
<TRadio :label="2">禁用</TRadio>
|
|
20
|
-
</TRadioGroup>
|
|
21
|
-
</TFormItem>
|
|
22
|
-
</TForm>
|
|
23
|
-
<template #footer>
|
|
24
|
-
<TButton @click="$Method.onClose">取消</TButton>
|
|
25
|
-
<TButton theme="primary" @click="$Method.onSubmit">确定</TButton>
|
|
26
|
-
</template>
|
|
27
|
-
</TDialog>
|
|
28
|
-
</template>
|
|
29
|
-
|
|
30
|
-
<script setup>
|
|
31
|
-
import { watch } from 'vue';
|
|
32
|
-
import { Dialog as TDialog, Form as TForm, FormItem as TFormItem, Input as TInput, InputNumber as TInputNumber, RadioGroup as TRadioGroup, Radio as TRadio, Button as TButton, MessagePlugin } from 'tdesign-vue-next';
|
|
33
|
-
import { $Http } from '@/plugins/http';
|
|
34
|
-
|
|
35
|
-
const $Prop = defineProps({
|
|
36
|
-
modelValue: {
|
|
37
|
-
type: Boolean,
|
|
38
|
-
default: false
|
|
39
|
-
},
|
|
40
|
-
actionType: {
|
|
41
|
-
type: String,
|
|
42
|
-
default: 'add'
|
|
43
|
-
},
|
|
44
|
-
rowData: {
|
|
45
|
-
type: Object,
|
|
46
|
-
default: {}
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
const $Emit = defineEmits(['update:modelValue', 'success']);
|
|
51
|
-
|
|
52
|
-
// 表单引用
|
|
53
|
-
const $From = $shallowRef({
|
|
54
|
-
form: null
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
const $Data = $ref({
|
|
58
|
-
visible: false,
|
|
59
|
-
formData: {
|
|
60
|
-
id: 0,
|
|
61
|
-
name: '',
|
|
62
|
-
path: '',
|
|
63
|
-
icon: '',
|
|
64
|
-
sort: 0,
|
|
65
|
-
pid: 0,
|
|
66
|
-
state: 1
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
const $Data2 = $shallowRef({
|
|
71
|
-
formRules: {
|
|
72
|
-
name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
|
|
73
|
-
path: [{ required: true, message: '请输入菜单路径', trigger: 'blur' }]
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
// 方法集合
|
|
78
|
-
const $Method = {
|
|
79
|
-
async initData() {
|
|
80
|
-
$Method.onShow();
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
onShow() {
|
|
84
|
-
$Data.visible = true;
|
|
85
|
-
if ($Prop.actionType === 'upd' && $Prop.rowData) {
|
|
86
|
-
$Data.formData.id = $Prop.rowData.id || 0;
|
|
87
|
-
$Data.formData.name = $Prop.rowData.name || '';
|
|
88
|
-
$Data.formData.path = $Prop.rowData.path ?? '';
|
|
89
|
-
$Data.formData.icon = $Prop.rowData.icon ?? '';
|
|
90
|
-
$Data.formData.sort = $Prop.rowData.sort ?? 0;
|
|
91
|
-
$Data.formData.state = $Prop.rowData.state ?? 1;
|
|
92
|
-
} else {
|
|
93
|
-
// 重置表单
|
|
94
|
-
$Data.formData.id = 0;
|
|
95
|
-
$Data.formData.name = '';
|
|
96
|
-
$Data.formData.path = '';
|
|
97
|
-
$Data.formData.icon = '';
|
|
98
|
-
$Data.formData.sort = 0;
|
|
99
|
-
$Data.formData.state = 1;
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
onClose() {
|
|
104
|
-
$Data.visible = false;
|
|
105
|
-
setTimeout(() => {
|
|
106
|
-
$Emit('update:modelValue', false);
|
|
107
|
-
}, 300);
|
|
108
|
-
},
|
|
109
|
-
|
|
110
|
-
async onSubmit() {
|
|
111
|
-
try {
|
|
112
|
-
const valid = await $From.form.validate();
|
|
113
|
-
if (!valid) return;
|
|
114
|
-
|
|
115
|
-
const res = await $Http($Prop.actionType === 'add' ? '/addon/admin/menuIns' : '/addon/admin/menuUpd', $Data.formData);
|
|
116
|
-
|
|
117
|
-
MessagePlugin.info({
|
|
118
|
-
message: $Prop.actionType === 'add' ? '添加成功' : '编辑成功',
|
|
119
|
-
status: 'success'
|
|
120
|
-
});
|
|
121
|
-
$Method.onClose();
|
|
122
|
-
$Emit('success');
|
|
123
|
-
} catch (error) {
|
|
124
|
-
console.error('提交失败:', error);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
// 监听 modelValue 变化
|
|
130
|
-
watch(
|
|
131
|
-
() => $Prop.modelValue,
|
|
132
|
-
(val) => {
|
|
133
|
-
if (val && !$Data.visible) {
|
|
134
|
-
$Method.initData();
|
|
135
|
-
} else if (!val && $Data.visible) {
|
|
136
|
-
$Data.visible = false;
|
|
137
|
-
}
|
|
138
|
-
},
|
|
139
|
-
{ immediate: true }
|
|
140
|
-
);
|
|
141
|
-
</script>
|
|
142
|
-
|
|
143
|
-
<style scoped lang="scss">
|
|
144
|
-
// 可根据需要添加样式
|
|
145
|
-
</style>
|