diff --git a/template/nestJs/menu-data.json b/template/nestJs/menu-data.json new file mode 100644 index 00000000..8e527aa5 --- /dev/null +++ b/template/nestJs/menu-data.json @@ -0,0 +1,263 @@ +[ + { + "label": "Board", + "children": [ + { + "label": "Home", + "children": [], + "url": "home", + "component": "board/home/index", + "icon": "", + "menuType": "normal", + "locale": "menu.home" + }, + { + "label": "Work", + "children": [], + "url": "work", + "component": "board/work/index", + "icon": "", + "menuType": "normal", + "locale": "menu.work" + } + ], + "url": "board", + "component": "board/index", + "icon": "IconApplication", + "menuType": "normal", + "locale": "menu.board" + }, + { + "label": "List", + "children": [ + { + "label": "Table", + "children": [], + "url": "table", + "component": "list/search-table/index", + "icon": "", + "menuType": "normal", + "locale": "menu.list.searchTable" + }, + { + "label": "Card", + "children": [], + "url": "card", + "component": "list/card-list/index", + "icon": "", + "menuType": "normal", + "locale": "menu.list.cardList" + } + ], + "url": "list", + "component": "list/index", + "icon": "IconFiles", + "menuType": "normal", + "locale": "menu.list" + }, + { + "label": "Form", + "children": [ + { + "label": "Base", + "children": [], + "url": "base", + "component": "form/base/index", + "icon": "", + "menuType": "normal", + "locale": "menu.form.base" + }, + { + "label": "Step", + "children": [], + "url": "step", + "component": "form/step/index", + "icon": "", + "menuType": "normal", + "locale": "menu.form.step" + } + ], + "url": "form", + "component": "form/index", + "icon": "IconSetting", + "menuType": "normal", + "locale": "menu.form" + }, + { + "label": "Profile", + "children": [ + { + "label": "Detail", + "children": [], + "url": "detail", + "component": "profile/detail/index", + "icon": "", + "menuType": "normal", + "locale": "menu.profile.detail" + } + ], + "url": "profile", + "component": "profile/index", + "icon": "IconFiletext", + "menuType": "normal", + "locale": "menu.profile" + }, + { + "label": "Result", + "children": [ + { + "label": "Success", + "children": [], + "url": "success", + "component": "result/success/index", + "icon": "", + "menuType": "normal", + "locale": "menu.result.success" + }, + { + "label": "Error", + "children": [], + "url": "error", + "component": "result/error/index", + "icon": "", + "menuType": "normal", + "locale": "menu.result.error" + } + ], + "url": "result", + "component": "result/index", + "icon": "IconSuccessful", + "menuType": "normal", + "locale": "menu.result" + }, + { + "label": "Exception", + "children": [ + { + "label": "403", + "children": [], + "url": "403", + "component": "exception/403/index", + "icon": "", + "menuType": "normal", + "locale": "menu.exception.403" + }, + { + "label": "500", + "children": [], + "url": "500", + "component": "exception/500/index", + "icon": "", + "menuType": "normal", + "locale": "menu.exception.500" + }, + { + "label": "404", + "children": [], + "url": "404", + "component": "exception/404/index", + "icon": "", + "menuType": "normal", + "locale": "menu.exception.404" + } + ], + "url": "exception", + "component": "exception/index", + "icon": "IconCueL", + "menuType": "normal", + "locale": "menu.exception" + }, + { + "label": "User", + "children": [ + { + "label": "Info", + "children": [], + "url": "info", + "component": "user/info/index", + "icon": "", + "menuType": "normal", + "locale": "menu.user.info" + } + ], + "url": "user", + "component": "user/index", + "icon": "IconUser", + "menuType": "normal", + "locale": "menu.user" + }, + { + "label": "MenuPage", + "children": [ + { + "label": "SecondMenu", + "children": [], + "url": "secondMenu", + "component": "menu/demo/index", + "icon": "add-cube", + "menuType": "normal", + "locale": "menu.menuPage.second" + } + ], + "url": "menuPage", + "component": "menu/index", + "icon": "IconApp", + "menuType": "normal", + "locale": "menu.menuPage" + }, + { + "label": "SystemManager", + "children": [ + { + "label": "AllMenu", + "children": [], + "url": "menu/allMenu", + "component": "menu/info/index", + "icon": "IconGrade", + "menuType": "admin", + "locale": "menu.menu.info" + }, + { + "label": "AllPermission", + "children": [], + "url": "permission/allPermission", + "component": "permission/info/index", + "icon": "IconFolderOpened", + "menuType": "admin", + "locale": "menu.permission.info" + }, + { + "label": "AllRole", + "children": [], + "url": "role/allRole", + "component": "role/info/index", + "icon": "IconActivation", + "menuType": "admin", + "locale": "menu.role.info" + }, + { + "label": "AllInfo", + "children": [], + "url": "userManager/allInfo", + "component": "userManager/info/index", + "icon": "IconGroup", + "menuType": "admin", + "locale": "menu.userManager.info" + }, + { + "label": "Local", + "children": [], + "url": "locale", + "component": "locale/index", + "icon": "IconFlag", + "menuType": "", + "locale": "menu.i18n" + } + ], + "url": "", + "component": "menu/index", + "icon": "IconTotal", + "menuType": "normal", + "locale": "menu.systemManager" + } +] diff --git a/template/nestJs/src/app.module.ts b/template/nestJs/src/app.module.ts index f3c727b9..99153659 100644 --- a/template/nestJs/src/app.module.ts +++ b/template/nestJs/src/app.module.ts @@ -1,8 +1,6 @@ -import { SequelizeModule } from '@nestjs/sequelize'; import { HttpException, Logger, - LoggerService, Module, OnModuleInit, } from '@nestjs/common'; @@ -20,10 +18,8 @@ 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'; import { I18Module } from './i18/i18.module'; import { I18LangService } from './i18/lang.service'; import { I18Service } from './i18/i18.service'; @@ -36,13 +32,17 @@ import { RejectRequestGuard } from './public/reject.guard'; import { HealthCheckController } from './health-check.controller'; import { ApplicationModule } from './application/application.module'; import { ApplicationService } from './application/application.service'; -import { applicationData } from './application/init/data'; import { CONFIG_SCHEMA, Configure } from './config-schema'; import { InstallLock } from './install-lock'; import { RedisService } from '../libs/redis/redis.service'; import Redis from 'ioredis'; import { RedisModule } from '../libs/redis/redis.module'; import { LockerModule } from '@app/locker'; +import { MenuInitializer } from './menu/menu.initializer'; +import { RoleInit } from './role/role.initializer'; +import { PermissionInit } from './permission/permission.initalizer'; +import { UserInit } from './user/user.initalizer'; +import { ApplicationInit } from './application/application.init'; const INSTALL_FLAG = 'FLAG:INSTALL'; const MAX_RETRY = 20; @@ -96,16 +96,16 @@ const MAX_RETRY = 20; }) export class AppModule implements OnModuleInit { constructor( - private user: UserService, - private role: RoleService, - private permission: PermissionService, - private menu: MenuService, private lang: I18LangService, private i18: I18Service, - private application: ApplicationService, private lock: InstallLock, private redis: RedisService, - private cfg: ConfigService + private cfg: ConfigService, + private menuInit: MenuInitializer, + private roleInit: RoleInit, + private permissionInit: PermissionInit, + private userInit: UserInit, + private applicationInit: ApplicationInit ) {} async isInstalled(redis: Redis) { return redis.exists(INSTALL_FLAG); @@ -186,91 +186,12 @@ export class AppModule implements OnModuleInit { Logger.log(`${name} - ${key} save success`); } } - const permissions = { - user: [ - 'add', - 'remove', - 'update', - 'query', - 'password::force-update', - 'batch-remove', - ], - permission: ['add', 'remove', 'update', 'get'], - role: ['add', 'remove', 'update', 'query'], - menu: ['add', 'remove', 'update', 'query'], - i18n: ['add', 'remove', 'update', 'query', 'batch-remove'], - lang: ['add', 'remove', 'update', 'query'], - }; - const tasks = []; - const isInit = true; - let permission = await this.permission.create( - { - name: '*', - desc: 'super permission', - }, - isInit - );; - for (const [module, actions] of Object.entries(permissions)) { - for (const action of actions) { - tasks.push( - this.permission.create( - { - name: `${module}::${action}`, - desc: '', - }, - isInit - ) - ); - } - } - // TODO Menu - for (const item of menuData) { - await this.menu.createMenu(item, isInit); - } - - // application - for (const item of applicationData) { - await this.application.createApplication(item, isInit); - } - const status = Promise.allSettled(tasks); - const statusData = await status; - const hasFail = statusData.some((data) => data.status === 'rejected'); - if (hasFail) { - const fail: any[] = statusData.filter( - (data) => data.status === 'rejected' - ); - fail.forEach((data) => { - Logger.error(`${data.reason}`); - }); - Logger.error('Please clear the database and try again'); - await this.lock.release(); - process.exit(-1); - } - - const menuId = this.menu.getMenuAllId(); - const role = await this.role.create( - { - name: 'admin', - permissionIds: [permission.id], - menuIds: await menuId, - }, - isInit - ); - const user = await this.user.create( - { - email: 'admin@no-reply.com', - password: 'admin', - roleIds: [role.id], - name: 'admin', - status: 1, - }, - isInit - ); - Logger.log(`[APP]: create admin user success`); - Logger.log(`[APP]: email: ${user.email}`); - Logger.log(`[APP]: password: 'admin'`); - Logger.log('Enjoy!'); + await this.applicationInit.run(); + await this.menuInit.run(); + await this.permissionInit.run(); + await this.roleInit.run(); + await this.userInit.run() await this.setIsInstalled(redis); } catch (e) { const err = e as HttpException; diff --git a/template/nestJs/src/application/application.init.ts b/template/nestJs/src/application/application.init.ts new file mode 100644 index 00000000..c210d1fe --- /dev/null +++ b/template/nestJs/src/application/application.init.ts @@ -0,0 +1,24 @@ +import { Initializer } from "../initalizer.interface"; +import { applicationData } from './init/data'; +import { Repository } from "typeorm"; +import { Application } from "@app/models"; +import { InjectRepository } from "@nestjs/typeorm"; + +export class ApplicationInit implements Initializer> { + constructor( + @InjectRepository(Application) + private application: Repository + ){} + async run(): Promise { + for (const app of applicationData) { + if ( + await this.application.findOne({where:{name:app.name}}) + ) { + return; + } + await this.application.save( + this.application.create(app) + ) + } + } +} diff --git a/template/nestJs/src/application/application.module.ts b/template/nestJs/src/application/application.module.ts index 4f28159b..73eb167a 100644 --- a/template/nestJs/src/application/application.module.ts +++ b/template/nestJs/src/application/application.module.ts @@ -3,11 +3,12 @@ import { Module } from '@nestjs/common'; import { Application } from '@app/models'; import { ApplicationController } from './application.controller'; import { ApplicationService } from './application.service'; +import { ApplicationInit } from './application.init'; @Module({ imports: [TypeOrmModule.forFeature([Application])], controllers: [ApplicationController], - providers: [ApplicationService], - exports: [ApplicationService], + providers: [ApplicationService, ApplicationInit], + exports: [ApplicationService, ApplicationInit], }) export class ApplicationModule {} diff --git a/template/nestJs/src/initalizer.interface.ts b/template/nestJs/src/initalizer.interface.ts new file mode 100644 index 00000000..709239cb --- /dev/null +++ b/template/nestJs/src/initalizer.interface.ts @@ -0,0 +1,3 @@ +export interface Initializer { + run(): RunReturn +} diff --git a/template/nestJs/src/menu/init/menuData.ts b/template/nestJs/src/menu/init/menuData.ts deleted file mode 100644 index 5b1a40e6..00000000 --- a/template/nestJs/src/menu/init/menuData.ts +++ /dev/null @@ -1,302 +0,0 @@ -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: 'MenuPage', - order: 9, - parentId: null, - menuType: 'normal', - icon: 'IconApp', - component: 'menu/index', - path: 'menuPage', - locale: 'menu.menuPage', - }, - { - name: 'SecondMenu', - order: 1, - parentId: null, - menuType: 'normal', - icon: '', - component: 'menu/index', - path: 'secondMenu', - locale: 'menu.menuPage.second', - }, - { - name: 'ThirdMenu', - order: 1, - parentId: null, - menuType: 'normal', - icon: '', - component: 'menu/demo/index', - path: 'thirdMenu', - locale: 'menu.menuPage.third', - }, - { - name: 'SystemManager', - order: 10, - parentId: null, - menuType: 'normal', - icon: 'IconTotal', - component: 'menu/index', - path: '', - locale: 'menu.systemManager', - }, - { - name: 'AllMenu', - order: 1, - parentId: null, - menuType: 'admin', - icon: 'IconGrade', - component: 'menu/info/index', - path: 'menu/allMenu', - locale: 'menu.menu.info', - }, - { - name: 'AllPermission', - order: 1, - parentId: null, - menuType: 'admin', - icon: 'IconFolderOpened', - component: 'permission/info/index', - path: 'permission/allPermission', - locale: 'menu.permission.info', - }, - { - name: 'AllRole', - order: 1, - parentId: null, - menuType: 'admin', - icon: 'IconActivation', - component: 'role/info/index', - path: 'role/allRole', - locale: 'menu.role.info', - }, - { - name: 'AllInfo', - order: 1, - parentId: null, - menuType: 'admin', - icon: 'IconGroup', - component: 'userManager/info/index', - path: 'userManager/allInfo', - locale: 'menu.userManager.info', - }, - { - name: 'Local', - order: 14, - parentId: null, - menuType: '', - icon: 'IconFlag', - component: 'locale/index', - path: 'locale', - locale: 'menu.i18n', - }, - { - name: 'Card', - order: 2, - parentId: null, - menuType: 'normal', - icon: '', - component: 'list/card-list/index', - path: 'card', - locale: 'menu.list.cardList', - }, - { - name: 'Advance', - order: 3, - parentId: null, - menuType: 'normal', - icon: '', - component: 'form/advance/index', - path: 'advance', - locale: 'menu.form.advance', - }, -]; diff --git a/template/nestJs/src/menu/menu.initializer.ts b/template/nestJs/src/menu/menu.initializer.ts new file mode 100644 index 00000000..45aac37e --- /dev/null +++ b/template/nestJs/src/menu/menu.initializer.ts @@ -0,0 +1,56 @@ +import { Menu } from "@app/models"; +import { Injectable, Logger } from "@nestjs/common"; +import { InjectRepository } from "@nestjs/typeorm"; +import { readFileSync } from "fs"; +import { join } from "path"; +import { Initializer } from "../initalizer.interface"; +import { Repository } from "typeorm"; + + +type RawMenuData = { + label: string; + url: string; + component: string; + icon: string; + locale: string; + menuType: string; + children?: RawMenuData[] +} + +@Injectable() +export class MenuInitializer implements Initializer> { + constructor( + @InjectRepository(Menu) + private menu: Repository, + ){} + + async run(){ + const path = join(process.cwd(), 'menu-data.json'); + const menuData:RawMenuData[] = JSON.parse(readFileSync(path).toString()); + const dfs = async (data: RawMenuData, level: number, parentId: number) =>{ + const menu = new Menu(); + menu.component = data.component; + menu.icon = data.icon; + menu.locale = data.locale; + menu.menuType = data.menuType || ''; + menu.name = data.label; + menu.order = level; + menu.parentId = parentId || null; + menu.path = data.url; + const res = await this.menu.findOne({ + where: { + path: menu.path + } + }) || await this.menu.save(menu); + if (!data.children) { + return; + } + for (const child of data.children) { + dfs(child, 0, res.id) + } + } + for (const data of menuData) { + await dfs(data, 0, undefined); + } + } +} diff --git a/template/nestJs/src/menu/menu.module.ts b/template/nestJs/src/menu/menu.module.ts index 721d71bd..d72489ed 100644 --- a/template/nestJs/src/menu/menu.module.ts +++ b/template/nestJs/src/menu/menu.module.ts @@ -3,11 +3,12 @@ import { MenuService } from './menu.service'; import { MenuController } from './menu.controller'; import { TypeOrmModule } from '@nestjs/typeorm'; import { Menu, Role, User } from '@app/models'; +import { MenuInitializer } from './menu.initializer'; @Module({ imports: [TypeOrmModule.forFeature([Menu, User, Role])], controllers: [MenuController], - providers: [MenuService], - exports: [MenuService], + providers: [MenuService, MenuInitializer], + exports: [MenuService, MenuInitializer], }) export class MenuModule {} diff --git a/template/nestJs/src/menu/menu.service.ts b/template/nestJs/src/menu/menu.service.ts index 3a3ecb12..e9c10a10 100644 --- a/template/nestJs/src/menu/menu.service.ts +++ b/template/nestJs/src/menu/menu.service.ts @@ -34,7 +34,6 @@ interface MenuMap { [key: number]: Menu; } -type NumberArray = number[]; const toNode = (menu: Menu): ITreeNodeData => { return { label: menu.name, @@ -100,47 +99,6 @@ export class MenuService { return convertToTree(await menu); } - /* istanbul ignore next */ - 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; - } - - /* istanbul ignore next */ - 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[20].parentId = menuId[19]; - menu[21].parentId = menuId[20]; - menu[23].parentId = menuId[22]; - menu[24].parentId = menuId[22]; - menu[25].parentId = menuId[22]; - menu[26].parentId = menuId[22]; - menu[27].parentId = menuId[22]; - menu[28].parentId = menuId[3]; - menu[29].parentId = menuId[5]; - } - for (const item of menu) { - await this.menu.update(item.id, { parentId: item.parentId }); - } - } - async createMenu(dto: CreateMenuDto, isInit: boolean) { const { order, diff --git a/template/nestJs/src/permission/permission.initalizer.ts b/template/nestJs/src/permission/permission.initalizer.ts new file mode 100644 index 00000000..93ab5772 --- /dev/null +++ b/template/nestJs/src/permission/permission.initalizer.ts @@ -0,0 +1,54 @@ +import { InjectRepository } from "@nestjs/typeorm"; +import { Initializer } from "../initalizer.interface"; +import { Permission } from "@app/models"; +import { Repository } from "typeorm"; + +export class PermissionInit implements Initializer>{ + constructor( + @InjectRepository(Permission) + private permission: Repository, + ){} + async run(): Promise { + const permissions = { + user: [ + 'add', + 'remove', + 'update', + 'query', + 'password::force-update', + 'batch-remove', + ], + permission: ['add', 'remove', 'update', 'get'], + role: ['add', 'remove', 'update', 'query'], + menu: ['add', 'remove', 'update', 'query'], + i18n: ['add', 'remove', 'update', 'query', 'batch-remove'], + lang: ['add', 'remove', 'update', 'query'], + }; + const permissionEntites:Permission[] = []; + permissionEntites.push( + this.permission.create({ + name: '*', + desc: '' + }) + ); + for (const [module, actions] of Object.entries(permissions)) { + for (const action of actions) { + if ( + await this.permission.findOne({ + where:{name: `${module}::${action}`} + }) + ) { + continue; + } + const p = this.permission.create( + { + name: `${module}::${action}`, + desc: '', + }, + ) + permissionEntites.push(p); + } + } + await this.permission.save(permissionEntites); + } +} diff --git a/template/nestJs/src/permission/permission.module.ts b/template/nestJs/src/permission/permission.module.ts index 7b018ea4..03cc1ff1 100644 --- a/template/nestJs/src/permission/permission.module.ts +++ b/template/nestJs/src/permission/permission.module.ts @@ -3,11 +3,12 @@ import { PermissionService } from './permission.service'; import { PermissionController } from './permission.controller'; import { TypeOrmModule } from '@nestjs/typeorm'; import { Permission } from '@app/models'; +import { PermissionInit } from './permission.initalizer'; @Module({ controllers: [PermissionController], - providers: [PermissionService], + providers: [PermissionService, PermissionInit], imports: [TypeOrmModule.forFeature([Permission])], - exports: [PermissionService], + exports: [PermissionService, PermissionInit], }) export class PermissionModule {} diff --git a/template/nestJs/src/role/role.initializer.ts b/template/nestJs/src/role/role.initializer.ts new file mode 100644 index 00000000..a9171288 --- /dev/null +++ b/template/nestJs/src/role/role.initializer.ts @@ -0,0 +1,35 @@ +import { Injectable } from "@nestjs/common"; +import { Initializer } from "../initalizer.interface"; +import { InjectRepository } from "@nestjs/typeorm"; +import { Menu, Permission, Role } from "@app/models"; +import { Repository } from "typeorm"; + +@Injectable() +export class RoleInit implements Initializer> { + constructor( + @InjectRepository(Role) + private role: Repository, + @InjectRepository(Permission) + private permission: Repository, + @InjectRepository(Menu) + private menu: Repository + ){ + + } + async run(): Promise { + const permission = await this.permission.find({ + where:{ + name: '*' + } + }) + const menus = await this.menu.find(); + if (await this.role.findOneBy({name: 'admin'})) { + return; + } + await this.role.save({ + name: 'admin', + permission: permission, + menus + }); + } +} diff --git a/template/nestJs/src/role/role.module.ts b/template/nestJs/src/role/role.module.ts index d4c21f68..815db4a4 100644 --- a/template/nestJs/src/role/role.module.ts +++ b/template/nestJs/src/role/role.module.ts @@ -3,11 +3,12 @@ import { RoleService } from './role.service'; import { RoleController } from './role.controller'; import { TypeOrmModule } from '@nestjs/typeorm'; import { Menu, Permission, Role, User } from '@app/models'; +import { RoleInit } from './role.initializer'; @Module({ controllers: [RoleController], - providers: [RoleService], + providers: [RoleService, RoleInit], imports: [TypeOrmModule.forFeature([Role, Permission, Menu, User])], - exports: [RoleService], + exports: [RoleService, RoleInit], }) export class RoleModule {} diff --git a/template/nestJs/src/user/user.initalizer.ts b/template/nestJs/src/user/user.initalizer.ts new file mode 100644 index 00000000..125aa60e --- /dev/null +++ b/template/nestJs/src/user/user.initalizer.ts @@ -0,0 +1,44 @@ +import { InjectRepository } from "@nestjs/typeorm"; +import { Initializer } from "../initalizer.interface"; +import { Role, User } from "@app/models"; +import { Repository } from "typeorm"; +import { UserService } from "./user.service"; +import { Logger } from "@nestjs/common"; + +export class UserInit implements Initializer> { + constructor( + @InjectRepository(User) + private userRepo: Repository, + private user: UserService, + @InjectRepository(Role) + private role: Repository + ){} + async run(): Promise { + const role = await this.role.findOneOrFail({ + where:{ + name: 'admin' + } + }); + if ( + await this.userRepo.findOneBy({ + email: 'admin@no-reply.com' + }) + ) { + return; + } + const user = await this.user.create( + { + email: 'admin@no-reply.com', + password: 'admin', + roleIds: [role.id], + name: 'admin', + status: 1, + }, + true + ); + Logger.log(`[APP]: create admin user success`); + Logger.log(`[APP]: email: ${user.email}`); + Logger.log(`[APP]: password: 'admin'`); + Logger.log('Enjoy!'); + } +} diff --git a/template/nestJs/src/user/user.module.ts b/template/nestJs/src/user/user.module.ts index d9932b57..899a8513 100644 --- a/template/nestJs/src/user/user.module.ts +++ b/template/nestJs/src/user/user.module.ts @@ -6,11 +6,12 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { AuthService } from '../auth/auth.service'; import { RedisService } from '../../libs/redis/redis.service'; import { TokenService } from '../auth/token.service'; +import { UserInit } from './user.initalizer'; @Module({ imports: [TypeOrmModule.forFeature([User, Permission, Role])], controllers: [UserController], - providers: [UserService, AuthService, RedisService, TokenService], - exports: [UserService], + providers: [UserService, AuthService, RedisService, TokenService, UserInit], + exports: [UserService, UserInit], }) export class UserModule {}