From 606d0a6f3a7b47adcaa2da627a4b7d58334c134e Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期一, 20 四月 2026 14:45:12 +0800
Subject: [PATCH] 排班管理
---
ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TLineController.java | 429 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 429 insertions(+), 0 deletions(-)
diff --git a/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TLineController.java b/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TLineController.java
index 7b82789..2214c06 100644
--- a/ManagementYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/specialTrain/TLineController.java
+++ b/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;
+ }
+
}
--
Gitblit v1.7.1