sql/mysql/hrm_attendance_record_fill_missing_clock_type.sql
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,39 @@ -- ============================================================ -- èå¤è®°å½ï¼è¡¥é½ã缺å¡ãæ è®°ï¼å岿°æ®ï¼ -- -- èæ¯ï¼ -- HrmAttendanceRecordServiceImpl#fillClockTypes åå®ç°åªå¨ã该侧ææå¡æ¶é´ãæ¶ -- æè®¾ç½® clockInType / clockOutTypeï¼å¯¼è´ãåªæä¸çå¡ã没æä¸çå¡ãçè®°å½ -- clockOutType ä¸ç´ä¸º NULLã -- èèå¤ç»è®¡ï¼HrmAttendanceSummaryServiceImpl#generateMonthlySummaryï¼åªç»è®¡ -- clockInType/clockOutType = 4ï¼MISSINGï¼çè®°å½ï¼äºæ¯ãç¼ºå¡æ¬¡æ°ãæ°¸è¿ä¸º 0ï¼ -- ä¸èå¤è®°å½æ¨¡å对ä¸ä¸ï¼å®¢æ·åé¦ã缺å¡ãæ©éæ°æ®ç»è®¡ä¸å¯¹ãï¼ã -- -- 代ç 已修å¤ï¼ç°å¨åªè¦æä¸ä¾§æ²¡ææå¡æ¶é´å°±æ 记为 4ï¼ç¼ºå¡ï¼ï¼ä¸ä¸ä¾èµèå¤è§åã -- æ¬èæ¬ç¨äºä¿®å¤ä¿®å¤åå·²å ¥åºçå岿å¡è®°å½ã -- -- æä¸¾ï¼HrmAttendanceClockTypeEnum NORMAL(1) / LATE(2) / EARLY(3) / MISSING(4) -- ============================================================ -- 1ï¼ç¼ºä¸çå¡ï¼æè®°å½ä½ clock_in_time 为空ï¼ä¸ç±»åè¿æ²¡æ UPDATE hrm_attendance_record SET clock_in_type = 4 WHERE deleted = b'0' AND clock_in_time IS NULL AND clock_in_type IS NULL; -- 2ï¼ç¼ºä¸çå¡ï¼æè®°å½ä½ clock_out_time 为空ï¼ä¸ç±»åè¿æ²¡æ UPDATE hrm_attendance_record SET clock_out_type = 4 WHERE deleted = b'0' AND clock_out_time IS NULL AND clock_out_type IS NULL; -- 3ï¼æ ¡éªï¼ç¼ºå¡æ è®°æ°é -- SELECT SUM(clock_in_type = 4) AS 缺ä¸ç塿¬¡æ°, -- SUM(clock_out_type = 4) AS 缺ä¸ç塿¬¡æ° -- FROM hrm_attendance_record WHERE deleted = b'0'; -- 4ï¼æ³¨æï¼ä¿®å®æ°æ®åéè¦éæ°çæèå¤ç»è®¡ï¼ç¼ºå¡æ¬¡æ°æä¼å·è¿æ±æ»è¡¨ï¼ -- èå¤ç®¡ç â èå¤ç»è®¡ â çæç»è®¡ï¼é对åºå¹´æï¼ï¼æè° -- POST /admin-api/hrm/attendance/summary/generate?yearMonth=YYYY-MM yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/HrmAttendanceSummaryController.java
@@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.hrm.controller.admin.attendance; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageParam; @@ -149,7 +150,15 @@ if (CollUtil.isNotEmpty(data)) { fillUserInfo(data, pageResult.getList()); } ExcelUtils.write(response, "èå¤ç»è®¡æ±æ».xls", "æ°æ®", HrmAttendanceSummaryRespVO.class, data); // æä»¶å带ä¸ç鿡件ï¼é¿å 导åºå¤ä¸ªæä»½æ°æ®æ¶è¢«è¯¯è®¤ä¸ºãéå¤ã String fileName = "èå¤ç»è®¡æ±æ»"; if (StrUtil.isNotBlank(pageReqVO.getYearMonth())) { fileName = fileName + "_" + pageReqVO.getYearMonth(); } else if (pageReqVO.getStartDate() != null) { fileName = fileName + "_" + pageReqVO.getStartDate() + "_" + (pageReqVO.getEndDate() != null ? pageReqVO.getEndDate() : "è³ä»"); } ExcelUtils.write(response, fileName + ".xls", "æ°æ®", HrmAttendanceSummaryRespVO.class, data); } } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/vo/HrmAttendanceSummaryPageReqVO.java
@@ -18,6 +18,9 @@ @Schema(description = "åå·¥ID", example = "1") private Long userId; @Schema(description = "åå·¥å§åï¼æ¨¡ç³å¹é ï¼ä¸ userId åæ¶ä¼ æ¶å交éï¼", 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/employee/HrmEmployeeMapper.java
@@ -47,6 +47,14 @@ return selectList(HrmEmployeeDO::getName, name); } /** * æå§åæ¨¡ç³æ¥è¯¢åå·¥ï¼èå¤ç»è®¡çå表çå§åæç´¢ç¨ï¼ */ default List<HrmEmployeeDO> selectListByNameLike(String name) { return selectList(new LambdaQueryWrapperX<HrmEmployeeDO>() .like(HrmEmployeeDO::getName, name)); } default HrmEmployeeDO selectByEmployeeNo(String employeeNo) { return selectOne(HrmEmployeeDO::getEmployeeNo, employeeNo); } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceRecordServiceImpl.java
@@ -94,9 +94,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; } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceSummaryServiceImpl.java
@@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.hrm.service.attendance; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceSummaryPageReqVO; @@ -206,12 +207,35 @@ if (pageReqVO.getStartDate() != null) { return getAttendanceSummaryByDateRange(pageReqVO); } // åå·¥å§åæ¨¡ç³æç´¢ï¼å æå§åæ¥åºåå·¥IDï¼åæ ID éåè¿æ»¤ï¼æ±æ»è¡¨ç user_id åçæ¯åå·¥IDï¼ Set<Long> nameMatchedIds = resolveEmployeeIdsByName(pageReqVO.getUserName()); if (nameMatchedIds != null && nameMatchedIds.isEmpty()) { // å§åæä¸å°ä»»ä½åå·¥æ¶ç´æ¥è¿å空ï¼é¿å éåææ¥å ¨é¨ return PageResult.empty(); } return attendanceSummaryMapper.selectPage(pageReqVO, new LambdaQueryWrapperX<HrmAttendanceSummaryDO>() .eqIfPresent(HrmAttendanceSummaryDO::getUserId, pageReqVO.getUserId()) .inIfPresent(HrmAttendanceSummaryDO::getUserId, nameMatchedIds) .eqIfPresent(HrmAttendanceSummaryDO::getDeptId, pageReqVO.getDeptId()) .eqIfPresent(HrmAttendanceSummaryDO::getYearMonth, pageReqVO.getYearMonth()) .orderByDesc(HrmAttendanceSummaryDO::getYearMonth) .orderByAsc(HrmAttendanceSummaryDO::getDeptId)); } /** * æåå·¥å§å模ç³å¹é ï¼è¿ååå·¥IDéå * * @return null 表示æªä¼ å§åï¼ä¸åä¸è¿æ»¤ï¼ï¼ç©ºéåè¡¨ç¤ºä¼ äºå§å使²¡æä»»ä½åå·¥å¹é */ private Set<Long> resolveEmployeeIdsByName(String userName) { if (StrUtil.isBlank(userName)) { return null; } List<HrmEmployeeDO> matched = employeeService.getEmployeeListByNameLike(userName.trim()); if (CollUtil.isEmpty(matched)) { return Collections.emptySet(); } return matched.stream().map(HrmEmployeeDO::getId).collect(Collectors.toSet()); } /** @@ -243,6 +267,13 @@ .filter(e -> reqVO.getUserId().equals(e.getId())) .toList(); } // åå·¥å§å模ç³è¿æ»¤ if (StrUtil.isNotBlank(reqVO.getUserName())) { String keyword = reqVO.getUserName().trim(); employees = employees.stream() .filter(e -> e.getName() != null && e.getName().contains(keyword)) .toList(); } if (CollUtil.isEmpty(employees)) { return PageResult.empty(); } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeService.java
@@ -130,6 +130,14 @@ /** æ ¹æ®åå·¥å§åè·ååå·¥ */ HrmEmployeeDO getEmployeeByName(String name); /** * æå§åæ¨¡ç³æ¥è¯¢åå·¥å表ï¼å表页å§åæç´¢ç¨ï¼ * * @param name å§åå ³é®å * @return åå·¥å表 */ List<HrmEmployeeDO> getEmployeeListByNameLike(String name); /** æ ¹æ®åå·¥å§åè·åææåååå·¥ */ List<HrmEmployeeDO> getEmployeeListByName(String name); yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java
@@ -520,6 +520,14 @@ } @Override public List<HrmEmployeeDO> getEmployeeListByNameLike(String name) { if (StrUtil.isBlank(name)) { return new ArrayList<>(); } return employeeMapper.selectListByNameLike(name.trim()); } @Override public HrmEmployeeImportRespVO importEmployeeList(List<HrmEmployeeImportExcelVO> importEmployees, HrmEmployeeImportReqVO importReqVO) { // 1. æ ¡éªé空