Skip to content

Nest 会议室模块

会议室模块 meeting.module.ts

ts
import { Module } from "@nestjs/common";
import { MeetingService } from "./meeting.service";
import { MeetingController } from "./meeting.controller";
// 增加Excel 动态模块
import { ExcelModule } from "../../commonModules/excel/excel.module";
// 增加上传模块
import { UploadModule } from "../../commonModules/upload/upload.module";
// 增加邮箱模块
import { EmailModule } from "../../commonModules/email/email.module";
// 增加加密解密模块
import { CryptoModule } from "../../commonModules/crypto/crypto.module";
@Module({
  imports: [
    ExcelModule.forRoot({ name: "testdemoexcel" }),
    UploadModule,
    EmailModule,
    CryptoModule,
  ],
  controllers: [MeetingController],
  providers: [MeetingService],
})
export class MeetingModule {}

会议室模块 meeting.controller.ts

ts
import {
  Controller,
  Get,
  Post,
  Body,
  Patch,
  Param,
  Delete,
} from "@nestjs/common";
import { MeetingService } from "./meeting.service";

// 引入dto
import { CreateMeetingDto } from "./dto/create-meeting.dto";
import { UpdateMeetingDto } from "./dto/update-meeting.dto";
import { SearchMeetingDto } from "./dto/search-meeting.dto";
import { GetListDto } from "../user/dto/getList.dto";
import { DeleteMeetingDto } from "./dto/delete-meeting.dto";
@Controller({
  path: "meeting",
  version: ["1"],
})
export class MeetingController {
  constructor(private readonly meetingService: MeetingService) {}

  // 新增会议室
  /**
   *
   * @api {POST} /v1/meeting/create 创建会议室
   * @apiName 创建会议室
   * @apiGroup meeting
   * @apiVersion  0.0.0
   *
   *
   * @apiBody  {String} name 会议室名称
   * @apiBody  {number} capacity 会议室人数
   * @apiBody  {String} location 地点
   * @apiBody  {String} equipment 设备
   * @apiBody  {String} description 描述
   *
   * @apiSuccess {Object} response 响应数据
   * @apiSuccess {Number} response.code 200
   * @apiSuccess {String} response.message 操作成功
   * @apiSuccess {String} response.data 发送成功
   *
   * @apiParamExample  {type} Request-Example:
   *  {
   *    "name":"会议室一号",
   *    "capacity":20,
   *    "location":"1号楼1层101室",
   *    "equipment":"投影仪,白板",
   *    "description":"这是开发组顶的"
   *  }
   *
   *
   * @apiSuccessExample {type} Success-Response:
   * {
   *     code : 200
   *     message : 操作成功
   *     data : 发送成功
   * }
   *
   *
   */
  @Post("create")
  async create(@Body() createMeetingDto: CreateMeetingDto) {
    const result = await this.meetingService.create(createMeetingDto);
    return result;
  }

  // 更新

  /**
   *
   * @api {POST} /v1/meeting/update 更新会议室
   * @apiName 更新会议室
   * @apiGroup meeting
   * @apiVersion  0.0.0
   *
   * @apiBody  {Number} id 会议室Id
   * @apiBody  {String} name 会议室名称
   * @apiBody  {number} capacity 会议室人数
   * @apiBody  {String} location 地点
   * @apiBody  {String} equipment 设备
   * @apiBody  {String} description 描述
   *
   * @apiSuccess {Object} response 响应数据
   * @apiSuccess {Number} response.code 200
   * @apiSuccess {String} response.message 操作成功
   * @apiSuccess {String} response.data 更新成功
   *
   * @apiParamExample  {type} Request-Example:
   *  {
   *    "id":1,
   *    "name":"会议室一号",
   *    "capacity":20,
   *    "location":"1号楼1层101室",
   *    "equipment":"投影仪,白板",
   *    "description":"这是开发组顶的"
   *  }
   *
   *
   * @apiSuccessExample {type} Success-Response:
   * {
   *     code : 200
   *     message : 操作成功
   *     data : 发送成功
   * }
   *
   *
   */
  @Post("update")
  async update(@Body() updateMeetingDto: UpdateMeetingDto) {
    const result = await this.meetingService.update(updateMeetingDto);
    return result;
  }

  /**
   *
   * @api {POST} /v1/meeting/search 搜索会议室
   * @apiName 搜索会议室
   * @apiGroup meeting
   * @apiVersion  0.0.0
   *
   * @apiBody  {String} searchContent 会议室名字
   * @apiBody  {Number} page 当前页
   * @apiBody  {number} pageSize 每页分的个数
   *
   * @apiSuccess {Object} response 响应数据
   * @apiSuccess {Number} response.code 200
   * @apiSuccess {String} response.message 操作成功
   * @apiSuccess {Object} response.data 更新成功
   * @apiSuccess {Object[]} response.data.list 数据集合
   * @apiSuccess {Number} response.data.list.id 会议室编号
   * @apiSuccess {String} response.data.list.name 会议室名称
   * @apiSuccess {Number} response.data.list.capacity 会议室人数
   * @apiSuccess {String} response.data.list.location 地点
   * @apiSuccess {String} response.data.list.equipment 设备
   * @apiSuccess {String} response.data.list.description 描述
   * @apiSuccess {Object} response.data.pagination 数据集合
   * @apiSuccess {Number} response.data.pagination.total 总数
   * @apiSuccess {Number} response.data.pagination.page 当前页
   * @apiSuccess {Number} response.data.pagination.pageSize 每页个数
   * @apiSuccess {Number} response.data.pagination.totalPages 总页数
   * @apiSuccess {Boolean} response.data.pagination.hasNextPage 是否有下一页
   * @apiSuccess {Boolean} response.data.pagination.hasPreviousPage 是否有上一页
   * @apiParamExample  {type} Request-Example:
   *  {
   *    "id":1,
   *    "name":"会议室一号",
   *    "capacity":20,
   *    "location":"1号楼1层101室",
   *    "equipment":"投影仪,白板",
   *    "description":"这是开发组顶的"
   *  }
   *
   *
   * @apiSuccessExample {type} Success-Response:
   * {
   *     code : 200
   *     message : 操作成功
   *     data: {
   *          list: [
   *   {
   *     "id": 1,
   *     "name": "会议室一号",
   *     "capacity": 20,
   *     "location": "1号楼1层101室",
   *     "equipment": "投影仪,白板",
   *     "description": "这是开发组顶的",
   *     "is_booked": 1,
   *     "create_time": "2025-12-31T02:21:19.000Z",
   *     "upadte_time": "2025-12-31T02:21:19.000Z"
   *   }
   * ],
   *  "pagination": {
   *   "total": 1,
   *   "page": 1,
   *   "pageSize": 10,
   *   "totalPages": 1,
   *   "hasNextPage": false,
   *   "hasPreviousPage": false
   *      }
   *   }
   * }
   *
   *
   */
  @Post("search")
  async search(@Body() SearchMeetingDto: SearchMeetingDto) {
    const result = await this.meetingService.search(SearchMeetingDto);
    return result;
  }

  /**
   *
   * @api {POST} /v1/meeting/getlist 获取会议室列表
   * @apiName 获取会议室列表
   * @apiGroup meeting
   * @apiVersion  0.0.0
   *
   * @apiBody  {Number} page 当前页
   * @apiBody  {number} pageSize 每页分的个数
   *
   * @apiSuccess {Object} response 响应数据
   * @apiSuccess {Number} response.code 200
   * @apiSuccess {String} response.message 操作成功
   * @apiSuccess {Object} response.data 获取数据
   * @apiSuccess {Object[]} response.data.list 数据集合
   * @apiSuccess {Number} response.data.list.id 会议室编号
   * @apiSuccess {String} response.data.list.name 会议室名称
   * @apiSuccess {Number} response.data.list.capacity 会议室人数
   * @apiSuccess {String} response.data.list.location 地点
   * @apiSuccess {String} response.data.list.equipment 设备
   * @apiSuccess {String} response.data.list.description 描述
   * @apiSuccess {Object} response.data.pagination 数据集合
   * @apiSuccess {Number} response.data.pagination.total 总数
   * @apiSuccess {Number} response.data.pagination.page 当前页
   * @apiSuccess {Number} response.data.pagination.pageSize 每页个数
   * @apiSuccess {Number} response.data.pagination.totalPages 总页数
   * @apiSuccess {Boolean} response.data.pagination.hasNextPage 是否有下一页
   * @apiSuccess {Boolean} response.data.pagination.hasPreviousPage 是否有上一页
   * @apiParamExample  {type} Request-Example:
   *  {
   *    "id":1,
   *    "name":"会议室一号",
   *    "capacity":20,
   *    "location":"1号楼1层101室",
   *    "equipment":"投影仪,白板",
   *    "description":"这是开发组顶的"
   *  }
   *
   *
   * @apiSuccessExample {type} Success-Response:
   * {
   *     code : 200
   *     message : 操作成功
   *     data: {
   *          list: [
   *   {
   *     "id": 1,
   *     "name": "会议室一号",
   *     "capacity": 20,
   *     "location": "1号楼1层101室",
   *     "equipment": "投影仪,白板",
   *     "description": "这是开发组顶的",
   *     "is_booked": 1,
   *     "create_time": "2025-12-31T02:21:19.000Z",
   *     "upadte_time": "2025-12-31T02:21:19.000Z"
   *   }
   * ],
   *  "pagination": {
   *   "total": 1,
   *   "page": 1,
   *   "pageSize": 10,
   *   "totalPages": 1,
   *   "hasNextPage": false,
   *   "hasPreviousPage": false
   *      }
   *   }
   * }
   *
   *
   */

  @Get("getlist")
  async getlist(@Body() body: GetListDto) {
    const result = await this.meetingService.getlist(body);
    return result;
  }

  @Post("delete")
  async delete(@Body() body: DeleteMeetingDto) {
    const result = await this.meetingService.delete(body);
    return result;
  }
}

会议室 meeting.service.ts

ts
import { Inject, Injectable } from "@nestjs/common";
import { PrismadbService } from "../../commonModules/prisma/prisma.service";
import { RedisService } from "../../commonModules/redis/redis.service";
import { JwtAllService } from "../../commonModules/jwt/jwt.service";
import { ExcelService } from "../../commonModules/excel/excel.service";
import { UploadService } from "../../commonModules/upload/upload.service";
import { CryptoService } from "../../commonModules/crypto/crypto.service";
// 引入dto
import { CreateMeetingDto } from "./dto/create-meeting.dto";
import { UpdateMeetingDto } from "./dto/update-meeting.dto";
import { SearchMeetingDto } from "./dto/search-meeting.dto";
import { GetListDto } from "../user/dto/getList.dto";
import { DeleteMeetingDto } from "./dto/delete-meeting.dto";
// 抛出异常
import { GlobalCheckException } from "../../common/globalcheck.exception";
@Injectable()
export class MeetingService {
  // 数据库
  @Inject()
  private readonly prisma: PrismadbService;

  // redis
  @Inject()
  private readonly redisService: RedisService;

  // JWT
  @Inject()
  private readonly jwtAllService: JwtAllService;

  // Excel
  @Inject()
  private readonly ExcelService: ExcelService;

  // 上传

  @Inject()
  private readonly UploadService: UploadService;

  // 加密解密
  @Inject()
  private readonly cryptoService: CryptoService;

  // 创建会议
  async create(createMeeting: CreateMeetingDto) {
    // 先去查询
    const meetingRoom = await this.prisma.meeting_rooms.findFirst({
      where: { name: createMeeting.name },
    });
    if (!meetingRoom) {
      const result = await this.prisma.meeting_rooms.create({
        data: createMeeting,
      });
      if (result) {
        return "会议创建成功";
      }
    } else {
      throw new GlobalCheckException("会议室已存在");
    }
  }

  // 更新会议
  async update(UpdateMeeting: UpdateMeetingDto) {
    // 先去查询
    const meetingRoom = await this.prisma.meeting_rooms.findFirst({
      where: { id: UpdateMeeting.id },
    });
    // 找到了就更新
    if (meetingRoom) {
      // 再去查询名称是否重复
      const meetingRoomName = await this.prisma.meeting_rooms.findFirst({
        where: { name: UpdateMeeting.name },
      });
      if (!meetingRoomName) {
        const result = await this.prisma.meeting_rooms.update({
          where: { id: UpdateMeeting.id },
          data: UpdateMeeting,
        });
        if (result) {
          return "会议更新成功";
        } else {
          throw new GlobalCheckException("会议更新失败");
        }
      } else {
        throw new GlobalCheckException("会议名称已经存在");
      }
    } else {
      throw new GlobalCheckException("会议室不存在");
    }
  }

  // 搜索会议
  async search(searchMeeting: SearchMeetingDto) {
    const result = await this.prisma.meeting_rooms.paginate(
      searchMeeting.page,
      searchMeeting.pageSize || 10,
      {
        where: {
          name: {
            contains: searchMeeting.searchContent,
          },
        },
        orderBy: {
          id: "desc",
        },
      }
    );
    return result;
  }

  // 获取列表
  async getlist(data: GetListDto) {
    const result = await this.prisma.meeting_rooms.paginate(
      data.page,
      data.pageSize || 10,
      {
        orderBy: {
          id: "desc",
        },
      }
    );
    return result;
  }

  // 删除会议
  async delete(data: DeleteMeetingDto) {
    // 先去查询
    const meetingRoom = await this.prisma.meeting_rooms.findFirst({
      where: { id: data.id },
    });
    // 找到了就删除
    if (meetingRoom) {
      const result = await this.prisma.meeting_rooms.delete({
        where: { id: data.id },
      });
      if (result) {
        return "会议删除成功";
      } else {
        throw new GlobalCheckException("会议删除失败");
      }
    } else {
      throw new GlobalCheckException("会议室不存在");
    }
  }
}

会议室模块 DTO

create-meeting.dto.ts

ts
import { IsString, IsNotEmpty, MaxLength } from "class-validator";
export class CreateMeetingDto {
  @IsNotEmpty({
    message: "会议室名称不能为空",
  })
  @MaxLength(10, {
    message: "会议室名称最长为 10 字符",
  })
  name: string;

  @IsNotEmpty({
    message: "容量不能为空",
  })
  capacity: number;

  @IsNotEmpty({
    message: "位置不能为空",
  })
  @MaxLength(50, {
    message: "位置最长为 50 字符",
  })
  location: string;

  @IsNotEmpty({
    message: "设备不能为空",
  })
  @MaxLength(50, {
    message: "设备最长为 50 字符",
  })
  equipment: string;

  @IsNotEmpty({
    message: "描述不能为空",
  })
  @MaxLength(100, {
    message: "描述最长为 100 字符",
  })
  description: string;
}

delete-meeting.dto.ts

ts
import { IsString, IsNotEmpty, MaxLength } from "class-validator";
export class DeleteMeetingDto {
  @IsNotEmpty({
    message: "id不能为空",
  })
  id: number;
}

getlist-meeting.dto.ts

ts
import { IsString, IsNotEmpty, MaxLength } from "class-validator";
export class GetListMeetingDto {
  @IsNotEmpty({
    message: "page不能为空",
  })
  page: number;

  @IsNotEmpty({
    message: "pageSize不能为空",
  })
  pageSize: number;
}

search-meeting.dto.ts

ts
import { IsString, IsNotEmpty, MaxLength } from "class-validator";
export class SearchMeetingDto {
  @IsNotEmpty({
    message: "搜索内容不能为空",
  })
  searchContent: string;

  @IsNotEmpty({
    message: "page不能为空",
  })
  page: number;

  @IsNotEmpty({
    message: "pageSize不能为空",
  })
  pageSize: number;
}

update-meeting.dto.ts

ts
import { IsString, IsNotEmpty, MaxLength } from "class-validator";
export class UpdateMeetingDto {
  @IsNotEmpty({
    message: "id不能为空",
  })
  id: number;

  @IsNotEmpty({
    message: "会议室名称不能为空",
  })
  @MaxLength(10, {
    message: "会议室名称最长为 10 字符",
  })
  name: string;

  @IsNotEmpty({
    message: "容量不能为空",
  })
  capacity: number;

  @IsNotEmpty({
    message: "位置不能为空",
  })
  @MaxLength(50, {
    message: "位置最长为 50 字符",
  })
  location: string;

  @IsNotEmpty({
    message: "设备不能为空",
  })
  @MaxLength(50, {
    message: "设备最长为 50 字符",
  })
  equipment: string;

  @IsNotEmpty({
    message: "描述不能为空",
  })
  @MaxLength(100, {
    message: "描述最长为 100 字符",
  })
  description: string;
}