重构任务接口展示无人车实际任务信息
- 移除内存任务库,改为从 activeMovingObjectsCache 获取无人车任务数据 - 新增 DataCollectorService.getActiveMovingObjectsCache() 公共方法 - 修复 missionStatus 空指针异常,添加空值检查 - 支持按任务状态筛选和分页查询 - 返回完整的任务上下文信息(任务ID、类型、状态、进度、路径点等) - 修正 getObjectType() 方法调用
This commit is contained in:
parent
8347eae959
commit
b23ca99916
@ -3,18 +3,18 @@ package com.qaup.collision.controller;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.qaup.common.constant.HttpStatus;
|
||||
import com.qaup.common.core.domain.AjaxResult;
|
||||
import com.qaup.collision.task.InMemoryTaskStore;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import com.qaup.collision.common.model.MovingObject;
|
||||
import com.qaup.collision.common.model.UnmannedVehicle;
|
||||
import com.qaup.collision.datacollector.service.DataCollectorService;
|
||||
import com.qaup.collision.datacollector.service.VehicleManagerCacheService;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
@ -23,30 +23,107 @@ import java.util.stream.Collectors;
|
||||
@RequiredArgsConstructor
|
||||
public class VehicleTaskController {
|
||||
|
||||
private final InMemoryTaskStore taskStore;
|
||||
private final VehicleManagerCacheService cacheService;
|
||||
private final DataCollectorService dataCollectorService;
|
||||
|
||||
@Data
|
||||
public static class TaskUpsertRequest {
|
||||
@NotBlank
|
||||
private String name;
|
||||
@Builder
|
||||
public static class VehicleTaskDTO {
|
||||
private String vehicleId;
|
||||
private String vehicleType;
|
||||
private String missionId;
|
||||
private String missionType;
|
||||
private String missionStatus;
|
||||
private Long missionStartTime;
|
||||
private Long estimatedEndTime;
|
||||
private Double progress;
|
||||
private Double totalMileage;
|
||||
private List<WaypointDTO> waypoints;
|
||||
private Long lastSeenAt;
|
||||
}
|
||||
|
||||
@NotBlank
|
||||
private String type;
|
||||
|
||||
private Integer priority;
|
||||
|
||||
private JsonNode payload;
|
||||
@Data
|
||||
@Builder
|
||||
public static class WaypointDTO {
|
||||
private String waypointId;
|
||||
private Double latitude;
|
||||
private Double longitude;
|
||||
private String status;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public AjaxResult list(@RequestParam(required = false, defaultValue = "1") int pageNum,
|
||||
@RequestParam(required = false, defaultValue = "10") int pageSize) {
|
||||
List<InMemoryTaskStore.Task> all = taskStore.listAll();
|
||||
int total = all.size();
|
||||
@RequestParam(required = false, defaultValue = "10") int pageSize,
|
||||
@RequestParam(required = false) String status) {
|
||||
Map<String, MovingObject> activeMovingObjectsCache = dataCollectorService.getActiveMovingObjectsCache();
|
||||
List<VehicleTaskDTO> allTasks = new ArrayList<>();
|
||||
|
||||
for (MovingObject movingObject : activeMovingObjectsCache.values()) {
|
||||
if (!(movingObject instanceof UnmannedVehicle vehicle)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String vehicleId = vehicle.getObjectId();
|
||||
String missionId = vehicle.getMissionId();
|
||||
|
||||
// 如果没有任务ID,跳过
|
||||
if (missionId == null || missionId.isBlank()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String missionStatus = vehicle.getMissionStatus() != null ? vehicle.getMissionStatus().name() : "UNKNOWN";
|
||||
|
||||
// 状态筛选
|
||||
if (status != null && !status.isEmpty() && !status.equalsIgnoreCase(missionStatus)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取车辆类型
|
||||
String vehicleType = vehicle.getObjectType().name();
|
||||
|
||||
// 获取路径点
|
||||
List<WaypointDTO> waypoints = new ArrayList<>();
|
||||
if (vehicle.getWaypoints() != null) {
|
||||
for (UnmannedVehicle.WaypointInfo wp : vehicle.getWaypoints()) {
|
||||
WaypointDTO waypoint = WaypointDTO.builder()
|
||||
.waypointId(wp.getWaypointId())
|
||||
.latitude(wp.getLatitude())
|
||||
.longitude(wp.getLongitude())
|
||||
.status(wp.getStatus().name())
|
||||
.build();
|
||||
waypoints.add(waypoint);
|
||||
}
|
||||
}
|
||||
|
||||
VehicleTaskDTO task = VehicleTaskDTO.builder()
|
||||
.vehicleId(vehicleId)
|
||||
.vehicleType(vehicleType)
|
||||
.missionId(missionId)
|
||||
.missionType(vehicle.getMissionType())
|
||||
.missionStatus(missionStatus)
|
||||
.missionStartTime(vehicle.getMissionStartTime())
|
||||
.estimatedEndTime(vehicle.getEstimatedEndTime())
|
||||
.progress(vehicle.getProgress())
|
||||
.totalMileage(vehicle.getTotalMileage())
|
||||
.waypoints(waypoints)
|
||||
.lastSeenAt(null) // 暂时设为null,后续可以从缓存获取
|
||||
.build();
|
||||
|
||||
allTasks.add(task);
|
||||
}
|
||||
|
||||
// 按任务开始时间倒序排序
|
||||
allTasks.sort((a, b) -> {
|
||||
if (a.getMissionStartTime() == null && b.getMissionStartTime() == null) return 0;
|
||||
if (a.getMissionStartTime() == null) return 1;
|
||||
if (b.getMissionStartTime() == null) return -1;
|
||||
return Long.compare(b.getMissionStartTime(), a.getMissionStartTime());
|
||||
});
|
||||
|
||||
int total = allTasks.size();
|
||||
int fromIndex = Math.max(0, (pageNum - 1) * pageSize);
|
||||
int toIndex = Math.min(total, fromIndex + pageSize);
|
||||
List<InMemoryTaskStore.Task> page = fromIndex >= total ? List.of() : all.subList(fromIndex, toIndex);
|
||||
List<VehicleTaskDTO> page = fromIndex >= total ? List.of() : allTasks.subList(fromIndex, toIndex);
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("total", total);
|
||||
@ -57,69 +134,50 @@ public class VehicleTaskController {
|
||||
return AjaxResult.success(data).put("timestamp", System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public AjaxResult get(@PathVariable long id) {
|
||||
InMemoryTaskStore.Task task = taskStore.get(id);
|
||||
if (task == null) {
|
||||
return AjaxResult.error(HttpStatus.NOT_FOUND, "任务不存在").put("timestamp", System.currentTimeMillis());
|
||||
@GetMapping("/{vehicleId}")
|
||||
public AjaxResult get(@PathVariable String vehicleId) {
|
||||
Map<String, MovingObject> activeMovingObjectsCache = dataCollectorService.getActiveMovingObjectsCache();
|
||||
MovingObject movingObject = activeMovingObjectsCache.get(vehicleId);
|
||||
|
||||
if (!(movingObject instanceof UnmannedVehicle vehicle)) {
|
||||
return AjaxResult.error(HttpStatus.NOT_FOUND, "车辆不存在或无任务").put("timestamp", System.currentTimeMillis());
|
||||
}
|
||||
return AjaxResult.success(task).put("timestamp", System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public AjaxResult create(@Valid @RequestBody TaskUpsertRequest request) {
|
||||
InMemoryTaskStore.Task task = taskStore.create(
|
||||
request.getName(),
|
||||
request.getType(),
|
||||
request.getPriority(),
|
||||
request.getPayload()
|
||||
);
|
||||
return AjaxResult.success(task).put("timestamp", System.currentTimeMillis());
|
||||
}
|
||||
String missionId = vehicle.getMissionId();
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public AjaxResult update(@PathVariable long id, @Valid @RequestBody TaskUpsertRequest request) {
|
||||
InMemoryTaskStore.Task task = taskStore.update(
|
||||
id,
|
||||
request.getName(),
|
||||
request.getType(),
|
||||
request.getPriority(),
|
||||
request.getPayload()
|
||||
);
|
||||
if (task == null) {
|
||||
return AjaxResult.error(HttpStatus.NOT_FOUND, "任务不存在").put("timestamp", System.currentTimeMillis());
|
||||
if (missionId == null || missionId.isBlank()) {
|
||||
return AjaxResult.error(HttpStatus.NOT_FOUND, "车辆无任务").put("timestamp", System.currentTimeMillis());
|
||||
}
|
||||
return AjaxResult.success(task).put("timestamp", System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@DeleteMapping("/{ids}")
|
||||
public AjaxResult delete(@PathVariable String ids) {
|
||||
List<Long> idList = parseIds(ids);
|
||||
int removed = taskStore.deleteMany(idList);
|
||||
String vehicleType = vehicle.getObjectType().name();
|
||||
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("removed", removed);
|
||||
data.put("requested", idList.size());
|
||||
|
||||
return AjaxResult.success(data).put("timestamp", System.currentTimeMillis());
|
||||
}
|
||||
|
||||
private List<Long> parseIds(String ids) {
|
||||
if (ids == null || ids.isBlank()) {
|
||||
return List.of();
|
||||
List<WaypointDTO> waypoints = new ArrayList<>();
|
||||
if (vehicle.getWaypoints() != null) {
|
||||
for (UnmannedVehicle.WaypointInfo wp : vehicle.getWaypoints()) {
|
||||
WaypointDTO waypoint = WaypointDTO.builder()
|
||||
.waypointId(wp.getWaypointId())
|
||||
.latitude(wp.getLatitude())
|
||||
.longitude(wp.getLongitude())
|
||||
.status(wp.getStatus().name())
|
||||
.build();
|
||||
waypoints.add(waypoint);
|
||||
}
|
||||
}
|
||||
return List.of(ids.split(","))
|
||||
.stream()
|
||||
.map(String::trim)
|
||||
.filter(s -> !s.isEmpty())
|
||||
.map(s -> {
|
||||
try {
|
||||
return Long.parseLong(s);
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.filter(v -> v != null)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
VehicleTaskDTO task = VehicleTaskDTO.builder()
|
||||
.vehicleId(vehicleId)
|
||||
.vehicleType(vehicleType)
|
||||
.missionId(missionId)
|
||||
.missionType(vehicle.getMissionType())
|
||||
.missionStatus(vehicle.getMissionStatus() != null ? vehicle.getMissionStatus().name() : "UNKNOWN")
|
||||
.missionStartTime(vehicle.getMissionStartTime())
|
||||
.estimatedEndTime(vehicle.getEstimatedEndTime())
|
||||
.progress(vehicle.getProgress())
|
||||
.totalMileage(vehicle.getTotalMileage())
|
||||
.waypoints(waypoints)
|
||||
.lastSeenAt(null) // 暂时设为null
|
||||
.build();
|
||||
|
||||
return AjaxResult.success(task).put("timestamp", System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,6 +108,13 @@ public class DataCollectorService {
|
||||
// 用于缓存所有活跃的MovingObject的最新状态
|
||||
private final Map<String, MovingObject> activeMovingObjectsCache = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 获取活跃的移动对象缓存(供外部访问)
|
||||
*/
|
||||
public Map<String, MovingObject> getActiveMovingObjectsCache() {
|
||||
return activeMovingObjectsCache;
|
||||
}
|
||||
|
||||
|
||||
// 航班通知缓存:Key=flightNo:type, Value=最新的航班通知
|
||||
private final Map<String, FlightNotification> flightNotificationCache = new ConcurrentHashMap<>();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user