tuqin
20 小时以前 2f16c2e5a23587005e9ad5651f1807e618d999b4
fix(hrm): 考勤记录支持员工姓名搜索,并全量核对两个模块的所有搜索条件

现象:考勤记录「员工姓名」搜索无效,仍返回全部记录。

根因与考勤统计同一个坑:前端搜索表单有 userName 字段,
但后端 HrmAttendanceRecordPageReqVO 没有该参数,传了被忽略。

修复:
- HrmAttendanceRecordPageReqVO 增加 userName;
- HrmAttendanceRecordMapper 新增 selectPage(reqVO, userIds) 重载,
支持按员工ID集合过滤(hrm_attendance_record.user_id 存的是 hrm_employee.id);
- Service 先按姓名模糊查出员工ID集合,再按集合过滤;查不到人时直接返回空,
避免退化成查全部。

全量核对(mom-zyjc 实测,逐条与数据库核对):
考勤记录 /hrm/attendance/record/page
无筛选 8 = 8 OK
userName=郭琴 5 = 5 OK
userName=兰帅 1 = 1 OK
userName=张 0 = 0 OK(3 个姓张的员工均无打卡记录)
userName=zzz不存在 0 = 0 OK
startDate~endDate 10-26~28 4 = 4 OK
startDate~endDate 11月 2 = 2 OK
deptId=133 6 = 6 OK(郭琴5 + 排孜来提1)
clockInType=2 迟到 7 = 7 OK
clockOutType=4 缺卡 7 = 7 OK
userName+clockOutType 组合 4 = 4 OK
userName+日期 组合 1 = 1 OK
考勤统计 /hrm/attendance/summary/page
无筛选 396 = 396 OK
userName=郭琴 3 = 3 OK
userName+yearMonth 1 = 1 OK
deptId=133 15 = 15 OK(5员工 x 3个月)
yearMonth=2026-10 132 = 132 OK
按日区间 132 = 132 OK
按日区间+userName 1 = 1 OK

前端无需改动(userId/userName/date/deptId/clockInType/clockOutType 均已就绪)。
已修改3个文件
33 ■■■■■ 文件已修改
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/vo/HrmAttendanceRecordPageReqVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/attendance/HrmAttendanceRecordMapper.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceRecordServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/vo/HrmAttendanceRecordPageReqVO.java
@@ -17,6 +17,9 @@
    @Schema(description = "员工ID", example = "1")
    private Long userId;
    @Schema(description = "员工姓名(模糊匹配)", example = "任伟")
    private String userName;
    @Schema(description = "部门ID", example = "1")
    private Long deptId;
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/attendance/HrmAttendanceRecordMapper.java
@@ -32,6 +32,21 @@
                .orderByDesc(HrmAttendanceRecordDO::getDate));
    }
/**
     * 分页查询(支持按员工ID集合过滤,用于「员工姓名」模糊搜索)
     */
    default PageResult<HrmAttendanceRecordDO> selectPage(HrmAttendanceRecordPageReqVO reqVO, Collection<Long> userIds) {
        return selectPage(reqVO, new LambdaQueryWrapperX<HrmAttendanceRecordDO>()
                .eqIfPresent(HrmAttendanceRecordDO::getUserId, reqVO.getUserId())
                .inIfPresent(HrmAttendanceRecordDO::getUserId, userIds)
                .eqIfPresent(HrmAttendanceRecordDO::getDeptId, reqVO.getDeptId())
                .geIfPresent(HrmAttendanceRecordDO::getDate, reqVO.getStartDate())
                .leIfPresent(HrmAttendanceRecordDO::getDate, reqVO.getEndDate())
                .eqIfPresent(HrmAttendanceRecordDO::getClockInType, reqVO.getClockInType())
                .eqIfPresent(HrmAttendanceRecordDO::getClockOutType, reqVO.getClockOutType())
                .orderByDesc(HrmAttendanceRecordDO::getDate));
    }
    default HrmAttendanceRecordDO selectByUserIdAndDate(Long userId, LocalDate date) {
        return selectOne(new LambdaQueryWrapperX<HrmAttendanceRecordDO>()
                .eq(HrmAttendanceRecordDO::getUserId, userId)
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