Commit b55d38ad by Jony.L

算力资源重构-算力资源客户端展示 以及算力资源订单功能初步修改

parent 8ea19ecb
package com.luhu.computility.framework.common.enums;
import cn.hutool.core.util.ObjUtil;
import com.luhu.computility.framework.common.core.ArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 通用删除状态枚举
*
* @author jony
*/
@Getter
@AllArgsConstructor
public enum CommonDeleteStatusEnum implements ArrayValuable<Integer> {
NOT_DELETED(0, "未删除"),
DELETED(1, "已删除");
public static final Integer[] ARRAYS = Arrays.stream(values()).map(CommonDeleteStatusEnum::getValue).toArray(Integer[]::new);
/**
* 状态值
*/
private final Integer value;
public Integer getValue() {
return value;
}
/**
* 状态名
*/
private final String name;
@Override
public Integer[] array() {
return ARRAYS;
}
public static boolean isNotDeleted(Integer status) {
return ObjUtil.equal(NOT_DELETED.value, status);
}
public static boolean isDeleted(Integer status) {
return ObjUtil.equal(DELETED.value, status);
}
}
\ No newline at end of file
......@@ -12,6 +12,11 @@ public interface ErrorCodeConstants {
ErrorCode RESOURCE_SKU_NOT_EXISTS = new ErrorCode(1_030_002_000, "算力资源SKU表(价格和租赁信息)不存在");
ErrorCode RESOURCE_SPU_NOT_EXISTS = new ErrorCode(1_030_003_000, "算力资源SPU表(基础配置信息)不存在");
ErrorCode RESOURCE_ORDER_NOT_EXISTS = new ErrorCode(1_030_004_000, "算力资源订单不存在");
ErrorCode RESOURCE_ORDER_SKU_NOT_EXISTS = new ErrorCode(1_030_004_001, "算力资源SKU不存在");
ErrorCode RESOURCE_ORDER_SPU_NOT_EXISTS = new ErrorCode(1_030_004_002, "算力资源SPU不存在");
ErrorCode RESOURCE_CONFIG_NOT_EXISTS = new ErrorCode(1_030_005_000, "算力资源配置不存在");
ErrorCode RESOURCE_ORDER_STATUS_NOT_UNPAID = new ErrorCode(1_030_006_000, "算力资源订单状态不是待支付");
ErrorCode RESOURCE_ORDER_PAY_ORDER_ID_MISMATCH = new ErrorCode(1_030_007_000, "支付订单ID不匹配");
ErrorCode RESOURCE_ORDER_NOT_BELONGS_TO_USER = new ErrorCode(1_030_008_000, "算力资源订单不属于当前用户");
}
\ No newline at end of file
package com.luhu.computility.module.compute.enums;
import lombok.Getter;
/**
* 算力资源订单状态枚举
*
* @Author: jony
* @Date : 2025/10/10
* @VERSION v1.0
*/
@Getter
public enum ResourceOrderStatus {
UNPAID(0, "待支付"),
PAID(1, "已支付"),
CANCELED(2, "已取消");
private final Integer value;
private final String label;
private ResourceOrderStatus(Integer value, String label) {
this.value = value;
this.label = label;
}
public static ResourceOrderStatus getByValue(int value) {
for (ResourceOrderStatus status : ResourceOrderStatus.values()) {
if (status.getValue() == value) {
return status;
}
}
return null;
}
public static String getLabelByValue(Integer value) {
for (ResourceOrderStatus status : values()) {
if (status.getValue() == value) {
return status.getLabel();
}
}
return null;
}
}
\ No newline at end of file
package com.luhu.computility.module.compute.enums;
import lombok.Getter;
/**
* 算力资源SKU状态枚举
*
* @Author: jony
* @Date : 2025/10/11
* @VERSION v1.0
*/
@Getter
public enum ResourceSkuStatus {
ONLINE(0, "上架"),
OFFLINE(1, "下架");
private final Integer value;
private final String label;
private ResourceSkuStatus(Integer value, String label) {
this.value = value;
this.label = label;
}
public static ResourceSkuStatus getByValue(int value) {
for (ResourceSkuStatus status : ResourceSkuStatus.values()) {
if (status.getValue() == value) {
return status;
}
}
return null;
}
public static String getLabelByValue(Integer value) {
for (ResourceSkuStatus status : values()) {
if (status.getValue() == value) {
return status.getLabel();
}
}
return null;
}
}
\ No newline at end of file
......@@ -31,6 +31,20 @@
<version>${revision}</version>
</dependency>
<!-- 依赖通用模块 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-common</artifactId>
<version>${revision}</version>
</dependency>
<!-- 依赖支付模块 -->
<dependency>
<groupId>com.luhu</groupId>
<artifactId>computility-module-pay</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>com.luhu</groupId>
......
package com.luhu.computility.module.compute.controller.app.resourcecategory;
import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.module.compute.controller.app.resourcecategory.vo.AppResourceCategoryRespVO;
import com.luhu.computility.module.compute.service.resourcecategory.ResourceCategoryService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.List;
import static com.luhu.computility.framework.common.pojo.CommonResult.success;
@Tag(name = "用户 APP - 算力资源分类")
@RestController
@RequestMapping("/compute/resource-category")
@Validated
@Slf4j
public class AppResourceCategoryController {
@Resource
private ResourceCategoryService resourceCategoryService;
@GetMapping("/list")
@Operation(summary = "获得算力资源分类列表")
public CommonResult<List<AppResourceCategoryRespVO>> getResourceCategoryList() {
return success(BeanUtils.toBean(resourceCategoryService.getAllCategory(), AppResourceCategoryRespVO.class));
}
}
\ No newline at end of file
package com.luhu.computility.module.compute.controller.app.resourcecategory.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "用户 APP - 算力资源分类 Response VO")
@Data
public class AppResourceCategoryRespVO {
@Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "GPU服务器")
private String name;
@Schema(description = "分类描述", example = "高性能GPU算力服务器")
private String remark;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}
\ No newline at end of file
package com.luhu.computility.module.compute.controller.app.resourceorder;
import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.module.compute.controller.app.resourceorder.vo.AppResourceOrderCreateReqVO;
import com.luhu.computility.module.compute.controller.app.resourceorder.vo.AppResourceOrderCreateRespVO;
import com.luhu.computility.module.compute.service.resourceorder.ResourceOrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.springframework.validation.annotation.Validated;
import static com.luhu.computility.framework.common.pojo.CommonResult.success;
import static com.luhu.computility.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "用户 APP - 算力资源订单")
@RestController
@RequestMapping("/compute/order")
@Validated
@Slf4j
public class AppResourceOrderController {
@Resource
private ResourceOrderService resourceOrderService;
@PostMapping("/create")
@Operation(summary = "创建算力资源订单")
public CommonResult<AppResourceOrderCreateRespVO> createResourceOrder(@Valid @RequestBody AppResourceOrderCreateReqVO createReqVO) {
Long userId = getLoginUserId();
AppResourceOrderCreateRespVO respVO = resourceOrderService.createUserResourceOrder(userId, createReqVO);
return success(respVO);
}
@PutMapping("/cancel")
@Operation(summary = "取消算力资源订单")
public CommonResult<Boolean> cancelResourceOrder(@RequestParam("orderId") Long orderId) {
Long userId = getLoginUserId();
resourceOrderService.cancelOrder(userId, orderId);
return success(true);
}
}
\ No newline at end of file
package com.luhu.computility.module.compute.controller.app.resourceorder;
import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.module.compute.service.resourceorder.ResourceOrderService;
import com.luhu.computility.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.validation.Valid;
import org.springframework.validation.annotation.Validated;
import static com.luhu.computility.framework.common.pojo.CommonResult.success;
@Tag(name = "支付回调 - 算力资源订单")
@RestController
@RequestMapping("/compute/order/pay")
@Validated
@Slf4j
public class ResourceOrderPayController {
@Resource
private ResourceOrderService resourceOrderService;
@PostMapping("/update-paid")
@Operation(summary = "支付订单回调,更新订单为已支付")
@PermitAll
public CommonResult<Boolean> updateOrderPaid(@Valid @RequestBody PayOrderNotifyReqDTO notifyReqDTO) {
log.info("[updateOrderPaid][req({})]", notifyReqDTO);
resourceOrderService.updateOrderPaid(Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayOrderId());
return success(true);
}
}
\ No newline at end of file
package com.luhu.computility.module.compute.controller.app.resourceorder.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Schema(description = "用户 APP - 算力资源订单创建 Request VO")
@Data
public class AppResourceOrderCreateReqVO {
@Schema(description = "算力资源SKU ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "31061")
@NotNull(message = "算力资源SKU ID不能为空")
private Long skuId;
}
\ No newline at end of file
package com.luhu.computility.module.compute.controller.app.resourceorder.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "用户 APP - 算力资源订单创建 Response VO")
@Data
public class AppResourceOrderCreateRespVO {
@Schema(description = "订单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1595")
private Long id;
@Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED)
private String orderNo;
@Schema(description = "支付订单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "15798")
private Long payOrderId;
}
\ No newline at end of file
package com.luhu.computility.module.compute.controller.app.resourcesku;
import com.luhu.computility.framework.common.pojo.CommonResult;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.module.compute.controller.app.resourcesku.vo.AppResourceSkuPageReqVO;
import com.luhu.computility.module.compute.controller.app.resourcesku.vo.AppResourceSkuRespVO;
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.service.resourcesku.ResourceSkuService;
import com.luhu.computility.module.compute.service.resourcespu.ResourceSpuService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.validation.annotation.Validated;
import static com.luhu.computility.framework.common.pojo.CommonResult.success;
@Tag(name = "用户 APP - 算力资源SKU")
@RestController
@RequestMapping("/compute/resource-sku")
@Validated
@Slf4j
public class AppResourceSkuController {
@Resource
private ResourceSkuService resourceSkuService;
@Resource
private ResourceSpuService resourceSpuService;
@GetMapping("/page")
@Operation(summary = "获得算力资源SKU分页")
public CommonResult<PageResult<AppResourceSkuRespVO>> getResourceSkuPage(@Valid AppResourceSkuPageReqVO pageReqVO) {
// 根据分类ID查询该分类下的所有SPU
List<ResourceSpuDO> spus;
if (pageReqVO.getCategoryId() != null) {
// 根据分类ID查询SPU
spus = resourceSpuService.getResourceSpuListByCategoryId(pageReqVO.getCategoryId());
} else {
// 查询所有上架的SPU
spus = resourceSpuService.getOnlineResourceSpuList();
}
if (spus.isEmpty()) {
PageResult<AppResourceSkuRespVO> emptyResult = new PageResult<>();
emptyResult.setTotal(0L);
emptyResult.setList(Collections.emptyList());
return success(emptyResult);
}
// 获取这些SPU对应的所有可用SKU
List<Long> spuIds = spus.stream().map(ResourceSpuDO::getId).collect(Collectors.toList());
List<ResourceSkuDO> skus = resourceSkuService.getResourceSkuListBySpuIds(spuIds, pageReqVO.getStatus());
// 分页处理
int total = skus.size();
int start = (pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize();
int end = Math.min(start + pageReqVO.getPageSize(), total);
List<ResourceSkuDO> pageSkus = skus.subList(start, end);
// 组装返回数据
Map<Long, ResourceSpuDO> spuMap = spus.stream()
.collect(Collectors.toMap(ResourceSpuDO::getId, spu -> spu));
List<AppResourceSkuRespVO> respList = pageSkus.stream().map(sku -> {
ResourceSpuDO spu = spuMap.get(sku.getSpuId());
if (spu == null) {
return null;
}
AppResourceSkuRespVO respVO = new AppResourceSkuRespVO();
respVO.setId(sku.getId());
respVO.setName(spu.getName());
respVO.setRemark(spu.getIntro());
respVO.setPrice(sku.getPaymentPrice());
respVO.setFeeInfo(sku.getDurationDays() + "天");
respVO.setCpu(spu.getCpu());
respVO.setGpu(spu.getGpu());
respVO.setRam(spu.getRam());
respVO.setStorage(spu.getStorage());
respVO.setIp(spu.getIp());
respVO.setLocation(spu.getLocation());
return respVO;
}).filter(obj -> obj != null).collect(Collectors.toList());
PageResult<AppResourceSkuRespVO> result = new PageResult<>();
result.setTotal((long) total);
result.setList(respList);
return success(result);
}
@GetMapping("/get-detail")
@Operation(summary = "获得算力资源SKU详情")
@Parameter(name = "id", description = "编号", required = true)
public CommonResult<AppResourceSkuRespVO> getResourceSkuDetail(@RequestParam("id") Long id) {
ResourceSkuDO resourceSku = resourceSkuService.getResourceSku(id);
ResourceSpuDO resourceSpu = resourceSpuService.getResourceSpu(resourceSku.getSpuId());
if (resourceSpu == null) {
return success(null);
}
AppResourceSkuRespVO respVO = new AppResourceSkuRespVO();
respVO.setId(resourceSku.getId());
respVO.setName(resourceSpu.getName());
respVO.setRemark(resourceSpu.getIntro());
respVO.setPrice(resourceSku.getPaymentPrice());
respVO.setFeeInfo(resourceSku.getDurationDays() + "天");
respVO.setCpu(resourceSpu.getCpu());
respVO.setGpu(resourceSpu.getGpu());
respVO.setRam(resourceSpu.getRam());
respVO.setStorage(resourceSpu.getStorage());
respVO.setIp(resourceSpu.getIp());
respVO.setLocation(resourceSpu.getLocation());
return success(respVO);
}
}
\ No newline at end of file
package com.luhu.computility.module.compute.controller.app.resourcesku.vo;
import com.luhu.computility.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "用户 APP - 算力资源SKU分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class AppResourceSkuPageReqVO extends PageParam {
@Schema(description = "分类ID", example = "1")
private Long categoryId;
@Schema(description = "状态", example = "1")
private Integer status;
}
\ No newline at end of file
package com.luhu.computility.module.compute.controller.app.resourcesku.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "用户 APP - 算力资源SKU Response VO")
@Data
public class AppResourceSkuRespVO {
@Schema(description = "SKU编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "GPU服务器A型")
private String name;
@Schema(description = "描述", example = "高性能GPU服务器,适合AI训练")
private String remark;
@Schema(description = "商品价格,单位使用:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "888800")
private Integer price;
@Schema(description = "费用信息", requiredMode = Schema.RequiredMode.REQUIRED, example = "7天")
private String feeInfo;
@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 = "服务器IP", example = "192.168.1.100")
private String ip;
@Schema(description = "服务器所在地", example = "深圳")
private String location;
}
\ No newline at end of file
package com.luhu.computility.module.compute.service.resourcecategory;
import cn.hutool.core.collection.CollUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import com.luhu.computility.module.compute.controller.admin.resourcecategory.vo.*;
import com.luhu.computility.module.compute.dal.dataobject.resourcecategory.ResourceCategoryDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.module.compute.controller.admin.resourcecategory.vo.ResourceCategoryPageReqVO;
import com.luhu.computility.module.compute.controller.admin.resourcecategory.vo.ResourceCategorySaveReqVO;
import com.luhu.computility.module.compute.dal.dataobject.resourcecategory.ResourceCategoryDO;
import com.luhu.computility.module.compute.dal.mysql.resourcecategory.ResourceCategoryMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
import static com.luhu.computility.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.luhu.computility.framework.common.util.collection.CollectionUtils.convertList;
import static com.luhu.computility.framework.common.util.collection.CollectionUtils.diffList;
import static com.luhu.computility.module.compute.enums.ErrorCodeConstants.*;
import static com.luhu.computility.module.compute.enums.ErrorCodeConstants.RESOURCE_CATEGORY_NOT_EXISTS;
import static com.luhu.computility.module.compute.enums.ResourceEnableStatus.ENABLE;
/**
......
......@@ -3,6 +3,8 @@ package com.luhu.computility.module.compute.service.resourceorder;
import java.util.*;
import javax.validation.*;
import com.luhu.computility.module.compute.controller.admin.resourceorder.vo.*;
import com.luhu.computility.module.compute.controller.app.resourceorder.vo.AppResourceOrderCreateReqVO;
import com.luhu.computility.module.compute.controller.app.resourceorder.vo.AppResourceOrderCreateRespVO;
import com.luhu.computility.module.compute.dal.dataobject.resourceorder.ResourceOrderDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
......@@ -59,4 +61,29 @@ public interface ResourceOrderService {
*/
PageResult<ResourceOrderDO> getResourceOrderPage(ResourceOrderPageReqVO pageReqVO);
/**
* 用户创建算力资源订单
*
* @param userId 用户ID
* @param createReqVO 创建信息
* @return 创建响应
*/
AppResourceOrderCreateRespVO createUserResourceOrder(Long userId, @Valid AppResourceOrderCreateReqVO createReqVO);
/**
* 更新订单为已支付(支付回调使用)
*
* @param orderId 订单ID
* @param payOrderId 支付订单ID
*/
void updateOrderPaid(Long orderId, Long payOrderId);
/**
* 取消订单
*
* @param userId 用户ID
* @param orderId 订单ID
*/
void cancelOrder(Long userId, Long orderId);
}
\ No newline at end of file
package com.luhu.computility.module.compute.service.resourceorder;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.*;
import com.luhu.computility.module.compute.controller.admin.resourceorder.vo.*;
import com.luhu.computility.module.compute.controller.app.resourceorder.vo.AppResourceOrderCreateReqVO;
import com.luhu.computility.module.compute.controller.app.resourceorder.vo.AppResourceOrderCreateRespVO;
import com.luhu.computility.module.compute.dal.dataobject.resourceorder.ResourceOrderDO;
import com.luhu.computility.framework.common.pojo.PageResult;
import com.luhu.computility.framework.common.pojo.PageParam;
import com.luhu.computility.framework.common.util.object.BeanUtils;
import com.luhu.computility.module.compute.dal.mysql.resourceorder.ResourceOrderMapper;
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.service.resourcesku.ResourceSkuService;
import com.luhu.computility.module.compute.service.resourcespu.ResourceSpuService;
import com.luhu.computility.module.compute.enums.ResourceOrderStatus;
import com.luhu.computility.module.pay.api.order.PayOrderApi;
import com.luhu.computility.module.pay.api.order.dto.PayOrderCreateReqDTO;
import static com.luhu.computility.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.luhu.computility.framework.common.util.collection.CollectionUtils.convertList;
......@@ -32,6 +43,15 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
@Resource
private ResourceOrderMapper resourceOrderMapper;
@Resource
private ResourceSkuService resourceSkuService;
@Resource
private ResourceSpuService resourceSpuService;
@Resource
private PayOrderApi payOrderApi;
@Override
public Long createResourceOrder(ResourceOrderSaveReqVO createReqVO) {
// 插入
......@@ -82,4 +102,122 @@ public class ResourceOrderServiceImpl implements ResourceOrderService {
return resourceOrderMapper.selectPage(pageReqVO);
}
@Override
@Transactional(rollbackFor = Exception.class)
public AppResourceOrderCreateRespVO createUserResourceOrder(Long userId, AppResourceOrderCreateReqVO createReqVO) {
// 获取SKU信息
ResourceSkuDO sku = resourceSkuService.getResourceSku(createReqVO.getSkuId());
if (sku == null) {
throw exception(RESOURCE_ORDER_SKU_NOT_EXISTS);
}
// 获取SPU信息
ResourceSpuDO spu = resourceSpuService.getResourceSpu(sku.getSpuId());
if (spu == null) {
throw exception(RESOURCE_ORDER_SPU_NOT_EXISTS);
}
// 创建算力资源订单
ResourceOrderDO order = new ResourceOrderDO();
order.setUserId(userId);
order.setSkuId(createReqVO.getSkuId());
order.setSpuName(spu.getName());
order.setOrderNo(generateOrderNo());
order.setStatus(ResourceOrderStatus.UNPAID.getValue());
order.setMarketPrice(sku.getMarketPrice().longValue());
order.setPaymentPrice(sku.getPaymentPrice().longValue());
order.setRefundStatus(0); // 无退款
order.setInvoiceStatus(0); // 未开票
order.setRentStartTime(LocalDateTime.now());
// 设置租赁结束时间
order.setRentEndTime(LocalDateTime.now().plusDays(sku.getDurationDays()));
resourceOrderMapper.insert(order);
// 创建支付订单
PayOrderCreateReqDTO payOrderCreateReqDTO = new PayOrderCreateReqDTO();
payOrderCreateReqDTO.setAppKey("computility-app"); // TODO: 从配置中获取
payOrderCreateReqDTO.setMerchantOrderId(order.getId().toString());
payOrderCreateReqDTO.setSubject("算力资源购买");
payOrderCreateReqDTO.setBody(spu.getName() + " - " + sku.getDurationDays() + "天");
payOrderCreateReqDTO.setPrice(sku.getPaymentPrice());
payOrderCreateReqDTO.setExpireTime(LocalDateTime.now().plusMinutes(30)); // 30分钟过期
Long payOrderId = payOrderApi.createOrder(payOrderCreateReqDTO);
// 更新订单的支付ID
order.setPayOrderId(payOrderId);
resourceOrderMapper.updateById(order);
// 返回结果
AppResourceOrderCreateRespVO respVO = new AppResourceOrderCreateRespVO();
respVO.setId(order.getId());
respVO.setOrderNo(order.getOrderNo());
respVO.setPayOrderId(payOrderId);
return respVO;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateOrderPaid(Long orderId, Long payOrderId) {
// 校验订单存在
ResourceOrderDO order = resourceOrderMapper.selectById(orderId);
if (order == null) {
throw exception(RESOURCE_ORDER_NOT_EXISTS);
}
// 校验订单状态
if (!order.getStatus().equals(ResourceOrderStatus.UNPAID.getValue())) {
throw exception(RESOURCE_ORDER_STATUS_NOT_UNPAID);
}
// 校验支付订单ID匹配
if (!Objects.equals(order.getPayOrderId(), payOrderId)) {
throw exception(RESOURCE_ORDER_PAY_ORDER_ID_MISMATCH);
}
// 更新订单状态
ResourceOrderDO updateOrder = new ResourceOrderDO();
updateOrder.setId(orderId);
updateOrder.setStatus(ResourceOrderStatus.PAID.getValue());
updateOrder.setPayTime(LocalDateTime.now());
resourceOrderMapper.updateById(updateOrder);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void cancelOrder(Long userId, Long orderId) {
// 校验订单存在且属于该用户
ResourceOrderDO order = resourceOrderMapper.selectById(orderId);
if (order == null) {
throw exception(RESOURCE_ORDER_NOT_EXISTS);
}
if (!Objects.equals(order.getUserId(), userId)) {
throw exception(RESOURCE_ORDER_NOT_BELONGS_TO_USER);
}
// 校验订单状态
if (!order.getStatus().equals(ResourceOrderStatus.UNPAID.getValue())) {
throw exception(RESOURCE_ORDER_STATUS_NOT_UNPAID);
}
// 更新订单状态
ResourceOrderDO updateOrder = new ResourceOrderDO();
updateOrder.setId(orderId);
updateOrder.setStatus(ResourceOrderStatus.CANCELED.getValue());
updateOrder.setCancelTime(LocalDateTime.now());
resourceOrderMapper.updateById(updateOrder);
}
/**
* 生成订单编号
*/
private String generateOrderNo() {
return "c" + IdUtil.getSnowflakeNextIdStr();
}
}
\ No newline at end of file
......@@ -59,4 +59,13 @@ public interface ResourceSkuService {
*/
PageResult<ResourceSkuDO> getResourceSkuPage(ResourceSkuPageReqVO pageReqVO);
/**
* 根据SPU ID列表获得SKU列表
*
* @param spuIds SPU ID列表
* @param status 状态筛选(可选)
* @return SKU列表
*/
List<ResourceSkuDO> getResourceSkuListBySpuIds(List<Long> spuIds, Integer status);
}
\ No newline at end of file
package com.luhu.computility.module.compute.service.resourcesku;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
......@@ -19,6 +20,8 @@ import static com.luhu.computility.framework.common.exception.util.ServiceExcept
import static com.luhu.computility.framework.common.util.collection.CollectionUtils.convertList;
import static com.luhu.computility.framework.common.util.collection.CollectionUtils.diffList;
import static com.luhu.computility.module.compute.enums.ErrorCodeConstants.*;
import static com.luhu.computility.module.compute.enums.ResourceSkuStatus.ONLINE;
import static com.luhu.computility.framework.common.enums.CommonDeleteStatusEnum.NOT_DELETED;
/**
* 算力资源SKU表(价格和租赁信息) Service 实现类
......@@ -82,4 +85,25 @@ public class ResourceSkuServiceImpl implements ResourceSkuService {
return resourceSkuMapper.selectPage(pageReqVO);
}
@Override
public List<ResourceSkuDO> getResourceSkuListBySpuIds(List<Long> spuIds, Integer status) {
if (spuIds == null || spuIds.isEmpty()) {
return Collections.emptyList();
}
LambdaQueryWrapper<ResourceSkuDO> wrapper = new LambdaQueryWrapper<>();
wrapper.in(ResourceSkuDO::getSpuId, spuIds)
.eq(ResourceSkuDO::getDeleted, NOT_DELETED.getValue());
if (status != null) {
// 根据状态筛选
wrapper.eq(ResourceSkuDO::getStatus, status);
} else {
// 不筛选状态,只要未删除的,默认只查上架状态的
wrapper.eq(ResourceSkuDO::getStatus, ONLINE.getValue());
}
return resourceSkuMapper.selectList(wrapper);
}
}
\ No newline at end of file
......@@ -62,4 +62,27 @@ public interface ResourceSpuService {
List<ResourceSpuSimpleRespVO> getResourceSimpleSpuList();
/**
* 根据ID列表获得算力资源SPU列表
*
* @param ids ID列表
* @return 算力资源SPU列表
*/
List<ResourceSpuDO> getResourceSpuListByIds(List<Long> ids);
/**
* 根据分类ID获得算力资源SPU列表
*
* @param categoryId 分类ID
* @return 算力资源SPU列表
*/
List<ResourceSpuDO> getResourceSpuListByCategoryId(Long categoryId);
/**
* 获取所有上架的算力资源SPU列表
*
* @return 上架的算力资源SPU列表
*/
List<ResourceSpuDO> getOnlineResourceSpuList();
}
\ No newline at end of file
package com.luhu.computility.module.compute.service.resourcespu;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
......@@ -20,6 +21,7 @@ import static com.luhu.computility.framework.common.util.collection.CollectionUt
import static com.luhu.computility.framework.common.util.collection.CollectionUtils.diffList;
import static com.luhu.computility.module.compute.enums.ErrorCodeConstants.*;
import static com.luhu.computility.module.compute.enums.ResourceSpuStatus.ONLINE;
import static com.luhu.computility.framework.common.enums.CommonDeleteStatusEnum.NOT_DELETED;
/**
* 算力资源SPU表(基础配置信息) Service 实现类
......@@ -90,4 +92,32 @@ public class ResourceSpuServiceImpl implements ResourceSpuService {
return BeanUtils.toBean(resourceSpuDOList, ResourceSpuSimpleRespVO.class);
}
@Override
public List<ResourceSpuDO> getResourceSpuListByIds(List<Long> ids) {
if (ids == null || ids.isEmpty()) {
return Collections.emptyList();
}
return resourceSpuMapper.selectBatchIds(ids);
}
@Override
public List<ResourceSpuDO> getResourceSpuListByCategoryId(Long categoryId) {
if (categoryId == null) {
return Collections.emptyList();
}
LambdaQueryWrapper<ResourceSpuDO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ResourceSpuDO::getCategoryId, categoryId)
.eq(ResourceSpuDO::getStatus, ONLINE.getValue())
.eq(ResourceSpuDO::getDeleted, NOT_DELETED.getValue());
return resourceSpuMapper.selectList(wrapper);
}
@Override
public List<ResourceSpuDO> getOnlineResourceSpuList() {
LambdaQueryWrapper<ResourceSpuDO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ResourceSpuDO::getStatus, ONLINE.getValue())
.eq(ResourceSpuDO::getDeleted, NOT_DELETED.getValue());
return resourceSpuMapper.selectList(wrapper);
}
}
\ No newline at end of file
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