当前位置: 首页 > 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 错误,在踩了很多配置的坑之后,终于把问题解决了,于是特意写了本篇文章。 虽然网络上的文章不少,大都写的没错,但是他们没有很清晰的把问题描述清楚,导致一些新手在看这些文章跟着处理问题的时候难免会踩坑,于是我就以我踩坑的经验写…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

boost::filesystem::path文件路径使用详解和示例

boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类&#xff0c;封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解&#xff0c;包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...