forked from wangziqi/gongxue-base
feat: add Bed and Locker CRUD to RoomsService
This commit is contained in:
@@ -3,13 +3,15 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
|||||||
import { Room } from '../entities/room.entity';
|
import { Room } from '../entities/room.entity';
|
||||||
import { Occupancy } from '../entities/occupancy.entity';
|
import { Occupancy } from '../entities/occupancy.entity';
|
||||||
import { RoomExpense } from '../entities/room-expense.entity';
|
import { RoomExpense } from '../entities/room-expense.entity';
|
||||||
|
import { Bed } from '../entities/bed.entity';
|
||||||
|
import { Locker } from '../entities/locker.entity';
|
||||||
import { RoomsService } from './rooms.service';
|
import { RoomsService } from './rooms.service';
|
||||||
import { RoomsController } from './rooms.controller';
|
import { RoomsController } from './rooms.controller';
|
||||||
import { OperationLogsModule } from '../operation-logs/operation-logs.module';
|
import { OperationLogsModule } from '../operation-logs/operation-logs.module';
|
||||||
import { CommonModule } from '../common/common.module';
|
import { CommonModule } from '../common/common.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [TypeOrmModule.forFeature([Room, Occupancy, RoomExpense]), OperationLogsModule, CommonModule],
|
imports: [TypeOrmModule.forFeature([Room, Occupancy, RoomExpense, Bed, Locker]), OperationLogsModule, CommonModule],
|
||||||
controllers: [RoomsController],
|
controllers: [RoomsController],
|
||||||
providers: [RoomsService],
|
providers: [RoomsService],
|
||||||
exports: [RoomsService],
|
exports: [RoomsService],
|
||||||
|
|||||||
@@ -5,7 +5,11 @@ import { CampusScope } from '../common/campus-scope';
|
|||||||
import { Room } from '../entities/room.entity';
|
import { Room } from '../entities/room.entity';
|
||||||
import { Occupancy } from '../entities/occupancy.entity';
|
import { Occupancy } from '../entities/occupancy.entity';
|
||||||
import { RoomExpense } from '../entities/room-expense.entity';
|
import { RoomExpense } from '../entities/room-expense.entity';
|
||||||
|
import { Bed } from '../entities/bed.entity';
|
||||||
|
import { Locker } from '../entities/locker.entity';
|
||||||
import { CreateRoomDto, UpdateRoomDto } from './dto/room.dto';
|
import { CreateRoomDto, UpdateRoomDto } from './dto/room.dto';
|
||||||
|
import { CreateBedDto, UpdateBedDto, BatchCreateBedDto } from './dto/bed.dto';
|
||||||
|
import { CreateLockerDto, UpdateLockerDto, BatchCreateLockerDto } from './dto/locker.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RoomsService {
|
export class RoomsService {
|
||||||
@@ -13,7 +17,8 @@ export class RoomsService {
|
|||||||
@InjectRepository(Room) private repo: Repository<Room>,
|
@InjectRepository(Room) private repo: Repository<Room>,
|
||||||
@InjectRepository(Occupancy) private occRepo: Repository<Occupancy>,
|
@InjectRepository(Occupancy) private occRepo: Repository<Occupancy>,
|
||||||
@InjectRepository(RoomExpense) private roomExpRepo: Repository<RoomExpense>,
|
@InjectRepository(RoomExpense) private roomExpRepo: Repository<RoomExpense>,
|
||||||
private readonly scope: CampusScope,
|
@InjectRepository(Bed) private bedRepo: Repository<Bed>,
|
||||||
|
@InjectRepository(Locker) private lockerRepo: Repository<Locker>,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -320,4 +325,122 @@ export class RoomsService {
|
|||||||
skipped,
|
skipped,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── 床位管理 ──
|
||||||
|
|
||||||
|
async getRoomBeds(roomId: number): Promise<Bed[]> {
|
||||||
|
const room = await this.repo.findOne({ where: { id: roomId } });
|
||||||
|
if (!room) throw new NotFoundException('宿舍不存在');
|
||||||
|
return this.bedRepo.find({ where: { roomId }, order: { bedNumber: 'ASC' } });
|
||||||
|
}
|
||||||
|
|
||||||
|
async getRoomAvailableBeds(roomId: number): Promise<Bed[]> {
|
||||||
|
const room = await this.repo.findOne({ where: { id: roomId } });
|
||||||
|
if (!room) throw new NotFoundException('宿舍不存在');
|
||||||
|
return this.bedRepo.find({ where: { roomId, status: 'available' }, order: { bedNumber: 'ASC' } });
|
||||||
|
}
|
||||||
|
|
||||||
|
async createBed(roomId: number, dto: CreateBedDto): Promise<Bed> {
|
||||||
|
const room = await this.repo.findOne({ where: { id: roomId } });
|
||||||
|
if (!room) throw new NotFoundException('宿舍不存在');
|
||||||
|
if (room.status === 'archived') throw new BadRequestException('已归档宿舍不能添加床位');
|
||||||
|
const existing = await this.bedRepo.findOne({ where: { roomId, bedNumber: dto.bedNumber } });
|
||||||
|
if (existing) throw new BadRequestException('该床位编号已存在');
|
||||||
|
const bed = this.bedRepo.create({ ...dto, roomId });
|
||||||
|
return this.bedRepo.save(bed);
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateBed(roomId: number, id: number, dto: UpdateBedDto): Promise<Bed> {
|
||||||
|
const bed = await this.bedRepo.findOne({ where: { id, roomId } });
|
||||||
|
if (!bed) throw new NotFoundException('床位不存在');
|
||||||
|
// 不允许将 occupied 的床位改为 maintenance
|
||||||
|
if (dto.status === 'maintenance' && bed.status === 'occupied') {
|
||||||
|
throw new BadRequestException('该床位有人入住,请先退宿');
|
||||||
|
}
|
||||||
|
// 编号唯一性检查
|
||||||
|
if (dto.bedNumber && dto.bedNumber !== bed.bedNumber) {
|
||||||
|
const dup = await this.bedRepo.findOne({ where: { roomId, bedNumber: dto.bedNumber } });
|
||||||
|
if (dup) throw new BadRequestException('该床位编号已存在');
|
||||||
|
}
|
||||||
|
Object.assign(bed, dto);
|
||||||
|
return this.bedRepo.save(bed);
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteBed(roomId: number, id: number): Promise<void> {
|
||||||
|
const bed = await this.bedRepo.findOne({ where: { id, roomId } });
|
||||||
|
if (!bed) throw new NotFoundException('床位不存在');
|
||||||
|
if (bed.status === 'occupied') throw new BadRequestException('该床位有人入住,无法删除');
|
||||||
|
await this.bedRepo.remove(bed);
|
||||||
|
}
|
||||||
|
|
||||||
|
async batchCreateBeds(roomId: number, dto: BatchCreateBedDto): Promise<Bed[]> {
|
||||||
|
const room = await this.repo.findOne({ where: { id: roomId } });
|
||||||
|
if (!room) throw new NotFoundException('宿舍不存在');
|
||||||
|
if (room.status === 'archived') throw new BadRequestException('已归档宿舍不能添加床位');
|
||||||
|
const existing = await this.bedRepo.count({ where: { roomId } });
|
||||||
|
const start = existing + 1;
|
||||||
|
const beds: Bed[] = [];
|
||||||
|
for (let i = 0; i < dto.count; i++) {
|
||||||
|
beds.push(this.bedRepo.create({ roomId, bedNumber: `${start + i}号床` }));
|
||||||
|
}
|
||||||
|
return this.bedRepo.save(beds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 柜子管理 ──
|
||||||
|
|
||||||
|
async getRoomLockers(roomId: number): Promise<Locker[]> {
|
||||||
|
const room = await this.repo.findOne({ where: { id: roomId } });
|
||||||
|
if (!room) throw new NotFoundException('宿舍不存在');
|
||||||
|
return this.lockerRepo.find({ where: { roomId }, order: { lockerNumber: 'ASC' } });
|
||||||
|
}
|
||||||
|
|
||||||
|
async getRoomAvailableLockers(roomId: number): Promise<Locker[]> {
|
||||||
|
const room = await this.repo.findOne({ where: { id: roomId } });
|
||||||
|
if (!room) throw new NotFoundException('宿舍不存在');
|
||||||
|
return this.lockerRepo.find({ where: { roomId, status: 'available' }, order: { lockerNumber: 'ASC' } });
|
||||||
|
}
|
||||||
|
|
||||||
|
async createLocker(roomId: number, dto: CreateLockerDto): Promise<Locker> {
|
||||||
|
const room = await this.repo.findOne({ where: { id: roomId } });
|
||||||
|
if (!room) throw new NotFoundException('宿舍不存在');
|
||||||
|
if (room.status === 'archived') throw new BadRequestException('已归档宿舍不能添加柜子');
|
||||||
|
const existing = await this.lockerRepo.findOne({ where: { roomId, lockerNumber: dto.lockerNumber } });
|
||||||
|
if (existing) throw new BadRequestException('该柜子编号已存在');
|
||||||
|
const locker = this.lockerRepo.create({ ...dto, roomId });
|
||||||
|
return this.lockerRepo.save(locker);
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateLocker(roomId: number, id: number, dto: UpdateLockerDto): Promise<Locker> {
|
||||||
|
const locker = await this.lockerRepo.findOne({ where: { id, roomId } });
|
||||||
|
if (!locker) throw new NotFoundException('柜子不存在');
|
||||||
|
if (dto.status === 'maintenance' && locker.status === 'occupied') {
|
||||||
|
throw new BadRequestException('该柜子有人占用,请先释放');
|
||||||
|
}
|
||||||
|
if (dto.lockerNumber && dto.lockerNumber !== locker.lockerNumber) {
|
||||||
|
const dup = await this.lockerRepo.findOne({ where: { roomId, lockerNumber: dto.lockerNumber } });
|
||||||
|
if (dup) throw new BadRequestException('该柜子编号已存在');
|
||||||
|
}
|
||||||
|
Object.assign(locker, dto);
|
||||||
|
return this.lockerRepo.save(locker);
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteLocker(roomId: number, id: number): Promise<void> {
|
||||||
|
const locker = await this.lockerRepo.findOne({ where: { id, roomId } });
|
||||||
|
if (!locker) throw new NotFoundException('柜子不存在');
|
||||||
|
if (locker.status === 'occupied') throw new BadRequestException('该柜子有人占用,无法删除');
|
||||||
|
await this.lockerRepo.remove(locker);
|
||||||
|
}
|
||||||
|
|
||||||
|
async batchCreateLockers(roomId: number, dto: BatchCreateLockerDto): Promise<Locker[]> {
|
||||||
|
const room = await this.repo.findOne({ where: { id: roomId } });
|
||||||
|
if (!room) throw new NotFoundException('宿舍不存在');
|
||||||
|
if (room.status === 'archived') throw new BadRequestException('已归档宿舍不能添加柜子');
|
||||||
|
const existing = await this.lockerRepo.count({ where: { roomId } });
|
||||||
|
const start = existing + 1;
|
||||||
|
const lockers: Locker[] = [];
|
||||||
|
for (let i = 0; i < dto.count; i++) {
|
||||||
|
lockers.push(this.lockerRepo.create({ roomId, lockerNumber: `${start + i}号柜` }));
|
||||||
|
}
|
||||||
|
return this.lockerRepo.save(lockers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user