package cn.iocoder.yudao.module.hrm.service.attendance; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmEmployeeScheduleListReqVO; import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmEmployeeScheduleRespVO; import cn.iocoder.yudao.module.hrm.controller.admin.attendance.vo.HrmEmployeeScheduleSaveReqVO; import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmEmployeeScheduleDO; import cn.iocoder.yudao.module.hrm.dal.dataobject.attendance.HrmShiftDO; import cn.iocoder.yudao.module.hrm.dal.dataobject.employee.HrmEmployeeDO; import cn.iocoder.yudao.module.hrm.dal.mysql.attendance.HrmEmployeeScheduleMapper; import cn.iocoder.yudao.module.hrm.dal.mysql.attendance.HrmShiftMapper; import cn.iocoder.yudao.module.hrm.dal.mysql.employee.HrmEmployeeMapper; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.time.LocalDate; import java.time.YearMonth; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*; /** * 员工排班 Service 实现类 * * @author 超级管理员 */ @Service @Validated public class HrmEmployeeScheduleServiceImpl implements HrmEmployeeScheduleService { @Resource private HrmEmployeeScheduleMapper employeeScheduleMapper; @Resource private HrmEmployeeMapper employeeMapper; @Resource private HrmShiftMapper shiftMapper; @Override public List getScheduleList(HrmEmployeeScheduleListReqVO reqVO) { YearMonth yearMonth = YearMonth.parse(reqVO.getYearMonth()); LocalDate startDate = yearMonth.atDay(1); LocalDate endDate = yearMonth.atEndOfMonth(); // 1. 按条件查询排班记录 List list; if (reqVO.getEmployeeId() != null) { list = employeeScheduleMapper.selectListByEmployeeIdAndPeriod(reqVO.getEmployeeId(), startDate, endDate); } else if (reqVO.getDeptId() != null) { List employees = employeeMapper.selectByDeptId(reqVO.getDeptId()); Set employeeIds = employees.stream().map(HrmEmployeeDO::getId).collect(Collectors.toSet()); list = CollUtil.isEmpty(employeeIds) ? Collections.emptyList() : employeeScheduleMapper.selectListByEmployeeIdsAndPeriod(employeeIds, startDate, endDate); } else { list = employeeScheduleMapper.selectListByPeriod(startDate, endDate); } if (CollUtil.isEmpty(list)) { return Collections.emptyList(); } // 2. 拼接员工信息与班次信息 Set employeeIds = list.stream().map(HrmEmployeeScheduleDO::getEmployeeId) .filter(Objects::nonNull).collect(Collectors.toSet()); Set shiftIds = list.stream().map(HrmEmployeeScheduleDO::getShiftId) .filter(Objects::nonNull).collect(Collectors.toSet()); Map employeeMap = CollUtil.isEmpty(employeeIds) ? Collections.emptyMap() : employeeMapper.selectBatchIds(employeeIds).stream() .collect(Collectors.toMap(HrmEmployeeDO::getId, Function.identity(), (a, b) -> a)); Map shiftMap = CollUtil.isEmpty(shiftIds) ? Collections.emptyMap() : shiftMapper.selectBatchIds(shiftIds).stream() .collect(Collectors.toMap(HrmShiftDO::getId, Function.identity(), (a, b) -> a)); return list.stream().map(schedule -> { HrmEmployeeScheduleRespVO respVO = new HrmEmployeeScheduleRespVO(); respVO.setId(schedule.getId()); respVO.setEmployeeId(schedule.getEmployeeId()); HrmEmployeeDO employee = schedule.getEmployeeId() == null ? null : employeeMap.get(schedule.getEmployeeId()); if (employee != null) { respVO.setEmployeeName(employee.getName()); respVO.setEmployeeNo(employee.getEmployeeNo()); } respVO.setDate(schedule.getDate()); respVO.setShiftId(schedule.getShiftId()); HrmShiftDO shift = schedule.getShiftId() == null ? null : shiftMap.get(schedule.getShiftId()); if (shift != null) { respVO.setShiftName(shift.getName()); respVO.setShiftColor(shift.getColor()); } respVO.setRemark(schedule.getRemark()); return respVO; }).collect(Collectors.toList()); } @Override @Transactional(rollbackFor = Exception.class) public void saveSchedule(List saveReqVOList) { if (CollUtil.isEmpty(saveReqVOList)) { throw exception(SCHEDULE_ITEM_LIST_EMPTY); } // 1. 校验员工存在 Set employeeIds = saveReqVOList.stream().map(HrmEmployeeScheduleSaveReqVO::getEmployeeId) .collect(Collectors.toSet()); if (CollUtil.isNotEmpty(employeeIds)) { List employees = employeeMapper.selectBatchIds(employeeIds); if (employees.size() != employeeIds.size()) { throw exception(SCHEDULE_EMPLOYEE_NOT_EXISTS); } } // 2. 校验班次存在 Set shiftIds = saveReqVOList.stream().map(HrmEmployeeScheduleSaveReqVO::getShiftId) .filter(Objects::nonNull).collect(Collectors.toSet()); if (CollUtil.isNotEmpty(shiftIds)) { List shifts = shiftMapper.selectBatchIds(shiftIds); if (shifts.size() != shiftIds.size()) { throw exception(SCHEDULE_SHIFT_NOT_EXISTS); } } // 3. 逐条 upsert:有班次则保存,无班次则删除 for (HrmEmployeeScheduleSaveReqVO reqVO : saveReqVOList) { HrmEmployeeScheduleDO existing = employeeScheduleMapper.selectByEmployeeIdAndDate( reqVO.getEmployeeId(), reqVO.getDate()); if (reqVO.getShiftId() == null) { if (existing != null) { employeeScheduleMapper.deleteById(existing.getId()); } } else { if (existing == null) { employeeScheduleMapper.insert(BeanUtils.toBean(reqVO, HrmEmployeeScheduleDO.class)); } else { existing.setShiftId(reqVO.getShiftId()); existing.setRemark(reqVO.getRemark()); employeeScheduleMapper.updateById(existing); } } } } }