puzhibing
2026-05-09 41ecbff2b97d26ce821edf6d4cb050e8f9fdf6f3
Merge remote-tracking branch 'origin/1.0' into 1.0
33个文件已修改
375 ■■■■■ 已修改文件
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpUserRoutePlanRuleController.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/account/XpOperationsUserPositionDTO.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/enums/RouteStrategyKind.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/vehicleConvoy/XpFleetOperationsClientFallbackFactory.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/vehicleConvoy/XpFleetOperationsClient.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpVehicleModel.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/vehicleConvoy/XpFleetOperations.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/account/OptionalUsersPageListQuery.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/XpPointSituationReportQuery.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/XpOperationsUserWithRoleVO.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/MultiRouteAndFareVo.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/RouteAndFareVo.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/RouteOptionVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/TaskUtil.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleModelController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/mapper/XpVehicleModelMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpVehicleModelService.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpCruiseCheckInRuleServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpVehicleModelServiceImpl.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/exportExcle/XpPointSituationReportExportExcel.java 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPointSituationReportServiceImpl.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpPointSituationReportMapper.xml 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/test/OrderTest.java 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/webSocket/handler/PositionMsgHandler.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetOperationsController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/mapper/XpFleetOperationsMapper.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/IXpFleetOperationsService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetOperationsServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-vehicle-convoy-boot/src/main/resources/mapper/vehicleConvoy/XpFleetOperationsMapper.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/controller/XpUserRoutePlanRuleController.java
@@ -2,12 +2,20 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaopeng.account.model.vo.XpAppUserCouponListVo;
import com.xiaopeng.account.service.IXpUserRoutePlanRuleService;
import com.xiaopeng.api.model.account.XpUserRoutePlanRule;
import com.xiaopeng.api.query.account.XpAppUserCouponPageListQuery;
import com.xiaopeng.api.vo.operation.RoutePreferenceItemVo;
import com.xiaopeng.common.core.domain.R;
import com.xiaopeng.common.core.web.page.PageInfo;
import com.xiaopeng.unifiedverification.interceptor.XpClientCheck;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
@@ -33,4 +41,15 @@
        return R.ok(one);
    }
    @PostMapping("/v1/api/mini-program/userRoutePlanRule/getXpUserRoutePlanRule")
    @ApiOperation(value = "获取用户导航偏好设置",tags = {"小程序-获取用户导航偏好设置"},response = XpUserRoutePlanRule.class)
    @XpClientCheck(checkToken = false, checkOtpToken = true)
    public R<XpUserRoutePlanRule> listRoutePreferences( HttpServletRequest request) {
        String uid = request.getHeader("XP-Uid");
        XpUserRoutePlanRule one = xpUserRoutePlanRuleService.getOne(new LambdaQueryWrapper<XpUserRoutePlanRule>().eq(XpUserRoutePlanRule::getUserId, uid)
                .eq(XpUserRoutePlanRule::getDeleted, 0));
        return R.ok(one);
    }
}
xp-robotaxi-account-boot/src/main/resources/mapper/account/XpOperationsUserMapper.xml
@@ -135,7 +135,19 @@
        </where>
        GROUP BY u.id
        ORDER BY u.create_time DESC
        <choose>
            <when test="query.orderByField != null and  query.orderByField == 1">
                ORDER BY FIELD
                <foreach collection="query.ids" item="id" open=" (u.id," separator="," close=")">
                    #{id}
                </foreach>
            </when>
            <otherwise>
                ORDER BY u.create_time DESC
            </otherwise>
        </choose>
    </select>
</mapper>
xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/account/XpOperationsUserPositionDTO.java
@@ -11,6 +11,9 @@
import org.springframework.data.mongodb.core.index.GeoSpatialIndexType;
import org.springframework.data.mongodb.core.index.GeoSpatialIndexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
/**
 * 运维人员查询条件DTO
@@ -36,6 +39,10 @@
    @ApiModelProperty(value = "纬度")
    private double longitude;
    @ApiModelProperty(value = "时间")
    private Long updateTime;
    @GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE)
    private GeoJsonPoint location;
xp-robotaxi-api/src/main/java/com/xiaopeng/api/enums/RouteStrategyKind.java
@@ -95,6 +95,10 @@
        return Optional.ofNullable(AMAP_STRATEGY_INDEX.get(strategy));
    }
    public static RouteStrategyKind getStrategy(int strategy) {
        return AMAP_STRATEGY_INDEX.get(strategy);
    }
    public static List<RouteStrategyKind> orderedValues() {
        return ORDERED_VALUES;
    }
xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/vehicleConvoy/XpFleetOperationsClientFallbackFactory.java
@@ -5,10 +5,16 @@
import com.xiaopeng.api.model.vehicleConvoy.XpFleetOperations;
import com.xiaopeng.common.core.domain.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
@@ -37,6 +43,12 @@
            }
            @Override
            public R<List<XpFleetOperations>> findListByUserIds(@RequestBody List<Long> userIds){
                log.error("根据人员id 获取所属车队,人员IDs: {},原因: {}", userIds.toString(), cause.getMessage());
                return R.ok(new ArrayList<>());
            }
            @Override
            public R<List<Long>> getFleetIdsByUserId(Long userId) {
                log.error("根据人员ID获取车队信息失败 {}",  cause.getMessage());
                return R.fail("根据人员ID获取车队信息失败");
xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/vehicleConvoy/XpFleetOperationsClient.java
@@ -42,6 +42,14 @@
    R<List<XpFleet>> getFleetByUserId(@PathVariable("id") Long id);
    /**
     * 根据人员id 获取所属车队
     * @param userIds 运维人员id
     * @return
     */
    @PostMapping("/logan/inner/fleet-operations/findListByUserIds")
    R<List<XpFleetOperations>> findListByUserIds(@RequestBody List<Long> userIds);
    /**
     * 根据运维人员ID查询关联的车队ID列表
     *
     * @param userId 运维人员ID
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/maintenance/XpVehicleModel.java
@@ -25,7 +25,7 @@
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.NONE)
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty(value = "名称")
    @NotBlank(message = "名称不能为空")
xp-robotaxi-api/src/main/java/com/xiaopeng/api/model/vehicleConvoy/XpFleetOperations.java
@@ -1,5 +1,6 @@
package com.xiaopeng.api.model.vehicleConvoy;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
@@ -35,4 +36,8 @@
    private Long operationsUserId;
    @ApiModelProperty(value = "车队名称")
    @TableField(exist = false)
    private String fleetName;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/account/OptionalUsersPageListQuery.java
@@ -18,4 +18,7 @@
    List<Long> ids;
    //null默认 1=ids
    Integer orderByField;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/query/operation/XpPointSituationReportQuery.java
@@ -22,7 +22,7 @@
    @ApiModelProperty(value = "点位编号唯一")
    private String pointNumber;
    @ApiModelProperty(value = "点位状态值")
    @ApiModelProperty(value = "点位状态值 1待测试 2测试中 3测试不通过 4可运营 5待生效 6启用中 7已停用 8失效")
    private String pointStatusValue;
    /**
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/account/XpOperationsUserWithRoleVO.java
@@ -24,4 +24,8 @@
    @ApiModelProperty(value = "和事故地点距离")
    private Double dis;
    @ApiModelProperty(value = "车队名")
    private String fleetName;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/MultiRouteAndFareVo.java
@@ -32,4 +32,5 @@
    private Double priceWaveThresholdPercent;
    @ApiModelProperty(value = "是否开启试运营(0=否,1=是)")
    private Integer operateFree;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/RouteAndFareVo.java
@@ -33,6 +33,8 @@
    @ApiModelProperty(value = "策略id")
    private Integer amapStrategy;
    @ApiModelProperty(value = "交通信号灯")
    private Integer trafficLights;
}
xp-robotaxi-api/src/main/java/com/xiaopeng/api/vo/operation/RouteOptionVo.java
@@ -27,6 +27,8 @@
    @ApiModelProperty("主策略对应的高德 strategy,用于下单/队列")
    private Integer primaryRoutePlanRule;
    @ApiModelProperty(value = "导航策略名称")
    private String primaryRoutePlanName;
    @ApiModelProperty("路线几何与耗时距离")
    private RouteVo route;
@@ -39,4 +41,5 @@
    @ApiModelProperty("优惠券不可用时的提示(无可用券时)")
    private String couponMessage;
}
xp-robotaxi-automatic-pilot-boot/src/main/java/com/xiaopeng/automaticPilot/util/TaskUtil.java
@@ -19,7 +19,7 @@
    private MongoTemplate mongoTemplate;
    //删除过期的车辆定位数据
    @Scheduled(cron = "0/30 * * * * ?")
//    @Scheduled(cron = "0/30 * * * * ?")
    public void task() {
        log.info("执行删除无效的车辆定位数据");
        mongoTemplate.remove(Query.query(Criteria.where("addTime").isNull()), VehiclePosition.class);
xp-robotaxi-itinerary-boot/src/main/java/com/xiaopeng/itinerary/service/impl/XpPricingServiceImpl.java
@@ -1107,6 +1107,7 @@
        fareVo.setSystemDiscount(new BigDecimal(fareVo.getSystemDiscount() == null ? 0 : fareVo.getSystemDiscount()).setScale(2, RoundingMode.HALF_UP).doubleValue());
        routeAndFareVo.setFareEstimate(fareVo);
        routeAndFareVo.getXpPricingCard().setFinalFareStr(fareVo.getFinalFareStr());
//        routeAndFareVo.setTrafficLights();//交通信号灯 todo 20260508 红绿灯功能还没有
        fareVo.setId(null);
        return routeAndFareVo;
    }
@@ -1136,7 +1137,7 @@
            throw new ServiceException("当前区域未开通服务", I18nKeyConstant.NO_CURRENT_REGION);
        }
        StrategyPlanningConfig planningConfig = buildStrategyKindsForPlanning(userId, routeAndFareDto.getOpenCityId());
        StrategyPlanningConfig planningConfig = this.buildStrategyKindsForPlanning(userId, routeAndFareDto.getOpenCityId());
        List<RouteStrategyKind> kinds = planningConfig.getKinds();
        Map<String, RouteVo> routeById = new LinkedHashMap<>();
        Map<String, Set<RouteStrategyKind>> strategiesById = new LinkedHashMap<>();
@@ -1186,6 +1187,7 @@
            opt.setStrategyLabels(labels);
            opt.setPrimaryStrategyLabel(resolveStrategyDisplayName(primary, planningConfig.getDisplayNames()));
            opt.setPrimaryRoutePlanRule(primary.getAmapStrategy());
            opt.setPrimaryRoutePlanName(primary.getDisplayName());
            opt.setRoute(part.getRoute());
            opt.setFareEstimate(part.getFareEstimate());
            opt.setXpPricingCard(part.getXpPricingCard());
@@ -1195,6 +1197,15 @@
            opt.setOperateFree(operateFree);
            options.add(opt);
        }
        // 根据 pathFingerprint 去重,保留第一次出现的路线
//        options = new ArrayList<>(options.stream()
//                .collect(Collectors.toMap(
//                        RouteOptionVo::getPathFingerprint,
//                        option -> option,
//                        (existing, replacement) -> existing,
//                        LinkedHashMap::new
//                )).values());
        RouteStrategyKind userPref = resolveUserPreferredKind(userId).orElse(RouteStrategyKind.SMART);
        options.sort((a, b) -> compareRouteOptionByUserPreference(a, b, userPref, strategiesById));
@@ -1299,22 +1310,25 @@
    @Override
    public List<RoutePreferenceItemVo> listRoutePreferences(Long openCityId, String userId) {
        Set<String> enabledCodes = parseEnabledPreferenceCodes();
        Optional<RouteStrategyKind> savedPref = resolveUserPreferredKind(userId);
        Map<RouteStrategyKind, String> displayNames = buildStrategyKindsForPlanning(userId, openCityId).getDisplayNames();
        Optional<RouteStrategyKind> savedPref = resolveUserPreferredKind(userId);//获取用户设置的路线偏好
        List<XpRoutePlan> routePlans = findRoutePlans(openCityId);
        List<RoutePreferenceItemVo> list = new ArrayList<>();
        int i = 0;
        for (RouteStrategyKind k : RouteStrategyKind.orderedValues()) {
            if (!enabledCodes.contains(k.name())) {
                continue;
        if(CollUtil.isNotEmpty(routePlans)){
            int i = 0;
            for (XpRoutePlan routePlan : routePlans) {
                RoutePreferenceItemVo v = new RoutePreferenceItemVo();
                RouteStrategyKind strategy = RouteStrategyKind.getStrategy(routePlan.getRoutePlanRule());
                if(strategy != null){
                    v.setCode(strategy.name());
                }
                v.setName(routePlan.getPlanName());
                v.setEnabled(true);
                v.setSortOrder(i++);
                v.setAmapStrategy(routePlan.getRoutePlanRule());
                v.setSelected(savedPref.isPresent() && strategy == savedPref.get());
                list.add(v);
            }
            RoutePreferenceItemVo v = new RoutePreferenceItemVo();
            v.setCode(k.name());
            v.setName(resolveStrategyDisplayName(k, displayNames));
            v.setEnabled(true);
            v.setSortOrder(i++);
            v.setAmapStrategy(k.getAmapStrategy());
            v.setSelected(savedPref.isPresent() && k == savedPref.get());
            list.add(v);
        }
        return list;
    }
@@ -1346,11 +1360,17 @@
        return set;
    }
    private List<XpRoutePlan> findRoutePlans (Long openCityId){
        return xpRoutePlanMapper.selectList(new LambdaQueryWrapper<XpRoutePlan>().eq(XpRoutePlan::getOpenCityId, openCityId)
                .eq(XpRoutePlan::getAuditStatus, 2));
    }
    /**
     * 用户偏好策略优先请求,其余策略仍请求以便合并去重。
     */
    private StrategyPlanningConfig buildStrategyKindsForPlanning(String userId, Long openCityId) {
        List<XpRoutePlan> xpRoutePlans = xpRoutePlanMapper.selectList(new LambdaQueryWrapper<XpRoutePlan>().eq(XpRoutePlan::getOpenCityId, openCityId));
        List<XpRoutePlan> xpRoutePlans = xpRoutePlanMapper.selectList(new LambdaQueryWrapper<XpRoutePlan>().eq(XpRoutePlan::getOpenCityId, openCityId)
                .eq(XpRoutePlan::getAuditStatus, 2));
        Map<RouteStrategyKind, String> displayNames = new LinkedHashMap<>();
        List<RouteStrategyKind> configuredKinds = new ArrayList<>();
        if (xpRoutePlans.isEmpty()) {
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpTaskController.java
@@ -3,6 +3,8 @@
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.xiaopeng.api.dto.account.XpOperationsUserPositionDTO;
@@ -14,6 +16,8 @@
import com.xiaopeng.api.model.maintenance.XpErrorType;
import com.xiaopeng.api.model.maintenance.XpTask;
import com.xiaopeng.api.model.maintenance.XpTaskRule;
import com.xiaopeng.api.model.vehicleConvoy.XpFleet;
import com.xiaopeng.api.model.vehicleConvoy.XpFleetOperations;
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
import com.xiaopeng.api.query.account.OptionalUsersPageListQuery;
import com.xiaopeng.api.vo.XpTaskVO;
@@ -21,6 +25,7 @@
import com.xiaopeng.api.vo.account.XpOperationsUserWithRoleVO;
import com.xiaopeng.api.vo.automaticPilot.VehiclePosition;
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.service.TokenService;
import com.xiaopeng.evi.oss.service.AliOssService;
@@ -65,6 +70,7 @@
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -370,27 +376,64 @@
        Query query = Query.query(new Criteria().andOperator(
                Criteria.where("location").withinSphere(circle)
        ));
        // 增加时间查询条件:最近1分钟更新的数据
        int  time = 10*60*1000;
        Long oneMinuteAgo = System.currentTimeMillis() - time;
        query.addCriteria(Criteria.where("updateTime").gte(oneMinuteAgo));
        List<XpOperationsUserPositionDTO> vehiclePositions = mongoTemplate.find(query, XpOperationsUserPositionDTO.class);
        Map<Long, Double> disMap = vehiclePositions.stream().collect(Collectors.toMap(XpOperationsUserPositionDTO::getId, XpOperationsUserPositionDTO::getDistance));
        // 查询车队下面面所有人员id和up求交集
        List<Long> data = xpFleetClient.idsByFleetName(query1.getFleet()).getData();
        List<Long> ids = vehiclePositions.stream().map(XpOperationsUserPositionDTO::getId)
                .filter(e -> data == null || data.isEmpty() || data.contains(e))
                .collect(Collectors.toList());
        if(CollUtil.isEmpty(vehiclePositions)){
            throw new ServiceException("未查询到运维人员");
        }
        List<Long> data = null ;
        if(StrUtil.isNotBlank(query1.getFleet())){
            // 查询车队下面面所有人员id和up求交集
            data = xpFleetClient.idsByFleetName(query1.getFleet()).getData();
        }
        //vehiclePositions根据距离升序排序
        vehiclePositions.sort(Comparator.comparing(XpOperationsUserPositionDTO::getDistance));
        //获取运维人员id
        List<Long> ids = new ArrayList<>();
        Map<Long, Double> disMap = new HashMap<>();
        if (  CollUtil.isNotEmpty(data)  ) {
            for (XpOperationsUserPositionDTO vehiclePosition : vehiclePositions) {
                if(data.contains(vehiclePosition.getId())){
                    ids.add(vehiclePosition.getId());
                    disMap.put(vehiclePosition.getId(), vehiclePosition.getDistance());
                }
            }
        }else{
            for (XpOperationsUserPositionDTO vehiclePosition : vehiclePositions) {
                ids.add(vehiclePosition.getId());
                disMap.put(vehiclePosition.getId(), vehiclePosition.getDistance());
            }
        }
        query1.setIds(ids);
        query1.setOrderByField(1);
        PageInfo<XpOperationsUserWithRoleVO> ret = operationUserClient.listByQueryIds(query1).getData();
        // 设置距离,然后排序
        if (ret == null || ret.getRecords() == null || ret.getRecords().isEmpty()) {
            return R.ok();
        }
        if(CollUtil.isNotEmpty(ids)){
            R<List<XpFleetOperations>> findListByUserIdsR = xpFleetOperationsClient.findListByUserIds(ids);
            if(findListByUserIdsR.getCode() != R.SUCCESS || findListByUserIdsR.getData().isEmpty()){
                throw new ServiceException("未查询该车队");
            }
            // 将查询结果转换为 Map,key 为 userId,value 为 XpFleetOperations 对象
            Map<Long, XpFleetOperations> fleetOperationsMap = findListByUserIdsR.getData().stream()
                    .collect(Collectors.toMap(XpFleetOperations::getOperationsUserId, Function.identity()));
            for (XpOperationsUserWithRoleVO record : ret.getRecords()) {
                if(fleetOperationsMap.containsKey(record.getId())){
                    record.setFleetName(fleetOperationsMap.get(record.getId()).getFleetName());
                }
            }
        }
        ret.getRecords().forEach(e -> e.setDis(disMap.get(e.getId())));
        List<XpOperationsUserWithRoleVO> sorted = ret.getRecords().stream().sorted(Comparator.comparing(XpOperationsUserWithRoleVO::getDis)).collect(Collectors.toList());
        ret.setRecords(sorted);
//        List<XpOperationsUserWithRoleVO> sorted = ret.getRecords().stream().sorted(Comparator.comparing(XpOperationsUserWithRoleVO::getDis)).collect(Collectors.toList());
//        ret.setRecords(sorted);
        return R.ok(ret);
    }
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleModelController.java
@@ -69,7 +69,7 @@
    public R<String> add(@RequestBody @Valid XpVehicleModel dto) {
        // 根据名称查询车辆型号,验证是否已存在
        List<XpVehicleModel> existingModel = xpVehicleModelService.queryByName(dto.getName());
        if (existingModel != null) {
        if (CollUtil.isNotEmpty(existingModel)) {
            return R.fail("车辆型号名称已存在");
        }
        boolean b = xpVehicleModelService.save(dto);
@@ -91,7 +91,7 @@
        }
        if(!model.getName().equals(dto.getName())){
            List<XpVehicleModel> existingModel = xpVehicleModelService.queryByName(dto.getName());
            if (existingModel != null) {
            if (CollUtil.isNotEmpty(existingModel)) {
                return R.fail("车辆型号名称已存在");
            }
        }
@@ -104,7 +104,7 @@
    @ApiOperation(value = "车型删除", tags = "管理后台-资产-车型管理")
    @DeleteMapping("/logan/inner/xpVehicleModel/deleteById")
    public R<String> deleteById(@RequestParam String id) {
    public R<String> deleteById(@RequestParam Long id) {
        /*
        1.判断车型是否被 车辆 xp_vehicle使用。
        2.判断车型是否被 定价管理 xp_pricing使用。
@@ -113,14 +113,14 @@
        if (vehicleCount > 0) {
            return R.fail("车辆型号已被车辆使用");
        }
        R<Long> priceCountByVmidR = xpPricingClient.getPriceCountByVmid(id);
        R<Long> priceCountByVmidR = xpPricingClient.getPriceCountByVmid(id+"");
        if (priceCountByVmidR.getCode() != R.SUCCESS || priceCountByVmidR.getData() == null) {
            return R.fail("根据车型获取定价策略失败");
        }
        if(priceCountByVmidR.getData()>0){
            return R.fail("车辆型号已被定价策略使用");
        }
        boolean b = xpVehicleModelService.logicalRemoveById(id);
        boolean b = xpVehicleModelService.removeById(id);
        if(b){
            return R.ok();
        }
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/mapper/XpVehicleModelMapper.java
@@ -27,6 +27,6 @@
     * @param id
     * @return
     */
    int getVehicleCount(String id);
    int getVehicleCount(Long id);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/IXpVehicleModelService.java
@@ -16,7 +16,7 @@
    List<XpVehicleModel> queryList();
    boolean logicalRemoveById(String id);
    boolean logicalRemoveById(Long id);
    int getVehicleCount(String id);
    int getVehicleCount(Long id);
}
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpCruiseCheckInRuleServiceImpl.java
@@ -312,6 +312,14 @@
        if(null != one){
            throw new ServiceException("巡游打卡规则名称已存在");
        }
        // 校验同一运维人员是否已存在有效规则(未删除且非循环模式或时间在有效期内)
        long count = this.count(new LambdaQueryWrapper<XpCruiseCheckInRule>()
                .eq(XpCruiseCheckInRule::getOperationsUserId, dto.getRelationId())
                .eq(XpCruiseCheckInRule::getDeleted, false));
        if (count > 0) {
            throw new ServiceException("该运维人员已存在有效的巡游打卡规则");
        }
        XpCruiseCheckInRule xpCruiseCheckInRule = new XpCruiseCheckInRule();
        BeanUtils.copyProperties(dto, xpCruiseCheckInRule);
        xpCruiseCheckInRule.setDeleted(false);
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
@@ -16,7 +16,6 @@
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;
@@ -68,6 +67,7 @@
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.redisson.api.RLock;
@@ -75,7 +75,6 @@
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
@@ -296,6 +295,9 @@
            List<Long> userIds = xpOperationsRoleResult.getData().stream().filter(x -> ids.contains(x.getOperationsUserId()))
                    .map(XpOperationsRole::getOperationsUserId)
                    .distinct().collect(Collectors.toList());
            if(CollUtil.isEmpty(userIds)){
                throw new ServiceException("未配置车队运维人员");
            }
            //获取首选人的实时定位,计算每个人到事故车辆位置的导航距离
            List<Operations> operationsList = new ArrayList<>();
            for (Long userId : userIds) {
@@ -1476,8 +1478,13 @@
        }
        List<XpTask.Reject> rejects = Optional.ofNullable(task.getExcluded()).orElse(new ArrayList<>());
        XpTask.Reject reject = task.reject(msg);
        rejects.add(reject);
        if(msg != null && Strings.isNotBlank(task.getHandleUserId())) {
            XpTask.Reject reject = task.reject(msg);
            rejects.add(reject);
            List<Long> id = Collections.singletonList(Long.parseLong(task.getHandleUserId()));
            String roleName = xpOperationUserClient.listByIdsWithRole(id).getData().get(0).getRoleName();
            reject.setRejectUserRoleName(roleName);
        }
        task.setExcluded(rejects);
        task.setReassignmentStatus(1);
        task.setStatus(4);
@@ -1493,9 +1500,9 @@
                .map(String::valueOf).collect(Collectors.joining(","));
//        VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vehicle.getVehicleVin())), VehiclePosition.class);
        VehiclePosition vehiclePosition = new VehiclePosition();
        vehiclePosition.setPoint(new GeoJsonPoint(103.12615621, 30.264561));
        VehiclePosition vehiclePosition = mongoTemplate.findOne(new Query(Criteria.where("vin").is(vehicle.getVehicleVin())), VehiclePosition.class);
//        VehiclePosition vehiclePosition = new VehiclePosition();
//        vehiclePosition.setPoint(new GeoJsonPoint(103.12615621, 30.264561));
        String handlerUser = chooseNearestAvailableOperationsUser(belongUserIds, vehiclePosition);
        task.setHandleUserId(handlerUser);
        if(handlerUser == null) {
@@ -1505,9 +1512,6 @@
        }
        updateById(task);
        if(StringUtils.isNotBlank(task.getHandleUserId())){
            List<Long> id = Collections.singletonList(Long.parseLong(task.getHandleUserId()));
            String roleName = xpOperationUserClient.listByIdsWithRole(id).getData().get(0).getRoleName();
            reject.setRejectUserRoleName(roleName);
            sendAccidentNotificationAsync(task, vehicle.getPlateNumber(), taskRule.getProcessingTimeLimit());
        }
    }
@@ -1563,7 +1567,7 @@
        task.setCreateTime(LocalDateTime.now());
        this.save(task);
        // 异步发送消息通知
        sendAccidentNotificationAsync(task, vehicle.getPlateNumber(), taskRule.getProcessingTimeLimit());
         sendAccidentNotificationAsync(task, vehicle.getPlateNumber(), taskRule.getProcessingTimeLimit());
    }
    @Override
@@ -1718,6 +1722,7 @@
    }
    @Override
    @Transactional
    public void saveTask(SaveErrorTaskDto dto, Long reportUserId) {
        List<XpTask> saveTask = new ArrayList<>();
@@ -1748,6 +1753,10 @@
        }
        this.saveBatch(saveTask);
        for (XpTask task : saveTask) {
            reassign(task.getId(),null);
        }
    }
    @Override
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpVehicleModelServiceImpl.java
@@ -29,7 +29,7 @@
    public List<XpVehicleModel> queryByName(String name) {
        return this.list(new LambdaQueryWrapper<XpVehicleModel>()
                .eq(XpVehicleModel::getDeleted, 0)
                .like(XpVehicleModel::getName, name));
                .eq(XpVehicleModel::getName, name));
    }
    /**
@@ -42,13 +42,13 @@
    }
    @Override
    public boolean logicalRemoveById(String id) {
//        XpVehicleModel entity = this.getById(id);
//        if (entity != null) {
//            entity.setDeleted(true);
//            return this.updateById(entity);
//        }
        return this.removeById(id);
    public boolean logicalRemoveById(Long id) {
        XpVehicleModel entity = this.getById(id);
        if (entity != null) {
            entity.setDeleted(true);
            return this.updateById(entity);
        }
        return true;
    }
    /**
     * 获取指定车型ID关联的车辆数量
@@ -57,7 +57,7 @@
     * @return 车辆数量
     */
    @Override
    public int getVehicleCount(String id){
    public int getVehicleCount(Long id){
        return this.baseMapper.getVehicleCount(id);
    }
    
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/exportExcle/XpPointSituationReportExportExcel.java
@@ -31,7 +31,7 @@
     * 现场情况说明
     */
    @ApiModelProperty("现场情况说明")
    @Excel(name = "现场情况说明",width = 20)
    @Excel(name = "异常情况说明",width = 20)
    private String sceneDescription;
@@ -40,7 +40,7 @@
    private String operationsUserName;
    @ApiModelProperty("上报时间")
    @Excel(name = "序号",width = 20)
    @Excel(name = "上报时间",width = 20)
    private String reportingTimeStr;
}
xp-robotaxi-operation-boot/src/main/java/com/xiaopeng/operation/service/impl/XpPointSituationReportServiceImpl.java
@@ -53,6 +53,9 @@
                query.setOperationsUserIds(ListUtil.toList(0L));
            }
        }
        if(query.getReportingTimeEnd() != null  ){
            query.setReportingTimeEnd(query.getReportingTimeEnd().plusDays(1));
        }
        // 创建分页对象
        PageInfo<XpPointSituationReportVo> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize());
        // 调用Mapper查询
xp-robotaxi-operation-boot/src/main/resources/mapper/operation/XpPointSituationReportMapper.xml
@@ -27,7 +27,39 @@
        <if test="query.pointNumber != null and query.pointNumber != ''">
            AND b.point_number LIKE CONCAT('%', #{query.pointNumber}, '%')
        </if>
        <if test="query.fieldSituation != null and query.fieldSituation != ''">
<!--        点位状态值 1待测试 2测试中 3测试不通过 4可运营 5待生效 6启用中 7已停用 8失效 -->
        <if test="query.pointStatusValue != null ">
          <choose>
              <!-- verification_status 验证状态 1=待验证、2=验证中、3=已验证 4验证失败 5待生效 -->
              <!-- operation_status 运营状态 1=待启用 2=启用中 3=已停用 4=已失效 -->
              <when test="query.pointStatusValue == 1">
                  AND b.verification_status = 1
              </when>
              <when test="query.pointStatusValue == 2">
                  AND b.verification_status = 2
              </when>
              <when test="query.pointStatusValue == 3">
                  AND b.verification_status = 4
              </when>
              <when test="query.pointStatusValue == 4">
                  AND b.verification_status = 3
              </when>
              <when test="query.pointStatusValue == 5">
                  AND b.verification_status = 5 and b.operation_status = 1
              </when>
              <when test="query.pointStatusValue == 6">
                  AND b.verification_status = 5 and b.operation_status = 2
              </when>
              <when test="query.pointStatusValue == 7">
                  AND b.verification_status = 5 and b.operation_status = 3
              </when>
              <when test="query.pointStatusValue == 8">
                  AND b.verification_status = 5 and b.operation_status = 4
              </when>
          </choose>
        </if>
        <if test="query.fieldSituation != null  or query.fieldSituation == 0">
            AND a.field_situation = #{query.fieldSituation}
        </if>
        <if test="query.operationsUserId != null and query.operationsUserId != ''">
@@ -43,7 +75,7 @@
            AND a.reporting_time &gt;= #{query.reportingTimeStart}
        </if>
        <if test="query.reportingTimeEnd != null">
            AND a.reporting_time &lt;= #{query.reportingTimeEnd}
            AND a.reporting_time &lt; #{query.reportingTimeEnd}
        </if>
        ORDER BY a.create_time DESC
    </select>
xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/controller/test/OrderTest.java
@@ -59,6 +59,7 @@
        vehiclePosition.setMileageRange(300f);
        vehiclePosition.setHasOrder(0);
        vehiclePosition.setOrderId(param.getId());
        vehiclePosition.setAddTime(System.currentTimeMillis()+100000);
        mongoTemplate.save(vehiclePosition);
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/webSocket/handler/PositionMsgHandler.java
@@ -14,6 +14,8 @@
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
@Slf4j
public class PositionMsgHandler implements BusinessMsgHandler{
@@ -47,12 +49,14 @@
            vehiclePosition.setLatitude(latitude);
            vehiclePosition.setLongitude(longitude);
            vehiclePosition.setLocation(location);
            vehiclePosition.setUpdateTime(System.currentTimeMillis());
            mongoTemplate.save(vehiclePosition);
        }else{
            Update update = new Update()
                    .set("id", Long.parseLong(uid))
                    .set("latitude", latitude)
                    .set("longitude", longitude);
                    .set("longitude", longitude)
                    .set("updateTime", System.currentTimeMillis());
            GeoJsonPoint location = new GeoJsonPoint(longitude, latitude);
            update.set("location", location);
            mongoTemplate.updateFirst(new Query(Criteria.where("id").is(Long.parseLong(uid))), update, XpOperationsUserPositionDTO.class);
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpFleetOperationsController.java
@@ -75,6 +75,20 @@
    /**
     * 根据人员id 获取所属车队
     *
     * @param userIds 运维人员id
     * @return
     */
    @PostMapping("/logan/inner/fleet-operations/findListByUserIds")
    public R<List<XpFleetOperations>> findListByUserIds(@RequestBody List<Long> userIds){
        List<XpFleetOperations> listByUserIds = xpFleetOperationsService.findListByUserIds(userIds);
        return R.ok(listByUserIds);
    }
    /**
     * 根据运维人员ID查询关联的车队ID列表(内部接口)
     *
     * @param userId 运维人员ID
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/mapper/XpFleetOperationsMapper.java
@@ -2,6 +2,9 @@
import com.xiaopeng.api.model.vehicleConvoy.XpFleetOperations;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
@@ -13,4 +16,6 @@
 */
public interface XpFleetOperationsMapper extends BaseMapper<XpFleetOperations> {
    List<XpFleetOperations> findListByUserIds(@Param("userIds") List<Long> userIds);
}
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/IXpFleetOperationsService.java
@@ -3,6 +3,8 @@
import com.xiaopeng.api.model.vehicleConvoy.XpFleetOperations;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
 * <p>
 * 车队人员中间表 服务类
@@ -13,4 +15,5 @@
 */
public interface IXpFleetOperationsService extends IService<XpFleetOperations> {
    List<XpFleetOperations> findListByUserIds(List<Long> userIds);
}
xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetOperationsServiceImpl.java
@@ -6,6 +6,8 @@
import com.xiaopeng.vehicleConvoy.service.IXpFleetOperationsService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * <p>
 * 车队人员中间表 服务实现类
@@ -17,4 +19,10 @@
@Service
public class XpFleetOperationsServiceImpl extends ServiceImpl<XpFleetOperationsMapper, XpFleetOperations> implements IXpFleetOperationsService {
    @Override
    public List<XpFleetOperations> findListByUserIds(List<Long> userIds){
        return  baseMapper.findListByUserIds(userIds);
    }
}
xp-robotaxi-vehicle-convoy-boot/src/main/resources/mapper/vehicleConvoy/XpFleetOperationsMapper.xml
@@ -2,4 +2,19 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xiaopeng.vehicleConvoy.mapper.XpFleetOperationsMapper">
    <select id="findListByUserIds" resultType="com.xiaopeng.api.model.vehicleConvoy.XpFleetOperations">
        SELECT a.*,b.fleet_name
        FROM xp_fleet_operations a
        INNER JOIN xp_fleet b on b.id = a.fleet_id
        where a.operations_user_id in
            <foreach collection="userIds" item="userId" open="(" separator="," close=")">
                #{userId}
            </foreach>
    </select>
</mapper>