规则引擎之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 {@Overridepublic 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 {@Overridepublic 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减去30if (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 {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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. 测试

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/624206.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

平台系统的微信支付服务突然不可用问题记录

背景 我们平台系统的微信支付突然不可用&#xff0c;用户点击支付都提示错误“系统繁忙”。 排查 查看日志&#xff0c;发现“支付聚合服务”调用“微信支付服务”的http请求返回read timeout&#xff0c;问题很显然出在“微信支付服务”。http请求报read timeout&#xff0…

OpenAI宣布GPT-4-Turbo全面升级,GPT-4 Turbo 新增视觉理解能力,可同时处理文本和图像信息

OpenAI宣布GPT-4-Turbo全面升级&#xff0c;GPT-4 Turbo with Vision新增视觉理解能力&#xff0c;可同时处理文本和图像信息&#xff0c;极大简化了开发流程。 OpenAI宣布GPT-4 Turbo全面升级&#xff01;根据官方说法&#xff0c;这一波 GPT 的升级包括&#xff1a; 更长的上…

由于找不到krpt.dll,无法继续执行代码的5种解决方法

在正常使用电脑的过程中&#xff0c;当尝试启动某个应用程序或者执行特定功能时&#xff0c;系统突然弹出一个错误提示窗口&#xff0c;明确指出由于缺失关键性文件——krpt.dll&#xff0c;导致当前运行的软件无法正常读取并执行相应的程序代码&#xff0c;进而无法顺利完成预…

初级软件测试常见问题

1.JMeter &#xff08;1&#xff09;在http请求的时候&#xff0c;消息体数据中的数据需要用{}和“”标记起来&#xff0c;变量要用${}括起来。 &#xff08;2&#xff09;在响应断言的时候&#xff0c;要根据测试模式输出的内容来改变测试字段&#xff0c;假如输出错误可以把…

根据ELK官网指引部署ELK- ECK-Elastic-​ Kibana​-Learn-ELK-(一)

**Attention: 1、You need open the ELK official website and step by step to deploy . 2、If you copy my command ,you must check them if it not match your environment . 一、official website Elastic documentation | Elastic Check there. 二、 ECK简介…

Token2049主办方遭遇假门票风波,韩国罗马基金会Charles Lee损失50万美元

加密货币——遍地黄金&#xff1f;还是遍地陷阱&#xff1f; 尽管伊朗空袭以色列导致中东局势愈发紧张&#xff0c;但加密社区对当地市场的热情丝毫没有受到影响&#xff0c;不出意外的话&#xff0c;Token 2049这场全球最受瞩目的加密货币盛会将于4月18至19日在迪拜如期举行&…

Apifox接口测试教程(一)接口测试的原理与工具

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

vs2019 - detected memory leak

文章目录 vs2019 - detected memory leak概述笔记vs2019 consolevs2019 MFC Dlg但是&#xff0c;工程大了之后&#xff0c;VS2019提示的就变了样整好的内存泄漏侦测头文件和实现my_debug_new_define.hmy_debug_new_define.cpp在所有.cpp文件入口处包含my_debug_new_define.h包含…

商家转账到零钱全攻略:开通、使用、区别与常见问题解答

商家转账到零钱是什么&#xff1f; 【商家转账到零钱】可以说是【企业付款到零钱】的升级版&#xff0c;商家转账到零钱可以为商户提供同时向多个用户微信零钱转账的能力&#xff0c;支持分销返佣、佣金报酬、企业报销、企业补贴、服务款项、采购货款等自动向用户转账的场景。…

ctf.show_web13

上传一句话木马 1.php文件&#xff0c;显示 再改后缀为.jpg&#xff0c;显示错误文件大小 用dirsearch扫一下 备份文件.bak 下载文件源码 <?php header("content-type:text/html;charsetutf-8");$filename $_FILES[file][name];$temp_name $_FILES[file][tm…

fork()的一道面试题

前言&#xff1a;题源 #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <sys/wait.h> int main(void) {int i;for(i0; i<2; i){fork();printf("-");}wait(NULL);wait(NULL);return 0; }知道一点fork()这个系统…

C++:Static

1 在内存中所在的位置 回想C程序中内存的划分是什么呢&#xff1f;从上到下首先是内核空间&#xff0c;然后是栈内存&#xff0c;内存映射段&#xff0c;堆&#xff0c;数据段&#xff0c;和代码段。用一张图的解释就是&#xff1a; 在这里主要探讨static&#xff0c;因此主要…