当前位置: 首页 > news >正文

营销系统规则引擎

一、系统介绍

        规则引擎是一个用于执行营销规则的模块,其包括营销规则配置、规则校验等功能。规则引擎可以根据预先设定的条件和逻辑,自动化地执行特点的营销策略,帮助企业更好地吸引客户,增加销售和提高客户满意度。

        规则引擎功能列表:

              1、规则装配 - 根据活动类型组装不同营销规则

              2、逻辑设计 - 支持与、或、非等复杂逻辑关系。

              3、配置校验 - 支持对活动规则进行自动化校验。

二、技术实现

1.UserCenterRegistryActivityRule - 个人中心注册活动规则

class UserCenterRegistryActivityRule extends ActivityRule{public UserCenterRegistryActivityRule(){super("region_rule&channel_rule&(user_group_rule|user_tag_rule)");}public String rootRulePath(){return "usercenter_registry_activity";}
}

2.ActivityRule - 活动规则抽象

public abstract class ActivityRule implements RuleItem{/*** 规则表达式*/private String ruleExpression;/*** 规则项配置校验*/@Autowiredprivate Map<String, RuleItem> ruleItemMap;public ActivityRule(String ruleExpression){this.ruleExpression = ruleExpression;}/*** 规则项校验*/public boolean apply(CalculateRequest request, PeContext peContext) {Stack<Character> opStack = new Stack<>();Stack<Boolean> resStack = new Stack<>();Set<Character> opChSet = Set.of('(', ')', '&', '|');int i = 0;// 处理右括号while (i < ruleExpression.length()) {char ch = ruleExpression.charAt(i);switch (ch) {case '(':opStack.push(ch);i++;break;case ')': while (opStack.peek() != '(') {Character opChar = opStack.peek();if (opChar == '&') {boolean right = resStack.pop();boolean left = resStack.pop();resStack.push(left && right);} else if (opChar == '|') {boolean right = resStack.pop();boolean left = resStack.pop();resStack.push(left || right);}opStack.pop();}break;case '&': // 操作符opStack.push('&');i++;break;case '|':opStack.push('|');i++;break;default: // 操作数int j = i;while (j < ruleExpression.length() && !opChSet.contains(ruleExpression.charAt(j))) {j++;}String rule = ruleExpression.substring(i, j);resStack.push(ruleItemMap.get(rule).apply(request, peContext));i = j;}}// 处理结果while (!opStack.isEmpty()) {Character opChar = opStack.peek();if (opChar == '&') {boolean right = resStack.pop();boolean left = resStack.pop();resStack.push(left && right);} else if (opChar == '|') {boolean right = resStack.pop();boolean left = resStack.pop();resStack.push(left || right);}opStack.pop();}return resStack.pop();}default String rootRulePath();/*** 规则配置校验*/public PathError validate(String rulePath) {if (rulePath == null){rulePath = rootRulePath();}PathError pathError = PathError.of(null, rulePath);for (Map.Entry<String, RuleItem> entry : ruleItemMap.entrySet()) {String ruleItemPath = entry.getKey();RuleItem ruleItem = entry.getValue();PathError ruleItemError = ruleItem.validate(ruleItemPath);if (ruleItemError != null) {return pathError.with(ruleItemError);}}return null;}
}

3.UserGroupRuleItem - 用户组规则项

class UserGroupRuleItem extends RuleItem{private List<String> groupsLimit;@Overridepublic PathError validate(String rulePath){PathError pathError = PathError.of(null, rulePath);if (groupsLimit == null || groupsLimit.size() == 0){return pathError.withPath("groupsLimit").withError("groupsLimit不能为空");}return null;}@Overriderpublic boolean apply(CalculateRequest req, PeContext context){UserService userService = SpringUtil.getBean(UserService.class);// 判断用户是否符合用户组规则List<String> userGroups = userService.getUserGroups(req.getUserId());if (groupsLimit.stream().anyMatch(userGroups::contains)){return true;}retrun false;}
}

4.RuleItem - 规则项定义

interface RuleItem {// 规则配置校验default PathError validate(String rulePath) {PathError pathError = new PathError(null, rulePath);// 校验规则字段Field[] fields = FieldUtils.getSpecFields(getClass(), RuleItem.class);if (fields.length == 0) {return null;}try {for (Field ruleField : fields) {RuleItem rule = (Rule) FieldUtils.getField(this, ruleField);if (rule == null){continue;}String fieldName = ruleField.getName();// 规则字段校验失败PathError fieldPathError = rule.validate(fieldName);// 返回字段校验失败结果if (fieldPathError != null) {return pathError.with(fieldPathError);}}} catch (Exception e) {throw new AppException(ErrorCode.SYSTEM_ERROR, String.format("校验Rule错误: %s", e.getMessage()));}return null;}// 规则应用default boolean apply(CalculateRequest request, PeContext peContext){return true;};@Data@NoArgsConstructor@AllArgsConstructorpublic static class PathError{private String error;private List<String> paths;public PathError with(PathError other){this.error = other.error;this.paths.addAll(other.paths);return this;}public PathError withError(String error){this.error = error;return this;}public PathError withPath(String path){this.paths.add(path);return this;}}
}

相关文章:

营销系统规则引擎

一、系统介绍 规则引擎是一个用于执行营销规则的模块&#xff0c;其包括营销规则配置、规则校验等功能。规则引擎可以根据预先设定的条件和逻辑&#xff0c;自动化地执行特点的营销策略&#xff0c;帮助企业更好地吸引客户&#xff0c;增加销售和提高客户满意度。 规则引擎功能…...

【Linux】命令行参数

文章目录 前言一、C语言main函数的参数二、环境变量总结 前言 我们在Linux命令行输入命令的时候&#xff0c;一般都会跟上一些参数选项&#xff0c;比如l命令&#xff0c;ls -a -l。以前我总是觉得这是理所当然的&#xff0c;没深究其本质究竟是什么&#xff0c;今天才终于知道…...

【信息安全】-个人敏感信息、个人信息、个人金融信息

文章目录 个人敏感信息个人敏感信息判定举例 个人信息个人信息判定举例 个人金融信息内容a) 账户信息指账户及账户相关信息b) 鉴别信息c) 金融交易信息d) 个人身份信息e) 财产信息f) 借贷信息g) 其他信息: 出处 个人敏感信息 个人敏感信息判定 个人敏感信息是指一旦泄露、非法…...

海外服务器和国内服务器有什么样的区别呢

海外服务器和国内服务器有什么样的区别呢&#xff0c;其实呢在外形方面是大同小异&#xff0c;除了外形还有一些其他方面还存在这一些差异。 一&#xff0c;地理位置的差异。 海外服务器——有可能在中国数据中心之外的任何国家地区&#xff0c;例如美国服务器&#xff0c;韩…...

电脑屏幕亮度怎么调?学会4个方法,轻松调节亮度!

“我总是感觉我电脑屏幕太暗了&#xff0c;有时候如果光线好一点&#xff0c;会看不清电脑屏幕。有什么可以把电脑调亮一点的简单方法吗&#xff1f;” 在我们的日常生活中&#xff0c;电脑已经成为我们工作、学习、娱乐不可或缺的工具。然而&#xff0c;长时间面对电脑屏幕可能…...

微信小程序之猜数字和猜拳小游戏

目录 效果图 app.json 一、首页&#xff08;index3&#xff09;的代码 wxml代码 wxss代码 二、猜数字页面&#xff08;index&#xff09;代码 wxml代码 wxss代码 js代码 三.游戏规则页面&#xff08;logs&#xff09;代码 wxml代码 wxss代码 四.猜拳页面&#xff…...

CETN01 - How to Use Cloud Classroom

文章目录 I. Introduction to Cloud ClassroomII. How to Use Cloud Classroom1. Publish Resources2. Conduct Activities3. Class Teaching Reports4. View Experience Values5. Performance in Cloud Classroom I. 云课堂介绍II. 如何使用云课堂1. 发布资源2. 进行活动3. 班…...

安卓8预装可卸载应用

环境 系统&#xff1a;Android 8 CPU:MTK 理论上改法适用于其他平台&#xff0c;比如展讯。 不适用于安卓11。安卓11请参照android 11预装APP到data/app目录 实现 假设要内置test这个应用。 第一步把test添加到系统编译配置中&#xff0c;不同平台或cpu文件不一样。 比如&am…...

微服务实战系列之MemCache

前言 书接前文&#xff0c;马不停蹄&#xff0c;博主继续书写Cache的传奇和精彩。 Redis主要用于数据的分布式缓存&#xff0c;通过设置缓存集群&#xff0c;实现数据的快速响应&#xff0c;同时也解决了缓存一致性的困扰。 EhCache主要用于数据的本地缓存&#xff0c;因无法保…...

解决服务端渲染程序SSR运行时报错: ReferenceError: document is not defined

现象&#xff1a; 原因&#xff1a; 该错误表明在服务端渲染 (SSR) 过程中&#xff0c;有一些代码尝试在没有浏览器环境的情况下执行与浏览器相关的操作。这在服务端渲染期间是一个常见的问题&#xff0c;因为在服务端渲染期间是没有浏览器 API。 解决办法&#xff1a; 1. 修…...

【漏洞复现】狮子鱼任意文件上传漏洞

漏洞描述 狮子鱼CMS(Content Management System)是一种网站管理系统,旨在帮助用户更轻松地创建和管理网站。它具有用户友好的界面和丰富的功能,包括页面管理、博客、新闻、产品展示等。 狮子鱼CMS使用简单直观的管理界面,使得网站所有者可以方便地进行内容的发布、管理和…...

LINUX 下部署github仓库

打开tumx django-admin startproject project_name #创建django项目 project_name配置git ssh-keygen # 生成密钥 连接 github 在github中打开setting 添加密钥 并且允许 write access git init # 把当前文件夹配置为git仓库 git config --global user.name xxx git config --g…...

CentOS中安装数据库

1.下载 网址&#xff1a;https://dev.mysql.com/downloads/mysql/ 按如图选择&#xff0c;然后点击Download 这里它让我们登录&#xff0c;我们直接选择不登录&#xff0c;直接下载 2.关闭防火墙 systemctl disable firewalld3.正式安装 切换到/usr/local下 cd /usr/l…...

GPT-Crawler一键爬虫构建GPTs知识库

GPT-Crawler一键爬虫构建GPTs知识库 写在最前面安装node.js安装GPT-Crawler启动爬虫结合 OpenAI自定义 assistant自定义 GPTs&#xff08;笔者用的这个&#xff09; 总结 写在最前面 GPT-Crawler一键爬虫构建GPTs知识库 能够爬取网站数据&#xff0c;构建GPTs的知识库&#xf…...

在微信小程序中如何改变默认打开的页面

在微信小程序中&#xff0c;在我们编写页面的时候&#xff0c;可能会在重新渲染的时候导致页面跳转到默认打开的页面上&#xff0c;为了提升用户的一个体验&#xff0c;我们可以设置一些内容来修改小程序默认打开的页面&#xff0c;提升开发者的开发体验。 当我们打开一个微信…...

Ardupilot开源飞控之VTOL之旅:配件试装

Ardupilot开源飞控之VTOL之旅&#xff1a;配件试装 1. 源由2. 分析2.1 【修改使用】FC & PDB & GPS打印件2.2 【直接使用】VTX & CRSF打印件 3. 试装3.1 【结构】问题1&#xff1a;GPS座子尺寸非常紧凑&#xff0c;需要用力压入卡座内。3.2 【结构】问题2&#xff…...

STM32-GPIO

一、GPIO简介 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口 可配置8种输入输出模式 引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V 输出模式下&#xff1a;可控制端口输出高低电平&#xff0c;用以驱动LED、控制蜂鸣器、模拟通信协议输…...

MySQL的事务

<!DOCTYPE html> <html> <head> <meta charset"UTF-8" /> <title>MySQL的事务</title> </head> <body> <!-- 事务是一组操作的集合&#xff0c;它是一个不可分隔的工作单位&#xff0c;事务会把所有的操作作…...

go-carbon v2.2.14 发布,轻量级、语义化、对开发者友好的 Golang 时间处理库

carbon 是一个轻量级、语义化、对开发者友好的 golang 时间处理库&#xff0c;支持链式调用。 目前已被 awesome-go 收录&#xff0c;如果您觉得不错&#xff0c;请给个 star 吧 github.com/golang-module/carbon gitee.com/golang-module/carbon 安装使用 Golang 版本大于…...

解决 IIS HTTP 403 错误问题

最近上传附件 IIS 总是返回 HTTP 403 错误,在踩了很多配置的坑之后,终于把问题解决了,于是特意写了本篇文章。 虽然网络上的文章不少,大都写的没错,但是他们没有很清晰的把问题描述清楚,导致一些新手在看这些文章跟着处理问题的时候难免会踩坑,于是我就以我踩坑的经验写…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...