From fc61c0a691600205ef6e7d7b1182afa825b1d550 Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期一, 26 十月 2026 14:24:10 +0800
Subject: [PATCH] feat(hrm): 新增我的考勤状态接口
---
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceRecordServiceImpl.java | 129 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 128 insertions(+), 1 deletions(-)
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceRecordServiceImpl.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceRecordServiceImpl.java
index 6eab672..1c84a33 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceRecordServiceImpl.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/attendance/HrmAttendanceRecordServiceImpl.java
@@ -2,6 +2,7 @@
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceMyStatusRespVO;
import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmAttendanceRecordPageReqVO;
import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceRecordDO;
import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmAttendanceRuleDO;
@@ -31,7 +32,7 @@
/**
* 鑰冨嫟璁板綍 Service 瀹炵幇绫�
*
- * @author 鑺嬮亾婧愮爜
+ * @author 瓒呯骇绠$悊鍛�
*/
@Service
@Validated
@@ -64,6 +65,86 @@
@Override
public HrmAttendanceRecordDO getAttendanceRecordByUserIdAndDate(Long userId, LocalDate date) {
return attendanceRecordMapper.selectByUserIdAndDate(userId, date);
+ }
+
+ @Override
+ public void createImportedRecord(HrmAttendanceRecordDO record) {
+ // 鎸夎�冨嫟瑙勫垯閲嶇畻鎵撳崱绫诲瀷涓庢椂闀匡紝涓嶄俊浠� Excel 濉啓鐨勫��
+ fillClockTypes(record);
+ fillCalculatedHours(record);
+ attendanceRecordMapper.insert(record);
+ }
+
+ @Override
+ public void updateImportedRecord(HrmAttendanceRecordDO record) {
+ fillClockTypes(record);
+ fillCalculatedHours(record);
+ attendanceRecordMapper.updateById(record);
+ }
+
+ /**
+ * 鎸夎�冨嫟瑙勫垯閲嶇畻涓婁笅鐝墦鍗$被鍨嬶紙姝e父/杩熷埌/鏃╅��锛夛紝涓庢墦鍗¢�昏緫淇濇寔涓�鑷�
+ */
+ private void fillClockTypes(HrmAttendanceRecordDO record) {
+ if (record.getDeptId() == null) {
+ return;
+ }
+ HrmAttendanceRuleDO rule = attendanceRuleService.getAttendanceRuleByDeptId(record.getDeptId());
+ if (rule == null) {
+ return;
+ }
+ // 涓婄彮鎵撳崱绫诲瀷锛氭櫄浜� 涓婄彮鏃堕棿+杩熷埌鍏佽 璁颁负杩熷埌
+ if (record.getClockInTime() != null && rule.getWorkStartTime() != null) {
+ int lateAllowMinutes = rule.getLateAllowMinutes() != null ? rule.getLateAllowMinutes() : 0;
+ LocalTime lateThreshold = rule.getWorkStartTime().plusMinutes(lateAllowMinutes);
+ LocalTime clockInOnly = record.getClockInTime().toLocalTime();
+ record.setClockInType(clockInOnly.isAfter(lateThreshold)
+ ? HrmAttendanceClockTypeEnum.LATE.getType()
+ : HrmAttendanceClockTypeEnum.NORMAL.getType());
+ }
+ // 涓嬬彮鎵撳崱绫诲瀷锛氭棭浜� 涓嬬彮鏃堕棿-鏃╅��鍏佽 璁颁负鏃╅��
+ if (record.getClockOutTime() != null && rule.getWorkEndTime() != null) {
+ int earlyAllowMinutes = rule.getEarlyAllowMinutes() != null ? rule.getEarlyAllowMinutes() : 0;
+ LocalTime earlyThreshold = rule.getWorkEndTime().minusMinutes(earlyAllowMinutes);
+ LocalTime clockOutOnly = record.getClockOutTime().toLocalTime();
+ record.setClockOutType(clockOutOnly.isBefore(earlyThreshold)
+ ? HrmAttendanceClockTypeEnum.EARLY.getType()
+ : HrmAttendanceClockTypeEnum.NORMAL.getType());
+ }
+ }
+
+ /**
+ * 鏍规嵁涓婁笅鐝墦鍗℃椂闂村拰鑰冨嫟瑙勫垯锛岃绠楀伐浣滄椂闀夸笌鍔犵彮鏃堕暱
+ */
+ private void fillCalculatedHours(HrmAttendanceRecordDO record) {
+ // 宸ヤ綔鏃堕暱 = 涓嬬彮鎵撳崱鏃堕棿 - 涓婄彮鎵撳崱鏃堕棿锛堜笌鎵撳崱閫昏緫涓�鑷达級
+ if (record.getClockInTime() != null && record.getClockOutTime() != null) {
+ Duration duration = Duration.between(record.getClockInTime(), record.getClockOutTime());
+ BigDecimal workHours = BigDecimal.valueOf(duration.toMinutes())
+ .divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
+ record.setWorkHours(workHours);
+ }
+ // 鍔犵彮鏃堕暱锛氭寜鑰冨嫟瑙勫垯鐨勬爣鍑嗕笅鐝椂闂磋绠楄秴棰濋儴鍒�
+ if (record.getClockOutTime() != null && record.getDeptId() != null) {
+ HrmAttendanceRuleDO rule = attendanceRuleService.getAttendanceRuleByDeptId(record.getDeptId());
+ if (rule != null && rule.getWorkEndTime() != null) {
+ LocalTime workEnd = rule.getWorkEndTime();
+ LocalDate outDate = record.getClockOutTime().toLocalDate();
+ LocalDateTime workEndDateTime = LocalDateTime.of(outDate, workEnd);
+ if (record.getClockOutTime().isAfter(workEndDateTime)) {
+ Duration overtimeDuration = Duration.between(workEndDateTime, record.getClockOutTime());
+ BigDecimal overtimeThreshold = rule.getOvertimeThreshold() != null
+ ? rule.getOvertimeThreshold() : BigDecimal.ZERO;
+ BigDecimal overtimeHours = BigDecimal.valueOf(overtimeDuration.toMinutes())
+ .divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
+ record.setOvertimeHours(overtimeHours.compareTo(overtimeThreshold) > 0 ? overtimeHours : BigDecimal.ZERO);
+ } else {
+ record.setOvertimeHours(BigDecimal.ZERO);
+ }
+ } else {
+ record.setOvertimeHours(BigDecimal.ZERO);
+ }
+ }
}
@Override
@@ -178,6 +259,52 @@
}
@Override
+ public HrmAttendanceMyStatusRespVO getMyStatus(Long userId) {
+ // 1. 鍛樺伐涓嶅瓨鍦ㄦ椂杩斿洖 null锛岀敱鍓嶇鎻愮ず鏈叧鑱斿憳宸ワ紝閬垮厤鎵撳崱椤靛姞杞界洿鎺ユ姤閿�
+ HrmEmployeeDO employee = employeeService.getEmployee(userId);
+ if (employee == null) {
+ return null;
+ }
+ LocalDate today = LocalDate.now();
+ // 2. 鏌ヨ浠婃棩鑰冨嫟璁板綍涓庤�冨嫟瑙勫垯
+ HrmAttendanceRecordDO record = attendanceRecordMapper.selectByUserIdAndDate(userId, today);
+ HrmAttendanceRuleDO rule = attendanceRuleService.getAttendanceRuleByDeptId(employee.getDeptId());
+ boolean workDay = attendanceHolidayService.isWorkDay(today);
+ boolean clockInDone = record != null && record.getClockInTime() != null;
+ boolean clockOutDone = record != null && record.getClockOutTime() != null;
+
+ // 3. 缁勮浠婃棩鎵撳崱鐘舵��
+ HrmAttendanceMyStatusRespVO respVO = new HrmAttendanceMyStatusRespVO();
+ respVO.setDate(today);
+ respVO.setWorkDay(workDay);
+ respVO.setEmployeeId(employee.getId());
+ respVO.setUserName(employee.getName());
+ respVO.setDeptId(employee.getDeptId());
+ if (rule != null) {
+ respVO.setRuleName(rule.getName());
+ respVO.setWorkStartTime(rule.getWorkStartTime());
+ respVO.setWorkEndTime(rule.getWorkEndTime());
+ }
+ if (record != null) {
+ respVO.setRecordId(record.getId());
+ respVO.setClockInTime(record.getClockInTime());
+ respVO.setClockOutTime(record.getClockOutTime());
+ respVO.setClockInType(record.getClockInType());
+ respVO.setClockOutType(record.getClockOutType());
+ respVO.setWorkHours(record.getWorkHours());
+ respVO.setOvertimeHours(record.getOvertimeHours());
+ respVO.setLocation(record.getLocation());
+ respVO.setDataSource(record.getDataSource());
+ }
+ respVO.setClockInDone(clockInDone);
+ respVO.setClockOutDone(clockOutDone);
+ // 闈炲伐浣滄棩涓嶅彲鎵撳崱锛屼笌鎵撳崱鎺ュ彛鐨勬牎楠屼繚鎸佷竴鑷�
+ respVO.setCanClockIn(workDay && !clockInDone);
+ respVO.setCanClockOut(workDay && !clockOutDone);
+ return respVO;
+ }
+
+ @Override
@Transactional(rollbackFor = Exception.class)
public void supplementClockIn(HrmAttendanceExceptionDO exception) {
// 浠呭鐞嗚ˉ鍗$被鍨�
--
Gitblit v1.9.3