refactor: 抽取课程考勤记录构建 helper,消除重复代码

This commit is contained in:
2026-08-05 18:51:06 +08:00
parent c8316e9e8e
commit 6ba7f4e3d0

View File

@@ -182,36 +182,18 @@ export class AttendanceLessonService {
);
for (const classStudent of classStudents) {
if (existingStudentIds.has(classStudent.studentId)) continue;
const raw = selectDingTalkRecordsForLesson(
rawByStudent.get(classStudent.studentId) ?? [],
schedule,
lessonDate,
);
const resolved = await this.resolveLessonStatus(
classStudent.studentId,
raw,
schedule,
lessonDate,
effectiveFinalize,
);
updatedRecords.push(
recordRepo.create({
studentId: classStudent.studentId,
student: classStudent.student,
classId: schedule.classId!,
await this.buildLessonRecord(
recordRepo,
rawByStudent,
classStudent,
schedule,
lessonDate,
lessonSessionKey,
existing.id,
scheduleId,
attendanceSessionId: existing.id,
attendanceDate: lessonDate,
session: lessonSessionKey,
status: resolved.status,
source: 'dingtalk',
...getLessonPunchMetadata(
raw,
lessonDate,
schedule.startTime,
),
remark: resolved.remark,
}),
effectiveFinalize,
),
);
}
@@ -274,37 +256,19 @@ export class AttendanceLessonService {
const lessonSessionKey = mapLessonScheduleTimeToSession(schedule.startTime);
const records = await Promise.all(
classStudents.map(async (classStudent) => {
const raw = selectDingTalkRecordsForLesson(
rawByStudent.get(classStudent.studentId) ?? [],
classStudents.map((classStudent) =>
this.buildLessonRecord(
recordRepo,
rawByStudent,
classStudent,
schedule,
lessonDate,
);
const resolved = await this.resolveLessonStatus(
classStudent.studentId,
raw,
schedule,
lessonDate,
finalize,
);
return recordRepo.create({
studentId: classStudent.studentId,
student: classStudent.student,
classId: schedule.classId!,
lessonSessionKey,
session.id,
scheduleId,
attendanceSessionId: session.id,
attendanceDate: lessonDate,
session: lessonSessionKey,
status: resolved.status,
source: 'dingtalk',
...getLessonPunchMetadata(
raw,
lessonDate,
schedule.startTime,
),
remark: resolved.remark,
});
}),
finalize,
),
),
);
const saved = await recordRepo.save(records);
if (finalize) {
@@ -347,6 +311,69 @@ export class AttendanceLessonService {
return { status: 'absent', remark: '课程截止仍未打卡' };
}
private createLessonRecord(
recordRepo: Repository<AttendanceRecord>,
classStudent: ClassStudent,
raw: DingAttendanceRaw[],
options: {
schedule: Pick<ClassSchedule, 'classId' | 'startTime' | 'endTime' | 'attendanceAdvanceMinutes'>;
scheduleId: number;
lessonDate: string;
lessonSessionKey: string;
attendanceSessionId: number;
status: string;
remark?: string;
},
): AttendanceRecord {
return recordRepo.create({
studentId: classStudent.studentId,
student: classStudent.student,
classId: options.schedule.classId!,
scheduleId: options.scheduleId,
attendanceSessionId: options.attendanceSessionId,
attendanceDate: options.lessonDate,
session: options.lessonSessionKey,
status: options.status,
source: 'dingtalk',
...getLessonPunchMetadata(raw, options.lessonDate, options.schedule.startTime),
remark: options.remark,
});
}
private async buildLessonRecord(
recordRepo: Repository<AttendanceRecord>,
rawByStudent: Map<number, DingAttendanceRaw[]>,
classStudent: ClassStudent,
schedule: Pick<ClassSchedule, 'classId' | 'startTime' | 'endTime' | 'attendanceAdvanceMinutes'>,
lessonDate: string,
lessonSessionKey: string,
attendanceSessionId: number,
scheduleId: number,
finalize: boolean,
): Promise<AttendanceRecord> {
const raw = selectDingTalkRecordsForLesson(
rawByStudent.get(classStudent.studentId) ?? [],
schedule,
lessonDate,
);
const resolved = await this.resolveLessonStatus(
classStudent.studentId,
raw,
schedule,
lessonDate,
finalize,
);
return this.createLessonRecord(recordRepo, classStudent, raw, {
schedule,
scheduleId,
lessonDate,
lessonSessionKey,
attendanceSessionId,
status: resolved.status,
remark: resolved.remark,
});
}
private async findApprovedLeaveForStudent(
studentId: number,
schedule: Pick<ClassSchedule, 'startTime' | 'endTime' | 'attendanceAdvanceMinutes'>,