fix: 修复多处边界条件问题

- rooms: parseRoomNumber 未知格式返回默认 capacity=4,防止 undefined 绕过入住容量检查
- rooms: 修复 parseInt() || undefined 导致楼层 0 被吞掉
- rooms: batchImport 中 capacity 使用 ?? 代替 ||,显式 0 不被覆盖
- occupancies: 所有 capacity 比较加 ?? 0 防守兜底,fail closed
- schedules: assertValidScheduleRange 增加 startTime > endTime 校验
- attendance: 时段重叠检查改为按 startTime 排序后再比较,消除漏检
- attendance: 移除 getScheduleOptionsForAttendance 中不可靠的 raw[index] fallback
- expenses: 个人附加费批量导入增加 assertPositiveAmount 校验
- expenses: 水电费导入增加 periodEnd >= periodStart 校验
This commit is contained in:
2026-07-20 14:45:53 +08:00
parent 990c0c16e6
commit 00e9c5e45a
6 changed files with 43 additions and 21 deletions

View File

@@ -866,9 +866,13 @@ export class AttendanceService {
};
}).sort((left, right) => left.sortOrder - right.sortOrder);
for (let index = 1; index < normalized.length; index += 1) {
const previous = normalized[index - 1];
const current = normalized[index];
// 按开始时间排序后再检查重叠,避免 sortOrder 与时间顺序不一致时漏检
const sortedByTime = [...normalized].sort(
(left, right) => this.toMinutes(left.startTime) - this.toMinutes(right.startTime),
);
for (let index = 1; index < sortedByTime.length; index += 1) {
const previous = sortedByTime[index - 1];
const current = sortedByTime[index];
if (previous.enabled && current.enabled && this.toMinutes(current.startTime) < this.toMinutes(previous.endTime)) {
throw new BadRequestException(`${previous.label}${current.label} 时间段不能重叠`);
}
@@ -996,10 +1000,10 @@ export class AttendanceService {
]),
);
return entities.map((schedule, index) => {
return entities.map((schedule) => {
const teacher = teacherByScheduleId.get(schedule.id) ?? {
teacherName: raw[index]?.teacherName || null,
teacherUsername: raw[index]?.teacherUsername || null,
teacherName: null,
teacherUsername: null,
};
return { ...schedule, ...teacher };
});