feat: show DingTalk punch device details

This commit is contained in:
2026-07-14 11:20:27 +08:00
parent d572e984d2
commit 811e7ce826
12 changed files with 377 additions and 13 deletions

View File

@@ -41,6 +41,7 @@ import { message } from '../../ui/app-message';
import {
canPullAttendance,
getAttendanceExperience,
getPunchDisplayInfo,
getSchedulePhase,
summarizeLessonCheckins,
type AttendanceSummary,
@@ -96,6 +97,10 @@ interface AttendanceRecordItem {
class: { id: number; name: string } | null;
scheduleId?: number | null;
attendanceSessionId?: number | null;
punchTime?: string | null;
punchSource?: string | null;
punchDeviceName?: string | null;
punchDeviceId?: string | null;
}
interface AssignedClass {
@@ -288,6 +293,7 @@ const TeacherAttendanceWorkspace: React.FC = () => {
`/attendance-lessons/schedules/${schedule.id}/pull`,
{ date: today },
);
setSelectedSchedule(data.schedule);
setLessonSession(data.session);
setLessonRecords(data.records);
message.success('钉钉打卡已更新;课程截止后系统将自动结算');
@@ -386,7 +392,7 @@ const TeacherAttendanceWorkspace: React.FC = () => {
)}
</Spin>
<Drawer open={drawerOpen} onClose={() => setDrawerOpen(false)} width={820} title={null} className="attendance-drawer">
<Drawer open={drawerOpen} onClose={() => setDrawerOpen(false)} width={960} title={null} className="attendance-drawer">
<div className="lesson-record-header">
<span className="attendance-eyebrow">LESSON ATTENDANCE</span>
<h2>{selectedSchedule?.subject || '课程考勤'}</h2>
@@ -438,6 +444,21 @@ const TeacherAttendanceWorkspace: React.FC = () => {
},
},
{ title: '当前状态', dataIndex: 'status', width: 105, render: (value: string) => <AttendanceStatusTag status={value === 'present' || value === 'late' ? 'present' : 'absent'} /> },
{
title: '打卡设备',
width: 220,
render: (_: unknown, record: AttendanceRecordItem) => {
const info = getPunchDisplayInfo(record);
if (!info) return <span className="muted-text"></span>;
return (
<div className="punch-device-cell">
<Tag color={info.machine ? 'green' : 'blue'}>{info.label}</Tag>
{info.detail && <strong>{info.detail}</strong>}
{info.time && <span>{dayjs(info.time).format('HH:mm:ss')}</span>}
</div>
);
},
},
{ title: '备注', dataIndex: 'remark', render: (value: string | null) => value || <span className="muted-text"></span> },
]}
/>