feat: 考勤模块重构与钉钉考勤同步

This commit is contained in:
2026-08-05 17:11:23 +08:00
parent c622e40a12
commit e9c8a1085d
36 changed files with 5122 additions and 3458 deletions

View File

@@ -96,13 +96,11 @@ export class AttendanceImportService {
let matched = 0;
try {
// Stage 1: Fetch
this.emit('fetching', 0, 0, 'Fetching attendance results from DingTalk...');
const rawResults = await this.fetchAllPages(params);
const total = rawResults.length;
this.emit('fetching', total, total, `Fetched ${total} raw attendance records`);
// Stage 2: Parse & deduplicate
this.emit('parsing', 0, total, `Parsing ${total} records...`);
const existingByDingId = await this.getExistingRecordsByDingId(rawResults);
const newRecords = rawResults.filter((r) => !existingByDingId.has(r.checkId));
@@ -117,7 +115,6 @@ export class AttendanceImportService {
return { success: true, imported, skipped, matched, errors, duration: Date.now() - startedAt };
}
// Stage 3: Batch save
this.emit('saving', 0, newRecords.length, `Saving ${newRecords.length} records...`);
const batchSize = 100;
for (let i = 0; i < newRecords.length; i += batchSize) {
@@ -134,7 +131,6 @@ export class AttendanceImportService {
}
}
// Stage 4: Auto-match (optional)
if (params.autoMatch && imported > 0) {
this.emit('matching', 0, imported, 'Auto-matching records to students...');
matched = await this.autoMatchUnmatched();
@@ -305,7 +301,6 @@ export class AttendanceImportService {
entity.punchDeviceName = r.deviceName || null;
entity.punchDeviceId = r.deviceId || null;
// Parse check-in/out times
if (r.actualCheckTime) {
const dt = new Date(r.actualCheckTime);
if (!isNaN(dt.getTime())) {