规则引擎之LiteFlow应用

官网地址:LiteFlow

DEMO 整体结构

1.引入maven依赖

复制代码
<dependency>
    <groupId>com.yomahub</groupId>
    <artifactId>liteflow-spring-boot-starter</artifactId>
    <version>2.11.4.2</version>
</dependency>

2. 配置yml

复制代码
liteflow:
  #规则文件路径
  rule-source: config/flow.el.xml

3. 模拟商品订单流程,下单-->计算优惠->计算邮费->总价-> 创建订单

3.0 实体类
java 复制代码
package com.example.demo.domain;

import lombok.Data;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author Jerry
 * @date 2024-04-10 16:15
 * 订单
 */
@Data
public class Order {

    private String orderId; // 订单号
    private List<Product> productList; // 商品列表
    private BigDecimal amount; // 总价
    private BigDecimal shippingCost; // 折扣价格
}
java 复制代码
package com.example.demo.domain;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.math.BigDecimal;

/**
 * @author Jerry
 * @date 2024-04-10 16:13
 */
@Data
@AllArgsConstructor
public class Product {

    private String productType; // 商品类型
    private String productName; // 商品名称
    private BigDecimal price; // 商品价格
}
3.1 流程上下文
java 复制代码
package com.example.demo.liteflow;

import com.example.demo.domain.Order;
import com.example.demo.domain.Product;
import lombok.Data;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Jerry
 * @date 2024-04-10 16:19
 * 订单流程规则上下文
 */
@Data
public class OrderProcessFlowContext {
    private List<Product> productList = new ArrayList<>(); // 商品列表
    private Order order; // 订单
    private Map<String, BigDecimal> strategyMap = new HashMap<>(); // 优惠策略
}
3.2 流程启动节点
java 复制代码
package com.example.demo.liteflow.node;

import cn.hutool.core.lang.UUID;
import com.example.demo.domain.Order;
import com.example.demo.liteflow.OrderProcessFlowContext;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * @author Jerry
 * @date 2024-04-10 16:08
 * 优惠券计算组件
 */
@Slf4j
@Component
@LiteflowComponent(id = "initOrderNode", name = "流程启动节点") // id - 在流程中的名称
public class InitOrderNode extends NodeComponent {


    @Override
    public void process() throws Exception {
        OrderProcessFlowContext contextBean = this.getContextBean(OrderProcessFlowContext.class);
        Order order = new Order();
        order.setOrderId(UUID.fastUUID().toString());
        order.setProductList(contextBean.getProductList());
        contextBean.setOrder(order);
        log.info("流程启动");
    }
}
3.3 满减策略节点
java 复制代码
package com.example.demo.liteflow.node.strategy;

import com.example.demo.domain.Product;
import com.example.demo.liteflow.OrderProcessFlowContext;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author Jerry
 * @date 2024-04-10 16:30
 * 满减策略
 */
@Slf4j
@Component
@LiteflowComponent(id = "free", name = "满减策略节点")
public class Free extends NodeComponent {

    @Override
    public void process() throws Exception {
        OrderProcessFlowContext contextBean = this.getContextBean(OrderProcessFlowContext.class);
        List<Product> productList = contextBean.getProductList();
        BigDecimal amount = new BigDecimal(0);
        for (Product product : productList) {
            amount = amount.add(product.getPrice());
        }
        // 满200减去30
        if (amount.intValue() >= 200) {
            amount = amount.subtract(new BigDecimal(30));
        }
        log.info("满减后商品总价:{}", amount.floatValue());
        contextBean.getStrategyMap().put("FREE", amount);
    }
}
3.4 折扣策略节点
java 复制代码
package com.example.demo.liteflow.node.strategy;

import com.example.demo.domain.Product;
import com.example.demo.liteflow.OrderProcessFlowContext;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * @author Jerry
 * @date 2024-04-10 16:37
 */
@Slf4j
@Component
@LiteflowComponent(id = "discount", name = "打折策略节点")
public class Discount extends NodeComponent {

    @Override
    public void process() throws Exception {
        OrderProcessFlowContext contextBean = this.getContextBean(OrderProcessFlowContext.class);
        List<Product> productList = contextBean.getProductList();
        BigDecimal amount = new BigDecimal(0);
        for (Product product : productList) {
            if ("零食".equals(product.getProductType())) {
                amount = amount.add(product.getPrice().multiply(new BigDecimal("0.8")));
            } else if ("电器".equals(product.getProductType())) {
                amount = amount.add(product.getPrice().multiply(new BigDecimal("0.6")));
            } else {
                amount = amount.add(product.getPrice());
            }
            amount = amount.setScale(2, RoundingMode.UP);
            log.info("折扣后商品总价:{}", amount.floatValue());
            contextBean.getStrategyMap().put("DISCOUNT", amount);
        }
    }
}
3.5 确认优惠券策略节点
java 复制代码
package com.example.demo.liteflow.node;

import com.example.demo.liteflow.OrderProcessFlowContext;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Comparator;
import java.util.Map;
import java.util.Optional;

/**
 * @author Jerry
 * @date 2024-04-10 16:44
 * 优惠券计算抵扣组件
 */
@Slf4j
@Component
@LiteflowComponent(id = "confirmStrategyNode", name = "确认优惠券策略节点")
public class ConfirmStrategyNode extends NodeComponent {

    @Override
    public void process() throws Exception {
        OrderProcessFlowContext contextBean = this.getContextBean(OrderProcessFlowContext.class);
        Map<String, BigDecimal> strategyMap = contextBean.getStrategyMap();
        Map.Entry<String, BigDecimal> min = strategyMap.entrySet().stream().min(Map.Entry.comparingByValue()).get();
        log.info("优惠策略已确认:{}", min.getValue());
        contextBean.getOrder().setAmount(min.getValue());
    }
}
3.6 确认邮费节点
java 复制代码
package com.example.demo.liteflow.node;

import com.example.demo.domain.Order;
import com.example.demo.liteflow.OrderProcessFlowContext;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * @author Jerry
 * @date 2024-04-10 17:06
 * 邮费计算
 */
@Slf4j
@Component
@LiteflowComponent(id = "confirmShippingCostNode", name = "确认邮费节点")
public class ConfirmShippingCostNode extends NodeComponent {
    @Override
    public void process() throws Exception {
        OrderProcessFlowContext contextBean = this.getContextBean(OrderProcessFlowContext.class);
        Order order = contextBean.getOrder();
        if (order.getAmount().intValue() > 68) {
            order.setShippingCost(new BigDecimal(0));
        } else {
            order.setShippingCost(new BigDecimal(10));
        }
        log.info("邮费已确认:{}", order.getShippingCost());
    }
}
3.7 创建订单节点
java 复制代码
package com.example.demo.liteflow.node;

import com.example.demo.domain.Order;
import com.example.demo.liteflow.OrderProcessFlowContext;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * @author Jerry
 * @date 2024-04-10 17:11
 */
@Slf4j
@Component
@LiteflowComponent(id = "createOrderNode", name = "创建订单节点")
public class CreateOrderNode extends NodeComponent {
    @Override
    public void process() throws Exception {
        OrderProcessFlowContext contextBean = this.getContextBean(OrderProcessFlowContext.class);
        Order order = contextBean.getOrder();
        log.info("订单创建成功:{}", order);
    }
}

4. flow.el.xml 配置文件

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<flow>
    <chain name="orderChain">
        THEN(
        initOrderNode,
        WHEN(free,discount),
        confirmStrategyNode,
        confirmShippingCostNode,
        createOrderNode);
    </chain>
</flow>

5. 测试

java 复制代码
   @Resource
    private FlowExecutor flowExecutor;

    @GetMapping("liteFlow")
    public String testLiteFlow() {
        OrderProcessFlowContext processFlowContext = new OrderProcessFlowContext();
        processFlowContext.getProductList().add(new Product("零食", "辣条", new BigDecimal(50)));
        processFlowContext.getProductList().add(new Product("电器", "洗衣机", new BigDecimal(200)));
        LiteflowResponse response = flowExecutor.execute2Resp("orderChain", null, processFlowContext);
        OrderProcessFlowContext context = response.getContextBean(OrderProcessFlowContext.class);
        if (response.isSuccess()) {
            return "success :" + JSONUtil.toJsonStr(context.getOrder());
        } else {
            return "error";
        }
    }

6.结果

相关推荐
reiraoy5 分钟前
缓存解决方案
java
安之若素^19 分钟前
启用不安全的HTTP方法
java·开发语言
ruanjiananquan9926 分钟前
c,c++语言的栈内存、堆内存及任意读写内存
java·c语言·c++
chuanauc1 小时前
Kubernets K8s 学习
java·学习·kubernetes
一头生产的驴1 小时前
java整合itext pdf实现自定义PDF文件格式导出
java·spring boot·pdf·itextpdf
YuTaoShao1 小时前
【LeetCode 热题 100】73. 矩阵置零——(解法二)空间复杂度 O(1)
java·算法·leetcode·矩阵
zzywxc7871 小时前
AI 正在深度重构软件开发的底层逻辑和全生命周期,从技术演进、流程重构和未来趋势三个维度进行系统性分析
java·大数据·开发语言·人工智能·spring
YuTaoShao4 小时前
【LeetCode 热题 100】56. 合并区间——排序+遍历
java·算法·leetcode·职场和发展
程序员张34 小时前
SpringBoot计时一次请求耗时
java·spring boot·后端
llwszx7 小时前
深入理解Java锁原理(一):偏向锁的设计原理与性能优化
java·spring··偏向锁