feat(pricing): 优惠券增加有效期时间范围功能

- 在VoucherBatchCreateReqV2、VoucherBatchResp、VoucherInfo 和 PriceVoucherBatchConfig 类中添加有效期开始时间和结束时间字段
- 实现有效期时间范围的验证和检查逻辑
- 更新 VoucherBatchServiceImpl 和 VoucherServiceImpl 以支持有效期时间范围功能
This commit is contained in:
2025-09-16 23:49:39 +08:00
parent 1506ae95b8
commit 6006fe460c
6 changed files with 132 additions and 2 deletions

View File

@@ -123,4 +123,45 @@ public class VoucherInfo {
* 最后使用时间 * 最后使用时间
*/ */
private Date lastUsedTime; private Date lastUsedTime;
/**
* 有效期开始时间
*/
private Date validStartTime;
/**
* 有效期结束时间
*/
private Date validEndTime;
/**
* 检查指定时间是否在有效期内
* @param checkTime 待检查的时间
* @return true-在有效期内,false-不在有效期内
*/
public boolean isWithinValidTimeRange(Date checkTime) {
if (checkTime == null) {
return false;
}
// 检查开始时间
if (validStartTime != null && checkTime.before(validStartTime)) {
return false;
}
// 检查结束时间
if (validEndTime != null && checkTime.after(validEndTime)) {
return false;
}
return true;
}
/**
* 检查当前时间是否在有效期内
* @return true-在有效期内,false-不在有效期内
*/
public boolean isWithinValidTimeRange() {
return isWithinValidTimeRange(new Date());
}
} }

View File

@@ -7,6 +7,7 @@ import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
@@ -70,4 +71,14 @@ public class VoucherBatchCreateReqV2 {
* 两次使用间隔小时数(NULL表示无间隔限制) * 两次使用间隔小时数(NULL表示无间隔限制)
*/ */
private Integer useIntervalHours; private Integer useIntervalHours;
/**
* 有效期开始时间(NULL表示无开始时间限制)
*/
private Date validStartTime;
/**
* 有效期结束时间(NULL表示无结束时间限制)
*/
private Date validEndTime;
} }

View File

@@ -30,4 +30,14 @@ public class VoucherBatchResp {
* null表示适用所有商品类型 * null表示适用所有商品类型
*/ */
private List<ProductType> applicableProducts; private List<ProductType> applicableProducts;
/**
* 有效期开始时间
*/
private Date validStartTime;
/**
* 有效期结束时间
*/
private Date validEndTime;
} }

View File

@@ -115,6 +115,49 @@ public class PriceVoucherBatchConfig {
private Date deletedAt; private Date deletedAt;
/**
* 有效期开始时间(NULL表示无开始时间限制)
*/
@TableField("valid_start_time")
private Date validStartTime;
/**
* 有效期结束时间(NULL表示无结束时间限制)
*/
@TableField("valid_end_time")
private Date validEndTime;
/**
* 检查当前时间是否在有效期内
* @return true-在有效期内,false-不在有效期内
*/
public boolean isWithinValidTimeRange() {
return isWithinValidTimeRange(new Date());
}
/**
* 检查指定时间是否在有效期内
* @param checkTime 待检查的时间
* @return true-在有效期内,false-不在有效期内
*/
public boolean isWithinValidTimeRange(Date checkTime) {
if (checkTime == null) {
return false;
}
// 检查开始时间
if (validStartTime != null && checkTime.before(validStartTime)) {
return false;
}
// 检查结束时间
if (validEndTime != null && checkTime.after(validEndTime)) {
return false;
}
return true;
}
/** /**
* 获取适用商品类型列表 * 获取适用商品类型列表
*/ */

View File

@@ -118,6 +118,13 @@ public class VoucherBatchServiceImpl implements VoucherBatchService {
throw new BizException(400, "使用间隔小时数不能为负数"); throw new BizException(400, "使用间隔小时数不能为负数");
} }
// 验证时间范围参数
if (req.getValidStartTime() != null && req.getValidEndTime() != null) {
if (req.getValidStartTime().after(req.getValidEndTime())) {
throw new BizException(400, "有效期开始时间不能晚于结束时间");
}
}
PriceVoucherBatchConfig batch = new PriceVoucherBatchConfig(); PriceVoucherBatchConfig batch = new PriceVoucherBatchConfig();
BeanUtils.copyProperties(req, batch); BeanUtils.copyProperties(req, batch);

View File

@@ -85,13 +85,27 @@ public class VoucherServiceImpl implements IVoucherService {
return null; return null;
} }
VoucherInfo voucherInfo = buildVoucherInfo(voucherCodeEntity, batchConfig);
// 检查券码批次的时间范围,提供详细的时间范围信息
if (!batchConfig.isWithinValidTimeRange()) {
voucherInfo.setAvailable(false);
Date now = new Date();
if (batchConfig.getValidStartTime() != null && now.before(batchConfig.getValidStartTime())) {
voucherInfo.setUnavailableReason("券码尚未生效");
} else if (batchConfig.getValidEndTime() != null && now.after(batchConfig.getValidEndTime())) {
voucherInfo.setUnavailableReason("券码已过期");
} else {
voucherInfo.setUnavailableReason("券码不在有效期内");
}
return voucherInfo;
}
// 验证景区匹配 // 验证景区匹配
if (scenicId != null && !scenicId.equals(voucherCodeEntity.getScenicId())) { if (scenicId != null && !scenicId.equals(voucherCodeEntity.getScenicId())) {
return null; return null;
} }
VoucherInfo voucherInfo = buildVoucherInfo(voucherCodeEntity, batchConfig);
// 检查券码状态和可用性,包含完整的重复使用权限验证 // 检查券码状态和可用性,包含完整的重复使用权限验证
if (VoucherCodeStatus.UNCLAIMED.getCode().equals(voucherCodeEntity.getStatus())) { if (VoucherCodeStatus.UNCLAIMED.getCode().equals(voucherCodeEntity.getStatus())) {
// 未领取状态,也需要检查用户的重复使用权限 // 未领取状态,也需要检查用户的重复使用权限
@@ -718,6 +732,10 @@ public void markVoucherAsUsed(String voucherCode, String remark, String orderId,
voucherInfo.setUseIntervalHours(batchConfig.getUseIntervalHours()); voucherInfo.setUseIntervalHours(batchConfig.getUseIntervalHours());
voucherInfo.setLastUsedTime(voucherCode.getLastUsedTime()); voucherInfo.setLastUsedTime(voucherCode.getLastUsedTime());
// 设置时间范围信息
voucherInfo.setValidStartTime(batchConfig.getValidStartTime());
voucherInfo.setValidEndTime(batchConfig.getValidEndTime());
// 计算剩余可使用次数 // 计算剩余可使用次数
if (batchConfig.getMaxUseCount() != null) { if (batchConfig.getMaxUseCount() != null) {
int remaining = batchConfig.getMaxUseCount() - currentUseCount; int remaining = batchConfig.getMaxUseCount() - currentUseCount;