采用责任链+策略模式处理不同产品类型的佣金计算逻辑
设计了灵活的多级分销佣金计算规则引擎,支持20+种佣金计算规则
在分销场景中,佣金计算是个复杂的业务,主要涉及多级渠道分佣、团队分佣、个人分佣等场景。我们设计了一个灵活的佣金计算引擎来处理这些复杂的规则。
1.传统方式实现(不使用规则引擎):
public class TraditionalCommissionService {
public BigDecimal calculateCommission(Order order) {
// 基础佣金
BigDecimal commission = BigDecimal.ZERO;
// 计算基础佣金
if (order.getProductType().equals("枚举:一类分销员")) {
commission = order.getAmount().multiply(new BigDecimal("0.1"));
} else if (order.getProductType().equals("枚举:二类分销员")) {
commission = order.getAmount().multiply(new BigDecimal("0.15"));
}
// 计算团队奖励
if (order.getTeamPerformance().compareTo(new BigDecimal("1000000")) > 0) {
commission = commission.add(order.getAmount().multiply(new BigDecimal("0.01")));
}
// 计算渠道奖励
if (order.getChannelLevel().equals("A")) {
commission = commission.add(order.getAmount().multiply(new BigDecimal("0.02")));
} else if (order.getChannelLevel().equals("B")) {
commission = commission.add(order.getAmount().multiply(new BigDecimal("0.015")));
}
// 更多的if-else...
return commission;
}
}
这种传统方式的问题:
- 代码臃肿:随着规则增加,if-else嵌套越来越多
- 难维护:修改一个规则可能需要改动多处代码
- 不灵活:规则修改需要改代码重新发布
- 难扩展:新增规则需要修改原有代码
- 业务耦合:业务规则和代码逻辑混在一起
2.使用规则引擎的方式:
// 1. 领域模型定义
public class TeamPerformanceBonusRule implements CommissionRule {
private static final BigDecimal PERFORMANCE_THRESHOLD = new BigDecimal("1000000");
private static final BigDecimal BONUS_RATE = new BigDecimal("0.01");
@Override
public BigDecimal calculate(Order order) {
Agent agent = order.getAgent();
if (agent.getMonthlyPerformance().compareTo(PERFORMANCE_THRESHOLD) > 0) {
return order.getAmount().multiply(BONUS_RATE);
}
return BigDecimal.ZERO;
}
@Override
public String getRuleName() {
return "团队业绩奖励规则";
}
}
// 3.4 渠道奖励规则
public class ChannelBonusRule implements CommissionRule {…}
// 3.5 新人奖励规则
public class NewAgentBonusRule implements CommissionRule {…}
// 4. 佣金计算结果
public class CommissionResult {…}
// 5. 规则链处理器
@Slf4j
public class CommissionRuleChain {
private final List<CommissionRule> rules = new ArrayList<>();
public CommissionRuleChain() {
// 按照处理顺序添加规则
rules.add(new BaseCommissionRule());
rules.add(new AgentLevelBonusRule());
rules.add(new TeamPerformanceBonusRule());
rules.add(new ChannelBonusRule());
rules.add(new NewAgentBonusRule());
}
public CommissionResult calculateCommission(Order order) {
CommissionResult result = new CommissionResult();
result.setOrderId(order.getOrderId());
result.setAgentId(order.getAgent().getAgentId());
result.setAgentName(order.getAgent().getName());
result.setOrderAmount(order.getAmount());
result.setCalculateTime(LocalDateTime.now());
for (CommissionRule rule : rules) {
try {
BigDecimal ruleCommission = rule.calculate(order);
result.addRuleResult(rule.getRuleName(), ruleCommission);
log.debug("规则[{}]计算结果: {}", rule.getRuleName(), ruleCommission);
} catch (Exception e) {
log.error("规则[{}]计算异常: {}", rule.getRuleName(), e.getMessage());
}
}
return result;
}
}
// 6. 佣金规则引擎服务
public class CommissionRuleEngineService {
private final CommissionRuleChain ruleChain = new CommissionRuleChain();
public CommissionResult calculateCommission(Order order) {
log.info("开始计算订单[{}]的佣金,代理人:{}", order.getOrderId(), order.getAgent().getName());
CommissionResult result = ruleChain.calculateCommission(order);
log.info("订单[{}]佣金计算完成,总佣金:{}", order.getOrderId(), result.getTotalCommission());
return result;
}
}
使用示例:
public class CommissionCalculationExample {
public static void main(String[] args) {
// 创建代理人
Agent agent = new Agent();
agent.setAgentId("AG001");
agent.setName("张三");
agent.setLevel("专家");
agent.setChannelLevel("A");
agent.setTeamId("TEAM001");
agent.setMonthlyPerformance(new BigDecimal("2000000"));
agent.setJoinTime(LocalDateTime.now().minusDays(30));
agent.setNewAgent(true);
// 创建订单
Order order = new Order();
order.setOrderId("ORD" + LocalDateTime.now().format(DateTimeFormatter.BASIC_ISO_DATE) + "001");
order.setProductType("枚举:一类分销员");
order.setAmount(new BigDecimal("100000"));
order.setCreateTime(LocalDateTime.now());
order.setAgent(agent);
// 用规则引擎计算佣金
CommissionRuleEngineService service = new CommissionRuleEngineService();
CommissionResult result = service.calculateCommission(order);
// 输出结果
System.out.println(result.toString());
}
}
运行结果:
开始计算订单ORD20241220001的佣金,代理人:张三
规则基础佣金规则计算结果: 10000.0
规则代理人等级奖励规则计算结果: 5000.00
规则团队业绩奖励规则计算结果: 1000.00
规则渠道奖励规则计算结果: 2000.00
规则新人奖励规则计算结果: 2000.00
订单ORD20241220001佣金计算完成,总佣金:20000.00
佣金计算结果明细:
订单号:ORD20241220001
代理人:张三(AG001)
订单金额:¥100000
规则计算明细:
- 基础佣金规则: ¥10000.0
- 代理人等级奖励规则: ¥5000.00
- 团队业绩奖励规则: ¥1000.00
- 渠道奖励规则: ¥2000.00
- 新人奖励规则: ¥2000.00
总佣金:¥20000.00
这个实现的优点:
- 代码结构清晰,每个规则独立封装
- 易于添加新规则,不需要修改现有代码
- 规则的执行顺序可控
- 便于单元测试
- 规则配置可以轻松扩展为从配置文件或数据库加载
总的来说,规则引擎特别适合分销这种业务规则复杂、经常变动的场景。它通过将业务规则从代码中抽离出来,实现了规则的灵活配置和管理,大大提高了系统的可维护性和扩展性。