package com.ruoyi.performance.service.impl;
|
|
import cn.hutool.core.date.DateTime;
|
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
import com.alibaba.excel.EasyExcel;
|
import com.alibaba.excel.ExcelWriter;
|
import com.alibaba.excel.support.ExcelTypeEnum;
|
import com.alibaba.excel.write.metadata.WriteSheet;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.google.common.util.concurrent.AtomicDouble;
|
import com.ruoyi.common.core.domain.entity.SysDictData;
|
import com.ruoyi.common.core.domain.entity.User;
|
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.performance.dto.PerformanceShiftAddDto;
|
import com.ruoyi.performance.dto.PerformanceShiftMapDto;
|
import com.ruoyi.performance.dto.StaffAttendanceDTO;
|
import com.ruoyi.performance.excel.PerformanceShiftAnnotationTextExcelData;
|
import com.ruoyi.performance.excel.PerformanceShiftExcelData;
|
import com.ruoyi.performance.excel.handler.performance.CommentWriteHandler;
|
import com.ruoyi.performance.mapper.PerformanceShiftMapper;
|
import com.ruoyi.performance.pojo.PerformanceShift;
|
import com.ruoyi.performance.pojo.StaffAttendanceTrackingRecord;
|
import com.ruoyi.performance.service.PerformanceShiftService;
|
import com.ruoyi.performance.service.StaffAttendanceTrackingRecordService;
|
import com.ruoyi.performance.vo.StaffAttendanceVO;
|
import com.ruoyi.system.mapper.UserMapper;
|
import com.ruoyi.system.service.ISysDictTypeService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.ibatis.annotations.Param;
|
import org.apache.poi.ss.usermodel.*;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.CollectionUtils;
|
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayOutputStream;
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.net.URLEncoder;
|
import java.nio.charset.StandardCharsets;
|
import java.text.SimpleDateFormat;
|
import java.time.LocalDate;
|
import java.time.LocalDateTime;
|
import java.time.LocalTime;
|
import java.time.ZoneId;
|
import java.time.format.DateTimeFormatter;
|
import java.time.temporal.TemporalAdjusters;
|
import java.util.*;
|
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.stream.Collectors;
|
|
/**
|
* <p>
|
* 绩效管理-班次 服务实现类
|
* </p>
|
*
|
* @author 江苏鵷雏网络科技有限公司
|
* @since 2024-05-08 09:12:04
|
*/
|
@Slf4j
|
@Service
|
public class PerformanceShiftServiceImpl extends ServiceImpl<PerformanceShiftMapper, PerformanceShift> implements PerformanceShiftService {
|
|
@Autowired
|
private StaffAttendanceTrackingRecordService trackingRecordService;
|
|
@Autowired
|
UserMapper userMapper;
|
|
private DateTimeFormatter yyyyMMdd = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
private DateTimeFormatter yyyyMMddHHmmss = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
private DateTimeFormatter yyyMMStr = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
|
|
private final int LIST_MAX_COUNT = 1000;
|
|
private static final String morningShiftKeyword = "早";//早班班次关键字
|
private static final String dayShiftKeyword = "中";//中班班次关键字
|
private static final String nightShiftKeyword = "夜";//夜班班次关键字
|
private static final String holidayLeaveKeyword = "休";//休假,调休假班次关键字
|
private static final String officialTripKeyword = "公";//公差班次关键字
|
private static final String personalLeaveKeyword = "事";//事假班次关键字
|
private static final String sickLeaveKeyword = "病";//病假班次关键字
|
private static final String annualLeaveKeyword = "年";//年假班次关键字
|
private static final String marriageLeaveKeyword = "婚";//婚假班次关键字
|
private static final String maternityLeaveKeyword = "产";//产假班次关键字
|
private static final String bereavementLeaveKeyword = "丧";//丧假班次关键字
|
|
private static final List<String> shiftSoreList = Arrays.asList("早","中","夜","休","公","事","病","年","婚","产","丧");
|
|
@Transactional(rollbackFor = Exception.class)
|
@Override
|
public void performanceShiftAdd(PerformanceShiftAddDto performanceShiftAddDto) {
|
//1.查询所选周次时间范围内已排班的数据
|
List<PerformanceShift> shiftList = baseMapper.selectList(Wrappers.<PerformanceShift>lambdaQuery()
|
.between(ObjectUtils.allNotNull(performanceShiftAddDto.getStartTime(), performanceShiftAddDto.getEndTime()),
|
PerformanceShift::getWorkTime, performanceShiftAddDto.getStartTime(), performanceShiftAddDto.getEndTime())
|
.in(!performanceShiftAddDto.getUserIdList().isEmpty(), PerformanceShift::getUserId, performanceShiftAddDto.getUserIdList())
|
);
|
List<LocalDateTime> timeList = getLocalDateTimesBetween(performanceShiftAddDto.getStartTime(), performanceShiftAddDto.getEndTime());
|
//处理选中人员
|
List<PerformanceShift> newShiftList = new ArrayList<>();
|
performanceShiftAddDto.getUserIdList().forEach(userId->{
|
List<PerformanceShift> oldShifts = shiftList.stream().filter(f -> Objects.equals(f.getUserId(), userId)).collect(Collectors.toList());
|
timeList.forEach(time->{
|
PerformanceShift performanceShift = oldShifts.stream().filter(f -> f.getWorkTime().isEqual(time)).findFirst().orElse(new PerformanceShift(userId, time));
|
if(Objects.isNull(performanceShift.getId())||StringUtils.isBlank(performanceShift.getShift())){
|
performanceShift.setShift(performanceShiftAddDto.getShift());
|
newShiftList.add(performanceShift);
|
}
|
});
|
if(newShiftList.size()>LIST_MAX_COUNT){
|
this.saveBatch(newShiftList);
|
newShiftList.clear();
|
}
|
});
|
if(!newShiftList.isEmpty())this.saveOrUpdateBatch(newShiftList);
|
}
|
|
private List<PerformanceShift> saveMonth (LocalDateTime week,String userId,List<PerformanceShift> list){
|
LocalDate firstDayOfMonth = week.toLocalDate().withDayOfMonth(1);
|
LocalDate lastDayOfMonth = week.toLocalDate().with(TemporalAdjusters.lastDayOfMonth());
|
List<LocalDateTime> localDateTimesBetween = getLocalDateTimesBetween(firstDayOfMonth.atStartOfDay(), lastDayOfMonth.atStartOfDay());
|
localDateTimesBetween.forEach(i -> {
|
PerformanceShift performanceShift = new PerformanceShift();
|
performanceShift.setUserId(Integer.valueOf(userId));
|
performanceShift.setWorkTime(i);
|
performanceShift.setShift("");
|
list.add(performanceShift);
|
if (list.size() >= 1000) {
|
baseMapper.insertBatchSomeColumn(list);
|
list.clear();
|
}
|
});
|
return list;
|
}
|
|
@Override
|
public Map<String, Object> performanceShift( String time, String userName, String laboratory) {
|
//查询人员架构
|
List<User> userList = userMapper.selectUserListByPerformance(false);
|
List<Integer> userIdList = userList.stream().map(User::getId).collect(Collectors.toList());
|
//班次时间范围为上个月的26号到本月的25号
|
LocalDateTime localDateTime = LocalDateTime.parse(time, yyyyMMddHHmmss);
|
LocalDate firstDayOfMonth = localDateTime.toLocalDate().minusMonths(1L).withDayOfMonth(26);
|
LocalDate lastDayOfMonth = localDateTime.toLocalDate().withDayOfMonth(25);
|
//人员排班详情
|
List<PerformanceShiftMapDto> mapIPage = baseMapper.performanceShift(firstDayOfMonth,lastDayOfMonth, userName, laboratory);
|
Map<Integer, List<PerformanceShiftMapDto>> groupByUserId = mapIPage.stream().collect(Collectors.groupingBy(PerformanceShiftMapDto::getUserId));
|
List<PerformanceShiftMapDto> newRecords = new ArrayList<>();
|
List<LocalDateTime> timeList = getLocalDateTimesBetween(LocalDateTime.of(firstDayOfMonth, LocalTime.MIN), LocalDateTime.of(lastDayOfMonth, LocalTime.MIN));
|
groupByUserId.keySet().forEach(key->{
|
PerformanceShiftMapDto shiftMapDto = new PerformanceShiftMapDto();
|
List<PerformanceShiftMapDto> shiftMapDtos = groupByUserId.get(key);
|
List<PerformanceShiftMapDto> newShiftMapDtos = new ArrayList<>();
|
timeList.forEach(t->{
|
PerformanceShiftMapDto mapDto = shiftMapDtos.stream().filter(s -> t.isEqual(s.getWorkTime())).findFirst().orElse(null);
|
if(ObjectUtils.isNotEmpty(mapDto)){
|
newShiftMapDtos.add(mapDto);
|
}else{
|
newShiftMapDtos.add(null);
|
}
|
});
|
//统计各班次天数
|
Map<String, Long> countShift = countShift(shiftMapDtos);
|
shiftMapDto.setMonthlyAttendance(countShift);
|
shiftMapDto.setMonthlyAttendanceStr(formateMap(countShift));
|
shiftMapDto.setList(newShiftMapDtos);
|
|
shiftMapDto.setUserName(shiftMapDtos.isEmpty()?"":shiftMapDtos.get(0).getUserName());
|
shiftMapDto.setUserId(key);
|
newRecords.add(shiftMapDto);
|
});
|
newRecords.sort(Comparator.comparing(r->userIdList.indexOf(r.getUserId())));
|
Map<String, Object> resultMap = new HashMap<>();
|
resultMap.put("page", newRecords);
|
resultMap.put("headerList", getYearHeaderTimeList(firstDayOfMonth,lastDayOfMonth));
|
return resultMap;
|
}
|
|
public String formateMap(Map<String, Long> map){
|
List<String> stringList = new ArrayList<>();
|
map.forEach((k,v)->{
|
if(shiftSoreList.contains(k)){
|
stringList.add(k+":"+v);
|
}
|
});
|
return String.join(",",stringList);
|
}
|
|
/**
|
* 统计班次
|
* @param shiftMapDtos 班次列表
|
*/
|
private Map<String,Long> countShift(List<PerformanceShiftMapDto> shiftMapDtos){
|
TreeMap<String, Long> targetMap = new TreeMap<>(Comparator.comparing(shiftSoreList::indexOf));
|
//汇总早班、中班、夜班、休息、请假、出差的天数,以及总出勤天数
|
Map<String, Long> groupByShiftName = shiftMapDtos.stream().filter(f-> StringUtils.isNotBlank(f.getShiftName())).collect(Collectors.groupingBy(PerformanceShiftMapDto::getShiftName,Collectors.counting()));
|
AtomicLong morningShiftCount = new AtomicLong(0);//早班
|
AtomicLong dayShiftCount = new AtomicLong(0);//中班
|
AtomicLong nightShiftCount = new AtomicLong(0);//晚班
|
AtomicLong holidayShiftCount = new AtomicLong(0);//休
|
AtomicLong totalCount = new AtomicLong(0);//总出勤天数
|
groupByShiftName.keySet().forEach(key->{
|
if(key.contains(morningShiftKeyword)){
|
morningShiftCount.getAndAdd(groupByShiftName.get(key));
|
totalCount.getAndAdd(groupByShiftName.get(key));
|
}else if(key.contains(dayShiftKeyword)){
|
dayShiftCount.getAndAdd(groupByShiftName.get(key));
|
totalCount.getAndAdd(groupByShiftName.get(key));
|
}else if(key.contains(nightShiftKeyword)){
|
nightShiftCount.getAndAdd(groupByShiftName.get(key));
|
totalCount.getAndAdd(groupByShiftName.get(key));
|
}else if(key.contains(holidayLeaveKeyword)){
|
holidayShiftCount.getAndAdd(groupByShiftName.get(key));
|
}else if(key.contains(officialTripKeyword)){
|
targetMap.put(key,groupByShiftName.get(key));
|
totalCount.getAndAdd(groupByShiftName.get(key));
|
}else{
|
targetMap.put(key,groupByShiftName.get(key));
|
}
|
});
|
targetMap.put("早",morningShiftCount.get());
|
targetMap.put("中",dayShiftCount.get());
|
targetMap.put("夜",nightShiftCount.get());
|
targetMap.put("休",holidayShiftCount.get());
|
targetMap.put("totalCount",totalCount.get());
|
return targetMap;
|
}
|
|
/**
|
* 班次分页查询:获取月度日期表头列表
|
* @param firstDayOfMonth
|
* @param lastDayOfMonth
|
* @return
|
*/
|
private List<Object> getYearHeaderTimeList(LocalDate firstDayOfMonth,LocalDate lastDayOfMonth){
|
List<LocalDateTime> localDateTimesBetween = getLocalDateTimesBetween(firstDayOfMonth.atStartOfDay(), lastDayOfMonth.atStartOfDay());
|
List<Object> list = new ArrayList<>();
|
for (LocalDateTime dateTime : localDateTimesBetween) {
|
Map<Object, Object> hashMap = new HashMap<>();
|
DateTime parse = DateUtil.parse(dateTime.format(yyyyMMdd));
|
hashMap.put("weekly", DateUtil.weekOfYear(DateUtil.offsetDay(parse, 1)));
|
hashMap.put("headerTime", getWeek(dateTime.format(yyyyMMddHHmmss)));
|
list.add(hashMap);
|
}
|
return list;
|
}
|
|
@Override
|
public void performanceShiftUpdate(PerformanceShift performanceShift) {
|
baseMapper.update(new PerformanceShift(), Wrappers.<PerformanceShift>lambdaUpdate()
|
.eq(PerformanceShift::getId, performanceShift.getId())
|
.set(PerformanceShift::getShift, performanceShift.getShift()));
|
}
|
|
@Override
|
public List<Map<String, Object>> performanceShiftPageYear(LocalDateTime time, String userName, String laboratory) {
|
//查询人员架构
|
List<User> userList = userMapper.selectUserListByPerformance(false);
|
List<Integer> userIdList = userList.stream().map(User::getId).collect(Collectors.toList());
|
if(ObjectUtil.isEmpty(time)){
|
throw new RuntimeException("查询日期不能为空");
|
}
|
LocalDateTime startDateTime = time.minusMonths(1L).withDayOfMonth(26);
|
LocalDateTime endDateTime = time.plusMonths(11L).withDayOfMonth(25);
|
List<PerformanceShiftMapDto> shiftYearList = baseMapper.performanceShiftYear(startDateTime,endDateTime, userName, laboratory);
|
//按人员分组,统计每个人的年度班次
|
Map<Integer, List<PerformanceShiftMapDto>> groupByUserId = shiftYearList.stream().collect(Collectors.groupingBy(PerformanceShift::getUserId));
|
List<Map<String,Object>> returnList = new ArrayList<>();
|
groupByUserId.keySet().forEach(userIdKey->{
|
//按月份分组,统计每个月的班次详情
|
Map<String, Object> returnMap = new HashMap<>();
|
List<PerformanceShiftMapDto> shiftMapDtos = groupByUserId.get(userIdKey);
|
Map<String, Long> sidebarAnnualAttendance = countShift(shiftMapDtos);//年度班次统计
|
List<Map<String, Object>> monthlyAttendances = new ArrayList<>();
|
if(!shiftMapDtos.isEmpty()){
|
returnMap.put("userName",shiftMapDtos.get(0).getUserName());
|
returnMap.put("userId",shiftMapDtos.get(0).getUserId());
|
//遍历12个月的班次信息
|
for (int i = 0; i < 11; i++) {
|
LocalDateTime firstDayOfMonth = startDateTime.plusMonths(i);
|
LocalDateTime lastDayOfMonth = firstDayOfMonth.plusMonths(1L).withDayOfMonth(25);
|
Map<String, Object> monthlyAttendanceMap = new HashMap<>();
|
List<PerformanceShiftMapDto> monthShiftDtos = shiftMapDtos.stream().filter(f->!f.getWorkTime().isBefore(firstDayOfMonth)&&!f.getWorkTime().isAfter(lastDayOfMonth)).collect(Collectors.toList());
|
if(CollectionUtils.isEmpty(monthShiftDtos)){
|
monthlyAttendanceMap.put("monthlyAttendanceStr",formateMap(countShift(new ArrayList<>())));//月度班次统计
|
monthlyAttendanceMap.put("monthlyAttendance",countShift(new ArrayList<>()));//月度班次统计
|
}else{
|
monthlyAttendanceMap.put("monthlyAttendanceStr",formateMap(countShift(monthShiftDtos)));//月度班次统计
|
monthlyAttendanceMap.put("monthlyAttendance",countShift(monthShiftDtos));//月度班次统计
|
}
|
monthlyAttendances.add(monthlyAttendanceMap);
|
}
|
returnMap.put("monthlyAttendances",monthlyAttendances);
|
returnMap.put("sidebarAnnualAttendance",sidebarAnnualAttendance);
|
returnMap.put("sidebarAnnualAttendanceStr",formateMap(sidebarAnnualAttendance));
|
}
|
returnList.add(returnMap);
|
});
|
returnList.sort(Comparator.comparing(r->userIdList.indexOf(Integer.parseInt(r.get("userId").toString()))));
|
return returnList;
|
}
|
|
@Override
|
public boolean editAnnotationText(PerformanceShift performanceShift) {
|
return this.updateById(performanceShift);
|
}
|
|
@Override
|
public void exportToExcel(LocalDateTime time, String userName, String laboratory, Boolean isMonth, HttpServletResponse response) {
|
response.reset();
|
try{
|
String fileName = "中天耐丝质量部班次信息"+ ExcelTypeEnum.XLSX;
|
fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
|
response.setContentType("application/vnd.ms-excel");
|
response.setHeader("Cache-Control", "no-cache");
|
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
|
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
|
Map<Object, Object> data;
|
LocalDateTime startDate;
|
LocalDateTime endDate;
|
if(!isMonth){
|
//年度统计,时间区间取一整年
|
startDate = time.minusMonths(1L).withDayOfMonth(26);
|
endDate = time.plusMonths(11L).withDayOfMonth(25);
|
}else{
|
//月度统计,时间区间取上个月26号到本月25号
|
startDate = time.minusMonths(1L).withDayOfMonth(26);
|
endDate = time.withDayOfMonth(25);
|
}
|
List<LocalDate> performanceShiftDateList = buildPerformanceShiftDateList(startDate,endDate,isMonth);
|
//批注信息坐标信息
|
List<PerformanceShiftAnnotationTextExcelData> annotationTextList = new ArrayList<>();
|
// 查询班次
|
List<PerformanceShiftMapDto> performanceShifts = baseMapper.selectListByWorkTime(startDate, endDate, userName);
|
//获取考勤数据
|
StaffAttendanceDTO staffAttendanceDTO = new StaffAttendanceDTO();
|
staffAttendanceDTO.setStartDate(startDate);
|
staffAttendanceDTO.setEndDate(endDate);
|
staffAttendanceDTO.setKeyword(userName);
|
List<StaffAttendanceVO> attendanceRecords = trackingRecordService.getAttendanceRecord(performanceShifts,staffAttendanceDTO);
|
//组装导出数据
|
List<PerformanceShiftExcelData> excelData = new ArrayList<>();
|
Map<Integer, List<PerformanceShiftMapDto>> groupByUserId = performanceShifts.stream().collect(Collectors.groupingBy(PerformanceShiftMapDto::getUserId));
|
List<Integer> userIdKeys = groupByUserId.keySet().stream().sorted().collect(Collectors.toList());
|
for (int i = 0; i < userIdKeys.size(); i++) {
|
List<PerformanceShiftMapDto> shiftMapDtos = groupByUserId.get(userIdKeys.get(i));
|
PerformanceShiftExcelData performanceShiftExcelData = new PerformanceShiftExcelData();
|
List<String> shiftList = new ArrayList<>();
|
performanceShiftExcelData.setPersonName(shiftMapDtos.get(0).getUserName());
|
performanceShiftExcelData.setExcelIndex(i+1);
|
AtomicInteger morningShiftCount = new AtomicInteger(0);//早班天数
|
AtomicInteger dayShiftCount = new AtomicInteger(0);//中班天数
|
AtomicInteger nightShiftCount = new AtomicInteger(0);//夜班天数
|
AtomicInteger holidayCount = new AtomicInteger(0);//休息天数
|
AtomicInteger personalLeaveCount = new AtomicInteger(0);//事假天数
|
AtomicInteger annualLeaveCount = new AtomicInteger(0);//年假天数
|
AtomicInteger officialTripCount = new AtomicInteger(0);//公差天数
|
AtomicInteger marriageLeaveCount = new AtomicInteger(0);//婚假天数
|
AtomicInteger bereavementLeaveCount = new AtomicInteger(0);//丧假天数
|
AtomicInteger sickLeaveCount = new AtomicInteger(0);//病假天数
|
AtomicInteger maternityLeaveCount = new AtomicInteger(0);//产假天数
|
AtomicInteger totalCount = new AtomicInteger(0);//出勤天数
|
AtomicDouble attendanceWorkHourCount = new AtomicDouble(0D);//出勤总时间
|
for (int j = 0; j < shiftMapDtos.size(); j++) {
|
PerformanceShiftMapDto shiftMapDto = shiftMapDtos.get(j);
|
//统计各班次的天数
|
if(StringUtils.contains(shiftMapDto.getShiftName(),morningShiftKeyword)){
|
morningShiftCount.getAndIncrement();
|
totalCount.getAndIncrement();
|
}else if(StringUtils.contains(shiftMapDto.getShiftName(),dayShiftKeyword)){
|
dayShiftCount.getAndIncrement();
|
totalCount.getAndIncrement();
|
}else if(StringUtils.contains(shiftMapDto.getShiftName(),nightShiftKeyword)){
|
nightShiftCount.getAndIncrement();
|
totalCount.getAndIncrement();
|
}else if(StringUtils.contains(shiftMapDto.getShiftName(),holidayLeaveKeyword)){
|
holidayCount.getAndIncrement();
|
}else if(StringUtils.contains(shiftMapDto.getShiftName(),personalLeaveKeyword)){
|
personalLeaveCount.getAndIncrement();
|
}else if(StringUtils.contains(shiftMapDto.getShiftName(),annualLeaveKeyword)){
|
annualLeaveCount.getAndIncrement();
|
}else if(StringUtils.contains(shiftMapDto.getShiftName(),officialTripKeyword)){
|
officialTripCount.getAndIncrement();
|
totalCount.getAndIncrement();
|
}else if(StringUtils.contains(shiftMapDto.getShiftName(),marriageLeaveKeyword)){
|
marriageLeaveCount.getAndIncrement();
|
}else if(StringUtils.contains(shiftMapDto.getShiftName(),bereavementLeaveKeyword)){
|
bereavementLeaveCount.getAndIncrement();
|
}else if(StringUtils.contains(shiftMapDto.getShiftName(),sickLeaveKeyword)){
|
sickLeaveCount.getAndIncrement();
|
}else if(StringUtils.contains(shiftMapDto.getShiftName(),maternityLeaveKeyword)){
|
maternityLeaveCount.getAndIncrement();
|
}
|
shiftList.add(shiftMapDto.getShiftName());
|
if(!StringUtils.isAllBlank(shiftMapDto.getStartTime(),shiftMapDto.getEndTime())){
|
//过滤当前人员的班次信息
|
StaffAttendanceVO vo = attendanceRecords.stream().filter(f-> StringUtils.isNotBlank(f.getPersonCode())).filter(f -> StringUtils.equals(f.getPersonCode(), shiftMapDto.getPersonCode()) && f.getSwingDate().isEqual(shiftMapDto.getWorkTime())).findFirst().orElse(null);
|
if(ObjectUtils.isNotEmpty(vo)){
|
String actualWorkHours = Objects.toString(vo.getActualWorkHours(), "");
|
if (StringUtils.isNotBlank(actualWorkHours)) {
|
attendanceWorkHourCount.getAndAdd(Double.parseDouble(actualWorkHours));
|
}
|
}
|
}
|
//月度统计才插入批注数据
|
if(isMonth){
|
if(StringUtils.isNotBlank(shiftMapDto.getAnnotationText())){
|
annotationTextList.add(new PerformanceShiftAnnotationTextExcelData(i,j,shiftMapDto.getAnnotationText()));
|
}
|
}
|
}
|
if(isMonth){
|
performanceShiftExcelData.setShiftNameList(shiftList);
|
}
|
performanceShiftExcelData.setTotalCount(totalCount.get());
|
//班次考勤天数
|
performanceShiftExcelData.setMorningShiftCount(morningShiftCount.get());
|
performanceShiftExcelData.setDayShiftCount(dayShiftCount.get());
|
performanceShiftExcelData.setNightShiftCount(nightShiftCount.get());
|
performanceShiftExcelData.setHolidayLeaveCount(holidayCount.get());
|
performanceShiftExcelData.setPersonalLeaveCount(personalLeaveCount.get());
|
performanceShiftExcelData.setAnnualLeaveCount(annualLeaveCount.get());
|
performanceShiftExcelData.setOfficialTripCount(officialTripCount.get());
|
performanceShiftExcelData.setMarriageLeaveCount(marriageLeaveCount.get());
|
performanceShiftExcelData.setBereavementLeaveCount(bereavementLeaveCount.get());
|
performanceShiftExcelData.setSickLeaveCount(sickLeaveCount.get());
|
performanceShiftExcelData.setMaternityLeaveCount(maternityLeaveCount.get());
|
performanceShiftExcelData.setTotalWorkHourCount(attendanceWorkHourCount.get());
|
excelData.add(performanceShiftExcelData);
|
}
|
//导出
|
InputStream resourceAsStream = buildPerformanceShiftTemplate(performanceShiftDateList,isMonth);
|
try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(resourceAsStream).registerWriteHandler(new CommentWriteHandler(excelData, annotationTextList)).relativeHeadRowIndex(4).build()) {
|
WriteSheet writeSheet = EasyExcel.writerSheet().build();
|
excelWriter.fill(excelData, writeSheet);
|
if(!isMonth){
|
String startDateStr = startDate.format(yyyMMStr);
|
String endDateStr = endDate.format(yyyMMStr);
|
Map<String, String> dateMap = new HashMap<>();
|
dateMap.put("startDate",startDateStr);
|
dateMap.put("endDate",endDateStr);
|
excelWriter.fill(dateMap, writeSheet);
|
}
|
}
|
}catch (Exception e){
|
throw new RuntimeException("班次导出异常");
|
}
|
}
|
|
private InputStream buildPerformanceShiftTemplate(List<LocalDate> attendanceDateList,Boolean isMonth) throws IOException {
|
String templateName = "/static/performance_shift_month_template.xlsx";
|
if(!isMonth){
|
templateName = "/static/performance_shift_year_template.xlsx";
|
}
|
try (InputStream templateStream = this.getClass().getResourceAsStream(templateName)) {
|
assert templateStream != null;
|
try (Workbook workbook = WorkbookFactory.create(templateStream);
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
Sheet sheet = workbook.getSheetAt(0);
|
if(isMonth){
|
fillPerformanceShiftHeader(sheet, attendanceDateList);
|
}
|
workbook.write(outputStream);
|
return new ByteArrayInputStream(outputStream.toByteArray());
|
}
|
} catch (Exception e) {
|
throw new IOException("构建班次导出模板失败", e);
|
}
|
}
|
|
private void fillPerformanceShiftHeader(Sheet sheet, List<LocalDate> attendanceDateList) {
|
if (sheet == null || attendanceDateList == null || attendanceDateList.isEmpty()) {
|
return;
|
}
|
Row titleRow = sheet.getRow(1);
|
if (titleRow != null) {
|
Cell titleCell = titleRow.getCell(0);
|
if (titleCell != null) {
|
titleCell.setCellValue(attendanceDateList.get(attendanceDateList.size() - 1).format(DateTimeFormatter.ofPattern("yyyy年M月")));
|
}
|
}
|
Row weekRow = sheet.getRow(2);
|
Row dayRow = sheet.getRow(3);
|
if (weekRow == null || dayRow == null) {
|
return;
|
}
|
final int startColumnIndex = 2;
|
final int maxDateColumnCount = 31;
|
for (int i = 0; i < maxDateColumnCount; i++) {
|
Cell weekCell = getOrCreateCell(weekRow, startColumnIndex + i, startColumnIndex);
|
Cell dayCell = getOrCreateCell(dayRow, startColumnIndex + i, startColumnIndex);
|
if (i < attendanceDateList.size()) {
|
LocalDate currentDate = attendanceDateList.get(i);
|
weekCell.setCellValue(resolveWeekOfYear(currentDate));
|
dayCell.setCellValue(currentDate.getDayOfMonth());
|
} else {
|
weekCell.setBlank();
|
dayCell.setBlank();
|
}
|
}
|
}
|
|
private Cell getOrCreateCell(Row row, int cellIndex, int templateCellIndex) {
|
Cell cell = row.getCell(cellIndex);
|
if (cell != null) {
|
return cell;
|
}
|
Cell templateCell = row.getCell(templateCellIndex);
|
cell = row.createCell(cellIndex);
|
if (templateCell != null && templateCell.getCellStyle() != null) {
|
cell.setCellStyle(templateCell.getCellStyle());
|
}
|
return cell;
|
}
|
|
private String resolveWeekOfYear(LocalDate date) {
|
switch (date.getDayOfWeek()) {
|
case MONDAY:
|
return "一";
|
case TUESDAY:
|
return "二";
|
case WEDNESDAY:
|
return "三";
|
case THURSDAY:
|
return "四";
|
case FRIDAY:
|
return "五";
|
case SATURDAY:
|
return "六";
|
case SUNDAY:
|
return "日";
|
default:
|
return "";
|
}
|
}
|
|
private List<LocalDate> buildPerformanceShiftDateList(LocalDateTime startDateTime,LocalDateTime endDateTime,Boolean isMonth) {
|
if (startDateTime == null || endDateTime == null) {
|
throw new IllegalArgumentException("导出时间范围不能为空");
|
}
|
LocalDate startDate = startDateTime.toLocalDate();
|
LocalDate endDate = endDateTime.toLocalDate();
|
if (startDate.isAfter(endDate)) {
|
throw new IllegalArgumentException("开始时间不能晚于结束时间");
|
}
|
List<LocalDate> attendanceDateList = new ArrayList<>();
|
for (LocalDate currentDate = startDate; !currentDate.isAfter(endDate); currentDate = currentDate.plusDays(1)) {
|
attendanceDateList.add(currentDate);
|
}
|
if (attendanceDateList.size() > 31 && isMonth) {
|
throw new IllegalArgumentException("导出时间范围不能超过31天");
|
}
|
return attendanceDateList;
|
}
|
|
// 获取两个localDateTime的每一天
|
public static List<LocalDateTime> getLocalDateTimesBetween(LocalDateTime start, LocalDateTime end) {
|
List<LocalDateTime> localDateTimes = new ArrayList<>();
|
LocalDate currentDate = start.toLocalDate();
|
LocalDateTime currentLocalDateTime = start;
|
while (!currentDate.isAfter(end.toLocalDate())) {
|
localDateTimes.add(currentLocalDateTime);
|
currentLocalDateTime = currentLocalDateTime.plusDays(1);
|
currentDate = currentDate.plusDays(1);
|
}
|
return localDateTimes;
|
}
|
|
public static String getWeek(String dayStr) {
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
try {
|
Date date = sdf.parse(dayStr);
|
Calendar calendar = Calendar.getInstance();
|
calendar.setTime(date);
|
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
|
int day = calendar.get(Calendar.DAY_OF_MONTH);
|
return day + " " + getWeekDay(dayOfWeek);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return null;
|
}
|
|
public static String getWeekDay(int dayOfWeek) {
|
switch (dayOfWeek) {
|
case Calendar.MONDAY:
|
return "周一";
|
case Calendar.TUESDAY:
|
return "周二";
|
case Calendar.WEDNESDAY:
|
return "周三";
|
case Calendar.THURSDAY:
|
return "周四";
|
case Calendar.FRIDAY:
|
return "周五";
|
case Calendar.SATURDAY:
|
return "周六";
|
case Calendar.SUNDAY:
|
return "周日";
|
default:
|
return "未知";
|
}
|
}
|
}
|