From 86652ef17483e89194212793c098193134af2044 Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期五, 26 六月 2026 18:18:34 +0800
Subject: [PATCH] 跨城改派fix

---
 DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/ReassignServiceImpl.java |  216 +++++++++++++++++++++++++++++--------------
 DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/PushUtil.java                    |   58 +++++++++++
 2 files changed, 203 insertions(+), 71 deletions(-)

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 25f3f08..90be6dc 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
@@ -12,6 +12,7 @@
 import com.stylefeng.guns.modular.crossCity.dao.LineShiftDriverMapper;
 import com.stylefeng.guns.modular.crossCity.dao.LineShiftMapper;
 import com.stylefeng.guns.modular.crossCity.dao.LineSiteMapper;
+import com.stylefeng.guns.modular.crossCity.model.Line;
 import com.stylefeng.guns.modular.crossCity.model.LineShift;
 import com.stylefeng.guns.modular.crossCity.model.LineShiftDriver;
 import com.stylefeng.guns.modular.crossCity.model.OrderCrossCity;
@@ -468,7 +469,15 @@
 //            return ResultUtil.error("有未完成支付的改派申请");
 //        }
         String[] split = orderIds.split(",");//获取支付金额
-        Double aDouble = orderService.queryReassignMoney(Integer.valueOf(split[0]), 3);
+
+        // 跨城改派:如果指定了司机,不收改派费用
+        Double aDouble;
+        if (reassign.getNowDriverId() != null && reassign.getNowDriverId() > 0) {
+            aDouble = 0.0; // 指定司机,免费
+        } else {
+            aDouble = orderService.queryReassignMoney(Integer.valueOf(split[0]), 3);
+        }
+
         Double totalMoney = aDouble * split.length;
         String ids = "";
         for (String id : split) {
@@ -568,9 +577,28 @@
 
 
                 //修改改派通知状态
+                boolean needConfirmPush = false; // 标记是否需要发送确认推送
+                OrderCrossCity firstOrder = null; // 保存第一个订单用于发送推送
+                int totalPeopleNumber = 0; // 累计总人数
+                List<String> orderIdList = new ArrayList<>(); // 收集所有订单ID
+                List<String> reassignIdList = new ArrayList<>(); // 收集所有改派记录ID
+
                 for (String id : split) {
                     OrderCrossCity orderCrossCity = orderCrossCityService.selectById(id);
                     orderCrossCity.setOldState(orderCrossCity.getState());
+
+                    // 查询改派记录
+                    Reassign reassignRecord = reassignMapper.query(uid, null, Integer.valueOf(id), 3, 1);
+                    if (reassignRecord != null) {
+                        reassignIdList.add(String.valueOf(reassignRecord.getId()));
+                    }
+
+                    // 累加人数
+                    if (orderCrossCity.getPeopleNumber() != null) {
+                        totalPeopleNumber += orderCrossCity.getPeopleNumber();
+                    }
+                    orderIdList.add(id);
+
                     if(reassign.getNowDriverId()==null){
                         orderCrossCity.setState(11);
                     }else {
@@ -578,12 +606,25 @@
                         boolean needConfirm = checkIfNeedConfirm(reassign.getNowDriverId(), orderCrossCity);
 
                         if (needConfirm) {
-                            // 需要确认:发送 Socket 推送
+                            // 需要确认:标记需要发送推送,但不立即发送
                             orderCrossCity.setState(11); // 改派中状态
-                            sendReassignConfirmPush(reassign.getNowDriverId(), reassign, orderCrossCity);
+                            needConfirmPush = true;
+                            if (firstOrder == null) {
+                                firstOrder = orderCrossCity; // 保存第一个订单
+                            }
                         } else {
                             // 不需要确认:直接改派
                             driverReassignSelf(reassign, orderCrossCity);
+
+                            // 只有无需确认时才推送乘客和司机信息
+                            try {
+                                // 推送用户消息
+                                pushUtil.pushOrderReassign(orderCrossCity.getUserId(), 1, orderCrossCity.getId(), 3);
+                                // 推送司机消息
+                                pushUtil.pushOrderReassign(orderCrossCity.getDriverId(), 2, orderCrossCity.getId(), 3);
+                            } catch (Exception ignore) {
+
+                            }
                         }
                     }
 
@@ -592,19 +633,11 @@
                     orderCrossCityService.updateById(orderCrossCity);
                     //添加已收入明细
                     incomeService.saveData(1, orderCrossCity.getCompanyId(), 4, orderCrossCity.getId(), 3, reassign.getMoney());
+                }
 
-
-                    if(reassign.getNowDriverId()!=null){
-                        try {
-                            // 推送用户消息
-                            pushUtil.pushOrderReassign(orderCrossCity.getUserId(), 1, orderCrossCity.getId(), 3);
-                            // 推送司机消息
-                            pushUtil.pushOrderReassign(orderCrossCity.getDriverId(), 2, orderCrossCity.getId(), 3);
-                        } catch (Exception ignore) {
-
-                        }
-
-                    }
+                // 所有订单处理完后,只发送一次确认推送
+                if (needConfirmPush && firstOrder != null) {
+                    sendReassignConfirmPush(reassign.getNowDriverId(), reassign, firstOrder, totalPeopleNumber, orderIdList, reassignIdList);
                 }
                 systemNoticeService.addSystemNotice(2, "您已使用余额成功支付改派申请费用!", uid, 1);
 
@@ -1323,23 +1356,35 @@
     }
 
     /**
-     * 发送改派确认推送给目标司机
+     * 发送改派确认推送给目标司机(使用Socket推送,不用极光推送)
+     * @param driverId 目标司机ID
+     * @param reassign 改派记录
+     * @param order 订单信息
+     * @param totalPeopleNumber 总人数(已在调用处计算好)
+     * @param orderIdList 订单ID列表
+     * @param reassignIdList 改派记录ID列表
      */
-    private void sendReassignConfirmPush(Integer driverId, Reassign reassign, OrderCrossCity order) {
+    private void sendReassignConfirmPush(Integer driverId, Reassign reassign, OrderCrossCity order, int totalPeopleNumber, List<String> orderIdList, List<String> reassignIdList) {
         try {
-            Map<String, String> data = new HashMap<>();
-            data.put("type", "REASSIGN_CONFIRM_REQUEST");
-            data.put("reassignId", String.valueOf(reassign.getId()));
-            data.put("orderId", String.valueOf(order.getId()));
-            data.put("startAddress", order.getStartAddress());
-            data.put("endAddress", order.getEndAddress());
-            data.put("peopleNumber", String.valueOf(order.getPeopleNumber()));
-            data.put("travelTime", order.getTravelTime() != null ? order.getTravelTime().toString() : "");
-            data.put("expireTime", reassign.getExpireTime() != null ? reassign.getExpireTime().toString() : "");
-            data.put("money", order.getOrderMoney() != null ? order.getOrderMoney().toString() : "");
+            // 使用订单的起点和终点地址(订单的startAddress和endAddress就是跨城站点地址)
+            String startSite = order.getStartAddress() != null ? order.getStartAddress() : "";
+            String endSite = order.getEndAddress() != null ? order.getEndAddress() : "";
 
-            // 使用 JGPushUtil 推送
-            jgPushUtil.push(2, "有新的改派订单需要您确认", "改派确认请求", data, "DRIVER" + driverId);
+            // 转换时间为字符串
+            String travelTime = order.getTravelTime() != null ? order.getTravelTime().toString() : "";
+            String expireTime = reassign.getExpireTime() != null ? reassign.getExpireTime().toString() : "";
+
+            // 使用 Socket 推送(不用极光推送)
+            pushUtil.pushReassignConfirmRequest(
+                driverId,
+                String.join(",", reassignIdList), // 改派记录ID列表(逗号分隔)
+                String.join(",", orderIdList),     // 订单ID列表(逗号分隔)
+                startSite,
+                endSite,
+                totalPeopleNumber,
+                travelTime,
+                expireTime
+            );
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -1449,110 +1494,139 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public ResultUtil respondReassign(Integer reassignId, Integer driverId, Integer responseType) {
+        // 兼容旧接口:单个改派记录
+        return respondReassignBatch(String.valueOf(reassignId), driverId, responseType);
+    }
+
+    /**
+     * 批量响应改派请求(同意或拒绝)
+     * @param reassignIds 改派记录ID列表(逗号分隔)
+     * @param driverId 司机ID
+     * @param responseType 响应类型(1=同意,2=拒绝)
+     * @return 处理结果
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public ResultUtil respondReassignBatch(String reassignIds, Integer driverId, Integer responseType) {
         try {
-            // 使用悲观锁查询,防止并发
-            Reassign reassign = this.baseMapper.selectById(reassignId);
-            if (reassign == null) {
-                return ResultUtil.error("改派申请不存在");
+            if (reassignIds == null || reassignIds.trim().isEmpty()) {
+                return ResultUtil.error("改派申请ID不能为空");
             }
 
-            // 加锁:使用数据库行锁(SELECT FOR UPDATE)
-            synchronized (("REASSIGN_" + reassignId).intern()) {
-                // 重新查询最新状态
-                reassign = this.selectById(reassignId);
+            String[] idArray = reassignIds.split(",");
+            List<Reassign> reassignList = new ArrayList<>();
+
+            // 第一步:验证所有改派记录
+            for (String idStr : idArray) {
+                Integer reassignId = Integer.valueOf(idStr.trim());
+                Reassign reassign = this.baseMapper.selectById(reassignId);
+
                 if (reassign == null) {
-                    return ResultUtil.error("改派申请不存在");
+                    return ResultUtil.error("改派申请不存在: " + reassignId);
                 }
 
-                // 验证权限:检查nowDriverId是否匹配(注意nowDriverId可能为null)
+                // 验证权限:检查nowDriverId是否匹配
                 if (reassign.getNowDriverId() == null || !reassign.getNowDriverId().equals(driverId)) {
-                    return ResultUtil.error("无权操作");
+                    return ResultUtil.error("无权操作改派申请: " + reassignId);
                 }
 
                 // 幂等性检查:只有待确认状态才能响应
                 if (reassign.getConfirmStatus() != 1) {
-                    // 已经被处理过了
                     if (reassign.getConfirmStatus() == 2) {
-                        return ResultUtil.error("该改派申请已被接受");
+                        return ResultUtil.error("改派申请已被接受: " + reassignId);
                     } else if (reassign.getConfirmStatus() == 3) {
-                        return ResultUtil.error("该改派申请已被拒绝");
+                        return ResultUtil.error("改派申请已被拒绝: " + reassignId);
                     } else if (reassign.getConfirmStatus() == 4) {
-                        return ResultUtil.error("该改派申请已超时");
+                        return ResultUtil.error("改派申请已超时: " + reassignId);
                     } else {
-                        return ResultUtil.error("该改派申请已处理");
+                        return ResultUtil.error("改派申请已处理: " + reassignId);
                     }
                 }
 
                 // 验证是否超时
                 if (new Date().after(reassign.getExpireTime())) {
-                    // 设置为超时状态
                     reassign.setConfirmStatus(4);
                     this.updateById(reassign);
-                    return ResultUtil.error("该改派申请已超时");
+                    return ResultUtil.error("改派申请已超时: " + reassignId);
                 }
 
-                if (responseType == 1) {
-                    // 同意改派
-                    // 先更新状态,防止重复处理
+                reassignList.add(reassign);
+            }
+
+            // 第二步:批量处理所有改派记录
+            if (responseType == 1) {
+                // 同意改派
+                for (Reassign reassign : reassignList) {
+                    // 使用乐观锁更新状态
                     reassign.setConfirmStatus(2);
                     reassign.setConfirmTime(new Date());
                     int updateCount = this.baseMapper.update(reassign,
                         new EntityWrapper<Reassign>()
-                            .eq("id", reassignId)
+                            .eq("id", reassign.getId())
                             .eq("confirmStatus", 1) // 只有待确认状态才能更新
                     );
 
-                    // 检查更新是否成功(乐观锁)
                     if (updateCount == 0) {
-                        return ResultUtil.error("该改派申请已被其他司机接受或已过期");
+                        return ResultUtil.error("改派申请已被处理: " + reassign.getId());
                     }
 
                     // 获取订单信息
                     OrderCrossCity order = orderCrossCityService.selectById(reassign.getOrderId());
                     if (order == null) {
-                        return ResultUtil.error("订单不存在");
+                        return ResultUtil.error("订单不存在: " + reassign.getOrderId());
                     }
 
-                    // 再次检查订单状态,确保订单还在改派中
+                    // 检查订单状态
                     if (order.getState() != 11) {
-                        return ResultUtil.error("订单状态已变更,无法改派");
+                        return ResultUtil.error("订单状态已变更,无法改派: " + order.getId());
                     }
 
                     // 创建临时 LineShiftDriver
                     Integer tempLineShiftDriverId = createTempLineShiftDriver(order, driverId);
                     reassign.setTempLineShiftDriverId(tempLineShiftDriverId);
-                    reassign.setNowDriverId(tempLineShiftDriverId); // 更新为新的 lineShiftDriverId
                     this.updateById(reassign);
 
                     // 执行改派
                     driverReassignSelf(reassign, order);
 
-                    // 通知原司机改派成功
-                    pushReassignSuccess(reassign);
+                    // 推送乘客和司机通知
+                    try {
+                        pushUtil.pushOrderReassign(order.getUserId(), 1, order.getId(), 3);
+                        pushUtil.pushOrderReassign(order.getDriverId(), 2, order.getId(), 3);
+                    } catch (Exception ignore) {
+                    }
+                }
 
-                    return ResultUtil.success("改派成功");
+                // 通知原司机改派成功(只通知一次)
+                if (!reassignList.isEmpty()) {
+                    pushReassignSuccess(reassignList.get(0));
+                }
 
-                } else {
-                    // 拒绝改派
-                    // 使用乐观锁更新
+                return ResultUtil.success("批量改派成功,共处理 " + reassignList.size() + " 条订单");
+
+            } else {
+                // 拒绝改派
+                for (Reassign reassign : reassignList) {
                     reassign.setConfirmStatus(3);
                     reassign.setConfirmTime(new Date());
                     int updateCount = this.baseMapper.update(reassign,
                         new EntityWrapper<Reassign>()
-                            .eq("id", reassignId)
-                            .eq("confirmStatus", 1) // 只有待确认状态才能更新
+                            .eq("id", reassign.getId())
+                            .eq("confirmStatus", 1)
                     );
 
                     if (updateCount == 0) {
-                        return ResultUtil.error("该改派申请已被处理");
+                        return ResultUtil.error("改派申请已被处理: " + reassign.getId());
                     }
-
-                    // 通知原司机被拒绝
-                    pushReassignRejected(reassign);
-
-                    return ResultUtil.success("已拒绝改派");
                 }
+
+                // 通知原司机被拒绝(只通知一次)
+                if (!reassignList.isEmpty()) {
+                    pushReassignRejected(reassignList.get(0));
+                }
+
+                return ResultUtil.success("已拒绝改派,共 " + reassignList.size() + " 条订单");
             }
+
         } catch (Exception e) {
             e.printStackTrace();
             return ResultUtil.error("操作失败:" + e.getMessage());
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 19e7c69..7a63aa2 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
@@ -266,6 +266,64 @@
         }
     }
 
+    /**
+     * 推送改派确认请求给目标司机(Socket推送)
+     * @param driverId 目标司机ID
+     * @param reassignIds 改派记录ID列表(逗号分隔)
+     * @param orderIds 订单ID列表(逗号分隔)
+     * @param startSite 线路起点站点
+     * @param endSite 线路终点站点
+     * @param totalPeopleNumber 总人数
+     * @param travelTime 出行时间
+     * @param expireTime 超时时间
+     */
+    public void pushReassignConfirmRequest(Integer driverId, String reassignIds, String orderIds,
+                                           String startSite, String endSite, Integer totalPeopleNumber,
+                                           String travelTime, String expireTime) {
+        System.out.println("推送改派确认请求给司机: driverId=" + driverId + ", reassignIds=" + reassignIds);
+
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("code", 200);
+        jsonObject.put("msg", "SUCCESS");
+        jsonObject.put("method", "REASSIGN_CONFIRM_REQUEST");
+
+        Map<String, Object> map = new HashMap<>();
+        map.put("reassignIds", reassignIds); // 改派记录ID列表(逗号分隔)
+        map.put("orderIds", orderIds);
+        map.put("startSite", startSite);
+        map.put("endSite", endSite);
+        map.put("routeInfo", startSite + " → " + endSite);
+        map.put("totalPeopleNumber", totalPeopleNumber);
+        map.put("travelTime", travelTime);
+        map.put("expireTime", expireTime);
+
+        jsonObject.put("data", map);
+
+        // 调用推送
+        HttpRequest post = HttpUtil.createPost(socket_uri + "/netty/sendMsgToClient");
+        post.header("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE);
+
+        // 将请求头部和参数合成一个请求
+        Map<String, Object> params = new HashMap<>();
+        params.put("msg", jsonObject.toJSONString());
+        params.put("id", driverId);
+        params.put("type", 2); // type=2 表示司机端
+        params.put("bussinessType", "dache");
+        post.form(params);
+
+        HttpResponse execute = post.execute();
+        if (200 != execute.getStatus()) {
+            System.err.println("改派确认请求推送异常");
+        } else {
+            JSONObject jsonObject1 = JSON.parseObject(execute.body(), JSONObject.class);
+            if (jsonObject1.getIntValue("code") != 200) {
+                System.err.println("改派确认请求推送失败: " + jsonObject1.getString("msg"));
+            } else {
+                System.out.println("改派确认请求推送成功: driverId=" + driverId);
+            }
+        }
+    }
+
 
     /**
      * 推送司机位置给乘客端

--
Gitblit v1.7.1