xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/constant/I18nKeyConstant.java
@@ -18,6 +18,8 @@ String LOGIN_USERNAME_NOT_VALID = "login.username.not.valid"; String LOGIN_PASSWORD_NOT_VALID = "login.password.not.valid"; String LOGIN_BLACK_LIST = "login.black.list"; String ACCOUNT_NOT_EXISTS = "account.not.exists"; String LOGIN_ACCOUNT_DISABLED = "login.account.disabled"; //========== 帐号相关 ========== String ACCOUNT_PROFILE_UPDATE_ERROR = "account.profile.update.error"; xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysLoginService.java
@@ -61,7 +61,7 @@ // 查询用户信息 SysUser user = userService.selectUserByUserName(username); if (StringUtils.isNull(user)) { throw new ServiceException("登录失败,请稍后重试", I18nKeyConstant.LOGIN_FAIL); throw new ServiceException("帐号不存在或已被删除", I18nKeyConstant.ACCOUNT_NOT_EXISTS); } // 角色集合 Set<String> roles = permissionService.getRolePermission(user); @@ -105,9 +105,9 @@ recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "对不起,您的账号已被删除"); throw new ServiceException("对不起,您的账号:" + username + " 已被删除"); } if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { if (Integer.valueOf("1").equals(user.getStatus())) { recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_FAIL_STATUS, "用户已停用,请联系管理员"); throw new ServiceException("对不起,您的账号:" + username + " 已停用"); throw new ServiceException("您的账号:" + username + " 已禁用", I18nKeyConstant.LOGIN_ACCOUNT_DISABLED); } passwordService.validate(user, password, request); // recordLogService.recordLogininfor(request, user.getId().intValue(), username, Constants.LOGIN_SUCCESS_STATUS, "登录成功"); xp-robotaxi-account-boot/src/main/java/com/xiaopeng/account/service/impl/SysRoleServiceImpl.java
@@ -209,7 +209,9 @@ // 构建查询条件 LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>(); if (StringUtils.isNotBlank(query.getRoleName())) { wrapper.like(SysRole::getRoleName, query.getRoleName()); // 转义 LIKE 特殊字符:% _ \ String roleName = StringUtils.escapeLike(query.getRoleName()); wrapper.like(SysRole::getRoleName, roleName); } wrapper.orderByDesc(SysRole::getCreateTime); xp-robotaxi-account-boot/src/main/resources/i18n/messages.properties
@@ -7,6 +7,8 @@ login.username.not.valid=用户名不在指定范围 login.password.not.valid=用户密码不在指定范围 login.black.list=很遗憾,访问IP已被列入系统黑名单 account.not.exists=帐号不存在或已被删除 login.account.disabled=您的账号:{0}已禁用 account.profile.update.error=修改个人信息异常,请联系管理员 account.password.update.error=修改密码异常,请联系管理员 account.phone.duplicate=手机号已开通账号 @@ -24,7 +26,7 @@ validation.group.name.notBlank=组名称不能为空 validation.group.remarks.notBlank=备注不能为空 validation.group.type.notNull=分组类型不能为空 validation.group.menuIds.notEmpty=菜单id集合不能为空 validation.group.menuIds.notEmpty=请选择操作权限 validation.group.id.notNull=权限组ID不能为空 group.name.exists=权限组名称已存在 group.not.exists=权限组不存在 xp-robotaxi-account-boot/src/main/resources/i18n/messages_en_US.properties
@@ -7,6 +7,8 @@ login.username.not.valid=The username is not within the specified range login.password.not.valid=The user password is not within the specified range login.black.list=Regrettably, the access IP has been blacklisted by the system account.not.exists=The account does not exist or has been deleted login.account.disabled=Your account: {0} has been disabled account.profile.update.error=If there is an abnormality in modifying personal information, please contact the administrator account.password.update.error=Password modification is abnormal. Please contact the administrator account.phone.duplicate=The mobile phone number has been activated for an account @@ -24,7 +26,7 @@ validation.group.name.notBlank=Group name cannot be empty validation.group.remarks.notBlank=Remarks cannot be empty validation.group.type.notNull=Group type cannot be null validation.group.menuIds.notEmpty=Menu IDs cannot be empty validation.group.menuIds.notEmpty=Please select the operation permission validation.group.id.notNull=Group permission ID cannot be null group.name.exists=The group name already exists group.not.exists=Group is not exist xp-robotaxi-account-boot/src/main/resources/i18n/messages_zh_CN.properties
@@ -7,6 +7,8 @@ login.username.not.valid=用户名不在指定范围 login.password.not.valid=用户密码不在指定范围 login.black.list=很遗憾,访问IP已被列入系统黑名单 account.not.exists=帐号不存在或已被删除 login.account.disabled=您的账号:{0}已禁用 account.profile.update.error=修改个人信息异常,请联系管理员 account.password.update.error=修改密码异常,请联系管理员 account.phone.duplicate=手机号已开通账号 @@ -24,7 +26,7 @@ validation.group.name.notBlank=组名称不能为空 validation.group.remarks.notBlank=备注不能为空 validation.group.type.notNull=分组类型不能为空 validation.group.menuIds.notEmpty=菜单id集合不能为空 validation.group.menuIds.notEmpty=请选择操作权限 validation.group.id.notNull=权限组ID不能为空 group.name.exists=权限组名称已存在 group.not.exists=权限组不存在 xp-robotaxi-api/src/main/java/com/xiaopeng/api/dto/automaticPilot/PushOrderDto.java
@@ -1,6 +1,6 @@ package com.xiaopeng.api.dto.automaticPilot; import com.xiaopeng.api.vo.automaticPilot.protobuf.OrderOperationType; import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.OrderOperationType; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; xp-robotaxi-api/src/main/java/com/xiaopeng/api/factory/maintenance/XpCheckLocationClientFallbackFactory.java
@@ -7,6 +7,8 @@ import org.springframework.cloud.openfeign.FallbackFactory; import org.springframework.stereotype.Component; import java.util.List; /** * 打卡地址Feign客户端降级工厂 * @@ -26,6 +28,12 @@ log.error("远程调用获取检查点位信息异常:{}", cause.getMessage()); return R.fail("远程调用获取检查点位信息异常"); } @Override public R<List<XpCheckLocation>> listByIds(List<Long> ids) { log.error("远程调用批量获取检查点位信息异常:{}", cause.getMessage()); return R.fail("远程调用批量获取检查点位信息异常"); } }; } } xp-robotaxi-api/src/main/java/com/xiaopeng/api/feignClient/maintenance/XpCheckLocationClient.java
@@ -6,7 +6,11 @@ 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 Client @@ -21,4 +25,10 @@ */ @GetMapping("/inner/check-location/queryById") R<XpCheckLocation> queryById(@RequestParam Long id); /** * 根据ID列表批量查询打卡地址 */ @PostMapping("/inner/check-location/listByIds") R<List<XpCheckLocation>> listByIds(@RequestBody List<Long> ids); } xp-robotaxi-common/xp-common-core/src/main/java/com/xiaopeng/common/core/utils/StringUtils.java
@@ -478,4 +478,16 @@ } return sb.toString(); } /** * 对字符串进行转义,转义字符为\,被转义的字符包括\、%、_。例如:输入abc%def_ghi\jkl,输出abc\%def\_ghi\\jkl * @param value * @return */ public static String escapeLike(String value) { if (value == null) return null; return value.replace("\\", "\\\\") .replace("%", "\\%") .replace("_", "\\_"); } } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpCheckLocationController.java
@@ -1,5 +1,6 @@ package com.xiaopeng.maintenance.controller; import cn.hutool.core.collection.CollUtil; import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; import com.xiaopeng.api.model.maintenance.XpCheckLocation; @@ -16,6 +17,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.List; /** @@ -43,6 +45,15 @@ return R.ok(xpCheckLocationService.getById(id)); } @PostMapping("/inner/check-location/listByIds") @ApiOperation(value = "根据ID列表批量查询打卡地址", tags = {"内部接口"}) public R<List<XpCheckLocation>> listByIds(@RequestBody List<Long> ids) { if (CollUtil.isEmpty(ids)) { return R.ok(new ArrayList<>()); } return R.ok(xpCheckLocationService.listByIds(ids)); } @ApiOperation(value = "根据ID查询打卡地址", tags = {"运维APP-排班与考勤"}) @GetMapping("/api/v1/check-location/queryByUserId") public R<XpCheckLocation> queryByUserId() { xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleOperationsController.java
@@ -116,17 +116,17 @@ xpCruiseOrder.setLastOrderId(r.getData()); // 找到收车站点 R<XpCruiseOrder> returnCruisePoint = xpCruisePlanClient.findReturnCruisePoint(xpCruiseOrder); XpCruiseOrder returnCruisePoint = xpCruisePlanClient.findReturnCruisePoint(xpCruiseOrder).getData(); if(returnCruisePoint!=null){ xpCruiseOrderClient.addCruiseOrder(returnCruisePoint.getData()); xpCruiseOrderClient.addCruiseOrder(returnCruisePoint); // 下发命令 PushOrderDto pushOrderDto = new PushOrderDto(); pushOrderDto.setVin(returnCruisePoint.getData().getVehicleVin()); pushOrderDto.setOrderId(returnCruisePoint.getData().getId()); pushOrderDto.setStartLatitude(returnCruisePoint.getData().getStartLat()); pushOrderDto.setStartLongitude(returnCruisePoint.getData().getStartLon()); pushOrderDto.setEndLatitude(returnCruisePoint.getData().getEndLat()); pushOrderDto.setEndLongitude(returnCruisePoint.getData().getEndLon()); pushOrderDto.setVin(returnCruisePoint.getVehicleVin()); pushOrderDto.setOrderId(returnCruisePoint.getId()); pushOrderDto.setStartLatitude(returnCruisePoint.getStartLat()); pushOrderDto.setStartLongitude(returnCruisePoint.getStartLon()); pushOrderDto.setEndLatitude(returnCruisePoint.getEndLat()); pushOrderDto.setEndLongitude(returnCruisePoint.getEndLon()); pushOrderDto.setOrderType(OrderType.CRUISE_ORDER); pushOrderDto.setStage(2); orderMissionClient.pushOrder(pushOrderDto); xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/controller/XpVehicleRepairController.java
@@ -9,6 +9,7 @@ import com.xiaopeng.maintenance.dto.XpVehicleRepairStartDTO; import com.xiaopeng.maintenance.model.query.XpVehicleRepairPageQuery; import com.xiaopeng.maintenance.model.vo.XpVehicleRepairVO; import com.xiaopeng.maintenance.schedule.InsuranceInspectionScheduleTask; import com.xiaopeng.maintenance.service.IXpVehicleRepairService; import com.xiaopeng.maintenance.vo.RepairStatusVO; import io.swagger.annotations.Api; xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/exportExcel/XpTaskExportExcel.java
@@ -22,7 +22,7 @@ @Excel(name = "序号",width = 20) private Integer number; @Excel(name = "车牌号",width = 20) @Excel(name = "车牌",width = 20) private String plateNumber; @ApiModelProperty(value = "任务类别1常规 2事故") @Excel(name = "任务类别",width = 20) xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/VehicleChargingScheduleTask.java
New file @@ -0,0 +1,269 @@ package com.xiaopeng.maintenance.schedule; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.xiaopeng.api.feignClient.account.XpOperationUserClient; import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient; import com.xiaopeng.api.model.account.XpOperationsRole; import com.xiaopeng.api.model.maintenance.XpTask; import com.xiaopeng.api.model.maintenance.XpTaskRule; import com.xiaopeng.api.model.maintenance.XpTaskRuleRole; import com.xiaopeng.api.model.vehicleConvoy.XpVehicle; import com.xiaopeng.api.vo.automaticPilot.VehiclePosition; import com.xiaopeng.common.core.domain.R; import com.xiaopeng.maintenance.constant.TaskScheduleConstants; import com.xiaopeng.maintenance.mapper.XpTaskMapper; import com.xiaopeng.maintenance.mapper.XpTaskRuleMapper; import com.xiaopeng.maintenance.mapper.XpTaskRuleRoleMapper; import com.xiaopeng.maintenance.utils.UUIDUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; /** * 运营车辆电量检测定时任务 * <p> * 根据任务规则配置的充电阈值,从MongoDB读取低电量车辆位置数据, * 创建充电类型任务并下发给配置角色对应的运维人员。 * </p> * * @author mitao * @since 2026-03-10 */ @Component public class VehicleChargingScheduleTask { private static final Logger log = LoggerFactory.getLogger(VehicleChargingScheduleTask.class); /** * 任务名称 */ private static final String TASK_NAME = "运营车辆电量检测定时任务"; @Autowired private XpTaskRuleMapper taskRuleMapper; @Autowired private XpTaskRuleRoleMapper taskRuleRoleMapper; @Autowired private XpTaskMapper taskMapper; @Autowired private XpVehicleClient xpVehicleClient; @Autowired private XpOperationUserClient xpOperationUserClient; @Autowired private MongoTemplate mongoTemplate; /** * 每分钟执行一次电量检测 */ @Scheduled(cron = "0 * * * * ?") public void executeChargingDetectionTask() { log.info("========== 开始执行{}检查 ==========", TASK_NAME); // 1. 获取任务规则配置 XpTaskRule taskRule = getTaskRule(); if (taskRule == null) { log.info("未找到任务规则配置,跳过执行"); return; } // 2. 判断充电策略功能是否启用 if (taskRule.getChargingStrategy() == null || taskRule.getChargingStrategy() != 1) { log.info("充电策略未启用,跳过执行"); return; } // 3. 获取电量阈值 BigDecimal thresholdDecimal = taskRule.getChargingStrategyBatteryl(); if (thresholdDecimal == null) { log.warn("充电策略电量阈值未配置,跳过执行"); return; } int threshold = thresholdDecimal.intValue(); if (threshold <= 0) { log.warn("充电策略电量阈值不合法:{},跳过执行", thresholdDecimal); return; } // 4. 获取任务接收角色的运维人员 List<Long> operationUserIds = getOperationUserIdsByRoleType(TaskScheduleConstants.RULE_ROLE_TYPE_CHARGING); if (CollectionUtils.isEmpty(operationUserIds)) { log.warn("未找到充电策略任务接收角色的运维人员"); return; } String belongUserIds = operationUserIds.stream().map(String::valueOf).collect(Collectors.joining(",")); // 5. 获取所有运营中的车辆,并构建 VIN -> Vehicle 映射 List<XpVehicle> operatingVehicles = getOperatingVehicles(); if (CollectionUtils.isEmpty(operatingVehicles)) { log.info("没有运营中的车辆,跳过执行"); return; } Map<String, XpVehicle> operatingVehicleByVin = operatingVehicles.stream() .filter(v -> StringUtils.hasLength(v.getVehicleVin())) .collect(Collectors.toMap(XpVehicle::getVehicleVin, v -> v, (a, b) -> a)); if (operatingVehicleByVin.isEmpty()) { log.info("运营车辆VIN为空,跳过执行"); return; } // 6. 从MongoDB查询电量低于阈值的车辆位置数据(只查运营车辆VIN) List<String> vins = new ArrayList<>(operatingVehicleByVin.keySet()); Query query = new Query(Criteria.where("vin").in(vins).and("currentElectricity").lt(threshold)); List<VehiclePosition> lowBatteryPositions = mongoTemplate.find(query, VehiclePosition.class); if (CollectionUtils.isEmpty(lowBatteryPositions)) { log.info("未找到低电量车辆(阈值={}),跳过执行", threshold); return; } int createdCount = 0; int skippedCount = 0; for (VehiclePosition position : lowBatteryPositions) { if (position == null || !StringUtils.hasLength(position.getVin())) { continue; } XpVehicle vehicle = operatingVehicleByVin.get(position.getVin()); if (vehicle == null || vehicle.getId() == null) { continue; } // 避免重复创建:若存在未完成的充电任务则跳过 if (hasUnfinishedTask(vehicle.getId(), TaskScheduleConstants.TASK_TYPE_CHARGING)) { skippedCount++; continue; } XpTask task = buildChargingTask(vehicle, position, belongUserIds, taskRule, threshold); taskMapper.insert(task); createdCount++; } log.info("========== {}执行完成,阈值={},命中={},创建任务数={},跳过(已存在未完成任务)={} ==========", TASK_NAME, threshold, lowBatteryPositions.size(), createdCount, skippedCount); } private XpTaskRule getTaskRule() { return taskRuleMapper.selectOne(new LambdaQueryWrapper<XpTaskRule>().last("limit 1")); } /** * 获取所有运营中的车辆 */ private List<XpVehicle> getOperatingVehicles() { try { R<List<XpVehicle>> result = xpVehicleClient.listVehicle(); if (result != null && result.getData() != null) { return result.getData().stream() .filter(v -> v.getVehicleType() != null && v.getVehicleType() == 2) .filter(v -> v.getOperatingStatus() != null && v.getOperatingStatus() == 1) .collect(Collectors.toList()); } } catch (Exception e) { log.error("获取车辆列表失败", e); } return Collections.emptyList(); } /** * 根据角色类型获取运维人员ID列表 */ private List<Long> getOperationUserIdsByRoleType(Integer roleType) { List<XpTaskRuleRole> ruleRoles = taskRuleRoleMapper.selectList( new LambdaQueryWrapper<XpTaskRuleRole>() .eq(XpTaskRuleRole::getRuleType, roleType) ); if (CollectionUtils.isEmpty(ruleRoles)) { return Collections.emptyList(); } Set<Long> userIds = new HashSet<>(); for (XpTaskRuleRole ruleRole : ruleRoles) { try { R<List<XpOperationsRole>> result = xpOperationUserClient.getXpOperationsRoleByRoleId(ruleRole.getRoleId()); if (result != null && result.getData() != null) { userIds.addAll( result.getData().stream() .map(XpOperationsRole::getOperationsUserId) .filter(Objects::nonNull) .collect(Collectors.toList()) ); } } catch (Exception e) { log.error("获取角色[{}]对应的运维人员失败", ruleRole.getRoleId(), e); } } return new ArrayList<>(userIds); } /** * 检查是否已存在未完成的同类型任务 */ private boolean hasUnfinishedTask(Long vehicleId, String taskTypeId) { XpTask existingTask = taskMapper.selectOne( new LambdaQueryWrapper<XpTask>() .eq(XpTask::getVehicleId, vehicleId) .eq(XpTask::getTaskTypeId, taskTypeId) .in(XpTask::getStatus, TaskScheduleConstants.TASK_STATUS_PENDING_ARRIVE, TaskScheduleConstants.TASK_STATUS_PENDING) .last("limit 1") ); return existingTask != null; } private XpTask buildChargingTask(XpVehicle vehicle, VehiclePosition position, String belongUserIds, XpTaskRule taskRule, int threshold) { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); String taskCode = sdf.format(new Date()) + UUIDUtil.getNumberRandom(5); Integer currentElectricity = position.getCurrentElectricity(); String desc = String.format("系统自动下发的车辆充电任务,当前电量%s%%,阈值%d%%", currentElectricity == null ? "-" : String.valueOf(currentElectricity), threshold); XpTask task = new XpTask(); task.setTaskCode(taskCode); task.setTaskCategory(TaskScheduleConstants.TASK_CATEGORY_ROUTINE); task.setTaskTypeId(TaskScheduleConstants.TASK_TYPE_CHARGING); task.setTaskUrgencyLevel(taskRule.getChargingStrategyLevel() != null ? taskRule.getChargingStrategyLevel() : TaskScheduleConstants.URGENCY_LEVEL_P2); task.setTaskDescription(desc); task.setVehicleId(vehicle.getId()); if (position.getPoint() != null) { task.setVehicleLon(BigDecimal.valueOf(position.getPoint().getX())); task.setVehicleLat(BigDecimal.valueOf(position.getPoint().getY())); } // 常规任务默认限时3天 task.setEndTime(LocalDateTime.now().plusDays(3)); task.setStatus(TaskScheduleConstants.TASK_STATUS_PENDING); task.setHandleUserId(belongUserIds); task.setReportUserId(0L); task.setReportTime(LocalDateTime.now()); task.setCreateBy(TaskScheduleConstants.SCHEDULE_CREATOR); return task; } } xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpTaskServiceImpl.java
@@ -1471,15 +1471,12 @@ res.setReportUserPhone("111111"); res.setReportUserAvatar("[]"); }else{ List<Long> reportUserIds = new ArrayList<>(); reportUserIds.add(task.getReportUserId()); List<SysUser> sysUsers = sysUserClient.listByIds(reportUserIds).getData(); if (sysUsers != null && !sysUsers.isEmpty()) { SysUser sysUser = sysUsers.get(0); res.setReportUserId(sysUser.getId()); res.setReportUserName(sysUser.getNickName()); res.setReportUserPhone(sysUser.getPhoneNumber()); res.setReportUserAvatar(sysUser.getAvatar()); XpOperationsUser data = xpOperationUserClient.queryById(task.getReportUserId()).getData(); if (data != null ) { res.setReportUserId(data.getId()); res.setReportUserName(data.getNickName()); res.setReportUserPhone(data.getPhoneNumber()); res.setReportUserAvatar(data.getAvatar()); } } xp-robotaxi-order-boot/src/main/java/com/xiaopeng/order/service/impl/XpOrderServiceImpl.java
@@ -46,7 +46,8 @@ import com.xiaopeng.api.vo.OrderType; import com.xiaopeng.api.vo.account.UserCouponVo; import com.xiaopeng.api.vo.automaticPilot.VehiclePosition; import com.xiaopeng.api.vo.automaticPilot.protobuf.OrderOperationType; // import com.xiaopeng.api.vo.automaticPilot.protobuf.OrderOperationType; import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.OrderOperationType; import com.xiaopeng.api.vo.operation.RouteVo; import com.xiaopeng.api.vo.order.*; import com.xiaopeng.api.vo.vehicleConvoy.AddTaxiPassengerVo; @@ -589,7 +590,7 @@ PushOrderDto pushOrderDto = new PushOrderDto(); pushOrderDto.setOrderId(order.getId().toString()); pushOrderDto.setVin(xpVehicleR.getData().getVehicleVin()); pushOrderDto.setOperation_type(com.xiaopeng.api.vo.automaticPilot.protobuf.OrderOperationType.CLOUD_CANCEL_ORDER); // pushOrderDto.setOperation_type(com.xiaopeng.api.vo.automaticPilot.protobuf.OrderOperationType.CLOUD_CANCEL_ORDER); orderMissionClient.cancelOrder(pushOrderDto); } } else { @@ -675,7 +676,7 @@ PushOrderDto cancelDto = new PushOrderDto(); cancelDto.setOrderId(order.getId().toString()); cancelDto.setVin(oldVehicle.getVehicleVin()); cancelDto.setOperation_type(com.xiaopeng.api.vo.automaticPilot.protobuf.OrderOperationType.CLOUD_CANCEL_ORDER); // cancelDto.setOperation_type(com.xiaopeng.api.vo.automaticPilot.protobuf.OrderOperationType.CLOUD_CANCEL_ORDER); orderMissionClient.cancelOrder(cancelDto); log.info("已取消原车辆订单指令,订单ID: {}, VIN: {}", orderId, oldVehicle.getVehicleVin()); @@ -1139,7 +1140,7 @@ PushOrderDto pushOrderDto = new PushOrderDto(); pushOrderDto.setOrderId(order.getId().toString()); pushOrderDto.setVin(xpVehicle.getVehicleVin()); pushOrderDto.setOperation_type(com.xiaopeng.api.vo.automaticPilot.protobuf.OrderOperationType.VEHICLE_CANCEL_ORDER); // pushOrderDto.setOperation_type(com.xiaopeng.api.vo.automaticPilot.protobuf.OrderOperationType.VEHICLE_CANCEL_ORDER); orderMissionClient.cancelOrder(pushOrderDto); } xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/controller/XpVehicleController.java
@@ -341,7 +341,7 @@ res.put("name", "测试.png"); return res.toJSONString(); } catch (Exception e) { log.error("广告物料整体项目结算表导入图片上传oss异常", e); log.error("在库车辆导入图片上传oss异常", e); } return null; } xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/model/vo/FleetPageVO.java
@@ -31,6 +31,9 @@ @ApiModelProperty(value = "关联运营区域") private String electronicName; @ApiModelProperty(value = "打卡地名称") private String locationName; @ApiModelProperty(value = "负责人电话") private String phoneNumber; xp-robotaxi-vehicle-convoy-boot/src/main/java/com/xiaopeng/vehicleConvoy/service/impl/XpFleetServiceImpl.java
@@ -328,8 +328,8 @@ .distinct() .collect(Collectors.toList()); List<Long> electronicIds = resultPage.getRecords().stream() .map(XpFleet::getElectronicId) List<Long> locationIds = resultPage.getRecords().stream() .map(XpFleet::getLocationId) .filter(Objects::nonNull) .distinct() .collect(Collectors.toList()); @@ -344,13 +344,19 @@ } } // 5. 批量查询围栏信息并转换为Map Map<Long, XpElectronicFence> fenceMap = new HashMap<>(); if (!CollectionUtils.isEmpty(electronicIds)) { R<List<XpElectronicFence>> fencesResult = xpElectronicClient.listByIds(electronicIds); if (fencesResult.getData() != null) { fenceMap = fencesResult.getData().stream() .collect(Collectors.toMap(XpElectronicFence::getId, fence -> fence)); // 5. 批量查询打卡地信息并转换为Map Map<Long, String> locationNameMap = Collections.emptyMap(); if (!CollectionUtils.isEmpty(locationIds)) { R<List<XpCheckLocation>> locationsResult = xpCheckLocationClient.listByIds(locationIds); if (locationsResult != null && locationsResult.getData() != null) { locationNameMap = locationsResult.getData().stream() .filter(Objects::nonNull) .filter(location -> location.getId() != null && location.getLocationAddress() != null) .collect(Collectors.toMap( XpCheckLocation::getId, XpCheckLocation::getLocationAddress, (a, b) -> a )); } } @@ -379,12 +385,9 @@ } } // 从Map中获取围栏名称 if (fleet.getElectronicId() != null) { XpElectronicFence fence = fenceMap.get(fleet.getElectronicId()); if (fence != null) { vo.setElectronicName(fence.getElectronicName()); } // 从Map中获取打卡地名称 if (fleet.getLocationId() != null) { vo.setLocationName(locationNameMap.get(fleet.getLocationId())); } records.add(vo);