puzhibing
2026-03-06 1ca66b10db05e7c9d5d653361d334f161b452c23
合并代码
1个文件已删除
30个文件已修改
398 ■■■■■ 已修改文件
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/MqttPublishDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPricingClientFallbackFactory.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPointClient.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPricingClient.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpGeoQueryEntity.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/ExportOperationsUserVo.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/FareVo.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/XPUUtil.java 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpClockInServiceImpl.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpInvitationCodeController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpWhitelistController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/exportExcle/XpInvitationCodeExportExcel.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/InvitationPageListQuery.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/WhitelistPageListQuery.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpGeoQueryEntityService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpGeoQueryEntityServiceImpl.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPointServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpWhitelistServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/task/TaskUtil.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/OssUtil.java 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpInvitationCodeMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpWhitelistMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpCruiseOrderServiceImpl.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/controller/PushOrderRouteController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java
@@ -245,8 +245,9 @@
    @ApiOperation(value = "运维人员管理导入数据", tags = {"管理后台-运维执行"})
    @PostMapping("/api/v1/operationsUser/importOperationsUser")
    public void importOperationsUser(@RequestPart("file") MultipartFile file){
    public R<String> importOperationsUser(@RequestPart("file") MultipartFile file){
        xpOperationsUserService.importOperationsUser(file);
        return R.ok();
    }
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java
@@ -354,17 +354,36 @@
                xpOperationsUser.setUniqueNumber(exportOperationsUserVo.getUniqueNumber());
                xpOperationsUser.setAvatar(exportOperationsUserVo.getAvatar());
                xpOperationsUser.setPhoneNumber(exportOperationsUserVo.getPhoneNumber());
                xpOperationsUser.setPassword(SecurityUtils.encryptPassword("a123456"));
                xpOperationsUser.setRemarks(exportOperationsUserVo.getRemarks());
                xpOperationsUser.setStatus(true);
                xpOperationsUser.setIdCardFront(exportOperationsUserVo.getIdCardFront());
                xpOperationsUser.setIdCardBack(exportOperationsUserVo.getIdCardBack());
                xpOperationsUser.setDriverLicense(exportOperationsUserVo.getDriverLicense());
                xpOperationsUser.setCertificateOfNoCriminalRecord(exportOperationsUserVo.getCertificateOfNoCriminalRecord());
                xpOperationsUser.setTrainingGraduationCertificate(exportOperationsUserVo.getTrainingGraduationCertificate());
                xpOperationsUser.setIdCardFront(StringUtils.isBlank(exportOperationsUserVo.getIdCardFront()) ? null : exportOperationsUserVo.getIdCardFront());
                xpOperationsUser.setIdCardBack(StringUtils.isBlank(exportOperationsUserVo.getIdCardBack()) ? null : exportOperationsUserVo.getIdCardBack());
                xpOperationsUser.setDriverLicense(StringUtils.isBlank(exportOperationsUserVo.getDriverLicense()) ? null : exportOperationsUserVo.getDriverLicense());
                xpOperationsUser.setCertificateOfNoCriminalRecord(StringUtils.isBlank(exportOperationsUserVo.getCertificateOfNoCriminalRecord()) ? null : exportOperationsUserVo.getCertificateOfNoCriminalRecord());
                xpOperationsUser.setTrainingGraduationCertificate(StringUtils.isBlank(exportOperationsUserVo.getTrainingGraduationCertificate()) ? null : exportOperationsUserVo.getTrainingGraduationCertificate());
                xpOperationsUser.setDeleted(false);
                xpOperationsUser.setCreateTime(LocalDateTime.now());
                xpOperationsUser.setUpdateTime(LocalDateTime.now());
                this.save(xpOperationsUser);
                // 通过角色名称查询角色
                String roleName = exportOperationsUserVo.getRoleName();
                if(StringUtils.isNotBlank(roleName)){
                    List<SysRole> sysRoles = iSysRoleService.list(Wrappers.lambdaQuery(SysRole.class)
                            .in(SysRole::getRoleName, Arrays.asList(roleName.split(","))));
                    if(!CollectionUtils.isEmpty(sysRoles)){
                        List<XpOperationsRole> xpOperationsRoles = new ArrayList<>();
                        for (SysRole sysRole : sysRoles) {
                            XpOperationsRole xpOperationsRole = new XpOperationsRole();
                            xpOperationsRole.setOperationsUserId(xpOperationsUser.getId());
                            xpOperationsRole.setRoleId(sysRole.getId());
                            xpOperationsRoles.add(xpOperationsRole);
                        }
                        xpOperationsRoleService.saveBatch(xpOperationsRoles);
                    }else {
                        throw new ServiceException("角色["+roleName+"]不存在",I18nKeyConstant.ROlE_NOT_EXISTS);
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/MqttPublishDto.java
@@ -1,5 +1,6 @@
package com.xiaopeng.api.dto.automaticPilot;
import com.xiaopeng.api.vo.automaticPilot.MqttPublishVo;
import lombok.Data;
@Data
@@ -16,4 +17,6 @@
     * 数据
     */
    private Object data;
    private MqttPublishVo vo;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPricingClientFallbackFactory.java
@@ -39,6 +39,12 @@
                return R.fail();
            }
            @Override
            public R<?> deleteXpGeoQueryEntity(String orderId) {
                log.error("删除XpGeoQueryEntity失败", cause);
                return null;
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPointClient.java
@@ -14,13 +14,15 @@
import com.xiaopeng.api.query.operation.PointPageListListQuery;
import com.xiaopeng.api.vo.order.XpHistoryEndPointsVo;
import com.xiaopeng.api.vo.order.XpHistoryStartPointsVo;
import com.xiaopeng.api.vo.order.XpPointInfoVo;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum;
import com.xiaopeng.common.core.web.page.PageInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
import java.util.Set;
@@ -34,12 +36,17 @@
    @PostMapping("/base/v1/mini-program/xp-point/getHistoryEndPoints")
    R<List<XpHistoryEndPointsVo>> getHistoryEndPoints(@RequestBody HistoryEndPointsDto historyEndPointsDto);
    @PostMapping("/api/v1/point/listElectronicFenceArea")
    R<List<XpElectronicFenceArea>> listElectronicFenceArea();
    @PostMapping("/api/v1/point/listPoint")
    R<List<XpPoint>> list(@RequestBody PointListQuery query);
    @PostMapping("/api/v1/point/pageList")
    R<PageInfo<XpPoint>> pageList(@RequestBody PointPageListListQuery query);
    @PostMapping("/api/v1/point/getByIds")
    R<List<XpPoint>> getByIds(@RequestBody XpPointExportExcelQuery query);
@@ -53,13 +60,14 @@
     * 编辑点位
     */
    @PostMapping("/api/v1/point/editPoint")
    R edit(@Validated@RequestBody PointUpdateDto pointAddDto);
    R edit(@Validated @RequestBody PointUpdateDto pointAddDto);
    /**
     * 点位详情
     */
    @GetMapping("/api/v1/point/queryPointById")
    public R<XpPoint> queryById(@RequestParam Long id);
    /**
     * 点位删除
     */
@@ -78,8 +86,10 @@
    @PostMapping("/base/v1/mini-program/inner/point/getPointsInfo")
    R<List<XpPoint>> getPointsInfo(@RequestBody Set<Long> points);
    /**
     * 判断点位是在有效期内
     *
     * @param pointId
     * @return
     */
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPricingClient.java
@@ -31,4 +31,14 @@
    R<?> updateXpGeoQueryEntity(@RequestParam String orderId);
    /**
     * 删除XpGeoQueryEntity
     * @param orderId
     * @return
     */
    @PostMapping("/inner/deleteXpGeoQueryEntity")
    R<?> deleteXpGeoQueryEntity(@RequestParam String orderId);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpGeoQueryEntity.java
@@ -48,6 +48,9 @@
    private String time;
    /**
     * 0待接单 1已处理 2取消
     */
    @Field("status")
    private Integer status;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/ExportOperationsUserVo.java
@@ -35,7 +35,7 @@
    /**
     * 状态
     */
    @Excel(name = "状态", sort = 5)
    @Excel(name = "状态", sort = 5,readConverterExp = "0=禁用,1=启用")
    private String status;
    /**
     * 创建时间
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/FareVo.java
@@ -1,5 +1,6 @@
package com.xiaopeng.api.vo.operation;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -33,8 +34,10 @@
    @ApiModelProperty(value = "优惠券id")
    private Long couponId;
    @ApiModelProperty("系统优惠金额")
    private Double systemDiscount;
    @ApiModelProperty(value = "最终价格-字符串")
    private String finalFareStr;
}
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
@@ -42,9 +42,7 @@
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.Date;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -126,7 +124,6 @@
        if (!dto.getOrderId().contains("XU") && mqttPublishDto.getCode()== 200) {
            // 修改车子为接单状态
            xpVehicleClient.updateVehicleStatus(new UpdateVehicleStateDto(dto.getVin(),1));
            return R.ok(true);
        }
        return R.ok(false);
@@ -144,9 +141,17 @@
        SnowFlake snowFlake = new SnowFlake(0, 0);
        snowFlake.withStartTimestamp(1420041600000L);
        long sequence = snowFlake.nextId();
        xpuUtil.cloudOrderOperation(operationBuilder.build(), dto.getVin(), sequence);
        redisService.setCacheObject(String.valueOf(sequence), "cancelOrder_" + dto.getOrderId() + "_" + dto.getVin(), 30l, TimeUnit.MINUTES);
        return R.ok(true);
        MqttPublishDto mqttPublishDto = xpuUtil.cloudOrderOperation(operationBuilder.build(), dto.getVin(), sequence);
        if (mqttPublishDto.getCode() == 200) {
            if(!dto.getOrderId().contains("XU")){
                // 正常订单处理
                redisService.setCacheObject(String.valueOf(sequence), "cancelOrder_" + dto.getOrderId() + "_" + dto.getVin(), 30l, TimeUnit.MINUTES);
            }
            return R.ok(true);
        }
        return R.ok(false);
    }
@@ -196,8 +201,8 @@
            vehicleId = 11L;//默认使用造的测试车辆
        }
        if(null == startLat || null == startLon){
            startLat = 23.157155D;
            startLon = 113.382373D;
            startLat = 30.583407D;
            startLon = 104.040251D;
        }
        XpVehicle xpVehicle = xpVehicleClient.queryById(vehicleId).getData();
        XpOrder xpOrder = null;
@@ -275,8 +280,16 @@
        orderId = xpOrder.getId();
        String vin = xpVehicle.getVehicleVin();
        Long appUserId = xpOrder.getAppUserId();
        Object cacheObject = redisService.getCacheObject("ORDER_NAVIGATION_START_DATA:" + xpOrder.getAppUserId());
        RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class);
//        Object cacheObject = redisService.getCacheObject("ORDER_NAVIGATION_START_DATA:" + xpOrder.getAppUserId());
//        RouteVo routeVo = JSON.parseObject(cacheObject.toString(), RouteVo.class);
        RouteVo routeVo =new RouteVo();
        ArrayList<LonLatDto> lonLatDtos = new ArrayList<>();
        LonLatDto lonLatDto1 = new LonLatDto();
        lonLatDto1.setLatitude(30.575685);
        lonLatDto1.setLongitude(104.001118);
        lonLatDtos.add(lonLatDto1);
        routeVo.setPolyline(lonLatDtos);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1000));
        Long finalOrderId = orderId;
@@ -287,7 +300,6 @@
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            List<LonLatDto> polyline = routeVo.getPolyline();
            for (LonLatDto lonLatDto : polyline) {
                Double latitude = lonLatDto.getLatitude();
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/XPUUtil.java
@@ -50,7 +50,6 @@
     * @param taskList
     * @return
     */
    //TODO 处理feign调用的异常
    public MqttPublishDto cloudCreateOrder(RtTaskList taskList, String vin, Long sequence) {
        MsgContent.Builder msgContentBuilder = MsgContent.newBuilder();
        MsgHeader.Builder headerBuilder = MsgHeader.newBuilder();
@@ -72,8 +71,17 @@
            log.error("Protobuf转JSON失败", e);
            throw new RuntimeException("Protobuf转JSON失败", e);
        }
        log.info("云端-->XPU 创建订单:{}", vo);
        return xpuClient.publish(vo);
        log.info("云端-->XPU 创建订单:{}", JSON.toJSONString(vo));
        try {
            MqttPublishDto dto = xpuClient.publish(vo);
            log.info("XPU返回:{}", JSON.toJSONString(dto));
            if(200 != dto.getCode()){
                dto = againPushMessage(vo);
            }
            return dto;
        }catch (Exception e){
            throw new RuntimeException("云端-->XPU 创建订单失败:", e);
        }
    }
@@ -82,7 +90,6 @@
     * @param operation
     * @return
     */
    //TODO 处理feign调用的异常
    public MqttPublishDto cloudOrderOperation(OrderOperation operation, String vin, Long sequence) {
        MsgContent.Builder msgContentBuilder = MsgContent.newBuilder();
        MsgHeader.Builder headerBuilder = MsgHeader.newBuilder();
@@ -105,9 +112,59 @@
            throw new RuntimeException("Protobuf转JSON失败", e);
        }
        log.info("云端-->XPU 修改订单:{}", vo);
        return xpuClient.publish(vo);
        try {
            MqttPublishDto dto = xpuClient.publish(vo);
            log.info("XPU返回:{}", JSON.toJSONString(dto));
            if(200 != dto.getCode()){
                dto = againPushMessage(vo);
            }
            return dto;
        }catch (Exception e){
            throw new RuntimeException("云端-->XPU 修改订单失败:", e);
        }
    }
    /**
     * 下发导航地址到车端
     *
     * @param navigationData
     * @return
     */
    public MqttPublishDto cloudPushNavigation(RestoreNavigationData navigationData, String xpuId, Long sequence) {
        MsgContent.Builder msgContentBuilder = MsgContent.newBuilder();
        MsgHeader.Builder headerBuilder = MsgHeader.newBuilder();
        headerBuilder.setMsgId(UUID.randomUUID().toString());
        headerBuilder.setTimestamp(System.currentTimeMillis());
        headerBuilder.setCmd(RTCmdType.CLOUD_NAVIGATION_RESPONSE.getValue());
        headerBuilder.setSequence(sequence);
        headerBuilder.setType(MessageType.MESSAGE_TYPE_RESPONSE);
        headerBuilder.setSource(SourceType.CLOUD);
        msgContentBuilder.setHeader(headerBuilder.build());
        msgContentBuilder.setRestoreNavigationData(navigationData);
        MqttPublishVo vo = new MqttPublishVo();
        vo.setTopic(buildTopicByXpuId(xpuId));
        try {
            vo.setPayload(jsonPrinter.print(msgContentBuilder.build()));
        } catch (Exception e) {
            log.error("Protobuf转JSON失败", e);
            throw new RuntimeException("Protobuf转JSON失败", e);
        }
        log.info("云端-->XPU 下发导航信息:{}", vo);
        try {
            MqttPublishDto dto = xpuClient.publish(vo);
            log.info("XPU返回:{}", JSON.toJSONString(dto));
            if(200 != dto.getCode()){
                dto = againPushMessage(vo);
            }
            return dto;
        }catch (Exception e){
            throw new RuntimeException("云端-->XPU 下发导航信息失败:", e);
        }
    }
@@ -141,38 +198,7 @@
        return xpuClient.publish(vo);
    }
    /**
     * 下发导航地址到车端
     *
     * @param navigationData
     * @return
     */
    //TODO 处理feign调用的异常
    public MqttPublishDto cloudPushNavigation(RestoreNavigationData navigationData, String xpuId, Long sequence) {
        MsgContent.Builder msgContentBuilder = MsgContent.newBuilder();
        MsgHeader.Builder headerBuilder = MsgHeader.newBuilder();
        headerBuilder.setMsgId(UUID.randomUUID().toString());
        headerBuilder.setTimestamp(System.currentTimeMillis());
        headerBuilder.setCmd(RTCmdType.CLOUD_NAVIGATION_RESPONSE.getValue());
        headerBuilder.setSequence(sequence);
        headerBuilder.setType(MessageType.MESSAGE_TYPE_RESPONSE);
        headerBuilder.setSource(SourceType.CLOUD);
        msgContentBuilder.setHeader(headerBuilder.build());
        msgContentBuilder.setRestoreNavigationData(navigationData);
        MqttPublishVo vo = new MqttPublishVo();
        vo.setTopic(buildTopicByXpuId(xpuId));
        try {
            vo.setPayload(jsonPrinter.print(msgContentBuilder.build()));
        } catch (Exception e) {
            log.error("Protobuf转JSON失败", e);
            throw new RuntimeException("Protobuf转JSON失败", e);
        }
        log.info("云端-->XPU 下发导航信息:{}", vo);
        return xpuClient.publish(vo);
    }
    /**
@@ -209,4 +235,26 @@
        return prefix + xpuId;
    }
    /**
     * 消息下发XPU重试机制
     * @param message
     * @return
     */
    public MqttPublishDto againPushMessage(MqttPublishVo message) {
        log.info("云端-->XPU 消息重试:{}", message);
        MqttPublishDto dto = null;
        for (int i = 0; i < 3; i++) {
            try {
                dto = xpuClient.publish(message);
                log.info("云端-->XPU 消息重试{}次:{}", (i+1), message);
                if (dto.getCode() == 200) {
                    break;
                }
            }catch (Exception e){
                log.error("云端-->XPU 推送失败:{}", message);
            }
        }
        return dto;
    }
}
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -375,6 +375,7 @@
        fareVo.setId(id);
        // 12. 设置费用信息
        fareVo.setFinalFareStr(fareVo.getFinalFare() + "");
        routeAndFareVo.setFareEstimate(fareVo);
@@ -383,6 +384,8 @@
        redisService.setCacheObject(key, voJsonStr, 5l, TimeUnit.MINUTES);
        //缓存导航数据,用于下单后推送导航给车端和乘客端
        redisService.setCacheObject("ORDER_NAVIGATION_END_DATA:" + userId, JSON.toJSONString(routeVo), 24L, TimeUnit.HOURS);
        return routeAndFareVo;
    }
@@ -407,13 +410,15 @@
        } else {
            // 已完成接单的数据
            List<XpGeoQueryEntity> validEntities = entities.stream().filter(e -> e.getStatus() == 1).collect(Collectors.toList());
            long waitNum = entities.stream().filter(e -> e.getStatus() == 0).count();
            // 计算平均等待时间
            OptionalDouble averageOptional = validEntities.stream().mapToDouble(XpGeoQueryEntity::getSeconds).average();
            if (averageOptional.isPresent()) {
                double average = averageOptional.getAsDouble();
                // 未完成接单的数量
                int count = entities.size() - validEntities.size();
                int count = (int) waitNum;
                if (count == 0) {
                    return 1;
                } else {
@@ -600,12 +605,13 @@
                String value = orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule();
                if (isPriorityDispatch) {
                    // 头部  value 订单_经纬度_状态_用户id_订单编号_距离_时间
//                    redisService.addToHead(s, orderId + "_" + xpPoint.getPointLon() + "," + xpPoint.getPointLat() + "_0" + "_" + uid + "_" + xpOrder.getOrderNumber() + "_" + distance + "_" + duration + "_" + routeAndFareDto.getRoutePlanRule());
                    redisService.addToHead(s, value);
                    log.info("添加到队列头部:{} {}", s, value);
                } else {
                    // 尾部
                    redisService.addToTail(s, value);
                    log.info("添加到队列尾部:{} {}", s, value);
                    log.info("添加到队列头部:{} {}", s, value);
                }
                xpOrder.setQueueName(s);
                xpOrderClient.updateOrder(xpOrder);
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpClockInServiceImpl.java
@@ -168,9 +168,9 @@
        xpClockIn.setClockOutLat(dto.getUserLat());
        xpClockIn.setClockOutAddress(dto.getClockOutAddress());
        if (xpClockIn.getClockOutTime().isBefore(endLocalDateTime)) {
            xpClockIn.setClockInResult(2);
            xpClockIn.setClockOutResult(2);
        } else {
            xpClockIn.setClockInResult(1);
            xpClockIn.setClockOutResult(1);
        }
        xpClockIn.setAppUserId(null);
        this.updateById(xpClockIn);
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpInvitationCodeController.java
@@ -19,6 +19,7 @@
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.log.annotation.Log;
import com.xiaopeng.common.log.enums.BusinessType;
import com.xiaopeng.operation.dto.InvitationAddDto;
import com.xiaopeng.operation.exportExcle.XpInvitationCodeExportExcel;
import com.xiaopeng.operation.exportExcle.XpWhitelistExportExcel;
import com.xiaopeng.operation.importExcel.InvitationCodeImportExcel;
@@ -76,15 +77,12 @@
    /**
     * 生成邀请码
     */
    @PutMapping("/api/v1/invitation/add")
    @PostMapping("/api/v1/invitation/add")
    @ResponseBody
    @ApiOperation(value = "生成邀请码")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "手机号 多个逗号隔开", name = "phones", dataType = "String", required = true)
    })
    @Transactional
    public R add(@RequestParam("phones") String phones){
        return xpInvitationCodeService.add(phones);
    public R add(@RequestBody InvitationAddDto dto){
        return xpInvitationCodeService.add(dto.getPhones());
    }
    /**
     * 解绑
@@ -217,7 +215,7 @@
        List<XpInvitationCodeExportExcel> xpWhitelistExportExcels = new ArrayList<>();
        for (XpInvitationCode xpInvitationCode : list) {
            XpInvitationCodeExportExcel xpWhitelistExportExcel = new XpInvitationCodeExportExcel();
            xpWhitelistExportExcel.setId(xpInvitationCode.getId());
//            xpWhitelistExportExcel.setId(xpInvitationCode.getId());
            xpWhitelistExportExcel.setBind_account(xpInvitationCode.getBindAccount());
            xpWhitelistExportExcel.setInvitationCode(xpInvitationCode.getInvitationCode());
            LocalDateTime createTime = xpInvitationCode.getCreateTime();
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java
@@ -141,6 +141,12 @@
    }
    @PostMapping("/inner/deleteXpGeoQueryEntity")
    public R<?> deleteXpGeoQueryEntity(@RequestParam String orderId){
        xpGeoQueryEntityService.deleteXpGeoQueryEntity(orderId);
        return R.ok();
    }
    /**
     * 播单
     */
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpWhitelistController.java
@@ -114,6 +114,9 @@
    @ApiOperation(value = "编辑白名单")
    @Transactional
    public R edit(@Validated @RequestBody WhitelistEditDto dto) {
        if (!StringUtils.hasLength(dto.getAccount())) {
            return R.fail("请输入账号");
        }
        SysUser sysUser = tokenService.getLoginUser().getSysUser();
        XpWhitelist xpWhitelist = new XpWhitelist();
        BeanUtils.copyProperties(dto, xpWhitelist);
@@ -224,7 +227,11 @@
            return AjaxResult.error("白名单手机号存在重复!");
        }
        Map<String, Long> codeMap = xpWhitelistService.list().stream()
                .collect(Collectors.toMap(XpWhitelist::getAccount, XpWhitelist::getId));
                .collect(Collectors.toMap(
                        XpWhitelist::getAccount,
                        XpWhitelist::getId,
                        (existing, replacement) -> replacement // 如果冲突,用新的覆盖
                ));
        JSONObject result = new JSONObject();
        List<XpWhitelist> addList = new ArrayList<>();
        for (WhitelistImportExcel whitelistImportExcel : whitelistImportExcels) {
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/exportExcle/XpInvitationCodeExportExcel.java
@@ -15,9 +15,9 @@
@Data
@ApiModel(value="邀请码导出")
public class XpInvitationCodeExportExcel {
    @ApiModelProperty(value = "序号")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "序号",width = 20)
    private Long id;
//    @ApiModelProperty(value = "序号")
//    @cn.afterturn.easypoi.excel.annotation.Excel(name = "序号",width = 20)
//    private Long id;
    @ApiModelProperty(value = "邀请码")
    @cn.afterturn.easypoi.excel.annotation.Excel(name = "用户名称",width = 20)
    private String invitationCode;
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/InvitationPageListQuery.java
@@ -5,6 +5,8 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel(value = "邀请码管理列表查询query")
public class InvitationPageListQuery extends BasePage {
@@ -14,5 +16,6 @@
    private String status;
    @ApiModelProperty(value = "绑定账号")
    private String bindAccount;
    @ApiModelProperty(value = "选择的id集合")
    private List<Long> ids;
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/query/WhitelistPageListQuery.java
@@ -5,6 +5,8 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel(value = "白名单管理列表查询query")
public class WhitelistPageListQuery extends BasePage {
@@ -14,5 +16,7 @@
    private Boolean status;
    @ApiModelProperty(value = "来源 1=添加 2=邀请码")
    private Integer whitelistSource;
    @ApiModelProperty(value = "选中的记录id集合")
    private List<Long> ids;
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpGeoQueryEntityService.java
@@ -54,4 +54,12 @@
     * @return 实体列表
     */
    List<XpGeoQueryEntity> findAll();
    /**
     * 删除
     * @param orderId
     */
    void deleteXpGeoQueryEntity(String orderId);
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpGeoQueryEntityServiceImpl.java
@@ -40,7 +40,7 @@
     */
    @Override
    public List<XpGeoQueryEntity> findByLocationWithin500MetersAndLastWeekAndStatusGreater(
            double longitude,
            double longitude,
            double latitude,
            String time
    ) {
@@ -105,7 +105,6 @@
    }
    @Override
    public XpGeoQueryEntity updateByOrderId(String orderId) {
        Query query = new Query(Criteria.where("orderId").is(orderId));
@@ -114,9 +113,9 @@
        Long timestamp = xpGeoQueryEntity.getTimestamp();
        long time = new Date().getTime();
        // 计算2个时间的秒数差
        long seconds = (time- timestamp) / 1000;
        long seconds = (time - timestamp) / 1000;
        Update update = new Update().set("seconds", seconds).set("status", 1);
        if(xpGeoQueryEntity.getStatus()==0){
        if (xpGeoQueryEntity.getStatus() == 0) {
            mongoTemplate.findAndModify(query, update, XpGeoQueryEntity.class);
        }
        return null;
@@ -150,4 +149,11 @@
    public List<XpGeoQueryEntity> findAll() {
        return repository.findAll();
    }
    @Override
    public void deleteXpGeoQueryEntity(String orderId) {
        Query query = new Query(Criteria.where("orderId").is(orderId));
        Update update = new Update().set("status", 2);
        mongoTemplate.findAndModify(query, update, XpGeoQueryEntity.class);
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPointServiceImpl.java
@@ -314,7 +314,7 @@
        }
        // 组装数据 并排序 剔除不在运营段的 数据
        List<XpPointsListVo> resultList = list.stream()
                .peek(vo -> vo.setDistance(BigDecimal.valueOf(FastDistanceCalculator.distanceFast(query.getLat(), query.getLon(), vo.getLatitude(), vo.getLongitude())).setScale(0, RoundingMode.HALF_UP).doubleValue()))
                .peek(vo -> vo.setDistance(BigDecimal.valueOf(FastDistanceCalculator.distanceFastKm(query.getLat(), query.getLon(), vo.getLatitude(), vo.getLongitude())).setScale(2, RoundingMode.HALF_UP).doubleValue()))
                .filter(vo -> vo.getState() == 1).collect(Collectors.toList());
        // 可用点位
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java
@@ -341,11 +341,11 @@
        }
        // 10. 检查等待时间
        Integer waitTime = getWaitTime(routeAndFareDto.getOrigin().getLongitude(), routeAndFareDto.getOrigin().getLatitude());
        if (waitTime > 3) {
            throw new ServiceException("当前区域正在等待中,请耐心等待", I18nKeyConstant.WAITING_TIME);
        }
        fareVo.setWaitingTime(waitTime);
//        Integer waitTime = getWaitTime(routeAndFareDto.getOrigin().getLongitude(), routeAndFareDto.getOrigin().getLatitude());
//        if (waitTime > 3) {
//            throw new ServiceException("当前区域正在等待中,请耐心等待", I18nKeyConstant.WAITING_TIME);
//        }
//        fareVo.setWaitingTime(waitTime);
        // 11. 生成订单ID并缓存
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpWhitelistServiceImpl.java
@@ -51,7 +51,6 @@
    @Override
    public List<XpWhitelist> exportList(WhitelistPageListQuery query) {
        List<XpWhitelist> list = this.baseMapper.exportList(query);
        return list;
    }
@@ -99,6 +98,13 @@
        if (!PhoneUtil.isPhone(dto.getAccount())) {
            throw new ServiceException("以下帐号格式不正确:", I18nKeyConstant.ACCOUNT_FORMAT_ERROR, new Object[]{dto.getAccount()});
        }
        XpWhitelist old = this.lambdaQuery()
                .eq(XpWhitelist::getAccount, dto.getAccount())
                .ne(XpWhitelist::getId, dto.getId())
                .last("limit 1").one();
        if (old != null) {
            return R.fail("该账号已存在");
        }
        XpWhitelist whitelist = this.getById(dto.getId());
        StringBuilder operationContent = new StringBuilder("编辑账号:");
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/task/TaskUtil.java
@@ -49,6 +49,7 @@
                        .in(XpPoint::getElectronicAreaId, areaIds)
                        .list();
                for (XpPoint xpPoint : xpPoints) {
                    xpPoint.setElectronicAreaId(null);
                    xpPoint.setOperationStatus(4);
                }
                xpPointService.updateBatchById(xpPoints);
@@ -68,6 +69,7 @@
                        .in(XpPoint::getElectronicAreaId, areaIds)
                        .list();
                for (XpPoint xpPoint : xpPoints) {
                    xpPoint.setElectronicAreaId(null);
                    xpPoint.setOperationStatus(4);
                }
                xpPointService.updateBatchById(xpPoints);
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/OssUtil.java
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpInvitationCodeMapper.xml
@@ -36,6 +36,12 @@
        <if test="query.bindAccount != null and query.bindAccount != ''">
            and bind_account like concat('%',#{query.bindAccount},'%')
        </if>
        <if test="query.ids != null and query.ids.size()>0">
            and id in
            <foreach item="item" collection="query.ids" separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
        ORDER BY create_time DESC
    </select>
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpWhitelistMapper.xml
@@ -36,6 +36,12 @@
        <if test="query.whitelistSource != null">
            and whitelist_source = #{query.source}
        </if>
        <if test="query.ids != null and query.ids.size()>0">
            and id in
            <foreach item="item" collection="query.ids" separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
        order by create_time desc
    </select>
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpCruiseOrderServiceImpl.java
@@ -118,7 +118,7 @@
    private final XpVehicleClient xpVehicleClient;
    private final XpFleetVehicleClient xpFleetVehicleClient;
    private final XpFleetClient xpFleetClient;
    private final OrderMissionClient orderMissionClient;
    /**
     * 关闭当前巡游单子
     * @param vin
@@ -130,6 +130,21 @@
        if (xpCruiseOrder != null) {
            xpCruiseOrder.setStatus(2);
            this.update(xpCruiseOrder, wrapper);
            // todo 给XPU下发订单取消报文,如果取消不成功需要重试。两次不成功,则需要换车
            PushOrderDto pushOrderDto = new PushOrderDto();
            pushOrderDto.setVin(vin);
            pushOrderDto.setOrderId(xpCruiseOrder.getId());
            pushOrderDto.setOperation_type(OrderOperationType.VEHICLE_CANCEL_ORDER);
            R<Boolean> booleanR = orderMissionClient.cancelOrder(pushOrderDto);
            if(booleanR==null || !booleanR.getData()){
                log.error("下发失败重试一次");
                R<Boolean> booleanR1 = orderMissionClient.cancelOrder(pushOrderDto);
                if(booleanR1==null || !booleanR1.getData()){
                    log.error("换车");
                    return null;
                }
            }
            return xpCruiseOrder.getId();
        }
        return null;
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -1019,6 +1019,24 @@
            redisService.setCacheCancelOrder("CANCEL_ORDER_" + uid, i + 1);
        }
        // 消息推送
        Map<String, Object> params = new HashMap<>();
        Map<String, Object> content = new HashMap<>();
        content.put("orderId", order.getId().toString());
        content.put("status", OrderStatusEnum.CANCELED.getCode());
        params.put("type", PushMessageTypeEnum.ORDER_STATUS.getDesc());
        params.put("content", com.alibaba.fastjson2.JSONObject.toJSONString(content));
        params.put("timestamp", new Date().getTime() + "");
        String message = JSONObject.toJSONString(params);
        SendMessageDTO sendMessageDTO = new SendMessageDTO();
        sendMessageDTO.setMessage(message);
        sendMessageDTO.setAppUserId(String.valueOf(order.getAppUserId()));
        xpPushMessageClient.sendStatus(sendMessageDTO);
        log.info("订单取消消息推送完毕");
        // 移除mongo数据
        xpPricingClient.deleteXpGeoQueryEntity(order.getId().toString());
        // 下发命令
        if (order.getStatus() > 1) {
            PushOrderDto pushOrderDto = new PushOrderDto();
@@ -1067,6 +1085,9 @@
        sendMessageDTO.setAppUserId(String.valueOf(order.getAppUserId()));
        xpPushMessageClient.sendStatus(sendMessageDTO);
        log.info("订单取消消息推送完毕");
        // 移除mongo数据
        xpPricingClient.deleteXpGeoQueryEntity(order.getId().toString());
        // 下发命令
        if (order.getStatus() > 1) {
@@ -1198,7 +1219,7 @@
        order.setStatus(8);
        order.setAppUserId(null);
        order.setTripEnd(LocalDateTime.now());
        order.setMileageKilometers(80.0);
//        order.setMileageKilometers(80.0);
        baseMapper.updateById(order);
        // 解绑用户与车辆关系
        CancelTaxiPassengerVo cancelTaxiPassengerVo = new CancelTaxiPassengerVo();
@@ -2089,10 +2110,13 @@
                // Redis弹出这个队列元素
                // value 订单Id_经纬度_状态_用户id_订单编号_距离_时间
                String popFirstElement = redisService.popFirstElement(order.getQueueName());
                try {
                    redisService.popFirstElement(order.getQueueName());
                }catch (Exception e){
                    log.error("Redis弹出队列元素出错");
                }
                XpGeoQueryEntity xpGeoQueryEntity = new XpGeoQueryEntity();
                String[] split = popFirstElement.split("_");
                xpGeoQueryEntity.setOrderId(split[0]);
                xpGeoQueryEntity.setOrderId(order.getId().toString());
                // 存mongo数据
                xpPricingClient.updateXpGeoQueryEntity(order.getId().toString());
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/controller/PushOrderRouteController.java
@@ -51,7 +51,7 @@
        if(routeType == 2){
            routeType = 3;
        }else {
            routeType = xpOrder.getStatus() == 3 ? 1 : 2;
            routeType = xpOrder.getStatus() == 2 || xpOrder.getStatus() == 3 ? 1 : 2;
        }
        // 获取路线规划
        String key = "";