sql
SELECT
'vacation' AS keyCode,
staff.staff_id AS staffId,
staff.staff_name AS staffName,
SUM(DATEDIFF(LEAST(staff.end_time, #{endDate}), GREATEST(staff.begin_time, #{startDate}))) AS vacationDays,
NULL AS lateDays,
NULL AS absenceDays,
NULL AS attendanceDays
FROM tb_staff_stop_receive_time AS staff
WHERE staff.stop_type = 1
AND (staff.begin_time BETWEEN #{startDate} AND #{endDate} OR staff.end_time BETWEEN #{startDate} AND #{endDate})
GROUP BY staff.staff_id
UNION ALL
SELECT
'late' AS keyCode,
staff.id AS staffId,
staff.staff_name AS staffName,
NULL AS vacationDays,
COUNT(*) AS lateDays,
NULL AS absenceDays,
NULL AS attendanceDays
FROM tb_staff_stop_receive_time AS staff
JOIN eb_store_order AS O ON staff.id = O.delivery_id
WHERE O.staff_late = 1
AND O.create_time BETWEEN #{startDate} AND #{endDate}
GROUP BY staff.id
UNION ALL
SELECT
'absence' AS keyCode,
staff.id AS staffId,
staff.staff_name AS staffName,
NULL AS vacationDays,
NULL AS lateDays,
COUNT(*) AS absenceDays,
NULL AS attendanceDays
FROM tb_staff_stop_receive_time AS staff
JOIN eb_store_order AS O ON staff.id = O.delivery_id
WHERE O.status NOT IN (2, 3, 4, 5) AND O.order_service_time < CURRENT_TIMESTAMP
AND O.create_time BETWEEN #{startDate} AND #{endDate}
GROUP BY staff.id
UNION ALL
SELECT
'attendance' AS keyCode,
staff.id AS staffId,
staff.staff_name AS staffName,
NULL AS vacationDays,
NULL AS lateDays,
NULL AS absenceDays,
COUNT(*) AS attendanceDays
FROM tb_staff_stop_receive_time AS staff
JOIN eb_store_order AS O ON staff.id = O.delivery_id
WHERE O.status = 2
AND O.create_time BETWEEN #{startDate} AND #{endDate}
GROUP BY staff.id
java
/*同比出勤*/
List<AbsenceThisWeekVo> getAbsenceThisWeek(@Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate);
java
int totalAbsenceCount = lateOrders.stream()
.filter(order -> order.getState() == 0 || order.getState() == 1)
.mapToInt(AbsenceThisWeekVo::getCount)
.sum();
//未出勤的
int totalAbsenceCountLast = lateOrders.stream()
.filter(order -> order.getState() == 2 || order.getState() == 3
|| order.getState() == 4 || order.getState() == 5)
.mapToInt(AbsenceThisWeekVo::getCount)
.sum();
java
public String getStaffPercentage(double count, double totalCount){
String rate = "0%";
if (totalCount == 0) {
throw new RuntimeException("分母/数据为0,无法计算!");
} else {
// 使用BigDecimal进行精确的数值计算
BigDecimal countBD = BigDecimal.valueOf(count);
BigDecimal totalCountBD = BigDecimal.valueOf(totalCount);
// 计算百分比
BigDecimal percentageBD = NumberUtil.div(countBD.toString(), totalCountBD.toString(), 2)
.multiply(BigDecimal.valueOf(100));
rate = percentageBD.intValue() + "%";
}
return rate;
}
java
public List<StaffAttendanceResponse> getStaffAttendance(Date startDate, Date endDate) {
//会查询出一个id有多条记录,要做的就是,将这些多条的数据,根据唯一id合成一条完整的
List<StaffAttendanceResponse> attendanceDaysList2 = statisticsStaffDao.getAttendanceDays(startDate, endDate);
// 创建一个 Map 用于存储每个员工的 StaffAttendanceResponse
Map<Integer, StaffAttendanceResponse> responseMap = new HashMap<>();
for (StaffAttendanceResponse response : attendanceDaysList2) {
Integer staffId = response.getStaffId();
StaffAttendanceResponse individualResponse;
if (CollectionUtil.isNotEmpty(responseMap) &&responseMap.containsKey(staffId) ) {
individualResponse = responseMap.get(staffId);
} else {
individualResponse = new StaffAttendanceResponse();
BeanUtils.copyProperties(response,individualResponse);
}
// 没有id创建一个新的 StaffAttendanceResponse 对象
// StaffAttendanceResponse individualResponse = responseMap.getOrDefault(staffId, new StaffAttendanceResponse());
switch (response.getKeyCode()) {
case "vacation":
individualResponse.setVacationDays(response.getVacationDays());
break;
case "late":
individualResponse.setLateDays(response.getLateDays());
break;
case "absence":
individualResponse.setAbsenceDays(response.getAbsenceDays());
break;
case "attendance":
individualResponse.setAttendanceDays(response.getAttendanceDays());
break;
default:
throw new ServiceException("数据错误!");
}
// 更新 Map
responseMap.put(staffId, individualResponse);
}
// 转换 Map 的值为 List 并返回
return new ArrayList<>(responseMap.values());
}
List<StaffAttendanceResponse> attendanceResponse = getVacationDaysByType(type,this::getStaffAttendance);
StaffCircleVo StaffCircleResponse = getVacationDaysByType(typeCircle,this::getTotalVacationDays);
得到固定时间
java
public interface StaffAttendanceFetcher<T> {
T fetch(Date startDate, Date endDate);
}
public <T> T getVacationDaysByType(String type, StaffAttendanceFetcher<T> fetcher) {
Calendar cal = Calendar.getInstance();
Date start = null, end = null;
switch (type) {
case "TODAY":
LocalDateTime startOfDay = LocalDate.now().atStartOfDay();
LocalDateTime endOfDay = LocalDate.now().atTime(23, 59, 59);
start = Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());
end = Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());
break;
case "WEEK":
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
start = cal.getTime();
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
end = cal.getTime();
break;
case "MONTH":
cal.set(Calendar.DAY_OF_MONTH, 1);
start = cal.getTime();
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
end = cal.getTime();
break;
case "YEAR":
cal.set(Calendar.DAY_OF_YEAR, 1);
start = cal.getTime();
cal.set(Calendar.DAY_OF_YEAR, cal.getActualMaximum(Calendar.DAY_OF_YEAR));
end = cal.getTime();
break;
default:
throw new IllegalArgumentException("请输入正确的参数: " + type + "TODAY,WEEK, MONTH, YEAR.");
}
return fetcher.fetch(start, end);
}