All checks were successful
CI / check (pull_request) Successful in 1m33s
- DatePicker editors open immediately on double-click - Student archive drawer hides empty studentNo parentheses - Student add/edit form uses 2-column grid layout - Table horizontal scrollbars show only on hover/focus - Remove fake 近7日趋势 stats from attendance student detail - Allow DingTalk refresh to update completed attendance sessions (late-arriving punches can now change absent → present) - Switch dev command from concurrently to turbo run dev - Remove concurrently/wait-on dependencies
54 lines
1.7 KiB
TypeScript
54 lines
1.7 KiB
TypeScript
import { BadRequestException, Injectable } from '@nestjs/common';
|
|
import { AttendanceImportService } from './attendance-import.service';
|
|
import { AttendanceService } from './attendance.service';
|
|
|
|
export type LessonAttendanceSyncMode = 'refresh' | 'finalize';
|
|
|
|
export interface LessonAttendanceSyncOptions {
|
|
scheduleId: number;
|
|
lessonDate: string;
|
|
actorId: number;
|
|
canManageAll: boolean;
|
|
mode: LessonAttendanceSyncMode;
|
|
}
|
|
|
|
@Injectable()
|
|
export class LessonAttendanceSyncService {
|
|
constructor(
|
|
private readonly attendanceService: AttendanceService,
|
|
private readonly importService: AttendanceImportService,
|
|
) {}
|
|
|
|
async syncLesson(options: LessonAttendanceSyncOptions) {
|
|
const { scheduleId, lessonDate, actorId, canManageAll, mode } = options;
|
|
const { schedule } = await this.attendanceService.getLessonAttendance(scheduleId, lessonDate);
|
|
const userIds = await this.attendanceService.getTeacherClassDingUserIds(
|
|
actorId,
|
|
schedule.classId!,
|
|
canManageAll,
|
|
lessonDate,
|
|
);
|
|
const dateRange = this.attendanceService.getLessonAttendanceImportDateRange(
|
|
schedule,
|
|
lessonDate,
|
|
);
|
|
const imported = await this.importService.importFromDingTalk({
|
|
...dateRange,
|
|
userIds,
|
|
autoMatch: true,
|
|
userId: actorId,
|
|
});
|
|
if (!imported.success || imported.errors.length > 0) {
|
|
throw new BadRequestException(imported.errors.join('; ') || '钉钉考勤拉取失败');
|
|
}
|
|
|
|
const attendance = await this.attendanceService.createLessonAttendanceFromDingTalk(
|
|
scheduleId,
|
|
lessonDate,
|
|
actorId,
|
|
mode === 'finalize',
|
|
);
|
|
return { attendance, imported: imported.imported, matched: imported.matched };
|
|
}
|
|
}
|