Java通过批次实现员工自动排班

需求:

浮动上班日;

实现员工自动排班,保证生产每天都有人上班工作,每个员工的休息日不固定到周末;

可调整员工上一周的哪几天;

可跨月跨年

实现思路:

前端调用:

        前端调用接口传入自动排班的开始时间和结束时间

后端逻辑:

        模型:批次表、员工表、排班表

1、分多个批次,每个批次指定上一周的几天(如:1批次休周末两天,2批次休周一周二,3批次休周三周四)

2、员工绑定批次

3、每次排班根据传入的时间(排班开始时间,排班结束时间)遍历每一天,将每一天的工作日看匹配哪个批次,再把对应批次的员工添加到当日

代码实现:

import cn.hutool.core.date.LocalDateTimeUtil;
import io.swagger.models.auth.In;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;

public class AutoShifts {


    public static void main(String[] args) {

        // 1、模拟数据库Group By查询 规则表关联员工表,一对多查询 -- 最终关联查询结果为下方groupEmployeelist列表
        // 模拟有3个批次组的员工
        List<Employee> groupA = new ArrayList<>(); // 上 1-5
        List<Employee> groupB = new ArrayList<>(); // 上 3-7
        List<Employee> groupC = new ArrayList<>(); // 上 1-2,5-7
        groupA.add(new Employee(1, "张三", 1));
        groupA.add(new Employee(2, "李四", 1));
        groupA.add(new Employee(3, "王五", 1));

        groupB.add(new Employee(4, "赵六", 2));
        groupB.add(new Employee(5, "钱七", 2));
        groupB.add(new Employee(6, "孙八", 2));

        groupC.add(new Employee(7, "周九", 3));
        groupC.add(new Employee(8, "吴十", 3));
        groupC.add(new Employee(9, "郑十一", 3));
        groupC.add(new Employee(10, "王二麻子", 3));

        // 数据库查询出来List就包含成3个对象 {id,List<Employee> }
        // 1 组值班是1-5,2 组值班是3-7,3 组值班是1-2,5-7
        String RULE_A = "1,2,3,4,5";
        String RULE_B = "3,4,5,6,7";
        String RULE_C = "1,2,5,6,7";

        // 最终查询一对多 规则表-员工表,结果:
        ArrayList<GroupEmployee> groupEmployeelist = new ArrayList<>();
        GroupEmployee groupEmployeeA = new GroupEmployee(1, RULE_A, groupA);
        GroupEmployee groupEmployeeB = new GroupEmployee(2, RULE_B, groupB);
        GroupEmployee groupEmployeeC = new GroupEmployee(3, RULE_C, groupC);
        groupEmployeelist.add(groupEmployeeA);
        groupEmployeelist.add(groupEmployeeB);
        groupEmployeelist.add(groupEmployeeC);

        // 2、校验
        if (RULE_A == null || RULE_B == null || RULE_C == null) {
            System.out.println("组参数规则错误");
            return;
        }
        int size = groupEmployeelist.size();
        if (size < 2) {
            System.out.println("值班员工只存在一个批次");
        }

        // 3、模拟前端传入自动排班时间段参数
        // 排班开始日期、结束日期
        LocalDate startDate = LocalDate.parse("2024-12-01");
        LocalDate endDate = LocalDate.parse("2025-01-02");
        if (startDate.isAfter(endDate)) {
            System.out.println("开始日期不能大于结束日期");
            return;
        }

        //存储最终排班结果
        List<Shift> shiftList = new ArrayList<>();

        // 遍历每一天,查找符合当天的批次组及其员工
        LocalDate currentDate = startDate;
        while (currentDate.isBefore(endDate.plusDays(1))) {
            int dayOfWeek = currentDate.getDayOfWeek().getValue();
            int finalDayOfWeek = dayOfWeek;
            LocalDate finalCurrentDate = currentDate;
            groupEmployeelist.stream().forEach(x -> {
                if (x.getAllWeek().contains(String.valueOf(finalDayOfWeek))) {
                    x.getEmployeeList().stream().forEach(item -> {
                        shiftList.add(new Shift(item.getId(), item.getName(), item.getGroupId(), "星期" + finalDayOfWeek, finalCurrentDate));
                    });
                }
            });
            currentDate = currentDate.plusDays(1);
        }

        
        shiftList.forEach(item -> {
            System.out.println(item);
        });

    }


}

/**
 * 每个批次组对应的所有员工
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
class GroupEmployee {
    private Integer id; // 批次组id
    private String allWeek; // 值班哪几天
    private List<Employee> employeeList; // 员工集合

}

/**
 * 员工表
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
class Employee {
    private Integer id; // 员工id
    private String name; // 员工姓名
    private Integer groupId; // 批次组id
}

/**
 * 排班结果
 */
@Data
class Shift {
    private Integer id; // 员工id
    private String name; // 员工姓名
    private Integer groupId; // 批次组id
    private String dayOfWeek; // 星期几
    private LocalDate currentDay; // 值班日期

    public Shift() {
    }

    public Shift(Integer item, String name, Integer groupId, String dayOfWeek, LocalDate currentDay) {

        this.id = item;
        this.name = name;
        this.groupId = groupId;
        this.dayOfWeek = dayOfWeek;
        this.currentDay = currentDay;
    }

    @Override
    public String toString() {
        return "shift{" +
                " currentDay='" + currentDay + '\'' +
                ", dayOfWeek='" + dayOfWeek + '\'' +
                ", id=" + id +
                ", name='" + name + '\'' +
                ", groupId=" + groupId +
                '}';
    }
}

排班结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值