Skip to content

Commit 5e421ce

Browse files
authored
chore: demo page menu management (#5619)
* 添加菜单管理演示页面
1 parent 1d8676f commit 5e421ce

File tree

18 files changed

+1328
-11
lines changed

18 files changed

+1328
-11
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { verifyAccessToken } from '~/utils/jwt-utils';
2+
import { MOCK_MENU_LIST } from '~/utils/mock-data';
3+
import { unAuthorizedResponse, useResponseSuccess } from '~/utils/response';
4+
5+
export default eventHandler(async (event) => {
6+
const userinfo = verifyAccessToken(event);
7+
if (!userinfo) {
8+
return unAuthorizedResponse(event);
9+
}
10+
11+
return useResponseSuccess(MOCK_MENU_LIST);
12+
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { verifyAccessToken } from '~/utils/jwt-utils';
2+
import { MOCK_MENU_LIST } from '~/utils/mock-data';
3+
import { unAuthorizedResponse } from '~/utils/response';
4+
5+
const namesMap: Record<string, any> = {};
6+
7+
function getNames(menus: any[]) {
8+
menus.forEach((menu) => {
9+
namesMap[menu.name] = String(menu.id);
10+
if (menu.children) {
11+
getNames(menu.children);
12+
}
13+
});
14+
}
15+
getNames(MOCK_MENU_LIST);
16+
17+
export default eventHandler(async (event) => {
18+
const userinfo = verifyAccessToken(event);
19+
if (!userinfo) {
20+
return unAuthorizedResponse(event);
21+
}
22+
const { id, name } = getQuery(event);
23+
24+
return (name as string) in namesMap &&
25+
(!id || namesMap[name as string] !== String(id))
26+
? useResponseSuccess(true)
27+
: useResponseSuccess(false);
28+
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { verifyAccessToken } from '~/utils/jwt-utils';
2+
import { MOCK_MENU_LIST } from '~/utils/mock-data';
3+
import { unAuthorizedResponse } from '~/utils/response';
4+
5+
const pathMap: Record<string, any> = { '/': 0 };
6+
7+
function getPaths(menus: any[]) {
8+
menus.forEach((menu) => {
9+
pathMap[menu.path] = String(menu.id);
10+
if (menu.children) {
11+
getPaths(menu.children);
12+
}
13+
});
14+
}
15+
getPaths(MOCK_MENU_LIST);
16+
17+
export default eventHandler(async (event) => {
18+
const userinfo = verifyAccessToken(event);
19+
if (!userinfo) {
20+
return unAuthorizedResponse(event);
21+
}
22+
const { id, path } = getQuery(event);
23+
24+
return (path as string) in pathMap &&
25+
(!id || pathMap[path as string] !== String(id))
26+
? useResponseSuccess(true)
27+
: useResponseSuccess(false);
28+
});

apps/backend-mock/utils/mock-data.ts

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,195 @@ export const MOCK_MENUS = [
185185
username: 'jack',
186186
},
187187
];
188+
189+
export const MOCK_MENU_LIST = [
190+
{
191+
id: 1,
192+
name: 'Workspace',
193+
status: 1,
194+
type: 'menu',
195+
icon: 'mdi:dashboard',
196+
path: '/workspace',
197+
component: '/dashboard/workspace/index',
198+
meta: {
199+
icon: 'carbon:workspace',
200+
title: 'page.dashboard.workspace',
201+
affixTab: true,
202+
order: 0,
203+
},
204+
},
205+
{
206+
id: 2,
207+
meta: {
208+
icon: 'carbon:settings',
209+
order: 9997,
210+
title: 'system.title',
211+
badge: 'new',
212+
badgeType: 'normal',
213+
badgeVariants: 'primary',
214+
},
215+
status: 1,
216+
type: 'catalog',
217+
name: 'System',
218+
path: '/system',
219+
children: [
220+
{
221+
id: 201,
222+
pid: 2,
223+
path: '/system/menu',
224+
name: 'SystemMenu',
225+
authCode: 'System:Menu:List',
226+
status: 1,
227+
type: 'menu',
228+
meta: {
229+
icon: 'carbon:menu',
230+
title: 'system.menu.title',
231+
},
232+
component: '/system/menu/list',
233+
children: [
234+
{
235+
id: 20_101,
236+
pid: 201,
237+
name: 'SystemMenuCreate',
238+
status: 1,
239+
type: 'button',
240+
authCode: 'System:Menu:Create',
241+
meta: { title: 'common.create' },
242+
},
243+
{
244+
id: 20_102,
245+
pid: 201,
246+
name: 'SystemMenuEdit',
247+
status: 1,
248+
type: 'button',
249+
authCode: 'System:Menu:Edit',
250+
meta: { title: 'common.edit' },
251+
},
252+
{
253+
id: 20_103,
254+
pid: 201,
255+
name: 'SystemMenuDelete',
256+
status: 1,
257+
type: 'button',
258+
authCode: 'System:Menu:Delete',
259+
meta: { title: 'common.delete' },
260+
},
261+
],
262+
},
263+
{
264+
id: 202,
265+
pid: 2,
266+
path: '/system/dept',
267+
name: 'SystemDept',
268+
status: 1,
269+
type: 'menu',
270+
authCode: 'System:Dept:List',
271+
meta: {
272+
icon: 'carbon:container-services',
273+
title: 'system.dept.title',
274+
},
275+
component: '/system/dept/list',
276+
children: [
277+
{
278+
id: 20_401,
279+
pid: 201,
280+
name: 'SystemDeptCreate',
281+
status: 1,
282+
type: 'button',
283+
authCode: 'System:Dept:Create',
284+
meta: { title: 'common.create' },
285+
},
286+
{
287+
id: 20_402,
288+
pid: 201,
289+
name: 'SystemDeptEdit',
290+
status: 1,
291+
type: 'button',
292+
authCode: 'System:Dept:Edit',
293+
meta: { title: 'common.edit' },
294+
},
295+
{
296+
id: 20_403,
297+
pid: 201,
298+
name: 'SystemDeptDelete',
299+
status: 1,
300+
type: 'button',
301+
authCode: 'System:Dept:Delete',
302+
meta: { title: 'common.delete' },
303+
},
304+
],
305+
},
306+
],
307+
},
308+
{
309+
id: 9,
310+
meta: {
311+
badgeType: 'dot',
312+
order: 9998,
313+
title: 'demos.vben.title',
314+
icon: 'carbon:data-center',
315+
},
316+
name: 'Project',
317+
path: '/vben-admin',
318+
type: 'catalog',
319+
status: 1,
320+
children: [
321+
{
322+
id: 901,
323+
pid: 9,
324+
name: 'VbenDocument',
325+
path: '/vben-admin/document',
326+
component: 'IFrameView',
327+
type: 'embedded',
328+
status: 1,
329+
meta: {
330+
icon: 'carbon:book',
331+
iframeSrc: 'https://doc.vben.pro',
332+
title: 'demos.vben.document',
333+
},
334+
},
335+
{
336+
id: 902,
337+
pid: 9,
338+
name: 'VbenGithub',
339+
path: '/vben-admin/github',
340+
component: 'IFrameView',
341+
type: 'link',
342+
status: 1,
343+
meta: {
344+
icon: 'carbon:logo-github',
345+
link: 'https://github.com/vbenjs/vue-vben-admin',
346+
title: 'Github',
347+
},
348+
},
349+
{
350+
id: 903,
351+
pid: 9,
352+
name: 'VbenAntdv',
353+
path: '/vben-admin/antdv',
354+
component: 'IFrameView',
355+
type: 'link',
356+
status: 0,
357+
meta: {
358+
icon: 'carbon:hexagon-vertical-solid',
359+
badgeType: 'dot',
360+
link: 'https://ant.vben.pro',
361+
title: 'demos.vben.antdv',
362+
},
363+
},
364+
],
365+
},
366+
{
367+
id: 10,
368+
component: '_core/about/index',
369+
type: 'menu',
370+
status: 1,
371+
meta: {
372+
icon: 'lucide:copyright',
373+
order: 9999,
374+
title: 'demos.vben.about',
375+
},
376+
name: 'About',
377+
path: '/about',
378+
},
379+
];

packages/@core/ui-kit/form-ui/src/form-api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ export class FormApi {
9393
return this.state;
9494
}
9595

96-
async getValues() {
96+
async getValues<T = Recordable<any>>() {
9797
const form = await this.getForm();
98-
return form.values ? this.handleRangeTimeValue(form.values) : {};
98+
return (form.values ? this.handleRangeTimeValue(form.values) : {}) as T;
9999
}
100100

101101
async isFieldValid(fieldName: string) {

packages/locales/src/langs/en-US/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,7 @@
1616
"disabled": "Disabled",
1717
"edit": "Edit",
1818
"delete": "Delete",
19-
"create": "Create"
19+
"create": "Create",
20+
"yes": "Yes",
21+
"no": "No"
2022
}

packages/locales/src/langs/en-US/ui.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
"selectRequired": "Please select {0}",
55
"minLength": "{0} must be at least {1} characters",
66
"maxLength": "{0} can be at most {1} characters",
7-
"length": "{0} must be {1} characters long"
7+
"length": "{0} must be {1} characters long",
8+
"alreadyExists": "{0} `{1}` already exists",
9+
"startWith": "{0} must start with `{1}`",
10+
"invalidURL": "Please input a valid URL"
811
},
912
"actionTitle": {
1013
"edit": "Modify {0}",

packages/locales/src/langs/zh-CN/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,7 @@
1616
"disabled": "已禁用",
1717
"edit": "修改",
1818
"delete": "删除",
19-
"create": "新增"
19+
"create": "新增",
20+
"yes": "",
21+
"no": ""
2022
}

packages/locales/src/langs/zh-CN/ui.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
"selectRequired": "请选择{0}",
55
"minLength": "{0}至少{1}个字符",
66
"maxLength": "{0}最多{1}个字符",
7-
"length": "{0}长度必须为{1}个字符"
7+
"length": "{0}长度必须为{1}个字符",
8+
"alreadyExists": "{0} `{1}` 已存在",
9+
"startWith": "{0}必须以 {1} 开头",
10+
"invalidURL": "请输入有效的链接"
811
},
912
"actionTitle": {
1013
"edit": "修改{0}",

playground/src/adapter/vxe-table.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { h } from 'vue';
55
import { IconifyIcon } from '@vben/icons';
66
import { $te } from '@vben/locales';
77
import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';
8-
import { isFunction, isString } from '@vben/utils';
8+
import { get, isFunction, isString } from '@vben/utils';
99

1010
import { objectOmit } from '@vueuse/core';
1111
import { Button, Image, Popconfirm, Tag } from 'ant-design-vue';
@@ -77,8 +77,8 @@ setupVbenVxeTable({
7777
// 单元格渲染: Tag
7878
vxeUI.renderer.add('CellTag', {
7979
renderTableDefault({ options, props }, { column, row }) {
80-
const value = row[column.field];
81-
const tagOptions = options || [
80+
const value = get(row, column.field);
81+
const tagOptions = options ?? [
8282
{ color: 'success', label: $t('common.enabled'), value: 1 },
8383
{ color: 'error', label: $t('common.disabled'), value: 0 },
8484
];
@@ -87,7 +87,7 @@ setupVbenVxeTable({
8787
Tag,
8888
{
8989
...props,
90-
...objectOmit(tagItem, ['label']),
90+
...objectOmit(tagItem ?? {}, ['label']),
9191
},
9292
{ default: () => tagItem?.label ?? value },
9393
);

0 commit comments

Comments
 (0)