longz
2026-06-30 80fd77e1bcb47726e440b8a728838189cd39a56a
跨城改派fix
12个文件已修改
607 ■■■■■ 已修改文件
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/controller/OrderCrossCityController.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/LineShiftDriverMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/OrderCrossCityMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/LineShiftDriverMapper.xml 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/dao/mapping/OrderCrossCityMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/LineShiftDriverServiceImpl.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/ReassignMapper.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IReassignService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/ReassignServiceImpl.java 425 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/task/ReassignTimeoutTask.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/PushUtil.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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) {
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);
    /**
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);
    /**
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
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>
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 {
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;
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">
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;
}
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());
                            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){
                            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 {
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);
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 {