yyy
2026-04-29 66e7a83f20944f1285bd869110e123564c7f9867
Merge remote-tracking branch 'origin/1.0' into 1.0
5个文件已添加
34个文件已修改
554 ■■■■■ 已修改文件
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserCouponController.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpAppUserCouponService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpAppUserCouponServiceImpl.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/account/XpAppUserCouponClientFallbackFactory.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/order/XpOrderClientFallbackFactory.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/account/XpAppUserCouponClient.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/order/XpOrderClient.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/map/XpTestGeoFencingProhibitedPolygon.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/CalculateDiscountAmountVo.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/order/FareBreakdownVo.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/constant/I18nKeyConstant.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages.properties 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages_en_US.properties 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages_zh_CN.properties 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/constant/I18nKeyConstant.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/XpTaskService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpCruiseCheckInRuleServiceImpl.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/TaskReassignmentVo.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/XpCruiseCheckInRuleInfoVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/resources/i18n/messages.properties 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/resources/i18n/messages_en_US.properties 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/resources/i18n/messages_zh_CN.properties 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpTestElectronicFenceManagementController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpTestElectronicFenceServiceImpl.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/constant/I18nKeyConstant.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/TimeJobType.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/TestOrderCancelJob.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpTestOrderServiceImpl.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/vo/FareBreakdownVo.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/resources/i18n/messages.properties 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/resources/i18n/messages_en_US.properties 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/resources/i18n/messages_zh_CN.properties 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpAppUserCouponController.java
@@ -25,6 +25,7 @@
import com.xiaopeng.api.model.account.XpAppUserCoupon;
import com.xiaopeng.api.model.operation.XpCoupon;
import com.xiaopeng.api.query.account.XpAppUserCouponPageListQuery;
import com.xiaopeng.api.vo.account.CalculateDiscountAmountVo;
import com.xiaopeng.api.vo.account.NavigationCouponPickerVo;
import com.xiaopeng.api.vo.account.UserCouponVo;
import com.xiaopeng.common.core.domain.R;
@@ -154,6 +155,8 @@
        }
    }
    @PostMapping("/logan/inner/appUserCoupon/useUserCoupon")
    public R<BigDecimal> useUserCoupon(@RequestBody UseUserCouponDto dto) {
        XpAppUserCoupon appUserCoupon = xpAppUserCouponService.getById(dto.getUserCouponId());
@@ -380,7 +383,7 @@
    @GetMapping("/api/v1/activity/getCouponReceiptRecord")
    @PostMapping("/api/v1/activity/getCouponReceiptRecord")
    @ApiOperation(value = "获取活动领取记录", tags = {"管理后台-活动管理"})
    public R<PageInfo<CouponReceiptRecordDto>> getCouponReceiptRecord(@RequestBody CouponReceiptRecordVo vo){
        PageInfo<CouponReceiptRecordDto> pageInfo = new PageInfo<CouponReceiptRecordDto>(vo.getPageNum(), vo.getPageSize());
@@ -390,5 +393,14 @@
    }
    /**
     * 计算优惠金额
     * @param vo
     * @return
     */
    @PostMapping("/logan/inner/appUserCoupon/calculateDiscountAmount")
    public R<BigDecimal> calculateDiscountAmount(@RequestParam CalculateDiscountAmountVo vo){
        BigDecimal bigDecimal = xpAppUserCouponService.calculateDiscountAmount(vo);
        return R.ok(bigDecimal);
    }
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpAppUserCouponService.java
@@ -14,10 +14,12 @@
import com.xiaopeng.api.dto.account.UseUserCouponDto;
import com.xiaopeng.api.model.account.XpAppUserCoupon;
import com.xiaopeng.api.query.account.XpAppUserCouponPageListQuery;
import com.xiaopeng.api.vo.account.CalculateDiscountAmountVo;
import com.xiaopeng.api.vo.account.NavigationCouponPickerVo;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.RequestParam;
import java.math.BigDecimal;
import java.util.List;
@@ -111,4 +113,12 @@
     * @return
     */
    List<CouponReceiptRecordDto> getCouponReceiptRecord(PageInfo<CouponReceiptRecordDto> pageInfo, CouponReceiptRecordVo vo);
    /**
     * 计算优惠金额
     * @param vo
     * @return
     */
    BigDecimal calculateDiscountAmount(CalculateDiscountAmountVo vo);
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpAppUserCouponServiceImpl.java
@@ -19,6 +19,7 @@
import com.xiaopeng.account.vo.CouponReceiptRecordDto;
import com.xiaopeng.account.vo.CouponReceiptRecordVo;
import com.xiaopeng.api.model.operation.XpWhitelist;
import com.xiaopeng.api.vo.account.CalculateDiscountAmountVo;
import com.xiaopeng.api.vo.account.CouponVo;
import com.xiaopeng.account.vo.UserCouponListVo;
import com.xiaopeng.api.dto.account.NavigationCouponPickerRequest;
@@ -48,6 +49,7 @@
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
@@ -630,4 +632,62 @@
        }
        return list;
    }
    /**
     * 计算优惠金额
     * @param vo
     * @return
     */
    @Override
    public BigDecimal calculateDiscountAmount(CalculateDiscountAmountVo vo) {
        XpAppUserCoupon userCoupon = this.getById(vo.getUserCouponId());
        if(null == userCoupon){
            return BigDecimal.ZERO;
        }
        if(1 != userCoupon.getStatus()){
            return BigDecimal.ZERO;
        }
        XpCoupon xpCoupon = xpCouponClient.getCouponById(userCoupon.getCouponId()).getData();
        if(null == xpCoupon){
            return BigDecimal.ZERO;
        }
        BigDecimal conditionalAmount = xpCoupon.getConditionalAmount();
        BigDecimal upperLimit = xpCoupon.getUpperLimit();
        //抵扣券
        if(1 == xpCoupon.getCouponType() && (null == conditionalAmount || conditionalAmount.compareTo(vo.getOrderMoney()) <= 0)){
            //没有达到预设条件
            if(vo.getOrderMoney().compareTo((null == conditionalAmount ? BigDecimal.ZERO : conditionalAmount)) < 0){
                return BigDecimal.ZERO;
            }
            //计算优惠金额
            BigDecimal multiply = vo.getOrderMoney().multiply(xpCoupon.getAmount().divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
            BigDecimal multiply1 = BigDecimal.ZERO;
            if(null != upperLimit){
                //计算最高优惠金额
                multiply1 = vo.getOrderMoney().multiply(upperLimit.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
            }
            //超出最高优惠金额,按照最高优惠金额进行扣减
            if(multiply.compareTo(multiply1) > 0){
                return multiply1;
            }else{
                return multiply;
            }
        }
        //抹零券
        if(3 == xpCoupon.getCouponType() && (null == conditionalAmount || conditionalAmount.compareTo(vo.getOrderMoney()) <= 0)){
            //没有达到预设条件
            if(vo.getOrderMoney().compareTo((null == conditionalAmount ? BigDecimal.ZERO : conditionalAmount)) < 0){
                return BigDecimal.ZERO;
            }
            return vo.getOrderMoney().subtract(xpCoupon.getAmount());
        }
        //满减券
        if(2 == xpCoupon.getCouponType() && (null == conditionalAmount || conditionalAmount.compareTo(vo.getOrderMoney()) <= 0)){
            if(vo.getOrderMoney().compareTo((null == conditionalAmount ? BigDecimal.ZERO : conditionalAmount)) >= 0){
                return xpCoupon.getAmount();
            }
        }
        return BigDecimal.ZERO;
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/account/XpAppUserCouponClientFallbackFactory.java
@@ -7,6 +7,7 @@
import com.xiaopeng.api.feignClient.account.XpAppUserClient;
import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient;
import com.xiaopeng.api.model.account.XpAppUserCoupon;
import com.xiaopeng.api.vo.account.CalculateDiscountAmountVo;
import com.xiaopeng.api.vo.account.UserCouponVo;
import com.xiaopeng.common.core.domain.R;
import lombok.extern.slf4j.Slf4j;
@@ -65,6 +66,12 @@
                log.error("获取用户活动领取的优惠券失败,原因: {}", cause.getMessage());
                return R.fail("获取用户活动领取的优惠券失败,原因: "+cause.getMessage());
            }
            @Override
            public R<BigDecimal> calculateDiscountAmount(CalculateDiscountAmountVo vo) {
                log.error("计算优惠金额失败,原因: {}", cause.getMessage());
                return R.fail("计算优惠金额失败");
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/order/XpOrderClientFallbackFactory.java
@@ -127,6 +127,13 @@
                log.error("确定用户类型失败,原因: {}", cause.getMessage());
                return R.fail("确定用户类型失败");
            }
            @Override
            public R<Long> getUserOrderNum(Long userId) {
                log.error("获取用户订单数量失败,原因: {}", cause.getMessage());
                return R.fail("获取用户订单数量失败");
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/account/XpAppUserCouponClient.java
@@ -4,6 +4,7 @@
import com.xiaopeng.api.dto.account.UseUserCouponDto;
import com.xiaopeng.api.factory.account.XpAppUserCouponClientFallbackFactory;
import com.xiaopeng.api.model.account.XpAppUserCoupon;
import com.xiaopeng.api.vo.account.CalculateDiscountAmountVo;
import com.xiaopeng.api.vo.account.UserCouponVo;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum;
@@ -64,4 +65,14 @@
     */
    @PostMapping("/logan/inner/appUserCoupon/getXpAppUserCoupon")
    R<List<XpAppUserCoupon>> getXpAppUserCoupon(@RequestParam Long activityId);
    /**
     * 计算优惠金额
     * @param vo
     * @return
     */
    @PostMapping("/logan/inner/appUserCoupon/calculateDiscountAmount")
    R<BigDecimal> calculateDiscountAmount(@RequestParam CalculateDiscountAmountVo vo);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/order/XpOrderClient.java
@@ -160,4 +160,13 @@
     */
    @PostMapping("/logan/inner/order/determineUserType")
    R<Integer> determineUserType(@RequestParam Long userId);
    /**
     * 获取用户订单数量
     * @param userId
     * @return
     */
    @PostMapping("/logan/inner/order/getUserOrderNum")
    R<Long> getUserOrderNum(@RequestParam Long userId);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/map/XpTestGeoFencingProhibitedPolygon.java
New file
@@ -0,0 +1,50 @@
package com.xiaopeng.api.model.map;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.geo.GeoJsonPolygon;
import org.springframework.data.mongodb.core.index.GeoSpatialIndexType;
import org.springframework.data.mongodb.core.index.GeoSpatialIndexed;
import org.springframework.data.mongodb.core.mapping.Document;
import java.io.Serializable;
/**
 * 禁行地理围栏-多边形
 * @author zhibing.pu
 * @date 2023/4/29 23:53
 */
@Data
@Document(collection = "test_prohibited_area")
public class XpTestGeoFencingProhibitedPolygon implements Serializable {
    private static final long serialVersionUID = 4508868382007529971L;
    @Id
    private String id;
    /**
     * 围栏id
     */
    private String fenceId;
    /**
     * 围栏名称
     */
    private String name;
    /**
     * 围栏区域id
     */
    private String areaId;
    /**
     * 场站id
     */
    private String stationId;
    /**
     * 多边形经纬度
     */
    @GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE)
    private GeoJsonPolygon points;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/CalculateDiscountAmountVo.java
New file
@@ -0,0 +1,17 @@
package com.xiaopeng.api.vo.account;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class CalculateDiscountAmountVo {
    /**
     * 订单金额
     */
    private BigDecimal orderMoney;
    /**
     * 优惠券id
     */
    private Long userCouponId;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/order/FareBreakdownVo.java
@@ -20,6 +20,8 @@
    private List<FareBreakdownDetailVo> longDistance;
    @ApiModelProperty(value = "红包抵扣金额")
    private BigDecimal redPacketMoney;
    @ApiModelProperty("优惠券id")
    private Long userCouponId;
    @ApiModelProperty(value = "优惠券抵扣金额")
    private BigDecimal couponMoney;
    @ApiModelProperty(value = "订单金额")
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -1202,12 +1202,6 @@
                    }
                    break;
                case ORDER_PASSENGER_ONBOARD:
//                    //先手动暂停触发,因为现目前车机响应状态时机不对
//                    try {
//                        Thread.sleep(waittime);
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
                    //乘客已上车
                    if(!orderId.contains("XU")){
                        if(orderId.contains("TEST")){
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/constant/I18nKeyConstant.java
@@ -12,7 +12,9 @@
    String NO_CURRENT_REGION = "no.current.region";
    String NO_PERMISSION = "no.permission";
    String MAX_ORDER_NUM = "max.order.num";
    String NO_CURRENT_POINT = "no.current.point";
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -8,12 +8,15 @@
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.dto.account.GetUserCouponDto;
import com.xiaopeng.api.dto.account.UcUserInfo;
import com.xiaopeng.api.dto.map.RouteAndFareDto;
import com.xiaopeng.api.dto.map.RouteStaleCheckDto;
import com.xiaopeng.api.dto.map.SelectNavigationRouteDto;
import com.xiaopeng.api.enums.RouteStrategyKind;
import com.xiaopeng.api.feignClient.account.UserResourcesClient;
import com.xiaopeng.api.feignClient.account.UserRoutePlanRuleClient;
import com.xiaopeng.api.feignClient.account.XpAppUserClient;
import com.xiaopeng.api.feignClient.account.XpAppUserCouponClient;
@@ -145,6 +148,8 @@
    private XpTargetedServiceClient xpTargetedServiceClient;
    @Resource
    private XpTradingStrategyClient xpTradingStrategyClient;
    @Resource
    private UserResourcesClient userResourcesClient;
    @Resource(name = "hutoolSnowflake")
    private Snowflake snowflake;
@@ -557,6 +562,21 @@
    @Override
    public String saveOrder(XpOrderDto dto, String uid) {
        //校验白名单用户
        UcUserInfo userInfo = userResourcesClient.getBaseUserByUid(uid);
        XpWhitelist xpWhitelist = xpWhitelistMapper.selectOne(new QueryWrapper<XpWhitelist>().eq("account", userInfo.getMobile())
                .eq("status", 1).last(" and (DATE(expire_time) < DATE(NOW()) or expire_time is null)"));
        if(null == xpWhitelist){
            throw new ServiceException("未授权用户,不能使用该功能", I18nKeyConstant.NO_PERMISSION);
        }
        //判断最大下单数
        if(null != xpWhitelist.getMaxOrderNum() && xpWhitelist.getMaxOrderNum()>0){
            Long count = xpOrderClient.getUserOrderNum(Long.valueOf(uid)).getData();
            if(xpWhitelist.getMaxOrderNum() <= count){
                throw new ServiceException("已达到最大下单数量,不能使用该功能", I18nKeyConstant.MAX_ORDER_NUM);
            }
        }
        // 是否在运营区域时间内
        XpElectronicFenceArea xpElectronicFenceArea = xpElectronicFenceAreaMapper.selectById(dto.getXpElectronicFenceAreaId());
        XpElectronicFence xpElectronicFence = xpElectronicFenceMapper.selectById(xpElectronicFenceArea.getElectronicId());
xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages.properties
@@ -7,4 +7,6 @@
to.work=当前的接送点距离过近。建议步行前往
wait.time=当前区域正在等待中,请耐心等待
walking.route.not.found=未找到步行路线
welcome.message=欢迎来到我们的应用程序!
welcome.message=欢迎来到我们的应用程序!
no.permission=未授权用户,不能使用该功能
max.order.num=已达到最大下单数量,不能使用该功能
xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages_en_US.properties
@@ -7,4 +7,6 @@
to.work=\ The current pick-up and drop-off points are too close to each other. It is recommended to walk there
wait.time=The current area is in a waiting state. Please be patient
walking.route.not.found=walking.route.not.found
welcome.message=Welcome to our application!
welcome.message=Welcome to our application!
no.permission=Unauthorized users are not allowed to use this function.
max.order.num=The maximum order quantity has been reached. This function cannot be used.
xp-robotaxi-itinerary-boot/src/main/resources/i18n/messages_zh_CN.properties
@@ -7,4 +7,6 @@
to.work=当前的接送点距离过近。建议步行前往
wait.time=当前区域正在等待中,请耐心等待
walking.route.not.found=未找到步行路线
welcome.message=欢迎来到我们的应用程序!
welcome.message=欢迎来到我们的应用程序!
no.permission=未授权用户,不能使用该功能
max.order.num=已达到最大下单数量,不能使用该功能
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/constant/I18nKeyConstant.java
@@ -15,4 +15,5 @@
    String ACCIDENT_TYPE_NOT_EXIST = "accident.type.not.exist";
    String CHECK_IN_LOCATION_DOES_NOT_EXIST = "check.in.location.does.not.exist";
    String CANNOT_REPEAT_CLOCKING_IN = "cannot.repeat.clocking.in";
    String TASK_HAS_BEEN_REASSIGNED = "task.has.been.reassigned";
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java
@@ -100,6 +100,12 @@
    @Resource
    private AccidentTaskQuartzScheduler accidentTaskQuartzScheduler;
    @Resource
    private XpOperationUserClient operationUserClient;
    @Resource
    XpFleetClient xpFleetClient;
    @ApiOperation(value = "事故类型列表", response = XpErrorType.class, tags = "运维APP-任务中心")
    @GetMapping("/maintenance-app/api/v1/task/errorTypeList")
    public R<List<XpErrorType>> errorTypeList() {
@@ -298,7 +304,8 @@
                if (Objects.isNull(jsonObject)) {
                    continue;
                }
                String downloadUrl = jsonObject.getString("url");;
                String downloadUrl = jsonObject.getString("url");
                ;
                try {
                    downloadUrl = aliOssService.getDownloadUrl(jsonObject.getString("id"), jsonObject.getString("name"), true);
                } catch (UnsupportedEncodingException e) {
@@ -320,7 +327,7 @@
    @ApiOperation(value = "待改派的工单导出", tags = {"管理后台-运维执行-任务工单-待改派工单"})
    @PostMapping("/api/v1/task/reassign/export")
    public R<?> export(@RequestBody TaskPageListQuery query, HttpServletResponse response) {
        List<XpTaskVO> list= xpTaskService.exportList(query);
        List<XpTaskVO> list = xpTaskService.exportList(query);
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), XpCruiseCheckInRecordVO.class, list);
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
@@ -348,8 +355,6 @@
        return R.ok();
    }
    @Resource
    XpFleetClient xpFleetClient;
    @ApiOperation(value = "可改派的运维人员列表", tags = {"管理后台-运维执行-任务工单-待改派工单"})
    @PostMapping("/api/v1/task/reassign/availableUsers")
@@ -357,12 +362,12 @@
        XpTask task = xpTaskService.getById(query.getTaskId());
        GeoJsonPoint point =
            new GeoJsonPoint(
                task.getVehicleLon().doubleValue(),
                task.getVehicleLat().doubleValue()
            );
                new GeoJsonPoint(
                        task.getVehicleLon().doubleValue(),
                        task.getVehicleLat().doubleValue()
                );
        Query q = new Query(Criteria.where("location").near(point)
            .maxDistance(new Distance(10, Metrics.KILOMETERS).getNormalizedValue()));
                .maxDistance(new Distance(10, Metrics.KILOMETERS).getNormalizedValue()));
        q.with(Sort.by(Sort.Direction.ASC, "dis"));
        List<XpOperationsUserPositionDTO> up = mongoTemplate.find(q, XpOperationsUserPositionDTO.class);
@@ -389,8 +394,6 @@
        return R.ok(ret);
    }
    @Resource
    private XpOperationUserClient operationUserClient;
    @ApiOperation(value = "改派详情", tags = {"管理后台-运维执行-任务工单-待改派工单"})
    @GetMapping("/api/v1/task/detail")
@@ -404,4 +407,12 @@
        insuranceInspectionScheduleTask.executeInsuranceInspectionTask();
        return R.ok();
    }
    @ApiOperation(value = "运营后台改派工单", tags = {"管理后台-运维执行-任务工单-待改派工单"})
    @PostMapping("/api/v1/task/reassign/taskReassignment")
    public R<?> taskReassignment(@RequestBody TaskReassignmentVo vo){
        xpTaskService.taskReassignment(vo);
        return R.ok();
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/XpTaskService.java
@@ -16,6 +16,8 @@
import com.xiaopeng.maintenance.model.vo.*;
import com.xiaopeng.maintenance.model.query.TaskPageListQuery;
import com.xiaopeng.maintenance.vo.TaskDetectionDetailVO;
import com.xiaopeng.maintenance.vo.TaskReassignmentVo;
import org.springframework.web.bind.annotation.RequestBody;
import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
@@ -107,4 +109,11 @@
    XpTaskVO detail(Long taskId);
    List<XpTaskVO> exportList(TaskPageListQuery query);
    /**
     * 任务改派操作
     * @param vo
     */
    void taskReassignment(TaskReassignmentVo vo);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpCruiseCheckInRuleServiceImpl.java
@@ -350,6 +350,10 @@
        }).collect(Collectors.toList());
        info.setLocationList(collect);
        XpOperationsUser xpOperationsUser = xpOperationsUserClient.queryById(byId.getOperationsUserId()).getData();
        if(null != xpOperationsUser){
            info.setOperationsUser(xpOperationsUser.getNickName());
        }
        return info;
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
@@ -57,6 +57,7 @@
import com.xiaopeng.maintenance.utils.UUIDUtil;
import com.xiaopeng.maintenance.vo.TaskCleanDetailVO;
import com.xiaopeng.maintenance.vo.TaskDetectionDetailVO;
import com.xiaopeng.maintenance.vo.TaskReassignmentVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType;
@@ -155,6 +156,9 @@
    private AliOssService aliOssService;
    @Autowired
    private AliOssDownloadUtil aliOssDownloadUtil;
    @Resource
    private WebSocketMessageClient xpWebSocketMessageClient;
    @Override
    public PageInfo<WorkBenchVO> workbench(WorkBenchQuery query) throws UnsupportedEncodingException {
@@ -437,8 +441,7 @@
        }
    }
    @Resource
    WebSocketMessageClient xpWebSocketMessageClient;
    /**
     * 推送阿里云通知
     *
@@ -2144,4 +2147,46 @@
    }
    /**
     * 任务改派操作
     * @param vo
     */
    @Override
    public void taskReassignment(TaskReassignmentVo vo) {
        XpTask xpTask = this.getById(vo.getTaskId());
        if(null == xpTask){
            throw new ServiceException("无效的任务", I18nKeyConstant.TASK_NOT_EXIST);
        }
        if(2 == xpTask.getReassignmentStatus()){
            throw new ServiceException("任务已改派,不能重复操作", I18nKeyConstant.TASK_HAS_BEEN_REASSIGNED);
        }
        xpTask.setReassignmentStatus(2);
        xpTask.setHandleUserId(vo.getNewOperationsUserId() + "");
        xpTask.setStatus(1);
        this.updateById(xpTask);
        //推送websocket
        XpTaskVO xpTaskVO = new XpTaskVO();
        BeanUtil.copyProperties(xpTask, xpTaskVO);
        xpWebSocketMessageClient.pushTask(xpTaskVO);
        boolean isAccidentTask = Integer.valueOf(2).equals(xpTask.getTaskCategory());
        Long vehicleId = xpTask.getVehicleId();
        Integer processingTimeLimit = null;
        String plateNumber = "";
        if (isAccidentTask) {
            // 查询规则 任务结束时间从任务分配时开始计算
            XpTaskRule taskRule = xpTaskRuleMapper.selectOne(null);
            if (taskRule != null) {
                processingTimeLimit = taskRule.getProcessingTimeLimit();
            }
            if (vehicleId != null) {
                XpVehicle vehicle = xpVehicleClient.queryById(vehicleId).getData();
                if (vehicle != null && StringUtils.isNotBlank(vehicle.getPlateNumber())) {
                    plateNumber = vehicle.getPlateNumber();
                }
            }
        }
        if (isAccidentTask && processingTimeLimit != null) {
            sendAssignedAccidentNotificationAsync(xpTask, Long.valueOf(xpTask.getHandleUserId()), plateNumber, processingTimeLimit);
        }
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/TaskReassignmentVo.java
New file
@@ -0,0 +1,14 @@
package com.xiaopeng.maintenance.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel
public class TaskReassignmentVo {
    @ApiModelProperty("任务id")
    private Long taskId;
    @ApiModelProperty("新运维人id")
    private Long newOperationsUserId;
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/vo/XpCruiseCheckInRuleInfoVo.java
@@ -14,4 +14,7 @@
    @ApiModelProperty("巡游打卡点位列表")
    private List<CruiseCheckInLocationVo> locationList;
    @ApiModelProperty("关联人名称")
    private String operationsUser;
}
xp-robotaxi-maintenance-boot/src/main/resources/i18n/messages.properties
@@ -7,4 +7,5 @@
task.vehicle.not.exist=上报失败,未获取到车辆信息
accident.type.not.exist=事故类型不存在
check.in.location.does.not.exist="打卡点位不存在"
cannot.repeat.clocking.in="不能重复打卡"
cannot.repeat.clocking.in="不能重复打卡"
task.has.been.reassigned = "任务已改派,不能重复操作"
xp-robotaxi-maintenance-boot/src/main/resources/i18n/messages_en_US.properties
@@ -9,3 +9,4 @@
task.rule.not.config=The vehicle accident task allocation rules have not been configured
check.in.location.does.not.exist="The check-in location does not exist."
cannot.repeat.clocking.in="Cannot repeat clocking in"
task.has.been.reassigned = "The task has been reassigned and cannot be performed again."
xp-robotaxi-maintenance-boot/src/main/resources/i18n/messages_zh_CN.properties
@@ -8,4 +8,5 @@
accident.type.not.exist=事故类型不存在
task.rule.not.config=未配置车辆事故任务分配规则
check.in.location.does.not.exist="打卡点位不存在"
cannot.repeat.clocking.in="不能重复打卡"
cannot.repeat.clocking.in="不能重复打卡"
task.has.been.reassigned = "任务已改派,不能重复操作"
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/controller/XpTestElectronicFenceManagementController.java
@@ -85,17 +85,8 @@
        PageInfo<XpTestElectronicFence> pageList = xpElectronicFenceService.pageList(query);
        return R.ok(pageList);
    }
    /**
     * 电子围栏列表接口
     *
     * @return 电子围栏列表
     */
    @ApiOperation(value = "电子围栏列表接口", tags = {"运维APP-电子围栏"})
    @GetMapping("/maintenance-app/api/v1/electronicFence/list")
    public R<List<XpTestElectronicFence>> vehicleMap() {
        List<XpTestElectronicFence> list = xpElectronicFenceService.list();
        return R.ok(list);
    }
    /**
     * 新增电子围栏
     */
xp-robotaxi-map-boot/src/main/java/com/xiaopeng/map/service/serviceimpl/XpTestElectronicFenceServiceImpl.java
@@ -12,6 +12,8 @@
import com.xiaopeng.api.dto.operation.TestElectronicFenceUpdateDto;
import com.xiaopeng.api.model.map.XpGeoFencingPolygon;
import com.xiaopeng.api.model.map.XpGeoFencingProhibitedPolygon;
import com.xiaopeng.api.model.map.XpTestGeoFencingPolygon;
import com.xiaopeng.api.model.map.XpTestGeoFencingProhibitedPolygon;
import com.xiaopeng.api.model.operation.*;
import com.xiaopeng.api.query.operation.ElectronicPageListQuery;
import com.xiaopeng.common.core.domain.R;
@@ -235,7 +237,7 @@
                            newArea.getFencePoints(),
                            existingArea.getFencePoints())) {
                        throw new ServiceException(
                                "运营区域{}与现有运营区域{}发生重叠",
                                "运营区域{}与现有测试区域{}发生重叠",
                                I18nKeyConstant.AREA_OVERLAP_ERROR,
                                new Object[]{existingArea.getAreaName(), existingArea.getAreaName()}
                        );
@@ -312,7 +314,7 @@
            for (XpTestElectronicFenceArea newElectronicFenceArea : newElectronicFenceAreas) {
                if (newElectronicFenceArea.getAreaType() == 1
                        && newElectronicFenceArea.getAreaStatus() == 1) {
                    XpGeoFencingPolygon xpGeoFencingPolygon = new XpGeoFencingPolygon();
                    XpTestGeoFencingPolygon xpGeoFencingPolygon = new XpTestGeoFencingPolygon();
                    xpGeoFencingPolygon.setFenceId(String.valueOf(xpElectronicFence.getId()));
                    xpGeoFencingPolygon.setName(xpElectronicFence.getElectronicName());
                    xpGeoFencingPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId()));
@@ -325,7 +327,7 @@
                }
                if (newElectronicFenceArea.getAreaType() == 2
                        && newElectronicFenceArea.getAreaStatus() == 1) {
                    XpGeoFencingProhibitedPolygon xpGeoFencingProhibitedPolygon = new XpGeoFencingProhibitedPolygon();
                    XpTestGeoFencingProhibitedPolygon xpGeoFencingProhibitedPolygon = new XpTestGeoFencingProhibitedPolygon();
                    xpGeoFencingProhibitedPolygon.setFenceId(String.valueOf(xpElectronicFence.getId()));
                    xpGeoFencingProhibitedPolygon.setName(xpElectronicFence.getElectronicName());
                    xpGeoFencingProhibitedPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId()));
@@ -371,7 +373,7 @@
                        res.add(updatedArea.getAreaName());
                        res.add(existingArea.getAreaName());
                        throw new ServiceException(
                                "运营区域{}与现有运营区域{}发生重叠,请编辑已有的运营区域",
                                "运营区域{}与现有测试区域{}发生重叠,请编辑已有的运营区域",
                                I18nKeyConstant.AREA_OVERLAP_ERROR,
                                res.toArray()
                        );
@@ -442,10 +444,10 @@
            Query delMongoQuery = new Query();
            delMongoQuery.addCriteria(Criteria.where("fenceId").is(String.valueOf(dto.getId())));
            delMongoQuery.addCriteria(Criteria.where("areaId").in(toDeleteAreaIdStrings));
            mongoTemplate.remove(delMongoQuery, XpGeoFencingProhibitedPolygon.class);
            mongoTemplate.remove(delMongoQuery, XpTestGeoFencingProhibitedPolygon.class);
        }
        // 删除旧的区域数据,然后保存新的区域数据
        mongoTemplate.remove(new Query(Criteria.where("fenceId").is(String.valueOf(dto.getId()))), XpGeoFencingPolygon.class);
        mongoTemplate.remove(new Query(Criteria.where("fenceId").is(String.valueOf(dto.getId()))), XpTestGeoFencingPolygon.class);
        if (xpElectronicFence.getStatus() == 2) {
            // 设置电子围栏ID并保存区域数据
            for (XpTestElectronicFenceArea area : updatedElectronicFenceAreas) {
@@ -487,7 +489,7 @@
                    query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId())));
                    XpGeoFencingPolygon old = mongoTemplate.findOne(query, XpGeoFencingPolygon.class);
                    if (old == null) {
                        XpGeoFencingPolygon xpGeoFencingPolygon = new XpGeoFencingPolygon();
                        XpTestGeoFencingPolygon xpGeoFencingPolygon = new XpTestGeoFencingPolygon();
                        xpGeoFencingPolygon.setFenceId(String.valueOf(xpElectronicFence.getId()));
                        xpGeoFencingPolygon.setName(xpElectronicFence.getElectronicName());
                        xpGeoFencingPolygon.setCityCode(cityCode);
@@ -520,7 +522,7 @@
                    query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId())));
                    XpGeoFencingProhibitedPolygon old = mongoTemplate.findOne(query, XpGeoFencingProhibitedPolygon.class);
                    if (old == null) {
                        XpGeoFencingProhibitedPolygon xpGeoFencingProhibitedPolygon = new XpGeoFencingProhibitedPolygon();
                        XpTestGeoFencingProhibitedPolygon xpGeoFencingProhibitedPolygon = new XpTestGeoFencingProhibitedPolygon();
                        xpGeoFencingProhibitedPolygon.setFenceId(String.valueOf(xpElectronicFence.getId()));
                        xpGeoFencingProhibitedPolygon.setName(xpElectronicFence.getElectronicName());
                        xpGeoFencingProhibitedPolygon.setAreaId(String.valueOf(newElectronicFenceArea.getId()));
@@ -542,7 +544,7 @@
                    Query query = new Query();
                    query.addCriteria(Criteria.where("fenceId").is(String.valueOf(xpElectronicFence.getId())));
                    query.addCriteria(Criteria.where("areaId").is(String.valueOf(newElectronicFenceArea.getId())));
                    mongoTemplate.remove(query, XpGeoFencingProhibitedPolygon.class);
                    mongoTemplate.remove(query, XpTestGeoFencingProhibitedPolygon.class);
                }
            }
        }
@@ -616,11 +618,11 @@
                            continue;
                        }
                        try {
                            boolean inOperatingArea = xpGeoFencingPolygonService.isInFence(lon, lat, fenceId, "operating_area");
                            boolean inOperatingArea = xpGeoFencingPolygonService.isInFence(lon, lat, fenceId, "test_operating_area");
                            if (!inOperatingArea) {
                                continue;
                            }
                            boolean inProhibitedArea = xpGeoFencingPolygonService.isInFence(lon, lat, fenceId, "prohibited_area");
                            boolean inProhibitedArea = xpGeoFencingPolygonService.isInFence(lon, lat, fenceId, "test_prohibited_area");
                            if (inProhibitedArea) {
                                continue;
                            }
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/constant/I18nKeyConstant.java
@@ -19,6 +19,9 @@
    String ORDER_REASSIGN_NEW_VEHICLE_NOT_IN_ACCEPT_MODE = "order.reassign.new.vehicle.not.in.accept.mode";
    String ORDER_REASSIGN_NEW_VEHICLE_NOT_START_ACCEPT = "order.reassign.new.vehicle.not.start.accept";
    String ORDER_REASSIGN_NEW_VEHICLE_NOT_FREE = "order.reassign.new.vehicle.not.free";
    String ORDER_REASSIGN_NEW_VEHICLE_NOT_OPERATIONAL = "order.reassign.new.vehicle.not.operational";
    String ORDER_REASSIGN_NEW_VEHICLE_NOT_POSITION = "order.reassign.new.vehicle.not.position";
    String ORDER_REASSIGN_NEW_VEHICLE_BATTERY_LOW = "order.reassign.new.vehicle.battery";
    String ORDER_STATUS_ERROR = "order.status.error";
    String ORDER_CHANGE_AMOUNT_ID_REQUIRED = "order.change.amount.id.required";
    String ORDER_CHANGE_AMOUNT_AMOUNT_REQUIRED = "order.change.amount.amount.required";
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
@@ -500,13 +500,13 @@
     * +
     * 获取行程费用明细
     */
    @PutMapping("/api/v1/mini-program/order/fare-breakdown/{orderId}")
    @PutMapping("/api/v1/mini-program/order/fare-breakdown")
    @ApiOperation(value = "获取行程费用明细", tags = {"小程序-获取行程费用明细"})
    @XpClientCheck(checkToken = false, checkOtpToken = true)
    public R<FareBreakdownVo> fareBreakdown(@PathVariable("orderId") Long orderId, HttpServletRequest request) {
    public R<FareBreakdownVo> fareBreakdown(@RequestBody com.xiaopeng.order.vo.FareBreakdownVo vo, HttpServletRequest request) {
        // uid已通过拦截器otp校验,可以直接使用
        String uid = request.getHeader("XP-Uid");
        return xpOrderService.fareBreakdown(orderId, uid);
        return xpOrderService.fareBreakdown(vo, uid);
    }
    /**
@@ -730,4 +730,17 @@
            return R.ok(3);
        }
    }
    /**
     * 获取用户订单数量
     * @param userId
     * @return
     */
    @PostMapping("/logan/inner/order/getUserOrderNum")
    public R<Long> getUserOrderNum(@RequestParam Long userId){
        long count = xpOrderService.count(new QueryWrapper<XpOrder>().eq("app_user_id", userId)
                .ne("status", 0).eq("is_deleted", 0));
        return R.ok(count);
    }
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/base/TimeJobType.java
@@ -6,6 +6,7 @@
 */
public enum TimeJobType {
    ORDER_CANCEL("order_cancel","订单取消"),
    TEST_ORDER_CANCEL("test_order_cancel","测试订单取消"),
    ADD_CRUISE_MISSION("add_cruise_mission","添加巡游任务"),
    ADD_CHAIN_REACTION_ORDER_MISSION("add_cruise_mission","添加派送连环单任务"),
    END_TRIP("end_trip","自动结束行程");
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/job/jobs/TestOrderCancelJob.java
New file
@@ -0,0 +1,58 @@
package com.xiaopeng.order.job.jobs;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.order.XpTestOrder;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.order.job.base.AbstractJob;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.Objects;
/**
 * 直播推送定时任务
 * @author Administrator
 *
 */
@Slf4j
public class TestOrderCancelJob extends AbstractJob {
    public static final String name = "testOrderCancel_";
    @Override
    public void execute(JobExecutionContext context)
            throws JobExecutionException {
        JobDataMap maps = context.getMergedJobDataMap();
        Long orderId = maps.getLong("id");
        try {
            log.info("开始执行订单取消任务");
            XpTestOrder xpOrder = testOrderService.getById(orderId);
            if(Objects.nonNull(xpOrder) && (xpOrder.getStatus()==4 || xpOrder.getStatus()==5)){
                Integer status = xpOrder.getStatus();
                log.info("订单取消开始");
                testOrderService.cancelTestOrderById(xpOrder.getId());
                // 下发命令
                if (null != xpOrder.getVehicleId()) {
                    R<XpVehicle> xpVehicleR = xpVehicleClient.queryById(xpOrder.getVehicleId());
                    XpVehicle xpVehicle = xpVehicleR.getData();
                    //还原车辆状态为空闲
                    if(1 == xpVehicle.getState()){
                        XpVehicle vehicle1 = new XpVehicle();
                        vehicle1.setId(xpVehicle.getId());
                        vehicle1.setState(0);
                        xpVehicleClient.updateVehicleById(vehicle1);
                        log.info("订单定时取消,车辆状态修改0 {}", xpVehicle.getPlateNumber());
                    }
                    //下发车机取消命令
                }
                log.info("订单取消状态修改完成");
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java
@@ -186,7 +186,7 @@
     */
    void addCruiseMission(XpOrder order, Integer status);
    R<FareBreakdownVo> fareBreakdown(Long orderId, String uid);
    R<FareBreakdownVo> fareBreakdown(com.xiaopeng.order.vo.FareBreakdownVo vo, String uid);
    R payment(XpOrderPayDto dto, String uid);
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -46,6 +46,7 @@
import com.xiaopeng.api.model.vehicleConvoy.XpFleet;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.OrderType;
import com.xiaopeng.api.vo.account.CalculateDiscountAmountVo;
import com.xiaopeng.api.vo.account.UserCouponVo;
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
import com.xiaopeng.api.vo.automaticPilot.protobuf.OrderOperationType;
@@ -266,8 +267,8 @@
        }
        List<XpOrder> list = this.list(wrapper);
        BigDecimal orderMoney = list.stream().map(XpOrder::getOrderMoney).collect(Collectors.toList()).stream().reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
        BigDecimal couponMoney = list.stream().map(XpOrder::getCouponMoney).collect(Collectors.toList()).stream().reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
        BigDecimal orderMoney = list.stream().filter(order -> Objects.nonNull(order.getOrderMoney())).map(XpOrder::getOrderMoney).collect(Collectors.toList()).stream().reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
        BigDecimal couponMoney = list.stream().filter(order -> Objects.nonNull(order.getCouponMoney())).map(XpOrder::getCouponMoney).collect(Collectors.toList()).stream().reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
        // 2. 分页查询
        Page<XpOrder> page = new Page<>(query.getPageNum(), query.getPageSize());
@@ -1013,6 +1014,16 @@
        if (Objects.isNull(newVehicle.getState()) || newVehicle.getState() != 0) {
            throw new ServiceException("新车辆已接单,请重新选择", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_NOT_FREE);
        }
        if (newVehicle.getOperatingStatus() != 1){
            throw new ServiceException("新车辆状态为非运营状态,请重新选择", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_NOT_OPERATIONAL);
        }
        VehiclePosition vehiclePosition = mongoTemplate.findOne(Query.query(Criteria.where("vin").is(newVehicle.getVehicleVin())), VehiclePosition.class);
        if(null == vehiclePosition){
            throw new ServiceException("未能获取到新车的定位数据,请重新选择", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_NOT_POSITION);
        }
        if(vehiclePosition.getCurrentElectricity() < 20){
            throw new ServiceException("新车电量不足,请重新选择", I18nKeyConstant.ORDER_REASSIGN_NEW_VEHICLE_BATTERY_LOW);
        }
        // 6. 保存原车辆和车队信息
@@ -3096,8 +3107,15 @@
    }
    @Override
    public R<FareBreakdownVo> fareBreakdown(Long orderId, String uid) {
        XpOrder order = this.getById(orderId);
    public R<FareBreakdownVo> fareBreakdown(com.xiaopeng.order.vo.FareBreakdownVo vo, String uid) {
        XpOrder order = this.getById(vo.getOrderId());
        //根据新的优惠券计算优惠金额
        if(null != order.getCouponId()){
            CalculateDiscountAmountVo discountAmountVo = new CalculateDiscountAmountVo();
            BigDecimal data = xpAppUserCouponClient.calculateDiscountAmount(discountAmountVo).getData();
            order.setCouponId(vo.getUserCouponId());
            order.setCouponMoney(data);
        }
        order.setAppUserId(null);
        FareBreakdownVo res = new FareBreakdownVo();
        res.setChangeMoneyFlag(order.getChangeMoneyFlag());
@@ -3107,7 +3125,7 @@
        List<FareBreakdownDetailVo> duration = new ArrayList<>();
        List<FareBreakdownDetailVo> longDistance = new ArrayList<>();
        List<XpOrderDetail> xpOrderDetails = xpOrderDetailMapper.selectList(new LambdaQueryWrapper<XpOrderDetail>().eq(XpOrderDetail::getOrderId, orderId));
        List<XpOrderDetail> xpOrderDetails = xpOrderDetailMapper.selectList(new LambdaQueryWrapper<XpOrderDetail>().eq(XpOrderDetail::getOrderId, vo.getOrderId()));
        for (XpOrderDetail xpOrderDetail : xpOrderDetails) {
            FareBreakdownDetailVo detail = new FareBreakdownDetailVo();
            detail.setType(xpOrderDetail.getType());
@@ -3131,6 +3149,7 @@
        res.setDuration(duration);
        res.setLongDistance(longDistance);
        res.setRedPacketMoney(order.getRedPacketMoney());
        res.setUserCouponId(order.getCouponId());
        res.setCouponMoney(order.getCouponMoney());
        res.setOrderMoney(order.getOrderMoney());
        res.setKilometer(order.getMileageKilometers() == null ? BigDecimal.ZERO : BigDecimal.valueOf(order.getMileageKilometers()).multiply(BigDecimal.valueOf(1000)));
@@ -3149,6 +3168,8 @@
        return R.ok(res);
    }
    @Override
    public R payment(XpOrderPayDto dto, String uid) {
        // mvp版本不做支付 使用优惠券抵扣为0元订单处理 处理订单状态即可
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpTestOrderServiceImpl.java
@@ -52,6 +52,7 @@
import com.xiaopeng.order.job.base.TimeJobType;
import com.xiaopeng.order.job.jobs.EndTripJob;
import com.xiaopeng.order.job.jobs.OrderCancelJob;
import com.xiaopeng.order.job.jobs.TestOrderCancelJob;
import com.xiaopeng.order.mangodb.model.OrderTrajectory;
import com.xiaopeng.order.mapper.XpCruiseOrderMapper;
import com.xiaopeng.order.mapper.XpTestOrderDetailMapper;
@@ -138,6 +139,9 @@
    @Resource
    private BootCommonService bootCommonService;
    @Resource
    private XpTradingStrategyClient tradingStrategyClient;
    @Resource(name = "hutoolSnowflake")
    private Snowflake snowflake;
@@ -896,9 +900,9 @@
                                    put("id", xpOrder.getId())
                                    .build();
                    QuartzManager.addJob(
                            OrderCancelJob.class,
                            (OrderCancelJob.name + xpOrder.getId()).toUpperCase(),
                            TimeJobType.ORDER_CANCEL,
                            TestOrderCancelJob.class,
                            (TestOrderCancelJob.name + xpOrder.getId()).toUpperCase(),
                            TimeJobType.TEST_ORDER_CANCEL,
                            DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(xpPoint.getParkingTimeLimit())),
                            cancelJobMaps
                    );
@@ -910,9 +914,27 @@
                    xpOrder.setBoardingTime(now);
                    xpOrder.setRideTime(now);
                    // 删除定时任务job
                    QuartzManager.removeJob((OrderCancelJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.ORDER_CANCEL);
                    QuartzManager.removeJob((TestOrderCancelJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.TEST_ORDER_CANCEL);
                    //乘客已上车,重新倒计时不开始行程取消订单
                    XpTestPoint xpPoint1 = xpTestPointClient.queryById(xpOrder.getStartTestPointId()).getData();
                    XpTradingStrategy tradingStrategy = tradingStrategyClient.getTradingStrategyByCityCode(xpPoint1.getCityCode()).getData();
                    if(null != tradingStrategy){
                        Map<String, ? extends Object> cancelJobMaps1 =
                                new ImmutableMap.Builder<String, Long>()
                                        .put("id", xpOrder.getId())
                                        .build();
                        QuartzManager.addJob(
                                TestOrderCancelJob.class,
                                (TestOrderCancelJob.name + xpOrder.getId()).toUpperCase(),
                                TimeJobType.TEST_ORDER_CANCEL,
                                DateUtils.localDateTimeToDate(LocalDateTime.now().plusMinutes(tradingStrategy.getBdNotBoardedTime())),
                                cancelJobMaps1
                        );
                    }
                    break;
                case 6:
                    // 删除定时任务job
                    QuartzManager.removeJob((TestOrderCancelJob.name + xpOrder.getId()).toUpperCase(), TimeJobType.TEST_ORDER_CANCEL);
                    // 行程开始时间
                    xpOrder.setTripBegin(LocalDateTime.now());
                    redisService.deleteObject("TEST_ORDER_NAVIGATION_START_DATA:" + xpOrder.getVehicleId());
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/vo/FareBreakdownVo.java
New file
@@ -0,0 +1,15 @@
package com.xiaopeng.order.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel
public class FareBreakdownVo {
    @ApiModelProperty("订单id")
    private Long orderId;
    @ApiModelProperty("优惠券id")
    private Long userCouponId;
}
xp-robotaxi-order-boot/src/main/resources/i18n/messages.properties
@@ -19,3 +19,6 @@
order.change.amount.status.invalid=当前订单状态不允许改价,只有待付款状态的订单可以改价
order.change.amount.failed=订单改价失败,请稍后重试
path.not.found=获取导航信息失败
order.reassign.new.vehicle.not.operational=新车辆状态为非运营状态,请重新选择
order.reassign.new.vehicle.not.position=未能获取到新车的定位数据,请重新选择
order.reassign.new.vehicle.battery=新车电量不足,请重新选择
xp-robotaxi-order-boot/src/main/resources/i18n/messages_en_US.properties
@@ -20,3 +20,6 @@
order.change.amount.status.invalid=The current order status does not allow price changes. Only pending payment orders can be changed.
order.change.amount.failed=Failed to change order amount. Please try again later.
path.not.found=Failed to obtain navigation information
order.reassign.new.vehicle.not.operational=The status of the new vehicle is not in operation. Please select again.
order.reassign.new.vehicle.not.position=Failed to obtain the positioning data of the new car. Please select again.
order.reassign.new.vehicle.battery=The battery of the new car is low. Please choose another one.
xp-robotaxi-order-boot/src/main/resources/i18n/messages_zh_CN.properties
@@ -20,3 +20,6 @@
order.change.amount.status.invalid=当前订单状态不允许改价,只有待付款状态的订单可以改价
order.change.amount.failed=订单改价失败,请稍后重试
path.not.found=获取导航信息失败
order.reassign.new.vehicle.not.operational=新车辆状态为非运营状态,请重新选择
order.reassign.new.vehicle.not.position=未能获取到新车的定位数据,请重新选择
order.reassign.new.vehicle.battery=新车电量不足,请重新选择