forked from wangziqi/gongxue-base
fix: keep room capacity and beds consistent
This commit is contained in:
@@ -1,6 +1,15 @@
|
||||
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository, Like, IsNull, Not, In, LessThanOrEqual, MoreThanOrEqual } from 'typeorm';
|
||||
import {
|
||||
DataSource,
|
||||
Repository,
|
||||
Like,
|
||||
IsNull,
|
||||
Not,
|
||||
In,
|
||||
LessThanOrEqual,
|
||||
MoreThanOrEqual,
|
||||
} from 'typeorm';
|
||||
|
||||
import { Room } from '../entities/room.entity';
|
||||
import { Occupancy } from '../entities/occupancy.entity';
|
||||
@@ -19,6 +28,7 @@ export class RoomsService {
|
||||
@InjectRepository(RoomExpense) private roomExpRepo: Repository<RoomExpense>,
|
||||
@InjectRepository(Bed) private bedRepo: Repository<Bed>,
|
||||
@InjectRepository(Locker) private lockerRepo: Repository<Locker>,
|
||||
private dataSource: DataSource,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -116,9 +126,54 @@ export class RoomsService {
|
||||
}
|
||||
|
||||
async update(id: number, dto: UpdateRoomDto) {
|
||||
await this.findOne(id);
|
||||
await this.repo.update(id, dto);
|
||||
return this.repo.findOne({ where: { id } });
|
||||
return this.dataSource.transaction(async (manager) => {
|
||||
const roomRepo = manager.getRepository(Room);
|
||||
const bedRepo = manager.getRepository(Bed);
|
||||
const occupancyRepo = manager.getRepository(Occupancy);
|
||||
const room = await roomRepo.findOne({ where: { id } });
|
||||
if (!room) throw new NotFoundException('宿舍不存在');
|
||||
|
||||
if (dto.capacity !== undefined) {
|
||||
const [beds, activeOccupantCount] = await Promise.all([
|
||||
bedRepo.find({ where: { roomId: id }, order: { bedNumber: 'ASC' } }),
|
||||
occupancyRepo.count({ where: { roomId: id, checkOutDate: IsNull() } }),
|
||||
]);
|
||||
|
||||
if (dto.capacity < activeOccupantCount) {
|
||||
throw new BadRequestException(
|
||||
`额定人数不能少于当前入住人数,当前有 ${activeOccupantCount} 人入住`,
|
||||
);
|
||||
}
|
||||
if (dto.capacity < beds.length) {
|
||||
throw new BadRequestException(
|
||||
`额定人数不能少于现有床位数,当前有 ${beds.length} 张床位,请先删除多余的空闲床位`,
|
||||
);
|
||||
}
|
||||
|
||||
if (dto.capacity > beds.length) {
|
||||
const countToCreate = dto.capacity - beds.length;
|
||||
const start = this.getNextBedNumber(beds);
|
||||
const newBeds = Array.from({ length: countToCreate }, (_, index) =>
|
||||
bedRepo.create({ roomId: id, bedNumber: `${start + index}号床` }),
|
||||
);
|
||||
await bedRepo.save(newBeds);
|
||||
}
|
||||
|
||||
if (
|
||||
dto.status === undefined &&
|
||||
room.status !== 'maintenance' &&
|
||||
room.status !== 'archived'
|
||||
) {
|
||||
dto = {
|
||||
...dto,
|
||||
status: activeOccupantCount >= dto.capacity ? 'full' : 'available',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
await roomRepo.update(id, dto);
|
||||
return roomRepo.findOne({ where: { id } });
|
||||
});
|
||||
}
|
||||
|
||||
async remove(id: number) {
|
||||
@@ -413,6 +468,14 @@ export class RoomsService {
|
||||
await this.bedRepo.save(beds);
|
||||
}
|
||||
|
||||
private getNextBedNumber(beds: Pick<Bed, 'bedNumber'>[]): number {
|
||||
const numbers = beds.map((bed) => {
|
||||
const match = bed.bedNumber.match(/^\d+/);
|
||||
return match ? parseInt(match[0], 10) : 0;
|
||||
});
|
||||
return numbers.length > 0 ? Math.max(...numbers) + 1 : 1;
|
||||
}
|
||||
|
||||
private async assertCanAddBeds(room: Room, count: number): Promise<void> {
|
||||
const existingCount = await this.bedRepo.count({ where: { roomId: room.id } });
|
||||
this.assertCanAddBedsFromCount(room, existingCount, count);
|
||||
@@ -421,7 +484,9 @@ export class RoomsService {
|
||||
private assertCanAddBedsFromCount(room: Room, existingCount: number, count: number): void {
|
||||
const remaining = Math.max((room.capacity ?? 0) - existingCount, 0);
|
||||
if (count > remaining) {
|
||||
throw new BadRequestException(`床位不能超过额定人数,当前已有 ${existingCount} 张,额定 ${room.capacity} 张,最多还能添加 ${remaining} 张`);
|
||||
throw new BadRequestException(
|
||||
`床位不能超过额定人数,当前已有 ${existingCount} 张,额定 ${room.capacity} 张,最多还能添加 ${remaining} 张`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user