diff --git a/packages/toolkits/pro/template/server/nestJs/libs/models/src/menu.ts b/packages/toolkits/pro/template/server/nestJs/libs/models/src/menu.ts index e543a55f..01c91794 100644 --- a/packages/toolkits/pro/template/server/nestJs/libs/models/src/menu.ts +++ b/packages/toolkits/pro/template/server/nestJs/libs/models/src/menu.ts @@ -18,4 +18,6 @@ export class Menu { component: string; @Column() path: string; + @Column() + locale: string; } diff --git a/packages/toolkits/pro/template/server/nestJs/src/app.module.ts b/packages/toolkits/pro/template/server/nestJs/src/app.module.ts index 755b153c..cd579d7a 100644 --- a/packages/toolkits/pro/template/server/nestJs/src/app.module.ts +++ b/packages/toolkits/pro/template/server/nestJs/src/app.module.ts @@ -13,9 +13,11 @@ import { existsSync, writeFileSync } from 'fs'; import { UserService } from './user/user.service'; import { RoleService } from './role/role.service'; import { PermissionService } from './permission/permission.service'; +import { MenuService } from "./menu/menu.service"; import { Permission } from '@app/models'; import { MenuModule } from './menu/menu.module'; import { ConfigModule, ConfigService } from '@nestjs/config'; +import {menuData} from "./menu/init/menuData"; @Module({ imports: [ @@ -44,7 +46,8 @@ export class AppModule implements OnModuleInit { constructor( private user: UserService, private role: RoleService, - private permission: PermissionService + private permission: PermissionService, + private menu: MenuService, ) {} async onModuleInit() { const ROOT = __dirname; @@ -52,12 +55,12 @@ export class AppModule implements OnModuleInit { if (existsSync(LOCK_FILE)) { return; } - // TODO: menu + // TODO: permission const modules = ['user', 'permission', 'role', 'menu']; const actions = ['add', 'remove', 'update', 'query']; const tasks = []; let permission; - let isInit = true; + const isInit = true; try { permission = await this.permission.create( { @@ -85,6 +88,17 @@ export class AppModule implements OnModuleInit { ); } } + // TODO Menu + try { + for (const item of menuData){ + await this.menu.createMenu(item, isInit) + } + }catch (e){ + const err = e as HttpException; + Logger.error(err.message); + Logger.error(`Please clear the database and try again`); + process.exit(-1); + } const status = Promise.allSettled(tasks); const statusData = await status; const hasFail = statusData.some((data) => data.status === 'rejected'); @@ -98,11 +112,12 @@ export class AppModule implements OnModuleInit { Logger.error('Please clear the database and try again'); process.exit(-1); } + const menuId = this.menu.getMenuAllId() const role = await this.role.create( { name: 'admin', permissionIds: [permission.id], - menuIds: [], + menuIds: await menuId, }, isInit ); diff --git a/packages/toolkits/pro/template/server/nestJs/src/menu/dto/create-menu.dto.ts b/packages/toolkits/pro/template/server/nestJs/src/menu/dto/create-menu.dto.ts index 80426070..62a240a9 100644 --- a/packages/toolkits/pro/template/server/nestJs/src/menu/dto/create-menu.dto.ts +++ b/packages/toolkits/pro/template/server/nestJs/src/menu/dto/create-menu.dto.ts @@ -13,6 +13,8 @@ export class CreateMenuDto { component: string; @IsNotEmpty() icon: string; + @IsNotEmpty() + locale: string; parentId: number | null; } diff --git a/packages/toolkits/pro/template/server/nestJs/src/menu/init/menuData.ts b/packages/toolkits/pro/template/server/nestJs/src/menu/init/menuData.ts new file mode 100644 index 00000000..3fc11ccc --- /dev/null +++ b/packages/toolkits/pro/template/server/nestJs/src/menu/init/menuData.ts @@ -0,0 +1,332 @@ +export const menuData = [ + { + name: 'Board', + order: 1, + parentId: null, + menuType: 'normal', + icon: 'IconApplication', + component: 'board/index', + path: 'board', + locale: 'menu.board', + }, + { + name: 'Home', + order: 1, + parentId: null, + menuType: 'normal', + icon: '', + component: 'board/home/index', + path: 'home', + locale: 'menu.home', + }, + { + name: 'Work', + order: 2, + parentId: null, + menuType: 'normal', + icon: '', + component: 'board/work/index', + path: 'work', + locale: 'menu.work', + }, + { + name: 'List', + order: 2, + parentId: null, + menuType: 'normal', + icon: 'IconFiles', + component: 'list/index', + path: 'list', + locale: 'menu.list', + }, + { + name: 'Table', + order: 1, + parentId: null, + menuType: 'normal', + icon: '', + component: 'list/search-table/index', + path: 'table', + locale: 'menu.list.searchTable', + }, + { + name: 'Form', + order: 3, + parentId: null, + menuType: 'normal', + icon: 'IconSetting', + component: 'form/index', + path: 'form', + locale: 'menu.form', + }, + { + name: 'Base', + order: 1, + parentId: null, + menuType: 'normal', + icon: '', + component: 'form/base/index', + path: 'base', + locale: 'menu.form.base', + }, + { + name: 'Step', + order: 2, + parentId: null, + menuType: 'normal', + icon: '', + component: 'form/step/index', + path: 'step', + locale: 'menu.form.step', + }, + { + name: 'Profile', + order: 4, + parentId: null, + menuType: 'normal', + icon: 'IconFiletext', + component: 'profile/index', + path: 'profile', + locale: 'menu.profile', + }, + { + name: 'Detail', + order: 1, + parentId: null, + menuType: 'normal', + icon: '', + component: 'profile/detail/index', + path: 'detail', + locale: 'menu.profile.detail', + }, + { + name: 'Result', + order: 5, + parentId: null, + menuType: 'normal', + icon: 'IconSuccessful', + component: 'result/index', + path: 'result', + locale: 'menu.result', + }, + { + name: 'Success', + order: 1, + parentId: null, + menuType: 'normal', + icon: '', + component: 'result/success/index', + path: 'success', + locale: 'menu.result.success', + }, + { + name: 'Error', + order: 2, + parentId: null, + menuType: 'normal', + icon: '', + component: 'result/error/index', + path: 'error', + locale: 'menu.result.error', + }, + { + name: 'Exception', + order: 6, + parentId: null, + menuType: 'normal', + icon: 'IconCueL', + component: 'exception/index', + path: 'exception', + locale: 'menu.exception', + }, + { + name: '403', + order: 1, + parentId: null, + menuType: 'normal', + icon: '', + component: 'exception/403/index', + path: '403', + locale: 'menu.exception.403', + }, + { + name: '404', + order: 2, + parentId: null, + menuType: 'normal', + icon: '', + component: 'exception/404/index', + path: '404', + locale: 'menu.exception.404', + }, + { + name: '500', + order: 1, + parentId: null, + menuType: 'normal', + icon: '', + component: 'exception/500/index', + path: '500', + locale: 'menu.exception.500', + }, + { + name: 'User', + order: 7, + parentId: null, + menuType: 'normal', + icon: 'IconUser', + component: 'user/index', + path: 'user', + locale: 'menu.user', + }, + { + name: 'Info', + order: 1, + parentId: null, + menuType: 'normal', + icon: '', + component: 'user/info/index', + path: 'info', + locale: 'menu.user.info', + }, + { + name: 'Setting', + order: 2, + parentId: null, + menuType: 'normal', + icon: '', + component: 'user/setting/index', + path: 'setting', + locale: 'menu.user.setting', + }, + { + name: 'Cloud', + order: 8, + parentId: null, + menuType: 'normal', + icon: 'IconDownloadCloud', + component: 'cloud/index', + path: 'cloud', + locale: 'menu.cloud', + }, + { + name: 'Hello', + order: 1, + parentId: null, + menuType: 'normal', + icon: '', + component: 'cloud/hello/index', + path: 'hello', + locale: 'menu.cloud.hello', + }, + { + name: 'Contracts', + order: 2, + parentId: null, + menuType: 'normal', + icon: '', + component: 'cloud/contracts/index', + path: 'contracts', + locale: 'menu.cloud.contracts', + }, + { + name: 'Menu', + order: 9, + parentId: null, + menuType: 'admin', + icon: 'IconGrade', + component: 'menu/index', + path: 'menu', + locale: 'menu.menu', + }, + { + name: 'AllMenu', + order: 1, + parentId: null, + menuType: 'admin', + icon: '', + component: 'menu/info/index', + path: 'allMenu', + locale: 'menu.menu.info', + }, + { + name: 'Permission', + order: 10, + parentId: null, + menuType: 'admin', + icon: 'IconFolderOpened', + component: 'permission/index', + path: 'permission', + locale: 'menu.permission', + }, + { + name: 'AllPermission', + order: 1, + parentId: null, + menuType: 'admin', + icon: '', + component: 'permission/info/index', + path: 'allPermission', + locale: 'menu.permission.info', + }, + { + name: 'Role', + order: 11, + parentId: null, + menuType: 'admin', + icon: 'IconActivation', + component: 'role/index', + path: 'role', + locale: 'menu.role', + }, + { + name: 'AllRole', + order: 1, + parentId: null, + menuType: 'admin', + icon: '', + component: 'role/info/index', + path: 'allRole', + locale: 'menu.role.info', + }, + { + name: 'UserManager', + order: 12, + parentId: null, + menuType: 'admin', + icon: 'IconGroup', + component: 'userManager/index', + path: 'userManager', + locale: 'menu.userManager', + }, + { + name: 'AllInfo', + order: 1, + parentId: null, + menuType: 'admin', + icon: '', + component: 'userManager/info/index', + path: 'allInfo', + locale: 'menu.userManager.info', + }, + { + name: 'AllSetting', + order: 1, + parentId: null, + menuType: 'admin', + icon: '', + component: 'userManager/setting/index', + path: 'allSetting', + locale: 'menu.userManager.setting', + }, + { + name: 'UserAdd', + order: 1, + parentId: null, + menuType: 'admin', + icon: '', + component: 'userManager/useradd/index', + path: 'userAdd', + locale: 'menu.userManager.useradd', + }, +] diff --git a/packages/toolkits/pro/template/server/nestJs/src/menu/menu.controller.ts b/packages/toolkits/pro/template/server/nestJs/src/menu/menu.controller.ts index acbc9b7a..0295b995 100644 --- a/packages/toolkits/pro/template/server/nestJs/src/menu/menu.controller.ts +++ b/packages/toolkits/pro/template/server/nestJs/src/menu/menu.controller.ts @@ -30,7 +30,7 @@ export class MenuController { @Post() @Permission('menu::add') async createMenu(@Body() dto: CreateMenuDto) { - return this.menuService.createMenu(dto); + return this.menuService.createMenu(dto, false); } @Patch() diff --git a/packages/toolkits/pro/template/server/nestJs/src/menu/menu.module.ts b/packages/toolkits/pro/template/server/nestJs/src/menu/menu.module.ts index 977ee110..721d71bd 100644 --- a/packages/toolkits/pro/template/server/nestJs/src/menu/menu.module.ts +++ b/packages/toolkits/pro/template/server/nestJs/src/menu/menu.module.ts @@ -8,5 +8,6 @@ import { Menu, Role, User } from '@app/models'; imports: [TypeOrmModule.forFeature([Menu, User, Role])], controllers: [MenuController], providers: [MenuService], + exports: [MenuService], }) export class MenuModule {} diff --git a/packages/toolkits/pro/template/server/nestJs/src/menu/menu.service.ts b/packages/toolkits/pro/template/server/nestJs/src/menu/menu.service.ts index 67b474bc..1fddd5ec 100644 --- a/packages/toolkits/pro/template/server/nestJs/src/menu/menu.service.ts +++ b/packages/toolkits/pro/template/server/nestJs/src/menu/menu.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import {HttpException, HttpStatus, Injectable} from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Menu, User } from '@app/models'; import { Repository } from 'typeorm'; @@ -17,19 +17,22 @@ export interface ITreeNodeData { //组件 component: string; //图标 - icon: string; + customIcon: string; //类型 menuType: string; //父节点 parentId: number; //排序 order: number; + //国际化 + locale: string; } interface MenuMap { [key: number]: Menu; } +type NumberArray = number[]; const toNode = (menu: Menu): ITreeNodeData => { return { label: menu.name, @@ -37,10 +40,11 @@ const toNode = (menu: Menu): ITreeNodeData => { children: [], url: menu.path, component: menu.component, - icon: menu.icon, + customIcon: menu.icon, menuType: menu.menuType, parentId: menu.parentId, order: menu.order, + locale: menu.locale, }; }; @@ -63,11 +67,12 @@ export const convertToTree = ( @Injectable() export class MenuService { + private menuId: number[] = []; constructor( @InjectRepository(User) private user: Repository, @InjectRepository(Menu) - private menu: Repository + private menu: Repository, ) {} async findRoleMenu(email: string) { const userInfo = await this.user @@ -92,7 +97,46 @@ export class MenuService { return convertToTree(await menu) } - async createMenu(dto: CreateMenuDto) { + async getMenuAllId() { + const menu = await this.menu.find(); + for (const item of menu) { + this.menuId.push(item.id) + } + await this.handleMenuParentId(this.menuId) + return this.menuId; + } + + async handleMenuParentId (menuId: number[]){ + const menu = await this.menu.find(); + if(menu){ + menu[1].parentId = menuId[0]; + menu[2].parentId = menuId[0]; + menu[4].parentId = menuId[3]; + menu[6].parentId = menuId[5]; + menu[7].parentId = menuId[5]; + menu[9].parentId = menuId[8]; + menu[11].parentId = menuId[10]; + menu[12].parentId = menuId[10]; + menu[14].parentId = menuId[13]; + menu[15].parentId = menuId[13]; + menu[16].parentId = menuId[13]; + menu[18].parentId = menuId[17]; + menu[19].parentId = menuId[17]; + menu[21].parentId = menuId[20]; + menu[22].parentId = menuId[20]; + menu[24].parentId = menuId[23]; + menu[26].parentId = menuId[25]; + menu[28].parentId = menuId[27]; + menu[30].parentId = menuId[29]; + menu[31].parentId = menuId[29]; + menu[32].parentId = menuId[29]; + } + for(const item of menu){ + await this.menu.update(item.id,{ parentId: item.parentId }) + } + } + + async createMenu(dto: CreateMenuDto, isInit: boolean) { const { order, menuType, @@ -101,7 +145,20 @@ export class MenuService { component, icon, parentId = null, + locale, } = dto; + const menuInfo = this.menu.findOne({ + where: { name,order,menuType,parentId,path,icon,component,locale }, + }); + if (isInit == true && (await menuInfo)) { + return menuInfo; + } + if ((await menuInfo) && isInit == false) { + throw new HttpException( + `菜单字段 ${name} 已经存在`, + HttpStatus.BAD_REQUEST + ); + } return this.menu.save({ name, path, @@ -110,6 +167,7 @@ export class MenuService { menuType, icon, order, + locale, }); } async updateMenu(newData: UpdateMenuDto) { @@ -121,6 +179,7 @@ export class MenuService { menuType: newData.menuType, icon: newData.icon, order: newData.order, + locale: newData.locale, }); return true; } diff --git a/packages/toolkits/pro/template/tinyvue/.gitignore b/packages/toolkits/pro/template/tinyvue/.gitignore index 06d7f53f..69904e8c 100644 --- a/packages/toolkits/pro/template/tinyvue/.gitignore +++ b/packages/toolkits/pro/template/tinyvue/.gitignore @@ -4,3 +4,4 @@ dist dist-ssr *.local *debug.log +*.idea diff --git a/packages/toolkits/pro/template/tinyvue/src/components/menu/index.vue b/packages/toolkits/pro/template/tinyvue/src/components/menu/index.vue index 70fd6f21..5ea359f1 100644 --- a/packages/toolkits/pro/template/tinyvue/src/components/menu/index.vue +++ b/packages/toolkits/pro/template/tinyvue/src/components/menu/index.vue @@ -2,7 +2,7 @@