产品明细单元测试完善

This commit is contained in:
gaoqr
2025-10-20 18:07:30 +08:00
parent 25b26c83dd
commit a3633fc6ef
7 changed files with 345 additions and 128 deletions
@@ -1,7 +1,6 @@
package com.cf.imes.module.system.controller.admin.funds.products.vo.productDetails;
import com.cf.imes.framework.common.pojo.PageParam;
import com.cf.imes.module.system.validation.products.ProductType;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -21,22 +20,12 @@ public class ProductDetailsPageReqVO extends PageParam {
@Schema(description = "产品ID", example = "1")
private Long productId;
@Schema(description = "购买方式", example = "0")
@ProductType
private Integer purchaseType;
@Schema(description = "产品时长", example = "1")
private String duration;
@Schema(description = "正常产量", example = "")
private BigDecimal output;
private Integer duration;
@Schema(description = "赠送市场", example = "1")
private String giftDuration;
@Schema(description = "赠送产量", example = "")
private BigDecimal giftOutput;
@Schema(description = "产品原价", example = "100")
private BigDecimal originalPrice;
@@ -46,7 +35,4 @@ public class ProductDetailsPageReqVO extends PageParam {
@Schema(description = "产品现价", example = "80")
private BigDecimal currentPrice;
@Schema(description = "是否特惠", example = "0")
private Boolean isDiscounted;
}
@@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Digits;
import jakarta.validation.constraints.Min;
import lombok.Data;
import jakarta.validation.constraints.NotNull;
@@ -25,19 +26,16 @@ public class ProductDetailsSaveReqVO {
@Schema(description = "购买方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
private Integer purchaseType = ProductsPurchaseTypeEnum.DURATION.getStatus();
@Schema(description = "产品时,格式:时长值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private String duration;
@Schema(description = "产品时,格式:时长值", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@Min(value = 1, message = "产品时长必须大于0")
@NotNull(message = "产品时长不能为空")
private Integer duration;
@Schema(description = "产品时长单位,0:年", example = "1")
@ProductDurationUnitValid
@NotNull(message = "产品时长单位不能为空")
private Integer durationUnit;
@Schema(description = "产品产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
private BigDecimal output;
@Schema(description = "赠送产量", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
private BigDecimal giftOutput;
@Schema(description = "折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "0.8")
@DecimalMax(value = "100", message = "折扣必须小于等于100")
@DecimalMin(value = "0", message = "折扣必须大于等于0")
@@ -35,11 +35,6 @@ public class ProductsDetailDO extends BaseDO {
*/
private Long productId;
/**
* 产品明细购买方式 0时长 1产量
*/
private Integer purchaseType;
/**
* 正常时间,不加赠送时间
*/
@@ -50,24 +45,8 @@ public class ProductsDetailDO extends BaseDO {
*/
private Integer durationUnit;
/**
* 正常产量,不加赠送产量
*/
@TableField("`output`")
private BigDecimal output;
/**
* 赠送产量
*/
private BigDecimal giftOutput;
/**
* 折扣
*/
private BigDecimal discount;
/**
* 是否特惠: 0否1是
*/
private Boolean isDiscounted;
}
@@ -7,8 +7,6 @@ import com.cf.imes.module.system.controller.admin.funds.products.vo.productDetai
import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDetailDO;
import org.apache.ibatis.annotations.Mapper;
import java.math.BigDecimal;
/**
* 产品明细表 product_details Mapper
*
@@ -17,23 +15,32 @@ import java.math.BigDecimal;
@Mapper
public interface ProductsDetailMapper extends BaseMapperX<ProductsDetailDO> {
/**
* 分页查询
*
* @param reqVO
* @return
*/
default PageResult<ProductsDetailDO> selectPage(ProductDetailsPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ProductsDetailDO>()
.eqIfPresent(ProductsDetailDO::getPurchaseType, reqVO.getPurchaseType())
.eqIfPresent(ProductsDetailDO::getProductId, reqVO.getProductId())
.eqIfPresent(ProductsDetailDO::getDuration, reqVO.getDuration())
.eqIfPresent(ProductsDetailDO::getOutput, reqVO.getOutput())
.eqIfPresent(ProductsDetailDO::getGiftOutput, reqVO.getGiftOutput())
.eqIfPresent(ProductsDetailDO::getDiscount, reqVO.getDiscount())
.eqIfPresent(ProductsDetailDO::getIsDiscounted, reqVO.getIsDiscounted())
.eqIfPresent(ProductsDetailDO::getDeleted, false)
.orderByAsc(ProductsDetailDO::getDuration)
);
}
// 时长查重,添加productId为查询条件
default int selectCountByDuration(Long productId, Long productDetailId, String duration, Integer durationUnit) {
/**
* 查询产品id下相同时长、时长单位的数量
*
* @param productId
* @param productDetailId
* @param duration
* @param durationUnit
* @return
*/
default int selectCountByDuration(Long productId, Long productDetailId, Integer duration, Integer durationUnit) {
LambdaQueryWrapperX<ProductsDetailDO> queryWrapper = new LambdaQueryWrapperX<>();
queryWrapper.eq(ProductsDetailDO::getProductId, productId)
.eq(ProductsDetailDO::getDeleted, false)
@@ -42,16 +49,4 @@ public interface ProductsDetailMapper extends BaseMapperX<ProductsDetailDO> {
.neIfPresent(ProductsDetailDO::getId, productDetailId);
return Math.toIntExact(selectCount(queryWrapper));
}
// 产量查重
default int selectCountByOutput(BigDecimal output, Long productId) {
LambdaQueryWrapperX<ProductsDetailDO> queryWrapper = new LambdaQueryWrapperX<>();
queryWrapper.eq(ProductsDetailDO::getProductId, productId)
.eq(ProductsDetailDO::getDeleted, false)
.eq(ProductsDetailDO::getDuration, output);
return Math.toIntExact(selectCount(queryWrapper));
}
}
@@ -16,7 +16,6 @@ import com.cf.imes.module.system.dal.mysql.funds.products.ProductsDetailMapper;
import com.cf.imes.module.system.dal.mysql.funds.products.ProductsMapper;
import com.cf.imes.module.system.enums.pay.ProductDurationUnitEnum;
import com.cf.imes.module.system.enums.products.ProductStatusEnum;
import com.cf.imes.module.system.enums.products.ProductsPurchaseTypeEnum;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -48,17 +47,8 @@ public class ProductsDetailServiceImpl implements ProductsDetailService {
// 校验是否有这个产品
validateProductExistAndNotOnList(createReqVO.getProductId());
if (ProductsPurchaseTypeEnum.DURATION.getStatus().equals(createReqVO.getPurchaseType())) {
// 校验时长
checkDuration(createReqVO.getDuration(), createReqVO.getDurationUnit());
// 查询是否有重复的定价
checkProductDetails(createReqVO);
} else if (createReqVO.getPurchaseType().equals(ProductsPurchaseTypeEnum.OUTPUT.getStatus())) {
// todo 暂不支持产量
throw exception(PRODUCTS_OUTPUT_NOT_SUPPORT);
}
// 查询是否有重复的定价
checkProductDetails(createReqVO);
ProductsDetailDO productDetailsDO = BeanUtils.toBean(createReqVO, ProductsDetailDO.class);
productDetailsMapper.insert(productDetailsDO);
@@ -73,16 +63,8 @@ public class ProductsDetailServiceImpl implements ProductsDetailService {
validateProductDetailsExists(updateReqVO.getId());
if (updateReqVO.getPurchaseType().equals(ProductsPurchaseTypeEnum.DURATION.getStatus())) {
// 校验时长
checkDuration(updateReqVO.getDuration(), updateReqVO.getDurationUnit());
// 校验同时长是否还有其他的定价规则
checkProductDetails(updateReqVO);
} else if (updateReqVO.getPurchaseType().equals(ProductsPurchaseTypeEnum.OUTPUT.getStatus())) {
// todo 暂不支持产量
throw exception(PRODUCTS_OUTPUT_NOT_SUPPORT);
}
// 校验同时长是否还有其他的定价规则
checkProductDetails(updateReqVO);
productDetailsMapper.update(new LambdaUpdateWrapper<ProductsDetailDO>()
.eq(ProductsDetailDO::getId, updateReqVO.getId())
@@ -132,29 +114,6 @@ public class ProductsDetailServiceImpl implements ProductsDetailService {
}
/**
* 校验时长
*
* @param duration
* @param timeUnit
* @return
*/
private void checkDuration(String duration, Integer timeUnit) {
AssertUtils.notEmpty(duration, PRODUCTS_DURATION_NOT_NULL);
AssertUtils.notEmpty(timeUnit, PRODUCTS_DURATION_NOT_NULL);
// 校验时长值
if (!duration.matches("^\\d+$")) {
throw exception(PRODUCTS_DURATION_INT_ERR);
}
int timeValue = Integer.parseInt(duration);
if (timeValue <= 0) {
throw exception(PRODUCTS_DURATION_INT_ERR);
}
}
/**
* 产品是否存在
*
@@ -203,20 +162,12 @@ public class ProductsDetailServiceImpl implements ProductsDetailService {
*/
private void checkProductDetails(ProductDetailsSaveReqVO createReqVO) {
int count;
if (createReqVO.getPurchaseType() == 0) {
String duration = createReqVO.getDuration();
Integer durationUnit = createReqVO.getDurationUnit();
// 时长去重
count = productDetailsMapper.selectCountByDuration(createReqVO.getProductId(), createReqVO.getId(), duration, durationUnit);
if (count > 0) {
throw ServiceExceptionUtil.exception(PRODUCTS_DETAIL_DURATION_EXIST, duration, ProductDurationUnitEnum.getDesc(durationUnit));
}
} else if (createReqVO.getPurchaseType() == 1) {
//产量去重
count = productDetailsMapper.selectCountByOutput(createReqVO.getOutput(), createReqVO.getProductId());
if (count > 0) {
throw exception(PRODUCTS_DETAIL_OUTPUT_EXIST);
}
Integer duration = createReqVO.getDuration();
Integer durationUnit = createReqVO.getDurationUnit();
// 时长去重
count = productDetailsMapper.selectCountByDuration(createReqVO.getProductId(), createReqVO.getId(), duration, durationUnit);
if (count > 0) {
throw ServiceExceptionUtil.exception(PRODUCTS_DETAIL_DURATION_EXIST, duration, ProductDurationUnitEnum.getDesc(durationUnit));
}
}