无关风月
2026-02-13 65dcb2917a3b68e19351878e1d93f0b0ecb83cb5
Merge remote-tracking branch 'origin/master'

# Conflicts:
# xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpElectronicFenceServiceImpl.java
1 文件已重命名
11个文件已添加
41个文件已修改
877 ■■■■■ 已修改文件
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsUserMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpOperationsUserPageQuery.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpOperationsUserService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/MqttPublishDto.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/PushOrderDto.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/order/PopOrderDto.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/automatic/OrderMissionClientFallbackFactory.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/automaticPilot/XPUClientFallbackFactory.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPricingClientFallbackFactory.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/automatic/OrderMissionClient.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/automaticPilot/XPUClient.java 25 ●●●●● 补丁 | 查看 | 原始文档 | 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/feignClient/order/XpOrderClient.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/vehicleConvoy/XpVehicleClient.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpGeoQueryEntity.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/MqttPublishVo.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/RTTask.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/XPUUtil.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/dto/ServiceNameConstantsEnum.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/SnowFlake.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-common/xp-common-redis/src/main/java/com/xiaopeng/common/redis/service/RedisService.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpErrorTypeServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpElectronicFenceController.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpGeoQueryEntityController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/repository/XpGeoQueryEntityRepository.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpElectronicFenceService.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpGeoQueryEntityService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpElectronicFenceServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpGeoQueryEntityServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/mapper/XpVehicleMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/VehicleSelectPageQuery.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/XpVehicleAnnualRecordPageQuery.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/FleetDetailVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/FleetPageVO.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/IXpVehicleService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicleConvoy-boot/src/main/resources/mapper/vehicleConvoy/XpVehicleMapper.xml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java
@@ -2,11 +2,13 @@
import com.xiaopeng.account.mapper.XpOperationsRoleMapper;
import com.xiaopeng.account.model.query.XpOperationsUserPageQuery;
import com.xiaopeng.account.service.IXpOperationsUserService;
import com.xiaopeng.api.dto.account.XpOperationsUserQueryDTO;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
@@ -98,17 +100,12 @@
    /**
     * 根据条件查询用户及角色信息
     * @param dto 查询条件
     * @param query 查询条件
     * @return 用户及角色信息列表
     */
    @ApiOperation(value = "根据条件查询用户不分页列表", tags = {"管理后台-车队管理"})
    @ApiOperation(value = "根据条件查询用户分页列表", tags = {"管理后台-车队管理"})
    @PostMapping("/api/v1/xpOperationsUser/queryByConditions")
    public R<List<XpOperationsUserWithRoleVO>> getList(@RequestBody XpOperationsUserQueryDTO dto) {
        List<XpOperationsUserWithRoleVO> result = xpOperationsRoleMapper.selectUsersByConditions(
                dto.getNickName(),
                dto.getPhoneNumber(),
                dto.getRoleId()
        );
        return R.ok(result);
    public R<PageInfo<XpOperationsUserWithRoleVO>> getList(@RequestBody XpOperationsUserPageQuery query) {
        return R.ok(xpOperationsUserService.selectUserPageByConditions(query));
    }
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsUserMapper.java
@@ -1,7 +1,11 @@
package com.xiaopeng.account.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaopeng.account.model.query.XpOperationsUserPageQuery;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO;
import org.apache.ibatis.annotations.Param;
/**
 * <p>
@@ -12,5 +16,11 @@
 * @since 2026-02-03
 */
public interface XpOperationsUserMapper extends BaseMapper<XpOperationsUser> {
    /**
     * 查询带角色信息的运维用户分页列表
     * @param xpOperationsUserWithRoleVOPage
     * @param query
     * @return
     */
    Page<XpOperationsUserWithRoleVO> selectUserPageByConditions(Page<XpOperationsUserWithRoleVO> xpOperationsUserWithRoleVOPage, @Param("query") XpOperationsUserPageQuery query);
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/model/query/XpOperationsUserPageQuery.java
New file
@@ -0,0 +1,25 @@
package com.xiaopeng.account.model.query;
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * 运维人员查询条件DTO
 *
 * @author mitao
 */
@Data
@ApiModel("运维人员查询条件DTO")
public class XpOperationsUserPageQuery extends BasePage {
    @ApiModelProperty(value = "姓名(模糊查询)")
    private String nickName;
    @ApiModelProperty(value = "手机号(模糊查询)")
    private String phoneNumber;
    @ApiModelProperty(value = "角色ID(精确查询)")
    private Long roleId;
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/IXpOperationsUserService.java
@@ -1,7 +1,10 @@
package com.xiaopeng.account.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.account.model.query.XpOperationsUserPageQuery;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO;
import com.xiaopeng.common.core.web.page.PageInfo;
import java.util.List;
@@ -20,4 +23,11 @@
     * @return
     */
    List<XpOperationsUser> listByName(String nickName);
    /**
     * 根据条件查询用户及角色信息
     * @param query
     * @return
     */
    PageInfo<XpOperationsUserWithRoleVO> selectUserPageByConditions(XpOperationsUserPageQuery query);
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java
@@ -1,9 +1,13 @@
package com.xiaopeng.account.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaopeng.account.mapper.XpOperationsUserMapper;
import com.xiaopeng.account.model.query.XpOperationsUserPageQuery;
import com.xiaopeng.account.service.IXpOperationsUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO;
import com.xiaopeng.common.core.web.page.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
@@ -27,4 +31,13 @@
        }
        return lambdaQuery().like(XpOperationsUser::getNickName, nickName).list();
    }
    @Override
    public PageInfo<XpOperationsUserWithRoleVO> selectUserPageByConditions(XpOperationsUserPageQuery query) {
        Page<XpOperationsUserWithRoleVO> page = baseMapper.selectUserPageByConditions(new Page<>(query.getPageNum(), query.getPageSize()), query);
        PageInfo<XpOperationsUserWithRoleVO> pageInfo = new PageInfo<>();
        pageInfo.setRecords(page.getRecords());
        pageInfo.setTotal(page.getTotal());
        return pageInfo;
    }
}
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml
@@ -6,5 +6,26 @@
    <sql id="Base_Column_List">
        id, nick_name, unique_number, avatar, password, phone_number, remarks, status, id_card_front, id_card_back, driver_license, certificate_of_no_criminal_record, training_graduation_certificate, is_deleted, create_time, update_time, create_by, update_by
    </sql>
    <select id="selectUserPageByConditions"
            resultType="com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO">
        SELECT
        u.*,
        r.id AS roleId,
        r.role_name AS roleName
        FROM xp_operations_user u
        LEFT JOIN xp_operations_role ur ON u.id = ur.operations_user_id
        LEFT JOIN sys_role r ON ur.role_id = r.id AND r.is_deleted = 0
     <where>
        <if test="query.nickName != null and query.nickName != ''">
            AND u.nick_name LIKE CONCAT('%', #{query.nickName}, '%')
        </if>
        <if test="query.phoneNumber != null and query.phoneNumber != ''">
            AND u.phone_number LIKE CONCAT('%', #{query.phoneNumber}, '%')
        </if>
        <if test="query.roleId != null">
            AND r.id = #{query.roleId}
        </if>
     </where>
    </select>
</mapper>
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/MqttPublishDto.java
New file
@@ -0,0 +1,19 @@
package com.xiaopeng.api.dto.automaticPilot;
import lombok.Data;
@Data
public class MqttPublishDto {
    /**
     * 状态码
     */
    private Integer code;
    /**
     * 状态信息
     */
    private String msg;
    /**
     * 数据
     */
    private Object data;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/PushOrderDto.java
New file
@@ -0,0 +1,16 @@
package com.xiaopeng.api.dto.automaticPilot;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("推送订单Dto")
public class PushOrderDto {
    @ApiModelProperty("车辆vin")
    private String vin;
    // 订单id
    @ApiModelProperty("订单id")
    private Long orderId;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/order/PopOrderDto.java
New file
@@ -0,0 +1,18 @@
package com.xiaopeng.api.dto.order;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "订单成功下发命令信息")
public class PopOrderDto {
    @ApiModelProperty(value = "订单Id")
    private Long orderId;
    @ApiModelProperty(value = "车辆Vin")
    private String xpVehicleVin;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/automatic/OrderMissionClientFallbackFactory.java
New file
@@ -0,0 +1,24 @@
package com.xiaopeng.api.factory.automatic;
import com.xiaopeng.api.feignClient.automatic.OrderMissionClient;
import com.xiaopeng.api.feignClient.maintenance.XpChargingRecordClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
 * 车辆整备Feign客户端降级工厂
 *
 * @author mitao
 * @since 2026-02-11
 */
@Slf4j
@Component
public class OrderMissionClientFallbackFactory implements FallbackFactory<OrderMissionClient> {
    @Override
    public OrderMissionClient create(Throwable cause) {
        return new OrderMissionClient() {
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/automaticPilot/XPUClientFallbackFactory.java
New file
@@ -0,0 +1,22 @@
package com.xiaopeng.api.factory.automaticPilot;
import com.xiaopeng.api.dto.automaticPilot.MqttPublishDto;
import com.xiaopeng.api.feignClient.automaticPilot.XPUClient;
import com.xiaopeng.api.vo.automaticPilot.MqttPublishVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;
@Slf4j
public class XPUClientFallbackFactory implements FallbackFactory<XPUClient> {
    @Override
    public XPUClient create(Throwable cause) {
        return new XPUClient(){
            @Override
            public MqttPublishDto publish(MqttPublishVo vo) {
                log.error("推送XPU-MQTT消息失败: {}", cause.getMessage());
                return null;
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/operation/XpPricingClientFallbackFactory.java
@@ -4,6 +4,7 @@
import com.xiaopeng.api.dto.order.HistoryStartPointsDto;
import com.xiaopeng.api.feignClient.operation.XpPointClient;
import com.xiaopeng.api.feignClient.operation.XpPricingClient;
import com.xiaopeng.api.model.operation.XpGeoQueryEntity;
import com.xiaopeng.api.model.operation.XpPricing;
import com.xiaopeng.api.vo.order.XpHistoryStartPointsVo;
import com.xiaopeng.common.core.domain.R;
@@ -31,6 +32,12 @@
                log.error("根据开通城市获取定价失败", cause);
                return R.ok(null);
            }
            @Override
            public R<?> saveXpGeoQueryEntity(XpGeoQueryEntity xpGeoQueryEntity) {
                log.error("保存XpGeoQueryEntity失败", cause);
                return R.fail();
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/order/XpOrderClientFallbackFactory.java
@@ -1,6 +1,7 @@
package com.xiaopeng.api.factory.order;
import com.xiaopeng.api.dto.order.GetOrderNumDto;
import com.xiaopeng.api.dto.order.PopOrderDto;
import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO;
import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO;
import com.xiaopeng.api.feignClient.order.XpOrderClient;
@@ -75,6 +76,12 @@
                log.error("获取订单数量失败,原因: {}", cause.getMessage());
                return R.fail();
            }
            @Override
            public R<?> popOrder(PopOrderDto dto) {
                log.error("订单出队失败,原因: {}", cause.getMessage());
                return R.fail();
            }
        };
    }
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/automatic/OrderMissionClient.java
New file
@@ -0,0 +1,36 @@
package com.xiaopeng.api.feignClient.automatic;
import com.xiaopeng.api.dto.account.XpOperationsUserQueryDTO;
import com.xiaopeng.api.dto.automaticPilot.PushOrderDto;
import com.xiaopeng.api.factory.account.XpAppUserClientFallbackFactory;
import com.xiaopeng.api.factory.automatic.OrderMissionClientFallbackFactory;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum;
import org.springframework.cloud.openfeign.FeignClient;
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;
/**
 * 小程序用户Feign客户端
 *
 * @author mitao
 */
@FeignClient(contextId = "OrderMissionClient",
        value = ServiceNameConstantsEnum.XP_AUTOMATIC_PILOT_SERVICE,
        fallbackFactory = OrderMissionClientFallbackFactory.class)
public interface OrderMissionClient {
    /**
     * 下发命令
     * @param
     * @return
     */
    @PostMapping("/inner/pushOrder")
     R<Boolean> pushOrder(@RequestBody PushOrderDto dto);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/automaticPilot/XPUClient.java
New file
@@ -0,0 +1,25 @@
package com.xiaopeng.api.feignClient.automaticPilot;
import com.xiaopeng.api.dto.automaticPilot.MqttPublishDto;
import com.xiaopeng.api.factory.automaticPilot.XPUClientFallbackFactory;
import com.xiaopeng.api.vo.automaticPilot.MqttPublishVo;
import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(contextId = "XPUClient",
        value = ServiceNameConstantsEnum.XP_MQTT_ROUTER_THIRDPARTY_BOOT,
        fallbackFactory = XPUClientFallbackFactory.class)
public interface XPUClient {
    /**
     * 推送MQTT消息
     * @param vo
     */
    @PostMapping("/logan/mqtt/publish")
    MqttPublishDto publish(@RequestBody MqttPublishVo vo);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/operation/XpPricingClient.java
@@ -3,6 +3,7 @@
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.factory.operation.XpPricingClientFallbackFactory;
import com.xiaopeng.api.model.operation.XpGeoQueryEntity;
import com.xiaopeng.api.model.operation.XpPricing;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum;
@@ -18,7 +19,16 @@
     */
    @PostMapping("/base/v1/mini-program/pricing/getWaitTime")
    R<Integer> getWaitTime(@RequestBody LonLatDto dto);
    // 根据开通城市 获取定价
    @GetMapping("/base/v1/mini-program/getPricingByCityId/{cityId}")
     R<XpPricing> getPricingByCityId(@PathVariable("cityId")Long cityId);
    /**
     * 保存XpGeoQueryEntity
     */
    @PostMapping("/inner/saveXpGeoQueryEntity")
    R<?> saveXpGeoQueryEntity(@RequestBody XpGeoQueryEntity xpGeoQueryEntity);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/order/XpOrderClient.java
@@ -1,6 +1,7 @@
package com.xiaopeng.api.feignClient.order;
import com.xiaopeng.api.dto.order.GetOrderNumDto;
import com.xiaopeng.api.dto.order.PopOrderDto;
import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO;
import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO;
import com.xiaopeng.api.factory.order.XpOrderClientFallbackFactory;
@@ -84,4 +85,10 @@
    R<Integer> getOrderNum(@RequestBody GetOrderNumDto dto);
    /**
     * 成功操作下发命令后调用 用于弹出redis队列的获取成功的数据
     */
    @PostMapping("/inner/order/popOrder")
    R<?> popOrder(@RequestBody PopOrderDto dto);
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/vehicleConvoy/XpVehicleClient.java
@@ -3,8 +3,6 @@
import com.xiaopeng.api.dto.operation.VehiclePositionByVinDto;
import com.xiaopeng.api.factory.vehicleConvoy.XpVehicleClientFallbackFactory;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
import com.xiaopeng.api.vo.operation.VehiclePositionVo;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.dto.ServiceNameConstantsEnum;
import org.springframework.cloud.openfeign.FeignClient;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/operation/XpGeoQueryEntity.java
File was renamed from xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/entity/XpGeoQueryEntity.java
@@ -1,4 +1,4 @@
package com.xiaopeng.operation.entity;
package com.xiaopeng.api.model.operation;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/MqttPublishVo.java
New file
@@ -0,0 +1,15 @@
package com.xiaopeng.api.vo.automaticPilot;
import lombok.Data;
@Data
public class MqttPublishVo {
    /**
     * 消息内容
     */
    private String payload;
    /**
     * Mqtt topic
     */
    private String topic;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/automaticPilot/proto/down/cloudCreateOrder/RTTask.java
@@ -17,6 +17,10 @@
     */
    private String order_id;
    /**
     * 车辆vin
     */
    private String vin;
    /**
     * 导航点列表
     */
    private List<NavigationWaypoint> points;
xp-robotaxi-api/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -21,4 +21,5 @@
com.xiaopeng.api.factory.vehicleConvoy.XpFleetOperationsClientFallbackFactory
com.xiaopeng.api.factory.pushMessage.XpPushMessageClientFallbackFactory
com.xiaopeng.api.factory.account.UserResourcesClientFallbackFactory
com.xiaopeng.api.factory.vehicleConvoy.VehicleControlClientFallbackFactory
com.xiaopeng.api.factory.vehicleConvoy.VehicleControlClientFallbackFactory
com.xiaopeng.api.factory.automaticPilot.XPUClientFallbackFactory
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/controller/OrderMissionController.java
@@ -1,5 +1,8 @@
package com.xiaopeng.automaticPilot.controller;
import cn.hutool.core.util.IdUtil;
import com.xiaopeng.api.dto.automaticPilot.MqttPublishDto;
import com.xiaopeng.api.dto.automaticPilot.PushOrderDto;
import com.xiaopeng.api.vo.automaticPilot.proto.down.ResponseMessage;
import com.xiaopeng.api.vo.automaticPilot.proto.down.StatusCode;
import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudCreateOrder.RTTask;
@@ -7,12 +10,13 @@
import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudCreateOrder.TaskType;
import com.xiaopeng.automaticPilot.util.XPUUtil;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.utils.SnowFlake;
import com.xiaopeng.common.redis.service.RedisService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.concurrent.TimeUnit;
@Slf4j
@RestController
@@ -22,24 +26,28 @@
    private final XPUUtil xpuUtil;
    private final RedisService redisService;
    public OrderMissionController(XPUUtil xpuUtil) {
    public OrderMissionController(XPUUtil xpuUtil, RedisService redisService) {
        this.xpuUtil = xpuUtil;
        this.redisService = redisService;
    }
    @PostMapping("/inner/pushOrder")
    public R<Boolean> pushOrder(@RequestParam Long orderId) {
    @PostMapping("/inner/pushOrder")
    public R<Boolean> pushOrder(@RequestBody PushOrderDto dto) {
        RTTask task = new RTTask();
        task.setOrder_id(orderId.toString());
        // TODO id处理 已经数据是否存储
        task.setTask_id(System.currentTimeMillis()+ "");
        task.setOrder_id(dto.getOrderId().toString());
        task.setTask_id("MISSION_"+ IdUtil.fastUUID());
        task.setTask_type(TaskType.ROBOTAXI);
        task.setStatus(TaskStatus.PENDING);
        ResponseMessage responseMessage = xpuUtil.cloudCreateOrder(task);
        if (responseMessage.getCode()== StatusCode.OK) {
        SnowFlake snowFlake = new SnowFlake(0, 0);
        snowFlake.withStartTimestamp(1420041600000L);
        long sequence = snowFlake.nextId();
        MqttPublishDto mqttPublishDto = xpuUtil.cloudCreateOrder(task, dto.getVin(),sequence);
        if (mqttPublishDto.getCode()== 200) {
            return R.ok(true);
        }
        return R.ok(false);
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/service/KafkaConsumerService.java
@@ -6,6 +6,7 @@
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.api.dto.map.OrderRouteAndFareDto;
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.dto.order.PopOrderDto;
import com.xiaopeng.api.dto.pushMessage.PushOrderRouteDTO;
import com.xiaopeng.api.dto.pushMessage.SendMessageDTO;
import com.xiaopeng.api.feignClient.map.XpMapClient;
@@ -35,6 +36,7 @@
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.enums.OrderStatusEnum;
import com.xiaopeng.common.core.enums.PushMessageTypeEnum;
import com.xiaopeng.common.core.utils.SnowFlake;
import com.xiaopeng.common.core.utils.StringUtils;
import com.xiaopeng.common.core.utils.uuid.UUID;
import com.xiaopeng.common.redis.service.RedisService;
@@ -49,6 +51,7 @@
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
 * Kafka 消费者服务
@@ -77,6 +80,7 @@
    @Resource
    private XpPushMessageClient xpPushMessageClient;
    /**
@@ -159,6 +163,17 @@
            com.xiaopeng.api.vo.automaticPilot.proto.up.StatusCode code = resposne.getCode();
            Long requestSeq = resposne.getRequest_seq();
            if(code == com.xiaopeng.api.vo.automaticPilot.proto.up.StatusCode.OK){
                Object sequence = redisTemplate.opsForValue().get(requestSeq);
                if(sequence!=null){
                    String[] split = sequence.toString().split("_");
                    if(split[0].equals("pushOrder")){
                        PopOrderDto dto = new PopOrderDto();
                        dto.setOrderId(Long.valueOf(split[1]));
                        dto.setXpVehicleVin(split[2]);
                        xpOrderClient.popOrder(dto);
                    }
                }
            }
        }
@@ -247,9 +262,6 @@
     * @param msgContent
     */
    public void systemStatusXpu(MsgContent msgContent) {
        //先响应消息
        Long sequence = msgContent.getHeader().getSequence();
        responseMessage(sequence);
        //开始处理消息对应的业务逻辑
        SystemRuntimeStatus systemRuntimeStatus = msgContent.getContent_detail().getObject("systemRuntimeStatus", SystemRuntimeStatus.class);
        //获取实时位姿
@@ -262,6 +274,10 @@
        //获取车辆静态信息
        VehicleStaticInfo staticInfo = systemRuntimeStatus.getVehicle_status().getStatic_info();
        String vin = staticInfo.getVin();
        //先响应消息
        Long sequence = msgContent.getHeader().getSequence();
        responseMessage(sequence, vin);
        //保存车辆实时位置到redis
        redisTemplate.opsForGeo().add("vehiclePosition:" + vin, new GeoJsonPoint(longitude, latitude), vin);
        //保存车辆实时信息到mongodb
@@ -314,9 +330,6 @@
     * @param msgContent
     */
    public void xpuNavigationRequest(MsgContent msgContent) {
        //先响应消息
        Long sequence = msgContent.getHeader().getSequence();
        responseMessage(sequence);
        //开始处理消息对应的业务逻辑
        NavigationRequest naviRequest = msgContent.getContent_detail().getObject("naviRequest", NavigationRequest.class);
        String orderId = naviRequest.getOrder_id();
@@ -330,15 +343,15 @@
                break;
            case ROUTE_TO_PICKUP:
                log.info("驶往上车点的行程");
                buildNaviRequest(orderId, taskId, orderPhase);
                buildNaviRequest(orderId, taskId, orderPhase, msgContent.getHeader().getSequence());
                break;
            case ROUTE_TO_DESTINATION:
                log.info("驶往下车点的行程");
                buildNaviRequest(orderId, taskId, orderPhase);
                buildNaviRequest(orderId, taskId, orderPhase, msgContent.getHeader().getSequence());
                break;
            case ROUTE_TO_CRUISE:
                log.info("巡游阶段路线");
                buildNaviRequest(orderId, taskId, orderPhase);
                buildNaviRequest(orderId, taskId, orderPhase, msgContent.getHeader().getSequence());
                break;
        }
    }
@@ -352,7 +365,6 @@
    public void navigationDeviationEvent(MsgContent msgContent) {
        //先响应消息
        Long sequence = msgContent.getHeader().getSequence();
        responseMessage(sequence);
        //开始处理消息对应的业务逻辑
        NavigationDeviationEvent deviationEvent = msgContent.getContent_detail().getObject("deviationEvent", NavigationDeviationEvent.class);
        //偏航事件类型 1:请求导航,2:取消导航
@@ -374,6 +386,8 @@
                origin.setLatitude(latitude);
                destination.setLongitude(116.40528);
                destination.setLatitude(39.90498);
                //响应消息
                responseMessage(sequence, "");
            } else {
                //正常单
                R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(Long.parseLong(orderId));
@@ -381,6 +395,9 @@
                    throw new RuntimeException("订单不存在");
                }
                XpOrder xpOrder = xpOrderR.getData();
                XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
                //响应消息
                responseMessage(sequence, xpVehicle.getVehicleVin());
                //驶往上车点的行程
                if (Arrays.asList(3).contains(xpOrder.getStatus())) {
                    //查询司机当前位置到起点的线路
@@ -407,7 +424,7 @@
                }
                RouteVo routeVo = routeVoR.getData();
                //构建导航下发请求对象
                cloudOrderOperation(orderType, orderId, taskId, routeVo);
                cloudOrderOperation(orderType, orderId, taskId, routeVo, xpVehicle.getVehicleVin());
            }
        }
    }
@@ -420,7 +437,7 @@
     * @param taskId
     * @param orderPhase
     */
    public void buildNaviRequest(String orderId, String taskId, OrderPhase orderPhase) {
    public void buildNaviRequest(String orderId, String taskId, OrderPhase orderPhase, Long sequence) {
        //订单类型  1:乘客订单,2=巡游订单
        Integer orderType = 1;
        LonLatDto destination = new LonLatDto();
@@ -434,6 +451,9 @@
                origin.setLatitude(39.90498);
                destination.setLongitude(116.40528);
                destination.setLatitude(39.90498);
                //先响应消息
                responseMessage(sequence, "");
            }
        } else {
            //正常单
@@ -445,6 +465,9 @@
            //驶往上车点的行程
            if (orderPhase.equals(OrderPhase.ROUTE_TO_PICKUP)) {
                XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
                //先响应消息
                responseMessage(sequence, xpVehicle.getVehicleVin());
                //查询车辆位置
                VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(xpVehicle.getVehicleVin())), VehiclePosition.class);
                if (Objects.isNull(vehiclePosition)) {
                    throw new RuntimeException("车辆位置信息不存在");
@@ -471,9 +494,10 @@
            if (200 != routeVoR.getCode()) {
                throw new RuntimeException("获取订单线路和运费失败");
            }
            XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
            RouteVo routeVo = routeVoR.getData();
            //构建导航下发请求对象
            cloudOrderOperation(orderType, orderId, taskId, routeVo);
            cloudOrderOperation(orderType, orderId, taskId, routeVo, xpVehicle.getVehicleVin());
        }
    }
@@ -483,7 +507,7 @@
     *
     * @param routeVo
     */
    public void cloudOrderOperation(Integer orderType, String orderId, String taskId, RouteVo routeVo) {
    public void cloudOrderOperation(Integer orderType, String orderId, String taskId, RouteVo routeVo, String vin) {
        //构建消息体
        OrderOperation orderOperation = new OrderOperation();
        orderOperation.setOrder_id(orderId);
@@ -518,20 +542,25 @@
            waypoints.add(waypoint);
        }
        orderOperation.setWaypoints(waypoints);
        SnowFlake snowFlake = new SnowFlake(0, 0);
        snowFlake.withStartTimestamp(1420041600000L);
        long sequence = snowFlake.nextId();
        // 处理数据
        redisTemplate.opsForValue().set(sequence,"pushOrder_"+orderId+"_"+vin,30, TimeUnit.MINUTES);
        //开发发送请求到XPU
        xpuUtil.cloudOrderOperation(orderOperation);
        xpuUtil.cloudOrderOperation(orderOperation, vin,sequence);
    }
    /**
     * 构建响应消息
     */
    public void responseMessage(Long request_seq) {
    public void responseMessage(Long request_seq, String vin) {
        ResponseMessage responseMessage = new ResponseMessage();
        responseMessage.setRequest_seq(request_seq);
        responseMessage.setCode(StatusCode.OK);
        responseMessage.setTimestamp(System.currentTimeMillis());
        xpuUtil.responseMessage(responseMessage);
        xpuUtil.responseMessage(responseMessage, vin);
    }
@@ -542,7 +571,6 @@
    public void orderStateUpdateEvent(MsgContent msgContent) {
        //先响应消息
        Long sequence = msgContent.getHeader().getSequence();
        responseMessage(sequence);
        //开始处理消息对应的业务逻辑
        OrderStatusInfoEvent orderStatusInfoEvent = msgContent.getContent_detail().getObject("orderStatusInfoEvent", OrderStatusInfoEvent.class);
        //只处理请求消息
@@ -558,7 +586,7 @@
                    break;
                case ORDER_RECEIVED:
                    //收到订单
                    buildPushOrderStatus(orderId, OrderStatusEnum.READY_DEPART);
                    buildPushOrderStatus(orderId, OrderStatusEnum.READY_DEPART, sequence);
                    break;
                case ORDER_STARTED:
                    //开始执行订单
@@ -566,7 +594,7 @@
                    break;
                case ORDER_EN_ROUTE_TO_PICKUP:
                    //前往上车点
                    buildPushOrderStatus(orderId, OrderStatusEnum.PICK_UP);
                    buildPushOrderStatus(orderId, OrderStatusEnum.PICK_UP, sequence);
                    break;
                case ORDER_ARRIVED_AT_PICKUP:
                    //到达上车点
@@ -574,15 +602,15 @@
                    break;
                case ORDER_WAITING_FOR_PICKUP:
                    //等待乘客上车
                    buildPushOrderStatus(orderId, OrderStatusEnum.PICK_UP_GUESTS);
                    buildPushOrderStatus(orderId, OrderStatusEnum.PICK_UP_GUESTS, sequence);
                    break;
                case ORDER_PASSENGER_ONBOARD:
                    //乘客已上车
                    buildPushOrderStatus(orderId, OrderStatusEnum.PASSENGER_BOARDED);
                    buildPushOrderStatus(orderId, OrderStatusEnum.PASSENGER_BOARDED, sequence);
                    break;
                case ORDER_EN_ROUTE_TO_DESTINATION:
                    //前往目的地
                    buildPushOrderStatus(orderId, OrderStatusEnum.IN_SERVICE);
                    buildPushOrderStatus(orderId, OrderStatusEnum.IN_SERVICE, sequence);
                    break;
                case ORDER_ARRIVED_AT_DESTINATION:
                    //到达目的地
@@ -590,11 +618,11 @@
                    break;
                case ORDER_WAITING_FOR_DROPOFF:
                    //等待乘客下车
                    buildPushOrderStatus(orderId, OrderStatusEnum.SEE_OFF_GUESTS);
                    buildPushOrderStatus(orderId, OrderStatusEnum.SEE_OFF_GUESTS, sequence);
                    break;
                case ORDER_DROPOFF_COMPLETED:
                    //下车完成
                    buildPushOrderStatus(orderId, OrderStatusEnum.APPROVAL_REJECTION);
                    buildPushOrderStatus(orderId, OrderStatusEnum.APPROVAL_REJECTION, sequence);
                    break;
                case ORDER_COMPLETED:
                    //已完成
@@ -602,11 +630,11 @@
                    break;
                case ORDER_CANCELLED:
                    //已取消
                    buildPushOrderStatus(orderId, OrderStatusEnum.CANCELED);
                    buildPushOrderStatus(orderId, OrderStatusEnum.CANCELED, sequence);
                    break;
                case ORDER_ARRIVED_AT_CRUISE_DESTINATION:
                    //到达巡游终点
                    buildPushOrderStatus(orderId, null);
                    buildPushOrderStatus(orderId, null, sequence);
                    break;
                case ORDER_PAUSED:
                    //订单暂停
@@ -624,11 +652,19 @@
     * @param orderId
     * @param status
     */
    public void buildPushOrderStatus(String orderId, OrderStatusEnum status){
    public void buildPushOrderStatus(String orderId, OrderStatusEnum status, Long sequence){
        if(orderId.contains("XU")){
            //巡游单
            //响应消息
            responseMessage(sequence, "");
        }else{
            //普通单
            R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(Long.parseLong(orderId));
            XpOrder xpOrder = xpOrderR.getData();
            XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData();
            //响应消息
            responseMessage(sequence, xpVehicle.getVehicleVin());
            //构建推送消息
            Map<String, Object> params = new HashMap<>();
            Map<String, Object> content = new HashMap<>();
@@ -638,8 +674,6 @@
            params.put("content", com.alibaba.fastjson2.JSONObject.toJSONString(content));
            params.put("timestamp", System.currentTimeMillis() + "");
            String message = JSONObject.toJSONString(params);
            R<XpOrder> xpOrderR = xpOrderClient.queryOrderById(Long.parseLong(orderId));
            XpOrder xpOrder = xpOrderR.getData();
            Long appUserId = xpOrder.getAppUserId();
            SendMessageDTO dto = new SendMessageDTO();
            dto.setAppUserId(appUserId + "");
xp-robotaxi-automaticPilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/XPUUtil.java
@@ -7,13 +7,17 @@
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.xiaopeng.api.dto.automaticPilot.MqttPublishDto;
import com.xiaopeng.api.feignClient.automaticPilot.XPUClient;
import com.xiaopeng.api.vo.automaticPilot.MqttPublishVo;
import com.xiaopeng.api.vo.automaticPilot.proto.down.*;
import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.OrderOperation;
import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudCreateOrder.RTTask;
import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.OrderOperation;
import com.xiaopeng.common.core.utils.uuid.UUID;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
 * 自动驾驶接口对接文档
@@ -22,11 +26,8 @@
@Component
public class XPUUtil {
    /**
     * 接口地址
     */
    @Value("${xpu.url}")
    private String xpuUrl;
    @Resource
    private XPUClient xpuClient;
    /**
@@ -35,14 +36,14 @@
     * @param task
     * @return
     */
    public ResponseMessage cloudCreateOrder(RTTask task) {
    public MqttPublishDto cloudCreateOrder(RTTask task, String vin, Long sequence) {
        MsgContent msgContent = new MsgContent();
        // 消息头
        RtMsgHeader header = new RtMsgHeader();
        header.setMsg_id(UUID.randomUUID().toString());
        header.setTimestamp(System.currentTimeMillis());
        header.setCmd(RTCmdType.CLOUD_CREATE_ORDER);
        header.setSequence(1L);
        header.setSequence(sequence);
        header.setType(MessageType.MESSAGE_TYPE_RESPONSE);
        msgContent.setHeader(header);
        // 消息内容
@@ -50,22 +51,12 @@
        jsonObject.put("task", task);
        msgContent.setContent_detail(jsonObject);
        log.info("云端-->XPU 创建订单:{}", msgContent);
        HttpRequest post = HttpUtil.createPost("");
        post.body(JSON.toJSONString(msgContent));
        HttpResponse execute = post.execute();
        int status = execute.getStatus();
        if (200 != status) {
            throw new RuntimeException("XPU 接口异常:" + execute.getStatus());
        }
        MsgContent resMsgContent = JSON.parseObject(execute.body(), MsgContent.class);
        RtMsgHeader resHeader = resMsgContent.getHeader();
        int value = resHeader.getType().getValue();
        //只处理应答消息
        if (value == MessageType.MESSAGE_TYPE_RESPONSE.getValue()) {
            JSONObject contentDetail = resMsgContent.getContent_detail();
            return contentDetail.getObject("response", ResponseMessage.class);
        }
        return null;
        //组装请求消息体
        MqttPublishVo vo = new MqttPublishVo();
        vo.setTopic("topic-prod-xpu-robotaxi-high/" + vin);
        vo.setPayload(JSON.toJSONString(msgContent));
        return xpuClient.publish(vo);
    }
@@ -76,15 +67,14 @@
     * @param operation
     * @return
     */
    public ResponseMessage cloudOrderOperation(OrderOperation operation) {
    public MqttPublishDto cloudOrderOperation(OrderOperation operation, String vin,Long  sequence) {
        MsgContent msgContent = new MsgContent();
        // 消息头
        RtMsgHeader header = new RtMsgHeader();
        header.setMsg_id(UUID.randomUUID().toString());
        header.setTimestamp(System.currentTimeMillis());
        header.setCmd(RTCmdType.CLOUD_ORDER_OPERATION);
        Snowflake snowflake = IdUtil.getSnowflake(0, 0);
        header.setSequence(snowflake.nextId());
        header.setSequence(sequence);
        header.setType(MessageType.MESSAGE_TYPE_REQUEST);
        msgContent.setHeader(header);
        // 消息内容
@@ -92,22 +82,15 @@
        jsonObject.put("operation", operation);
        msgContent.setContent_detail(jsonObject);
        log.info("云端-->XPU 操作订单:{}", msgContent);
        HttpRequest post = HttpUtil.createPost("");
        post.body(JSON.toJSONString(msgContent));
        HttpResponse execute = post.execute();
        int status = execute.getStatus();
        if (200 != status) {
            throw new RuntimeException("XPU 接口异常:" + execute.getStatus());
        }
        MsgContent resMsgContent = JSON.parseObject(execute.body(), MsgContent.class);
        RtMsgHeader resHeader = resMsgContent.getHeader();
        int value = resHeader.getType().getValue();
        //只处理应答消息
        if (value == MessageType.MESSAGE_TYPE_RESPONSE.getValue()) {
            JSONObject contentDetail = resMsgContent.getContent_detail();
            return contentDetail.getObject("response", ResponseMessage.class);
        }
        return null;
        //组装请求消息体
        MqttPublishVo vo = new MqttPublishVo();
        vo.setTopic("topic-prod-xpu-robotaxi-high/" + vin);
        vo.setPayload(JSON.toJSONString(msgContent));
        return xpuClient.publish(vo);
    }
@@ -119,7 +102,7 @@
     * @param responseMessage
     * @return
     */
    public ResponseMessage responseMessage(ResponseMessage responseMessage) {
    public MqttPublishDto responseMessage(ResponseMessage responseMessage, String vin) {
        MsgContent msgContent = new MsgContent();
        // 消息头
        RtMsgHeader header = new RtMsgHeader();
@@ -135,14 +118,11 @@
        jsonObject.put("resposne", responseMessage);
        msgContent.setContent_detail(jsonObject);
        log.info("云端-->XPU 响应消息:{}", msgContent);
        HttpRequest post = HttpUtil.createPost("");
        post.body(JSON.toJSONString(msgContent));
        HttpResponse execute = post.execute();
        int status = execute.getStatus();
        if (200 != status) {
            throw new RuntimeException("XPU 接口异常:" + execute.getStatus());
        }
        return null;
        //组装请求消息体
        MqttPublishVo vo = new MqttPublishVo();
        vo.setTopic("topic-prod-xpu-robotaxi-high/" + vin);
        vo.setPayload(JSON.toJSONString(msgContent));
        return xpuClient.publish(vo);
    }
}
xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/dto/ServiceNameConstantsEnum.java
@@ -61,5 +61,9 @@
     * 小鹏用车控服务
     */
    String XP_IM_OPEN_BOOT_SERVICE = "xp-im-open-boot";
    /**
     * 小鹏用车控服务
     */
    String XP_MQTT_ROUTER_THIRDPARTY_BOOT = "xp-mqtt-router-thirdparty-boot";
}
xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/SnowFlake.java
New file
@@ -0,0 +1,111 @@
package com.xiaopeng.common.core.utils;
/**
 * see @https://raw.githubusercontent.com/beyondfengyu/SnowFlake/master/SnowFlake.java
 * Created by Lox on 2017/8/21.
 */
public class SnowFlake {
    /**
     * 起始的时间戳
     */
    private static long START_STMP = 1503305692631L;
    /**
     * 每一部分占用的位数
     */
    private final static long SEQUENCE_BIT = 12; //序列号占用的位数
    private final static long MACHINE_BIT = 5;   //机器标识占用的位数
    private final static long DATACENTER_BIT = 5;//数据中心占用的位数
    /**
     * 每一部分的最大值
     */
    public final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
    public final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
    private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
    /**
     * 每一部分向左的位移
     */
    private final static long MACHINE_LEFT = SEQUENCE_BIT;
    private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
    private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
    private long datacenterId;  //数据中心
    private long machineId;     //机器标识
    private long sequence = 0L; //序列号
    private long lastStmp = -1L;//上一次时间戳
    public SnowFlake(long datacenterId, long machineId) {
        if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
            throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0");
        }
        if (machineId > MAX_MACHINE_NUM || machineId < 0) {
            throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
        }
        this.datacenterId = datacenterId;
        this.machineId = machineId;
    }
    /**
     * 设置初始时间,各业务方的旧算法有可能初始时间不一致,请使用
     * @param timestamp 设定的新初始时间戳
     * @return 当前对象
     */
    public SnowFlake withStartTimestamp(long timestamp) {
        SnowFlake.START_STMP = timestamp;
        return this;
    }
    /**
     * 产生下一个ID
     *
     * @return
     */
    public synchronized long nextId() {
        long currStmp = getNewstmp();
        if (currStmp < lastStmp) {
            throw new RuntimeException("Clock moved backwards.  Refusing to generate id");
        }
        if (currStmp == lastStmp) {
            //相同毫秒内,序列号自增
            sequence = (sequence + 1) & MAX_SEQUENCE;
            //同一毫秒的序列数已经达到最大
            if (sequence == 0L) {
                currStmp = getNextMill();
            }
        } else {
            //不同毫秒内,序列号置为0
            sequence = 0L;
        }
        lastStmp = currStmp;
        return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
                | datacenterId << DATACENTER_LEFT       //数据中心部分
                | machineId << MACHINE_LEFT             //机器标识部分
                | sequence;                             //序列号部分
    }
    private long getNextMill() {
        long mill = getNewstmp();
        while (mill <= lastStmp) {
            mill = getNewstmp();
        }
        return mill;
    }
    private long getNewstmp() {
        return System.currentTimeMillis();
    }
//    public static void main(String[] args) {
//        SnowFlake snowFlake = new SnowFlake(0, 0);
//        snowFlake.withStartTimestamp(1420041600000L);
//
//        for (int i = 0; i < (1 << 5); i++) {
//            System.out.println(snowFlake.nextId());
//        }
//    }
}
xp-robotaxi-common/xp-common-redis/src/main/java/com/xiaopeng/common/redis/service/RedisService.java
@@ -179,8 +179,8 @@
    }
    // 获取第一个元素并删除(弹出)
    public Object popFirstElement(String key) {
        return redisTemplate.opsForList().leftPop(key);
    public String popFirstElement(String key) {
        return (String)redisTemplate.opsForList().leftPop(key);
    }
    /**
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java
@@ -181,4 +181,9 @@
        xpTaskService.deleteTaskById(id);
        return R.ok();
    }
    @ApiOperation(value = "事故类型列表", response = XpErrorType.class, tags = "管理后台-车辆管理-运营车辆管理")
    @GetMapping("/api/v1/task/errorTypeTreeList")
    public R<List<XpErrorType>> errorTypeTreeList() {
        return xpErrorTypeService.errorTypeList();
    }
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpErrorTypeServiceImpl.java
@@ -1,6 +1,5 @@
package com.xiaopeng.maintenance.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.model.maintenance.XpErrorType;
import com.xiaopeng.common.core.domain.R;
@@ -8,7 +7,6 @@
import com.xiaopeng.maintenance.service.IXpErrorTypeService;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpElectronicFenceController.java
@@ -18,7 +18,6 @@
import com.xiaopeng.operation.service.IXpElectronicFenceAreaService;
import com.xiaopeng.operation.service.IXpElectronicFenceService;
import com.xiaopeng.operation.service.XpRegionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
@@ -188,4 +187,11 @@
    R<List<XpElectronicFence>> getAvailableList(){
        return R.ok(xpElectronicFenceService.getAvailableList());
    }
    @ApiOperation(value = "获取已启用的电子围栏列表",tags = {"管理后台-在库车辆管理"})
    @GetMapping("/list")
    R<List<XpElectronicFence>> getList(){
        return R.ok(xpElectronicFenceService.getList());
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpGeoQueryEntityController.java
@@ -1,11 +1,10 @@
package com.xiaopeng.operation.controller;
import com.xiaopeng.operation.entity.XpGeoQueryEntity;
import com.xiaopeng.api.model.operation.XpGeoQueryEntity;
import com.xiaopeng.operation.service.IXpGeoQueryEntityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/controller/XpPricingController.java
@@ -3,12 +3,14 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.model.operation.XpGeoQueryEntity;
import com.xiaopeng.api.model.operation.XpPricing;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.controller.BaseController;
import com.xiaopeng.common.core.web.domain.AjaxResult;
import com.xiaopeng.api.dto.map.RouteAndFareDto;
import com.xiaopeng.operation.dto.XpOrderDto;
import com.xiaopeng.operation.service.IXpGeoQueryEntityService;
import com.xiaopeng.operation.service.XpPricingService;
import com.xiaopeng.api.vo.operation.RouteAndFareVo;
import com.xiaopeng.operation.vo.SaveOrderVo;
@@ -38,10 +40,12 @@
public class XpPricingController extends BaseController {
    private final XpPricingService xpPricingService;
    private final IXpGeoQueryEntityService xpGeoQueryEntityService;
    public XpPricingController(XpPricingService xpPricingService) {
    public XpPricingController(XpPricingService xpPricingService, IXpGeoQueryEntityService xpGeoQueryEntityService) {
        this.xpPricingService = xpPricingService;
        this.xpGeoQueryEntityService = xpGeoQueryEntityService;
    }
@@ -87,6 +91,18 @@
    /**
     * 保存信息
     * @param xpGeoQueryEntity
     * @return
     */
    @PostMapping("/inner/saveXpGeoQueryEntity")
    public R<?> saveXpGeoQueryEntity(@RequestBody XpGeoQueryEntity xpGeoQueryEntity){
        xpGeoQueryEntityService.save(xpGeoQueryEntity);
        return R.ok();
    }
    /**
     * 播单
     */
    @PostMapping("/base/v1/mini-program/order/save")
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/repository/XpGeoQueryEntityRepository.java
@@ -1,6 +1,6 @@
package com.xiaopeng.operation.repository;
import com.xiaopeng.operation.entity.XpGeoQueryEntity;
import com.xiaopeng.api.model.operation.XpGeoQueryEntity;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.repository.MongoRepository;
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpElectronicFenceService.java
@@ -31,4 +31,10 @@
     * @return
     */
    List<XpElectronicFence> getAvailableList();
    /**
     * 获取不分页的围栏列表
     * @return
     */
    List<XpElectronicFence> getList();
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/IXpGeoQueryEntityService.java
@@ -1,7 +1,6 @@
package com.xiaopeng.operation.service;
import com.xiaopeng.operation.entity.XpGeoQueryEntity;
import org.springframework.data.geo.Point;
import com.xiaopeng.api.model.operation.XpGeoQueryEntity;
import java.util.List;
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpElectronicFenceServiceImpl.java
@@ -2,12 +2,16 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.ImmutableMap;
import com.xiaopeng.api.dto.operation.ElectronicFenceAddDto;
import com.xiaopeng.api.dto.operation.ElectronicFenceUpdateDto;
import com.xiaopeng.api.model.map.XpGeoFencingPolygon;
import com.xiaopeng.api.model.map.XpGeoFencingProhibitedPolygon;
import com.xiaopeng.api.model.operation.XpElectronicFence;
import com.xiaopeng.api.model.operation.XpElectronicFenceArea;
import com.xiaopeng.api.model.operation.XpPoint;
import com.xiaopeng.api.query.operation.ElectronicPageListQuery;
import com.xiaopeng.api.model.operation.XpRegion;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
@@ -16,8 +20,6 @@
import com.xiaopeng.common.core.utils.bean.BeanUtils;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.operation.constant.I18nKeyConstant;
import com.xiaopeng.api.dto.operation.ElectronicFenceAddDto;
import com.xiaopeng.api.dto.operation.ElectronicFenceUpdateDto;
import com.xiaopeng.operation.job.base.QuartzManager;
import com.xiaopeng.operation.job.base.TimeJobType;
import com.xiaopeng.operation.job.jobs.ElectronicEffectJob;
@@ -616,4 +618,9 @@
    public List<XpElectronicFence> getAvailableList() {
        return lambdaQuery().eq(XpElectronicFence::getStatus, 2).list(); //查询已启用的围栏
    }
    @Override
    public List<XpElectronicFence> getList() {
        return list();
    }
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpGeoQueryEntityServiceImpl.java
@@ -1,6 +1,6 @@
package com.xiaopeng.operation.service.impl;
import com.xiaopeng.operation.entity.XpGeoQueryEntity;
import com.xiaopeng.api.model.operation.XpGeoQueryEntity;
import com.xiaopeng.operation.repository.XpGeoQueryEntityRepository;
import com.xiaopeng.operation.service.IXpGeoQueryEntityService;
import org.springframework.beans.factory.annotation.Autowired;
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPricingServiceImpl.java
@@ -16,7 +16,6 @@
import com.xiaopeng.api.model.account.XpAppUser;
import com.xiaopeng.api.model.operation.*;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.account.UserCouponVo;
import com.xiaopeng.api.vo.operation.FareVo;
import com.xiaopeng.api.vo.operation.RouteAndFareVo;
@@ -29,7 +28,7 @@
import com.xiaopeng.common.redis.service.RedisService;
import com.xiaopeng.operation.constant.I18nKeyConstant;
import com.xiaopeng.operation.dto.XpOrderDto;
import com.xiaopeng.operation.entity.XpGeoQueryEntity;
import com.xiaopeng.api.model.operation.XpGeoQueryEntity;
import com.xiaopeng.operation.mapper.*;
import com.xiaopeng.operation.service.IXpGeoQueryEntityService;
import com.xiaopeng.operation.service.XpPricingService;
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/utils/TaskOrderUtil.java
@@ -641,6 +641,12 @@
                        BaseVehicleUserDto baseVehicleUserDto = userVehicleClient.addTaxiPassenger(addTaxiPassengerVo);
                        if (baseVehicleUserDto!=null && baseVehicleUserDto.getCode() == 200) {
                            // TODO 下单
                            // 调用推送服务  orderId + carVin
                            // 绑定成功  弹出这个队列第一个订单
                            redisService.popFirstElement(quoteName);
                            return;
@@ -680,6 +686,9 @@
                        addTaxiPassengerVo.setAppId("");
                        BaseVehicleUserDto baseVehicleUserDto = userVehicleClient.addTaxiPassenger(addTaxiPassengerVo);
                        if (baseVehicleUserDto.getCode() == 200) {
                            redisService.popFirstElement(quoteName);
                            lock.unlock();
                            return;
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/XpOrderController.java
@@ -5,6 +5,7 @@
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaopeng.api.dto.order.GetOrderNumDto;
import com.xiaopeng.api.dto.order.PopOrderDto;
import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO;
import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO;
import com.xiaopeng.api.model.order.XpOrder;
@@ -116,6 +117,18 @@
        return R.ok(xpOrderService.getOrderNum(dto));
    }
    /**
     * 成功操作下发命令后调用 用于弹出redis队列的获取成功的数据
     */
    @PostMapping("/inner/order/popOrder")
    public  R<?> popOrder(@RequestBody PopOrderDto dto){
        xpOrderService.popOrder(dto);
        return R.ok();
    }
    /**
     * 新增订单
     *
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/IXpOrderService.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xiaopeng.api.dto.order.GetOrderNumDto;
import com.xiaopeng.api.dto.order.PopOrderDto;
import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO;
import com.xiaopeng.api.dto.statistics.StatisticsQueryDTO;
import com.xiaopeng.api.model.order.XpOrder;
@@ -188,5 +189,11 @@
     */
    void saveVehicleLocation(OrderTrajectory orderTrajectory);
    /**
     * 成功操作下发命令后调用 用于弹出redis队列的获取成功的数据
     * @param dto
     */
    void popOrder(PopOrderDto dto);
    OrderDetailVo orderDetail(Long orderId, String uid);
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -12,6 +12,7 @@
import com.xiaopeng.api.dto.order.GetOrderNumDto;
import com.xiaopeng.api.dto.order.HistoryEndPointsDto;
import com.xiaopeng.api.dto.order.HistoryStartPointsDto;
import com.xiaopeng.api.dto.order.PopOrderDto;
import com.xiaopeng.api.dto.pushMessage.SendMessageDTO;
import com.xiaopeng.api.dto.statistics.DailyCountDTO;
import com.xiaopeng.api.dto.statistics.OrderStatisticsDTO;
@@ -28,6 +29,7 @@
import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetVehicleClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.account.XpAppUser;
import com.xiaopeng.api.model.operation.XpGeoQueryEntity;
import com.xiaopeng.api.model.operation.XpFeedbackType;
import com.xiaopeng.api.model.operation.XpPoint;
import com.xiaopeng.api.model.order.XpOrder;
@@ -74,11 +76,13 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
@@ -1639,6 +1643,42 @@
    /**
     * 成功操作下发命令后调用 用于弹出redis队列的获取成功的数据
     * @param dto
     */
    @Override
    @Transactional
//    @ShardingTransactionType(TransactionType.BASE)
    public void popOrder(PopOrderDto dto) {
        XpOrder order = this.getById(dto.getOrderId());
        order.setAcceptanceTime(LocalDateTime.now());
        order.setVehicleId(dto.getXpVehicleId());
        order.setStatus(2);
        // Redis弹出这个队列元素
        // value 订单Id_经纬度_状态_用户id_订单编号_距离_时间
        String popFirstElement = redisService.popFirstElement(dto.getQueueName());
        XpGeoQueryEntity xpGeoQueryEntity = new XpGeoQueryEntity();
        String[] split = popFirstElement.split("_");
        xpGeoQueryEntity.setOrderId(split[0]);
        String[] split1 = split[1].split(",");
        xpGeoQueryEntity.setLocation(new GeoJsonPoint(Double.parseDouble(split1[0]), Double.parseDouble(split1[1])));
        xpGeoQueryEntity.setTimestamp(new Date());
        // 计算2个时间的秒数
        LocalDateTime createTime = order.getCreateTime();
        LocalDateTime acceptanceTime = order.getAcceptanceTime();
        xpGeoQueryEntity.setSeconds((int) Duration.between(createTime, acceptanceTime).getSeconds());
        String currentTimeSlot = DateUtils.getCurrentTimeSlot();
        xpGeoQueryEntity.setTime(currentTimeSlot);
        // 存mongo数据
        xpPricingClient.saveXpGeoQueryEntity(xpGeoQueryEntity);
        this.updateById(order);
    }
    /**
     * 获取当前用户正在执行的订单
     *
     * @param uid
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
@@ -15,7 +15,6 @@
import com.xiaopeng.api.feignClient.order.XpOrderClient;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicleAnnualRecord;
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
import com.xiaopeng.api.vo.vehicleConvoy.VehiclesCommandCallbackVo;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
@@ -35,7 +34,6 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@@ -318,7 +316,7 @@
     *
     * @param query 查询参数
     */
    @ApiOperation(value = "运营车辆管理列表导出", tags = {"管理后台-车辆管理-在库车辆管理"})
    @ApiOperation(value = "运营车辆管理列表导出", tags = {"管理后台-车辆管理-运营车辆管理"})
    @PostMapping("/api/v1/vehicle/operationExportExcel")
    public void exportExcel(@RequestBody OperationVehicleExportQuery query) {
        // 1. 查询导出数据
@@ -505,16 +503,12 @@
    /**
     * 获取车辆不分页列表
     *
     * @param plateNumber
     * @param fleetName
     * @param query
     * @return
     */
    @ApiOperation(value = "获取车辆不分页列表", tags = {"管理后台-车队管理"})
    @PostMapping("/api/v1/vehicle/list")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "plateNumber", value = "车牌号", dataTypeClass = String.class),
            @ApiImplicitParam(name = "fleetName", value = "车队名称", dataTypeClass = String.class)})
    public R<List<XpVehicleVO>> getList(String plateNumber, String fleetName) {
        return R.ok(xpVehicleService.getList(plateNumber, fleetName));
    @ApiOperation(value = "获取车辆分页列表", tags = {"管理后台-车队管理"})
    @PostMapping("/api/v1/vehicle/page-list")
    public R<PageInfo<XpVehicleVO>> getVehiclePageList(@RequestBody VehicleSelectPageQuery query) {
        return R.ok(xpVehicleService.getVehiclePageList(query));
    }
}
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/mapper/XpVehicleMapper.java
@@ -1,5 +1,6 @@
package com.xiaopeng.vehicleConvoy.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaopeng.api.dto.statistics.DailyCountDTO;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@@ -82,10 +83,10 @@
    List<XpVehicle> vehicleExportList(@Param("query") VehicleExportQuery query);
    /**
     * 车辆不分页列表
     * 车辆分页列表
     * @param plateNumber
     * @param fleetName
     * @return
     */
    List<XpVehicleVO> getList(@Param("plateNumber") String plateNumber, @Param("fleetName") String fleetName);
    Page<XpVehicleVO> getVehiclePageList(Page<XpVehicleVO> page, @Param("plateNumber") String plateNumber, @Param("fleetName") String fleetName);
}
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/VehicleSelectPageQuery.java
New file
@@ -0,0 +1,24 @@
package com.xiaopeng.vehicleConvoy.model.query;
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * 车队分页查询参数
 *
 * @author mitao
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "车队分页查询参数")
public class VehicleSelectPageQuery extends BasePage {
    @ApiModelProperty(value = "车队名称")
    private String fleetName;
    @ApiModelProperty(value = "车牌号")
    private String plateNumber;
}
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/query/XpVehicleAnnualRecordPageQuery.java
@@ -4,7 +4,6 @@
import com.xiaopeng.common.core.web.page.BasePage;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -19,7 +18,7 @@
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "运营车辆管理分页查询参数")
@ApiModel(value = "运营车辆详情年检记录分页查询参数")
public class XpVehicleAnnualRecordPageQuery extends BasePage {
    @ApiModelProperty(value = "车辆ID")
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/FleetDetailVO.java
@@ -28,6 +28,9 @@
    @ApiModelProperty(value = "负责人姓名")
    private String operationsUserName;
    @ApiModelProperty(value = "负责人-手机号")
    private String phoneNumber;
    @ApiModelProperty(value = "打卡地id")
    private Long locationId;
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/FleetPageVO.java
@@ -43,4 +43,12 @@
    @ApiModelProperty(value = "创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime createTime;
    @ApiModelProperty(value = "电子围栏id")
    private Long electronicId;
    @ApiModelProperty(value = "打卡地id")
    private Long locationId;
}
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/IXpVehicleService.java
@@ -168,11 +168,9 @@
    VehicleTemperatureDto queryTemperatureByOrderId(Long orderId, String uid);
    /**
     * 车辆不分页列表
     * 车辆分页列表
     *
     * @param plateNumber
     * @param fleetName
     * @return
     * @param query@return
     */
    List<XpVehicleVO> getList(String plateNumber, String fleetName);
    PageInfo<XpVehicleVO> getVehiclePageList(VehicleSelectPageQuery query);
}
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java
@@ -6,9 +6,11 @@
import com.xiaopeng.api.dto.account.XpOperationsUserQueryDTO;
import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
import com.xiaopeng.api.feignClient.operation.XpElectronicClient;
import com.xiaopeng.api.feignClient.operation.XpPointClient;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.account.XpOperationsUser;
import com.xiaopeng.api.model.operation.XpElectronicFence;
import com.xiaopeng.api.model.operation.XpPoint;
import com.xiaopeng.api.model.vehicleConvoy.XpFleet;
import com.xiaopeng.api.model.vehicleConvoy.XpFleetOperations;
import com.xiaopeng.api.model.vehicleConvoy.XpFleetVehicle;
@@ -63,6 +65,8 @@
    private final XpVehicleClient xpVehicleClient;
    private final XpElectronicClient xpElectronicClient;
    private final XpPointClient xpPointClient;
    @Override
    public List<XpFleet> listByIds(List<Long> ids) {
@@ -240,6 +244,15 @@
            R<XpOperationsUser> userResult = xpOperationUserClient.queryById(fleet.getOperationsUserId());
            if (userResult.getData() != null) {
                vo.setOperationsUserName(userResult.getData().getNickName());
                vo.setPhoneNumber(userResult.getData().getPhoneNumber());
            }
        }
        // 6. 查询打卡地信息
        if (fleet.getLocationId() != null) {
            R<XpPoint> pointResult = xpPointClient.queryById(fleet.getLocationId());
            if (pointResult.getData() != null) {
                vo.setLocationName(pointResult.getData().getPointName());
            }
        }
xp-robotaxi-vehicleConvoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpVehicleServiceImpl.java
@@ -4,6 +4,7 @@
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaopeng.api.dto.vehicleConvoy.VehicleTemperatureDto;
import com.xiaopeng.api.feignClient.operation.XpElectronicClient;
@@ -19,7 +20,6 @@
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.exception.ServiceException;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.common.security.utils.SecurityUtils;
import com.xiaopeng.vehicleConvoy.constant.I18nKeyConstant;
import com.xiaopeng.vehicleConvoy.mapper.XpVehicleMapper;
import com.xiaopeng.vehicleConvoy.model.dto.*;
@@ -191,7 +191,6 @@
        xpVehicle.setStatus(1);
        // 设置入库时间
        xpVehicle.setWarehousingTime(LocalDateTime.now());
        xpVehicle.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        this.save(xpVehicle);
    }
@@ -201,8 +200,6 @@
        // DTO转实体
        XpVehicle xpVehicle = new XpVehicle();
        BeanUtil.copyProperties(dto, xpVehicle);
        xpVehicle.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        this.updateById(xpVehicle);
    }
@@ -242,7 +239,6 @@
        //保存年检记录
        XpVehicleAnnualRecord xpVehicleAnnualRecord = BeanUtil.copyProperties(dto, XpVehicleAnnualRecord.class, "id");
        xpVehicleAnnualRecord.setVehicleId(dto.getId());
        xpVehicleAnnualRecord.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getCreateBy());
        xpVehicleAnnualRecordService.save(xpVehicleAnnualRecord);
    }
@@ -610,7 +606,12 @@
    }
    @Override
    public List<XpVehicleVO> getList(String plateNumber, String fleetName) {
        return baseMapper.getList(plateNumber, fleetName);
    public PageInfo<XpVehicleVO> getVehiclePageList(VehicleSelectPageQuery query) {
        Page<XpVehicleVO> page = new Page<>(query.getPageNum(), query.getPageSize());
        page = baseMapper.getVehiclePageList(page, query.getPlateNumber(), query.getFleetName());
        PageInfo<XpVehicleVO> pageInfo = new PageInfo<>();
        pageInfo.setTotal(page.getTotal());
        pageInfo.setRecords(page.getRecords());
        return pageInfo;
    }
}
xp-robotaxi-vehicleConvoy-boot/src/main/resources/mapper/vehicleConvoy/XpVehicleMapper.xml
@@ -108,7 +108,7 @@
        </where>
        ORDER BY create_time DESC
    </select>
    <select id="getList" resultType="com.xiaopeng.vehicleConvoy.model.vo.XpVehicleVO">
    <select id="getVehiclePageList" resultType="com.xiaopeng.vehicleConvoy.model.vo.XpVehicleVO">
        select xv.id,
        xv.vehicle_code,
        xv.vehicle_vin,