package com.cmvr.resource.service; import com.cmvr.common.exception.GlobalException; import com.cmvr.common.robot.RobotEndpoint; import com.cmvr.common.robot.RobotEndpointResolver; import com.cmvr.resource.config.ResourceRobotStateProperties; import com.cmvr.resource.domain.ResourceRobot; import com.cmvr.resource.mapper.ResourceRobotMapper; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import java.util.Date; @Service @RequiredArgsConstructor public class ResourceRobotEndpointResolver implements RobotEndpointResolver { private final ResourceRobotMapper robotMapper; private final ResourceRobotStateProperties stateProperties; @Override public RobotEndpoint resolve(String robotId) { String normalized = StringUtils.trimToNull(robotId); if (normalized == null) { throw new GlobalException("机器人ID不能为空"); } if (stateProperties.isVirtualRobot(normalized)) { throw new GlobalException("虚拟机器人不能调用边缘设备服务:" + normalized); } ResourceRobot robot = robotMapper.selectByRobotIdentity(normalized); if (robot == null) { throw new GlobalException("机器人不存在:" + normalized); } if ("1".equals(robot.getArchivedStatus())) { throw new GlobalException("机器人已归档:" + normalized); } if (!"1".equals(robot.getConnectStatus())) { throw new GlobalException("机器人当前离线:" + normalized); } Date cutoff = stateProperties.heartbeatCutoff(new Date()); if (robot.getLastHeartbeatTime() == null || robot.getLastHeartbeatTime().before(cutoff)) { throw new GlobalException("机器人QUIC心跳已超时:" + normalized); } if (StringUtils.isBlank(robot.getIpAddress()) || robot.getPort() == null) { throw new GlobalException("机器人尚未上报gRPC地址:" + normalized); } return new RobotEndpoint(robot.getIpAddress(), robot.getPort().intValue()); } }