From 21898888e7781959f746b1fe6814f7353ab4810f Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期五, 21 八月 2026 17:03:14 +0800
Subject: [PATCH] 考勤记录下载模板 导入计算迟到加班正常打卡

---
 yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/HrmAttendanceRecordController.java |  102 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 102 insertions(+), 0 deletions(-)

diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/HrmAttendanceRecordController.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/HrmAttendanceRecordController.java
index e99c45f..9f94ad3 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/HrmAttendanceRecordController.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/controller/admin/attendance/HrmAttendanceRecordController.java
@@ -7,6 +7,8 @@
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceRecordImportExcelVO;
+import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceRecordImportReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceRecordPageReqVO;
 import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceRecordRespVO;
 import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceRecordDO;
@@ -142,6 +144,7 @@
             HrmEmployeeDO employee = employeeMap.get(respVO.getUserId());
             if (employee != null) {
                 respVO.setUserName(employee.getName());
+                respVO.setPhone(employee.getPhone());
             }
             // 閮ㄩ棬鍚嶇О
             DeptRespDTO dept = deptMap.get(respVO.getDeptId());
@@ -166,6 +169,7 @@
             HrmEmployeeDO employee = employeeService.getEmployee(attendanceRecord.getUserId());
             if (employee != null) {
                 respVO.setUserName(employee.getName());
+                respVO.setPhone(employee.getPhone());
             }
         }
         if (attendanceRecord.getDeptId() != null) {
@@ -177,6 +181,104 @@
         return success(respVO);
     }
 
+    @GetMapping("/get-import-template")
+    @Operation(summary = "涓嬭浇鑰冨嫟璁板綍瀵煎叆妯℃澘")
+    @PreAuthorize("@ss.hasPermission('hrm:attendance-record:import')")
+    public void importTemplate(HttpServletResponse response) throws IOException {
+        List<HrmAttendanceRecordImportExcelVO> list = Collections.singletonList(
+                HrmAttendanceRecordImportExcelVO.builder()
+                        .userName("寮犱笁")
+                        .phone("13800138000")
+                        .date(java.time.LocalDate.of(2026, 1, 15))
+                        .clockInTime(java.time.LocalDateTime.of(2026, 1, 15, 8, 30))
+                        .clockOutTime(java.time.LocalDateTime.of(2026, 1, 15, 17, 30))
+                        .clockInType(1)
+                        .clockOutType(1)
+                        .location("鍔炲叕鍖�")
+                        .remark("绀轰緥鏁版嵁")
+                        .build()
+        );
+        ExcelUtils.write(response, "鑰冨嫟瀵煎叆妯℃澘.xls", "鑰冨嫟璁板綍", HrmAttendanceRecordImportExcelVO.class, list);
+    }
+
+    @PostMapping("/import")
+    @Operation(summary = "瀵煎叆鑰冨嫟璁板綍")
+    @PreAuthorize("@ss.hasPermission('hrm:attendance-record:import')")
+    public CommonResult<String> importExcel(@Valid HrmAttendanceRecordImportReqVO importReqVO) throws IOException {
+        List<HrmAttendanceRecordImportExcelVO> list = ExcelUtils.read(importReqVO.getFile(), HrmAttendanceRecordImportExcelVO.class);
+        if (CollUtil.isEmpty(list)) {
+            return success("娌℃湁鍙鍏ョ殑鏁版嵁");
+        }
+        int successCount = 0;
+        Set<String> missingNames = new LinkedHashSet<>();
+        Set<String> duplicateNames = new LinkedHashSet<>();
+        Set<String> invalidRows = new LinkedHashSet<>();
+        for (HrmAttendanceRecordImportExcelVO item : list) {
+            if (item.getDate() == null) {
+                invalidRows.add((item.getUserName() == null || item.getUserName().isBlank()) ? "鏈~濮撳悕鐨勮" : "鑰冨嫟鏃ユ湡涓虹┖(" + item.getUserName().trim() + ")");
+                continue;
+            }
+            if (item.getUserName() == null || item.getUserName().isBlank()) {
+                invalidRows.add("鑰冨嫟鏃ユ湡涓� " + item.getDate() + " 浣嗘湭濉憳宸ュ鍚�");
+                continue;
+            }
+            List<HrmEmployeeDO> employees = employeeService.getEmployeeListByName(item.getUserName().trim());
+            if (employees.isEmpty()) {
+                missingNames.add(item.getUserName().trim());
+                continue;
+            }
+            HrmEmployeeDO employee = employees.get(0);
+            // 瀛樺湪澶氫釜鍚屽悕鍛樺伐鏃讹紝鐢ㄦ墜鏈哄彿鍖哄垎
+            if (employees.size() > 1) {
+                String phone = item.getPhone() != null ? item.getPhone().trim() : null;
+                List<HrmEmployeeDO> matchedByPhone = new ArrayList<>();
+                if (phone != null && !phone.isEmpty()) {
+                    for (HrmEmployeeDO emp : employees) {
+                        if (phone.equals(emp.getPhone())) {
+                            matchedByPhone.add(emp);
+                        }
+                    }
+                }
+                if (matchedByPhone.size() == 1) {
+                    employee = matchedByPhone.get(0);
+                } else {
+                    duplicateNames.add(item.getUserName().trim());
+                    continue;
+                }
+            }
+            HrmAttendanceRecordDO record = attendanceRecordService.getAttendanceRecordByUserIdAndDate(employee.getId(), item.getDate());
+            if (record == null) {
+                record = HrmAttendanceRecordDO.builder()
+                        .userId(employee.getId()).deptId(employee.getDeptId()).date(item.getDate())
+                        .clockInTime(item.getClockInTime()).clockOutTime(item.getClockOutTime())
+                        .clockInType(item.getClockInType()).clockOutType(item.getClockOutType())
+                        .location(item.getLocation()).remark(item.getRemark())
+                        .dataSource(2).build();
+                attendanceRecordService.createImportedRecord(record);
+            } else if (Boolean.TRUE.equals(importReqVO.getUpdateSupport())) {
+                record.setClockInTime(item.getClockInTime());
+                record.setClockOutTime(item.getClockOutTime());
+                record.setClockInType(item.getClockInType());
+                record.setClockOutType(item.getClockOutType());
+                record.setLocation(item.getLocation());
+                record.setRemark(item.getRemark());
+                attendanceRecordService.updateImportedRecord(record);
+            }
+            successCount++;
+        }
+        StringBuilder msg = new StringBuilder("鎴愬姛瀵煎叆 " + successCount + " 鏉�");
+        if (!missingNames.isEmpty()) {
+            msg.append("锛涗互涓嬪憳宸ヤ笉瀛樺湪锛屾湭鑳藉鍏ワ細").append(String.join("銆�", missingNames));
+        }
+        if (!duplicateNames.isEmpty()) {
+            msg.append("锛涗互涓嬪憳宸ュ瓨鍦ㄥ鍚嶅悓鍚嶅憳宸ワ紝闇�琛ュ厖鎵嬫満鍙峰尯鍒嗭紝鏈兘瀵煎叆锛�").append(String.join("銆�", duplicateNames));
+        }
+        if (!invalidRows.isEmpty()) {
+            msg.append("锛涗互涓嬭褰曟暟鎹笉瀹屾暣锛屾湭鑳藉鍏ワ細").append(String.join("銆�", invalidRows));
+        }
+        return success(msg.toString());
+    }
+
     @GetMapping("/export-excel")
     @Operation(summary = "瀵煎嚭鑰冨嫟璁板綍 Excel")
     @PreAuthorize("@ss.hasPermission('hrm:attendance:export')")

--
Gitblit v1.9.3