From 80fd77e1bcb47726e440b8a728838189cd39a56a Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期二, 30 六月 2026 21:25:35 +0800
Subject: [PATCH] 跨城改派fix

---
 DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/LineShiftDriverServiceImpl.java |   51 +++-
 DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IReassignService.java                  |    5 
 DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/LineShiftDriverMapper.java              |    6 
 DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/LineShiftDriverMapper.xml       |   72 ++++++
 DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/ReassignServiceImpl.java          |  437 ++++++++++++++++++++++++++++++++------
 DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/PushUtil.java                             |    2 
 DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/OrderCrossCityController.java    |   18 +
 DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/OrderCrossCityMapper.java               |    2 
 DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/ReassignMapper.xml                 |   13 +
 DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/task/ReassignTimeoutTask.java                  |    5 
 DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java  |    2 
 DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/OrderCrossCityMapper.xml        |    8 
 12 files changed, 520 insertions(+), 101 deletions(-)

diff --git a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/OrderCrossCityController.java b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/OrderCrossCityController.java
index dba1b0e..6d87525 100644
--- a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/OrderCrossCityController.java
+++ b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/OrderCrossCityController.java
@@ -165,11 +165,20 @@
     })
     public ResultUtil respondReassign(String reassignIds, Integer responseType, HttpServletRequest request) {
         try {
-            Integer driverId = ShiroKit.getUser().getId();
+            Integer driverId = driverService.getUserIdFormRedis(request);
+            if (null == driverId) {
+                return ResultUtil.tokenErr();
+            }
+            if (ToolUtil.isEmpty(reassignIds)) {
+                return ResultUtil.success("改派ID不能为空", false);
+            }
+            if (responseType == null) {
+                return ResultUtil.success("响应类型不能为空", false);
+            }
             return reassignService.respondReassignBatch(reassignIds, driverId, responseType);
         } catch (Exception e) {
             e.printStackTrace();
-            return ResultUtil.error("操作失败");
+            return ResultUtil.success("操作失败", false);
         }
     }
 
@@ -186,7 +195,10 @@
     })
     public ResultUtil queryPendingReassigns(HttpServletRequest request) {
         try {
-            Integer driverId = ShiroKit.getUser().getId();
+            Integer driverId = driverService.getUserIdFormRedis(request);
+            if (null == driverId) {
+                return ResultUtil.tokenErr();
+            }
             List<Map<String, Object>> list = reassignService.queryPendingReassigns(driverId);
             return ResultUtil.success(list);
         } catch (Exception e) {
diff --git a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/LineShiftDriverMapper.java b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/LineShiftDriverMapper.java
index 5848c4d..1cdb014 100644
--- a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/LineShiftDriverMapper.java
+++ b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/LineShiftDriverMapper.java
@@ -70,6 +70,12 @@
      */
     List<Map<String, Object>> queryOtherDriverShiftListWithShiftId(@Param("driverShiftId") Long driverShiftId);
 
+    /**
+     * 查询同公司且当前班次时间段无订单、无其他预约批次的司机(改派扩展候选)
+     */
+    List<Map<String, Object>> queryAvailableCompanyDriversForShift(@Param("driverShiftId") Long driverShiftId,
+                                                                   @Param("orderId") Integer orderId);
+
     Integer queryCustomerIdByLineShiftDriverId(@Param("lineShiftDriverId") Integer lineShiftDriverId);
 
     /**
diff --git a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/OrderCrossCityMapper.java b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/OrderCrossCityMapper.java
index d81eff0..9fcf8b0 100644
--- a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/OrderCrossCityMapper.java
+++ b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/OrderCrossCityMapper.java
@@ -46,7 +46,7 @@
      * @param orderNum
      * @return
      */
-    List<Map<String, Object>> queryOrderInfo(@Param("orderNum") String orderNum);
+    List<Map<String, Object>> queryOrderInfo(@Param("orderNum") String orderNum, @Param("lineShiftDriverId") Integer lineShiftDriverId);
 
 
     /**
diff --git a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/LineShiftDriverMapper.xml b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/LineShiftDriverMapper.xml
index cc63641..83908a6 100644
--- a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/LineShiftDriverMapper.xml
+++ b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/LineShiftDriverMapper.xml
@@ -310,6 +310,78 @@
         ORDER BY ls.startTime ASC, other.id ASC
     </select>
 
+    <select id="queryAvailableCompanyDriversForShift" resultType="java.util.Map">
+        SELECT
+            0 - d.id as lineShiftDriverId,
+            d.id as driverId,
+            d.headImgUrl as headImgUrl,
+            d.name as driverName,
+            c.carLicensePlate as carLicensePlate,
+            CONCAT(IFNULL(cb.name, ''), IFNULL(cm.name, '')) as carModel,
+            IFNULL(c.carColor, '') as carColor,
+            (IFNULL(cm.seat, 1) - 1) as laveSeat,
+            (IFNULL(cm.seat, 1) - 1) as totalSeat,
+            IFNULL((
+                SELECT ROUND(AVG(oe.fraction), 2)
+                FROM t_order_evaluate oe
+                WHERE oe.driverId = d.id
+            ), 0) as score,
+            ls.startTime as startTime,
+            2 as needConfirm
+        FROM t_line_shift_driver cur
+        INNER JOIN t_line_shift ls ON cur.lineShiftId = ls.id
+        INNER JOIN t_order_cross_city occ ON occ.id = #{orderId}
+        INNER JOIN t_driver currentDriver ON cur.driverId = currentDriver.id
+        INNER JOIN t_driver d
+            ON d.id != cur.driverId
+            AND d.state = 2
+            AND (
+                (IFNULL(currentDriver.franchiseeId, 0) > 0 AND d.franchiseeId = currentDriver.franchiseeId)
+                OR (IFNULL(currentDriver.franchiseeId, 0) = 0 AND d.companyId = currentDriver.companyId)
+            )
+        INNER JOIN t_car c ON d.carId = c.id
+        LEFT JOIN t_car_brand cb ON c.carBrandId = cb.id
+        LEFT JOIN t_car_model cm ON c.carModelId = cm.id
+        WHERE cur.id = #{driverShiftId}
+          AND cur.lineShiftId != -1
+          AND ls.state = 1
+          AND (IFNULL(cm.seat, 1) - 1) >= IFNULL(occ.peopleNumber, 1)
+          AND NOT EXISTS (
+              SELECT 1
+              FROM t_line_shift_driver lsd2
+              INNER JOIN t_line_shift ls2 ON lsd2.lineShiftId = ls2.id
+              WHERE lsd2.driverId = d.id
+                AND lsd2.lineShiftId != -1
+                AND DATE(lsd2.day) = DATE(cur.day)
+                AND lsd2.id != cur.id
+                AND ls2.startTime &lt; ls.endTime
+                AND ls2.endTime &gt; ls.startTime
+          )
+          AND NOT EXISTS (
+              SELECT 1
+              FROM t_order_cross_city occ2
+              WHERE occ2.driverId = d.id
+                AND occ2.isDelete = 1
+                AND occ2.state IN (2, 3, 4, 5, 11)
+                AND DATE(occ2.travelTime) = DATE(cur.day)
+          )
+          AND NOT EXISTS (
+              SELECT 1
+              FROM t_order_taxi ot
+              WHERE ot.driverId = d.id
+                AND ot.state IN (2, 3, 4, 5, 11)
+                AND DATE(ot.travelTime) = DATE(cur.day)
+          )
+          AND NOT EXISTS (
+              SELECT 1
+              FROM t_order_private_car opc
+              WHERE opc.driverId = d.id
+                AND opc.state IN (2, 3, 4, 5, 11)
+                AND DATE(opc.travelTime) = DATE(cur.day)
+          )
+        ORDER BY d.id ASC
+    </select>
+
     <select id="queryExpiredNoOrderShiftIds" resultType="java.lang.Integer">
         SELECT lsd.id
         FROM t_line_shift_driver lsd
diff --git a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/OrderCrossCityMapper.xml b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/OrderCrossCityMapper.xml
index a0e988c..22c77e3 100644
--- a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/OrderCrossCityMapper.xml
+++ b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/OrderCrossCityMapper.xml
@@ -237,7 +237,13 @@
         left join t_user b on (a.userId = b.id)
         left join t_line_shift_driver c on (a.lineShiftDriverId = c.id)
 		left join t_line_shift d on (c.lineShiftId = d.id)
-        where a.orderNum = #{orderNum} and a.state in (2, 3, 4, 5, 6, 8, 9, 11) order by a.sort desc
+        where (a.orderNum = #{orderNum}
+            <if test="lineShiftDriverId != null">
+                or a.lineShiftDriverId = #{lineShiftDriverId}
+            </if>
+        )
+        and a.state in (2, 3, 4, 5, 6, 8, 9, 11)
+        order by a.sort desc
     </select>
 
 
diff --git a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/LineShiftDriverServiceImpl.java b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/LineShiftDriverServiceImpl.java
index 912fc37..6c2aaa7 100644
--- a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/LineShiftDriverServiceImpl.java
+++ b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/LineShiftDriverServiceImpl.java
@@ -79,6 +79,7 @@
     private ILineService lineService;
     @Autowired
     private IReassignService reassignService;
+    @Resource
     private LineMapper lineMapper;
 
 
@@ -446,28 +447,48 @@
             return new ArrayList<>();
         }
 
-        // 如果提供了订单ID,使用新的改派逻辑(包含needConfirm字段)
-        if (ToolUtil.isNotEmpty(orderIds)) {
-            try {
-                // 使用第一个订单ID来查询(改派场景通常是单个订单,多个订单取第一个)
-                String firstOrderId = orderIds.split(",")[0].trim();
-                List<Map<String, Object>> drivers = reassignService.queryDriver(firstOrderId);
-                return OtherDriverShiftWarpper.fromMaps(drivers);
-            } catch (Exception e) {
-                e.printStackTrace();
-                // 如果新逻辑失败,降级到旧逻辑
+        List<Map<String, Object>> rows = lineShiftDriverMapper.queryOtherDriverShiftListWithShiftId(driverShiftId);
+        // 同批次司机不需要确认。
+        Set<Integer> driverIds = new HashSet<>();
+        for (Map<String, Object> row : rows) {
+            row.put("needConfirm", 1);
+            if (row.get("driverId") != null) {
+                driverIds.add(Integer.valueOf(row.get("driverId").toString()));
             }
         }
 
-        // 旧逻辑:只查询同批次司机(兼容没有传orderIds的场景)
-        List<Map<String, Object>> rows = lineShiftDriverMapper.queryOtherDriverShiftListWithShiftId(driverShiftId);
-        // 旧逻辑默认都是同批次,不需要确认
-        for (Map<String, Object> row : rows) {
-            row.put("needConfirm", 1);
+        // 扩展内容:对应时间段无订单且无其他预约批次的同公司其他司机,需要确认。
+        Integer firstOrderId = getFirstOrderId(orderIds);
+        if (firstOrderId != null) {
+            List<Map<String, Object>> extraRows = lineShiftDriverMapper.queryAvailableCompanyDriversForShift(driverShiftId, firstOrderId);
+            for (Map<String, Object> row : extraRows) {
+                if (row.get("driverId") == null) {
+                    continue;
+                }
+                Integer extraDriverId = Integer.valueOf(row.get("driverId").toString());
+                if (driverIds.contains(extraDriverId)) {
+                    continue;
+                }
+                row.put("needConfirm", 2);
+                rows.add(row);
+                driverIds.add(extraDriverId);
+            }
         }
         return OtherDriverShiftWarpper.fromMaps(rows);
     }
 
+    private Integer getFirstOrderId(String orderIds) {
+        if (ToolUtil.isEmpty(orderIds)) {
+            return null;
+        }
+        try {
+            String firstOrderId = orderIds.split(",")[0].trim();
+            return ToolUtil.isEmpty(firstOrderId) ? null : Integer.valueOf(firstOrderId);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public ResultUtil<Map<String, Object>> addSelfTrip(Integer driverId, AddSelfTripWarpper warpper) throws Exception {
diff --git a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java
index 8e56269..ab93e43 100644
--- a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java
+++ b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java
@@ -231,7 +231,7 @@
     public Map<String, Object> queryOrderInfo(Integer orderId) throws Exception {
         Map<String, Object> map = new HashMap<>();
         OrderCrossCity orderCrossCity = this.selectById(orderId);
-        List<Map<String, Object>> order = orderCrossCityMapper.queryOrderInfo(orderCrossCity.getOrderNum());
+        List<Map<String, Object>> order = orderCrossCityMapper.queryOrderInfo(orderCrossCity.getOrderNum(), orderCrossCity.getLineShiftDriverId());
 
         int num = 0;
         Double serverMoney = 0D;
diff --git a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/ReassignMapper.xml b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/ReassignMapper.xml
index 0c34acd..1bebd62 100644
--- a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/ReassignMapper.xml
+++ b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/ReassignMapper.xml
@@ -12,6 +12,11 @@
         <result column="insertTime" property="insertTime"/>
         <result column="nowDriverId" property="nowDriverId"/>
         <result column="nowCarId" property="nowCarId"/>
+        <result column="needConfirm" property="needConfirm"/>
+        <result column="confirmStatus" property="confirmStatus"/>
+        <result column="confirmTime" property="confirmTime"/>
+        <result column="expireTime" property="expireTime"/>
+        <result column="tempLineShiftDriverId" property="tempLineShiftDriverId"/>
         <result column="money" property="money"/>
         <result column="payType" property="payType"/>
         <result column="payTime" property="payTime"/>
@@ -33,6 +38,11 @@
         insertTime as insertTime,
         nowDriverId as nowDriverId,
         nowCarId as nowCarId,
+        needConfirm as needConfirm,
+        confirmStatus as confirmStatus,
+        confirmTime as confirmTime,
+        expireTime as expireTime,
+        tempLineShiftDriverId as tempLineShiftDriverId,
         money as money,
         payType as payType,
         payTime as payTime,
@@ -60,6 +70,7 @@
                 #{item}
             </foreach>
         </if>
+        order by id desc limit 1
     </select>
 
     <select id="queryList" resultType="map">
@@ -69,4 +80,4 @@
         ('改派处罚') as name
         from t_reassign where payTime is not null and originalDriverId = #{uid} order by insertTime desc limit #{pageNum}, #{size}
     </select>
-</mapper>
\ No newline at end of file
+</mapper>
diff --git a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IReassignService.java b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IReassignService.java
index f584805..9dabfd9 100644
--- a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IReassignService.java
+++ b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IReassignService.java
@@ -86,4 +86,9 @@
      * @return
      */
     List<Map<String, Object>> queryPendingReassigns(Integer driverId);
+
+    /**
+     * 改派确认超时后恢复订单状态
+     */
+    void timeoutReassign(Reassign reassign) throws Exception;
 }
diff --git a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/ReassignServiceImpl.java b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/ReassignServiceImpl.java
index 391be0c..8fd8b95 100644
--- a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/ReassignServiceImpl.java
+++ b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/ReassignServiceImpl.java
@@ -155,14 +155,14 @@
 //        }
         int types = 1;
         Reassign query = reassignMapper.query(uid, null, reassign.getOrderId(), reassign.getOrderType(), 1);
-        if (null != query) {
+        if (isActiveReassign(query)) {
             types = 2;
 //            return ResultUtil.error("不能重复提交申请");
             reassignMapper.deleteById(query.getId());
         }
         query = reassignMapper.query(uid, null, reassign.getOrderId(), reassign.getOrderType(), 2);
 
-        if (null != query) {
+        if (isActiveReassign(query)) {
             types = 2;
 //            return ResultUtil.error("您提交的申请正在处理中");
         }
@@ -472,7 +472,7 @@
 
         // 跨城改派:如果指定了司机,不收改派费用
         Double aDouble;
-        if (reassign.getNowDriverId() != null && reassign.getNowDriverId() > 0) {
+        if (isAssignedReassignTarget(reassign.getNowDriverId())) {
             aDouble = 0.0; // 指定司机,免费
         } else {
             aDouble = orderService.queryReassignMoney(Integer.valueOf(split[0]), 3);
@@ -480,14 +480,16 @@
 
         Double totalMoney = aDouble * split.length;
         String ids = "";
+        Integer requestTargetId = reassign.getNowDriverId();
+        List<Reassign> currentReassignList = new ArrayList<>();
         for (String id : split) {
             Reassign query = reassignMapper.query(uid, null, Integer.valueOf(id), 3, 1);
-            if (null != query) {
+            if (isActiveReassign(query)) {
 //                return ResultUtil.error("不能重复提交申请");
                 reassignMapper.deleteById(query.getId());
             }
             query = reassignMapper.query(uid, null, Integer.valueOf(id), 3, 2);
-            if (null != query) {
+            if (isActiveReassign(query)) {
                 return ResultUtil.error("您提交的申请正在处理中");
             }
 
@@ -498,19 +500,27 @@
             reassign.setOriginalCarId(driver.getCarId());
             reassign.setInsertTime(new Date());
             reassign.setState(1);
+            reassign.setNowDriverId(requestTargetId);
+            reassign.setNeedConfirm(null);
+            reassign.setConfirmStatus(null);
+            reassign.setConfirmTime(null);
+            reassign.setExpireTime(null);
+            reassign.setTempLineShiftDriverId(null);
 
             // 设置是否需要确认相关字段
-            if (reassign.getNowDriverId() != null && reassign.getNowDriverId() > 0) {
+            if (isAssignedReassignTarget(requestTargetId)) {
                 OrderCrossCity orderCrossCity = orderCrossCityService.selectById(Integer.valueOf(id));
-                boolean needConfirm = checkIfNeedConfirm(reassign.getNowDriverId(), orderCrossCity);
+                boolean needConfirm = checkIfNeedConfirm(requestTargetId, orderCrossCity);
                 reassign.setNeedConfirm(needConfirm ? 2 : 1);
 
                 if (needConfirm) {
+                    reassign.setNowDriverId(resolveConfirmDriverId(requestTargetId));
                     // 需要确认:设置超时时间
                     reassign.setConfirmStatus(1); // 待确认
                     Date expireTime = new Date(System.currentTimeMillis() + 60000); // 60秒后
                     reassign.setExpireTime(expireTime);
                 } else {
+                    reassign.setNowDriverId(requestTargetId);
                     // 不需要确认
                     reassign.setConfirmStatus(2); // 直接同意
                 }
@@ -520,10 +530,16 @@
             }
 
             this.insert(reassign);
+            currentReassignList.add(this.selectById(reassign.getId()));
             ids += reassign.getId() + ",";
         }
         ids = ids.substring(0, ids.length() - 1);
         systemNoticeService.addSystemNotice(2, "您的改派申请已成功提交,我们会尽快为你处理!", uid, 1);
+
+        if (isAssignedReassignTarget(requestTargetId)) {
+            processFreeAssignedCrossCityReassign(split, currentReassignList, reassign);
+            return ResultUtil.success();
+        }
 
         //开始支付
         if (null != reassign.getPayType()) {
@@ -579,6 +595,7 @@
                 //修改改派通知状态
                 boolean needConfirmPush = false; // 标记是否需要发送确认推送
                 OrderCrossCity firstOrder = null; // 保存第一个订单用于发送推送
+                Reassign firstConfirmReassign = null; // 保存第一条待确认改派记录
                 int totalPeopleNumber = 0; // 累计总人数
                 List<String> orderIdList = new ArrayList<>(); // 收集所有订单ID
                 List<String> reassignIdList = new ArrayList<>(); // 收集所有改派记录ID
@@ -588,7 +605,7 @@
                     orderCrossCity.setOldState(orderCrossCity.getState());
 
                     // 查询改派记录
-                    Reassign reassignRecord = reassignMapper.query(uid, null, Integer.valueOf(id), 3, 1);
+                    Reassign reassignRecord = reassignMapper.query(uid, null, Integer.valueOf(id), 3, 1, 2, 3);
                     if (reassignRecord != null) {
                         reassignIdList.add(String.valueOf(reassignRecord.getId()));
                     }
@@ -599,22 +616,31 @@
                     }
                     orderIdList.add(id);
 
-                    if(reassign.getNowDriverId()==null){
+                    if(reassignRecord == null || reassignRecord.getNowDriverId()==null){
+                        System.out.println("跨城改派确认Socket未触发: reassignRecord为空或未指定司机, orderId=" + id);
                         orderCrossCity.setState(11);
                     }else {
-                        // 检查是否需要确认
-                        boolean needConfirm = checkIfNeedConfirm(reassign.getNowDriverId(), orderCrossCity);
+                        boolean needConfirm = reassignRecord.getNeedConfirm() != null && reassignRecord.getNeedConfirm() == 2;
+                        System.out.println("跨城改派余额支付确认判断: orderId=" + id
+                                + ", reassignId=" + reassignRecord.getId()
+                                + ", nowDriverId=" + reassignRecord.getNowDriverId()
+                                + ", needConfirm=" + reassignRecord.getNeedConfirm()
+                                + ", confirmStatus=" + reassignRecord.getConfirmStatus()
+                                + ", state=" + reassignRecord.getState());
 
                         if (needConfirm) {
                             // 需要确认:标记需要发送推送,但不立即发送
                             orderCrossCity.setState(11); // 改派中状态
                             needConfirmPush = true;
+                            if (firstConfirmReassign == null) {
+                                firstConfirmReassign = reassignRecord;
+                            }
                             if (firstOrder == null) {
                                 firstOrder = orderCrossCity; // 保存第一个订单
                             }
                         } else {
                             // 不需要确认:直接改派
-                            driverReassignSelf(reassign, orderCrossCity);
+                            driverReassignSelf(reassignRecord, orderCrossCity);
 
                             // 只有无需确认时才推送乘客和司机信息
                             try {
@@ -636,8 +662,15 @@
                 }
 
                 // 所有订单处理完后,只发送一次确认推送
-                if (needConfirmPush && firstOrder != null) {
-                    sendReassignConfirmPush(reassign.getNowDriverId(), reassign, firstOrder, totalPeopleNumber, orderIdList, reassignIdList);
+                if (needConfirmPush && firstOrder != null && firstConfirmReassign != null) {
+                    System.out.println("准备发送跨城改派确认Socket(余额支付): driverId=" + firstConfirmReassign.getNowDriverId()
+                            + ", reassignIds=" + String.join(",", reassignIdList)
+                            + ", orderIds=" + String.join(",", orderIdList));
+                    sendReassignConfirmPush(firstConfirmReassign.getNowDriverId(), firstConfirmReassign, firstOrder, totalPeopleNumber, orderIdList, reassignIdList);
+                } else {
+                    System.out.println("跨城改派确认Socket未发送(余额支付): needConfirmPush=" + needConfirmPush
+                            + ", firstOrder=" + (firstOrder == null ? "null" : firstOrder.getId())
+                            + ", firstConfirmReassign=" + (firstConfirmReassign == null ? "null" : firstConfirmReassign.getId()));
                 }
                 systemNoticeService.addSystemNotice(2, "您已使用余额成功支付改派申请费用!", uid, 1);
 
@@ -716,6 +749,7 @@
             String[] split = s[0].split(",");
             List<Reassign> reassigns = this.selectBatchIds(Arrays.asList(split));
             Driver driver = driverService.selectById(reassigns.get(0).getOriginalDriverId());
+            boolean batchHandled = false;
             for (String key : split) {
                 PaymentRecord query = paymentRecordService.query(1, driver.getId(), 2, Integer.valueOf(key), 3, type, 1);
                 if (null != query) {
@@ -744,16 +778,60 @@
                     query.setCode(order_id);
                     paymentRecordService.updateById(query);
                     System.out.println("==============paymentRecord完毕===================" + query);
+
+                    if (batchHandled) {
+                        continue;
+                    }
+                    batchHandled = true;
+
                     //修改改派通知状态
+                    boolean needConfirmPush = false;
+                    OrderCrossCity firstOrder = null;
+                    Reassign firstConfirmReassign = null;
+                    int totalPeopleNumber = 0;
+                    List<String> orderIdList = new ArrayList<>();
+                    List<String> reassignIdList = new ArrayList<>();
                     for (Reassign reassign : reassigns) {
                         OrderCrossCity orderCrossCity1 = orderCrossCityService.selectById(reassign.getOrderId());
                         orderCrossCity1.setOldState(orderCrossCity1.getState());
+                        if (orderCrossCity1.getPeopleNumber() != null) {
+                            totalPeopleNumber += orderCrossCity1.getPeopleNumber();
+                        }
+                        orderIdList.add(String.valueOf(orderCrossCity1.getId()));
+                        reassignIdList.add(String.valueOf(reassign.getId()));
                         if(reassign.getNowDriverId()==null){
+                            System.out.println("跨城改派确认Socket未触发: 未指定司机, reassignId=" + reassign.getId() + ", orderId=" + reassign.getOrderId());
                             orderCrossCity1.setState(11);
                         } else {
-//                            orderCrossCity1.setDriverId(reassign.getNowDriverId());
-                            //reassign.getNowDriverId() 是lineShiftDriverId
-                            driverReassignSelf(reassign, orderCrossCity1);
+                            boolean needConfirm = reassign.getNeedConfirm() != null
+                                    ? reassign.getNeedConfirm() == 2
+                                    : checkIfNeedConfirm(reassign.getNowDriverId(), orderCrossCity1);
+                            System.out.println("跨城改派在线支付确认判断: orderId=" + reassign.getOrderId()
+                                    + ", reassignId=" + reassign.getId()
+                                    + ", nowDriverId=" + reassign.getNowDriverId()
+                                    + ", needConfirm=" + reassign.getNeedConfirm()
+                                    + ", confirmStatus=" + reassign.getConfirmStatus()
+                                    + ", state=" + reassign.getState()
+                                    + ", needConfirmResult=" + needConfirm);
+                            if (needConfirm) {
+                                if (reassign.getNeedConfirm() == null) {
+                                    reassign.setNowDriverId(resolveConfirmDriverId(reassign.getNowDriverId()));
+                                }
+                                ensureReassignConfirmTimeout(reassign);
+                                reassign.setState(3);
+                                this.updateById(reassign);
+                                orderCrossCity1.setState(11);
+                                needConfirmPush = true;
+                                if (firstConfirmReassign == null) {
+                                    firstConfirmReassign = reassign;
+                                }
+                                if (firstOrder == null) {
+                                    firstOrder = orderCrossCity1;
+                                }
+                            } else {
+                                // reassign.getNowDriverId() 是 lineShiftDriverId
+                                driverReassignSelf(reassign, orderCrossCity1);
+                            }
                         }
                         orderCrossCity1.setReassignNotice(2);
                         orderCrossCity1.setIsReassign(2);
@@ -765,11 +843,23 @@
 
 
                         if(reassign.getNowDriverId()!=null){
-                            // 推送用户消息
-                            pushUtil.pushOrderReassign(orderCrossCity1.getUserId(), 1, orderCrossCity1.getId(), 3);
-                            // 推送司机消息
-                            pushUtil.pushOrderReassign(orderCrossCity1.getDriverId(), 2, orderCrossCity1.getId(), 3);
+                            if (reassign.getNeedConfirm() == null || reassign.getNeedConfirm().intValue() != 2) {
+                                // 推送用户消息
+                                pushUtil.pushOrderReassign(orderCrossCity1.getUserId(), 1, orderCrossCity1.getId(), 3);
+                                // 推送司机消息
+                                pushUtil.pushOrderReassign(orderCrossCity1.getDriverId(), 2, orderCrossCity1.getId(), 3);
+                            }
                         }
+                    }
+                    if (needConfirmPush && firstOrder != null && firstConfirmReassign != null) {
+                        System.out.println("准备发送跨城改派确认Socket(在线支付): driverId=" + firstConfirmReassign.getNowDriverId()
+                                + ", reassignIds=" + String.join(",", reassignIdList)
+                                + ", orderIds=" + String.join(",", orderIdList));
+                        sendReassignConfirmPush(firstConfirmReassign.getNowDriverId(), firstConfirmReassign, firstOrder, totalPeopleNumber, orderIdList, reassignIdList);
+                    } else {
+                        System.out.println("跨城改派确认Socket未发送(在线支付): needConfirmPush=" + needConfirmPush
+                                + ", firstOrder=" + (firstOrder == null ? "null" : firstOrder.getId())
+                                + ", firstConfirmReassign=" + (firstConfirmReassign == null ? "null" : firstConfirmReassign.getId()));
                     }
                     systemNoticeService.addSystemNotice(2, "您已使用" + (type == 1 ? "微信" : (type == 2 ? "支付宝" : "云闪付")) + "成功支付改派申请费用!", reassigns.get(0).getOriginalDriverId(), 1);
                     System.out.println("==============跨城修改改派通知状态完毕===================");
@@ -873,6 +963,10 @@
     }
 
     private void driverReassignSelf(Reassign reassign, OrderCrossCity orderCrossCity1) {
+        driverReassignSelf(reassign, orderCrossCity1, null);
+    }
+
+    private void driverReassignSelf(Reassign reassign, OrderCrossCity orderCrossCity1, Integer peopleNumberOverride) {
         // 交换人数 交换座位
         Integer oldLineShiftDriverId = orderCrossCity1.getLineShiftDriverId();
         LineShiftDriver oldLineShiftDriver = lineShiftDriverMapper.selectById(oldLineShiftDriverId);
@@ -881,7 +975,7 @@
         orderCrossCity1.setLineShiftDriverId(reassign.getNowDriverId());
         Driver driver1 = driverService.selectById(lineShiftDriver.getDriverId());
         orderCrossCity1.setCarId(driver1.getCarId());
-        Integer peopleNumber = orderCrossCity1.getPeopleNumber();
+        Integer peopleNumber = peopleNumberOverride == null ? orderCrossCity1.getPeopleNumber() : peopleNumberOverride;
         oldLineShiftDriver.setLaveSeat(oldLineShiftDriver.getLaveSeat() + peopleNumber);
         lineShiftDriver.setLaveSeat(lineShiftDriver.getLaveSeat() - peopleNumber);
         String laveSeatNumber = Arrays.stream(lineShiftDriver.getLaveSeatNumber().split(",")).skip(peopleNumber).collect(Collectors.joining(","));
@@ -897,6 +991,137 @@
         lineShiftDriver.setLaveSeatNumber(laveSeatNumber);
         lineShiftDriverMapper.updateById(oldLineShiftDriver);
         lineShiftDriverMapper.updateById(lineShiftDriver);
+    }
+
+    private void processFreeAssignedCrossCityReassign(String[] orderIds, List<Reassign> currentReassignList, Reassign requestReassign) throws Exception {
+        Map<Integer, Reassign> currentReassignMap = new HashMap<>();
+        for (Reassign currentReassign : currentReassignList) {
+            if (currentReassign == null || currentReassign.getOrderId() == null) {
+                continue;
+            }
+            currentReassign.setState(currentReassign.getNowDriverId() != null ? 3 : 2);
+            currentReassign.setPayTime(new Date());
+            reassignMapper.updateById(currentReassign);
+            currentReassignMap.put(currentReassign.getOrderId(), currentReassign);
+        }
+
+        boolean needConfirmPush = false;
+        OrderCrossCity firstOrder = null;
+        Reassign firstConfirmReassign = null;
+        int totalPeopleNumber = 0;
+        List<String> orderIdList = new ArrayList<>();
+        List<String> reassignIdList = new ArrayList<>();
+
+        for (String id : orderIds) {
+            OrderCrossCity orderCrossCity = orderCrossCityService.selectById(id);
+            if (orderCrossCity == null) {
+                continue;
+            }
+            orderCrossCity.setOldState(orderCrossCity.getState());
+
+            Reassign reassignRecord = currentReassignMap.get(Integer.valueOf(id));
+            if (reassignRecord != null) {
+                reassignIdList.add(String.valueOf(reassignRecord.getId()));
+            }
+
+            if (orderCrossCity.getPeopleNumber() != null) {
+                totalPeopleNumber += orderCrossCity.getPeopleNumber();
+            }
+            orderIdList.add(id);
+
+            if (reassignRecord == null || reassignRecord.getNowDriverId() == null) {
+                orderCrossCity.setState(11);
+            } else {
+                boolean needConfirm = reassignRecord.getNeedConfirm() != null && reassignRecord.getNeedConfirm() == 2;
+                System.out.println("跨城指定司机免费改派确认判断: orderId=" + id
+                        + ", reassignId=" + reassignRecord.getId()
+                        + ", nowDriverId=" + reassignRecord.getNowDriverId()
+                        + ", needConfirm=" + reassignRecord.getNeedConfirm()
+                        + ", confirmStatus=" + reassignRecord.getConfirmStatus()
+                        + ", state=" + reassignRecord.getState());
+
+                if (needConfirm) {
+                    orderCrossCity.setState(11);
+                    needConfirmPush = true;
+                    if (firstConfirmReassign == null) {
+                        firstConfirmReassign = reassignRecord;
+                    }
+                    if (firstOrder == null) {
+                        firstOrder = orderCrossCity;
+                    }
+                } else {
+                    driverReassignSelf(reassignRecord, orderCrossCity);
+                    try {
+                        pushUtil.pushOrderReassign(orderCrossCity.getUserId(), 1, orderCrossCity.getId(), 3);
+                        pushUtil.pushOrderReassign(orderCrossCity.getDriverId(), 2, orderCrossCity.getId(), 3);
+                    } catch (Exception ignore) {
+                    }
+                }
+            }
+
+            orderCrossCity.setReassignNotice(2);
+            orderCrossCity.setIsReassign(2);
+            orderCrossCityService.updateById(orderCrossCity);
+            incomeService.saveData(1, orderCrossCity.getCompanyId(), 4, orderCrossCity.getId(), 3, requestReassign.getMoney());
+        }
+
+        if (needConfirmPush && firstOrder != null && firstConfirmReassign != null) {
+            System.out.println("准备发送跨城改派确认Socket(指定司机免费): driverId=" + firstConfirmReassign.getNowDriverId()
+                    + ", reassignIds=" + String.join(",", reassignIdList)
+                    + ", orderIds=" + String.join(",", orderIdList));
+            sendReassignConfirmPush(firstConfirmReassign.getNowDriverId(), firstConfirmReassign, firstOrder, totalPeopleNumber, orderIdList, reassignIdList);
+        } else {
+            System.out.println("跨城改派确认Socket未发送(指定司机免费): needConfirmPush=" + needConfirmPush
+                    + ", firstOrder=" + (firstOrder == null ? "null" : firstOrder.getId())
+                    + ", firstConfirmReassign=" + (firstConfirmReassign == null ? "null" : firstConfirmReassign.getId()));
+        }
+    }
+
+    private void ensureReassignConfirmTimeout(Reassign reassign) {
+        reassign.setNeedConfirm(2);
+        reassign.setConfirmStatus(1);
+        if (reassign.getExpireTime() == null) {
+            reassign.setExpireTime(new Date(System.currentTimeMillis() + 60000));
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void timeoutReassign(Reassign reassign) throws Exception {
+        if (reassign == null) {
+            return;
+        }
+        Reassign current = this.selectById(reassign.getId());
+        if (current == null || current.getConfirmStatus() == null || current.getConfirmStatus() != 1) {
+            return;
+        }
+        current.setConfirmStatus(4);
+        current.setState(5);
+        current.setConfirmTime(new Date());
+        this.updateById(current);
+        restoreCrossCityOrderAfterReassignEnd(current);
+    }
+
+    private void restoreCrossCityOrderAfterReassignEnd(Reassign reassign) {
+        if (reassign == null || reassign.getOrderType() == null || reassign.getOrderType() != 3 || reassign.getOrderId() == null) {
+            return;
+        }
+        OrderCrossCity order = orderCrossCityService.selectById(reassign.getOrderId());
+        if (order == null || order.getState() == null || order.getState() != 11) {
+            return;
+        }
+        order.setState(order.getOldState() == null ? 2 : order.getOldState());
+        order.setReassignNotice(0);
+        order.setIsReassign(1);
+        orderCrossCityService.updateById(order);
+    }
+    private void restoreCrossCityOrderAfterReassignSuccess(OrderCrossCity order) {
+        if (order == null || order.getState() == null || order.getState() != 11) {
+            return;
+        }
+        order.setState(order.getOldState() == null ? 2 : order.getOldState());
+        order.setReassignNotice(0);
+        order.setIsReassign(1);
     }
 
     @Override
@@ -1325,34 +1550,61 @@
 
     /**
      * 检查是否需要对方确认
-     * @param targetDriverId 目标司机ID
+     * @param targetId 正数为同批次 lineShiftDriverId,负数为扩展司机的 0-driverId
      * @param orderCrossCity 订单
      * @return true=需要确认, false=不需要确认
      */
-    private boolean checkIfNeedConfirm(Integer targetDriverId, OrderCrossCity orderCrossCity) {
+    private boolean checkIfNeedConfirm(Integer targetId, OrderCrossCity orderCrossCity) {
         try {
-            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-            String day = sdf.format(orderCrossCity.getTravelTime());
-
-            // 查询目标司机在该时段是否有排班
-            LineShiftDriver originalLsd = lineShiftDriverMapper.selectById(orderCrossCity.getLineShiftDriverId());
-            if (originalLsd == null) {
+            if (targetId == null || orderCrossCity == null || orderCrossCity.getLineShiftDriverId() == null) {
                 return true;
             }
-
-            int count = lineShiftDriverMapper.selectCount(
-                new EntityWrapper<LineShiftDriver>()
-                    .eq("driverId", targetDriverId)
-                    .eq("lineShiftId", originalLsd.getLineShiftId())
-                    .eq("day", sdf.parse(day))
-            );
-
-            // 有排班 = 同批次同时间 = 不需要确认
-            return count == 0;
+            if (targetId < 0) {
+                return true;
+            }
+            LineShiftDriver targetLineShiftDriver = lineShiftDriverMapper.selectById(targetId);
+            if (targetLineShiftDriver == null) {
+                return true;
+            }
+            LineShiftDriver originalLsd = lineShiftDriverMapper.selectById(orderCrossCity.getLineShiftDriverId());
+            if (originalLsd == null || targetLineShiftDriver.getLineShiftId() == null || originalLsd.getLineShiftId() == null) {
+                return true;
+            }
+            return targetLineShiftDriver.getLineShiftId().compareTo(originalLsd.getLineShiftId()) != 0
+                    || targetLineShiftDriver.getDay() == null
+                    || originalLsd.getDay() == null
+                    || !new SimpleDateFormat("yyyy-MM-dd").format(targetLineShiftDriver.getDay())
+                    .equals(new SimpleDateFormat("yyyy-MM-dd").format(originalLsd.getDay()));
         } catch (Exception e) {
             e.printStackTrace();
             return true; // 出错默认需要确认
         }
+    }
+
+    private boolean isAssignedReassignTarget(Integer targetId) {
+        return targetId != null && targetId != 0;
+    }
+
+    private boolean isActiveReassign(Reassign reassign) {
+        if (reassign == null) {
+            return false;
+        }
+        if (reassign.getState() != null && (reassign.getState() == 4 || reassign.getState() == 5)) {
+            return false;
+        }
+        return reassign.getConfirmStatus() == null
+                || (reassign.getConfirmStatus() != 3 && reassign.getConfirmStatus() != 4);
+    }
+
+    private Integer resolveConfirmDriverId(Integer targetId) {
+        if (targetId == null) {
+            return null;
+        }
+        if (targetId < 0) {
+            return 0 - targetId;
+        }
+        LineShiftDriver lineShiftDriver = lineShiftDriverMapper.selectById(targetId);
+        return lineShiftDriver == null ? targetId : lineShiftDriver.getDriverId();
     }
 
     /**
@@ -1366,13 +1618,18 @@
      */
     private void sendReassignConfirmPush(Integer driverId, Reassign reassign, OrderCrossCity order, int totalPeopleNumber, List<String> orderIdList, List<String> reassignIdList) {
         try {
+            System.out.println("进入跨城改派确认Socket发送方法: driverId=" + driverId
+                    + ", reassignId=" + (reassign == null ? "null" : reassign.getId())
+                    + ", orderId=" + (order == null ? "null" : order.getId())
+                    + ", totalPeopleNumber=" + totalPeopleNumber);
             // 使用订单的起点和终点地址(订单的startAddress和endAddress就是跨城站点地址)
             String startSite = order.getStartAddress() != null ? order.getStartAddress() : "";
             String endSite = order.getEndAddress() != null ? order.getEndAddress() : "";
 
             // 转换时间为字符串
-            String travelTime = order.getTravelTime() != null ? order.getTravelTime().toString() : "";
-            String expireTime = reassign.getExpireTime() != null ? reassign.getExpireTime().toString() : "";
+            SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            String travelTime = order.getTravelTime() != null ? dateTimeFormat.format(order.getTravelTime()) : "";
+            String expireTime = reassign.getExpireTime() != null ? dateTimeFormat.format(reassign.getExpireTime()) : "";
 
             // 使用 Socket 推送(不用极光推送)
             pushUtil.pushReassignConfirmRequest(
@@ -1397,6 +1654,10 @@
      * @return 新创建的 LineShiftDriverId
      */
     private Integer createTempLineShiftDriver(OrderCrossCity order, Integer driverId) throws Exception {
+        return createTempLineShiftDriver(order, driverId, order.getPeopleNumber());
+    }
+
+    private Integer createTempLineShiftDriver(OrderCrossCity order, Integer driverId, Integer peopleNumber) throws Exception {
         // 获取原始班次信息
         LineShiftDriver originalLsd = lineShiftDriverMapper.selectById(order.getLineShiftDriverId());
         if (originalLsd == null) {
@@ -1427,11 +1688,11 @@
 
         int totalSeat = carModel.getSeat() - 1; // 总座位数(减去司机位)
         tempLsd.setTotalSeat(totalSeat);
-        tempLsd.setLaveSeat(totalSeat - order.getPeopleNumber());
+        tempLsd.setLaveSeat(totalSeat);
 
-        // 生成座位号
+        // 新建临时班次时先放全部可用座位,后续统一按本批总人数扣减。
         StringBuilder seatNumbers = new StringBuilder();
-        for (int i = 1; i <= order.getPeopleNumber(); i++) {
+        for (int i = 1; i <= totalSeat; i++) {
             if (i > 1) seatNumbers.append(",");
             seatNumbers.append(i);
         }
@@ -1509,7 +1770,7 @@
     public ResultUtil respondReassignBatch(String reassignIds, Integer driverId, Integer responseType) {
         try {
             if (reassignIds == null || reassignIds.trim().isEmpty()) {
-                return ResultUtil.error("改派申请ID不能为空");
+                return reassignResponse("改派申请ID不能为空", false);
             }
 
             String[] idArray = reassignIds.split(",");
@@ -1521,24 +1782,24 @@
                 Reassign reassign = this.baseMapper.selectById(reassignId);
 
                 if (reassign == null) {
-                    return ResultUtil.error("改派申请不存在: " + reassignId);
+                    return reassignResponse("改派申请不存在: " + reassignId, false);
                 }
 
                 // 验证权限:检查nowDriverId是否匹配
                 if (reassign.getNowDriverId() == null || !reassign.getNowDriverId().equals(driverId)) {
-                    return ResultUtil.error("无权操作改派申请: " + reassignId);
+                    return reassignResponse("无权操作改派申请: " + reassignId, false);
                 }
 
                 // 幂等性检查:只有待确认状态才能响应
                 if (reassign.getConfirmStatus() != 1) {
                     if (reassign.getConfirmStatus() == 2) {
-                        return ResultUtil.error("改派申请已被接受: " + reassignId);
+                        return reassignResponse("改派申请已被接受: " + reassignId, false);
                     } else if (reassign.getConfirmStatus() == 3) {
-                        return ResultUtil.error("改派申请已被拒绝: " + reassignId);
+                        return reassignResponse("改派申请已被拒绝: " + reassignId, false);
                     } else if (reassign.getConfirmStatus() == 4) {
-                        return ResultUtil.error("改派申请已超时: " + reassignId);
+                        return reassignResponse("改派申请已超时: " + reassignId, false);
                     } else {
-                        return ResultUtil.error("改派申请已处理: " + reassignId);
+                        return reassignResponse("改派申请已处理: " + reassignId, false);
                     }
                 }
 
@@ -1546,7 +1807,7 @@
                 if (new Date().after(reassign.getExpireTime())) {
                     reassign.setConfirmStatus(4);
                     this.updateById(reassign);
-                    return ResultUtil.error("改派申请已超时: " + reassignId);
+                    return reassignResponse("改派申请已超时: " + reassignId, false);
                 }
 
                 reassignList.add(reassign);
@@ -1555,10 +1816,39 @@
             // 第二步:批量处理所有改派记录
             if (responseType == 1) {
                 // 同意改派
+                List<OrderCrossCity> orderList = new ArrayList<>();
+                int totalPeopleNumber = 0;
                 for (Reassign reassign : reassignList) {
+                    OrderCrossCity order = orderCrossCityService.selectById(reassign.getOrderId());
+                    if (order == null) {
+                        return reassignResponse("订单不存在: " + reassign.getOrderId(), false);
+                    }
+                    if (order.getState() != 11) {
+                        return reassignResponse("订单状态已变更,无法改派: " + order.getId(), false);
+                    }
+                    orderList.add(order);
+                    if (order.getPeopleNumber() != null) {
+                        totalPeopleNumber += order.getPeopleNumber();
+                    }
+                }
+
+                OrderCrossCity firstOrder = orderList.get(0);
+                String batchOrderNum = firstOrder.getOrderNum();
+                Integer tempLineShiftDriverId = createTempLineShiftDriver(firstOrder, driverId, totalPeopleNumber);
+                Reassign tempReassign = new Reassign();
+                tempReassign.setNowDriverId(tempLineShiftDriverId);
+                driverReassignSelf(tempReassign, firstOrder, totalPeopleNumber);
+
+                LineShiftDriver tempLineShiftDriver = lineShiftDriverMapper.selectById(tempLineShiftDriverId);
+                Driver targetDriver = driverService.selectById(driverId);
+
+                for (int i = 0; i < reassignList.size(); i++) {
+                    Reassign reassign = reassignList.get(i);
+                    OrderCrossCity order = orderList.get(i);
                     // 使用乐观锁更新状态
                     reassign.setConfirmStatus(2);
                     reassign.setConfirmTime(new Date());
+                    reassign.setTempLineShiftDriverId(tempLineShiftDriverId);
                     int updateCount = this.baseMapper.update(reassign,
                         new EntityWrapper<Reassign>()
                             .eq("id", reassign.getId())
@@ -1566,32 +1856,22 @@
                     );
 
                     if (updateCount == 0) {
-                        return ResultUtil.error("改派申请已被处理: " + reassign.getId());
+                        return reassignResponse("改派申请已被处理: " + reassign.getId(), false);
                     }
 
-                    // 获取订单信息
-                    OrderCrossCity order = orderCrossCityService.selectById(reassign.getOrderId());
-                    if (order == null) {
-                        return ResultUtil.error("订单不存在: " + reassign.getOrderId());
+                    order.setDriverId(tempLineShiftDriver.getDriverId());
+                    order.setLineShiftDriverId(tempLineShiftDriverId);
+                    order.setOrderNum(batchOrderNum);
+                    restoreCrossCityOrderAfterReassignSuccess(order);
+                    if (targetDriver != null) {
+                        order.setCarId(targetDriver.getCarId());
                     }
-
-                    // 检查订单状态
-                    if (order.getState() != 11) {
-                        return ResultUtil.error("订单状态已变更,无法改派: " + order.getId());
-                    }
-
-                    // 创建临时 LineShiftDriver
-                    Integer tempLineShiftDriverId = createTempLineShiftDriver(order, driverId);
-                    reassign.setTempLineShiftDriverId(tempLineShiftDriverId);
-                    this.updateById(reassign);
-
-                    // 执行改派
-                    driverReassignSelf(reassign, order);
+                    orderCrossCityService.updateById(order);
 
                     // 推送乘客和司机通知
                     try {
                         pushUtil.pushOrderReassign(order.getUserId(), 1, order.getId(), 3);
-                        pushUtil.pushOrderReassign(order.getDriverId(), 2, order.getId(), 3);
+                        //司机就是发起确定的人 这里就不需要通知司机了
                     } catch (Exception ignore) {
                     }
                 }
@@ -1601,7 +1881,7 @@
                     pushReassignSuccess(reassignList.get(0));
                 }
 
-                return ResultUtil.success("批量改派成功,共处理 " + reassignList.size() + " 条订单");
+                return reassignResponse("批量改派成功,共处理 " + reassignList.size() + " 条订单", true);
 
             } else {
                 // 拒绝改派
@@ -1615,8 +1895,9 @@
                     );
 
                     if (updateCount == 0) {
-                        return ResultUtil.error("改派申请已被处理: " + reassign.getId());
+                        return reassignResponse("改派申请已被处理: " + reassign.getId(), false);
                     }
+                    restoreCrossCityOrderAfterReassignEnd(reassign);
                 }
 
                 // 通知原司机被拒绝(只通知一次)
@@ -1624,15 +1905,19 @@
                     pushReassignRejected(reassignList.get(0));
                 }
 
-                return ResultUtil.success("已拒绝改派,共 " + reassignList.size() + " 条订单");
+                return reassignResponse("已拒绝改派,共 " + reassignList.size() + " 条订单", true);
             }
 
         } catch (Exception e) {
             e.printStackTrace();
-            return ResultUtil.error("操作失败:" + e.getMessage());
+            return reassignResponse("操作失败:" + e.getMessage(), false);
         }
     }
 
+    private ResultUtil<Boolean> reassignResponse(String message, boolean success) {
+        return ResultUtil.success(message, success);
+    }
+
     @Override
     public List<Map<String, Object>> queryPendingReassigns(Integer driverId) {
         try {
diff --git a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/task/ReassignTimeoutTask.java b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/task/ReassignTimeoutTask.java
index d754caf..b2f9744 100644
--- a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/task/ReassignTimeoutTask.java
+++ b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/task/ReassignTimeoutTask.java
@@ -39,9 +39,8 @@
             );
 
             for (Reassign reassign : timeoutList) {
-                // 设置为超时状态
-                reassign.setConfirmStatus(4);
-                reassignService.updateById(reassign);
+                // 设置超时并恢复订单状态
+                reassignService.timeoutReassign(reassign);
 
                 // 通知原司机超时
                 pushReassignTimeout(reassign);
diff --git a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/PushUtil.java b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/PushUtil.java
index c35cb83..ac0976a 100644
--- a/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/PushUtil.java
+++ b/DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/PushUtil.java
@@ -311,7 +311,9 @@
         params.put("bussinessType", "dache");
         post.form(params);
 
+        System.out.println("改派确认Socket请求: url=" + socket_uri + "/netty/sendMsgToClient, params=" + params);
         HttpResponse execute = post.execute();
+        System.out.println("改派确认Socket响应: status=" + execute.getStatus() + ", body=" + execute.body());
         if (200 != execute.getStatus()) {
             System.err.println("改派确认请求推送异常");
         } else {

--
Gitblit v1.7.1