From c96fbe6b0aeb413a17c429133ee6d81d138144b9 Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期二, 09 六月 2026 10:58:52 +0800
Subject: [PATCH] Merge branch '1.0' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi into 1.0
---
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/InsuranceInspectionScheduleTask.java | 171 ++++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 144 insertions(+), 27 deletions(-)
diff --git a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/InsuranceInspectionScheduleTask.java b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/InsuranceInspectionScheduleTask.java
index ca9a930..33ca266 100644
--- a/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/InsuranceInspectionScheduleTask.java
+++ b/xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/schedule/InsuranceInspectionScheduleTask.java
@@ -2,17 +2,21 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
+import com.xiaopeng.api.feignClient.vehicleConvoy.XpFleetOperationsClient;
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.api.vo.maintenance.TaskScheduleConstants;
+import com.xiaopeng.common.core.utils.SensitiveDataCryptoUtil;
import com.xiaopeng.maintenance.mapper.XpTaskMapper;
import com.xiaopeng.maintenance.mapper.XpTaskRuleMapper;
import com.xiaopeng.maintenance.mapper.XpTaskRuleRoleMapper;
+import com.xiaopeng.maintenance.service.VehicleLocationFillService;
import com.xiaopeng.maintenance.utils.UUIDUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -20,6 +24,7 @@
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
@@ -62,6 +67,12 @@
@Autowired
private XpOperationUserClient xpOperationUserClient;
+
+ @Autowired
+ private XpFleetOperationsClient xpFleetOperationsClient;
+
+ @Autowired
+ private VehicleLocationFillService vehicleLocationFillService;
/**
* 每天凌晨1点执行一次
@@ -127,13 +138,14 @@
*/
private int createExpireTasks(XpTaskRule taskRule) {
// 1. 获取任务接收角色的运维人员
- List<Long> operationUserIds = getOperationUserIdsByRoleType(TaskScheduleConstants.RULE_ROLE_TYPE_INSURANCE);
- if (CollectionUtils.isEmpty(operationUserIds)) {
+ List<Long> roleOperationUserIds = getOperationUserIdsByRoleType(TaskScheduleConstants.RULE_ROLE_TYPE_INSURANCE);
+ if (CollectionUtils.isEmpty(roleOperationUserIds)) {
log.warn("未找到年检/保险任务接收角色的运维人员");
return 0;
}
- log.info("找到 {} 个运维人员可接收年检/保险任务", operationUserIds.size());
+ Set<Long> roleOperationUserIdSet = new HashSet<>(roleOperationUserIds);
+ log.info("找到 {} 个运维人员可接收年检/保险任务", roleOperationUserIdSet.size());
// 2. 获取所有运营中的车辆
List<XpVehicle> vehicles = getOperatingVehicles();
@@ -144,16 +156,30 @@
log.info("找到 {} 辆运营中的车辆", vehicles.size());
+ Map<String, VehiclePosition> positionByVin = vehicleLocationFillService.loadPositionByVin(
+ vehicles.stream()
+ .map(XpVehicle::getVehicleVin)
+ .filter(StringUtils::hasLength)
+ .distinct()
+ .collect(Collectors.toList())
+ );
+
+ Map<Long, Long> vehicleIdToFleetIdCache = new HashMap<>();
+ Map<Long, Set<Long>> fleetIdToOperationUserIdsCache = new HashMap<>();
+
int totalCreatedCount = 0;
// 3. 检查保险到期
- totalCreatedCount += checkAndCreateInsuranceExpireTasks(vehicles, operationUserIds, taskRule);
+ totalCreatedCount += checkAndCreateInsuranceExpireTasks(vehicles, roleOperationUserIdSet, taskRule,
+ vehicleIdToFleetIdCache, fleetIdToOperationUserIdsCache, positionByVin);
// 4. 检查年检到期
- totalCreatedCount += checkAndCreateInspectionExpireTasks(vehicles, operationUserIds, taskRule);
+ totalCreatedCount += checkAndCreateInspectionExpireTasks(vehicles, roleOperationUserIdSet, taskRule,
+ vehicleIdToFleetIdCache, fleetIdToOperationUserIdsCache, positionByVin);
// 5. 检查运营资质到期
- totalCreatedCount += checkAndCreateQualificationExpireTasks(vehicles, operationUserIds, taskRule);
+ totalCreatedCount += checkAndCreateQualificationExpireTasks(vehicles, roleOperationUserIdSet, taskRule,
+ vehicleIdToFleetIdCache, fleetIdToOperationUserIdsCache, positionByVin);
return totalCreatedCount;
}
@@ -162,11 +188,15 @@
* 检查并创建保险到期任务
*
* @param vehicles 车辆列表
- * @param operationUserIds 运维人员ID列表
+ * @param roleOperationUserIds 配置角色下的运维人员ID集合
* @param taskRule 任务规则
+ * @param vehicleIdToFleetIdCache 车辆->车队缓存
+ * @param fleetIdToOperationUserIdsCache 车队->人员缓存
* @return 创建的任务数量
*/
- private int checkAndCreateInsuranceExpireTasks(List<XpVehicle> vehicles, List<Long> operationUserIds, XpTaskRule taskRule) {
+ private int checkAndCreateInsuranceExpireTasks(List<XpVehicle> vehicles, Set<Long> roleOperationUserIds, XpTaskRule taskRule,
+ Map<Long, Long> vehicleIdToFleetIdCache, Map<Long, Set<Long>> fleetIdToOperationUserIdsCache,
+ Map<String, VehiclePosition> positionByVin) {
if (taskRule.getInsuranceExpires() == null || taskRule.getInsuranceExpires() <= 0) {
log.info("保险到期提醒天数未配置,跳过保险到期检查");
return 0;
@@ -186,10 +216,13 @@
return createTasksForExpireType(
needWarnVehicles,
- operationUserIds,
+ roleOperationUserIds,
taskRule,
TaskScheduleConstants.TASK_TYPE_INSURANCE_EXPIRE,
- "保险即将到期"
+ "保险即将到期",
+ vehicleIdToFleetIdCache,
+ fleetIdToOperationUserIdsCache,
+ positionByVin
);
}
@@ -197,11 +230,15 @@
* 检查并创建年检到期任务
*
* @param vehicles 车辆列表
- * @param operationUserIds 运维人员ID列表
+ * @param roleOperationUserIds 配置角色下的运维人员ID集合
* @param taskRule 任务规则
+ * @param vehicleIdToFleetIdCache 车辆->车队缓存
+ * @param fleetIdToOperationUserIdsCache 车队->人员缓存
* @return 创建的任务数量
*/
- private int checkAndCreateInspectionExpireTasks(List<XpVehicle> vehicles, List<Long> operationUserIds, XpTaskRule taskRule) {
+ private int checkAndCreateInspectionExpireTasks(List<XpVehicle> vehicles, Set<Long> roleOperationUserIds, XpTaskRule taskRule,
+ Map<Long, Long> vehicleIdToFleetIdCache, Map<Long, Set<Long>> fleetIdToOperationUserIdsCache,
+ Map<String, VehiclePosition> positionByVin) {
if (taskRule.getInsuranceInspectionExpires() == null || taskRule.getInsuranceInspectionExpires() <= 0) {
log.info("年检到期提醒天数未配置,跳过年检到期检查");
return 0;
@@ -221,10 +258,13 @@
return createTasksForExpireType(
needWarnVehicles,
- operationUserIds,
+ roleOperationUserIds,
taskRule,
TaskScheduleConstants.TASK_TYPE_INSPECTION_EXPIRE,
- "年检即将到期"
+ "年检即将到期",
+ vehicleIdToFleetIdCache,
+ fleetIdToOperationUserIdsCache,
+ positionByVin
);
}
@@ -232,11 +272,15 @@
* 检查并创建运营资质到期任务
*
* @param vehicles 车辆列表
- * @param operationUserIds 运维人员ID列表
+ * @param roleOperationUserIds 配置角色下的运维人员ID集合
* @param taskRule 任务规则
+ * @param vehicleIdToFleetIdCache 车辆->车队缓存
+ * @param fleetIdToOperationUserIdsCache 车队->人员缓存
* @return 创建的任务数量
*/
- private int checkAndCreateQualificationExpireTasks(List<XpVehicle> vehicles, List<Long> operationUserIds, XpTaskRule taskRule) {
+ private int checkAndCreateQualificationExpireTasks(List<XpVehicle> vehicles, Set<Long> roleOperationUserIds, XpTaskRule taskRule,
+ Map<Long, Long> vehicleIdToFleetIdCache, Map<Long, Set<Long>> fleetIdToOperationUserIdsCache,
+ Map<String, VehiclePosition> positionByVin) {
if (taskRule.getOperationQualificationExpires() == null || taskRule.getOperationQualificationExpires() <= 0) {
log.info("运营资质到期提醒天数未配置,跳过运营资质到期检查");
return 0;
@@ -256,10 +300,13 @@
return createTasksForExpireType(
needWarnVehicles,
- operationUserIds,
+ roleOperationUserIds,
taskRule,
TaskScheduleConstants.TASK_TYPE_QUALIFICATION_EXPIRE,
- "运营资质即将到期"
+ "运营资质即将到期",
+ vehicleIdToFleetIdCache,
+ fleetIdToOperationUserIdsCache,
+ positionByVin
);
}
@@ -310,23 +357,33 @@
* 为指定到期类型创建任务
*
* @param vehicles 需要提醒的车辆列表
- * @param operationUserIds 运维人员ID列表
+ * @param roleOperationUserIds 配置角色下的运维人员ID集合
* @param taskRule 任务规则
* @param taskTypeId 任务类型ID
* @param taskDescription 任务描述
+ * @param vehicleIdToFleetIdCache 车辆->车队缓存
+ * @param fleetIdToOperationUserIdsCache 车队->人员缓存
* @return 创建的任务数量
*/
- private int createTasksForExpireType(List<XpVehicle> vehicles, List<Long> operationUserIds,
- XpTaskRule taskRule, String taskTypeId, String taskDescription) {
+ private int createTasksForExpireType(List<XpVehicle> vehicles, Set<Long> roleOperationUserIds,
+ XpTaskRule taskRule, String taskTypeId, String taskDescription,
+ Map<Long, Long> vehicleIdToFleetIdCache,
+ Map<Long, Set<Long>> fleetIdToOperationUserIdsCache,
+ Map<String, VehiclePosition> positionByVin) {
List<XpTask> tasksToSave = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
-
- // 将所有配置角色的运维人员ID拼接,任务分配给该角色下的所有运维人员
- String belongUserIds = operationUserIds.stream()
- .map(String::valueOf)
- .collect(Collectors.joining(","));
+ int skippedCount = 0;
for (XpVehicle vehicle : vehicles) {
+ List<Long> handleUserIds = resolveHandleUserIds(vehicle.getId(), taskTypeId, roleOperationUserIds,
+ vehicleIdToFleetIdCache, fleetIdToOperationUserIdsCache);
+ if (CollectionUtils.isEmpty(handleUserIds)) {
+ skippedCount++;
+ continue;
+ }
+
+ String belongUserIds = handleUserIds.stream().map(String::valueOf).collect(Collectors.joining(","));
+
XpTask task = new XpTask();
// 生成任务编号
@@ -343,6 +400,8 @@
// 设置车辆信息
task.setVehicleId(vehicle.getId());
+ String vin = SensitiveDataCryptoUtil.decryptIfPossible(vehicle.getVehicleVin());
+ vehicleLocationFillService.fillFromVin(task, vin, positionByVin);
// 设置任务时限 常规任务限时3天
task.setEndTime(LocalDateTime.now().plusDays(3));
@@ -350,7 +409,7 @@
// 设置任务状态为待到达
task.setStatus(TaskScheduleConstants.TASK_STATUS_PENDING);
- // 设置任务接收人(配置角色下的所有运维人员都可以看到)
+ // 设置任务接收人(车辆所属车队关联人员与配置角色人员取交集)
task.setHandleUserId(belongUserIds);
task.setReportTime(LocalDateTime.now());
task.setReportUserId(0L);
@@ -367,10 +426,68 @@
}
log.info("成功创建 {} 个{}提醒任务", tasksToSave.size(), taskDescription);
}
+ if (skippedCount > 0) {
+ log.warn("{}提醒任务:跳过 {} 辆车(无可分配处理人)", taskDescription, skippedCount);
+ }
return tasksToSave.size();
}
+ private List<Long> resolveHandleUserIds(Long vehicleId, String taskTypeId, Set<Long> roleOperationUserIds,
+ Map<Long, Long> vehicleIdToFleetIdCache,
+ Map<Long, Set<Long>> fleetIdToOperationUserIdsCache) {
+ if (vehicleId == null) {
+ log.warn("定时任务分配处理人失败:vehicleId为空,taskTypeId={}", taskTypeId);
+ return Collections.emptyList();
+ }
+
+ Long fleetId = vehicleIdToFleetIdCache.get(vehicleId);
+ if (!vehicleIdToFleetIdCache.containsKey(vehicleId)) {
+ try {
+ R<Long> fleetIdResult = xpVehicleClient.findFleetIdByVehicleId(vehicleId);
+ fleetId = fleetIdResult != null ? fleetIdResult.getData() : null;
+ } catch (Exception e) {
+ log.error("根据车辆查询车队失败,vehicleId={}, taskTypeId={}", vehicleId, taskTypeId, e);
+ fleetId = null;
+ }
+ vehicleIdToFleetIdCache.put(vehicleId, fleetId);
+ }
+
+ if (fleetId == null) {
+ log.warn("定时任务跳过:车辆未关联车队,vehicleId={}, taskTypeId={}", vehicleId, taskTypeId);
+ return Collections.emptyList();
+ }
+
+ Set<Long> fleetOperationUserIds = fleetIdToOperationUserIdsCache.get(fleetId);
+ if (!fleetIdToOperationUserIdsCache.containsKey(fleetId)) {
+ try {
+ R<List<Long>> opsResult = xpFleetOperationsClient.getOperationsIdsByFleetId(fleetId);
+ List<Long> opsIds = opsResult != null ? opsResult.getData() : null;
+ fleetOperationUserIds = CollectionUtils.isEmpty(opsIds) ? Collections.emptySet() : new HashSet<>(opsIds);
+ } catch (Exception e) {
+ log.error("根据车队查询关联人员失败,fleetId={}, vehicleId={}, taskTypeId={}", fleetId, vehicleId, taskTypeId, e);
+ fleetOperationUserIds = Collections.emptySet();
+ }
+ fleetIdToOperationUserIdsCache.put(fleetId, fleetOperationUserIds);
+ }
+
+ if (CollectionUtils.isEmpty(fleetOperationUserIds)) {
+ log.warn("定时任务跳过:车队未关联人员,fleetId={}, vehicleId={}, taskTypeId={}", fleetId, vehicleId, taskTypeId);
+ return Collections.emptyList();
+ }
+
+ List<Long> finalUserIds = fleetOperationUserIds.stream()
+ .filter(roleOperationUserIds::contains)
+ .sorted()
+ .collect(Collectors.toList());
+ if (CollectionUtils.isEmpty(finalUserIds)) {
+ log.warn("定时任务跳过:车队人员与角色人员无交集,fleetId={}, vehicleId={}, taskTypeId={}", fleetId, vehicleId, taskTypeId);
+ return Collections.emptyList();
+ }
+
+ return finalUserIds;
+ }
+
/**
* 根据角色类型获取运维人员ID列表
*
--
Gitblit v1.7.1