修复坐标转换问题并新增车辆列表接口
- 修正经纬度坐标转换错误(longitude/latitude互换) - 新增车辆列表查询接口 GET /api/vehicle-manager/vehicles - 支持分页、状态筛选和离线判定 - 更新生产环境配置(Redis主机和无人车服务地址) - 优化任务路径点坐标映射
This commit is contained in:
parent
5309b98bcf
commit
8347eae959
@ -21,7 +21,7 @@ spring:
|
|||||||
# Redis配置(支持环境变量)
|
# Redis配置(支持环境变量)
|
||||||
data:
|
data:
|
||||||
redis:
|
redis:
|
||||||
host: ${REDIS_HOST:localhost}
|
host: ${REDIS_HOST:10.0.0.58}
|
||||||
port: ${REDIS_PORT:6379}
|
port: ${REDIS_PORT:6379}
|
||||||
database: ${REDIS_DATABASE:0}
|
database: ${REDIS_DATABASE:0}
|
||||||
password: ${REDIS_PASSWORD:}
|
password: ${REDIS_PASSWORD:}
|
||||||
@ -77,8 +77,8 @@ data:
|
|||||||
retry-attempts: ${VEHICLE_API_RETRY:3}
|
retry-attempts: ${VEHICLE_API_RETRY:3}
|
||||||
|
|
||||||
vehicle-manager:
|
vehicle-manager:
|
||||||
host: ${VEHICLE_MANAGER_HOST:}
|
host: ${VEHICLE_MANAGER_HOST:localhost}
|
||||||
port: ${VEHICLE_MANAGER_PORT:0}
|
port: ${VEHICLE_MANAGER_PORT:8020}
|
||||||
reconnect-delay-millis: ${VEHICLE_MANAGER_RECONNECT_DELAY:3000}
|
reconnect-delay-millis: ${VEHICLE_MANAGER_RECONNECT_DELAY:3000}
|
||||||
ws:
|
ws:
|
||||||
at-manager: /ws/at_manager
|
at-manager: /ws/at_manager
|
||||||
|
|||||||
@ -40,7 +40,7 @@ spring:
|
|||||||
|
|
||||||
# 默认激活的profile(开发环境)
|
# 默认激活的profile(开发环境)
|
||||||
profiles:
|
profiles:
|
||||||
# active: dev,druid
|
#active: dev,druid
|
||||||
active: prod,druid
|
active: prod,druid
|
||||||
|
|
||||||
# 文件上传
|
# 文件上传
|
||||||
|
|||||||
@ -38,6 +38,16 @@ public class VehicleManagerApiController {
|
|||||||
return AjaxResult.success(summary).put("timestamp", System.currentTimeMillis());
|
return AjaxResult.success(summary).put("timestamp", System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/vehicles")
|
||||||
|
public AjaxResult getVehicleList(
|
||||||
|
@RequestParam(defaultValue = "1") int pageNum,
|
||||||
|
@RequestParam(defaultValue = "10") int pageSize,
|
||||||
|
@RequestParam(required = false) String status,
|
||||||
|
@RequestParam(defaultValue = "30000") long staleMillis) {
|
||||||
|
VehicleManagerQueryService.VehicleListResponse response = queryService.getVehicleList(pageNum, pageSize, status, staleMillis);
|
||||||
|
return AjaxResult.success(response).put("timestamp", System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/vehicles/{vehicleId}")
|
@GetMapping("/vehicles/{vehicleId}")
|
||||||
public AjaxResult getVehicleSnapshot(@PathVariable String vehicleId) {
|
public AjaxResult getVehicleSnapshot(@PathVariable String vehicleId) {
|
||||||
Map<String, Object> snapshot = queryService.getVehicleSnapshot(vehicleId);
|
Map<String, Object> snapshot = queryService.getVehicleSnapshot(vehicleId);
|
||||||
@ -122,8 +132,8 @@ public class VehicleManagerApiController {
|
|||||||
Double y = getDouble(node, "y");
|
Double y = getDouble(node, "y");
|
||||||
waypoints.add(MissionContextDTO.WaypointDTO.builder()
|
waypoints.add(MissionContextDTO.WaypointDTO.builder()
|
||||||
.waypointId(String.valueOf(index++))
|
.waypointId(String.valueOf(index++))
|
||||||
.longitude(x)
|
.longitude(y)
|
||||||
.latitude(y)
|
.latitude(x)
|
||||||
.status("PENDING")
|
.status("PENDING")
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -297,7 +297,7 @@ public class DataCollectorService {
|
|||||||
Double x = getDouble(dataNode, "x");
|
Double x = getDouble(dataNode, "x");
|
||||||
Double y = getDouble(dataNode, "y");
|
Double y = getDouble(dataNode, "y");
|
||||||
if (x != null && y != null) {
|
if (x != null && y != null) {
|
||||||
Point currentPosition = geometryFactory.createPoint(new org.locationtech.jts.geom.Coordinate(x, y));
|
Point currentPosition = geometryFactory.createPoint(new org.locationtech.jts.geom.Coordinate(y, x));
|
||||||
|
|
||||||
MovingObject existing = activeMovingObjectsCache.get(vehicleId);
|
MovingObject existing = activeMovingObjectsCache.get(vehicleId);
|
||||||
UnmannedVehicle vehicle = existing instanceof UnmannedVehicle
|
UnmannedVehicle vehicle = existing instanceof UnmannedVehicle
|
||||||
|
|||||||
@ -6,9 +6,7 @@ import lombok.Data;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -187,4 +185,166 @@ public class VehicleManagerQueryService {
|
|||||||
}
|
}
|
||||||
return value.asText();
|
return value.asText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public static class VehicleListItemDTO {
|
||||||
|
private String vehicleId;
|
||||||
|
private String vehicleType;
|
||||||
|
private String status;
|
||||||
|
private Map<String, Object> position;
|
||||||
|
private Double speed;
|
||||||
|
private Double batteryLevel;
|
||||||
|
private Long lastSeenAt;
|
||||||
|
private Boolean isEmergency;
|
||||||
|
private Boolean isFault;
|
||||||
|
private String currentTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public static class VehicleListResponse {
|
||||||
|
private int total;
|
||||||
|
private int pageNum;
|
||||||
|
private int pageSize;
|
||||||
|
private List<VehicleListItemDTO> rows;
|
||||||
|
private VehicleSummary summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VehicleListResponse getVehicleList(int pageNum, int pageSize, String statusFilter, long staleMillis) {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
Set<String> vehicleIds = cacheService.getKnownVehicleIds();
|
||||||
|
List<VehicleListItemDTO> allVehicles = new ArrayList<>();
|
||||||
|
|
||||||
|
for (String vehicleId : vehicleIds) {
|
||||||
|
VehicleManagerCacheService.CacheEntry detailsEntry = cacheService.getVehicleDetails(vehicleId);
|
||||||
|
VehicleManagerCacheService.CacheEntry loginEntry = cacheService.getVehicleLoginStatus(vehicleId);
|
||||||
|
VehicleManagerCacheService.CacheEntry positionEntry = cacheService.getVehiclePosition(vehicleId);
|
||||||
|
VehicleManagerCacheService.CacheEntry chassisEntry = cacheService.getVehicleChassis(vehicleId);
|
||||||
|
VehicleManagerCacheService.CacheEntry suspendEntry = cacheService.getVehicleSuspend(vehicleId);
|
||||||
|
VehicleManagerCacheService.CacheEntry fmsEntry = cacheService.getVehicleFmsMessage(vehicleId);
|
||||||
|
VehicleManagerCacheService.CacheEntry orderEntry = cacheService.getVehicleOrder(vehicleId);
|
||||||
|
|
||||||
|
String vehicleType = getText(detailsEntry != null ? detailsEntry.getData() : null, "vehicleType");
|
||||||
|
String loginStatus = getText(loginEntry != null ? loginEntry.getData() : null, "loginStatus");
|
||||||
|
boolean loginStale = isStale(loginEntry, now, staleMillis);
|
||||||
|
|
||||||
|
String status;
|
||||||
|
if (loginEntry == null || loginStale) {
|
||||||
|
status = "offline";
|
||||||
|
} else {
|
||||||
|
status = "login".equalsIgnoreCase(loginStatus) ? "online" : "offline";
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isEmergency = false;
|
||||||
|
if (!isStale(suspendEntry, now, staleMillis)) {
|
||||||
|
Integer suspendStatus = getInt(suspendEntry != null ? suspendEntry.getData() : null, "suspendStatus");
|
||||||
|
if (suspendStatus != null && suspendStatus != 0) {
|
||||||
|
isEmergency = true;
|
||||||
|
status = "emergency";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isFault = false;
|
||||||
|
if (!isStale(fmsEntry, now, staleMillis)) {
|
||||||
|
if (isFault(fmsEntry != null ? fmsEntry.getData() : null)) {
|
||||||
|
isFault = true;
|
||||||
|
status = "fault";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statusFilter != null && !statusFilter.isEmpty() && !status.equalsIgnoreCase(statusFilter)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> position = null;
|
||||||
|
if (positionEntry != null && positionEntry.getData() != null) {
|
||||||
|
JsonNode posData = positionEntry.getData();
|
||||||
|
position = new HashMap<>();
|
||||||
|
position.put("x", getDouble(posData, "x"));
|
||||||
|
position.put("y", getDouble(posData, "y"));
|
||||||
|
position.put("theta", getDouble(posData, "theta"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Double speed = null;
|
||||||
|
if (chassisEntry != null && chassisEntry.getData() != null) {
|
||||||
|
JsonNode chassisData = chassisEntry.getData();
|
||||||
|
JsonNode stateInfo = chassisData.path("sys_info").path("state_info");
|
||||||
|
speed = getDouble(stateInfo, "d_speed_kmph");
|
||||||
|
}
|
||||||
|
|
||||||
|
Double batteryLevel = null;
|
||||||
|
if (chassisEntry != null && chassisEntry.getData() != null) {
|
||||||
|
JsonNode chassisData = chassisEntry.getData();
|
||||||
|
JsonNode stateInfo = chassisData.path("sys_info").path("state_info");
|
||||||
|
String batteryStr = getText(stateInfo, "d_battery_available");
|
||||||
|
if (batteryStr != null) {
|
||||||
|
try {
|
||||||
|
batteryLevel = Double.parseDouble(batteryStr);
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String currentTask = null;
|
||||||
|
if (orderEntry != null && orderEntry.getData() != null) {
|
||||||
|
currentTask = getText(orderEntry.getData(), "businessKey");
|
||||||
|
}
|
||||||
|
|
||||||
|
VehicleListItemDTO item = VehicleListItemDTO.builder()
|
||||||
|
.vehicleId(vehicleId)
|
||||||
|
.vehicleType(vehicleType)
|
||||||
|
.status(status)
|
||||||
|
.position(position)
|
||||||
|
.speed(speed)
|
||||||
|
.batteryLevel(batteryLevel)
|
||||||
|
.lastSeenAt(getLastSeenAt(vehicleId))
|
||||||
|
.isEmergency(isEmergency)
|
||||||
|
.isFault(isFault)
|
||||||
|
.currentTask(currentTask)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
allVehicles.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
int total = allVehicles.size();
|
||||||
|
int fromIndex = (pageNum - 1) * pageSize;
|
||||||
|
int toIndex = Math.min(fromIndex + pageSize, total);
|
||||||
|
List<VehicleListItemDTO> pagedVehicles = fromIndex < total ?
|
||||||
|
allVehicles.subList(fromIndex, toIndex) : new ArrayList<>();
|
||||||
|
|
||||||
|
VehicleSummary summary = getVehicleSummary(staleMillis);
|
||||||
|
|
||||||
|
return VehicleListResponse.builder()
|
||||||
|
.total(total)
|
||||||
|
.pageNum(pageNum)
|
||||||
|
.pageSize(pageSize)
|
||||||
|
.rows(pagedVehicles)
|
||||||
|
.summary(summary)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Double getDouble(JsonNode node, String field) {
|
||||||
|
if (node == null || node.isMissingNode()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JsonNode value = node.get(field);
|
||||||
|
if (value == null || value.isNull()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value.isDouble() || value.isFloat()) {
|
||||||
|
return value.asDouble();
|
||||||
|
}
|
||||||
|
if (value.isInt() || value.isLong()) {
|
||||||
|
return (double) value.asLong();
|
||||||
|
}
|
||||||
|
if (value.isTextual()) {
|
||||||
|
try {
|
||||||
|
return Double.parseDouble(value.asText());
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,8 +61,8 @@ public class VehicleStatusAggregationService {
|
|||||||
Double y = getDouble(data, "y");
|
Double y = getDouble(data, "y");
|
||||||
if (x != null && y != null) {
|
if (x != null && y != null) {
|
||||||
position = MotionStatusDTO.PositionDTO.builder()
|
position = MotionStatusDTO.PositionDTO.builder()
|
||||||
.longitude(x)
|
.longitude(y)
|
||||||
.latitude(y)
|
.latitude(x)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
Double theta = getDouble(data, "theta");
|
Double theta = getDouble(data, "theta");
|
||||||
@ -166,8 +166,8 @@ public class VehicleStatusAggregationService {
|
|||||||
Double y = getDouble(node, "y");
|
Double y = getDouble(node, "y");
|
||||||
MissionContextDTO.WaypointDTO waypoint = MissionContextDTO.WaypointDTO.builder()
|
MissionContextDTO.WaypointDTO waypoint = MissionContextDTO.WaypointDTO.builder()
|
||||||
.waypointId(String.valueOf(index++))
|
.waypointId(String.valueOf(index++))
|
||||||
.longitude(x)
|
.longitude(y)
|
||||||
.latitude(y)
|
.latitude(x)
|
||||||
.status("PENDING")
|
.status("PENDING")
|
||||||
.build();
|
.build();
|
||||||
waypoints.add(waypoint);
|
waypoints.add(waypoint);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user