forked from wangziqi/gongxue-base
fix: F12 P2 follow-up — batch imports set departmentId, optimize getDescendantIds, enforce campus root invariant
This commit is contained in:
@@ -2,6 +2,7 @@ import { Injectable, NotFoundException, ConflictException } from '@nestjs/common
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { Department } from '../entities/department.entity';
|
||||
import { DepartmentType } from '../entities/department.entity';
|
||||
import { UserDepartment } from '../entities/user-department.entity';
|
||||
import { CreateDepartmentDto, UpdateDepartmentDto, AssignUserDto } from './dto/department.dto';
|
||||
|
||||
@@ -58,6 +59,9 @@ export class DepartmentsService {
|
||||
}
|
||||
|
||||
async create(dto: CreateDepartmentDto): Promise<Department> {
|
||||
if (dto.type === DepartmentType.CAMPUS && dto.parentId) {
|
||||
throw new ConflictException('校区类型的部门必须是根部门,不能设置上级');
|
||||
}
|
||||
const dept = this.deptRepo.create(dto);
|
||||
return this.deptRepo.save(dept);
|
||||
}
|
||||
@@ -65,6 +69,12 @@ export class DepartmentsService {
|
||||
async update(id: number, dto: UpdateDepartmentDto): Promise<Department> {
|
||||
const dept = await this.findOne(id);
|
||||
|
||||
const effectiveType = dto.type ?? dept.type;
|
||||
const effectiveParentId = dto.parentId !== undefined ? dto.parentId : dept.parentId;
|
||||
if (effectiveType === DepartmentType.CAMPUS && effectiveParentId) {
|
||||
throw new ConflictException('校区类型的部门必须是根部门,不能设置上级');
|
||||
}
|
||||
|
||||
// Prevent parent cycles: parentId must not be the dept itself or one of its descendants
|
||||
if (dto.parentId !== undefined && dto.parentId !== null) {
|
||||
const newParentId = dto.parentId;
|
||||
@@ -93,14 +103,21 @@ export class DepartmentsService {
|
||||
|
||||
/** 获取部门的所有子部门 ID(递归,含自身) */
|
||||
async getDescendantIds(departmentId: number): Promise<number[]> {
|
||||
const ids = [departmentId];
|
||||
const children = await this.deptRepo.find({
|
||||
where: { parentId: departmentId, status: 'active' },
|
||||
});
|
||||
for (const child of children) {
|
||||
const childIds = await this.getDescendantIds(child.id);
|
||||
ids.push(...childIds);
|
||||
const all = await this.deptRepo.find({ where: { status: 'active' }, select: ['id', 'parentId'] });
|
||||
const byParent = new Map<number | null, number[]>();
|
||||
for (const d of all) {
|
||||
const key = d.parentId ?? null;
|
||||
byParent.set(key, [...(byParent.get(key) ?? []), d.id]);
|
||||
}
|
||||
const ids: number[] = [departmentId];
|
||||
const collect = (parentId: number) => {
|
||||
const children = byParent.get(parentId) ?? [];
|
||||
for (const childId of children) {
|
||||
ids.push(childId);
|
||||
collect(childId);
|
||||
}
|
||||
};
|
||||
collect(departmentId);
|
||||
return ids;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user