longz
2026-04-20 606d0a6f3a7b47adcaa2da627a4b7d58334c134e
ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TLineController.java
@@ -12,6 +12,7 @@
import com.stylefeng.guns.core.util.SinataUtil;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.model.*;
import com.stylefeng.guns.modular.system.dao.LineShiftDriverMapper;
import com.stylefeng.guns.modular.system.service.*;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
@@ -24,7 +25,9 @@
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.math.BigDecimal;
@@ -67,6 +70,12 @@
    
    @Autowired
    private ITLineCompanyService itLineCompanyService;
    @Autowired
    private LineShiftDriverMapper lineShiftDriverMapper;
    @Autowired
    private ITDriverService tDriverService;
    
    /**
     * 跳转到跨城站点管理首页
@@ -420,10 +429,337 @@
                lineCompany.setCompanyId(jsonObject.getInteger("companyId"));
                lineCompany.setInsertTime(new Date());
                lineCompany.setInsertUserId(ShiroKit.getUser().getId());
                lineCompany.setAutoPlan(2);
                itLineCompanyService.insert(lineCompany);
            }
        }
        return SUCCESS_TIP;
    }
    /**
     * 查询线路已分配企业
     */
    @RequestMapping(value = "/lineCompanyList")
    @ResponseBody
    public Object lineCompanyList(Integer lineId) {
        if (lineId == null) {
            return ResultUtil.error("线路ID不能为空");
        }
        return ResultUtil.success(tLineService.getLineCompanyList(lineId));
    }
    /**
     * 排班管理页面
     */
    @RequestMapping(value = "/schedulePage")
    public String schedulePage(Integer lineId, Integer companyId, Model model) {
        TLine line = tLineService.selectById(lineId);
        TCompany company = itCompanyService.selectById(companyId);
        TLineCompany lineCompany = itLineCompanyService.selectOne(new EntityWrapper<TLineCompany>()
                .eq("lineId", lineId).eq("companyId", companyId));
        model.addAttribute("lineId", lineId);
        model.addAttribute("companyId", companyId);
        model.addAttribute("lineName", line == null ? "" : line.getName());
        model.addAttribute("companyName", company == null ? "" : company.getName());
        model.addAttribute("autoPlan", lineCompany == null || lineCompany.getAutoPlan() == null ? 2 : lineCompany.getAutoPlan());
        return PREFIX + "tLine_schedule.html";
    }
    /**
     * 排班管理-月份数据
     */
    @RequestMapping(value = "/schedule/month")
    @ResponseBody
    public Object scheduleMonth(Integer lineId, Integer companyId, String month) {
        try {
            TLineCompany lineCompany = checkLineCompany(lineId, companyId);
            if (lineCompany == null) {
                return ResultUtil.error("线路未关联该企业");
            }
            if (SinataUtil.isEmpty(month)) {
                month = new SimpleDateFormat("yyyy-MM").format(new Date());
            }
            SimpleDateFormat monthSdf = new SimpleDateFormat("yyyy-MM");
            Date monthDate = monthSdf.parse(month);
            Calendar cal = Calendar.getInstance();
            cal.setTime(monthDate);
            cal.set(Calendar.DAY_OF_MONTH, 1);
            String monthStart = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
            int maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
            cal.set(Calendar.DAY_OF_MONTH, maxDay);
            String monthEnd = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
            Integer companyType = getCompanyType(companyId);
            List<Map<String, Object>> stats = lineShiftDriverMapper.getMonthScheduleStats(lineId, monthStart, monthEnd, companyId, companyType);
            Map<String, Integer> dayAssignMap = new HashMap<>();
            for (Map<String, Object> stat : stats) {
                dayAssignMap.put(String.valueOf(stat.get("dayStr")), Integer.parseInt(String.valueOf(stat.get("assignNum"))));
            }
            List<TLineShift> shifts = itLineShiftService.selectList(new EntityWrapper<TLineShift>().eq("lineId", lineId).ne("state", 3));
            int totalNeed = 0;
            for (TLineShift shift : shifts) {
                totalNeed += (shift.getCarNum() == null ? 0 : shift.getCarNum());
            }
            List<Map<String, Object>> dayList = new ArrayList<>();
            cal.setTime(monthDate);
            cal.set(Calendar.DAY_OF_MONTH, 1);
            for (int i = 1; i <= maxDay; i++) {
                cal.set(Calendar.DAY_OF_MONTH, i);
                String dayStr = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
                int assignNum = dayAssignMap.get(dayStr) == null ? 0 : dayAssignMap.get(dayStr);
                Map<String, Object> obj = new HashMap<>();
                obj.put("day", dayStr);
                obj.put("assignNum", assignNum);
                obj.put("totalNeed", totalNeed);
                if (totalNeed <= 0) {
                    obj.put("status", 0);
                    obj.put("statusText", "无班次");
                } else if (assignNum >= totalNeed) {
                    obj.put("status", 1);
                    obj.put("statusText", "已排班");
                } else {
                    obj.put("status", 2);
                    obj.put("statusText", "未排满");
                }
                dayList.add(obj);
            }
            Map<String, Object> result = new HashMap<>();
            result.put("month", month);
            result.put("totalNeed", totalNeed);
            result.put("days", dayList);
            return ResultUtil.success(result);
        } catch (Exception ex) {
            ex.printStackTrace();
            return ResultUtil.runErr();
        }
    }
    /**
     * 排班管理-某天班次详情
     */
    @RequestMapping(value = "/schedule/dayDetail")
    @ResponseBody
    public Object scheduleDayDetail(Integer lineId, Integer companyId, String day) {
        try {
            TLineCompany lineCompany = checkLineCompany(lineId, companyId);
            if (lineCompany == null) {
                return ResultUtil.error("线路未关联该企业");
            }
            Integer companyType = getCompanyType(companyId);
            List<Map<String, Object>> shiftList = lineShiftDriverMapper.getDayShiftSchedule(lineId, day, companyId, companyType);
            for (Map<String, Object> shift : shiftList) {
                Integer lineShiftId = Integer.valueOf(String.valueOf(shift.get("lineShiftId")));
                List<Map<String, Object>> drivers = lineShiftDriverMapper.getDayShiftDrivers(lineShiftId, day, companyId, companyType);
                int carNum = shift.get("carNum") == null ? 0 : Integer.parseInt(String.valueOf(shift.get("carNum")));
                int assignNum = shift.get("assignNum") == null ? 0 : Integer.parseInt(String.valueOf(shift.get("assignNum")));
                shift.put("drivers", drivers);
                shift.put("remainNum", Math.max(carNum - assignNum, 0));
                shift.put("canAdd", assignNum < carNum ? 1 : 0);
            }
            return ResultUtil.success(shiftList);
        } catch (Exception ex) {
            ex.printStackTrace();
            return ResultUtil.runErr();
        }
    }
    /**
     * 排班管理-可添加司机
     */
    @RequestMapping(value = "/schedule/drivers")
    @ResponseBody
    public Object scheduleDrivers(Integer lineId, Integer companyId, Integer lineShiftId, String day) {
        try {
            TLineCompany lineCompany = checkLineCompany(lineId, companyId);
            if (lineCompany == null) {
                return ResultUtil.error("线路未关联该企业");
            }
            Integer companyType = getCompanyType(companyId);
            return ResultUtil.success(lineShiftDriverMapper.getAvailableDrivers(lineId, lineShiftId, day, companyId, companyType));
        } catch (Exception ex) {
            ex.printStackTrace();
            return ResultUtil.runErr();
        }
    }
    /**
     * 排班管理-新增排班
     */
    @RequestMapping(value = "/schedule/add")
    @ResponseBody
    public Object scheduleAdd(Integer lineId, Integer companyId, Integer lineShiftId, String day, @RequestParam String driverIds) {
        try {
            TLineCompany lineCompany = checkLineCompany(lineId, companyId);
            if (lineCompany == null) {
                return ResultUtil.error("线路未关联该企业");
            }
            TLineShift shift = itLineShiftService.selectById(lineShiftId);
            if (shift == null || shift.getState() == 3 || !shift.getLineId().equals(lineId)) {
                return ResultUtil.error("班次不存在");
            }
            Date dayDate = parseDay(day);
            Integer companyType = getCompanyType(companyId);
            List<Map<String, Object>> currentDrivers = lineShiftDriverMapper.getDayShiftDrivers(lineShiftId, day, companyId, companyType);
            int currentAssignNum = currentDrivers == null ? 0 : currentDrivers.size();
            int carNum = shift.getCarNum() == null ? 0 : shift.getCarNum();
            if (currentAssignNum >= carNum) {
                return ResultUtil.error("当前班次已排满");
            }
            List<Integer> driverIdList = parseIdList(driverIds);
            if (driverIdList.size() <= 0) {
                return ResultUtil.error("请选择司机");
            }
            List<Map<String, Object>> availableDrivers = lineShiftDriverMapper.getAvailableDrivers(lineId, lineShiftId, day, companyId, companyType);
            Map<Integer, Integer> seatMap = new HashMap<>();
            for (Map<String, Object> driver : availableDrivers) {
                Integer driverId = Integer.valueOf(String.valueOf(driver.get("driverId")));
                Integer seatNum = driver.get("seatNum") == null ? 5 : Integer.valueOf(String.valueOf(driver.get("seatNum")));
                seatMap.put(driverId, seatNum);
            }
            List<Integer> validDriverIds = new ArrayList<>();
            for (Integer driverId : driverIdList) {
                if (seatMap.containsKey(driverId)) {
                    validDriverIds.add(driverId);
                }
            }
            if (validDriverIds.size() <= 0) {
                return ResultUtil.error("没有可添加的司机");
            }
            if (currentAssignNum + validDriverIds.size() > carNum) {
                return ResultUtil.error("可排班人数不足,当前班次最多还能添加" + (carNum - currentAssignNum) + "名司机");
            }
            for (Integer driverId : validDriverIds) {
                Integer count = lineShiftDriverMapper.countExistsSchedule(lineShiftId, driverId, day);
                if (count != null && count > 0) {
                    continue;
                }
                int seatNum = seatMap.get(driverId) == null ? 5 : seatMap.get(driverId);
                if (seatNum <= 0) {
                    seatNum = 5;
                }
                LineShiftDriver record = new LineShiftDriver();
                record.setLineShiftId(lineShiftId);
                record.setDriverId(driverId);
                record.setDay(dayDate);
                record.setTotalSeat(seatNum);
                record.setLaveSeat(seatNum);
                record.setLaveSeatNumber(buildSeatNoStr(seatNum));
                record.setInserTime(new Date());
                record.setAssignType(2);
                lineShiftDriverMapper.insert(record);
            }
            return ResultUtil.success();
        } catch (Exception ex) {
            ex.printStackTrace();
            return ResultUtil.runErr();
        }
    }
    /**
     * 排班管理-删除手动排班
     */
    @RequestMapping(value = "/schedule/delete")
    @ResponseBody
    public Object scheduleDelete(Integer scheduleId, Integer lineId, Integer companyId) {
        try {
            TLineCompany lineCompany = checkLineCompany(lineId, companyId);
            if (lineCompany == null) {
                return ResultUtil.error("线路未关联该企业");
            }
            LineShiftDriver record = lineShiftDriverMapper.selectById(scheduleId);
            if (record == null) {
                return ResultUtil.error("排班记录不存在");
            }
            if (record.getAssignType() == null || record.getAssignType() != 2) {
                return ResultUtil.error("仅支持删除手动排班记录");
            }
            TLineShift shift = itLineShiftService.selectById(record.getLineShiftId());
            if (shift == null || !shift.getLineId().equals(lineId)) {
                return ResultUtil.error("排班记录线路不匹配");
            }
            TDriver driver = tDriverService.selectById(record.getDriverId());
            if (driver == null || !checkDriverBelongCompany(driver, companyId)) {
                return ResultUtil.error("司机企业信息不匹配");
            }
            lineShiftDriverMapper.deleteById(scheduleId);
            return ResultUtil.success();
        } catch (Exception ex) {
            ex.printStackTrace();
            return ResultUtil.runErr();
        }
    }
    /**
     * 排班管理-复制排班
     */
    @RequestMapping(value = "/schedule/copy")
    @ResponseBody
    public Object scheduleCopy(Integer lineId, Integer companyId, String sourceStart, String sourceEnd, String targetStart) {
        try {
            TLineCompany lineCompany = checkLineCompany(lineId, companyId);
            if (lineCompany == null) {
                return ResultUtil.error("线路未关联该企业");
            }
            Date sourceStartDate = parseDay(sourceStart);
            Date sourceEndDate = parseDay(sourceEnd);
            Date targetStartDate = parseDay(targetStart);
            if (sourceEndDate.before(sourceStartDate)) {
                return ResultUtil.error("复制结束日期不能早于开始日期");
            }
            Integer companyType = getCompanyType(companyId);
            List<LineShiftDriver> sourceList = lineShiftDriverMapper.getManualSchedulesForCopy(lineId, sourceStart, sourceEnd, companyId, companyType);
            int addNum = 0;
            int skipNum = 0;
            for (LineShiftDriver source : sourceList) {
                int diff = getDayDiff(sourceStartDate, source.getDay());
                Date targetDay = addDays(targetStartDate, diff);
                String targetDayStr = formatDay(targetDay);
                Integer count = lineShiftDriverMapper.countExistsSchedule(source.getLineShiftId(), source.getDriverId(), targetDayStr);
                if (count != null && count > 0) {
                    skipNum++;
                    continue;
                }
                LineShiftDriver target = new LineShiftDriver();
                target.setLineShiftId(source.getLineShiftId());
                target.setDriverId(source.getDriverId());
                target.setDay(targetDay);
                target.setLaveSeat(source.getLaveSeat());
                target.setLaveSeatNumber(source.getLaveSeatNumber());
                target.setTotalSeat(source.getTotalSeat());
                target.setInserTime(new Date());
                target.setAssignType(2);
                lineShiftDriverMapper.insert(target);
                addNum++;
            }
            Map<String, Object> result = new HashMap<>();
            result.put("addNum", addNum);
            result.put("skipNum", skipNum);
            return ResultUtil.success(result);
        } catch (Exception ex) {
            ex.printStackTrace();
            return ResultUtil.runErr();
        }
    }
    /**
     * 排班管理-保存智能排班开关
     */
    @RequestMapping(value = "/schedule/autoPlan")
    @ResponseBody
    public Object scheduleAutoPlan(Integer lineId, Integer companyId, Integer autoPlan) {
        if (autoPlan == null || (autoPlan != 1 && autoPlan != 2)) {
            return ResultUtil.error("智能排班参数错误");
        }
        TLineCompany lineCompany = checkLineCompany(lineId, companyId);
        if (lineCompany == null) {
            return ResultUtil.error("线路未关联该企业");
        }
        lineCompany.setAutoPlan(autoPlan);
        itLineCompanyService.updateById(lineCompany);
        return ResultUtil.success();
    }
    /**
     * 修改跨城站点管理
@@ -601,4 +937,97 @@
        return ResultUtil.success();
    }
    private TLineCompany checkLineCompany(Integer lineId, Integer companyId) {
        if (lineId == null || companyId == null) {
            return null;
        }
        return itLineCompanyService.selectOne(new EntityWrapper<TLineCompany>().eq("lineId", lineId).eq("companyId", companyId));
    }
    private Integer getCompanyType(Integer companyId) {
        TCompany company = itCompanyService.selectById(companyId);
        return company == null ? null : company.getType();
    }
    private boolean checkDriverBelongCompany(TDriver driver, Integer companyId) {
        if (driver == null || companyId == null) {
            return false;
        }
        Integer companyType = getCompanyType(companyId);
        if (companyType == null) {
            return false;
        }
        if (companyType == 2) {
            return driver.getCompanyId() != null && driver.getCompanyId().intValue() == companyId.intValue();
        }
        if (companyType == 3) {
            return driver.getFranchiseeId() != null && driver.getFranchiseeId().intValue() == companyId.intValue();
        }
        return false;
    }
    private Date parseDay(String day) throws Exception {
        return new SimpleDateFormat("yyyy-MM-dd").parse(day);
    }
    private String formatDay(Date day) {
        return new SimpleDateFormat("yyyy-MM-dd").format(day);
    }
    private int getDayDiff(Date start, Date end) {
        long oneDay = 24L * 60L * 60L * 1000L;
        long startTime = start.getTime() / oneDay;
        long endTime = end.getTime() / oneDay;
        return (int) (endTime - startTime);
    }
    private Date addDays(Date date, int days) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_MONTH, days);
        return cal.getTime();
    }
    private String buildSeatNoStr(int seatNum) {
        StringBuilder builder = new StringBuilder();
        for (int i = 1; i <= seatNum; i++) {
            if (i > 1) {
                builder.append(",");
            }
            builder.append(i);
        }
        return builder.toString();
    }
    private List<Integer> parseIdList(String ids) {
        List<Integer> list = new ArrayList<>();
        if (SinataUtil.isEmpty(ids)) {
            return list;
        }
        try {
            if (ids.startsWith("[")) {
                JSONArray array = JSON.parseArray(ids);
                for (int i = 0; i < array.size(); i++) {
                    Integer id = array.getInteger(i);
                    if (id != null && !list.contains(id)) {
                        list.add(id);
                    }
                }
            } else {
                String[] arr = ids.split(",");
                for (String s : arr) {
                    if (SinataUtil.isNotEmpty(s)) {
                        Integer id = Integer.valueOf(s.trim());
                        if (!list.contains(id)) {
                            list.add(id);
                        }
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return list;
    }
}