tuqin
21 小时以前 2f16c2e5a23587005e9ad5651f1807e618d999b4
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceRecordServiceImpl.java
@@ -34,6 +34,8 @@
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*;
@@ -60,7 +62,18 @@
    @Override
    public PageResult<HrmAttendanceRecordDO> getAttendanceRecordPage(HrmAttendanceRecordPageReqVO pageReqVO) {
        return attendanceRecordMapper.selectPage(pageReqVO);
        // 员工姓名模糊搜索:先按姓名查出员工ID集合,再按集合过滤
        // (hrm_attendance_record.user_id 存的是 hrm_employee.id)
        Set<Long> nameMatchedIds = null;
        if (StrUtil.isNotBlank(pageReqVO.getUserName())) {
            List<HrmEmployeeDO> matched = employeeService.getEmployeeListByNameLike(pageReqVO.getUserName().trim());
            nameMatchedIds = matched.stream().map(HrmEmployeeDO::getId).collect(Collectors.toSet());
            if (nameMatchedIds.isEmpty()) {
                // 姓名搜不到人时直接返回空,避免退化成查全部
                return PageResult.empty();
            }
        }
        return attendanceRecordMapper.selectPage(pageReqVO, nameMatchedIds);
    }
    @Override
@@ -94,9 +107,22 @@
    }
    /**
     * 按考勤规则重算上下班打卡类型(正常/迟到/早退),与打卡逻辑保持一致
     * 按考勤规则重算上下班打卡类型(正常/迟到/早退/缺卡),与打卡逻辑保持一致
     *
     * <p>缺卡标记不依赖考勤规则:只要某一侧没有打卡时间就是缺卡。
     * 原实现只在「该侧有打卡时间」时才设置类型,导致「只打上班卡、没打下班卡」的记录
     * clockOutType 一直是 null;而考勤统计只认 MISSING 类型,
     * 于是缺卡次数永远统计为 0(客户反馈「缺卡数据统计不对、没和考勤记录联动」)。
     */
    private void fillClockTypes(HrmAttendanceRecordDO record) {
        // 1. 缺卡优先:某一侧没有打卡时间即为缺卡,不依赖部门与考勤规则
        if (record.getClockInTime() == null) {
            record.setClockInType(HrmAttendanceClockTypeEnum.MISSING.getType());
        }
        if (record.getClockOutTime() == null) {
            record.setClockOutType(HrmAttendanceClockTypeEnum.MISSING.getType());
        }
        if (record.getDeptId() == null) {
            return;
        }