规则引擎之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 实体类
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; // 折扣价格
}
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 流程上下文
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 流程启动节点 
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 满减策略节点
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 折扣策略节点
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  确认优惠券策略节点
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 确认邮费节点
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 创建订单节点
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 配置文件

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

5. 测试

   @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.结果

相关推荐

  1. golang 规则引擎gengine

    2024-04-13 22:08:02       45 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-13 22:08:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-13 22:08:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-13 22:08:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-13 22:08:02       20 阅读

热门阅读

  1. skynet中newservice和uniqueservice的区别

    2024-04-13 22:08:02       15 阅读
  2. ChatGPT革新学术写作:论文撰写的新思路

    2024-04-13 22:08:02       18 阅读
  3. shell脚本启动jar包

    2024-04-13 22:08:02       14 阅读
  4. C语言隐藏执行其他程序

    2024-04-13 22:08:02       14 阅读
  5. openjudge_2.5基本算法之搜索_1756:八皇后

    2024-04-13 22:08:02       12 阅读
  6. 预训练的启蒙:浅谈BERT、RoBERTa、ALBERT、T5

    2024-04-13 22:08:02       14 阅读
  7. P1085 [NOIP2004 普及组] 不高兴的津津

    2024-04-13 22:08:02       14 阅读
  8. 前端面试复习大纲

    2024-04-13 22:08:02       14 阅读
  9. 单片机家电产品--OC门电路

    2024-04-13 22:08:02       17 阅读
  10. 岛屿个数(dfs)

    2024-04-13 22:08:02       11 阅读
  11. 用户层read write io命令到NVMe SSD全流程

    2024-04-13 22:08:02       13 阅读
  12. 华为OD-C卷-考勤信息[100分]

    2024-04-13 22:08:02       14 阅读
  13. 面试经典150题 删除有序数组中的重复项 II

    2024-04-13 22:08:02       12 阅读