feat: show DingTalk punch device details
This commit is contained in:
@@ -200,6 +200,53 @@ export class AttendanceService {
|
||||
if (hasPunch) return 'present';
|
||||
return finalize ? 'absent' : 'pending';
|
||||
}
|
||||
|
||||
private getLessonPunchMetadata(
|
||||
records: DingAttendanceRaw[],
|
||||
lessonDate: string,
|
||||
startTime: string,
|
||||
): Pick<AttendanceRecord, 'punchTime' | 'punchSource' | 'punchDeviceName' | 'punchDeviceId'> {
|
||||
const punches = records
|
||||
.map((record) => ({ record, time: record.checkInTime ?? record.checkOutTime }))
|
||||
.filter((item): item is { record: DingAttendanceRaw; time: Date } => !!item.time);
|
||||
if (punches.length === 0) {
|
||||
return {
|
||||
punchTime: null,
|
||||
punchSource: null,
|
||||
punchDeviceName: null,
|
||||
punchDeviceId: null,
|
||||
};
|
||||
}
|
||||
|
||||
const lessonStart = new Date(`${lessonDate}T${startTime}:00+08:00`).getTime();
|
||||
punches.sort(
|
||||
(left, right) =>
|
||||
Math.abs(left.time.getTime() - lessonStart) - Math.abs(right.time.getTime() - lessonStart),
|
||||
);
|
||||
const primary = punches[0];
|
||||
const metadataRecord = [...punches]
|
||||
.filter(({ record }) =>
|
||||
!!(record.punchSource || record.punchDeviceName || record.punchDeviceId) ||
|
||||
!['OnDuty', 'OffDuty'].includes(record.attendanceType),
|
||||
)
|
||||
.sort(
|
||||
(left, right) =>
|
||||
Math.abs(left.time.getTime() - primary.time.getTime()) -
|
||||
Math.abs(right.time.getTime() - primary.time.getTime()),
|
||||
)[0]?.record;
|
||||
const source =
|
||||
metadataRecord?.punchSource ||
|
||||
(metadataRecord && !['OnDuty', 'OffDuty'].includes(metadataRecord.attendanceType)
|
||||
? metadataRecord.attendanceType
|
||||
: primary.record.punchSource);
|
||||
|
||||
return {
|
||||
punchTime: primary.time,
|
||||
punchSource: source || null,
|
||||
punchDeviceName: metadataRecord?.punchDeviceName || primary.record.punchDeviceName || null,
|
||||
punchDeviceId: metadataRecord?.punchDeviceId || primary.record.punchDeviceId || null,
|
||||
};
|
||||
}
|
||||
async createLessonAttendanceFromDingTalk(
|
||||
scheduleId: number,
|
||||
lessonDate: string,
|
||||
@@ -270,6 +317,11 @@ export class AttendanceService {
|
||||
schedule.endTime,
|
||||
);
|
||||
record.status = this.mapDingTalkStatus(raw, finalize);
|
||||
Object.assign(record, this.getLessonPunchMetadata(
|
||||
raw,
|
||||
lessonDate,
|
||||
schedule.startTime,
|
||||
));
|
||||
record.remark = raw.some((item) => item.checkInTime || item.checkOutTime)
|
||||
? null
|
||||
: finalize
|
||||
@@ -296,6 +348,11 @@ export class AttendanceService {
|
||||
session: this.mapScheduleTimeToSession(schedule.startTime),
|
||||
status: this.mapDingTalkStatus(raw, finalize),
|
||||
source: 'dingtalk',
|
||||
...this.getLessonPunchMetadata(
|
||||
raw,
|
||||
lessonDate,
|
||||
schedule.startTime,
|
||||
),
|
||||
remark: raw.some((item) => item.checkInTime || item.checkOutTime)
|
||||
? undefined
|
||||
: finalize
|
||||
@@ -378,6 +435,11 @@ export class AttendanceService {
|
||||
session: this.mapScheduleTimeToSession(schedule.startTime),
|
||||
status: this.mapDingTalkStatus(raw, finalize),
|
||||
source: 'dingtalk',
|
||||
...this.getLessonPunchMetadata(
|
||||
raw,
|
||||
lessonDate,
|
||||
schedule.startTime,
|
||||
),
|
||||
remark: raw.some((item) => item.checkInTime || item.checkOutTime)
|
||||
? undefined
|
||||
: finalize
|
||||
@@ -908,6 +970,10 @@ export class AttendanceService {
|
||||
if (dto.status !== undefined) {
|
||||
record.status = dto.status;
|
||||
record.source = 'manual';
|
||||
record.punchTime = null;
|
||||
record.punchSource = null;
|
||||
record.punchDeviceName = null;
|
||||
record.punchDeviceId = null;
|
||||
}
|
||||
if (dto.remark !== undefined) {
|
||||
record.remark = dto.remark;
|
||||
@@ -933,6 +999,10 @@ export class AttendanceService {
|
||||
if (dto.status !== undefined) {
|
||||
freshRecord.status = dto.status;
|
||||
freshRecord.source = 'manual';
|
||||
freshRecord.punchTime = null;
|
||||
freshRecord.punchSource = null;
|
||||
freshRecord.punchDeviceName = null;
|
||||
freshRecord.punchDeviceId = null;
|
||||
}
|
||||
if (dto.remark !== undefined) {
|
||||
freshRecord.remark = dto.remark;
|
||||
|
||||
Reference in New Issue
Block a user