记录代码编写。
/**
* @Author linht
* @Date 2023/2/13 9:34
**/
@Service
@Slf4j
public class ByhAttendanceServiceImpl implements ByhAttendanceService {
private static final int INSERT_CODE = 1,UPDATE_CODE = 2;
@Autowired
private ByhAttendanceMapper byhAttendanceMapper;
@Transactional(rollbackFor = Exception.class)
@Override
public void addSchedule(ByhAttendanceDTO byhAttendanceDTO) {
// 排班日期
List<String> daysBetween = getDaysBetween(byhAttendanceDTO.getStartDay(), byhAttendanceDTO.getEndDay());
List<UserShiftDTO> userShiftDTOList = byhAttendanceDTO.getUserShiftDTOList();
// 校验排班计划
this.checkSchedule(byhAttendanceDTO,INSERT_CODE);
List<ByhAttendance> byhAttendanceList = daysBetween.stream()
.flatMap(day -> userShiftDTOList.stream().map(userShiftDTO -> {
ByhAttendance byhAttendance = new ByhAttendance();
byhAttendance.setScheduleDate(day);
byhAttendance.setIsHoliday(this.checkIsHoliday(day));
byhAttendance.setIsLeave("0");
byhAttendance.setRemark(byhAttendanceDTO.getRemark());
byhAttendance.setShift(userShiftDTO.getShift());
return byhAttendance;
})).collect(Collectors.toList());
byhAttendanceMapper.insertBatch(byhAttendanceList);
// 保存排班人员关联
List<ByhAttendanceUserAssociate> byhAttendanceUserAssociateList = IntStream.range(0, byhAttendanceList.size())
.mapToObj(i -> {
ByhAttendance byhAttendance = byhAttendanceList.get(i);
ByhAttendanceUserAssociate byhAttendanceUserAssociate = new ByhAttendanceUserAssociate();
byhAttendanceUserAssociate.setUserId(userShiftDTOList.get(i % userShiftDTOList.size()).getUserId());
byhAttendanceUserAssociate.setCode(byhAttendanceDTO.getCode());
byhAttendanceUserAssociate.setAttendanceId(byhAttendance.getId());
return byhAttendanceUserAssociate;
}).collect(Collectors.toList());
byhAttendanceMapper.insertUserBatch(byhAttendanceUserAssociateList);
}
@Override
public Map<String,Object> list(RequestParams<AttendanceQueryDTO> requestParams) {
AttendanceQueryDTO attendanceQueryDTO = requestParams.getData();
List<ByhAttendanceVO> list = byhAttendanceMapper.list(attendanceQueryDTO);
// 姓名需要二次过滤
if (attendanceQueryDTO != null && StringUtils.isNotBlank(attendanceQueryDTO.getName())){
list = list.stream().filter(item -> item.getTableUserVO().getName().contains(attendanceQueryDTO.getName())).collect(Collectors.toList());
}
// 分页返回
List<ByhAttendanceVO> byhAttendanceVOS = CalculateUtil.pageT(list, requestParams.getPageNum(), requestParams.getPageSize());
List<ByhAttendanceVO> finalList = list;
return new HashMap<String,Object>(2){{
put("list",byhAttendanceVOS);
put("total", finalList.size());
}};
}
@Override
public ByhAttendanceVO queryById(Integer id) {
return byhAttendanceMapper.queryById(id);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateSchedule(ByhAttendanceDTO byhAttendanceDTO) {
// 校验排班计划
this.checkSchedule(byhAttendanceDTO,UPDATE_CODE);
byhAttendanceMapper.updateSchedule(new ByhAttendance().setId(byhAttendanceDTO.getId()).setScheduleDate(byhAttendanceDTO.getStartDay())
.setShift(byhAttendanceDTO.getUserShiftDTOList().get(0).getShift())
.setRemark(byhAttendanceDTO.getRemark()));
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteSchedule(List<Integer> ids) {
byhAttendanceMapper.deleteSchedule(ids);
}
@Override
public Map<String, Object> ruleList(RequestParams<ByhAttendanceRuleDTO> requestParams) {
Page<List<ByhAttendanceRule>> page = PageHelper.startPage(requestParams.getPageNum(), requestParams.getPageSize());
List<ByhAttendanceRule> byhAttendanceRules = byhAttendanceMapper.ruleList(requestParams.getData());
return new HashMap<String,Object>(2){{
put("list",byhAttendanceRules);
put("total", page.getTotal());
}};
}
@Transactional(rollbackFor = Exception.class)
@Override
public void addRule(ByhAttendanceRule byhAttendanceRule) {
// 校验考勤规则
this.checkRule(byhAttendanceRule,INSERT_CODE);
byhAttendanceMapper.addRule(byhAttendanceRule);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateRule(ByhAttendanceRule byhAttendanceRule) {
// 校验考勤规则
this.checkRule(byhAttendanceRule,UPDATE_CODE);
byhAttendanceMapper.updateRule(byhAttendanceRule);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteRule(List<Integer> ids) {
}
@Override
public Map<String, Object> recordList(RequestParams<ByhAttendanceRecordDTO> requestParams) {
ByhAttendanceRecordDTO data = requestParams.getData();
List<ByhAttendanceRecord> list = byhAttendanceMapper.recordList(data);
// 姓名需要二次过滤
if (data != null && StringUtils.isNotBlank(data.getName())){
list = list.stream().filter(item -> item.getName().contains(data.getName())).collect(Collectors.toList());
}
// 分页返回
List<ByhAttendanceRecord> byhAttendanceRecords = CalculateUtil.pageT(list, requestParams.getPageNum(), requestParams.getPageSize());
List<ByhAttendanceRecord> finalList = list;
return new HashMap<String,Object>(2){{
put("list",byhAttendanceRecords);
put("total", finalList.size());
}};
}
@Override
public Map<String, Object> attendanceStatistics(RequestParams<ByhAttendanceRecordDTO> requestParams) {
ByhAttendanceRecordDTO data = requestParams.getData();
String startDay = data.getStartDay();
String endDay = data.getEndDay();
List<ByhAttendanceRecord> attendanceRecords = (List<ByhAttendanceRecord>) this.recordList(requestParams).get("list");
Map<String, List<ByhAttendanceRecord>> attendanceRecordMap = attendanceRecords.stream()
.collect(Collectors.groupingBy(ByhAttendanceRecord::getName));
List<ByhAttendanceCountVO> attendanceCountVOs = new ArrayList<>();
attendanceRecordMap.entrySet().forEach(entry -> {
String name = entry.getKey();
List<ByhAttendanceRecord> records = entry.getValue();
ByhAttendanceCountVO attendanceCountVO = countAttendance(records, startDay, endDay);
attendanceCountVO.setName(name);
attendanceCountVOs.add(attendanceCountVO);
});
Map<String, Object> resultMap = new HashMap<>(2);
resultMap.put("list", attendanceCountVOs);
resultMap.put("total", attendanceCountVOs.size());
return resultMap;
}
/**
* 考勤统计
* @param records 考勤记录
* @param startDay 开始日期
* @param endDay 结束日期
*/
private ByhAttendanceCountVO countAttendance(List<ByhAttendanceRecord> records, String startDay, String endDay) {
ByhAttendanceCountVO attendanceCountVO = new ByhAttendanceCountVO();
attendanceCountVO.setTime(startDay + "-" + endDay);
attendanceCountVO.setTableName(records.get(0).getTableName());
int chuDay = (int) records.stream().filter(record -> isBetween(record.getScheduleDate(),startDay,endDay)).count();
attendanceCountVO.setChuDay(String.valueOf(chuDay));
int qingDay = (int) records.stream().filter(record -> Objects.equals(record.getAttendanceStatus(), AttendanceStatusEnum.LEAVE.getCode())).count();
attendanceCountVO.setQingDay(String.valueOf(qingDay));
int jieDay = (int) records.stream().filter(record -> HolidayConstant.isHoliday(record.getScheduleDate())).count();
attendanceCountVO.setJieDay(String.valueOf(jieDay));
int xiuDay = this.getDaysBetween(startDay,endDay).size() - chuDay - qingDay;
attendanceCountVO.setXiuDay(String.valueOf(xiuDay));
int zaoDay = (int) records.stream().filter(record -> Objects.equals(record.getShift(), "1")).count();
attendanceCountVO.setZaoDay(String.valueOf(zaoDay));
int zhongDay = (int) records.stream().filter(record -> Objects.equals(record.getShift(), "2")).count();
attendanceCountVO.setZhongDay(String.valueOf(zhongDay));
int wanDay = (int) records.stream().filter(record -> Objects.equals(record.getShift(), "3")).count();
attendanceCountVO.setWangDay(String.valueOf(wanDay));
int yichangNum = (int) records.stream().filter(record -> Objects.equals(record.getAttendanceStatus(), AttendanceStatusEnum.ABNORMAL.getCode())).count();
attendanceCountVO.setYichangNum(String.valueOf(yichangNum));
return attendanceCountVO;
}
/**
* 判断某个日期是否在某个日期区间内
* @param date 日期
* @param startDay 开始日期
* @param endDay 结束日期
*/
private boolean isBetween(String date, String startDay, String endDay) {
LocalDate localDate = LocalDate.parse(date);
LocalDate startDate = LocalDate.parse(startDay);
LocalDate endDate = LocalDate.parse(endDay);
return !localDate.isBefore(startDate) && !localDate.isAfter(endDate);
}
/**
* 校验考勤规则
*/
private void checkRule(ByhAttendanceRule byhAttendanceRule,int type) {
if (byhAttendanceMapper.isRuleUnique(byhAttendanceRule)){
throw new GzsendiException("({})不唯一,不能提交",byhAttendanceRule.getRuleName());
}
if(type == INSERT_CODE && byhAttendanceMapper.isRuleEnable(byhAttendanceRule)){
throw new GzsendiException("该类型的考勤规则已启用,请先禁用");
}
if(type == UPDATE_CODE && byhAttendanceMapper.isRuleEnable(byhAttendanceRule) ){
throw new GzsendiException("该类型的考勤规则已启用,请先禁用");
}
}
/**
* 校验是否已有排班计划
* @param
* @param type 1:新增 2:修改
*/
private void checkSchedule(ByhAttendanceDTO byhAttendanceDTO,int type) {
List<String> daysBetween = getDaysBetween(byhAttendanceDTO.getStartDay(), byhAttendanceDTO.getEndDay());
// 校验是否已有排班计划
List<AttendanceCheckDTO> checkDTOS = daysBetween.stream().flatMap(day -> byhAttendanceDTO.getUserShiftDTOList().stream().map(userShiftDTO -> {
AttendanceCheckDTO attendanceCheckDTO = new AttendanceCheckDTO();
attendanceCheckDTO.setScheduleDate(day);
attendanceCheckDTO.setShift(userShiftDTO.getShift());
attendanceCheckDTO.setCode(byhAttendanceDTO.getCode());
attendanceCheckDTO.setUserId(userShiftDTO.getUserId());
attendanceCheckDTO.setRemark(byhAttendanceDTO.getRemark());
return attendanceCheckDTO;
})).collect(Collectors.toList());
checkDTOS.forEach(attendanceCheckDTO -> {
TableUserVO tableUserVO = byhAttendanceMapper.queryUserInfo(attendanceCheckDTO.getUserId(), attendanceCheckDTO.getTableName());
boolean existSchedule = byhAttendanceMapper.isExistSchedule(attendanceCheckDTO);
if (existSchedule){
throw new GzsendiException(tableUserVO.getName()+"在"+attendanceCheckDTO.getScheduleDate()+"已有排班计划");
}
});
}
/**
* 校验是否节假日,是1,否0
* @param date 日期
*/
private String checkIsHoliday(String date) {
return HolidayConstant.isHoliday(date) ? "1" : "0";
}
/**
* 获取两个日期之间的所有日期
* @param startDay 开始日期
* @param endDay 结束日期
*/
private List<String> getDaysBetween(String startDay, String endDay) {
List<String> days = new ArrayList<>();
LocalDate startDate = LocalDate.parse(startDay);
LocalDate endDate = LocalDate.parse(endDay);
while (!startDate.isAfter(endDate)) {
days.add(startDate.toString());
startDate = startDate.plusDays(1);
}
return days;
}
}