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,