leniu-marketing-price-rule-customizer
SKILL.md
leniu-tengyun-core 营销计费规则定制
概述
leniu-tengyun-core 项目的营销计费(price)规则功能采用扩展点设计,支持灵活的规则定制。
营销计费规则是营销系统的核心组件,负责计算订单的优惠金额、限制消费行为、提供补贴等功能。
何时使用此 Skill
- 需要新增一个计价规则类型
- 需要修改现有规则的计算逻辑
- 需要为规则添加新的配置字段
- 需要针对特定项目定制规则行为
- 参考现有规则实现新的定制需求
规则定制工作流
步骤1:确定定制模式
根据需求选择合适的定制模式:
模式A:新增规则
- 适用场景:创建全新的规则类型
- 需要创建:DTO、扩展接口、默认实现
模式B:重写规则(@Primary)
- 适用场景:完全替换现有规则行为
- 需要创建:定制实现类(使用@Primary注解)
- 可选:扩展DTO字段
模式C:重写规则(Ordered)
- 适用场景:多个实现共存
- 需要创建:定制实现类(实现Ordered接口)
步骤2:理解规则结构
了解:
- 规则接口层次(RulePriceHandler → Extension → Implementation)
- 规则DTO结构
- 规则计算入参(RulePriceResultOrderDTO、MarketRuleVO、orderResults)
- 规则计算流程
- 常用工具类(MarketUtil、MarketRuleRangeService)
步骤3:参考实际案例
查看实际案例,了解如何实现具体的定制需求:
- 案例1:支持自定义场景类型选择(@Primary + DTO扩展)
- 案例2:移除订单类型过滤(直接修改)
步骤4:实现规则定制
新增规则的实现步骤
-
创建规则DTO
- 位置:
net.xnzn.core.marketing.v2.rule.price.handler.[ruletype].dto - 包含规则配置字段
- 实现
toString()方法返回可读描述
- 位置:
-
创建扩展接口
- 位置:
net.xnzn.core.marketing.v2.rule.price.handler.[ruletype].extension - 继承
RulePriceHandler - 实现
getRuleType()和checkRuleInfo()方法
- 位置:
-
创建默认实现
- 位置:
net.xnzn.core.marketing.v2.rule.price.handler.[ruletype].extension.impl - 实现扩展接口
- 添加
@Service注解 - 实现
handle()方法
- 位置:
-
注册规则枚举
- 在
RulePriceEnum中添加新的规则类型
- 在
重写规则的实现步骤(@Primary模式)
-
(可选)扩展DTO字段
- 在定制项目中覆盖核心DTO类
- 添加新字段并保持向后兼容
-
创建定制实现
- 位置:定制项目包(如
net.xnzn.yunshitang.marketing.handler) - 继承默认实现类(可选,用于复用逻辑)
- 实现扩展接口
- 添加
@Service和@Primary注解 - 重写
handle()方法
- 位置:定制项目包(如
-
实现定制逻辑
- 解析规则配置(包含新字段)
- 实现自定义计算逻辑
- 更新订单优惠金额或抛出限制异常
步骤5:测试规则
- 测试向后兼容性(新字段为null的场景)
- 测试新功能(新字段有值的场景)
- 测试边界条件
- 测试与其他规则的组合使用
代码模板
新增规则模板
// 1. DTO
@Data
@ApiModel("计价规则详情-[规则名称]")
public class [RuleType]DTO {
@ApiModelProperty("[字段说明]")
private [Type] fieldName;
@Override
public String toString() {
return "字段:" + fieldName;
}
}
// 2. 扩展接口
public interface [RuleType]HandlerExtension extends RulePriceHandler {
@Override
default Integer getRuleType() {
return RulePriceEnum.[RULE_TYPE_ENUM].getKey();
}
@Override
default String checkRuleInfo(String ruleInfo) {
[RuleType]DTO rule = JSON.parseObject(ruleInfo, [RuleType]DTO.class);
return rule.toString();
}
}
// 3. 默认实现
@Slf4j
@Service
public class Default[RuleType]HandlerImpl implements [RuleType]HandlerExtension {
@Autowired
private MarketRuleRangeService rangeService;
@Override
public void handle(RulePriceResultOrderDTO order, MarketRuleVO rule,
List<RulePriceResultOrderDTO> orderResults) {
// 1. 解析规则配置
[RuleType]DTO ruleInfo = JSON.parseObject(rule.getRuleInfo(), [RuleType]DTO.class);
// 2. 查询规则适用范围
List<MarketRuleRange> rangeList = rangeService.listRuleRangeLatest(rule.getRuleId());
// 3. 实现规则计算逻辑
// ...
// 4. 更新订单优惠金额或抛出异常
order.setDiscountsAmount(order.getDiscountsAmount().add(discountAmount));
}
}
重写规则模板(@Primary)
@Slf4j
@Service
@Primary // 标记为主要实现
public class Custom[RuleType]HandlerImpl extends Default[RuleType]HandlerImpl
implements [RuleType]HandlerExtension {
@Autowired
private MarketRuleRangeService rangeService;
@Override
public void handle(RulePriceResultOrderDTO order, MarketRuleVO rule,
List<RulePriceResultOrderDTO> orderResults) {
// 解析规则配置(可能包含扩展字段)
[RuleType]DTO ruleInfo = JSON.parseObject(rule.getRuleInfo(), [RuleType]DTO.class);
// 实现定制逻辑
// 可以调用父类方法:super.handle(order, rule, orderResults);
// 或完全自定义实现
}
}
常见规则类型
优惠类规则
- 折扣规则:
PriceDiscountHandlerExtension - 菜品折扣:
PriceDishDiscountHandlerExtension - 商品折扣:
PriceGoodsDiscountHandlerExtension - 满减规则:
PriceReductionFixedHandlerExtension
限制类规则
- 限额-单次金额:
PriceLimitMaxAmountHandlerExtension - 限额-累计次数:
PriceLimitMaxCountHandlerExtension - 限额-累计金额:
PriceLimitSumAmountHandlerExtension
补贴类规则
- 固定补贴:
PriceSubsidyFixedHandlerExtension - 累计赠送:
PriceSumGiveHandlerExtension
最佳实践
包名规范
- 覆盖核心类:使用核心工程的包名(
net.xnzn.core.marketing.v2.rule.price.handler.[ruletype]) - 定制实现:使用项目特定包名(如
net.xnzn.yunshitang.marketing.handler)
类名规范
- 扩展接口:
[RuleType]HandlerExtension - 默认实现:
Default[RuleType]HandlerImpl - 定制实现:
Custom[RuleType]HandlerImpl或描述性名称
注解使用
- 所有实现类必须添加
@Service注解 - 重写规则使用
@Primary注解(推荐) - 日志记录使用
@Slf4j注解
向后兼容
- 扩展DTO字段时,新字段应支持null值
- 新字段为null时应保持原有行为
- 在toString方法中包含所有字段
快速开始示例
假设需要为限额累计金额规则(PriceLimitSumAmountHandlerExtension)添加场景类型选择功能:
- 扩展DTO:在
PriceLimitSumAmountDTO中添加sceneTypes字段 - 创建定制实现:创建
CrossScenePriceLimitSumAmountHandlerImpl,位于net.xnzn.yunshitang.marketing.handler,使用@Primary注解 - 实现逻辑:在
handle()方法中使用sceneTypes字段过滤订单 - 向后兼容:
sceneTypes为null时查询所有场景
// 1. 扩展DTO(在核心工程包名下覆盖)
// 位置:net.xnzn.core.marketing.v2.rule.price.handler.limitsum.dto.PriceLimitSumAmountDTO
@Data
@ApiModel("限额-累计金额规则详情")
public class PriceLimitSumAmountDTO {
@ApiModelProperty("累计金额限额(分)")
private BigDecimal limitAmount;
// 扩展字段:场景类型列表,null时表示所有场景
@ApiModelProperty("适用场景类型(null=所有)")
private List<Integer> sceneTypes;
@Override
public String toString() {
return "limitAmount=" + limitAmount + ", sceneTypes=" + sceneTypes;
}
}
// 2. 定制实现(在yunshitang项目包下)
// 位置:net.xnzn.yunshitang.marketing.handler
@Slf4j
@Service
@Primary
public class CrossScenePriceLimitSumAmountHandlerImpl
implements PriceLimitSumAmountHandlerExtension {
@Autowired
private MarketRuleRangeService rangeService;
@Override
public void handle(RulePriceResultOrderDTO order, MarketRuleVO rule,
List<RulePriceResultOrderDTO> orderResults) {
PriceLimitSumAmountDTO ruleInfo = JSON.parseObject(
rule.getRuleInfo(), PriceLimitSumAmountDTO.class);
// 场景过滤(向后兼容:null时不过滤)
if (CollUtil.isNotEmpty(ruleInfo.getSceneTypes())
&& !ruleInfo.getSceneTypes().contains(order.getSceneType())) {
return; // 不在适用场景内,跳过
}
// 原有累计金额限额逻辑...
BigDecimal sumAmount = calcSumAmount(order, orderResults);
if (sumAmount.compareTo(ruleInfo.getLimitAmount()) >= 0) {
throw new LeException("已超出累计消费限额");
}
}
}
参考文档
Weekly Installs
3
Repository
xu-cell/ai-engi…ing-initGitHub Stars
8
First Seen
8 days ago
Security Audits
Installed on
github-copilot3
codex3
kimi-cli3
gemini-cli3
cursor3
amp3