fix: 修正换宿当天查寝归属
All checks were successful
CI / check (pull_request) Successful in 3m8s

This commit is contained in:
2026-07-22 15:18:12 +08:00
parent 7ffc573d2e
commit a9009f86fb
4 changed files with 41 additions and 14 deletions

View File

@@ -1,13 +1,14 @@
import { BadRequestException, Injectable, Logger, OnApplicationBootstrap } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
import { InjectRepository } from '@nestjs/typeorm';
import { DataSource, EntityManager, IsNull, LessThanOrEqual, MoreThanOrEqual, Repository } from 'typeorm';
import { DataSource, EntityManager, Repository } from 'typeorm';
import { Bed } from '../entities/bed.entity';
import { Occupancy } from '../entities/occupancy.entity';
import { Room } from '../entities/room.entity';
import { RoomInspection } from '../entities/room-inspection.entity';
import { RoomInspectionDetail } from '../entities/room-inspection-detail.entity';
import { OperationLogsService } from '../operation-logs/operation-logs.service';
import { occupancyWhereOnDate } from './room-occupancy-date';
interface InspectorIdentity {
id?: number;
@@ -211,10 +212,7 @@ export class RoomInspectionsService implements OnApplicationBootstrap {
private findOccupanciesForDate(manager: EntityManager, roomId: number, date: string) {
return manager.getRepository(Occupancy).find({
where: [
{ roomId, checkInDate: LessThanOrEqual(date), checkOutDate: IsNull() },
{ roomId, checkInDate: LessThanOrEqual(date), checkOutDate: MoreThanOrEqual(date) },
],
where: occupancyWhereOnDate(date, roomId),
relations: ['student', 'bed'],
order: { id: 'ASC' },
});
@@ -222,10 +220,7 @@ export class RoomInspectionsService implements OnApplicationBootstrap {
private findAllOccupanciesForDate(manager: EntityManager, date: string) {
return manager.getRepository(Occupancy).find({
where: [
{ checkInDate: LessThanOrEqual(date), checkOutDate: IsNull() },
{ checkInDate: LessThanOrEqual(date), checkOutDate: MoreThanOrEqual(date) },
],
where: occupancyWhereOnDate(date),
relations: ['student', 'bed'],
order: { roomId: 'ASC', id: 'ASC' },
});

View File

@@ -0,0 +1,22 @@
import { occupancyWhereOnDate } from './room-occupancy-date';
describe('occupancyWhereOnDate', () => {
it('treats checkout date as the first day no longer occupying the old room', () => {
const where = occupancyWhereOnDate('2026-07-22', 10);
expect(where).toHaveLength(2);
expect(where[0]).toEqual(
expect.objectContaining({ roomId: 10, checkInDate: expect.anything(), checkOutDate: expect.anything() }),
);
expect(where[1]).toEqual(
expect.objectContaining({ roomId: 10, checkInDate: expect.anything(), checkOutDate: expect.anything() }),
);
expect(String((where[1] as any).checkOutDate._type)).toBe('moreThan');
expect((where[1] as any).checkOutDate._value).toBe('2026-07-22');
});
it('can query all rooms for automatic settlement', () => {
const where = occupancyWhereOnDate('2026-07-22');
expect(where.every((condition) => condition.roomId === undefined)).toBe(true);
});
});

View File

@@ -0,0 +1,13 @@
import { FindOptionsWhere, IsNull, LessThanOrEqual, MoreThan } from 'typeorm';
import { Occupancy } from '../entities/occupancy.entity';
export function occupancyWhereOnDate(
date: string,
roomId?: number,
): FindOptionsWhere<Occupancy>[] {
const scope = roomId === undefined ? {} : { roomId };
return [
{ ...scope, checkInDate: LessThanOrEqual(date), checkOutDate: IsNull() },
{ ...scope, checkInDate: LessThanOrEqual(date), checkOutDate: MoreThan(date) },
];
}

View File

@@ -8,7 +8,6 @@ import {
Not,
In,
LessThanOrEqual,
MoreThanOrEqual,
} from 'typeorm';
import { Room } from '../entities/room.entity';
@@ -20,6 +19,7 @@ import { CreateRoomDto, UpdateRoomDto } from './dto/room.dto';
import { CreateBedDto, UpdateBedDto, BatchCreateBedDto } from './dto/bed.dto';
import { CreateLockerDto, UpdateLockerDto, BatchCreateLockerDto } from './dto/locker.dto';
import { RoomInspectionsService } from './room-inspections.service';
import { occupancyWhereOnDate } from './room-occupancy-date';
@Injectable()
export class RoomsService {
@@ -246,10 +246,7 @@ export class RoomsService {
});
const occupancies = await this.occRepo.find({
where: [
{ checkInDate: LessThanOrEqual(targetDate), checkOutDate: IsNull() },
{ checkInDate: LessThanOrEqual(targetDate), checkOutDate: MoreThanOrEqual(targetDate) },
],
where: occupancyWhereOnDate(targetDate),
relations: ['student', 'student.organization', 'responsibleOrganization', 'bed'],
order: { checkInDate: 'ASC' },
});