diff --git a/nex-be/src/main/java/com/unisinsight/project/controller/ImageVirtualMachinesController.java b/nex-be/src/main/java/com/unisinsight/project/controller/ImageVirtualMachinesController.java index 997cc74..e0f6d5a 100644 --- a/nex-be/src/main/java/com/unisinsight/project/controller/ImageVirtualMachinesController.java +++ b/nex-be/src/main/java/com/unisinsight/project/controller/ImageVirtualMachinesController.java @@ -13,10 +13,7 @@ import com.unisinsight.project.service.ImageVirtualMachinesService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.Objects; @@ -154,6 +151,13 @@ public class ImageVirtualMachinesController { log.info("终端卸载文件请求参数为:{}", JSONUtil.toJsonStr(req)); return service.removeIso(req); } + @ApiOperation(value = "获取VNC信息") + @GetMapping("/vnc") + public Result getVncData(@RequestParam("vmName") String vmName) { + + log.info("获取VNC信息请求参数为:{}", vmName); + return service.getVncData(vmName); + } } diff --git a/nex-be/src/main/java/com/unisinsight/project/entity/res/DeviceImageMappingRes.java b/nex-be/src/main/java/com/unisinsight/project/entity/res/DeviceImageMappingRes.java index b4d3d33..e2de209 100644 --- a/nex-be/src/main/java/com/unisinsight/project/entity/res/DeviceImageMappingRes.java +++ b/nex-be/src/main/java/com/unisinsight/project/entity/res/DeviceImageMappingRes.java @@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; +import java.util.Date; /** * @TableName device_image_mapping @@ -59,6 +60,19 @@ public class DeviceImageMappingRes implements Serializable { @JsonProperty(value = "image_file_name") @ApiModelProperty("镜像源文件名称") private String imageFileName; + + /** + * 父镜像名称 + */ + @JsonProperty(value = "parent_image_name") + @ApiModelProperty("父镜像名称") + private String parentImageName; + /** + * 父镜像名称 + */ + @JsonProperty(value = "create_time") + @ApiModelProperty("创建时间") + private Date createTime; /** * 还原方式 diff --git a/nex-be/src/main/java/com/unisinsight/project/entity/res/VncData.java b/nex-be/src/main/java/com/unisinsight/project/entity/res/VncData.java new file mode 100644 index 0000000..4c8053e --- /dev/null +++ b/nex-be/src/main/java/com/unisinsight/project/entity/res/VncData.java @@ -0,0 +1,33 @@ +package com.unisinsight.project.entity.res; + + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author : ch + * @version : 1.0 + * @ClassName : VncData + * @Description : + * @DATE : Created in 9:41 2025/9/8 + *
       Copyright: Copyright(c) 2025     
+ *
       Company :   	紫光汇智信息技术有限公司		           
+ * Modification History: + * Date Author Version Discription + * -------------------------------------------------------------------------- + * 2025/09/08 ch 1.0 Why & What is modified: <修改原因描述> * + */ +@NoArgsConstructor +@Data +public class VncData { + + @JsonProperty("host") + private String host; + @JsonProperty("port") + private Integer port; + @JsonProperty("url") + private String url; + @JsonProperty("websocket_url") + private String websocketUrl; +} diff --git a/nex-be/src/main/java/com/unisinsight/project/feign/ExternalApiClient.java b/nex-be/src/main/java/com/unisinsight/project/feign/ExternalApiClient.java index e92251e..ca889bb 100644 --- a/nex-be/src/main/java/com/unisinsight/project/feign/ExternalApiClient.java +++ b/nex-be/src/main/java/com/unisinsight/project/feign/ExternalApiClient.java @@ -4,6 +4,7 @@ import com.unisinsight.project.config.FeignConfig; import com.unisinsight.project.entity.dto.*; import com.unisinsight.project.entity.req.*; import com.unisinsight.project.entity.res.ImageStatusRes; +import com.unisinsight.project.entity.res.VncData; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*; @@ -90,5 +91,7 @@ public interface ExternalApiClient { @GetMapping("/api/v1/network/bridge-interfaces") ApiResponse> getBridgeInterfaces(); + @GetMapping("/api/v1/vm/{vmName}/vnc") + ApiResponse getVncData(@PathVariable("vmName") String vmName); } diff --git a/nex-be/src/main/java/com/unisinsight/project/grpc/service/ClientNotificationServiceImpl.java b/nex-be/src/main/java/com/unisinsight/project/grpc/service/ClientNotificationServiceImpl.java index bcc8fec..b57401f 100644 --- a/nex-be/src/main/java/com/unisinsight/project/grpc/service/ClientNotificationServiceImpl.java +++ b/nex-be/src/main/java/com/unisinsight/project/grpc/service/ClientNotificationServiceImpl.java @@ -41,7 +41,7 @@ public class ClientNotificationServiceImpl extends NotificationServiceGrpc.Notif private final ConcurrentHashMap> clientStreamMap = new ConcurrentHashMap<>(); private final static int MAX_CLIENT_COUNT = 1000; - + public static final String DEFAULT_USER = "NexOS"; // 生成客户端连接key的工具方法 private String generateClientKey(String clientId, String clientUser) { return clientId + "#" + clientUser; @@ -70,15 +70,7 @@ public class ClientNotificationServiceImpl extends NotificationServiceGrpc.Notif return; // 避免继续执行后续逻辑 } - if (StringUtil.isEmpty(clientUser)) { - NotificationMessage errMsg = NotificationMessage.newBuilder() - .setCode(HttpStatus.BAD_REQUEST.value()) - .setMsg("client_user不能为空") - .build(); - responseObserver.onNext(errMsg); - responseObserver.onCompleted(); - return; // 避免继续执行后续逻辑 - } + clientUser= StringUtil.isEmpty(clientUser) ? DEFAULT_USER : clientUser; log.info("客户端连接:client_sn:[{}],client_user: [{}]", clientSn, clientUser); @@ -93,11 +85,12 @@ public class ClientNotificationServiceImpl extends NotificationServiceGrpc.Notif final io.grpc.Context context = io.grpc.Context.current(); // 注册一个取消监听器来监听客户端断开连接 + String finalClientUser = clientUser; context.addListener(context1 -> { // 客户端断开连接时的处理逻辑 - log.info("通过Context监听到客户端断开连接: {}, 用户: {}", clientSn, clientUser); - removeClientConnection(clientSn, clientUser); - log.info("清理客户端连接: {}#{}, 剩余客户端数: {}", clientSn, clientUser, clientStreamMap.size()); + log.info("通过Context监听到客户端断开连接: {}, 用户: {}", clientSn, finalClientUser); + removeClientConnection(clientSn, finalClientUser); + log.info("清理客户端连接: {}#{}, 剩余客户端数: {}", clientSn, finalClientUser, clientStreamMap.size()); }, executorService); } diff --git a/nex-be/src/main/java/com/unisinsight/project/service/ImageVirtualMachinesService.java b/nex-be/src/main/java/com/unisinsight/project/service/ImageVirtualMachinesService.java index 8767b0b..641e958 100644 --- a/nex-be/src/main/java/com/unisinsight/project/service/ImageVirtualMachinesService.java +++ b/nex-be/src/main/java/com/unisinsight/project/service/ImageVirtualMachinesService.java @@ -61,5 +61,7 @@ public interface ImageVirtualMachinesService extends IService removeIso(ImageVirtualMachinesReq req); Result attachIso(ImageVirtualMachinesReq req); + + Result getVncData(String vmName); } diff --git a/nex-be/src/main/java/com/unisinsight/project/service/impl/DeviceImageMappingServiceImpl.java b/nex-be/src/main/java/com/unisinsight/project/service/impl/DeviceImageMappingServiceImpl.java index 1670d0a..e3b0d66 100644 --- a/nex-be/src/main/java/com/unisinsight/project/service/impl/DeviceImageMappingServiceImpl.java +++ b/nex-be/src/main/java/com/unisinsight/project/service/impl/DeviceImageMappingServiceImpl.java @@ -7,23 +7,18 @@ import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.unisinsight.project.entity.dao.DeviceImageMapping; -import com.unisinsight.project.entity.dao.Image; -import com.unisinsight.project.entity.dao.ImageDesktop; -import com.unisinsight.project.entity.dao.UserDeviceGroup; +import com.unisinsight.project.entity.dao.*; import com.unisinsight.project.entity.req.DeviceImageMappingReq; import com.unisinsight.project.entity.res.DeviceImageMappingRes; import com.unisinsight.project.exception.Result; -import com.unisinsight.project.mapper.DeviceImageMappingMapper; -import com.unisinsight.project.mapper.ImageDesktopMapper; -import com.unisinsight.project.mapper.ImageMapper; -import com.unisinsight.project.mapper.UserDeviceGroupMapper; +import com.unisinsight.project.mapper.*; import com.unisinsight.project.service.DeviceImageMappingService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; @@ -43,6 +38,8 @@ public class DeviceImageMappingServiceImpl extends ServiceImpl imageLambdaQueryWrapper = new LambdaQueryWrapper().in(ImageDesktop::getId, imageIds); List images = imageDesktopMapper.selectList(imageLambdaQueryWrapper); + List imageVirtualIdList = images.stream().map(ImageDesktop::getImageVirtualId).filter(Objects::nonNull).collect(Collectors.toList()); + LambdaQueryWrapper imageVirtualMachinesLambdaQueryWrapper = new LambdaQueryWrapper().in(ImageVirtualMachines::getId, imageVirtualIdList); + List imageVirtualMachines = imageVirtualMachinesMapper.selectList(imageVirtualMachinesLambdaQueryWrapper); + Map imageVirtualMachinesMap = imageVirtualMachines.stream().collect(Collectors.toMap(ImageVirtualMachines::getId, ImageVirtualMachines::getImageName)); + if (CollectionUtil.isNotEmpty(images)) { deviceImageMappingRes.forEach(deviceImage -> images.forEach(image -> { if (ObjectUtil.isNotEmpty(deviceImage.getImageId()) && image.getId().equals(deviceImage.getImageId())) { deviceImage.setImageName(image.getDesktopName()); deviceImage.setImageFileName(image.getDesktopName()+"."+image.getDesktopType()); + deviceImage.setCreateTime(image.getCreateTime()); + // 设置父镜像名称 + if (image.getImageVirtualId() != null) { + deviceImage.setParentImageName(imageVirtualMachinesMap.get(image.getImageVirtualId().longValue())); + } } })); } diff --git a/nex-be/src/main/java/com/unisinsight/project/service/impl/ImageVirtualMachinesServiceImpl.java b/nex-be/src/main/java/com/unisinsight/project/service/impl/ImageVirtualMachinesServiceImpl.java index a1033fc..7130459 100644 --- a/nex-be/src/main/java/com/unisinsight/project/service/impl/ImageVirtualMachinesServiceImpl.java +++ b/nex-be/src/main/java/com/unisinsight/project/service/impl/ImageVirtualMachinesServiceImpl.java @@ -17,6 +17,7 @@ import com.unisinsight.project.entity.req.*; import com.unisinsight.project.entity.res.ImageStatusRes; import com.unisinsight.project.entity.res.ImageVirtualMachinesRes; import com.unisinsight.project.entity.res.PageResult; +import com.unisinsight.project.entity.res.VncData; import com.unisinsight.project.exception.BaseErrorCode; import com.unisinsight.project.exception.Result; import com.unisinsight.project.feign.ExternalApiClient; @@ -323,7 +324,7 @@ public class ImageVirtualMachinesServiceImpl extends ServiceImpl getVncData(String vmName) { + ApiResponse vncData = externalApiClient.getVncData(vmName); + if ("200".equals(vncData.getCode())){ + return Result.successResult(vncData.getData()); + } + return Result.errorResultMessage(BaseErrorCode.HTTP_ERROR_CODE_500, vncData.getMessage()); + } + }