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;
}