Commit ddb18310 by renyizhao

动态规格

parent 4cfe1e14
...@@ -22,6 +22,9 @@ public class ResourceSpuPageReqVO extends PageParam { ...@@ -22,6 +22,9 @@ public class ResourceSpuPageReqVO extends PageParam {
@Schema(description = "算力资源分类编号", example = "21747") @Schema(description = "算力资源分类编号", example = "21747")
private Long categoryId; private Long categoryId;
@Schema(description = "算力来源", example = "own")
private String source;
@Schema(description = "商品封面图", example = "https://www.iocoder.cn") @Schema(description = "商品封面图", example = "https://www.iocoder.cn")
private String picUrl; private String picUrl;
......
...@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; ...@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Map;
@Schema(description = "用户 APP - 算力资源订单 Response VO") @Schema(description = "用户 APP - 算力资源订单 Response VO")
@Data @Data
...@@ -57,23 +58,8 @@ public class AppResourceOrderRespVO { ...@@ -57,23 +58,8 @@ public class AppResourceOrderRespVO {
@Schema(description = "发票文件URL", example = "https://example.com/invoice.pdf") @Schema(description = "发票文件URL", example = "https://example.com/invoice.pdf")
private String invoiceUrl; private String invoiceUrl;
@Schema(description = "CPU配置", example = "Intel Xeon E5-2680 v4") @Schema(description = "商品规格 Map(key=configCategory, value=configOption)")
private String cpu; private Map<String, String> specMap;
@Schema(description = "GPU配置", example = "NVIDIA RTX 4090")
private String gpu;
@Schema(description = "内存配置", example = "64GB DDR4")
private String ram;
@Schema(description = "存储配置", example = "2TB NVMe SSD")
private String storage;
@Schema(description = "电源配置", example = "3500W")
private String powerSupply;
@Schema(description = "网卡配置", example = "2Gbps")
private String nic;
@Schema(description = "服务器IP", example = "192.168.1.100") @Schema(description = "服务器IP", example = "192.168.1.100")
private String ip; private String ip;
...@@ -96,4 +82,4 @@ public class AppResourceOrderRespVO { ...@@ -96,4 +82,4 @@ public class AppResourceOrderRespVO {
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime updateTime; private LocalDateTime updateTime;
} }
\ No newline at end of file
...@@ -25,24 +25,6 @@ public class AppResourceOrderSnapshotPageReqVO extends PageParam { ...@@ -25,24 +25,6 @@ public class AppResourceOrderSnapshotPageReqVO extends PageParam {
@Schema(description = "SPU名称", example = "GPU服务器A型") @Schema(description = "SPU名称", example = "GPU服务器A型")
private String spuName; private String spuName;
@Schema(description = "CPU配置", example = "Intel Xeon E5-2680 v4")
private String cpu;
@Schema(description = "GPU配置", example = "NVIDIA RTX 4090")
private String gpu;
@Schema(description = "内存配置", example = "64GB DDR4")
private String ram;
@Schema(description = "存储配置", example = "2TB NVMe SSD")
private String storage;
@Schema(description = "电源配置", example = "3500W")
private String powerSupply;
@Schema(description = "网卡配置", example = "2Gbps")
private String nic;
@Schema(description = "服务器IP", example = "192.168.1.100") @Schema(description = "服务器IP", example = "192.168.1.100")
private String ip; private String ip;
......
...@@ -27,23 +27,8 @@ public class AppResourceOrderSnapshotRespVO { ...@@ -27,23 +27,8 @@ public class AppResourceOrderSnapshotRespVO {
@Schema(description = "支付订单ID", example = "1024") @Schema(description = "支付订单ID", example = "1024")
private Long payOrderId; private Long payOrderId;
@Schema(description = "CPU配置", example = "Intel Xeon E5-2680 v4") @Schema(description = "下单时商品规格快照(Map<configCategory, configOption>,JSON 字符串)")
private String cpu; private String specSnapshot;
@Schema(description = "GPU配置", example = "NVIDIA RTX 4090")
private String gpu;
@Schema(description = "内存配置", example = "64GB DDR4")
private String ram;
@Schema(description = "存储配置", example = "2TB NVMe SSD")
private String storage;
@Schema(description = "电源配置", example = "3500W")
private String powerSupply;
@Schema(description = "网卡配置", example = "2Gbps")
private String nic;
@Schema(description = "服务器IP", example = "192.168.1.100") @Schema(description = "服务器IP", example = "192.168.1.100")
private String ip; private String ip;
......
...@@ -25,51 +25,14 @@ public class AppResourceOrderSnapshotSaveReqVO { ...@@ -25,51 +25,14 @@ public class AppResourceOrderSnapshotSaveReqVO {
@Schema(description = "支付订单ID", example = "1024") @Schema(description = "支付订单ID", example = "1024")
private Long payOrderId; private Long payOrderId;
@Schema(description = "CPU配置", requiredMode = Schema.RequiredMode.REQUIRED, example = "Intel Xeon E5-2680 v4") @Schema(description = "下单时商品规格快照(Map<configCategory, configOption>,JSON 字符串)")
@NotBlank(message = "CPU配置不能为空") private String specSnapshot;
private String cpu;
@Schema(description = "GPU配置", example = "NVIDIA RTX 4090")
private String gpu;
@Schema(description = "内存配置", requiredMode = Schema.RequiredMode.REQUIRED, example = "64GB DDR4")
@NotBlank(message = "内存配置不能为空")
private String ram;
@Schema(description = "算力", requiredMode = Schema.RequiredMode.REQUIRED, example = "222.22")
@NotBlank(message = "算力不能为空")
private Double compute;
@Schema(description = "GPU卡数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8")
@NotBlank(message = "GPU卡数量不能为空")
private Long gpuCount;
@Schema(description = "CPU核数", requiredMode = Schema.RequiredMode.REQUIRED, example = "8")
@NotBlank(message = "CPU核数")
private Long coreCount;
@Schema(description = "内存大小", requiredMode = Schema.RequiredMode.REQUIRED, example = "64")
@NotBlank(message = "内存大小不能为空")
private Long memoryCapacity;
@Schema(description = "服务器位置", requiredMode = Schema.RequiredMode.REQUIRED, example = "长沙") @Schema(description = "服务器位置", requiredMode = Schema.RequiredMode.REQUIRED, example = "长沙")
@NotBlank(message = "服务器位置不能为空") @NotBlank(message = "服务器位置不能为空")
private String location; private String location;
@Schema(description = "存储配置", requiredMode = Schema.RequiredMode.REQUIRED, example = "2TB NVMe SSD") @Schema(description = "服务器IP", example = "192.168.1.100")
@NotBlank(message = "存储配置不能为空")
private String storage;
@Schema(description = "电源配置", requiredMode = Schema.RequiredMode.REQUIRED, example = "3500W")
@NotBlank(message = "电源配置不能为空")
private String powerSupply;
@Schema(description = "网卡配置", requiredMode = Schema.RequiredMode.REQUIRED, example = "2Gbps")
@NotBlank(message = "网卡配置不能为空")
private String nic;
@Schema(description = "服务器IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "192.168.1.100")
@NotBlank(message = "服务器IP不能为空")
private String ip; private String ip;
@Schema(description = "服务器初始用户名", example = "root") @Schema(description = "服务器初始用户名", example = "root")
......
...@@ -44,49 +44,9 @@ public class ResourceOrderSnapshotDO extends BaseDO { ...@@ -44,49 +44,9 @@ public class ResourceOrderSnapshotDO extends BaseDO {
private Long payOrderId; private Long payOrderId;
/** /**
* CPU配置快照 * 下单时商品规格快照(Map<configCategory, configOption>,JSON 字符串)
*/ */
private String cpu; private String specSnapshot;
/**
* GPU配置快照
*/
private String gpu;
/**
* 算力
*/
private Double compute;
/**
* GPU数量
*/
private Integer gpuCount;
/**
* CPU核心数
*/
private Integer coreCount;
/**
* 内存容量
*/
private Integer memoryCapacity;
/**
* 内存配置快照
*/
private String ram;
/**
* 存储配置快照
*/
private String storage;
/**
* 电源配置快照
*/
private String powerSupply;
/**
* 网卡配置快照
*/
private String nic;
/** /**
* 服务器IP地址快照 * 服务器IP地址快照
......
package com.luhu.computility.module.compute.dal.mysql.resourceordersnapshot; package com.luhu.computility.module.compute.dal.mysql.resourceordersnapshot;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*; import java.util.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.luhu.computility.framework.common.pojo.PageResult; import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.mybatis.core.query.LambdaQueryWrapperX; import com.luhu.computility.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.luhu.computility.framework.mybatis.core.query.MPJLambdaWrapperX; import com.luhu.computility.framework.mybatis.core.query.MPJLambdaWrapperX;
...@@ -36,12 +32,6 @@ public interface ResourceOrderSnapshotMapper extends BaseMapperX<ResourceOrderSn ...@@ -36,12 +32,6 @@ public interface ResourceOrderSnapshotMapper extends BaseMapperX<ResourceOrderSn
.eqIfPresent(ResourceOrderSnapshotDO::getOrderId, reqVO.getOrderId()) .eqIfPresent(ResourceOrderSnapshotDO::getOrderId, reqVO.getOrderId())
.eqIfPresent(ResourceOrderSnapshotDO::getPayOrderId, reqVO.getPayOrderId()) .eqIfPresent(ResourceOrderSnapshotDO::getPayOrderId, reqVO.getPayOrderId())
.likeIfPresent(ResourceOrderSnapshotDO::getSpuName, reqVO.getSpuName()) .likeIfPresent(ResourceOrderSnapshotDO::getSpuName, reqVO.getSpuName())
.eqIfPresent(ResourceOrderSnapshotDO::getCpu, reqVO.getCpu())
.eqIfPresent(ResourceOrderSnapshotDO::getGpu, reqVO.getGpu())
.eqIfPresent(ResourceOrderSnapshotDO::getRam, reqVO.getRam())
.eqIfPresent(ResourceOrderSnapshotDO::getStorage, reqVO.getStorage())
.eqIfPresent(ResourceOrderSnapshotDO::getPowerSupply, reqVO.getPowerSupply())
.eqIfPresent(ResourceOrderSnapshotDO::getNic, reqVO.getNic())
.eqIfPresent(ResourceOrderSnapshotDO::getIp, reqVO.getIp()) .eqIfPresent(ResourceOrderSnapshotDO::getIp, reqVO.getIp())
.eqIfPresent(ResourceOrderSnapshotDO::getDurationDays, reqVO.getDurationDays()) .eqIfPresent(ResourceOrderSnapshotDO::getDurationDays, reqVO.getDurationDays())
.eqIfPresent(ResourceOrderSnapshotDO::getPaymentPrice, reqVO.getPaymentPrice()) .eqIfPresent(ResourceOrderSnapshotDO::getPaymentPrice, reqVO.getPaymentPrice())
...@@ -73,39 +63,12 @@ public interface ResourceOrderSnapshotMapper extends BaseMapperX<ResourceOrderSn ...@@ -73,39 +63,12 @@ public interface ResourceOrderSnapshotMapper extends BaseMapperX<ResourceOrderSn
} }
default ResourceOrderSnapshotStatisticDTO queryResourceOrderSnapshotStatistic() { default ResourceOrderSnapshotStatisticDTO queryResourceOrderSnapshotStatistic() {
// 阶段 6 改造:compute / gpu_count / core_count / memory_capacity 列已从 compute_resource_order_snapshot 删除,
// 真实统计需改走规格中间表(compute_resource_spu_spec_value),不在本阶段范围。
// 当前先返回零值占位,保证 HomeIndexOverallSituation 看板不报错。
// TODO 后续阶段:从规格中间表按 config_category='算力'/'GPU' 等汇总真实数据
ResourceOrderSnapshotStatisticDTO resp = new ResourceOrderSnapshotStatisticDTO(); ResourceOrderSnapshotStatisticDTO resp = new ResourceOrderSnapshotStatisticDTO();
// SQL sum 查询 - 统计当前在租赁期内的订单(租赁开始时间 <= 当前时间 AND 租赁结束时间 >= 当前时间)
List<Map<String, Object>> result = selectMaps(new QueryWrapper<ResourceOrderSnapshotDO>()
.select("IFNULL(SUM(compute), 0) as totalCompute, IFNULL(SUM(gpu_count), 0) as totalGpuCount, " +
"IFNULL(SUM(core_count), 0) as totalCoreCount, IFNULL(SUM(memory_capacity), 0) as totalMemoryCapacity")
.apply("rent_start_time <= NOW() AND rent_end_time >= NOW()"));
if (!result.isEmpty()) {
// compute -> BigDecimal,保留两位小数
Map<String, Object> row = result.get(0);
//算力(保留 2 位)
BigDecimal compute = getBigDecimal(row, "totalCompute")
.setScale(2, RoundingMode.HALF_UP);
//强烈建议:VO 用 BigDecimal
resp.setTotalCompute(compute.doubleValue());
//GPU 数量
resp.setTotalGpuCount( getBigDecimal(row, "totalGpuCount").longValue() );
//CPU 核心数
resp.setTotalCoreCount( getBigDecimal(row, "totalCoreCount").longValue() );
//内存容量
resp.setTotalMemoryCapacity( getBigDecimal(row, "totalMemoryCapacity").longValue());
}
return resp; return resp;
} }
static BigDecimal getBigDecimal(Map<String, Object> map, String key) {
Object val = map.get(key);
return val == null ? BigDecimal.ZERO : (BigDecimal) val;
}
} }
...@@ -32,6 +32,7 @@ public interface ResourceSpuMapper extends BaseMapperX<ResourceSpuDO> { ...@@ -32,6 +32,7 @@ public interface ResourceSpuMapper extends BaseMapperX<ResourceSpuDO> {
.likeIfPresent(ResourceSpuDO::getName, reqVO.getName()) .likeIfPresent(ResourceSpuDO::getName, reqVO.getName())
.likeIfPresent(ResourceSpuDO::getIntro, reqVO.getIntro()) .likeIfPresent(ResourceSpuDO::getIntro, reqVO.getIntro())
.eqIfPresent(ResourceSpuDO::getCategoryId, reqVO.getCategoryId()) .eqIfPresent(ResourceSpuDO::getCategoryId, reqVO.getCategoryId())
.eqIfPresent(ResourceSpuDO::getSource, reqVO.getSource())
.eqIfPresent(ResourceSpuDO::getPicUrl, reqVO.getPicUrl()) .eqIfPresent(ResourceSpuDO::getPicUrl, reqVO.getPicUrl())
.eqIfPresent(ResourceSpuDO::getSliderPicUrls, reqVO.getSliderPicUrls()) .eqIfPresent(ResourceSpuDO::getSliderPicUrls, reqVO.getSliderPicUrls())
.eqIfPresent(ResourceSpuDO::getSales, reqVO.getSales()) .eqIfPresent(ResourceSpuDO::getSales, reqVO.getSales())
......
...@@ -2,6 +2,7 @@ package com.luhu.computility.module.compute.service.resourceorder; ...@@ -2,6 +2,7 @@ package com.luhu.computility.module.compute.service.resourceorder;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.luhu.computility.framework.common.exception.ServiceException; import com.luhu.computility.framework.common.exception.ServiceException;
import com.luhu.computility.framework.common.pojo.PageResult; import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.util.json.JsonUtils; import com.luhu.computility.framework.common.util.json.JsonUtils;
...@@ -14,10 +15,12 @@ import com.luhu.computility.module.compute.controller.admin.resourceorder.vo.Res ...@@ -14,10 +15,12 @@ import com.luhu.computility.module.compute.controller.admin.resourceorder.vo.Res
import com.luhu.computility.module.compute.controller.admin.resourcespu.vo.ResourceSpuRespVO; import com.luhu.computility.module.compute.controller.admin.resourcespu.vo.ResourceSpuRespVO;
import com.luhu.computility.module.compute.controller.app.resourceorder.vo.*; import com.luhu.computility.module.compute.controller.app.resourceorder.vo.*;
import com.luhu.computility.module.compute.controller.app.resourceordersnapshot.vo.AppResourceOrderSnapshotSaveReqVO; import com.luhu.computility.module.compute.controller.app.resourceordersnapshot.vo.AppResourceOrderSnapshotSaveReqVO;
import com.luhu.computility.module.compute.dal.dataobject.resourceconfig.ResourceConfigDO;
import com.luhu.computility.module.compute.dal.dataobject.resourceorder.ResourceOrderDO; import com.luhu.computility.module.compute.dal.dataobject.resourceorder.ResourceOrderDO;
import com.luhu.computility.module.compute.dal.dataobject.resourcesku.ResourceSkuDO; import com.luhu.computility.module.compute.dal.dataobject.resourcesku.ResourceSkuDO;
import com.luhu.computility.module.compute.dal.dataobject.resourcespu.ResourceSpuDO; import com.luhu.computility.module.compute.dal.dataobject.resourcespu.ResourceSpuDO;
import com.luhu.computility.module.compute.dal.dataobject.resourceordersnapshot.ResourceOrderSnapshotDO; import com.luhu.computility.module.compute.dal.dataobject.resourceordersnapshot.ResourceOrderSnapshotDO;
import com.luhu.computility.module.compute.dal.dataobject.resourcespuspecvalue.ResourceSpuSpecValueDO;
import com.luhu.computility.module.compute.dal.mysql.resourceorder.ResourceOrderMapper; import com.luhu.computility.module.compute.dal.mysql.resourceorder.ResourceOrderMapper;
import com.luhu.computility.module.compute.dal.redis.no.ResourceOrderNoRedisDAO; import com.luhu.computility.module.compute.dal.redis.no.ResourceOrderNoRedisDAO;
import com.luhu.computility.module.compute.enums.ResourceOrderInvoiceStatus; import com.luhu.computility.module.compute.enums.ResourceOrderInvoiceStatus;
...@@ -25,8 +28,10 @@ import com.luhu.computility.module.compute.enums.ResourceOrderStatus; ...@@ -25,8 +28,10 @@ import com.luhu.computility.module.compute.enums.ResourceOrderStatus;
import com.luhu.computility.module.compute.enums.ResourceSkuStatus; import com.luhu.computility.module.compute.enums.ResourceSkuStatus;
import com.luhu.computility.module.compute.enums.ResourceSpuStatus; import com.luhu.computility.module.compute.enums.ResourceSpuStatus;
import com.luhu.computility.module.compute.service.resourcecategory.ResourceCategoryService; import com.luhu.computility.module.compute.service.resourcecategory.ResourceCategoryService;
import com.luhu.computility.module.compute.service.resourceconfig.ResourceConfigService;
import com.luhu.computility.module.compute.service.resourcesku.ResourceSkuService; import com.luhu.computility.module.compute.service.resourcesku.ResourceSkuService;
import com.luhu.computility.module.compute.service.resourcespu.ResourceSpuService; import com.luhu.computility.module.compute.service.resourcespu.ResourceSpuService;
import com.luhu.computility.module.compute.service.resourcespuspecvalue.ResourceSpuSpecValueService;
import com.luhu.computility.module.compute.service.resourceordersnapshot.ResourceOrderSnapshotService; import com.luhu.computility.module.compute.service.resourceordersnapshot.ResourceOrderSnapshotService;
import com.luhu.computility.module.pay.api.order.PayOrderApi; import com.luhu.computility.module.pay.api.order.PayOrderApi;
import com.luhu.computility.module.pay.api.order.dto.PayOrderCreateReqDTO; import com.luhu.computility.module.pay.api.order.dto.PayOrderCreateReqDTO;
...@@ -55,7 +60,9 @@ import java.math.BigDecimal; ...@@ -55,7 +60,9 @@ import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import static com.luhu.computility.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.luhu.computility.framework.common.exception.util.ServiceExceptionUtil.exception;
...@@ -116,6 +123,12 @@ public class ResourceOrderServiceImpl implements ResourceOrderService { ...@@ -116,6 +123,12 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
@Resource @Resource
private ResourceOrderSnapshotService resourceOrderSnapshotService; private ResourceOrderSnapshotService resourceOrderSnapshotService;
@Resource
private ResourceSpuSpecValueService resourceSpuSpecValueService;
@Resource
private ResourceConfigService resourceConfigService;
@Override @Override
public Long createResourceOrder(ResourceOrderSaveReqVO createReqVO) { public Long createResourceOrder(ResourceOrderSaveReqVO createReqVO) {
// 插入 // 插入
...@@ -369,14 +382,12 @@ public class ResourceOrderServiceImpl implements ResourceOrderService { ...@@ -369,14 +382,12 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
if (snapshot != null) { if (snapshot != null) {
// 从快照中读取硬件配置(优先级更高) // 从快照中读取硬件配置(优先级更高)
respVO.setSpuName(snapshot.getSpuName()); respVO.setSpuName(snapshot.getSpuName());
respVO.setCpu(snapshot.getCpu());
respVO.setGpu(snapshot.getGpu());
respVO.setRam(snapshot.getRam());
respVO.setStorage(snapshot.getStorage());
respVO.setPowerSupply(snapshot.getPowerSupply());
respVO.setPaymentPrice(snapshot.getPaymentPrice()); respVO.setPaymentPrice(snapshot.getPaymentPrice());
respVO.setNic(snapshot.getNic());
respVO.setIp(snapshot.getIp()); respVO.setIp(snapshot.getIp());
// 读快照 JSON 解析为 specMap
if (snapshot.getSpecSnapshot() != null) {
respVO.setSpecMap(JSONUtil.toBean(snapshot.getSpecSnapshot(), Map.class));
}
respVO.setSkuName(snapshot.getSpuName() + " - " + snapshot.getDurationDays() + "天"); respVO.setSkuName(snapshot.getSpuName() + " - " + snapshot.getDurationDays() + "天");
// 快照中没有的字段(分类、位置)需要从SPU获取 // 快照中没有的字段(分类、位置)需要从SPU获取
...@@ -403,9 +414,7 @@ public class ResourceOrderServiceImpl implements ResourceOrderService { ...@@ -403,9 +414,7 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
respVO.setSpuId(spu.getId()); respVO.setSpuId(spu.getId());
respVO.setSpuName(spu.getName()); respVO.setSpuName(spu.getName());
respVO.setCategoryId(spu.getCategoryId()); respVO.setCategoryId(spu.getCategoryId());
// 规格字段已迁移至 specMap,AppResourceOrderRespVO 上的 cpu/gpu/ram 等暂保留以便兼容老字段。
respVO.setLocation(spu.getLocation()); respVO.setLocation(spu.getLocation());
respVO.setSkuName(spu.getName() + " - " + sku.getDurationDays() + "天"); respVO.setSkuName(spu.getName() + " - " + sku.getDurationDays() + "天");
// 设置分类名称 // 设置分类名称
...@@ -443,15 +452,13 @@ public class ResourceOrderServiceImpl implements ResourceOrderService { ...@@ -443,15 +452,13 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
if (snapshot != null) { if (snapshot != null) {
// 从快照中读取硬件配置(优先级更高) // 从快照中读取硬件配置(优先级更高)
respVO.setSpuName(snapshot.getSpuName()); respVO.setSpuName(snapshot.getSpuName());
respVO.setCpu(snapshot.getCpu());
respVO.setGpu(snapshot.getGpu());
respVO.setRam(snapshot.getRam());
respVO.setStorage(snapshot.getStorage());
respVO.setPowerSupply(snapshot.getPowerSupply());
respVO.setNic(snapshot.getNic());
respVO.setIp(snapshot.getIp()); respVO.setIp(snapshot.getIp());
respVO.setInitUsername(snapshot.getInitUsername()); respVO.setInitUsername(snapshot.getInitUsername());
respVO.setInitPassword(snapshot.getInitPassword()); respVO.setInitPassword(snapshot.getInitPassword());
// 读快照 JSON 解析为 specMap
if (snapshot.getSpecSnapshot() != null) {
respVO.setSpecMap(JSONUtil.toBean(snapshot.getSpecSnapshot(), Map.class));
}
respVO.setSkuName(snapshot.getSpuName() + " - " + snapshot.getDurationDays() + "天"); respVO.setSkuName(snapshot.getSpuName() + " - " + snapshot.getDurationDays() + "天");
// 快照中没有的字段(分类、位置)需要从SPU获取 // 快照中没有的字段(分类、位置)需要从SPU获取
...@@ -478,7 +485,6 @@ public class ResourceOrderServiceImpl implements ResourceOrderService { ...@@ -478,7 +485,6 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
respVO.setSpuId(spu.getId()); respVO.setSpuId(spu.getId());
respVO.setSpuName(spu.getName()); respVO.setSpuName(spu.getName());
respVO.setCategoryId(spu.getCategoryId()); respVO.setCategoryId(spu.getCategoryId());
// 规格字段已迁移至 specMap,AppResourceOrderRespVO 上的 cpu/gpu/ram 等暂保留以便兼容老字段。
respVO.setLocation(spu.getLocation()); respVO.setLocation(spu.getLocation());
respVO.setSkuName(spu.getName() + " - " + sku.getDurationDays() + "天"); respVO.setSkuName(spu.getName() + " - " + sku.getDurationDays() + "天");
...@@ -831,9 +837,23 @@ public class ResourceOrderServiceImpl implements ResourceOrderService { ...@@ -831,9 +837,23 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
order.getId(), spu.getName(), sku.getDurationDays()); order.getId(), spu.getName(), sku.getDurationDays());
// 构建快照创建请求 // 构建快照创建请求
// 阶段 1 改造后 SPU 不再保存 cpu/gpu/ram/storage 等硬编码规格列, // 1. 查 SPU 关联的所有规格
// 这些列已从 ResourceSpuDO 删除,对应的 snapshot 字段暂置 null List<ResourceSpuSpecValueDO> specValues = resourceSpuSpecValueService.getSpuSpecValueListBySpuId(spu.getId());
// (后续阶段 6 改造时统一从规格中间表生成 spec_snapshot JSON)。 List<Long> configIds = convertList(specValues, ResourceSpuSpecValueDO::getConfigId);
Map<Long, ResourceConfigDO> configMap = resourceConfigService.getConfigMapByIds(configIds);
// 2. 转 Map<configCategory, configOption>;同类别多值用「,」拼接,避免后写覆盖先写
Map<String, String> specSnapshot = new LinkedHashMap<>();
for (ResourceSpuSpecValueDO sv : specValues) {
ResourceConfigDO cfg = configMap.get(sv.getConfigId());
if (cfg != null) {
String category = cfg.getConfigCategory();
String option = cfg.getConfigOption();
String existing = specSnapshot.get(category);
specSnapshot.put(category, existing == null ? option : existing + "," + option);
}
}
AppResourceOrderSnapshotSaveReqVO createReqVO = new AppResourceOrderSnapshotSaveReqVO(); AppResourceOrderSnapshotSaveReqVO createReqVO = new AppResourceOrderSnapshotSaveReqVO();
createReqVO.setOrderId(order.getId()); createReqVO.setOrderId(order.getId());
createReqVO.setUserId(order.getUserId()); createReqVO.setUserId(order.getUserId());
...@@ -846,6 +866,9 @@ public class ResourceOrderServiceImpl implements ResourceOrderService { ...@@ -846,6 +866,9 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
createReqVO.setPaymentPrice(order.getPaymentPrice()); createReqVO.setPaymentPrice(order.getPaymentPrice());
createReqVO.setMarketPrice(order.getMarketPrice()); createReqVO.setMarketPrice(order.getMarketPrice());
// 3. 写快照
createReqVO.setSpecSnapshot(JsonUtils.toJsonString(specSnapshot));
// 调用快照服务创建快照 // 调用快照服务创建快照
Long snapshotId = resourceOrderSnapshotService.createOrderSnapshot(createReqVO); Long snapshotId = resourceOrderSnapshotService.createOrderSnapshot(createReqVO);
......
...@@ -151,13 +151,16 @@ public class ResourceSpuServiceImpl implements ResourceSpuService { ...@@ -151,13 +151,16 @@ public class ResourceSpuServiceImpl implements ResourceSpuService {
List<Long> configIds = convertList(specs, ResourceSpuSpecValueDO::getConfigId); List<Long> configIds = convertList(specs, ResourceSpuSpecValueDO::getConfigId);
Map<Long, ResourceConfigDO> configMap = resourceConfigService.getConfigMapByIds(configIds); Map<Long, ResourceConfigDO> configMap = resourceConfigService.getConfigMapByIds(configIds);
// 转 Map<category, option> // 转 Map<category, option>;同类别多值用「,」拼接,避免后写覆盖先写
Map<String, String> specMap = new LinkedHashMap<>(); Map<String, String> specMap = new LinkedHashMap<>();
List<Long> specConfigIds = new ArrayList<>(); List<Long> specConfigIds = new ArrayList<>();
for (ResourceSpuSpecValueDO sv : specs) { for (ResourceSpuSpecValueDO sv : specs) {
ResourceConfigDO cfg = configMap.get(sv.getConfigId()); ResourceConfigDO cfg = configMap.get(sv.getConfigId());
if (cfg != null) { if (cfg != null) {
specMap.put(cfg.getConfigCategory(), cfg.getConfigOption()); String category = cfg.getConfigCategory();
String option = cfg.getConfigOption();
String existing = specMap.get(category);
specMap.put(category, existing == null ? option : existing + "," + option);
specConfigIds.add(sv.getConfigId()); specConfigIds.add(sv.getConfigId());
} }
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
FROM compute_resource_spu_spec_value FROM compute_resource_spu_spec_value
WHERE spu_id = #{spuId} WHERE spu_id = #{spuId}
AND deleted = b'0' AND deleted = b'0'
ORDER BY sort ASC, id ASC
</select> </select>
<select id="selectListBySpuIds" resultType="com.luhu.computility.module.compute.dal.dataobject.resourcespuspecvalue.ResourceSpuSpecValueDO"> <select id="selectListBySpuIds" resultType="com.luhu.computility.module.compute.dal.dataobject.resourcespuspecvalue.ResourceSpuSpecValueDO">
...@@ -32,6 +33,7 @@ ...@@ -32,6 +33,7 @@
#{spuId} #{spuId}
</foreach> </foreach>
AND deleted = b'0' AND deleted = b'0'
ORDER BY spu_id ASC, sort ASC, id ASC
</select> </select>
</mapper> </mapper>
-- ============================================================
-- 算力资源商品改造 · 阶段 5 补丁
-- 目标:删除中间表 compute_resource_spu_spec_value 的多余唯一键
-- 适用库:new_computility
-- 背景:阶段 1 建的唯一键 uk_spu_config_deleted (spu_id, config_id, deleted)
-- 在「软删除 + 重建」模式下会产生历史残留行冲突,编辑时撞键 500。
-- 软删除的并发安全由应用层 replaceSpuSpecValues 流程保证
-- (先全量 SET deleted=1,再批量 INSERT 新行),数据库层面不再约束。
-- 前置:阶段 1 / 2 已执行
-- 警告:唯一键被删后,依赖应用层逻辑保证 active 唯一,请勿绕开 Service 直接写表
-- ============================================================
USE `new_computility`;
-- 1. 删除唯一键 uk_spu_config_deleted
ALTER TABLE `compute_resource_spu_spec_value`
DROP INDEX `uk_spu_config_deleted`;
-- 2. 保留普通索引 idx_spu_id 和 idx_config_id(用于按 SPU / 按 config 反查),性能不受影响
-- 如果之前没建这两个索引,可以补一下:
-- CREATE INDEX `idx_spu_id` ON `compute_resource_spu_spec_value` (`spu_id`);
-- CREATE INDEX `idx_config_id` ON `compute_resource_spu_spec_value` (`config_id`);
-- 3. 清理历史软删除残留(同一 spu+config 只保留最新的软删除记录,其余删掉)
-- 这一步是清理之前撞键产生的脏数据,可选但建议执行一次让数据干净
DELETE sv1
FROM `compute_resource_spu_spec_value` sv1
INNER JOIN `compute_resource_spu_spec_value` sv2
ON sv1.spu_id = sv2.spu_id
AND sv1.config_id = sv2.config_id
AND sv1.deleted = b'1'
AND sv2.deleted = b'1'
AND sv1.id < sv2.id;
-- ============================================================
-- 算力资源商品改造 · 阶段 6(完整版)
-- 目标:
-- 1. 订单硬件配置快照表 compute_resource_order_snapshot 改成
-- spec_snapshot JSON 字段存储规格
-- 2. ip 字段允许 NULL(下单时为空,商家发货时填写)
-- 适用库:new_computility
-- 前置:阶段 2 已 TRUNCATE 订单快照表,本脚本只动结构
-- 配套:
-- - ResourceOrderSnapshotDO 删 10 个规格列,加 specSnapshot
-- - AppResourceOrderSnapshotSaveReqVO / RespVO / PageReqVO 同步
-- - AppResourceOrderSnapshotSaveReqVO 去掉 ip 字段的 @NotBlank 校验
-- - ResourceOrderServiceImpl.createOrderHardwareSnapshot 写 JSON
-- - ResourceOrderServiceImpl.getUserResourceOrder* 读 JSON
-- ============================================================
USE `new_computility`;
ALTER TABLE `compute_resource_order_snapshot`
ADD COLUMN `spec_snapshot` JSON NULL DEFAULT NULL
COMMENT '下单时商品规格快照(Map<configCategory, configOption>)'
AFTER `spu_name`,
MODIFY COLUMN `ip` VARCHAR(64) NULL DEFAULT NULL
COMMENT '服务器IP地址快照(商家发货时填写,下单时为空)',
DROP COLUMN `cpu`,
DROP COLUMN `gpu`,
DROP COLUMN `ram`,
DROP COLUMN `storage`,
DROP COLUMN `power_supply`,
DROP COLUMN `nic`,
DROP COLUMN `gpu_count`,
DROP COLUMN `compute`,
DROP COLUMN `core_count`,
DROP COLUMN `memory_capacity`;
-- 验证:
-- SHOW COLUMNS FROM `compute_resource_order_snapshot`;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment