修复充电
This commit is contained in:
@@ -227,14 +227,27 @@ public class ChargingRobotServiceImpl extends ServiceImpl<ChargingRobotMapper, C
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean releaseRobot(Long robotId) {
|
||||
ChargingRobot robot = getById(robotId);
|
||||
if (robot == null) {
|
||||
log.warn("尝试释放机器人失败,机器人不存在: {}", robotId);
|
||||
return false;
|
||||
}
|
||||
// 将机器人状态设置为空闲,并清除当前任务ID
|
||||
return updateRobotStatus(robot.getRobotUid(), RobotStatusEnum.IDLE, null, null, null, null); // 第二个参数传null以清除任务ID
|
||||
|
||||
// 关键修复:确保释放机器人时,原子性地更新其状态和任务ID
|
||||
ChargingRobot robotToUpdate = new ChargingRobot();
|
||||
robotToUpdate.setId(robotId);
|
||||
robotToUpdate.setStatus(RobotStatusEnum.IDLE.getValue());
|
||||
robotToUpdate.setCurrentTaskId(null); // 显式清除任务ID
|
||||
|
||||
boolean success = this.updateById(robotToUpdate);
|
||||
if (success) {
|
||||
log.info("成功释放机器人 {},状态设置为IDLE,任务ID已清除。", robot.getRobotUid());
|
||||
} else {
|
||||
log.error("数据库操作失败,未能释放机器人 {}", robot.getRobotUid());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -352,24 +352,6 @@ public class ChargingSessionServiceImpl extends ServiceImpl<ChargingSessionMappe
|
||||
log.info("会话 {} 费用计算完成: {}元. 状态更新为 PAYMENT_PENDING", sessionId, cost);
|
||||
// 此处可以触发通知用户支付
|
||||
}
|
||||
|
||||
// 在计费完成后,如果会话已标记为COMPLETED,但尚未支付,并且车位状态不是AVAILABLE,则将其设置为空闲
|
||||
// 这主要覆盖了 handleChargingEnd 中可能未完全释放车位的情况(例如,如果计费失败)
|
||||
// 或者如果 calculateCostAndFinalizeSession 是独立调用的。
|
||||
String sessionStatus = session.getStatus();
|
||||
String paymentStatus = session.getPaymentStatus();
|
||||
|
||||
if (ChargingSessionStatusEnum.CHARGING_COMPLETED.getValue().equals(sessionStatus) ||
|
||||
PaymentStatusEnum.PAID.getValue().equals(paymentStatus) ||
|
||||
PaymentStatusEnum.FAILED.getValue().equals(paymentStatus)) {
|
||||
|
||||
ParkingSpot spot = parkingSpotService.getById(session.getSpotId());
|
||||
if (spot != null && !ParkingSpotStatusEnum.AVAILABLE.getValue().equals(spot.getStatus())) {
|
||||
log.info("在 finalizeSession for session {} 时,车位 {} (UID: {}) 状态为 {},将其更新为 AVAILABLE。",
|
||||
sessionId, spot.getId(), spot.getSpotUid(), spot.getStatus());
|
||||
parkingSpotService.updateSpotStatus(spot.getSpotUid(), ParkingSpotStatusEnum.AVAILABLE, null);
|
||||
}
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,34 +68,34 @@ public class MqttMessageHandler implements IMqttMessageListener {
|
||||
statusMessage.getStatus(), statusMessage.getTaskId(), robotUIDFromTopicSource, payloadJson);
|
||||
// Do not return, general status might still need processing.
|
||||
} else {
|
||||
boolean taskUpdated; // Defined outside switch
|
||||
switch (taskNewStatus) {
|
||||
case PROCESSING:
|
||||
taskUpdated = robotTaskService.markTaskAsProcessing(statusMessage.getTaskId(), new Date(), statusMessage.getMessage());
|
||||
break;
|
||||
case COMPLETED:
|
||||
taskUpdated = robotTaskService.markTaskAsCompleted(statusMessage.getTaskId(), new Date(), statusMessage.getMessage());
|
||||
break;
|
||||
case FAILED:
|
||||
String combinedTaskErrorMessage = statusMessage.getErrorCode() != null ?
|
||||
statusMessage.getErrorCode() + ": " + statusMessage.getMessage() :
|
||||
statusMessage.getMessage();
|
||||
taskUpdated = robotTaskService.markTaskAsFailed(statusMessage.getTaskId(), combinedTaskErrorMessage, new Date());
|
||||
break;
|
||||
default:
|
||||
log.warn("Received unhandled RobotTaskStatusEnum: {} for task {} from robot {}. Ignoring.",
|
||||
taskNewStatus, statusMessage.getTaskId(), robotUIDFromTopicSource);
|
||||
boolean taskUpdated; // Defined outside switch
|
||||
switch (taskNewStatus) {
|
||||
case PROCESSING:
|
||||
taskUpdated = robotTaskService.markTaskAsProcessing(statusMessage.getTaskId(), new Date(), statusMessage.getMessage());
|
||||
break;
|
||||
case COMPLETED:
|
||||
taskUpdated = robotTaskService.markTaskAsCompleted(statusMessage.getTaskId(), new Date(), statusMessage.getMessage());
|
||||
break;
|
||||
case FAILED:
|
||||
String combinedTaskErrorMessage = statusMessage.getErrorCode() != null ?
|
||||
statusMessage.getErrorCode() + ": " + statusMessage.getMessage() :
|
||||
statusMessage.getMessage();
|
||||
taskUpdated = robotTaskService.markTaskAsFailed(statusMessage.getTaskId(), combinedTaskErrorMessage, new Date());
|
||||
break;
|
||||
default:
|
||||
log.warn("Received unhandled RobotTaskStatusEnum: {} for task {} from robot {}. Ignoring.",
|
||||
taskNewStatus, statusMessage.getTaskId(), robotUIDFromTopicSource);
|
||||
taskUpdated = false; // To prevent logging success
|
||||
break;
|
||||
}
|
||||
if (taskUpdated) {
|
||||
log.info("Successfully updated task {} to status {} for robot {} based on MQTT message.",
|
||||
statusMessage.getTaskId(), taskNewStatus, robotUIDFromTopicSource);
|
||||
} else {
|
||||
log.warn("Failed to update task {} to status {} for robot {} (or task not found/invalid state transition). Message: {}",
|
||||
statusMessage.getTaskId(), taskNewStatus, robotUIDFromTopicSource, statusMessage.getMessage());
|
||||
}
|
||||
}
|
||||
if (taskUpdated) {
|
||||
log.info("Successfully updated task {} to status {} for robot {} based on MQTT message.",
|
||||
statusMessage.getTaskId(), taskNewStatus, robotUIDFromTopicSource);
|
||||
} else {
|
||||
log.warn("Failed to update task {} to status {} for robot {} (or task not found/invalid state transition). Message: {}",
|
||||
statusMessage.getTaskId(), taskNewStatus, robotUIDFromTopicSource, statusMessage.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scenario 2: Message contains a general robot status update.
|
||||
|
||||
@@ -127,41 +127,51 @@ public class ParkingSpotServiceImpl extends ServiceImpl<ParkingSpotMapper, Parki
|
||||
return false;
|
||||
}
|
||||
|
||||
ParkingSpot parkingSpot = this.findBySpotUid(spotUID);
|
||||
ParkingSpot parkingSpot = this.findBySpotUid(spotUID);
|
||||
if (parkingSpot == null) {
|
||||
log.warn("更新车位状态失败:未找到 UID 为 {} 的车位。", spotUID);
|
||||
return false;
|
||||
}
|
||||
|
||||
ParkingSpot spotToUpdate = new ParkingSpot();
|
||||
spotToUpdate.setId(parkingSpot.getId());
|
||||
boolean changed = false;
|
||||
|
||||
// Compare enum with String value from entity
|
||||
if (newStatus != null && !newStatus.getValue().equals(parkingSpot.getStatus())) {
|
||||
spotToUpdate.setStatus(newStatus.getValue()); // Set String value to entity
|
||||
changed = true;
|
||||
// 彻底重构:创建一个包含所有最终状态的更新对象,避免复杂的条件逻辑。
|
||||
// 这是解决顽固的 "empty set clause" 问题的最稳健方法。
|
||||
|
||||
boolean needsUpdate = false;
|
||||
|
||||
// 检查状态是否需要更新
|
||||
if (!newStatus.getValue().equals(parkingSpot.getStatus())) {
|
||||
needsUpdate = true;
|
||||
}
|
||||
|
||||
if (currentSessionId == null && parkingSpot.getCurrentSessionId() != null) {
|
||||
spotToUpdate.setCurrentSessionId(null);
|
||||
changed = true;
|
||||
} else if (currentSessionId != null && !currentSessionId.equals(parkingSpot.getCurrentSessionId())) {
|
||||
// 检查会话ID是否需要更新
|
||||
Long targetSessionId = (newStatus == ParkingSpotStatusEnum.AVAILABLE) ? null : currentSessionId;
|
||||
if (targetSessionId == null && parkingSpot.getCurrentSessionId() != null) {
|
||||
needsUpdate = true;
|
||||
} else if (targetSessionId != null && !targetSessionId.equals(parkingSpot.getCurrentSessionId())) {
|
||||
needsUpdate = true;
|
||||
}
|
||||
|
||||
if (!needsUpdate) {
|
||||
log.info("车位 {} 的状态与数据库一致 (状态: {}, 会话ID: {}),无需更新。",
|
||||
spotUID, newStatus, currentSessionId == null ? "null" : currentSessionId);
|
||||
return true; // 数据一致,操作成功
|
||||
}
|
||||
|
||||
// 创建一个完整的更新实体
|
||||
ParkingSpot spotToUpdate = new ParkingSpot();
|
||||
spotToUpdate.setId(parkingSpot.getId());
|
||||
spotToUpdate.setStatus(newStatus.getValue());
|
||||
|
||||
if (newStatus == ParkingSpotStatusEnum.AVAILABLE) {
|
||||
spotToUpdate.setCurrentSessionId(null);
|
||||
} else {
|
||||
spotToUpdate.setCurrentSessionId(currentSessionId);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (!changed) {
|
||||
log.info("车位 {} 的状态与数据库一致 (状态: {}, 会话ID: {}),无需更新。",
|
||||
spotUID, newStatus, currentSessionId == null ? "null" : currentSessionId);
|
||||
return true; // Data is consistent, operation considered successful
|
||||
}
|
||||
|
||||
// updateTime will be auto-filled
|
||||
boolean success = this.updateById(spotToUpdate);
|
||||
if (success) {
|
||||
log.info("成功更新车位 {} 的状态。新状态: {}, 当前会话ID: {}",
|
||||
spotUID, newStatus, currentSessionId == null ? "null" : currentSessionId);
|
||||
log.info("成功更新车位 {} 的状态。新状态: {}, 当前会话ID: {}",
|
||||
spotUID, spotToUpdate.getStatus(), spotToUpdate.getCurrentSessionId() == null ? "null" : spotToUpdate.getCurrentSessionId());
|
||||
} else {
|
||||
log.error("更新车位 {} 的状态失败 (数据库操作失败)。", spotUID);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user