yyy
2026-05-01 ec7f066183204ab15245f9f99931b922ae05a364
合并代码
2个文件已添加
10个文件已修改
362 ■■■■■ 已修改文件
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsUserMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/account/XpOperationUserClient.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/utils/GDMapGeocodingUtil.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-map-boot/src/test/java/com/xiaopeng/map/service/serviceimpl/XpStationServiceImplTest.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/test/OrderTest.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/webSocket/handler/PositionMsgHandler.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/webSocket/handler/WebSocketTextFrameHandler.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpOperationsUserController.java
@@ -238,6 +238,9 @@
    @PostMapping("/api/v1/operationsUser/listAll")
    public R<List<XpOperationsUser>> listAll() {
        List<XpOperationsUser> listAll = xpOperationsUserService.list();
        for (XpOperationsUser xpOperationsUser : listAll) {
            // todo 需要上传工单id,根据距离进行排序
        }
        return R.ok(listAll);
    }
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/mapper/XpOperationsUserMapper.java
@@ -51,5 +51,5 @@
     */
    List<ExportOperationsUserVo> exportOperationsUser(@Param("query")XpOperationsUserQuery query);
    List<XpOperationsUserWithRoleVO> pageListByIds(PageInfo<XpOperationsUserWithRoleVO> pageInfo, OptionalUsersPageListQuery q);
    List<XpOperationsUserWithRoleVO> pageListByIds(PageInfo<XpOperationsUserWithRoleVO> pageInfo, @Param("query") OptionalUsersPageListQuery query);
}
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/XpOperationsUserServiceImpl.java
@@ -550,7 +550,6 @@
    @Override
    public PageInfo<XpOperationsUserWithRoleVO> pageListByIds(OptionalUsersPageListQuery q) {
        PageInfo<XpOperationsUserWithRoleVO> pageInfo = new PageInfo<>(q.getPageNum(), q.getPageSize());
        List<XpOperationsUserWithRoleVO> list = baseMapper.pageListByIds(pageInfo, q);
        pageInfo.setRecords(list);
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/account/XpOperationUserClient.java
@@ -113,5 +113,5 @@
    R<XpOperationsUser> getByExactPhone(@RequestParam("phoneNumber") String phoneNumber);
    @PostMapping("/logan/inner/xpOperationsUser/pageListByIds")
    R<PageInfo<XpOperationsUserWithRoleVO>> listByQueryIds(OptionalUsersPageListQuery query);
    R<PageInfo<XpOperationsUserWithRoleVO>> listByQueryIds(@RequestBody OptionalUsersPageListQuery query);
}
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -759,7 +759,7 @@
            List<XpTradingStrategyPush> xpTradingStrategyPushes = xpTradingStrategyPushMapper.selectList(new QueryWrapper<XpTradingStrategyPush>().eq("trading_strategy_id", xpTradingStrategy.getId()));
            long now = Long.parseLong(LocalDateTime.now().format(DateTimeFormatter.ofPattern("HHmm")));
            XpTradingStrategyPush xpTradingStrategyPush = xpTradingStrategyPushes.stream().filter(item -> {
                long start = Long.parseLong(item.getStarTime().replace(":", ""));
                long start = Long.parseLong(item.getStartTime().replace(":", ""));
                long end = Long.parseLong(item.getEndTime().replace(":", ""));
                return now >= start && now < end;
            }).findFirst().orElse(null);
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java
@@ -47,6 +47,7 @@
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
import org.springframework.data.mongodb.core.MongoTemplate;
@@ -358,30 +359,29 @@
    @ApiOperation(value = "可改派的运维人员列表", tags = {"管理后台-运维执行-任务工单-待改派工单"})
    @PostMapping("/api/v1/task/reassign/availableUsers")
    public R<PageInfo<XpOperationsUserWithRoleVO>> availableReassignUsers(@RequestBody OptionalUsersPageListQuery query) {
    public R<PageInfo<XpOperationsUserWithRoleVO>> availableReassignUsers(@RequestBody OptionalUsersPageListQuery query1) {
        XpTask task = xpTaskService.getById(query1.getTaskId());
        // 找到中心点
        GeoJsonPoint geoJsonPoint = new GeoJsonPoint(task.getVehicleLon().doubleValue(), task.getVehicleLat().doubleValue());
        // 构造半径
        Distance distanceR = new Distance(10, Metrics.KILOMETERS);
        // 画圆
        Circle circle = new Circle(geoJsonPoint, distanceR);
        Query query = Query.query(new Criteria().andOperator(
                Criteria.where("location").withinSphere(circle)
        ));
        List<XpOperationsUserPositionDTO> vehiclePositions = mongoTemplate.find(query, XpOperationsUserPositionDTO.class);
        Map<Long, Double> disMap = vehiclePositions.stream().collect(Collectors.toMap(XpOperationsUserPositionDTO::getId, XpOperationsUserPositionDTO::getDistance));
        XpTask task = xpTaskService.getById(query.getTaskId());
        GeoJsonPoint point =
                new GeoJsonPoint(
                        task.getVehicleLon().doubleValue(),
                        task.getVehicleLat().doubleValue()
                );
        Query q = new Query(Criteria.where("location").near(point)
                .maxDistance(new Distance(10, Metrics.KILOMETERS).getNormalizedValue()));
        q.with(Sort.by(Sort.Direction.ASC, "dis"));
        List<XpOperationsUserPositionDTO> up = mongoTemplate.find(q, XpOperationsUserPositionDTO.class);
        Map<Long, Double> disMap = up.stream().collect(Collectors.toMap(XpOperationsUserPositionDTO::getId, XpOperationsUserPositionDTO::getDistance));
        // 查询车队下面面所有人员id和up求交集
        List<Long> data = xpFleetClient.idsByFleetName(query.getFleet()).getData();
        List<Long> data = xpFleetClient.idsByFleetName(query1.getFleet()).getData();
        List<Long> ids = up.stream().map(XpOperationsUserPositionDTO::getId)
        List<Long> ids = vehiclePositions.stream().map(XpOperationsUserPositionDTO::getId)
                .filter(e -> data == null || data.isEmpty() || data.contains(e))
                .collect(Collectors.toList());
        query.setIds(ids);
        PageInfo<XpOperationsUserWithRoleVO> ret = operationUserClient.listByQueryIds(query).getData();
        query1.setIds(ids);
        PageInfo<XpOperationsUserWithRoleVO> ret = operationUserClient.listByQueryIds(query1).getData();
        // 设置距离,然后排序
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
@@ -5,14 +5,18 @@
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.xiaopeng.api.dto.account.XpOperationsUserPositionDTO;
import com.xiaopeng.api.dto.account.XpOperationsUserQueryDTO;
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.dto.pushMessage.AliPushMessageDTO;
import com.xiaopeng.api.feignClient.account.SysUserClient;
import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
import com.xiaopeng.api.feignClient.account.XpOperationUserNotificationClient;
import com.xiaopeng.api.feignClient.map.XpMapClient;
import com.xiaopeng.api.feignClient.operation.SmsClient;
import com.xiaopeng.api.feignClient.pushMessage.WebSocketMessageClient;
import com.xiaopeng.api.feignClient.pushMessage.XpAliPushMessageClient;
@@ -26,8 +30,10 @@
import com.xiaopeng.api.model.maintenance.*;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.XpTaskVO;
import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO;
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
import com.xiaopeng.api.vo.maintenance.TaskScheduleConstants;
import com.xiaopeng.api.vo.operation.RouteVo;
import com.xiaopeng.api.vo.operation.SmsVo;
import com.xiaopeng.common.core.constant.AliPushTypeConstant;
import com.xiaopeng.common.core.domain.R;
@@ -49,6 +55,7 @@
import com.xiaopeng.maintenance.model.query.XpTaskRecordPageQuery;
import com.xiaopeng.maintenance.model.vo.*;
import com.xiaopeng.maintenance.repo.XpOperationsUserRepository;
import com.xiaopeng.maintenance.service.IXpClockInService;
import com.xiaopeng.maintenance.service.IXpTaskRuleRoleService;
import com.xiaopeng.maintenance.service.IXpTaskRuleService;
import com.xiaopeng.maintenance.service.XpTaskService;
@@ -58,6 +65,7 @@
import com.xiaopeng.maintenance.vo.TaskCleanDetailVO;
import com.xiaopeng.maintenance.vo.TaskDetectionDetailVO;
import com.xiaopeng.maintenance.vo.TaskReassignmentVo;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType;
@@ -159,6 +167,9 @@
    @Resource
    private WebSocketMessageClient xpWebSocketMessageClient;
    @Resource
    private IXpClockInService xpClockInService;
    @Override
    public PageInfo<WorkBenchVO> workbench(WorkBenchQuery query) throws UnsupportedEncodingException {
@@ -285,7 +296,52 @@
            List<Long> userIds = xpOperationsRoleResult.getData().stream().filter(x -> ids.contains(x.getOperationsUserId()))
                    .map(XpOperationsRole::getOperationsUserId)
                    .distinct().collect(Collectors.toList());
            xpTask.setHandleUserId(StringUtils.join(userIds, ","));
            //获取首选人的实时定位,计算每个人到事故车辆位置的导航距离
            List<Operations> operationsList = new ArrayList<>();
            for (Long userId : userIds) {
                Operations operations = new Operations();
                operations.setUserId(userId);
                XpOperationsUserPositionDTO vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("id").is(userId)), XpOperationsUserPositionDTO.class);
                if(null != vehiclePosition){
                    LonLatDto start = new LonLatDto(vehiclePosition.getLongitude(), vehiclePosition.getLatitude());
                    LonLatDto end = new LonLatDto(xpTask.getVehicleLon().doubleValue(), xpTask.getVehicleLat().doubleValue());
                    RouteVo routeVo = gdMapGeocodingUtil.getDistanceAndTime(start, end, null, null, null, null);
                    operations.setDistance(routeVo.getDistance());
                }
                operationsList.add(operations);
            }
            //对距离进行排序,去距离最近的人员
            operationsList.sort((o1, o2) -> o1.getDistance().compareTo(o2.getDistance()) * -1);
            Operations operations = operationsList.get(0);
            Long userId = operations.getUserId();
            //如果多人距离相同,可按照上班状态>空闲状态>工号排序
            List<Operations> collect = operationsList.stream().filter(s -> s.getDistance().equals(operations.getDistance())).collect(Collectors.toList());
            if(collect.size() > 1){
                //查询已经上班打卡了的人员
                List<XpClockIn> xpClockIns = xpClockInService.list(new QueryWrapper<XpClockIn>().in("app_user_id", collect)
                        .isNull("clock_out_result").last(" and DATE(now()) = DATE(clock_in_time)"));
                if(xpClockIns.size() == 1){
                    userId = xpClockIns.get(0).getAppUserId();
                }else if(xpClockIns.size() > 1){
                    //查询有任务的人员
                    List<Long> collect1 = xpClockIns.stream().map(XpClockIn::getAppUserId).collect(Collectors.toList());
                    List<XpTask> list1 = this.list(new QueryWrapper<XpTask>().eq("task_category", 2).in("handle_user_id", collect1)
                            .in("status", Arrays.asList(0, 1, 4)));
                    if(list1.size() > 0){
                        //对工号进行排序
                        List<String> collect2 = list1.stream().map(XpTask::getHandleUserId).collect(Collectors.toList());
                        //找出没有任务的人员
                        List<Long> collect3 = collect1.stream().filter(s -> !collect2.contains(s.toString())).collect(Collectors.toList());
                        //查询人员数据,对其进行工号排序
                        XpOperationsUserQueryDTO dto1 = new XpOperationsUserQueryDTO();
                        dto1.setIds(collect3);
                        List<XpOperationsUserWithRoleVO> data = xpOperationUserClient.findList(dto1).getData();
                        data.sort((o1, o2) -> o1.getUniqueNumber().compareTo(o2.getUniqueNumber()) * -1);
                        userId = data.get(0).getId();
                    }
                }
            }
            xpTask.setHandleUserId(userId.toString());
        }
        // 根据事故处理限时配置设置任务截止时间
        LocalDateTime endTime = LocalDateTime.now().plusMinutes(taskRule.getProcessingTimeLimit());
@@ -308,6 +364,21 @@
        return xpTask;
    }
    @Data
    class Operations {
        /**
         * 候选人id
         */
        private Long userId;
        /**
         * 距离
         */
        private Integer distance;
    }
    /**
     * 异步发送事故通知
     * @param xpTask 任务信息
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/utils/GDMapGeocodingUtil.java
@@ -1,19 +1,28 @@
package com.xiaopeng.maintenance.utils;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.api.dto.map.HistoryPointDto;
import com.xiaopeng.api.dto.operation.LonLatDto;
import com.xiaopeng.api.vo.operation.RouteVo;
import com.xiaopeng.common.core.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ForkJoinPool;
/**
 * 高德地图的地理编码工具类
 */
@Component
@Lazy
@Slf4j
public class GDMapGeocodingUtil {
    private String key = "66ae577f63898dae3016d599fda57221";
@@ -53,4 +62,93 @@
        return map;
    }
    /**
     * 根据起始点获取驾车距离 和 时间  以及避让区域
     *
     * @param start         起点
     * @param end           终点
     * @param avoidRoads    避让点
     * @param fenceId       mango id
     * @param routePlanRule 线路规划规则
     * @return
     * @throws Exception
     */
    public RouteVo getDistanceAndTime(LonLatDto start, LonLatDto end, ArrayList<JSONObject> avoidRoads, String fenceId, Integer routePlanRule, List<HistoryPointDto> history) {
        RouteVo routeVo = new RouteVo();
        String url = "https://tsapi.amap.com/v1/route/price?key=" + key + "&extensions=all&start=" + start.getLongitude() + "," + start.getLatitude();
        HashMap<String, Object> params = new HashMap<>();
        params.put("extensions", "all");
        params.put("start", start.getLongitude() + "," + start.getLatitude());
        params.put("end", end.getLongitude() + "," + end.getLatitude());
        params.put("routeUserType", 2);
        if (avoidRoads != null && !avoidRoads.isEmpty()) {
            params.put("avoidPolygons", avoidRoads);
        }
        if (routePlanRule != null) {
            params.put("strategy", routePlanRule);
        }
        if (null != history && !history.isEmpty()) {
            params.put("history", history);
        }
        log.info("高德地图接口:{}", url);
        log.info("高德地图参数:{}", JSON.toJSONString(params));
        String post = HttpUtils.post(url, JSON.toJSONString(params));
        log.info("高德地图返回结果:" + post);
        JSONObject jsonObject = JSON.parseObject(post);
        String data = jsonObject.getString("data");
        JSONObject jsonObject1 = JSON.parseObject(data);
        JSONArray path = jsonObject1.getJSONArray("paths");
        log.info("开始判断导航路径是否在运营区域范围内 {}", fenceId);
        log.info("先判断是否有大众常选的线路,优先选择大众常选的路线");
        for (Object o : path) {
            JSONObject jsonObject2 = (JSONObject) o;
            String routeID = jsonObject2.getString("routeID");
            String points = jsonObject2.getString("points");
            String label = jsonObject2.getString("label");
            if (label.contains("大众常选")) {
                String[] split = points.split(";");
                Integer costTime = jsonObject2.getInteger("costTime");
                Integer distance = jsonObject2.getInteger("distance");
                routeVo.setDistance(distance);
                routeVo.setDuration(costTime);
                ArrayList<LonLatDto> lonLatDtos = new ArrayList<>(split.length);
                for (String s : split) {
                    String[] split1 = s.split(",");
                    LonLatDto lonLatDto = new LonLatDto(Double.parseDouble(split1[0]), Double.parseDouble(split1[1]));
                    lonLatDtos.add(lonLatDto);
                }
                routeVo.setPolyline(lonLatDtos);
                routeVo.setRouteID(routeID);
                log.info("导航 {} 在 {} 运营区域内", routeVo.getRouteID(), fenceId);
                return routeVo;
            }
        }
        for (Object o : path) {
            JSONObject jsonObject2 = (JSONObject) o;
            String routeID = jsonObject2.getString("routeID");
            String points = jsonObject2.getString("points");
            String[] split = points.split(";");
            Integer costTime = jsonObject2.getInteger("costTime");
            Integer distance = jsonObject2.getInteger("distance");
            routeVo.setDistance(distance);
            routeVo.setDuration(costTime);
            ArrayList<LonLatDto> lonLatDtos = new ArrayList<>(split.length);
            for (String s : split) {
                String[] split1 = s.split(",");
                LonLatDto lonLatDto = new LonLatDto(Double.parseDouble(split1[0]), Double.parseDouble(split1[1]));
                lonLatDtos.add(lonLatDto);
            }
            routeVo.setPolyline(lonLatDtos);
            routeVo.setRouteID(routeID);
            log.info("导航 {} 在 {} 运营区域内", routeVo.getRouteID(), fenceId);
            return routeVo;
        }
        return null;
    }
}
xp-robotaxi-map-boot/src/test/java/com/xiaopeng/map/service/serviceimpl/XpStationServiceImplTest.java
New file
@@ -0,0 +1,27 @@
package com.xiaopeng.map.service.serviceimpl;
import com.xiaopeng.map.MapApplication;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.*;
/**
 * XpStationServiceImpl.isPolygonInPolygon 方法单元测试
 *
 * 测试场景:
 * 1. 正常情况 - 小多边形完全在大多边形内
 * 2. 边界情况 - 小多边形部分在大多边形外
 * 3. 边界情况 - 小多边形完全在大多边形外
 * 4. 边界情况 - 两个多边形相同
 * 5. 异常情况 - 空值或null输入
 * 6. 异常情况 - 无效的坐标格式
 * 7. 边界情况 - 点位数量不足
 */
@SpringBootTest
public class XpStationServiceImplTest {
}
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/test/OrderTest.java
New file
@@ -0,0 +1,68 @@
package com.xiaopeng.order.controller.test;
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
import com.xiaopeng.api.model.order.XpOrder;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.order.service.IXpOrderService;
import com.xiaopeng.unifiedverification.interceptor.XpClientCheck;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("/base/test")
@Api(tags = "订单测试")
public class OrderTest {
    @Resource
    private MongoTemplate mongoTemplate;
    @Resource
    private  IXpOrderService xpOrderService;
    @Resource
    private  XpVehicleClient xpVehicleClient;
    /**
     * 分享行程接口2-订单查询轨迹路线
     */
    @ApiOperation(value = "分享行程接口2-订单查询轨迹路线")
    @PostMapping("/mongo/saveVehiclePosition")
    @XpClientCheck(checkToken = false, checkOtpToken = false)
    public R upateOrderState(@RequestBody XpOrder  param) {
        XpOrder xpOrder = xpOrderService.getById(param.getId());
        // 查询车辆
        XpVehicle xpVehicle = xpVehicleClient.queryById(param.getVehicleId()).getData();
        xpOrder.setVehicleId(xpVehicle.getId());
        xpOrder.setFleetId(xpVehicle.getFleetId());
        xpOrderService.updateById(xpOrder);
        VehiclePosition vehiclePosition = new VehiclePosition();
        vehiclePosition.setVin(xpVehicle.getVehicleVin());
        vehiclePosition.setPoint(new GeoJsonPoint(xpOrder.getStartLon(), xpOrder.getStartLat()));
        vehiclePosition.setCourse(60D);
        vehiclePosition.setAlt(100F);
        vehiclePosition.setSpeed(50F);
        vehiclePosition.setCurrentElectricity(80);
        vehiclePosition.setMileageRange(300f);
        vehiclePosition.setHasOrder(0);
        vehiclePosition.setOrderId(param.getId());
        mongoTemplate.save(vehiclePosition);
        return R.ok();
    }
}
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/webSocket/handler/PositionMsgHandler.java
@@ -1,5 +1,7 @@
package com.xiaopeng.pushMessage.webSocket.handler;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xiaopeng.api.dto.account.XpOperationsUserPositionDTO;
@@ -16,6 +18,10 @@
@Slf4j
public class PositionMsgHandler implements BusinessMsgHandler{
    @Autowired
    private MongoTemplate mongoTemplate;
    @Override
    public String getMessageType() {
        return "position";
@@ -23,36 +29,35 @@
    @Override
    public void handle(String uid, String msg) {
        XpOperationsUserPositionDTO xpOperationsUserPositionDTO;
        try {
            xpOperationsUserPositionDTO = om.readValue(msg, XpOperationsUserPositionDTO.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        if (null != xpOperationsUserPositionDTO) {
            xpOperationsUserPositionDTO.setId(Long.parseLong(uid));
            saveToMongo(xpOperationsUserPositionDTO);
        JSONObject jsonObject = JSON.parseObject(msg);
        if (null != jsonObject) {
            saveToMongo(uid, jsonObject);
        }
    }
    @Autowired ObjectMapper om;
    @Autowired MongoTemplate mongoTemplate;
    private void saveToMongo(XpOperationsUserPositionDTO dto) {
        XpOperationsUserPositionDTO vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("id").is(dto.getId())), XpOperationsUserPositionDTO.class);
    private void saveToMongo(String uid, JSONObject jsonObject) {
        Double latitude = jsonObject.getDouble("latitude");
        Double longitude = jsonObject.getDouble("longitude");
        XpOperationsUserPositionDTO vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("id").is(uid)), XpOperationsUserPositionDTO.class);
        if (null == vehiclePosition) {
            GeoJsonPoint location = new GeoJsonPoint(dto.getLongitude(), dto.getLatitude());
            dto.setLocation(location);
            mongoTemplate.save(dto);
            vehiclePosition = new XpOperationsUserPositionDTO();
            GeoJsonPoint location = new GeoJsonPoint(longitude, latitude);
            vehiclePosition.setLocation(location);
            vehiclePosition.setId(Long.parseLong(uid));
            vehiclePosition.setLatitude(latitude);
            vehiclePosition.setLongitude(longitude);
            vehiclePosition.setLocation(location);
            mongoTemplate.save(vehiclePosition);
        }else{
            Update update = new Update()
                    .set("id",dto.getId())
                    .set("latitude", dto.getLatitude())
                    .set("longitude", dto.getLongitude());
            double[] location = {dto.getLongitude(), dto.getLatitude()};
                    .set("id", Long.parseLong(uid))
                    .set("latitude", latitude)
                    .set("longitude", longitude);
            GeoJsonPoint location = new GeoJsonPoint(longitude, latitude);
            update.set("location", location);
            mongoTemplate.updateFirst(new Query(Criteria.where("id").is(dto.getId())), update, XpOperationsUserPositionDTO.class);
            mongoTemplate.updateFirst(new Query(Criteria.where("id").is(Long.parseLong(uid))), update, XpOperationsUserPositionDTO.class);
        }
        log.info("保存位置信息成功:id:{},longitude:{},latitude:{}", dto.getId(), dto.getLongitude(),dto.getLatitude());
        log.info("保存位置信息成功:id:{},longitude:{},latitude:{}", uid, longitude, latitude);
    }
}
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/webSocket/handler/WebSocketTextFrameHandler.java
@@ -76,6 +76,7 @@
                handleBusinessMessage(ctx, messageObj);
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 如果不是JSON格式,按普通文本处理
            log.debug("消息不是JSON格式,按普通文本处理: {}", message);
            ctx.channel().writeAndFlush(new TextWebSocketFrame("服务器时间: " + LocalDateTime.now() + "->" + message));