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

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

高防服务器价格高原因分析

高防服务器的价格较高&#xff0c;主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因&#xff1a; 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器&#xff0c;因此…...

Axure Rp 11 安装、汉化、授权

Axure Rp 11 安装、汉化、授权 1、前言2、汉化2.1、汉化文件下载2.2、windows汉化流程2.3、 macOs汉化流程 3、授权 1、前言 Axure Rp 11官方下载链接&#xff1a;https://www.axure.com/downloadthanks 2、汉化 2.1、汉化文件下载 链接: https://pan.baidu.com/s/18Clf…...

java 局域网 rtsp 取流 WebSocket 推送到前端显示 低延迟

众所周知 摄像头取流推流显示前端延迟大 传统方法是服务器取摄像头的rtsp流 然后客户端连服务器 中转多了&#xff0c;延迟一定不小。 假设相机没有专网 公网 1相机自带推流 直接推送到云服务器 然后客户端拉去 2相机只有rtsp &#xff0c;边缘服务器拉流推送到云服务器 …...