longz
2026-06-04 da780b14b8db78043d2c0f27d3bfd73111e6d550
DriverYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java
@@ -9,13 +9,8 @@
import com.stylefeng.guns.modular.account.unionpay.GetOpenBodySig;
import com.stylefeng.guns.modular.account.unionpay.QrCodeConfiguration;
import com.stylefeng.guns.modular.account.unionpay.Util;
import com.stylefeng.guns.modular.crossCity.dao.LinePriceMapper;
import com.stylefeng.guns.modular.crossCity.dao.LineShiftDriverMapper;
import com.stylefeng.guns.modular.crossCity.dao.OrderCrossCityMapper;
import com.stylefeng.guns.modular.crossCity.model.Line;
import com.stylefeng.guns.modular.crossCity.model.LineShiftDriver;
import com.stylefeng.guns.modular.crossCity.model.LineSite;
import com.stylefeng.guns.modular.crossCity.model.OrderCrossCity;
import com.stylefeng.guns.modular.crossCity.dao.*;
import com.stylefeng.guns.modular.crossCity.model.*;
import com.stylefeng.guns.modular.crossCity.server.ILineService;
import com.stylefeng.guns.modular.crossCity.server.ILineSiteService;
import com.stylefeng.guns.modular.crossCity.server.IOrderCrossCityService;
@@ -32,6 +27,7 @@
import com.stylefeng.guns.modular.system.warpper.MerchantCouponListWarpper;
import com.stylefeng.guns.modular.taxi.dao.OrderTaxiMapper;
import com.stylefeng.guns.modular.taxi.model.OrderTaxi;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -86,7 +82,10 @@
    private DateUtil dateUtil;
    @Resource
    private LinePriceMapper linePriceMapper;
    private LineMapper lineMapper;
    @Resource
    private DriverSelfTripMapper driverSelfTripMapper;
    @Autowired
    private GDMapGeocodingUtil gdMapGeocodingUtil;
@@ -253,16 +252,28 @@
                serverMoney += income.getMoney();
            }
        }
        Line line = lineService.selectById(orderCrossCity.getLineId());
        map.put("line", line.getName());
        String dispatchPhone = null;
        if (orderCrossCity.getLineId() <= -1) {
            LineShiftDriver lineShiftDriver = lineShiftDriverMapper.selectById(orderCrossCity.getLineShiftDriverId());
            DriverSelfTrip driverSelfTrip = driverSelfTripMapper.selectById(lineShiftDriver.getCustomerId());
            map.put("line", driverSelfTrip.getStartCityName() + "-" + driverSelfTrip.getEndCityName());
            map.put("lineId", orderCrossCity.getLineId());
        } else {
            Line line = lineService.selectById(orderCrossCity.getLineId());
            map.put("line", line == null ? "" : line.getName());
            map.put("lineId", orderCrossCity.getLineId());
            dispatchPhone = line == null ? null : line.getDispatchPhone();
        }
        map.put("peopleNumber", num);
        map.put("orderNumber", orderCrossCity.getOrderNum());
        map.put("totalMoney", new BigDecimal(totalMoney).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
        map.put("serverMoney", new BigDecimal(serverMoney).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
        OpenCity openCity = openCityService.openCity1(orderCrossCity.getStartLon().toString(), orderCrossCity.getStartLat().toString());
        Phone phone = phoneMapper.queryInfo(openCity.getId(), 1, 1);
        map.put("emergencyCall", null != phone ? phone.getPhone() : "110");
        Phone phone = phoneMapper.queryInfo(openCity == null ? 0 : openCity.getId(), 1, 1);
        map.put("emergencyCall", StringUtils.isNotBlank(dispatchPhone) ? dispatchPhone : (null != phone ? phone.getPhone() : "110"));
        if (!order.isEmpty()){
            map.put("lineShiftDriverId", order.get(0).get("lineShiftDriverId"));
        }
        map.put("orders", JSON.toJSONString(order));
        System.out.println("map"+map);
@@ -600,9 +611,16 @@
        endAddress = endAddress.replaceAll("& #41;", ")");
        orderCrossCity.setEndAddress(endAddress);
        orderCrossCity.setMileage(0D);
        ResultUtil<Map<String, Object>> price = this.getPrice(orderCrossCityWarpper.getDistance(), orderCrossCityWarpper.getPeopleNumber(), orderCrossCityWarpper.getTravelMode(), orderCrossCityWarpper.getLineId(),
                orderCrossCityWarpper.getServerCarModelId(), orderCrossCityWarpper.getTotalSeat(), orderCrossCityWarpper.getSeatNumber());
        ResultUtil<Map<String, Object>> price = this.getPriceV2(orderCrossCityWarpper.getLineId(), null,
                orderCrossCityWarpper.getTotalSeat(), orderCrossCityWarpper.getPeopleNumber(), orderCrossCityWarpper.getEndLon(),
                orderCrossCityWarpper.getEndLat(), orderCrossCityWarpper.getLineShiftDriverId());
        if (price.getCode() != 200) {
            return ResultUtil.error("计算价格失败");
        }
        Double money = Double.valueOf(price.getData().get("price").toString());
        if (money < 0) {
            return ResultUtil.error("计算价格失败");
        }
        orderCrossCity.setOrderMoney(money);
        Integer companyId = driver.getCompanyId();
        orderCrossCity.setCompanyId(companyId);
@@ -666,35 +684,70 @@
            lineShiftDriver.setLaveSeatNumber("");
        }else{//拼车
            lineShiftDriver.setLaveSeat(lineShiftDriver.getLaveSeat() - orderCrossCity.getPeopleNumber());
            String[] split = orderCrossCity.getSeatNumber().split(",");
            String[] split1 = lineShiftDriver.getLaveSeatNumber().split(",");
            String seatNumber = "";
            //先判断选中座位号和剩余座位号是否匹配
            for(String spl : split){
                boolean b = true;
                for(String sp : split1){
                    if(ToolUtil.isNotEmpty(spl) && ToolUtil.isNotEmpty(sp) && sp.equals(spl)){
                        b = false;
                        break;
                    }
                }
                if(b){
                    throw new SystemException("您选中的" + spl + "号座位已被占用,请选择其他座位!");
                }
            }
            for(String sp : split1){
                boolean b = true;
            if (StringUtils.isNotEmpty(orderCrossCity.getSeatNumber())){
                // 用户已选座的情况
                String[] split = orderCrossCity.getSeatNumber().split(",");
                String seatNumber = "";
                //先判断选中座位号和剩余座位号是否匹配
                for(String spl : split){
                    if(ToolUtil.isNotEmpty(spl) && ToolUtil.isNotEmpty(sp) && sp.equals(spl)){
                        b = false;
                        break;
                    boolean b = true;
                    for(String sp : split1){
                        if(ToolUtil.isNotEmpty(spl) && ToolUtil.isNotEmpty(sp) && sp.equals(spl)){
                            b = false;
                            break;
                        }
                    }
                    if(b){
                        throw new SystemException("您选中的" + spl + "号座位已被占用,请选择其他座位!");
                    }
                }
                if(b && ToolUtil.isNotEmpty(sp)){
                    seatNumber += (sp + ",");
                for(String sp : split1){
                    boolean b = true;
                    for(String spl : split){
                        if(ToolUtil.isNotEmpty(spl) && ToolUtil.isNotEmpty(sp) && sp.equals(spl)){
                            b = false;
                            break;
                        }
                    }
                    if(b && ToolUtil.isNotEmpty(sp)){
                        seatNumber += (sp + ",");
                    }
                }
                lineShiftDriver.setLaveSeatNumber(ToolUtil.isNotEmpty(seatNumber) ? seatNumber.substring(0, seatNumber.length() - 1) : "");
            } else {
                // 用户未选座的情况,自动分配剩余座位的前peopleNumber个
                StringBuilder assignedSeats = new StringBuilder();
                StringBuilder remainingSeats = new StringBuilder();
                for(int i = 0; i < split1.length; i++){
                    if(ToolUtil.isEmpty(split1[i])){
                        continue;
                    }
                    if(i < orderCrossCity.getPeopleNumber()){
                        // 分配给当前订单的座位
                        if(assignedSeats.length() > 0){
                            assignedSeats.append(",");
                        }
                        assignedSeats.append(split1[i]);
                    } else {
                        // 剩余的座位
                        if(remainingSeats.length() > 0){
                            remainingSeats.append(",");
                        }
                        remainingSeats.append(split1[i]);
                    }
                }
                // 设置订单的座位号
                orderCrossCity.setSeatNumber(assignedSeats.toString());
                this.updateById(orderCrossCity);
                // 更新班次的剩余座位号
                lineShiftDriver.setLaveSeatNumber(remainingSeats.toString());
            }
            lineShiftDriver.setLaveSeatNumber(ToolUtil.isNotEmpty(seatNumber) ? seatNumber.substring(0, seatNumber.length() - 1) : "");
        }
        lineShiftDriverMapper.updateById(lineShiftDriver);
@@ -828,12 +881,24 @@
    @Override
    public ResultUtil queryOrderMoney(String startLonLat, String endLonLat, Integer peopleNumber, Integer travelMode, Integer lineId,
                                      Integer serverCarModelId, Integer totalSeat, String seatNumber) throws Exception {
        // TODO: 2023/11/4 无法修改
        Map<String, String> distance = gdMapElectricFenceUtil.getDistance(startLonLat, endLonLat, 1);//调用高德计算距离
        if(null != distance){
            return this.getPrice(Double.valueOf(distance.get("distance")), peopleNumber, travelMode, lineId, serverCarModelId, totalSeat, seatNumber);
        Double endLon = null;
        Double endLat = null;
        if (ToolUtil.isNotEmpty(endLonLat) && endLonLat.contains(",")) {
            String[] endArr = endLonLat.split(",");
            if (endArr.length == 2) {
                endLon = Double.valueOf(endArr[0]);
                endLat = Double.valueOf(endArr[1]);
            }
        }
        return ResultUtil.error("计算行程距离出错啦!");
        ResultUtil<Map<String, Object>> result = this.getPriceV2(lineId, null, totalSeat, peopleNumber, endLon, endLat, null);
        if (result.getCode() != 200) {
            return result;
        }
        Double price = Double.valueOf(String.valueOf(result.getData().get("price")));
        if (price < 0) {
            return ResultUtil.error("计算行程距离出错啦!");
        }
        return result;
    }
@@ -1095,99 +1160,211 @@
        }
        Map<String, Object> map = new HashMap<>();
        double distance1 = distance.doubleValue() / 1000;//公里
        map.put("distance", distance);
        Integer pricePeopleNumber = travelMode != null && travelMode == 2 && totalSeat != null && totalSeat > 0 ? totalSeat : peopleNumber;
        BigDecimal unitPrice = queryDefaultLineDestinationPrice(lineId, totalSeat);
        map.put("price", unitPrice == null ? -1 : multiplyPeopleNumber(unitPrice, pricePeopleNumber).doubleValue());
        return ResultUtil.success(map);
    }
        /**
         * 1.固定价格的包车是整车价格
         * 2.五座车和七座车的优惠系数是中间特殊位置的优惠折扣
         * 3.包车的情况不享受中间特殊位置的优惠折扣
         * 4.浮动计费拼车如果选中中间特殊位置既享受优惠系数又享受中间特殊位置的优惠折扣
         */
        Map<String, Object> query = linePriceMapper.query(lineId, serverCarModelId);
        if(null == query){
            map.put("distance", 0);
            map.put("price", 0);
    public ResultUtil<Map<String, Object>> getPriceV2(Integer lineId, LineShiftDriver lineShiftDriver, Double endLon, Double endLat, Integer peopleNumber) {
        Map<String, Object> map = new HashMap<>();
        map.put("distance", 0);
        if (lineShiftDriver == null || endLon == null || endLat == null || peopleNumber == null || peopleNumber <= 0) {
            map.put("price", -1);
            return ResultUtil.success(map);
        }
        String content = query.get("content").toString();
        JSONObject jsonObject = JSON.parseObject(content);
        if(Integer.valueOf(query.get("type").toString()) == 1){//固定金额
            double num1 = Double.valueOf(jsonObject.getString("num1")).doubleValue();
            double num2 = Double.valueOf(jsonObject.getString("num2")).doubleValue();
            double num3 = Double.valueOf(jsonObject.getString("num3")).doubleValue();
            double num4 = Double.valueOf(jsonObject.getString("num4")).doubleValue();
            if(travelMode == 1){//拼车
                String[] split = seatNumber.split(",");
                boolean b = false;
                for(String s : split){
                    if((totalSeat == 4 && s.equals("3")) || (totalSeat == 6 && s.equals("5"))){
                        b = true;
                        break;
                    }
                }
                double price1 = 0D;
                if(b){
                    price1 = num1 * (totalSeat == 4 ? num3 : num4);
                    peopleNumber -= 1;
                }
                double price = (num1 * peopleNumber) + price1;
                map.put("price", new BigDecimal(price).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
            }else{
                map.put("price", num2);//包车价
            }
        if (lineId != null && lineId <= -1) {
            BigDecimal price = querySelfTripNearestPrice(lineShiftDriver, endLon, endLat);
            map.put("price", price == null ? -1 : multiplyPeopleNumber(price, peopleNumber).doubleValue());
            return ResultUtil.success(map);
        }
        BigDecimal price = queryLineDestinationPrice(lineId, lineShiftDriver, endLon, endLat);
        map.put("price", price == null ? -1 : multiplyPeopleNumber(price, peopleNumber).doubleValue());
        return ResultUtil.success(map);
    }
        }else{//浮动计费
            //计算公式:实际历程 * 基础单价 * (参考费用 / (参考里程 * 基础单价)) + (实际历程 - 参考里程) * 基础单价 * 优惠系数
            double num1 = Double.valueOf(jsonObject.getString("num1")).doubleValue();//参考价格
            double num2 = Double.valueOf(jsonObject.getString("num2")).doubleValue();//参考里程
            double num3 = Double.valueOf(jsonObject.getString("num3")).doubleValue();//保底价
            double num4 = Double.valueOf(jsonObject.getString("num4")).doubleValue();//超出参考里程优惠系数
            double num5 = Double.valueOf(jsonObject.getString("num5")).doubleValue();//低于参考里程优惠系数
            double num6 = Double.valueOf(jsonObject.getString("num6")).doubleValue();//包车系数
            double num7 = Double.valueOf(jsonObject.getString("num7")).doubleValue();//五座系数
            double num8 = Double.valueOf(jsonObject.getString("num8")).doubleValue();//七座系数
            /**
             * 1、实际里程>=参考里程
             *    参考价+((实际里程-参考里程)*(参考价/参考里程)*超出参考里程优惠系数)
             *
             * 2、实际里程<参考里程
             *    参考价-(参考里程-实际路程)*(参考价/参考里程)*低于参考里程优惠系数
             */
            double unitPrice = 0d;
            if(distance1 > num2){//1
                unitPrice = num1 + ((distance1 - num2) * (num1 / num2) * num4);
    public ResultUtil<Map<String, Object>> getPriceV2(Integer lineId, Integer lineDestinationId, Integer totalSeat,
                                                      Integer peopleNumber, Double endLon, Double endLat, Integer lineShiftDriverId) {
        Map<String, Object> map = new HashMap<>();
        map.put("distance", 0);
        if (peopleNumber == null || peopleNumber <= 0 || endLon == null || endLat == null) {
            map.put("price", -1);
            return ResultUtil.success(map);
        }
        if (lineDestinationId != null) {
            Map<String, Object> destination = lineMapper.queryLineDestinationById(lineDestinationId, lineId);
            BigDecimal unitPrice = null;
            if (destination != null) {
                unitPrice = getDestinationPrice(destination, totalSeat);
            }
            if(distance1 < num2){//2
                unitPrice = num1 - ((num2 - distance1) * (num1 / num2) * num5);
            map.put("price", unitPrice == null ? -1 : multiplyPeopleNumber(unitPrice, peopleNumber).doubleValue());
            return ResultUtil.success(map);
        }
        if (lineId != null && lineId <= -1) {
            if (lineShiftDriverId == null) {
                map.put("price", -1);
                return ResultUtil.success(map);
            }
            if(distance1 == num2){
                unitPrice = num1;
            LineShiftDriver lineShiftDriver = lineShiftDriverMapper.selectById(lineShiftDriverId);
            if (lineShiftDriver == null) {
                map.put("price", -1);
                return ResultUtil.success(map);
            }
            if(travelMode == 1){//拼车
                String[] split = seatNumber.split(",");
                boolean b = false;
                for(String s : split){
                    if((totalSeat == 4 && s.equals("3")) || (totalSeat == 6 && s.equals("5"))){
                        b = true;
                        break;
                    }
                }
                double price1 = 0D;
                if(b){
                    price1 = unitPrice * (totalSeat == 4 ? num7 : num8);
                    peopleNumber -= 1;
                }
                double price = (unitPrice * peopleNumber) + price1;
                map.put("price", new BigDecimal(num3 > price ? num3 : price).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
            }else{
                double price = unitPrice * totalSeat * num6;
                map.put("price", new BigDecimal(num3 > price ? num3 : price).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
            return getPriceV2(lineId, lineShiftDriver, endLon, endLat, peopleNumber);
        }
        List<Map<String, Object>> destinations = lineMapper.queryLineDestinations(lineId);
        if (destinations == null || destinations.size() == 0) {
            map.put("price", -1);
            return ResultUtil.success(map);
        }
        BigDecimal defaultPrice = getDestinationPrice(destinations.get(0), totalSeat);
        BigDecimal matchedPrice = null;
        for (Map<String, Object> destination : destinations) {
            if (isPointInDestinationFence(destination, endLon, endLat)) {
                matchedPrice = getDestinationPrice(destination, totalSeat);
                break;
            }
        }
        BigDecimal finalPrice = matchedPrice == null ? defaultPrice : matchedPrice;
        map.put("price", finalPrice == null ? -1 : multiplyPeopleNumber(finalPrice, peopleNumber).doubleValue());
        return ResultUtil.success(map);
    }
    private BigDecimal querySelfTripNearestPrice(LineShiftDriver lineShiftDriver, Double endLon, Double endLat) {
        Integer customerId = lineShiftDriverMapper.queryCustomerIdByLineShiftDriverId(lineShiftDriver.getId());
        if (customerId == null) {
            return null;
        }
        DriverSelfTrip selfTrip = driverSelfTripMapper.selectById(customerId);
        if (selfTrip == null || ToolUtil.isEmpty(selfTrip.getDestJson())) {
            return null;
        }
        JSONArray destArray = JSON.parseArray(selfTrip.getDestJson());
        if (destArray == null || destArray.size() == 0) {
            return null;
        }
        BigDecimal bestPrice = null;
        Double minDistance = null;
        String target = endLon + "," + endLat;
        for (int i = 0; i < destArray.size(); i++) {
            JSONObject dest = destArray.getJSONObject(i);
            if (dest == null || dest.getDouble("endLon") == null || dest.getDouble("endLat") == null || dest.getBigDecimal("price") == null) {
                continue;
            }
            String source = dest.getDouble("endLon") + "," + dest.getDouble("endLat");
            Map<String, Double> distanceMap = geodesyUtil.getDistance(source, target);
            Double currentDistance = distanceMap == null ? null : distanceMap.get("WGS84");
            if (currentDistance == null) {
                continue;
            }
            if (minDistance == null || currentDistance < minDistance) {
                minDistance = currentDistance;
                bestPrice = dest.getBigDecimal("price");
            }
        }
        return bestPrice;
    }
    private BigDecimal queryLineDestinationPrice(Integer lineId, LineShiftDriver lineShiftDriver, Double endLon, Double endLat) {
        List<Map<String, Object>> destinations = lineMapper.queryLineDestinations(lineId);
        if (destinations == null || destinations.size() == 0) {
            return null;
        }
        BigDecimal defaultPrice = getDestinationPrice(destinations.get(0), lineShiftDriver.getTotalSeat());
        for (Map<String, Object> destination : destinations) {
            if (isPointInDestinationFence(destination, endLon, endLat)) {
                BigDecimal price = getDestinationPrice(destination, lineShiftDriver.getTotalSeat());
                return price == null ? defaultPrice : price;
            }
        }
        return defaultPrice;
    }
    private boolean isPointInDestinationFence(Map<String, Object> destination, Double lon, Double lat) {
        if (destination == null || lon == null || lat == null) {
            return false;
        }
        Integer fenceType = destination.get("fenceType") == null ? null : Integer.valueOf(String.valueOf(destination.get("fenceType")));
        String coordinate = destination.get("coordinate") == null ? null : String.valueOf(destination.get("coordinate"));
        if (fenceType == null || ToolUtil.isEmpty(coordinate)) {
            return false;
        }
        if (fenceType == 1) {
            String[] arr = coordinate.split(";");
            if (arr.length != 2) {
                return false;
            }
            String[] center = arr[0].split(",");
            if (center.length != 2) {
                return false;
            }
            Map<String, Double> distanceMap = geodesyUtil.getDistance(center[0] + "," + center[1], lon + "," + lat);
            Double currentDistance = distanceMap == null ? null : distanceMap.get("WGS84");
            return currentDistance != null && currentDistance <= Double.valueOf(arr[1]);
        }
        return isPointInPolygon(coordinate, lon, lat);
    }
    private boolean isPointInPolygon(String coordinate, Double lon, Double lat) {
        String[] points = coordinate.split(";");
        if (points.length < 3) {
            return false;
        }
        boolean inside = false;
        for (int i = 0, j = points.length - 1; i < points.length; j = i++) {
            String[] current = points[i].split(",");
            String[] previous = points[j].split(",");
            if (current.length != 2 || previous.length != 2) {
                continue;
            }
            double xi = Double.parseDouble(current[0]);
            double yi = Double.parseDouble(current[1]);
            double xj = Double.parseDouble(previous[0]);
            double yj = Double.parseDouble(previous[1]);
            boolean intersect = ((yi > lat) != (yj > lat))
                    && (lon < (xj - xi) * (lat - yi) / ((yj - yi) == 0 ? 0.0000001D : (yj - yi)) + xi);
            if (intersect) {
                inside = !inside;
            }
        }
        return inside;
    }
    private BigDecimal getBigDecimal(Object value) {
        if (value == null || ToolUtil.isEmpty(String.valueOf(value))) {
            return null;
        }
        try {
            return new BigDecimal(String.valueOf(value));
        } catch (Exception e) {
            return null;
        }
    }
    private BigDecimal queryDefaultLineDestinationPrice(Integer lineId, Integer totalSeat) {
        List<Map<String, Object>> destinations = lineMapper.queryLineDestinations(lineId);
        if (destinations == null || destinations.size() == 0) {
            return null;
        }
        return getDestinationPrice(destinations.get(0), totalSeat);
    }
    private BigDecimal getDestinationPrice(Map<String, Object> destination, Integer totalSeat) {
        if (destination == null) {
            return null;
        }
        BigDecimal price = totalSeat != null && totalSeat == 6
                ? getBigDecimal(destination.get("price7"))
                : getBigDecimal(destination.get("price5"));
        return price == null ? getBigDecimal(destination.get("price5")) : price;
    }
    private BigDecimal multiplyPeopleNumber(BigDecimal price, Integer peopleNumber) {
        if (price == null || peopleNumber == null || peopleNumber <= 0) {
            return null;
        }
        return price.multiply(new BigDecimal(peopleNumber)).setScale(2, BigDecimal.ROUND_HALF_UP);
    }
    @Override
@@ -1201,7 +1378,7 @@
     * @throws Exception
     */
    public synchronized String getOrderNum(Integer driverId, Integer lineShiftDriverId) throws Exception{
        List<OrderCrossCity> orderCrossCities = orderCrossCityMapper.queryOrders(driverId, lineShiftDriverId, Arrays.asList(2, 3, 4, 7));
        List<OrderCrossCity> orderCrossCities = orderCrossCityMapper.queryOrders(driverId, lineShiftDriverId, Arrays.asList(2, 3, 4, 5, 6, 7));
        if(orderCrossCities.size() > 0){
            return orderCrossCities.get(0).getOrderNum();
        }
@@ -1283,6 +1460,9 @@
        if (warpper.getOtherFee() != null && warpper.getOtherFee().compareTo(BigDecimal.ZERO) < 0) {
            return ResultUtil.error("其他费用不能为负数");
        }
        if (warpper.getChangePrice() != null && warpper.getChangePrice().compareTo(BigDecimal.ZERO) < 0) {
            return ResultUtil.error("改价费用不能为负数");
        }
        // 2. 校验班次信息
        LineShiftDriver lineShiftDriver = lineShiftDriverMapper.selectById(warpper.getLineShiftDriverId());
@@ -1327,14 +1507,27 @@
        }
        // 6. 获取线路班次信息
        LineSite lineSite = lineSiteService.selectById(lineShiftDriver.getLineShiftId());
        if (lineSite == null) {
            return ResultUtil.error("线路班次信息不存在");
        LineSite lineSite;
        if (lineShiftDriver.getLineShiftId() <= -1) {
            lineSite = new LineSite();
            lineSite.setLineId(-1);
            if (lineShiftDriver.getCustomerId() != null) {
                DriverSelfTrip selfTrip = driverSelfTripMapper.selectById(lineShiftDriver.getCustomerId());
                if (selfTrip != null) {
                    lineSite.setStartTime(selfTrip.getStartTime());
                }
            }
        } else {
            lineSite = lineSiteService.selectById(lineShiftDriver.getLineShiftId());
            if (lineSite == null) {
                return ResultUtil.error("线路班次信息不存在");
            }
            Line line = lineService.selectById(lineSite.getLineId());
            if (line == null) {
                return ResultUtil.error("线路信息不存在");
            }
        }
        Line line = lineService.selectById(lineSite.getLineId());
        if (line == null) {
            return ResultUtil.error("线路信息不存在");
        }
        // 7. 处理用户信息
        String phone = warpper.getPassengersPhone();
@@ -1369,20 +1562,20 @@
            return ResultUtil.error("该乘客有未完成的订单");
        }
        // 9. 检查司机是否正在服务中
        List<OrderCrossCity> orderCrossCities2 = orderCrossCityMapper.queryOrders(driverId, warpper.getLineShiftDriverId(), Arrays.asList(5));
        if (orderCrossCities2.size() > 0) {
            return ResultUtil.error("司机正在服务中");
        }
//        // 9. 检查司机是否正在服务中
//        List<OrderCrossCity> orderCrossCities2 = orderCrossCityMapper.queryOrders(driverId, warpper.getLineShiftDriverId(), Arrays.asList(5));
//        if (orderCrossCities2.size() > 0) {
//            return ResultUtil.error("司机正在服务中");
//        }
        // 10. 计算价格
        Map<String, String> distanceMap = gdMapElectricFenceUtil.getDistance(
                warpper.getStartLon() + "," + warpper.getStartLat(),
                warpper.getEndLon() + "," + warpper.getEndLat(), 1);
        if (distanceMap == null) {
            return ResultUtil.error("计算行程距离出错");
        }
        Double distance = Double.valueOf(distanceMap.get("distance"));
//        // 10. 计算价格
//        Map<String, String> distanceMap = gdMapElectricFenceUtil.getDistance(
//                warpper.getStartLon() + "," + warpper.getStartLat(),
//                warpper.getEndLon() + "," + warpper.getEndLat(), 1);
//        if (distanceMap == null) {
//            return ResultUtil.error("计算行程距离出错");
//        }
//        Double distance = Double.valueOf(distanceMap.get("distance"));
        // 获取车辆信息
        Car car = carServiceImpl.selectById(driver.getCarId());
@@ -1397,12 +1590,15 @@
        if(null == carService){
            return ResultUtil.error("车辆未开通该服务");
        }
        ResultUtil<Map<String, Object>> priceResult = this.getPrice(distance, warpper.getPeopleNumber(), 1,
                lineSite.getLineId(), carService.getServerCarModelId(), lineShiftDriver.getTotalSeat(), seatNumber);
        ResultUtil<Map<String, Object>> priceResult = this.getPriceV2(lineSite.getLineId(), lineShiftDriver,
                warpper.getEndLon(), warpper.getEndLat(), warpper.getPeopleNumber());
        if (priceResult.getCode() != 200) {
            return ResultUtil.error("计算价格失败");
        }
        Double ticketPrice = Double.valueOf(priceResult.getData().get("price").toString());
        if (ticketPrice < 0) {
            return ResultUtil.error("计算价格失败");
        }
        // 计算合计费用
        Double otherFee = warpper.getOtherFee() != null ? warpper.getOtherFee().setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue() : 0D;
@@ -1444,7 +1640,12 @@
        orderCrossCity.setEndAddress(endAddress);
        orderCrossCity.setMileage(0D);
        orderCrossCity.setOrderMoney(totalMoney);
        if (warpper.getChangePrice() != null) {
            orderCrossCity.setOrderMoney(warpper.getChangePrice().doubleValue());
            orderCrossCity.setHasChangePrice(1);
        } else {
            orderCrossCity.setOrderMoney(totalMoney);
        }
        orderCrossCity.setCompanyId(driver.getCompanyId());
        orderCrossCity.setPeopleNumber(warpper.getPeopleNumber());
        orderCrossCity.setSeatNumber(seatNumber);
@@ -1541,4 +1742,61 @@
        baseWarpper.setId(orderCrossCity.getId());
        return ResultUtil.success(baseWarpper);
    }
    @Override
    public ResultUtil orderOnBehalfPay(int crossCityOrderId, int type, Integer driverId) throws Exception {
        OrderCrossCity order = orderCrossCityMapper.selectById(crossCityOrderId);
        if (order == null) {
            return ResultUtil.error("订单不存在");
        }
        if (!order.getDriverId().equals(driverId)) {
            return ResultUtil.error("您没有权限支付此订单");
        }
        if (order.getState() != 7) {
            return ResultUtil.error("订单不在待支付,无法完成订单");
        }
        if (type == 1) {
//            UserInfo userInfo = userInfoMapper.selectById(order.getUserId());
            Driver driver = driverService.selectById(driverId);
            if (driver == null) {
                return ResultUtil.error("司机不存在");
            }
            if (ToolUtil.isEmpty(driver.getAppletsOpenId())) {
                return ResultUtil.errorOpenId("司机未绑定微信小程序openid,无法发起微信支付");
            }
            String outTradeNo = buildCbyzxOnBehalfOutTradeNo(crossCityOrderId);
            JSONObject response = cbyzxOrderPayHelper.createOrder(
                    order.getUserId(),
                    driver.getAppletsOpenId(),
                    outTradeNo,
                    order.getOrderMoney()
            );
            if (!cbyzxOrderPayHelper.isCreateSuccess(response)) {
                return ResultUtil.error(cbyzxOrderPayHelper.extractMessage(response), response);
            }
            paymentRecordService.saveData(1, order.getDriverId(), 2, crossCityOrderId, 3, 1, order.getOrderMoney(), outTradeNo, 1);
            return ResultUtil.success(response);
        } else if (type == 3) {
            order.setState(2);
            order.setPayMoney(order.getOrderMoney());
            orderCrossCityMapper.updateById(order);
            //添加交易明细
            transactionDetailsService.saveData(driverId, "跨城出行订单", order.getOrderMoney(), 2, 1, 2, 3, order.getId());
            return ResultUtil.success();
        } else if (type == 2) {
            String path = "pages/home/home";
            String unlimitQrcode = weChatUtil.getUnlimitQrcode(path, "default");
            return ResultUtil.success(unlimitQrcode);
        }
        return ResultUtil.error("支付失败");
    }
    /**
     * 创博优代客支付单号,增加业务前缀便于统一回调路由。
     */
    private String buildCbyzxOnBehalfOutTradeNo(Integer orderId) throws Exception {
        return "onBehalf_" + orderId + "_3_" + UUIDUtil.getRandomCode(5);
    }
}