liyong
3 天以前 35b42db401542f3a85b2670873363ad4025da3d4
排班计划提交修改
已修改4个文件
69 ■■■■■ 文件已修改
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/MesCalPlanRespVO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/MesCalPlanSaveReqVO.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/cal/plan/MesCalPlanDO.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/cal/team/MesCalTeamShiftServiceImpl.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/MesCalPlanRespVO.java
@@ -52,6 +52,10 @@
    @ExcelProperty("状态")
    private Integer status;
    @Schema(description = "是否排除周末", example = "true")
    @ExcelProperty("是否排除周末")
    private Boolean excludeWeekend;
    @Schema(description = "备注")
    @ExcelProperty("备注")
    private String remark;
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/cal/plan/vo/MesCalPlanSaveReqVO.java
@@ -47,7 +47,10 @@
    @Schema(description = "状态", example = "0")
    private Integer status;
    @Schema(description = "是否排除周末", example = "true")
    private Boolean excludeWeekend;
    @Schema(description = "备注")
    private String remark;
    }
}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/cal/plan/MesCalPlanDO.java
@@ -78,6 +78,14 @@
     */
    private Integer status;
    /**
     * 是否排除周末
     *
     * true:周六日不生成排班记录(默认)
     * false:周六日正常排班(如注塑车间需要连续生产)
     */
    private Boolean excludeWeekend;
    /**
     * 备注
     */
    private String remark;
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/cal/team/MesCalTeamShiftServiceImpl.java
@@ -1,13 +1,16 @@
package cn.iocoder.yudao.module.mes.service.cal.team;
import cn.iocoder.yudao.module.mes.controller.admin.cal.team.vo.shift.MesCalTeamShiftListReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.cal.holiday.MesCalHolidayDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.cal.plan.MesCalPlanDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.cal.plan.MesCalPlanShiftDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.cal.plan.MesCalPlanTeamDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.cal.team.MesCalTeamShiftDO;
import cn.iocoder.yudao.module.mes.dal.mysql.cal.team.MesCalTeamShiftMapper;
import cn.iocoder.yudao.module.mes.enums.cal.MesCalHolidayTypeEnum;
import cn.iocoder.yudao.module.mes.enums.cal.MesCalShiftMethodEnum;
import cn.iocoder.yudao.module.mes.enums.cal.MesCalShiftTypeEnum;
import cn.iocoder.yudao.module.mes.service.cal.holiday.MesCalHolidayService;
import cn.iocoder.yudao.module.mes.service.cal.plan.MesCalPlanService;
import cn.iocoder.yudao.module.mes.service.cal.plan.MesCalPlanShiftService;
import cn.iocoder.yudao.module.mes.service.cal.plan.MesCalPlanTeamService;
@@ -18,11 +21,14 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.CAL_TEAM_SHIFT_GENERATE_SHIFT_NOT_ENOUGH;
@@ -49,6 +55,9 @@
    @Resource
    @Lazy
    private MesCalPlanTeamService planTeamService;
    @Resource
    @Lazy
    private MesCalHolidayService holidayService;
    @Transactional(rollbackFor = Exception.class)
    @Override
@@ -69,23 +78,56 @@
            throw exception(CAL_TEAM_SHIFT_GENERATE_SHIFT_NOT_ENOUGH);
        }
        // 2. 计算日期跨度,遍历每天生成排班记录,最后统一写入数据库
        // 1.5 加载日期区间内的假日数据,构建 Map<日期, 类型>
        Map<LocalDate, Integer> holidayMap = holidayService.getHolidayList(plan.getStartDate(), plan.getEndDate())
                .stream().collect(Collectors.toMap(h -> h.getDay().toLocalDate(), MesCalHolidayDO::getType));
        // 2. 计算日期跨度,逐天判断工作日,生成排班记录
        LocalDate startDate = plan.getStartDate().toLocalDate();
        LocalDate endDate = plan.getEndDate().toLocalDate();
        long days = ChronoUnit.DAYS.between(startDate, endDate) + 1;
        boolean excludeWeekend = plan.getExcludeWeekend() != null && plan.getExcludeWeekend();
        List<MesCalTeamShiftDO> allRecords = new ArrayList<>();
        int shiftIndex = 0;
        int workdayOffset = 0; // 仅工作日递增,用于倒班轮换计数
        for (int i = 0; i < days; i++) {
            LocalDate currentDate = startDate.plusDays(i);
            // 2.1 跳过非工作日
            if (!isWorkday(currentDate, holidayMap, excludeWeekend)) {
                continue;
            }
            LocalDateTime currentDay = currentDate.atStartOfDay();
            // 2.2.1 根据倒班方式计算 shiftIndex
            shiftIndex = calculateShiftIndex(shiftIndex, i, currentDate, startDate, plan);
            // 2.2.1 根据倒班方式计算 shiftIndex(以工作日偏移为准)
            shiftIndex = calculateShiftIndex(shiftIndex, workdayOffset, currentDate, startDate, plan);
            // 2.2.2 根据轮班方式生成排班记录,收集到列表
            buildRecordsForDay(allRecords, planId, currentDay, shiftIndex, plan.getShiftType(), teams, shifts);
            workdayOffset++;
        }
        // 3. 批量插入排班记录
        teamShiftMapper.insertBatch(allRecords);
    }
    /**
     * 判断指定日期是否为工作日
     *
     * 优先级:holiday 表 > 周末排除开关 > 默认工作日
     */
    private boolean isWorkday(LocalDate date, Map<LocalDate, Integer> holidayMap, boolean excludeWeekend) {
        // 1. holiday 表优先:显式标记的日期以标记为准
        Integer holidayType = holidayMap.get(date);
        if (holidayType != null) {
            return MesCalHolidayTypeEnum.WORKDAY.getType().equals(holidayType);
        }
        // 2. 若开启了排除周末,周六日默认为休息日
        if (excludeWeekend) {
            DayOfWeek dow = date.getDayOfWeek();
            if (dow == DayOfWeek.SATURDAY || dow == DayOfWeek.SUNDAY) {
                return false;
            }
        }
        // 3. 默认工作日
        return true;
    }
    /**
@@ -96,6 +138,10 @@
        if (dayOffset == 0) {
            return shiftIndex; // 第一天不递增
        }
        // 单白班不需要倒班,shiftMethod 为 null,直接返回
        if (plan.getShiftMethod() == null) {
            return shiftIndex;
        }
        if (MesCalShiftMethodEnum.QUARTER.getMethod().equals(plan.getShiftMethod())) {
            // 按季度轮班:到了新季度的第一天
            LocalDate quarterStart = LocalDateTimeUtils.getQuarterStart(currentDate);