You've already forked FrameTour-BE
feat(pricing): 添加券码管理和使用功能
- 新增券码批次配置和券码实体 - 实现券码创建、领取、使用等接口 - 添加券码状态和优惠类型枚举 - 优化价格计算逻辑,支持券码优惠 - 新增优惠检测和应用相关功能
This commit is contained in:
@@ -3,7 +3,7 @@ package com.ycwl.basic.pricing.dto;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 优惠券使用结果DTO
|
||||
@@ -29,7 +29,7 @@ public class CouponUseResult {
|
||||
/**
|
||||
* 使用时间
|
||||
*/
|
||||
private LocalDateTime useTime;
|
||||
private Date useTime;
|
||||
|
||||
/**
|
||||
* 优惠金额
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.ycwl.basic.pricing.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 优惠组合结果
|
||||
*/
|
||||
@Data
|
||||
public class DiscountCombinationResult {
|
||||
|
||||
/**
|
||||
* 原始金额
|
||||
*/
|
||||
private BigDecimal originalAmount;
|
||||
|
||||
/**
|
||||
* 最终金额
|
||||
*/
|
||||
private BigDecimal finalAmount;
|
||||
|
||||
/**
|
||||
* 总优惠金额
|
||||
*/
|
||||
private BigDecimal totalDiscountAmount;
|
||||
|
||||
/**
|
||||
* 应用的优惠列表(按优先级排序)
|
||||
*/
|
||||
private List<DiscountResult> appliedDiscounts;
|
||||
|
||||
/**
|
||||
* 可用但未应用的优惠列表
|
||||
*/
|
||||
private List<DiscountInfo> availableDiscounts;
|
||||
|
||||
/**
|
||||
* 优惠详情列表(用于展示)
|
||||
*/
|
||||
private List<DiscountDetail> discountDetails;
|
||||
|
||||
/**
|
||||
* 计算是否成功
|
||||
*/
|
||||
private Boolean success;
|
||||
|
||||
/**
|
||||
* 错误信息(如果success为false)
|
||||
*/
|
||||
private String errorMessage;
|
||||
}
|
||||
@@ -44,7 +44,7 @@ public class DiscountDetail {
|
||||
detail.setDiscountName("限时立减");
|
||||
detail.setDiscountAmount(discountAmount);
|
||||
detail.setDescription("限时优惠,立即享受");
|
||||
detail.setSortOrder(1); // 限时立减排在最前面
|
||||
detail.setSortOrder(2); // 限时立减排在券码后面
|
||||
return detail;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,20 @@ public class DiscountDetail {
|
||||
detail.setDiscountName(couponName);
|
||||
detail.setDiscountAmount(discountAmount);
|
||||
detail.setDescription("优惠券减免");
|
||||
detail.setSortOrder(2); // 优惠券排在限时立减后面
|
||||
detail.setSortOrder(3); // 优惠券排在限时立减后面
|
||||
return detail;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建券码折扣明细
|
||||
*/
|
||||
public static DiscountDetail createVoucherDiscount(String voucherCode, String discountTypeName, BigDecimal discountAmount) {
|
||||
DiscountDetail detail = new DiscountDetail();
|
||||
detail.setDiscountType("VOUCHER");
|
||||
detail.setDiscountName("券码优惠");
|
||||
detail.setDiscountAmount(discountAmount);
|
||||
detail.setDescription(String.format("券码 %s - %s", voucherCode, discountTypeName));
|
||||
detail.setSortOrder(1); // 券码优先级最高,排在最前面
|
||||
return detail;
|
||||
}
|
||||
|
||||
@@ -70,7 +83,7 @@ public class DiscountDetail {
|
||||
detail.setDiscountName("一口价优惠");
|
||||
detail.setDiscountAmount(discountAmount);
|
||||
detail.setDescription("一口价购买更优惠");
|
||||
detail.setSortOrder(3); // 一口价排在最后
|
||||
detail.setSortOrder(4); // 一口价排在最后
|
||||
return detail;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.ycwl.basic.pricing.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 优惠检测上下文
|
||||
*/
|
||||
@Data
|
||||
public class DiscountDetectionContext {
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 用户faceId
|
||||
*/
|
||||
private Long faceId;
|
||||
|
||||
/**
|
||||
* 景区ID
|
||||
*/
|
||||
private Long scenicId;
|
||||
|
||||
/**
|
||||
* 商品列表
|
||||
*/
|
||||
private List<ProductItem> products;
|
||||
|
||||
/**
|
||||
* 当前金额
|
||||
*/
|
||||
private BigDecimal currentAmount;
|
||||
|
||||
/**
|
||||
* 用户主动输入的券码
|
||||
*/
|
||||
private String voucherCode;
|
||||
|
||||
/**
|
||||
* 是否自动使用优惠券
|
||||
*/
|
||||
private Boolean autoUseCoupon;
|
||||
|
||||
/**
|
||||
* 是否自动使用券码
|
||||
*/
|
||||
private Boolean autoUseVoucher;
|
||||
}
|
||||
82
src/main/java/com/ycwl/basic/pricing/dto/DiscountInfo.java
Normal file
82
src/main/java/com/ycwl/basic/pricing/dto/DiscountInfo.java
Normal file
@@ -0,0 +1,82 @@
|
||||
package com.ycwl.basic.pricing.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 优惠信息DTO
|
||||
*/
|
||||
@Data
|
||||
public class DiscountInfo {
|
||||
|
||||
/**
|
||||
* 优惠ID
|
||||
*/
|
||||
private Long discountId;
|
||||
|
||||
/**
|
||||
* 优惠类型(COUPON, VOUCHER等)
|
||||
*/
|
||||
private String discountType;
|
||||
|
||||
/**
|
||||
* 优惠名称
|
||||
*/
|
||||
private String discountName;
|
||||
|
||||
/**
|
||||
* 优惠描述
|
||||
*/
|
||||
private String discountDescription;
|
||||
|
||||
/**
|
||||
* 优惠金额
|
||||
*/
|
||||
private BigDecimal discountAmount;
|
||||
|
||||
/**
|
||||
* 原始优惠值(用于百分比折扣等)
|
||||
*/
|
||||
private BigDecimal originalValue;
|
||||
|
||||
/**
|
||||
* 优惠值类型(PERCENTAGE, FIXED_AMOUNT等)
|
||||
*/
|
||||
private String valueType;
|
||||
|
||||
/**
|
||||
* 最小消费金额限制
|
||||
*/
|
||||
private BigDecimal minAmount;
|
||||
|
||||
/**
|
||||
* 最大优惠金额限制
|
||||
*/
|
||||
private BigDecimal maxDiscount;
|
||||
|
||||
/**
|
||||
* 优惠提供者类型
|
||||
*/
|
||||
private String providerType;
|
||||
|
||||
/**
|
||||
* 优惠优先级
|
||||
*/
|
||||
private Integer priority;
|
||||
|
||||
/**
|
||||
* 是否可与其他优惠叠加
|
||||
*/
|
||||
private Boolean stackable;
|
||||
|
||||
/**
|
||||
* 券码(如果是voucher类型)
|
||||
*/
|
||||
private String voucherCode;
|
||||
|
||||
/**
|
||||
* 优惠券ID(如果是coupon类型)
|
||||
*/
|
||||
private Long couponId;
|
||||
}
|
||||
43
src/main/java/com/ycwl/basic/pricing/dto/DiscountResult.java
Normal file
43
src/main/java/com/ycwl/basic/pricing/dto/DiscountResult.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package com.ycwl.basic.pricing.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 优惠应用结果
|
||||
*/
|
||||
@Data
|
||||
public class DiscountResult {
|
||||
|
||||
/**
|
||||
* 应用的优惠信息
|
||||
*/
|
||||
private DiscountInfo discountInfo;
|
||||
|
||||
/**
|
||||
* 实际优惠金额
|
||||
*/
|
||||
private BigDecimal actualDiscountAmount;
|
||||
|
||||
/**
|
||||
* 应用后的金额
|
||||
*/
|
||||
private BigDecimal finalAmount;
|
||||
|
||||
/**
|
||||
* 是否成功应用
|
||||
*/
|
||||
private Boolean success;
|
||||
|
||||
/**
|
||||
* 失败原因(如果success为false)
|
||||
*/
|
||||
private String failureReason;
|
||||
|
||||
/**
|
||||
* 影响的商品项(用于商品级别的优惠)
|
||||
*/
|
||||
private List<ProductItem> affectedProducts;
|
||||
}
|
||||
@@ -24,4 +24,29 @@ public class PriceCalculationRequest {
|
||||
* 是否自动使用优惠券
|
||||
*/
|
||||
private Boolean autoUseCoupon = true;
|
||||
|
||||
/**
|
||||
* 用户输入的券码
|
||||
*/
|
||||
private String voucherCode;
|
||||
|
||||
/**
|
||||
* 景区ID(用于券码验证)
|
||||
*/
|
||||
private Long scenicId;
|
||||
|
||||
/**
|
||||
* 用户faceId(用于券码领取资格验证)
|
||||
*/
|
||||
private Long faceId;
|
||||
|
||||
/**
|
||||
* 是否自动使用券码优惠
|
||||
*/
|
||||
private Boolean autoUseVoucher = true;
|
||||
|
||||
/**
|
||||
* 是否仅预览优惠(不实际使用)
|
||||
*/
|
||||
private Boolean previewOnly = false;
|
||||
}
|
||||
@@ -37,10 +37,20 @@ public class PriceCalculationResult {
|
||||
private CouponInfo usedCoupon;
|
||||
|
||||
/**
|
||||
* 折扣明细列表(包含限时立减、优惠券、一口价等)
|
||||
* 使用的券码信息
|
||||
*/
|
||||
private VoucherInfo usedVoucher;
|
||||
|
||||
/**
|
||||
* 折扣明细列表(包含限时立减、优惠券、券码、一口价等)
|
||||
*/
|
||||
private List<DiscountDetail> discountDetails;
|
||||
|
||||
/**
|
||||
* 可用但未使用的优惠列表(预览时使用)
|
||||
*/
|
||||
private List<DiscountInfo> availableDiscounts;
|
||||
|
||||
/**
|
||||
* 商品明细列表
|
||||
*/
|
||||
|
||||
84
src/main/java/com/ycwl/basic/pricing/dto/VoucherInfo.java
Normal file
84
src/main/java/com/ycwl/basic/pricing/dto/VoucherInfo.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package com.ycwl.basic.pricing.dto;
|
||||
|
||||
import com.ycwl.basic.pricing.enums.VoucherDiscountType;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 券码信息DTO
|
||||
*/
|
||||
@Data
|
||||
public class VoucherInfo {
|
||||
|
||||
/**
|
||||
* 券码ID
|
||||
*/
|
||||
private Long voucherId;
|
||||
|
||||
/**
|
||||
* 券码
|
||||
*/
|
||||
private String voucherCode;
|
||||
|
||||
/**
|
||||
* 批次ID
|
||||
*/
|
||||
private Long batchId;
|
||||
|
||||
/**
|
||||
* 批次名称
|
||||
*/
|
||||
private String batchName;
|
||||
|
||||
/**
|
||||
* 景区ID
|
||||
*/
|
||||
private Long scenicId;
|
||||
|
||||
/**
|
||||
* 推客ID
|
||||
*/
|
||||
private Long brokerId;
|
||||
|
||||
/**
|
||||
* 优惠类型
|
||||
*/
|
||||
private VoucherDiscountType discountType;
|
||||
|
||||
/**
|
||||
* 优惠值
|
||||
*/
|
||||
private BigDecimal discountValue;
|
||||
|
||||
/**
|
||||
* 实际优惠金额
|
||||
*/
|
||||
private BigDecimal actualDiscountAmount;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 领取时间
|
||||
*/
|
||||
private Date claimedTime;
|
||||
|
||||
/**
|
||||
* 使用时间
|
||||
*/
|
||||
private Date usedTime;
|
||||
|
||||
/**
|
||||
* 是否可用
|
||||
*/
|
||||
private Boolean available;
|
||||
|
||||
/**
|
||||
* 不可用原因
|
||||
*/
|
||||
private String unavailableReason;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.ycwl.basic.pricing.dto.req;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
public class VoucherBatchCreateReq {
|
||||
private String batchName;
|
||||
private Long scenicId;
|
||||
private Long brokerId;
|
||||
private Integer discountType;
|
||||
private BigDecimal discountValue;
|
||||
private Integer totalCount;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.ycwl.basic.pricing.dto.req;
|
||||
|
||||
import com.ycwl.basic.model.common.BaseQueryParameterReq;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class VoucherBatchQueryReq extends BaseQueryParameterReq {
|
||||
private Long scenicId;
|
||||
private Long brokerId;
|
||||
private Integer status;
|
||||
private String batchName;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.ycwl.basic.pricing.dto.req;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class VoucherClaimReq {
|
||||
private Long scenicId;
|
||||
private Long brokerId;
|
||||
private Long faceId;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.ycwl.basic.pricing.dto.req;
|
||||
|
||||
import com.ycwl.basic.model.common.BaseQueryParameterReq;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class VoucherCodeQueryReq extends BaseQueryParameterReq {
|
||||
private Long batchId;
|
||||
private Long scenicId;
|
||||
private Long faceId;
|
||||
private Integer status;
|
||||
private String code;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.ycwl.basic.pricing.dto.resp;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class VoucherBatchResp {
|
||||
private Long id;
|
||||
private String batchName;
|
||||
private Long scenicId;
|
||||
private Long brokerId;
|
||||
private Integer discountType;
|
||||
private String discountTypeName;
|
||||
private BigDecimal discountValue;
|
||||
private Integer totalCount;
|
||||
private Integer usedCount;
|
||||
private Integer claimedCount;
|
||||
private Integer availableCount;
|
||||
private Integer status;
|
||||
private String statusName;
|
||||
private Date createTime;
|
||||
private Long createBy;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.ycwl.basic.pricing.dto.resp;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class VoucherBatchStatsResp {
|
||||
private Long batchId;
|
||||
private String batchName;
|
||||
private Integer totalCount;
|
||||
private Integer claimedCount;
|
||||
private Integer usedCount;
|
||||
private Integer availableCount;
|
||||
private Double claimedRate;
|
||||
private Double usedRate;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.ycwl.basic.pricing.dto.resp;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class VoucherCodeResp {
|
||||
private Long id;
|
||||
private Long batchId;
|
||||
private String batchName;
|
||||
private Long scenicId;
|
||||
private String code;
|
||||
private Integer status;
|
||||
private String statusName;
|
||||
private Long faceId;
|
||||
private Date claimedTime;
|
||||
private Date usedTime;
|
||||
private String remark;
|
||||
private Date createTime;
|
||||
|
||||
private Integer discountType;
|
||||
private String discountTypeName;
|
||||
private String discountDescription;
|
||||
private BigDecimal discountValue;
|
||||
}
|
||||
Reference in New Issue
Block a user