wenhongquan 4 месяцев назад
Родитель
Сommit
fab07d4359

+ 6 - 0
ruoyi-modules/ruoyi-dzbc/src/main/java/org/dromara/system/controller/TblDzbcDriverTripController.java

@@ -64,6 +64,12 @@ public class TblDzbcDriverTripController extends BaseController {
         return toAjax(tblDzbcDriverTripService.startTrip(id));
     }
 
+    @Log(title = "根据排班ID开始任务", businessType = BusinessType.UPDATE)
+    @PostMapping("/startByScheduling/{schedulingId}")
+    public R<Void> startByScheduling(@NotNull(message = "排班ID不能为空") @PathVariable Long schedulingId) {
+        return toAjax(tblDzbcDriverTripService.startTripBySchedulingId(schedulingId));
+    }
+
     @Log(title = "到达站点", businessType = BusinessType.UPDATE)
     @PostMapping("/arrive/{id}")
     public R<Void> arrive(@NotNull(message = "主键不能为空") @PathVariable Long id,

+ 14 - 0
ruoyi-modules/ruoyi-dzbc/src/main/java/org/dromara/system/service/ITblDzbcDriverTripService.java

@@ -23,12 +23,26 @@ public interface ITblDzbcDriverTripService {
 
     Boolean startTrip(Long id);
 
+    /**
+     * 根据排班ID发车
+     * @param schedulingId 排班ID
+     * @return 是否成功
+     */
+    Boolean startTripBySchedulingId(Long schedulingId);
+
     Boolean arriveSite(Long id, Long siteId);
 
     Boolean completeTrip(Long id);
 
     Boolean cancelTrip(Long id);
 
+    /**
+     * 生成新的车次号,保持司机和班次信息
+     * @param id 原车次ID
+     * @return 新的车次信息
+     */
+    TblDzbcDriverTripVo generateNewTripNo(Long id);
+
     Boolean updateByBo(TblDzbcDriverTripBo bo);
 
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);

+ 133 - 25
ruoyi-modules/ruoyi-dzbc/src/main/java/org/dromara/system/service/impl/TblDzbcDriverTripServiceImpl.java

@@ -3,6 +3,8 @@ package org.dromara.system.service.impl;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -12,6 +14,7 @@ import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.system.domain.TblDzbcDriverTrip;
+import org.dromara.system.domain.TblDzbcPathScheduling;
 import org.dromara.system.domain.vo.SysUserVo;
 import org.dromara.system.domain.bo.TblDzbcDriverTripBo;
 import org.dromara.system.domain.vo.TblDzbcCargoOrderVo;
@@ -19,6 +22,7 @@ import org.dromara.system.domain.vo.TblDzbcDriverTripVo;
 import org.dromara.system.domain.vo.TblDzbcPathSiteVo;
 import org.dromara.system.mapper.SysUserMapper;
 import org.dromara.system.mapper.TblDzbcDriverTripMapper;
+import org.dromara.system.mapper.TblDzbcPathSchedulingMapper;
 import org.dromara.system.mapper.TblDzbcPathSiteMapper;
 import org.dromara.system.service.ITblDzbcCargoOrderService;
 import org.dromara.system.service.ITblDzbcDriverTripService;
@@ -33,6 +37,7 @@ import java.util.List;
 public class TblDzbcDriverTripServiceImpl implements ITblDzbcDriverTripService {
 
     private final TblDzbcDriverTripMapper baseMapper;
+    private final TblDzbcPathSchedulingMapper pathSchedulingMapper;
     private final SysUserMapper userMapper;
     private final TblDzbcPathSiteMapper pathSiteMapper;
     private final ITblDzbcCargoOrderService cargoOrderService;
@@ -96,10 +101,114 @@ public class TblDzbcDriverTripServiceImpl implements ITblDzbcDriverTripService {
 
     @Override
     public Boolean startTrip(Long id) {
-        TblDzbcDriverTrip trip = new TblDzbcDriverTrip();
-        trip.setId(id);
-        trip.setStatus(1);
-        return baseMapper.updateById(trip) > 0;
+        return generateNewTripNo(id) != null;
+    }
+
+    @Override
+    public Boolean startTripBySchedulingId(Long schedulingId) {
+        // 根据 schedulingId 查找对应的 driverTrip
+        TblDzbcDriverTrip trip = baseMapper.selectOne(
+            new LambdaQueryWrapper<TblDzbcDriverTrip>()
+                .apply("ext2->'$.schedulingId' = {0}", schedulingId)
+                .last("LIMIT 1")
+        );
+
+        if (trip != null) {
+            // 已存在 driverTrip,直接更新状态为发车
+            if (trip.getStatus() != null && trip.getStatus() >= 1) {
+                throw new ServiceException("该排班已发车");
+            }
+            TblDzbcDriverTrip update = new TblDzbcDriverTrip();
+            update.setId(trip.getId());
+            update.setStatus(1); // 状态设为1(发车中)
+            return baseMapper.updateById(update) > 0;
+        }
+
+        // 不存在 driverTrip,需要根据排班信息创建并直接发车
+        TblDzbcPathScheduling scheduling = pathSchedulingMapper.selectById(schedulingId);
+        if (scheduling == null) {
+            throw new ServiceException("排班信息不存在");
+        }
+
+        // 解析 ext1 获取司机和车辆信息
+        if (scheduling.getExt1() == null) {
+            throw new ServiceException("排班扩展信息不存在");
+        }
+
+        JSONObject ext1 = JSONUtil.parseObj(scheduling.getExt1());
+        JSONObject driverInfo = ext1.getJSONObject("driverInfo");
+        JSONObject carInfo = ext1.getJSONObject("carInfo");
+
+        if (driverInfo == null || carInfo == null) {
+            throw new ServiceException("司机或车辆信息不存在");
+        }
+
+        // 创建 driverTrip
+        TblDzbcDriverTrip newTrip = new TblDzbcDriverTrip();
+        newTrip.setTripNo(generateTripNo());
+        newTrip.setPathId(scheduling.getPathId());
+        newTrip.setDriverId(driverInfo.getLong("userId"));
+        newTrip.setDriverName(driverInfo.getStr("nickName"));
+        newTrip.setDriverPhone(driverInfo.getStr("phonenumber"));
+        newTrip.setCarId(carInfo.getLong("id"));
+        newTrip.setStatus(1); // 直接设为发车状态
+
+        // 设置开始时间
+        if (scheduling.getMdate() != null && scheduling.getMtime() != null) {
+            String timeStr = scheduling.getMtime();
+            if (org.dromara.common.core.utils.StringUtils.countMatches(timeStr, ":") == 1) {
+                timeStr += ":00";
+            }
+            String dateTimeStr = DateUtil.formatDate(scheduling.getMdate()) + " " + timeStr;
+            newTrip.setStartTime(LocalDateTime.parse(dateTimeStr, java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        }
+
+        // 设置 ext1 存储排班快照
+        newTrip.setExt1(JSONUtil.toJsonStr(scheduling));
+
+        // 设置 ext2 关联 schedulingId
+        JSONObject ext2 = JSONUtil.createObj();
+        ext2.set("schedulingId", schedulingId);
+        newTrip.setExt2(ext2.toString());
+
+        validEntityBeforeSave(newTrip);
+        return baseMapper.insert(newTrip) > 0;
+    }
+
+    @Override
+    public TblDzbcDriverTripVo generateNewTripNo(Long id) {
+        // 查询原车次信息
+        TblDzbcDriverTrip originalTrip = baseMapper.selectById(id);
+        if (originalTrip == null) {
+            throw new RuntimeException("原车次不存在");
+        }
+
+        // 创建新的车次记录,复制原车次的司机和班次信息
+        TblDzbcDriverTrip newTrip = new TblDzbcDriverTrip();
+        newTrip.setTripNo(generateTripNo());
+        newTrip.setPathId(originalTrip.getPathId());
+        newTrip.setDriverId(originalTrip.getDriverId());
+        newTrip.setDriverName(originalTrip.getDriverName());
+        newTrip.setDriverPhone(originalTrip.getDriverPhone());
+        newTrip.setCarId(originalTrip.getCarId());
+        newTrip.setStartTime(originalTrip.getStartTime());
+        newTrip.setExt1(originalTrip.getExt1());
+        newTrip.setExt2(originalTrip.getExt2());
+        newTrip.setStatus(1); // 新车次状态设为1(发车中)
+        newTrip.setCurrentSiteId(originalTrip.getCurrentSiteId());
+        newTrip.setCurrentSiteName(originalTrip.getCurrentSiteName());
+
+        // 保存新车次
+        validEntityBeforeSave(newTrip);
+        baseMapper.insert(newTrip);
+
+        // 更新原车次状态为已生成新车次
+        TblDzbcDriverTrip updateOriginal = new TblDzbcDriverTrip();
+        updateOriginal.setId(id);
+        updateOriginal.setStatus(1); // 原车次也设为1,表示已发车
+        baseMapper.updateById(updateOriginal);
+
+        return queryById(newTrip.getId());
     }
 
     @Override
@@ -166,30 +275,29 @@ public class TblDzbcDriverTripServiceImpl implements ITblDzbcDriverTripService {
 
     private void validEntityBeforeSave(TblDzbcDriverTrip entity) {
         // 校验同一时间的同一辆车只能发车一次
-        if (entity.getCarId() != null || entity.getStartTime() != null) {
-            Long carId = entity.getCarId();
-            LocalDateTime startTime = entity.getStartTime();
+        Long carId = entity.getCarId();
+        LocalDateTime startTime = entity.getStartTime();
 
-            // 如果是更新操作,且字段缺失,需要查询数据库补充
-            if (entity.getId() != null) {
-                TblDzbcDriverTrip old = baseMapper.selectById(entity.getId());
-                if (old != null) {
-                    if (carId == null) carId = old.getCarId();
-                    if (startTime == null) startTime = old.getStartTime();
-                }
+        // 如果是更新操作,且字段缺失,需要查询数据库补充
+        if (entity.getId() != null) {
+            TblDzbcDriverTrip old = baseMapper.selectById(entity.getId());
+            if (old != null) {
+                if (carId == null) carId = old.getCarId();
+                if (startTime == null) startTime = old.getStartTime();
             }
+        }
 
-            if (carId != null && startTime != null) {
-                LambdaQueryWrapper<TblDzbcDriverTrip> lqw = Wrappers.lambdaQuery();
-                lqw.eq(TblDzbcDriverTrip::getCarId, carId);
-                lqw.eq(TblDzbcDriverTrip::getStartTime, startTime);
-                lqw.ne(TblDzbcDriverTrip::getStatus, 3); // 排除已取消
-                if (entity.getId() != null) {
-                    lqw.ne(TblDzbcDriverTrip::getId, entity.getId());
-                }
-                if (baseMapper.selectCount(lqw) > 0) {
-                    throw new ServiceException("该车辆在该时间段已有任务");
-                }
+        // 只有当 carId 和 startTime 都存在时才进行校验
+        if (carId != null && startTime != null) {
+            LambdaQueryWrapper<TblDzbcDriverTrip> lqw = Wrappers.lambdaQuery();
+            lqw.eq(TblDzbcDriverTrip::getCarId, carId);
+            lqw.eq(TblDzbcDriverTrip::getStartTime, startTime);
+            lqw.ne(TblDzbcDriverTrip::getStatus, 3); // 排除已取消
+            if (entity.getId() != null) {
+                lqw.ne(TblDzbcDriverTrip::getId, entity.getId());
+            }
+            if (baseMapper.selectCount(lqw) > 0) {
+                throw new ServiceException("该车辆在该时间段已有任务");
             }
         }
     }

+ 20 - 0
ruoyi-modules/ruoyi-dzbc/src/main/java/org/dromara/system/service/impl/TblDzbcPathSchedulingServiceImpl.java

@@ -25,8 +25,10 @@ import org.dromara.system.domain.vo.SysUserVo;
 import org.dromara.system.domain.vo.TblDzbcCarVo;
 import org.dromara.system.domain.vo.TblDzbcMultiSitePathVo;
 import org.dromara.system.domain.vo.TblDzbcPathVo;
+import org.dromara.system.domain.TblDzbcDriverTrip;
 import org.dromara.system.mapper.SysUserMapper;
 import org.dromara.system.mapper.TblDzbcCarMapper;
+import org.dromara.system.mapper.TblDzbcDriverTripMapper;
 import org.dromara.system.mapper.TblDzbcMultiSitePathMapper;
 import org.dromara.system.mapper.TblDzbcPathMapper;
 import org.springframework.stereotype.Service;
@@ -59,6 +61,7 @@ public class TblDzbcPathSchedulingServiceImpl implements ITblDzbcPathSchedulingS
     private final TblDzbcPathMapper pathMapper;
     private final TblDzbcMultiSitePathMapper multiSitePathMapper;
     private final ITblDzbcDriverTripService driverTripService;
+    private final TblDzbcDriverTripMapper driverTripMapper;
 
     private final SysUserMapper userMapper;
     private final OssService ossService;
@@ -97,6 +100,23 @@ public class TblDzbcPathSchedulingServiceImpl implements ITblDzbcPathSchedulingS
                     }
                 } catch (Exception e) {}
             }
+            // 固定路线(type=2)时,通过 driverTrip 判断发车状态
+            if (vo.getType() != null && vo.getType() == 2) {
+                try {
+                    // 通过 schedulingId 查询对应的 driverTrip
+                    TblDzbcDriverTrip trip = driverTripMapper.selectOne(
+                        new LambdaQueryWrapper<TblDzbcDriverTrip>()
+                            .apply("ext2->'$.schedulingId' = {0}", vo.getId())
+                            .last("LIMIT 1")
+                    );
+                    if (trip != null) {
+                        // status: 0-待发车 1-运行中 2-已完成 3-已取消
+                        if (trip.getStatus() != null && trip.getStatus() >= 1) {
+                            vo.setCarStatus("已发车");
+                        }
+                    }
+                } catch (Exception e) {}
+            }
         });
         return TableDataInfo.build(result);
     }