|
|
@@ -584,19 +584,7 @@ public class DkRecordServiceImpl implements DkRecordService { |
|
|
|
setCellValue(sheet, rowIndex, 11, record.getQingjia()); |
|
|
|
setCellValue(sheet, rowIndex, 12, record.getRemark()); |
|
|
|
} |
|
|
|
//查询两个时间的时间差 以0.5为准 多的按0.5算 少的 为0 |
|
|
|
public static Double getHalfHourDiffAsCleanString(String startTime, String endTime) { |
|
|
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
|
|
|
LocalDateTime start = LocalDateTime.parse(startTime, formatter); |
|
|
|
LocalDateTime end = LocalDateTime.parse(endTime, formatter); |
|
|
|
|
|
|
|
long seconds = Duration.between(start, end).getSeconds(); |
|
|
|
double hours = seconds / 3600.0; |
|
|
|
|
|
|
|
// 每0.5小时为单位,舍去不足 |
|
|
|
double stepped = Math.floor(hours * 2) / 2.0; |
|
|
|
return stepped; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------日本 --------------------------*/ |
|
|
|
|
|
|
@@ -623,10 +611,31 @@ public class DkRecordServiceImpl implements DkRecordService { |
|
|
|
// 根据用户的ID 和月份查询该用户所有的打卡记录 |
|
|
|
LambdaQueryWrapper<DkCheckInRecord> queryWrapper = buildQueryWrapper(dkCheckInRecordDTO); |
|
|
|
List<DkCheckInRecordDTO> dkCheckInRecordDTOS = dkMapper.selectVoList(queryWrapper); |
|
|
|
|
|
|
|
//根据userId获取打卡配置信息 |
|
|
|
DkAttendanceGroup dkAttendanceGroup = dkMapper.queryConfigByUserId(dkCheckInRecordDTO.getSysUserId()); |
|
|
|
|
|
|
|
// 构造excel数据 |
|
|
|
for(DkCheckInRecordDTO dk : dkCheckInRecordDTOS){ |
|
|
|
// 根据打卡时间获取打卡日期 |
|
|
|
LocalDate localDate = dk.getCheckInTime() != null ? dk.getCheckInTime().toLocalDate() : LocalDate.now(); |
|
|
|
|
|
|
|
// 获取所属考勤组的上班打卡时间 |
|
|
|
String workStartTime = dkAttendanceGroup.getWorkStartTime(); |
|
|
|
LocalDateTime workStartTime1 = LocalDateTime.of(localDate, LocalTime.parse(workStartTime)); |
|
|
|
// 获取所属考勤组的下班打卡时间 |
|
|
|
String workEndTime = dkAttendanceGroup.getWorkEndTime(); |
|
|
|
LocalDateTime workEndTime1 = LocalDateTime.of(localDate, LocalTime.parse(workEndTime)); |
|
|
|
|
|
|
|
// 获取所属考勤组的午休开始时间 |
|
|
|
String lunchStartTime = dkAttendanceGroup.getLunchStartTime(); |
|
|
|
LocalDateTime lunchStartTime1 = LocalDateTime.of(localDate, LocalTime.parse(lunchStartTime)); |
|
|
|
// 获取所属考勤组的午休结束时间 |
|
|
|
String lunchEndTime = dkAttendanceGroup.getLunchEndTime(); |
|
|
|
LocalDateTime lunchEndTime1 = LocalDateTime.of(localDate, LocalTime.parse(lunchEndTime)); |
|
|
|
// 获取所属考勤组的午休时间 |
|
|
|
String lunchTime = dkAttendanceGroup.getLunchTime(); |
|
|
|
|
|
|
|
// 构造DayRecord |
|
|
|
DayRecord dayRecord = new DayRecord(); |
|
|
|
|
|
|
@@ -635,6 +644,12 @@ public class DkRecordServiceImpl implements DkRecordService { |
|
|
|
//下班打卡 |
|
|
|
dayRecord.setEndTime(null != dk.getClockOut() ? dk.getClockOut().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : ""); |
|
|
|
dayRecord.setDay(dayRecord.getStartTime()==""?0:localDate.getDayOfMonth()); |
|
|
|
|
|
|
|
//一天工作时间 |
|
|
|
double rbHalf = calculateWorkHours(dk.getClockIn(), dk.getClockOut(), |
|
|
|
workStartTime1, workEndTime1, |
|
|
|
lunchStartTime1, lunchEndTime1); |
|
|
|
dayRecord.setRbHalf(rbHalf); |
|
|
|
dayRecords.add(dayRecord); |
|
|
|
} |
|
|
|
|
|
|
@@ -675,37 +690,28 @@ public class DkRecordServiceImpl implements DkRecordService { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Double hj = null; |
|
|
|
double hj = 0d; |
|
|
|
//考勤信息区域 |
|
|
|
for (DayRecord record : data.getDayRecords()) { |
|
|
|
if(record.getDay() >0 &&record.getDay()<=31){ |
|
|
|
Double half = fillTemplateRiBenCell(sheet, record.getDay()+9, record); |
|
|
|
//合计计算一共多少工时 |
|
|
|
if(half!=null) { |
|
|
|
if (hj!=null) { |
|
|
|
hj = hj + half ; |
|
|
|
} else { |
|
|
|
hj = half; |
|
|
|
} |
|
|
|
} |
|
|
|
fillTemplateRiBenCell(sheet, record.getDay()+9, record); |
|
|
|
hj = hj+record.getRbHalf(); |
|
|
|
} |
|
|
|
} |
|
|
|
//合计区域 |
|
|
|
setCellValue(sheet, 41, 7, hj==null?"":hj); |
|
|
|
setCellValue(sheet, 41, 7, hj==0d?"":hj); |
|
|
|
|
|
|
|
} |
|
|
|
//日本excel 打卡信息赋值 |
|
|
|
private Double fillTemplateRiBenCell(Sheet sheet, int rowIndex, DayRecord record) { |
|
|
|
private void fillTemplateRiBenCell(Sheet sheet, int rowIndex, DayRecord record) { |
|
|
|
//1. 备注 |
|
|
|
setCellValue(sheet, rowIndex, 8, record.getRemark()); |
|
|
|
|
|
|
|
String startTime = record.getStartTime(); |
|
|
|
String endTime = record.getEndTime(); |
|
|
|
//2. 计算差值 |
|
|
|
Double half = null; |
|
|
|
//2. 获取一天的工时 |
|
|
|
if (StringUtils.isNotBlank(startTime)&&StringUtils.isNotBlank(endTime)) { |
|
|
|
half = getHalfHourDiffAsCleanString(startTime, endTime); |
|
|
|
setCellValue(sheet, rowIndex, 7, half); |
|
|
|
setCellValue(sheet, rowIndex, 7, record.getRbHalf()==0d?"":record.getRbHalf()); |
|
|
|
} else { |
|
|
|
setCellValue(sheet, rowIndex, 7, ""); |
|
|
|
} |
|
|
@@ -719,9 +725,6 @@ public class DkRecordServiceImpl implements DkRecordService { |
|
|
|
} |
|
|
|
setCellValue(sheet, rowIndex, 3, startTime); |
|
|
|
setCellValue(sheet, rowIndex, 4, endTime); |
|
|
|
|
|
|
|
return half; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@@ -769,6 +772,56 @@ public class DkRecordServiceImpl implements DkRecordService { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 日本模板 计算一天的工作时长(以0.5小时为最小单位) |
|
|
|
*/ |
|
|
|
public static double calculateWorkHours( |
|
|
|
LocalDateTime clockIn, |
|
|
|
LocalDateTime clockOut, |
|
|
|
LocalDateTime workStartTime, |
|
|
|
LocalDateTime workEndTime, |
|
|
|
LocalDateTime lunchStartTime, |
|
|
|
LocalDateTime lunchEndTime) { |
|
|
|
|
|
|
|
if (clockIn == null || clockOut == null) { |
|
|
|
return 0.0; |
|
|
|
} |
|
|
|
|
|
|
|
// 1. 上班时间取规定与打卡的较晚者 |
|
|
|
LocalDateTime actualStart = clockIn.isBefore(workStartTime) ? workStartTime : clockIn; |
|
|
|
|
|
|
|
// 2. 下班时间取打卡与规定的较早者(如果早于0.5小时以内仍算正常下班) |
|
|
|
LocalDateTime actualEnd = clockOut; |
|
|
|
|
|
|
|
// 如果下班比规定下班早 <= 0.5小时,按规定时间算(不算加班) |
|
|
|
Duration diff = Duration.between(clockOut, workEndTime); |
|
|
|
if (!diff.isNegative() && diff.toMinutes() <= 30) { |
|
|
|
actualEnd = workEndTime; |
|
|
|
} |
|
|
|
|
|
|
|
// 3. 计算总时长 |
|
|
|
long totalMinutes = Duration.between(actualStart, actualEnd).toMinutes(); |
|
|
|
|
|
|
|
// 4. 扣除午休时长(如果上班时间和下班时间跨越了午休) |
|
|
|
long lunchMinutes = 0; |
|
|
|
if (actualStart.isBefore(lunchEndTime) && actualEnd.isAfter(lunchStartTime)) { |
|
|
|
// 午休重叠部分 |
|
|
|
LocalDateTime lunchStart = actualStart.isAfter(lunchStartTime) ? actualStart : lunchStartTime; |
|
|
|
LocalDateTime lunchEnd = actualEnd.isBefore(lunchEndTime) ? actualEnd : lunchEndTime; |
|
|
|
lunchMinutes = Duration.between(lunchStart, lunchEnd).toMinutes(); |
|
|
|
} |
|
|
|
|
|
|
|
totalMinutes -= lunchMinutes; |
|
|
|
|
|
|
|
if (totalMinutes <= 0) { |
|
|
|
return 0.0; |
|
|
|
} |
|
|
|
|
|
|
|
// 5. 按0.5小时为单位取整 |
|
|
|
double hours = totalMinutes / 60.0; |
|
|
|
// 向下取到0.5小时倍数 |
|
|
|
return Math.floor(hours * 2) / 2.0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|