1、购买方式列表新增定价记录为空时的1年方式;2、支持产品购买1年自动生成方式的计算、补充软件购买首购时间计算异常;

This commit is contained in:
gaoqr
2025-10-09 15:43:35 +08:00
parent 6aceb9ad03
commit a7ea3cd5a1
4 changed files with 63 additions and 18 deletions
@@ -12,4 +12,6 @@ public class PayConstants {
public static final String PAY_PRODUCT_DETAIL_BUSINESSNO_PREFIX_FORMAT = "P%dD%s"; // 产品购买流水号格式 public static final String PAY_PRODUCT_DETAIL_BUSINESSNO_PREFIX_FORMAT = "P%dD%s"; // 产品购买流水号格式
public static final String PAY_PRODUCT_DETAIL_AUTO_GENERATE_MONTH_ID_FORMAT = "1759029544%d"; // 1~12月定价规则自动生成ID格式 public static final String PAY_PRODUCT_DETAIL_AUTO_GENERATE_MONTH_ID_FORMAT = "1759029544%d"; // 1~12月定价规则自动生成ID格式
public static final String PAY_PRODUCT_DETAIL_AUTO_GENERATE_YEAR_ID_FORMAT = "1759993429%d"; // 1年定价规则自动生成ID格式
} }
@@ -55,6 +55,7 @@ import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORG_PRODUCT_PUR
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORG_PRODUCT_PURCHASE_NOT_EXIST_ERROR; import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORG_PRODUCT_PURCHASE_NOT_EXIST_ERROR;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCT_PRICE_NULL_ERROR; import static com.cf.imes.module.system.enums.ErrorCodeConstants.PRODUCT_PRICE_NULL_ERROR;
import static com.cf.imes.module.system.enums.pay.PayConstants.PAY_PRODUCT_DETAIL_AUTO_GENERATE_MONTH_ID_FORMAT; import static com.cf.imes.module.system.enums.pay.PayConstants.PAY_PRODUCT_DETAIL_AUTO_GENERATE_MONTH_ID_FORMAT;
import static com.cf.imes.module.system.enums.pay.PayConstants.PAY_PRODUCT_DETAIL_AUTO_GENERATE_YEAR_ID_FORMAT;
/** /**
* @author 软件购买接口 实现类 * @author 软件购买接口 实现类
@@ -366,6 +367,16 @@ public class PurchaseServiceImpl implements PurchaseService {
} }
} }
} }
// 没有定价年的规则,自动补充一个1年的
if (CollUtil.isEmpty(productDetailRespVOList)) {
ProductDetailsRespVO oneYearRespVO = new ProductDetailsRespVO();
oneYearRespVO.setProductId(productId);
oneYearRespVO.setDuration(1);
oneYearRespVO.setDurationUnit(ProductDurationUnitEnum.YEAR.getCode());
oneYearRespVO.setCurrentPrice(productsDO.getPrice());
oneYearRespVO.setOriginalPrice(productsDO.getPrice());
productDetailRespVOList.add(oneYearRespVO);
}
// 默认展示1到10月的价格 // 默认展示1到10月的价格
for (int i = 1; i <= 10; i++) { for (int i = 1; i <= 10; i++) {
ProductDetailsRespVO detailRespVO = new ProductDetailsRespVO(); ProductDetailsRespVO detailRespVO = new ProductDetailsRespVO();
@@ -423,6 +434,17 @@ public class PurchaseServiceImpl implements PurchaseService {
} }
} }
} }
// 没有定价年的规则,自动补充一个1年的
if (CollUtil.isEmpty(productDetailRespVOList)) {
ProductDetailsRespVO oneYearRespVO = new ProductDetailsRespVO();
oneYearRespVO.setId(Long.parseLong(String.format(PAY_PRODUCT_DETAIL_AUTO_GENERATE_YEAR_ID_FORMAT, 1)));
oneYearRespVO.setProductId(productsDO.getId());
oneYearRespVO.setDuration(1);
oneYearRespVO.setDurationUnit(ProductDurationUnitEnum.YEAR.getCode());
oneYearRespVO.setCurrentPrice(productsDO.getPrice());
oneYearRespVO.setOriginalPrice(productsDO.getPrice());
productDetailRespVOList.add(oneYearRespVO);
}
// 默认展示1到10月的价格 // 默认展示1到10月的价格
for (int i = 1; i <= 10; i++) { for (int i = 1; i <= 10; i++) {
@@ -113,7 +113,8 @@ public class PayOrderServiceImpl implements PayOrderService {
private static final Pattern pattern = Pattern.compile("P(\\d+)O"); private static final Pattern pattern = Pattern.compile("P(\\d+)O");
// 自动生成定价id正则 // 自动生成定价id正则
private static final Pattern productDetailIdPattern = Pattern.compile("^1759029544(\\d+)$"); private static final Pattern productMonthDetailIdPattern = Pattern.compile("^1759029544(\\d+)$");
private static final Pattern productYearDetailIdPattern = Pattern.compile("^1759993429(\\d+)$");
@Resource @Resource
private PayHandlerFactory payHandlerFactory; private PayHandlerFactory payHandlerFactory;
@@ -264,10 +265,10 @@ public class PayOrderServiceImpl implements PayOrderService {
* @return * @return
*/ */
private ProductsDetailDO analyzeProductDetail(Long productId, Long productDetailId) { private ProductsDetailDO analyzeProductDetail(Long productId, Long productDetailId) {
// productDetailId符合规则PPAG%d // productDetailId符合规则month自动生成规则
Matcher matcher = productDetailIdPattern.matcher(String.valueOf(productDetailId)); Matcher matcher = productMonthDetailIdPattern.matcher(String.valueOf(productDetailId));
if (matcher.find()) { if (matcher.find()) {
// 取PPAG后的数字,是订购月份 // 取规则后的数字,是订购月份
String monthDuration = matcher.group(1); String monthDuration = matcher.group(1);
ProductsDetailDO monthDetail = new ProductsDetailDO(); ProductsDetailDO monthDetail = new ProductsDetailDO();
monthDetail.setId(productDetailId); monthDetail.setId(productDetailId);
@@ -276,10 +277,23 @@ public class PayOrderServiceImpl implements PayOrderService {
// 获取产品下的1年的折扣 // 获取产品下的1年的折扣
monthDetail.setDiscount(productsDetailService.getProductDetailOneYearDiscount(productId)); monthDetail.setDiscount(productsDetailService.getProductDetailOneYearDiscount(productId));
return monthDetail; return monthDetail;
} else {
// productDetailId符合规则year自动生成规则
matcher = productYearDetailIdPattern.matcher(String.valueOf(productDetailId));
if (matcher.find()) {
// 负责规则的年默认是1年
ProductsDetailDO yearDetail = new ProductsDetailDO();
yearDetail.setId(productDetailId);
yearDetail.setDuration(1);
yearDetail.setDurationUnit(ProductDurationUnitEnum.YEAR.getCode());
// 自动生产的没有折扣
yearDetail.setDiscount(BigDecimal.valueOf(100));
return yearDetail;
} else { } else {
return productsDetailService.validateProductDetailsExists(productDetailId); return productsDetailService.validateProductDetailsExists(productDetailId);
} }
} }
}
/** /**
* 处理前序购买记录: * 处理前序购买记录:
@@ -89,7 +89,7 @@ public class PayProductProcessor {
private PurchaseRecordDO previousPurchaseRecord; private PurchaseRecordDO previousPurchaseRecord;
// 本地订购产品的开始时间 // 本地订购产品的开始时间
private LocalDate startTime; private LocalDate startTime = LocalDate.now();
// 产品结束时间 // 产品结束时间
private LocalDate endTime; private LocalDate endTime;
@@ -111,6 +111,9 @@ public class PayProductProcessor {
// 上一次订购产品的结束时间进行计算 // 上一次订购产品的结束时间进行计算
endTime = previousPurchaseRecord.getEndTime(); endTime = previousPurchaseRecord.getEndTime();
endTime = calculateEndTime(productsDetailDO.getDuration(), productsDetailDO.getDurationUnit()); endTime = calculateEndTime(productsDetailDO.getDuration(), productsDetailDO.getDurationUnit());
} else {
// 首次订购正常从今天开始累加算世界时间
endTime = addTime(startTime, productsDetailDO.getDuration(), productsDetailDO.getDurationUnit());
} }
this.organAmountDO = organAmountDO; this.organAmountDO = organAmountDO;
this.organId = organId; this.organId = organId;
@@ -129,7 +132,7 @@ public class PayProductProcessor {
boolean initialPurchaseExist = ObjectUtil.isNotNull(orgInitialPurchaseRecord); boolean initialPurchaseExist = ObjectUtil.isNotNull(orgInitialPurchaseRecord);
BigDecimal price; BigDecimal price;
if (initialPurchaseExist) { if (initialPurchaseExist) {
price = computePrice(orgInitialPurchaseRecord, productsDetailDO); price = computePrice();
} else { } else {
price = computeInitialProductPayAmount(); price = computeInitialProductPayAmount();
// 首次购买记录是空,那么当前就是首次订购 // 首次购买记录是空,那么当前就是首次订购
@@ -725,10 +728,7 @@ public class PayProductProcessor {
.orElse(endTime); .orElse(endTime);
} }
// 2、订单的生效时间 // 2、 计算有效期叠加的起点
startTime = today;
// 3、 计算有效期叠加的起点
LocalDate purchaseStart; LocalDate purchaseStart;
if (today.isAfter(maxDelayEnd)) { if (today.isAfter(maxDelayEnd)) {
// 已过期 → 从今天开始累加 // 已过期 → 从今天开始累加
@@ -738,12 +738,12 @@ public class PayProductProcessor {
purchaseStart = maxDelayEnd; purchaseStart = maxDelayEnd;
} }
// 加正常时间 // 3、加正常时间
if (ObjectUtil.isNotNull(duration) && durationUnit != null) { if (ObjectUtil.isNotNull(duration) && durationUnit != null) {
endTime = addTime(purchaseStart, duration, durationUnit); endTime = addTime(purchaseStart, duration, durationUnit);
} }
// 5. 扣掉延期天数 // 4、扣掉延期天数
long delayDays = 0L; long delayDays = 0L;
if (CollUtil.isNotEmpty(delayRespVOList)) { if (CollUtil.isNotEmpty(delayRespVOList)) {
delayDays = calculateDelayDays(startTime, delayRespVOList); delayDays = calculateDelayDays(startTime, delayRespVOList);
@@ -871,11 +871,9 @@ public class PayProductProcessor {
/** /**
* 计算有首购记录的产品价格 * 计算有首购记录的产品价格
* *
* @param orgInitialPurchaseRecord 首次购买记录
* @param productsDetailDO 本次购买产品的定价规则
* @return * @return
*/ */
private BigDecimal computePrice(PurchaseRecordDO orgInitialPurchaseRecord, ProductsDetailDO productsDetailDO) { private BigDecimal computePrice() {
// 月均单价 // 月均单价
monthAverageAmount = orgInitialPurchaseRecord.getMonthAverageAmount(); monthAverageAmount = orgInitialPurchaseRecord.getMonthAverageAmount();
@@ -884,6 +882,9 @@ public class PayProductProcessor {
// 定价规则的折扣 // 定价规则的折扣
BigDecimal discount = productsDetailDO.getDiscount(); BigDecimal discount = productsDetailDO.getDiscount();
if (ObjectUtil.isNull(discount)) {
discount = BigDecimal.valueOf(100);
}
BigDecimal totalAmount; BigDecimal totalAmount;
/** /**
@@ -925,6 +926,9 @@ public class PayProductProcessor {
BigDecimal orgPurchasePrice = productsDO.getPrice(); BigDecimal orgPurchasePrice = productsDO.getPrice();
// 折扣 // 折扣
BigDecimal discount = productsDetailDO.getDiscount(); BigDecimal discount = productsDetailDO.getDiscount();
if (ObjectUtil.isNull(discount)) {
discount = BigDecimal.valueOf(100);
}
BigDecimal totalAmount; BigDecimal totalAmount;
switch (ProductDurationUnitEnum.fromStatus(productsDetailDO.getDurationUnit())) { switch (ProductDurationUnitEnum.fromStatus(productsDetailDO.getDurationUnit())) {
@@ -932,7 +936,9 @@ public class PayProductProcessor {
// 原价 // 原价
originalPrice = orgPurchasePrice.multiply(BigDecimal.valueOf(duration)); originalPrice = orgPurchasePrice.multiply(BigDecimal.valueOf(duration));
// 折扣价格 = 原价 * 折扣 // 折扣价格 = 原价 * 折扣
totalAmount = originalPrice.multiply(discount); totalAmount = originalPrice
.multiply(discount)
.divide(new BigDecimal(100), 2, RoundingMode.DOWN);
// 月均单价 = 折扣价格 / 10 // 月均单价 = 折扣价格 / 10
monthAverageAmount = originalPrice.divide(new BigDecimal(10), 2, RoundingMode.DOWN); monthAverageAmount = originalPrice.divide(new BigDecimal(10), 2, RoundingMode.DOWN);
} }
@@ -942,7 +948,8 @@ public class PayProductProcessor {
// 原价 // 原价
originalPrice = monthAverageAmount.multiply(BigDecimal.valueOf(duration)); originalPrice = monthAverageAmount.multiply(BigDecimal.valueOf(duration));
// 折扣价格 = 原价 * 折扣 // 折扣价格 = 原价 * 折扣
totalAmount = originalPrice.multiply(discount); totalAmount = originalPrice.multiply(discount)
.divide(new BigDecimal(100), 2, RoundingMode.DOWN);
} }
default -> throw new ServiceException(PRODUCTS_DETAIL_DURATION_UNIT_NOT_SUPPORT); default -> throw new ServiceException(PRODUCTS_DETAIL_DURATION_UNIT_NOT_SUPPORT);
} }