feat: integrate CampusScope.filter() into all business services (12 services + 12 modules)

This commit is contained in:
2026-07-05 23:58:51 +08:00
parent eeae06fe30
commit cd6364268d
40 changed files with 949 additions and 172 deletions

View File

@@ -1,6 +1,7 @@
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Like, IsNull, Not, In } from 'typeorm';
import { CampusScope } from '../common/campus-scope';
import { Room } from '../entities/room.entity';
import { Occupancy } from '../entities/occupancy.entity';
import { RoomExpense } from '../entities/room-expense.entity';
@@ -12,6 +13,7 @@ export class RoomsService {
@InjectRepository(Room) private repo: Repository<Room>,
@InjectRepository(Occupancy) private occRepo: Repository<Occupancy>,
@InjectRepository(RoomExpense) private roomExpRepo: Repository<RoomExpense>,
private readonly scope: CampusScope,
) {}
/**
@@ -62,7 +64,8 @@ export class RoomsService {
const where: any = {};
if (query?.building) where.building = query.building;
if (!query?.includeArchived) where.status = Not('archived');
return this.repo.find({ where, order: { roomNumber: 'ASC' } });
const filteredWhere = await this.scope.filter(where);
return this.repo.find({ where: filteredWhere, order: { roomNumber: 'ASC' } });
}
async findOne(id: number) {
@@ -84,7 +87,8 @@ export class RoomsService {
async getRoomOverview(query?: { includeArchived?: boolean }) {
const where: any = {};
if (!query?.includeArchived) where.status = Not('archived');
const rooms = await this.repo.find({ where, order: { building: 'ASC', roomNumber: 'ASC' } });
const filteredWhere = await this.scope.filter(where);
const rooms = await this.repo.find({ where: filteredWhere, order: { building: 'ASC', roomNumber: 'ASC' } });
const result: any[] = [];
for (const room of rooms) {
const count = await this.occRepo.count({
@@ -161,12 +165,12 @@ export class RoomsService {
async getRoomVisual() {
const rooms = await this.repo.find({
where: { status: Not('archived') },
where: await this.scope.filter({ status: Not('archived') }),
order: { building: 'ASC', roomNumber: 'ASC' },
});
const occupancies = await this.occRepo.find({
where: { checkOutDate: IsNull() },
relations: ['student'],
where: await this.scope.filter({ checkOutDate: IsNull() }),
relations: ['student', 'tenant'],
order: { checkInDate: 'ASC' },
});
@@ -188,6 +192,8 @@ export class RoomsService {
days,
organization: occ.student?.organization || null,
supervisor: occ.student?.supervisor || null,
tenantName: occ.tenant?.name || null,
tenantColor: occ.tenant?.color || null,
});
}
@@ -209,6 +215,9 @@ export class RoomsService {
orgLabel = `存在${orgs.join('、')}人员`;
}
}
// 计算租户颜色:所有住户同一租户则使用该颜色
const tenantColors = [...new Set(occ.map((o: any) => o.tenantColor).filter(Boolean))];
const tenantColor: string | null = tenantColors.length === 1 ? tenantColors[0] : null;
return {
id: room.id,
roomNumber: room.roomNumber,
@@ -219,6 +228,7 @@ export class RoomsService {
currentCount: occ.length,
occupants: occ,
orgLabel,
tenantColor,
};
}),
};
@@ -231,6 +241,8 @@ export class RoomsService {
floor?: number;
capacity?: number;
roomType?: string;
rentalCategory?: string;
monthlyRate?: number;
}[],
) {
let imported = 0;
@@ -254,6 +266,8 @@ export class RoomsService {
floor: row.floor || parsed.floor || undefined,
capacity: row.capacity || parsed.capacity || 4,
roomType: row.roomType || parsed.roomType || undefined,
rentalCategory: row.rentalCategory || undefined,
monthlyRate: row.monthlyRate ?? undefined,
}),
);
imported++;