refactor(server): remove Department/UserDepartment entities, CampusScope, and departmentId from all entities

- Delete department.entity.ts, user-department.entity.ts
- Remove Department/UserDepartment from entities/index.ts
- Remove departmentId column from 18 entities (AttendanceRecord, ArchiveAttachment, Bill, ClassSchedule, Classroom, ClassroomRental, Deposit, DepositInstallment, ExamScore, LearningRecord, Occupancy, PersonalExpense, ResultArchive, Room, RoomExpense, Student, StudentEnrollment, StudentProfile, StudentReport)
- Remove departments/ module entirely
- Delete campus-scope.ts, campus-scope.middleware.ts (request-utils.ts kept — it's just IP extraction)
- Simplify common.module.ts to empty module
- Remove CampusScopeMiddleware from app.module.ts
- Remove all CampusScope injections and filter calls across all services
- Remove departmentId from all DTOs and controllers
- Simplify dingtalk/wecom sync to only sync users (no dept table)
- Update seed module to remove department seeding
- Clean frontend compilation
This commit is contained in:
2026-07-09 17:51:32 +08:00
parent b0f7883f33
commit 6029d8e2fd
68 changed files with 220 additions and 1516 deletions

View File

@@ -9,7 +9,6 @@ import { PersonalExpense } from '../entities/personal-expense.entity';
import { Occupancy } from '../entities/occupancy.entity';
import { Room } from '../entities/room.entity';
import { Deposit } from '../entities/deposit.entity';
import { CampusScope } from '../common/campus-scope';
type MockRepository<T> = Partial<Record<keyof Repository<T>, jest.Mock>>;
@@ -70,7 +69,6 @@ describe('BillsService — generateBills', () => {
{ provide: getRepositoryToken(Room), useValue: roomRepo },
{ provide: getRepositoryToken(Deposit), useValue: depositRepo },
{ provide: DataSource, useValue: dataSource },
{ provide: CampusScope, useValue: { getScopeDepartmentIds: jest.fn().mockResolvedValue(null), filter: jest.fn((w: any) => w) } },
],
}).compile();

View File

@@ -9,7 +9,7 @@ import { Occupancy } from '../entities/occupancy.entity';
import { Room } from '../entities/room.entity';
import { Deposit } from '../entities/deposit.entity';
import { GenerateBillsDto, UpdateBillStatusDto } from './dto/bill.dto';
import { CampusScope } from '../common/campus-scope';
@Injectable()
export class BillsService {
@@ -22,7 +22,6 @@ export class BillsService {
@InjectRepository(Room) private roomRepo: Repository<Room>,
@InjectRepository(Deposit) private depositRepo: Repository<Deposit>,
private dataSource: DataSource,
private readonly scope: CampusScope,
) {}
/**
@@ -181,15 +180,6 @@ export class BillsService {
// 合并所有涉及的学生
const allStudentIds = new Set([...studentBillData.keys(), ...personalMap.keys()]);
// 生成账单
// Batch-load student departmentIds
const studentIdsArr = [...allStudentIds];
const studentDeptMap = new Map<number, number>();
if (studentIdsArr.length > 0) {
const studentsData: { id: number; department_id: number | null }[] = await this.dataSource.query(
`SELECT id, department_id FROM students WHERE id IN (${studentIdsArr.join(',')})`
);
for (const s of studentsData) if (s.department_id != null) studentDeptMap.set(s.id, s.department_id);
}
const bills: Bill[] = [];
for (const studentId of allStudentIds) {
const shared = studentBillData.get(studentId)?.shared || 0;
@@ -204,7 +194,6 @@ export class BillsService {
personalAmount: personal,
totalAmount: total,
status: 'draft',
departmentId: studentDeptMap.get(studentId),
});
const savedBill = await this.billRepo.save(bill);
@@ -229,12 +218,10 @@ export class BillsService {
status?: string;
expenseType?: string;
}) {
const scopeIds = await this.scope.getScopeDepartmentIds();
const qb = this.billRepo
.createQueryBuilder('b')
.leftJoinAndSelect('b.student', 'student')
.orderBy('b.generatedAt', 'DESC');
if (scopeIds) qb.andWhere('b.departmentId IN (:...scopeIds)', { scopeIds });
if (query?.periodStart) qb.andWhere('b.periodStart = :ps', { ps: query.periodStart });
if (query?.periodEnd) qb.andWhere('b.periodEnd = :pe', { pe: query.periodEnd });
if (query?.studentId) qb.andWhere('b.studentId = :sid', { sid: query.studentId });