Skip to content

Commit 550a00e

Browse files
authored
feat: add the admin dept view (#20)
1 parent 3287aa7 commit 550a00e

File tree

11 files changed

+556
-18
lines changed

11 files changed

+556
-18
lines changed

apps/web-antd/src/adapter/vxe-table.ts

+142-3
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ import type { Recordable } from '@vben/types';
22

33
import { h } from 'vue';
44

5+
import { IconifyIcon } from '@vben/icons';
6+
import { $te } from '@vben/locales';
57
import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';
6-
import { get } from '@vben/utils';
8+
import { get, isFunction, isString } from '@vben/utils';
79

810
import { objectOmit } from '@vueuse/core';
9-
import { Button, Image, Switch, Tag } from 'ant-design-vue';
11+
import { Button, Image, Popconfirm, Switch, Tag } from 'ant-design-vue';
1012

1113
import { $t } from '#/locales';
1214

@@ -31,7 +33,7 @@ setupVbenVxeTable({
3133
response: {
3234
result: 'items',
3335
total: 'total',
34-
list: 'items',
36+
list: '',
3537
},
3638
showActiveMsg: true,
3739
showResponseMsg: false,
@@ -119,6 +121,143 @@ setupVbenVxeTable({
119121
},
120122
});
121123

124+
/**
125+
* 注册表格的操作按钮渲染器
126+
*/
127+
vxeUI.renderer.add('CellOperation', {
128+
renderTableDefault({ attrs, options, props }, { column, row }) {
129+
const defaultProps = { size: 'small', type: 'link', ...props };
130+
let align = 'end';
131+
switch (column.align) {
132+
case 'center': {
133+
align = 'center';
134+
break;
135+
}
136+
case 'left': {
137+
align = 'start';
138+
break;
139+
}
140+
default: {
141+
align = 'end';
142+
break;
143+
}
144+
}
145+
const presets: Recordable<Recordable<any>> = {
146+
delete: {
147+
danger: true,
148+
text: $t('common.delete'),
149+
},
150+
edit: {
151+
text: $t('common.edit'),
152+
},
153+
};
154+
const operations: Array<Recordable<any>> = (
155+
options || ['edit', 'delete']
156+
)
157+
.map((opt) => {
158+
if (isString(opt)) {
159+
return presets[opt]
160+
? { code: opt, ...presets[opt], ...defaultProps }
161+
: {
162+
code: opt,
163+
text: $te(`common.${opt}`) ? $t(`common.${opt}`) : opt,
164+
...defaultProps,
165+
};
166+
} else {
167+
return { ...defaultProps, ...presets[opt.code], ...opt };
168+
}
169+
})
170+
.map((opt) => {
171+
const optBtn: Recordable<any> = {};
172+
Object.keys(opt).forEach((key) => {
173+
optBtn[key] = isFunction(opt[key]) ? opt[key](row) : opt[key];
174+
});
175+
return optBtn;
176+
})
177+
.filter((opt) => opt.show !== false);
178+
179+
function renderBtn(opt: Recordable<any>, listen = true) {
180+
return h(
181+
Button,
182+
{
183+
...props,
184+
...opt,
185+
icon: undefined,
186+
onClick: listen
187+
? () =>
188+
attrs?.onClick?.({
189+
code: opt.code,
190+
row,
191+
})
192+
: undefined,
193+
},
194+
{
195+
default: () => {
196+
const content = [];
197+
if (opt.icon) {
198+
content.push(
199+
h(IconifyIcon, { class: 'size-5', icon: opt.icon }),
200+
);
201+
}
202+
content.push(opt.text);
203+
return content;
204+
},
205+
},
206+
);
207+
}
208+
209+
function renderConfirm(opt: Recordable<any>) {
210+
return h(
211+
Popconfirm,
212+
{
213+
getPopupContainer(el) {
214+
return (
215+
el
216+
.closest('.vxe-table--viewport-wrapper')
217+
?.querySelector('.vxe-table--main-wrapper')
218+
?.querySelector('tbody') || document.body
219+
);
220+
},
221+
placement: 'topLeft',
222+
title: $t('ui.actionTitle.delete', [attrs?.nameTitle || '']),
223+
...props,
224+
...opt,
225+
icon: undefined,
226+
onConfirm: () => {
227+
attrs?.onClick?.({
228+
code: opt.code,
229+
row,
230+
});
231+
},
232+
},
233+
{
234+
default: () => renderBtn({ ...opt }, false),
235+
description: () =>
236+
h(
237+
'div',
238+
{ class: 'truncate' },
239+
$t('ui.actionMessage.deleteConfirm', [
240+
row[attrs?.nameField || 'name'],
241+
]),
242+
),
243+
},
244+
);
245+
}
246+
247+
const btns = operations.map((opt) =>
248+
opt.code === 'delete' ? renderConfirm(opt) : renderBtn(opt),
249+
);
250+
return h(
251+
'div',
252+
{
253+
class: 'flex table-operations',
254+
style: { justifyContent: align },
255+
},
256+
btns,
257+
);
258+
},
259+
});
260+
122261
// 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
123262
// vxeUI.formats.add
124263
},

apps/web-antd/src/api/api.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ export interface SysApiResult {
2121
/**
2222
* 获取系统 API 列表
2323
*/
24-
export function getSysApiList(params: SysApiParams) {
24+
export async function getSysApiList(params: SysApiParams) {
2525
return requestClient.get<PaginationResult>('/api/v1/sys/apis', { params });
2626
}

apps/web-antd/src/api/auth.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export type RefreshTokenResult = LoginResult;
2424
/**
2525
* 登录验证码
2626
*/
27-
export function getCaptchaApi() {
27+
export async function getCaptchaApi() {
2828
return requestClient.get<CaptchaResult>('/api/v1/auth/captcha');
2929
}
3030

apps/web-antd/src/api/dept.ts

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { requestClient } from './request';
2+
3+
export interface SysDeptResult {
4+
id: number;
5+
name: string;
6+
parent_id: number;
7+
sort: number;
8+
leader?: string;
9+
phone?: string;
10+
email?: string;
11+
status: number;
12+
created_time: string;
13+
}
14+
15+
export interface SysDeptTreeResult extends SysDeptResult {
16+
children?: SysDeptTreeResult[];
17+
}
18+
19+
export interface SysDeptParams {
20+
name: string;
21+
parent_id?: number;
22+
sort?: number;
23+
leader?: string;
24+
phone?: string;
25+
email?: string;
26+
status: number;
27+
}
28+
29+
export interface SysDeptTreeParams {
30+
name?: string;
31+
leader?: string;
32+
phone?: string;
33+
status?: number;
34+
}
35+
36+
/**
37+
* 获取部门树
38+
*/
39+
export async function getSysDeptTree(params: SysDeptTreeParams) {
40+
return requestClient.get<SysDeptTreeResult[]>('/api/v1/sys/depts', {
41+
params,
42+
});
43+
}
44+
45+
/**
46+
* 获取部门详情
47+
*/
48+
export async function getSysDeptDetail(pk: number) {
49+
return requestClient.get<SysDeptTreeResult>(`/api/v1/sys/depts/${pk}`);
50+
}
51+
52+
/**
53+
* 创建部门
54+
*/
55+
export async function createSysDept(data: SysDeptParams) {
56+
return requestClient.post('/api/v1/sys/depts', data);
57+
}
58+
59+
/**
60+
* 更新部门
61+
*/
62+
export async function updateSysDept(pk: number, data: SysDeptParams) {
63+
return requestClient.put(`/api/v1/sys/depts/${pk}`, data);
64+
}
65+
66+
/**
67+
* 删除部门
68+
*/
69+
export async function deleteSysDept(pk: number) {
70+
return requestClient.delete(`/api/v1/sys/depts/${pk}`);
71+
}

apps/web-antd/src/api/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from './api';
22
export * from './auth';
3+
export * from './dept';
34
export * from './log';
45
export * from './menu';
56
export * from './monitor';

apps/web-antd/src/api/log.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export interface LoginLogParams {
1313
export interface LoginLogResult {
1414
id: number;
1515
username: string;
16-
status: 0 | 1;
16+
status: number;
1717
ip: string;
1818
country?: string;
1919
region?: string;
@@ -39,17 +39,17 @@ export interface OperaLogResult {
3939
browser?: string;
4040
device?: string;
4141
args?: JSON;
42-
status: 0 | 1;
42+
status: number;
4343
code: string;
4444
msg: string;
4545
cost_time: number;
4646
opera_time: string;
4747
}
4848

49-
export function getLoginLogListApi(params: LoginLogParams) {
49+
export async function getLoginLogListApi(params: LoginLogParams) {
5050
return requestClient.get<PaginationResult>('/api/v1/logs/login', { params });
5151
}
5252

53-
export function getOperaLogListApi(params: OperaLogParams) {
53+
export async function getOperaLogListApi(params: OperaLogParams) {
5454
return requestClient.get<PaginationResult>('/api/v1/logs/opera', { params });
5555
}

apps/web-antd/src/api/menu.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ export interface SysMenuResult {
1212
type: number;
1313
component?: string;
1414
perms?: string;
15-
status: 0 | 1;
16-
display: 0 | 1;
17-
cache: 0 | 1;
15+
status: number;
16+
display: number;
17+
cache: number;
1818
remark?: string;
1919
parent_id?: number;
2020
created_time: string;

apps/web-antd/src/api/monitor.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ export interface RedisMonitorResult {
1313
stats: Record<string, any>[];
1414
}
1515

16-
export function getServerMonitor() {
16+
export async function getServerMonitor() {
1717
return requestClient.get<ServerMonitorResult>('/api/v1/monitors/server');
1818
}
1919

20-
export function getRedisMonitor() {
20+
export async function getRedisMonitor() {
2121
return requestClient.get<RedisMonitorResult>('/api/v1/monitors/redis');
2222
}

apps/web-antd/src/api/role.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ export interface SysRoleResult {
2222
/**
2323
* 获取系统角色列表
2424
*/
25-
export function getSysRoleList(params: SysRoleParams) {
25+
export async function getSysRoleList(params: SysRoleParams) {
2626
return requestClient.get<SysRoleResult>('/api/v1/sys/roles', { params });
2727
}

0 commit comments

Comments
 (0)