NestJS-菜单模块

NestJS-菜单模块

1、菜单模块

接下来我们新建一个菜单模块,实现对于菜单部分的管理功能接口

👉生成菜单文件

javascript 复制代码
nest g controller modules/menu --no-spec
nest g module modules/menu --no-spec
nest g service modules/menu --no-spec

创建完成以后的目录如下图所示

javascript 复制代码
src\modules\menu
  src\modules\menu\menu.controller.ts
  src\modules\menu\menu.module.ts
  src\modules\menu\menu.service.ts

👉menu.entity.ts实体搭建

javascript 复制代码
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';

@Entity()
export class SysMenu {
  @PrimaryGeneratedColumn()
  menuId: number;

  @Column()
  menuName: string;

  @Column()
  parentId: number;

  @Column()
  orderNum: number;

  @Column()
  path: string;

  @Column({ nullable: true })
  component: string;

  @Column({ default: '' })
  query: string;

  @Column()
  isFrame: number;

  @Column()
  isCache: number;

  @Column()
  menuType: string;

  @Column()
  visible: string;

  @Column()
  status: string;

  @Column({ nullable: true })
  perms: string;

  @Column()
  icon: string;

  @Column()
  createBy: string;

  @Column()
  createTime: string;

  @Column({ nullable: true })
  updateBy: string;

  @Column({ nullable: true })
  updateTime: string;

  @Column({ nullable: true })
  remark: string;
}

略微完善和调整

javascript 复制代码
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity('sys_menu')
export class Menu {
  @PrimaryGeneratedColumn({ comment: '菜单ID',type: 'bigint',name: 'menu_id' })
  menuId: number;

  @Column({ type: 'varchar', length: 50, comment: '菜单名称',name: 'menu_name' })
  menuName: string;

  @Column({ type: 'bigint', default: 0,nullable: true, comment: '父菜单ID' ,name: 'parent_id'})
  parentId: number;

  @Column({ type: 'int', default: 0,nullable: true, comment: '显示顺序' ,name: 'order_num'})
  orderNum: number;

  @Column({ type: 'varchar', length: 200,nullable: true, default: '', comment: '路由地址' })
  path: string;

  @Column({ type: 'varchar', length: 255, nullable: true, comment: '组件路径' })
  component: string;

  @Column({ type: 'varchar', length: 255, nullable: true, comment: '路由参数' })
  query: string;

  @Column({ type: 'int', default: 1,nullable: true, comment: '是否为外链(0是 1否)' ,name: 'is_frame'})
  isFrame: number;

  @Column({ type: 'int', default: 0,nullable: true, comment: '是否缓存(0缓存 1不缓存)',name: 'is_cache' })
  isCache: number;

  @Column({ type: 'char', length: 1,nullable: true, default: '', comment: '菜单类型(M目录 C菜单 F按钮)',name: 'menu_type' })
  menuType: string;

  @Column({ type: 'char', length: 1, nullable: true,default: 1, comment: '菜单状态(0显示 1隐藏)' })
  visible: string;

  @Column({ type: 'char', length: 1, nullable: true,default: 0, comment: '菜单状态(0正常 1停用)' })
  status: string;

  @Column({ type: 'varchar', length: 100, nullable: true, comment: '权限标识' })
  perms: string;

  @Column({ type: 'varchar', length: 100, nullable: true,default: '#', comment: '菜单图标' })
  icon: string;

  @Column({ type: 'varchar', length: 64, nullable: true,default: '', comment: '创建者',name: 'create_by' })
  createBy: string;

  @Column({ type: 'datetime', nullable: true, comment: '创建时间',name: 'create_time' })
  createTime: Date;

  @Column({ type: 'varchar', length: 64,nullable: true, default: '', comment: '更新者',name: 'update_by' })
  updateBy: string;

  @Column({ type: 'datetime', nullable: true, comment: '更新时间',name: 'update_time' })
  updateTime: Date;

  @Column({ type: 'varchar', length: 500,nullable: true, default: '', comment: '备注' })
  remark: string;
}

👉实体映射

在我们的src\common\entity\index.ts文件之中导入实体并进行映射

javascript 复制代码
import { SysMenu } from '../../modules/menu/menu.entity'; // 菜单实体

export const typeOrmConfig: TypeOrmModuleOptions = {
  type: 'mysql', // 可以选择其他数据库,如 MySQL
  host: 'localhost',
  port: 3306,
  username: 'root',
  password: 'XXXXX',
  database: 'nexusnest',
  entities: [User,SysChat,SysGruop,GroupUser,SysMenu], 
  synchronize: true, // 自动同步实体到数据库(开发时可以启用,生产环境应谨慎使用)
  logging: false,  // 启用日志记录
  timezone: '+08:00', // 设置时区
};

这个时候刷新我们数据库可以发现,数据库的表已经对应上我们对应的实体了

2、搜索

接下来我们就根据对应的实体帮助我们生成一下我们的菜单功能部分的api接口

实现菜单功能其实跟我们其他管理的部分差不多

菜单功能主要是我们在pc端用户进行登陆以后可以对于角色菜单权限进行控制,然后可以通过角色对用户进行权限的统一管理

在菜单模块之中导入其他的模块部分

javascript 复制代码
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

import { MenuService } from './menu.service';
import { MenuController } from './menu.controller';
import { Menu } from './menu.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Menu])],    // 导入实体
  controllers: [MenuController],                  // 注册控制器
  providers: [MenuService],                       // 注册服务
  exports: [MenuService]                          // 导出服务
})
export class MenuModule {}

👉menu.controller.ts 控制器

javascript 复制代码
// 列表 
  @Get('/system/menu')
  @ApiOperation({ summary: '获取列表带分页' }) // 操作描述
  @ApiQuery({ name: 'pageNum', required: false, description: 'Page number', example: 1 })  // pageNum参数
  @ApiQuery({ name: 'pageSize', required: false, description: 'Number of items per page', example: 10 })  // pageSize参数
  @ApiQuery({ name: 'menuName', required: false, description: '菜单名称', example: 'John' })  // search参数
  // 获取列表所有
  async getAll(
    @Query('menuName') menuName: string,
  ){
    // const queryParams: QueryParams = { name, phone, age, sex };
    const queryParams = { menuName };
    const ResponseData = await this.menuService.getAll(queryParams);
    return ResponseData;
  }

👉menu.service.ts 服务层

javascript 复制代码
// 通用列表
async getAll(queryParams: any) {
  // 通用分页查询
  const where = await getListAllApi(this.menuRepository,queryParams);
  return where;
}

查询一下,接口ok

👉getListAllApi通用方法

getListAllApi接口是通用的

javascript 复制代码
// 通用查询所有
export const getListAllApi = async (Repository,queryParams: any) => {
  const where = await buildQueryParams(queryParams);
  const [data, total] = await Repository.findAndCount(
    {
      where,
    }
  );
  if (data) {
    return {
      message: '查询成功!',
      code: 200,
      data: data, // 返回查询到的用户数据
      total: total,
    };
  } else {
    return {
      message: '查询失败!',
      code: 500,
      data: [], // 返回查询到的用户数据
      total: 0,
    }
  }
}

3、增加

👉menu.controller.ts 控制器

javascript 复制代码
// 创建
@ApiOperation({ summary: '新增' }) // 操作描述
@Post('/system/menu')
async create(@Body() addFormData) {
  console.log(addFormData, 'addFormData');
  return this.menuService.addOne(addFormData);
}

👉menu.service.ts 服务层

javascript 复制代码
 // 通用添加
async addOne(addFormData) {
  const resdata = await addApi(this.menuRepository, addFormData);
  return resdata;
}

尝试一下我们的新增接口

增加功能ok,并且能正确返回我们想要的东西

4、详情

详情,通过id然后查到对应的内容

👉menu.controller.ts 控制器

javascript 复制代码
// 查询单个
@Get('/system/menu/:id')
@ApiOperation({ summary: '查询单个' }) // 操作描述
async getOne(@Param('id') id: string) {
  return this.menuService.getOne(id);
}

👉menu.service.ts 服务层

javascript 复制代码
// 通用详情
async getOne(id) {
  const resdata = await getOneApi(this.menuRepository,{menuId:id});
  return resdata;
}

简单测试一下,详情接口没问题,我们采用的也是通过ID的方式进行获取的

5、修改

接下来我们完善一下我们的修改接口:

👉menu.controller.ts 控制器

javascript 复制代码
  @Put('/system/menu')
  @ApiOperation({ summary: '更新' }) // 操作描述
  async updateOne(
    @Body() updateFormData
  ) {
    console.log(updateFormData, 'updateFormData');
    // console.log(updateFormData, 'updateFormData');
    return this.menuService.updateOne(updateFormData.menuId, updateFormData);
  }

👉menu.service.ts 服务层

javascript 复制代码
// 通用更新
async updateOne(id,updateFormData) {
  const resdata = await updateOneApi(this.menuRepository,updateFormData,{menuId:id});
  return resdata;
}

简单测试一下,修改接口没问题

5、删除

👉menu.controller.ts 控制器

javascript 复制代码
// 删除
@Delete('/system/menu/:id')
@ApiOperation({ summary: '删除' }) // 操作描述
async deleteOne(@Param('id') id: number) {
  return this.menuService.deleteOne(id);
}

👉menu.service.ts 服务层

javascript 复制代码
 // 通用删除
async deleteOne(id) {
  const resdata = await deleteOneApi(this.menuRepository,{menuId:id});
  return resdata;
}

测试可以发现,我们的删除功能已经好了!

相关推荐
paopaokaka_luck27 分钟前
基于SpringBoot+Uniapp的健身饮食小程序(协同过滤算法、地图组件)
前端·javascript·vue.js·spring boot·后端·小程序·uni-app
Villiam_AY30 分钟前
Redis 缓存机制详解:原理、问题与最佳实践
开发语言·redis·后端
患得患失9491 小时前
【前端】【vscode】【.vscode/settings.json】为单个项目配置自动格式化和开发环境
前端·vscode·json
飛_1 小时前
解决VSCode无法加载Json架构问题
java·服务器·前端
YGY Webgis糕手之路4 小时前
OpenLayers 综合案例-轨迹回放
前端·经验分享·笔记·vue·web
魔尔助理顾问4 小时前
系统整理Python的循环语句和常用方法
开发语言·后端·python
90后的晨仔4 小时前
🚨XSS 攻击全解:什么是跨站脚本攻击?前端如何防御?
前端·vue.js
Ares-Wang4 小时前
JavaScript》》JS》 Var、Let、Const 大总结
开发语言·前端·javascript
90后的晨仔4 小时前
Vue 模板语法完全指南:从插值表达式到动态指令,彻底搞懂 Vue 模板语言
前端·vue.js
程序视点4 小时前
Java BigDecimal详解:小数精确计算、使用方法与常见问题解决方案
java·后端