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_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.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_YEAR_ID_FORMAT;
/**
* @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月的价格
for (int i = 1; i <= 10; i++) {
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月的价格
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");
// 自动生成定价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
private PayHandlerFactory payHandlerFactory;
@@ -264,10 +265,10 @@ public class PayOrderServiceImpl implements PayOrderService {
* @return
*/
private ProductsDetailDO analyzeProductDetail(Long productId, Long productDetailId) {
// productDetailId符合规则PPAG%d
Matcher matcher = productDetailIdPattern.matcher(String.valueOf(productDetailId));
// productDetailId符合规则month自动生成规则
Matcher matcher = productMonthDetailIdPattern.matcher(String.valueOf(productDetailId));
if (matcher.find()) {
// 取PPAG后的数字,是订购月份
// 取规则后的数字,是订购月份
String monthDuration = matcher.group(1);
ProductsDetailDO monthDetail = new ProductsDetailDO();
monthDetail.setId(productDetailId);
@@ -277,7 +278,20 @@ public class PayOrderServiceImpl implements PayOrderService {
monthDetail.setDiscount(productsDetailService.getProductDetailOneYearDiscount(productId));
return monthDetail;
} else {
return productsDetailService.validateProductDetailsExists(productDetailId);
// 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 {
return productsDetailService.validateProductDetailsExists(productDetailId);
}
}
}
@@ -89,7 +89,7 @@ public class PayProductProcessor {
private PurchaseRecordDO previousPurchaseRecord;
// 本地订购产品的开始时间
private LocalDate startTime;
private LocalDate startTime = LocalDate.now();
// 产品结束时间
private LocalDate endTime;
@@ -111,6 +111,9 @@ public class PayProductProcessor {
// 上一次订购产品的结束时间进行计算
endTime = previousPurchaseRecord.getEndTime();
endTime = calculateEndTime(productsDetailDO.getDuration(), productsDetailDO.getDurationUnit());
} else {
// 首次订购正常从今天开始累加算世界时间
endTime = addTime(startTime, productsDetailDO.getDuration(), productsDetailDO.getDurationUnit());
}
this.organAmountDO = organAmountDO;
this.organId = organId;
@@ -129,7 +132,7 @@ public class PayProductProcessor {
boolean initialPurchaseExist = ObjectUtil.isNotNull(orgInitialPurchaseRecord);
BigDecimal price;
if (initialPurchaseExist) {
price = computePrice(orgInitialPurchaseRecord, productsDetailDO);
price = computePrice();
} else {
price = computeInitialProductPayAmount();
// 首次购买记录是空,那么当前就是首次订购
@@ -725,10 +728,7 @@ public class PayProductProcessor {
.orElse(endTime);
}
// 2、订单的生效时间
startTime = today;
// 3、 计算有效期叠加的起点
// 2、 计算有效期叠加的起点
LocalDate purchaseStart;
if (today.isAfter(maxDelayEnd)) {
// 已过期 → 从今天开始累加
@@ -738,12 +738,12 @@ public class PayProductProcessor {
purchaseStart = maxDelayEnd;
}
// 加正常时间
// 3、加正常时间
if (ObjectUtil.isNotNull(duration) && durationUnit != null) {
endTime = addTime(purchaseStart, duration, durationUnit);
}
// 5. 扣掉延期天数
// 4、扣掉延期天数
long delayDays = 0L;
if (CollUtil.isNotEmpty(delayRespVOList)) {
delayDays = calculateDelayDays(startTime, delayRespVOList);
@@ -871,11 +871,9 @@ public class PayProductProcessor {
/**
* 计算有首购记录的产品价格
*
* @param orgInitialPurchaseRecord 首次购买记录
* @param productsDetailDO 本次购买产品的定价规则
* @return
*/
private BigDecimal computePrice(PurchaseRecordDO orgInitialPurchaseRecord, ProductsDetailDO productsDetailDO) {
private BigDecimal computePrice() {
// 月均单价
monthAverageAmount = orgInitialPurchaseRecord.getMonthAverageAmount();
@@ -884,6 +882,9 @@ public class PayProductProcessor {
// 定价规则的折扣
BigDecimal discount = productsDetailDO.getDiscount();
if (ObjectUtil.isNull(discount)) {
discount = BigDecimal.valueOf(100);
}
BigDecimal totalAmount;
/**
@@ -925,6 +926,9 @@ public class PayProductProcessor {
BigDecimal orgPurchasePrice = productsDO.getPrice();
// 折扣
BigDecimal discount = productsDetailDO.getDiscount();
if (ObjectUtil.isNull(discount)) {
discount = BigDecimal.valueOf(100);
}
BigDecimal totalAmount;
switch (ProductDurationUnitEnum.fromStatus(productsDetailDO.getDurationUnit())) {
@@ -932,7 +936,9 @@ public class PayProductProcessor {
// 原价
originalPrice = orgPurchasePrice.multiply(BigDecimal.valueOf(duration));
// 折扣价格 = 原价 * 折扣
totalAmount = originalPrice.multiply(discount);
totalAmount = originalPrice
.multiply(discount)
.divide(new BigDecimal(100), 2, RoundingMode.DOWN);
// 月均单价 = 折扣价格 / 10
monthAverageAmount = originalPrice.divide(new BigDecimal(10), 2, RoundingMode.DOWN);
}
@@ -942,7 +948,8 @@ public class PayProductProcessor {
// 原价
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);
}