|
|
@@ -167,6 +167,8 @@ public class AttendanceDetail extends AbstractDomain<String, AttendanceDetailPo>
|
|
|
String buMen = po.getBuMen();
|
|
|
String paiBanMingChen = po.getPaiBanMingChen();
|
|
|
String banCiMing = po.getBanCiMing();
|
|
|
+ String clockType = po.getClockType(); // 新增:打卡类型
|
|
|
+
|
|
|
if (BeanUtils.isEmpty(yongHuId)) {
|
|
|
throw new Exception("用户ID不能为空");
|
|
|
}
|
|
|
@@ -179,7 +181,17 @@ public class AttendanceDetail extends AbstractDomain<String, AttendanceDetailPo>
|
|
|
if (BeanUtils.isEmpty(banCiMing)) {
|
|
|
throw new Exception("考勤类型不能为空");
|
|
|
}
|
|
|
-
|
|
|
+ if (BeanUtils.isEmpty(clockType)) {
|
|
|
+ throw new Exception("打卡类型不能为空,请传入 clockType=1(上班) 或 2(下班)");
|
|
|
+ }
|
|
|
+ boolean isMorningClock;
|
|
|
+ if ("1".equals(clockType)) {
|
|
|
+ isMorningClock = true;
|
|
|
+ } else if ("2".equals(clockType)) {
|
|
|
+ isMorningClock = false;
|
|
|
+ } else {
|
|
|
+ throw new Exception("无效的打卡类型,应为 1(上班) 或 2(下班)");
|
|
|
+ }
|
|
|
// 2. 查询用户信息(检查用户是否存在,并获取工号)
|
|
|
Map<String, String> userParam = new HashMap<>();
|
|
|
userParam.put("ID_", yongHuId);
|
|
|
@@ -227,10 +239,24 @@ public class AttendanceDetail extends AbstractDomain<String, AttendanceDetailPo>
|
|
|
throw new Exception("非跨日配置中,下班时间不能小于等于上班时间");
|
|
|
}
|
|
|
|
|
|
- // 4. 构建基础信息
|
|
|
- LocalDate today = LocalDate.now();
|
|
|
- String riQi = today.format(DATE_FORMATTER);
|
|
|
- po.setRiQi(riQi);//这个后续在统计考勤中有用到必须保证有值且格式为2026-03-18
|
|
|
+ // 4. 构建班次开始/结束时间,并确定班次日期(riQi = 班次开始日期)
|
|
|
+ LocalDateTime now = LocalDateTime.of(2026, 4, 22, 05, 30, 0); // 2025年1月15日 08:30:00
|
|
|
+ // LocalDateTime now = LocalDateTime.now();
|
|
|
+ LocalDate today = now.toLocalDate();
|
|
|
+ // 临时先用今天构建班次开始时间(如果跨日且当前时间已经过了午夜,可能应该用昨天?但实际班次日期由配置和当前时间共同决定)
|
|
|
+ // 更严谨的做法:根据当前时间推断所属班次。简化:上班打卡用今天,下班打卡时如果跨日且当前时间小于上班时间,则班次开始日期为昨天。
|
|
|
+ // 但为了统一,我们根据打卡类型和当前时间计算出正确的班次开始日期。
|
|
|
+ LocalDate banCiDate = today; // 默认
|
|
|
+ if (!isMorningClock && "Y".equals(shiFouKuaRiPz)) {
|
|
|
+ // 下班打卡且跨日:如果当前时间 < 配置的上班时间(比如凌晨3点 < 22:00),说明班次开始日期是昨天
|
|
|
+ LocalTime shangBanTime = LocalTime.parse(shangBanShiJianPz);
|
|
|
+ //if (now.toLocalTime().isBefore(shangBanTime)) {
|
|
|
+ if (!now.toLocalTime().isAfter(shangBanTime)){
|
|
|
+ banCiDate = today.minusDays(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String riQi = banCiDate.format(DATE_FORMATTER);
|
|
|
+ po.setRiQi(riQi);
|
|
|
po.setShiFouKuaRi(shiFouKuaRiPz);
|
|
|
|
|
|
// 构建班次开始时间
|
|
|
@@ -239,9 +265,9 @@ public class AttendanceDetail extends AbstractDomain<String, AttendanceDetailPo>
|
|
|
po.setBanCiKaiShi(banCiKaiShi.format(DATETIME_FORMATTER));
|
|
|
|
|
|
// 构建班次结束时间(考虑跨日)
|
|
|
- LocalDate endDate = today;
|
|
|
+ LocalDate endDate = banCiDate;
|
|
|
if ("Y".equals(shiFouKuaRiPz)) {
|
|
|
- endDate = today.plusDays(1);
|
|
|
+ endDate = banCiDate.plusDays(1);
|
|
|
}
|
|
|
String banCiJieShuStr = endDate.format(DATE_FORMATTER) + " " + xiaBanShiJianPz + ":00";
|
|
|
LocalDateTime banCiJieShu = LocalDateTime.parse(banCiJieShuStr, DATETIME_FORMATTER);
|
|
|
@@ -311,18 +337,7 @@ public class AttendanceDetail extends AbstractDomain<String, AttendanceDetailPo>
|
|
|
LOGGER.info("记录{[]}读取到的existingPo{}",po.getId(),existingPo);
|
|
|
}
|
|
|
|
|
|
- // 6. 判断是上班打卡还是下班打卡
|
|
|
- LocalDateTime now = LocalDateTime.now();
|
|
|
- long timeInterval = banCiShiChang / 2; // 班次时长的一半
|
|
|
-
|
|
|
- boolean isMorningClock;
|
|
|
- if (now.toLocalDate().equals(banCiKaiShi.toLocalDate()) &&
|
|
|
- banCiKaiShi.plusMinutes(timeInterval).isAfter(now)) {
|
|
|
- isMorningClock = true; // 上班打卡
|
|
|
- } else {
|
|
|
- isMorningClock = false; // 下班打卡
|
|
|
- }
|
|
|
- LOGGER.info("记录{[]}上班or下班打卡标志:{}",po.getId(),isMorningClock);
|
|
|
+ // 6. 判断是上班打卡还是下班打卡(需要特殊考虑跨日情况)
|
|
|
if (isMorningClock) {
|
|
|
// 上班打卡
|
|
|
if (existingPo != null) {
|