diff --git a/nex-be/src/main/java/com/unisinsight/project/entity/dao/NetworkManage.java b/nex-be/src/main/java/com/unisinsight/project/entity/dao/NetworkManage.java index 5a3d190..17b4f37 100644 --- a/nex-be/src/main/java/com/unisinsight/project/entity/dao/NetworkManage.java +++ b/nex-be/src/main/java/com/unisinsight/project/entity/dao/NetworkManage.java @@ -1,6 +1,8 @@ + package com.unisinsight.project.entity.dao; import com.baomidou.mybatisplus.annotation.*; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import java.util.Date; @@ -24,89 +26,110 @@ public class NetworkManage { * 网络名称 */ @TableField("network_name") + @JsonProperty("network_name") private String networkName; /** * 网络类型 */ @TableField("type") + @JsonProperty("type") private String type; /** * 桥接名称 */ @TableField("bridge_name") + @JsonProperty("bridge_name") private String bridgeName; /** * IP范围 */ @TableField("ip_range") + @JsonProperty("ip_range") private String ipRange; /** * 网关 */ @TableField("gateway") + @JsonProperty("gateway") private String gateway; /** * 子网掩码 */ @TableField("netmask") + @JsonProperty("netmask") private String netmask; /** * DHCP启用状态 */ @TableField("dhcp_enabled") - private Short dhcpEnabled; + @JsonProperty("dhcp_enabled") + private Integer dhcpEnabled; /** * DHCP起始地址 */ @TableField("dhcp_start") + @JsonProperty("dhcp_start") private String dhcpStart; /** * DHCP结束地址 */ @TableField("dhcp_end") + @JsonProperty("dhcp_end") private String dhcpEnd; /** * VLAN ID */ @TableField("vlan_id") + @JsonProperty("vlan_id") private String vlanId; /** * 状态 */ @TableField("status") + @JsonProperty("status") private Integer status; /** * 创建用户 */ @TableField("create_user") + @JsonProperty("create_user") private String createUser; /** * 创建时间 */ @TableField("create_time") + @JsonProperty("create_time") private Date createTime; /** * 更新时间 */ @TableField("update_time") + @JsonProperty("update_time") private Date updateTime; /** * 描述信息 */ @TableField("description") + @JsonProperty("description") private String description; -} + + /** + * 开机自启动 + */ + @TableField("autostart") + private Integer autostart; +} \ No newline at end of file diff --git a/nex-be/src/main/java/com/unisinsight/project/entity/dto/Network.java b/nex-be/src/main/java/com/unisinsight/project/entity/dto/Network.java index 9b3564c..a7d35e5 100644 --- a/nex-be/src/main/java/com/unisinsight/project/entity/dto/Network.java +++ b/nex-be/src/main/java/com/unisinsight/project/entity/dto/Network.java @@ -1,150 +1,54 @@ + // Network.java - 网络信息对象 package com.unisinsight.project.entity.dto; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data public class Network { + @JsonProperty("network_name") + private String networkName; + private String name; + private String uuid; + private String state; - private Integer autostart; + + @JsonProperty("autostart") + private Boolean autostart; + private Integer persistent; + private String description; + private String type; + private String bridge; + + @JsonProperty("bridge_name") private String bridgeName; + + @JsonProperty("ip_address") private String ipAddress; + private String netmask; + private String gateway; + + @JsonProperty("ip_range") private String ipRange; + + @JsonProperty("dhcp_enabled") private Boolean dhcpEnabled; + + @JsonProperty("dhcp_start") private String dhcpStart; + + @JsonProperty("dhcp_end") private String dhcpEnd; - // Getters and Setters - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getUuid() { - return uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - public String getState() { - return state; - } - - public void setState(String state) { - this.state = state; - } - - public Integer getAutostart() { - return autostart; - } - - public void setAutostart(Integer autostart) { - this.autostart = autostart; - } - - public Integer getPersistent() { - return persistent; - } - - public void setPersistent(Integer persistent) { - this.persistent = persistent; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getBridge() { - return bridge; - } - - public void setBridge(String bridge) { - this.bridge = bridge; - } - - public String getBridgeName() { - return bridgeName; - } - - public void setBridgeName(String bridgeName) { - this.bridgeName = bridgeName; - } - - public String getIpAddress() { - return ipAddress; - } - - public void setIpAddress(String ipAddress) { - this.ipAddress = ipAddress; - } - - public String getNetmask() { - return netmask; - } - - public void setNetmask(String netmask) { - this.netmask = netmask; - } - - public String getGateway() { - return gateway; - } - - public void setGateway(String gateway) { - this.gateway = gateway; - } - - public String getIpRange() { - return ipRange; - } - - public void setIpRange(String ipRange) { - this.ipRange = ipRange; - } - - public Boolean getDhcpEnabled() { - return dhcpEnabled; - } - - public void setDhcpEnabled(Boolean dhcpEnabled) { - this.dhcpEnabled = dhcpEnabled; - } - - public String getDhcpStart() { - return dhcpStart; - } - - public void setDhcpStart(String dhcpStart) { - this.dhcpStart = dhcpStart; - } - - public String getDhcpEnd() { - return dhcpEnd; - } - - public void setDhcpEnd(String dhcpEnd) { - this.dhcpEnd = dhcpEnd; - } -} + @JsonProperty("vlan_id") + private Integer vlanId; +} \ No newline at end of file diff --git a/nex-be/src/main/java/com/unisinsight/project/entity/req/NetworkManagePageReq.java b/nex-be/src/main/java/com/unisinsight/project/entity/req/NetworkManagePageReq.java index d309ff0..9a69500 100644 --- a/nex-be/src/main/java/com/unisinsight/project/entity/req/NetworkManagePageReq.java +++ b/nex-be/src/main/java/com/unisinsight/project/entity/req/NetworkManagePageReq.java @@ -1,3 +1,4 @@ + package com.unisinsight.project.entity.req; import com.fasterxml.jackson.annotation.JsonProperty; @@ -16,7 +17,8 @@ public class NetworkManagePageReq { * 网络名称 */ @Size(max = 64, message = "网络名称长度不能超过64个字符") - @ApiModelProperty(value = "网络名称", required = true) + @ApiModelProperty(value = "网络名称") + @JsonProperty("network_name") private String networkName; /** @@ -24,6 +26,7 @@ public class NetworkManagePageReq { */ @Size(max = 16, message = "网络类型长度不能超过16个字符") @ApiModelProperty(value = "网络类型") + @JsonProperty("type") private String type; /** @@ -31,13 +34,14 @@ public class NetworkManagePageReq { */ @Size(max = 64, message = "桥接名称长度不能超过64个字符") @ApiModelProperty(value = "桥接名称") + @JsonProperty("bridge_name") private String bridgeName; /** * 状态 */ - @NotNull(message = "状态不能为空") - @ApiModelProperty(value = "状态", required = true) + @ApiModelProperty(value = "状态") + @JsonProperty("status") private Integer status; /** @@ -54,4 +58,4 @@ public class NetworkManagePageReq { @JsonProperty("page_size") private Integer pageSize = 10; -} +} \ No newline at end of file diff --git a/nex-be/src/main/java/com/unisinsight/project/entity/req/NetworkManageReq.java b/nex-be/src/main/java/com/unisinsight/project/entity/req/NetworkManageReq.java index 0dc22da..2d8e60e 100644 --- a/nex-be/src/main/java/com/unisinsight/project/entity/req/NetworkManageReq.java +++ b/nex-be/src/main/java/com/unisinsight/project/entity/req/NetworkManageReq.java @@ -1,12 +1,13 @@ + package com.unisinsight.project.entity.req; +import com.baomidou.mybatisplus.annotation.TableField; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; @Data @@ -22,13 +23,15 @@ public class NetworkManageReq { @NotBlank(message = "网络名称不能为空") @Size(max = 64, message = "网络名称长度不能超过64个字符") @ApiModelProperty(value = "网络名称", required = true) + @JsonProperty("network_name") private String networkName; /** * 网络类型 */ @Size(max = 16, message = "网络类型长度不能超过16个字符") - @ApiModelProperty(value = "网络类型") + @ApiModelProperty(value = "网络类型:nat:(NAT网络地址转换)、bridge:Bridge(桥接模式)、Isolated(隔离模式)") + @JsonProperty("type") private String type; /** @@ -36,6 +39,7 @@ public class NetworkManageReq { */ @Size(max = 64, message = "桥接名称长度不能超过64个字符") @ApiModelProperty(value = "桥接名称") + @JsonProperty("bridge_name") private String bridgeName; /** @@ -43,6 +47,7 @@ public class NetworkManageReq { */ @Size(max = 64, message = "IP范围长度不能超过64个字符") @ApiModelProperty(value = "IP范围") + @JsonProperty("ip_range") private String ipRange; /** @@ -50,6 +55,7 @@ public class NetworkManageReq { */ @Size(max = 64, message = "网关长度不能超过64个字符") @ApiModelProperty(value = "网关") + @JsonProperty("gateway") private String gateway; /** @@ -57,12 +63,14 @@ public class NetworkManageReq { */ @Size(max = 64, message = "子网掩码长度不能超过64个字符") @ApiModelProperty(value = "子网掩码") + @JsonProperty("netmask") private String netmask; /** * DHCP启用状态 */ @ApiModelProperty(value = "DHCP启用状态") + @JsonProperty("dhcp_enabled:1 启用 0 不启用") private Short dhcpEnabled; /** @@ -70,6 +78,7 @@ public class NetworkManageReq { */ @Size(max = 64, message = "DHCP起始地址长度不能超过64个字符") @ApiModelProperty(value = "DHCP起始地址") + @JsonProperty("dhcp_start") private String dhcpStart; /** @@ -77,6 +86,7 @@ public class NetworkManageReq { */ @Size(max = 64, message = "DHCP结束地址长度不能超过64个字符") @ApiModelProperty(value = "DHCP结束地址") + @JsonProperty("dhcp_end") private String dhcpEnd; /** @@ -84,20 +94,21 @@ public class NetworkManageReq { */ @Size(max = 64, message = "VLAN ID长度不能超过64个字符") @ApiModelProperty(value = "VLAN ID") + @JsonProperty("vlan_id") private String vlanId; /** * 状态 */ - @NotNull(message = "状态不能为空") - @ApiModelProperty(value = "状态", required = true) + @ApiModelProperty(value = "状态,新增时不传") + @JsonProperty("status:1,活跃,0,非活跃") private Integer status; /** * 创建用户 */ - @Size(max = 64, message = "创建用户长度不能超过64个字符") @ApiModelProperty(value = "创建用户") + @JsonProperty("create_user") private String createUser; /** @@ -105,20 +116,13 @@ public class NetworkManageReq { */ @Size(max = 128, message = "描述信息长度不能超过128个字符") @ApiModelProperty(value = "描述信息") + @JsonProperty("description") private String description; /** - * 查询页 + * 开机自启动 */ - @ApiModelProperty(value = "查询页", notes = "分页查询时再传", dataType = "Integer") - @JsonProperty("page_num") - private Integer pageNum; + @ApiModelProperty(value = "开机自启动:1是,0否") + private Short autostart; - /** - * 每页数量 - */ - @ApiModelProperty(value = "每页数量", notes = "分页查询时再传", dataType = "Integer") - @JsonProperty("page_size") - private Integer pageSize; - -} +} \ No newline at end of file diff --git a/nex-be/src/main/java/com/unisinsight/project/entity/req/StoragePoolReq.java b/nex-be/src/main/java/com/unisinsight/project/entity/req/StoragePoolReq.java index 9ce0af3..9296914 100644 --- a/nex-be/src/main/java/com/unisinsight/project/entity/req/StoragePoolReq.java +++ b/nex-be/src/main/java/com/unisinsight/project/entity/req/StoragePoolReq.java @@ -18,28 +18,34 @@ import javax.validation.constraints.*; public class StoragePoolReq { @ApiModelProperty(value = "id") + @JsonProperty("id") private Integer id; @ApiModelProperty("自动启动,默认是") + @JsonProperty("autostart") private boolean autostart = true; @ApiModelProperty("名称") @NotBlank(message = "名称不能为空") @Size(max = 64, message = "名称长度不能超过64个字符") + @JsonProperty("pool_name") private String poolName; @ApiModelProperty("类型") @Size(max = 16, message = "类型长度不能超过16个字符") + @JsonProperty("type") private String type; @ApiModelProperty("路径") @Size(max = 128, message = "路径长度不能超过128个字符") + @JsonProperty("path") private String path; /** * 状态: 1-活跃,2-关闭 **/ @ApiModelProperty("状态") + @JsonProperty("status") private Integer status; /** diff --git a/nex-be/src/main/java/com/unisinsight/project/entity/res/StoragePoolRes.java b/nex-be/src/main/java/com/unisinsight/project/entity/res/StoragePoolRes.java index 25d05b8..10225cc 100644 --- a/nex-be/src/main/java/com/unisinsight/project/entity/res/StoragePoolRes.java +++ b/nex-be/src/main/java/com/unisinsight/project/entity/res/StoragePoolRes.java @@ -15,15 +15,15 @@ import java.io.Serializable; * @since 2025-08-25 11:42:57 */ @Data -@ApiModel("镜像虚拟机") +@ApiModel("存储池") public class StoragePoolRes implements Serializable { @JsonProperty("id") @ApiModelProperty("ID") private Long id; - @JsonProperty("name") + @JsonProperty("pool_name") @ApiModelProperty("名称") - private String name; + private String poolName; @JsonProperty("type") @ApiModelProperty("类型") @@ -34,9 +34,9 @@ public class StoragePoolRes implements Serializable { private String path; /** - * 镜像状态: 1-活跃,2-关闭 + * 镜像状态: 1-活跃,0-非活跃 **/ - @JsonProperty("image_status") + @JsonProperty("status") @ApiModelProperty("状态") private String status; 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 60bf629..eae61dc 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 @@ -2,6 +2,7 @@ package com.unisinsight.project.feign; import com.unisinsight.project.config.FeignConfig; import com.unisinsight.project.entity.dto.ApiResponse; +import com.unisinsight.project.entity.dto.Network; import com.unisinsight.project.entity.dto.NetworkData; import com.unisinsight.project.entity.dto.StoragePoolData; import com.unisinsight.project.entity.req.NetworkManageReq; @@ -20,7 +21,7 @@ import org.springframework.web.bind.annotation.*; public interface ExternalApiClient { @PostMapping("/api/v1/network/create") - ApiResponse createNetwork(@RequestBody NetworkManageReq networkManageReq); + ApiResponse createNetwork(@RequestBody Network network); @DeleteMapping("/api/v1/network/{network_name}") ApiResponse deleteNetwork(@PathVariable("network_name") String networkName); diff --git a/nex-be/src/main/java/com/unisinsight/project/service/impl/NetworkManageServiceImpl.java b/nex-be/src/main/java/com/unisinsight/project/service/impl/NetworkManageServiceImpl.java index 4641f17..8abed65 100644 --- a/nex-be/src/main/java/com/unisinsight/project/service/impl/NetworkManageServiceImpl.java +++ b/nex-be/src/main/java/com/unisinsight/project/service/impl/NetworkManageServiceImpl.java @@ -14,19 +14,27 @@ import com.unisinsight.project.exception.BusinessException; import com.unisinsight.project.feign.ExternalApiClient; import com.unisinsight.project.mapper.NetworkManageMapper; import com.unisinsight.project.service.NetworkManageService; +import com.unisinsight.project.util.StringUtil; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; /** * 网络管理服务实现类 */ @Service +@Slf4j public class NetworkManageServiceImpl extends ServiceImpl implements NetworkManageService { @Resource @@ -48,14 +56,8 @@ public class NetworkManageServiceImpl extends ServiceImpl queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("name", networkManageReq.getNetworkName()); + queryWrapper.eq("network_name", networkManageReq.getNetworkName()); if (this.count(queryWrapper) > 0) { throw new BusinessException("网络名称'" + networkManageReq.getNetworkName() + "'已存在,请使用其他名称"); } @@ -163,18 +180,18 @@ public class NetworkManageServiceImpl extends ServiceImpl 网络管理列表 */ @Override - public List listNetworkManages(String name, String type, Short status) { + public List listNetworkManages(String networkName, String type, Short status) { QueryWrapper queryWrapper = new QueryWrapper<>(); // 添加查询条件 - if (name != null && !name.isEmpty()) { - queryWrapper.like("name", name); + if (networkName != null && !networkName.isEmpty()) { + queryWrapper.like("network_name", networkName); } if (type != null && !type.isEmpty()) { queryWrapper.eq("type", type); @@ -216,14 +233,19 @@ public class NetworkManageServiceImpl extends ServiceImpl response; try { - response = client.list(1, 100); + response = client.list(1, 100); if (!"200".equals(response.getCode())) { throw new BusinessException("调用外部接口失败: " + response.getMessage()); } @@ -231,24 +253,88 @@ public class NetworkManageServiceImpl extends ServiceImpl networkList = response.getData().getNetworks(); - if (CollectionUtils.isEmpty(networkList)) { - return; + List networkList = response.getData().getNetworks(); + if (CollectionUtils.isEmpty(networkList)) { + return; + } + + log.info("开始同步网络数据,共{}条记录", networkList.size()); + + // 先查询现有数据 + List existingList = this.list(); + // 创建现有数据的名称映射,用于快速查找 + Map existingMap = existingList.stream() + .collect(Collectors.toMap(NetworkManage::getNetworkName, Function.identity(), (a, b) -> a)); + + List toUpdate = new ArrayList<>(); + List toInsert = new ArrayList<>(); + + for (Network network : networkList) { + NetworkManage networkManage = new NetworkManage(); + BeanUtils.copyProperties(network, networkManage); + networkManage.setNetworkName(StringUtil.isEmpty(network.getNetworkName())?network.getName(): networkManage.getNetworkName() ); + networkManage.setStatus("active".equals(network.getState()) ? 1 : 0); + networkManage.setAutostart(network.getAutostart()? 1 : 0); + networkManage.setDhcpEnabled(network.getDhcpEnabled()? 1 : 0); + networkManage.setUpdateTime(new Date()); + + // 判断是更新还是插入 + if (existingMap.containsKey(networkManage.getNetworkName())) { + networkManage.setId(existingMap.get(networkManage.getNetworkName()).getId()); + networkManage.setCreateTime(existingMap.get(networkManage.getNetworkName()).getCreateTime()); + toUpdate.add(networkManage); + } else { + networkManage.setCreateTime(new Date()); + toInsert.add(networkManage); } - List networkManageList = new ArrayList<>(); - for (Network network : networkList) { - NetworkManage networkManage = new NetworkManage(); - BeanUtils.copyProperties(network, networkManage); - networkManage.setNetworkName(network.getName()); - networkManage.setStatus("active".equals(network.getState()) ? 1 : 2); - networkManageList.add(networkManage); - } - // 清空数据并重新插入 - this.remove(new QueryWrapper<>()); - this.saveOrUpdateBatch(networkManageList); + } + log.info("需要更新{}条记录,需要插入{}条记录", toUpdate.size(), toInsert.size()); + // 执行批量操作,分批处理避免大数据量问题 + if (!toUpdate.isEmpty()) { + updateBatch(toUpdate); + } + if (!toInsert.isEmpty()) { + insertBatch(toInsert); + } + // 删除不存在的记录 + List currentNames = networkList.stream() + .map(Network::getName) + .collect(Collectors.toList()); + + List idsToDelete = existingList.stream() + .filter(item -> !currentNames.contains(item.getNetworkName())) + .map(NetworkManage::getId) + .collect(Collectors.toList()); + + if (!idsToDelete.isEmpty()) { + log.info("需要删除{}条记录", idsToDelete.size()); + this.removeByIds(idsToDelete); + } + } + + private void updateBatch(List list) { + // 分批更新,每批100条 + int batchSize = 100; + for (int i = 0; i < list.size(); i += batchSize) { + int endIndex = Math.min(i + batchSize, list.size()); + List batch = list.subList(i, endIndex); + this.updateBatchById(batch); + log.info("已更新{}条记录", endIndex); + } + } + + private void insertBatch(List list) { + // 分批插入,每批100条 + int batchSize = 100; + for (int i = 0; i < list.size(); i += batchSize) { + int endIndex = Math.min(i + batchSize, list.size()); + List batch = list.subList(i, endIndex); + this.saveBatch(batch); + log.info("已插入{}条记录", endIndex); + } } }