谈谈优惠券系统的设计

article/2025/10/29 0:36:19

优惠券系统的核心在于各种券种的管理,发放和使用。

通常的设计角度是从终端用户出发,所谓“所见即所得”,终端用户所见到的形形色色的优惠券,正是开发整个系统的挑战所在。

可以想象,为了配合不同形式的线上、线下活动,优惠券系统势必有较大的改动,如何最大限度的降低改动的成本,成为了最核心的挑战。

就上述问题而言,解决的方法就是:规则与执行相隔离。

规则层,即是各类优惠券的使用限制,以及能达到的效果。

执行层,可以理解为根据规则计算最终成交价格。

对于规则层,笔者并不想将其上升到规则引擎的高度,只做适当的抽象。况且市面上的规则引擎开发框架未必能满足优惠券这一复杂的应用场景。

值得注意的是,优惠券不等同于任何形式的优惠促销活动,但却是整个营销系统的一部分。相较于优惠券,促销活动系统的实现还要更困难。本文旨在阐述怎么开发一个优惠券系统,促销活动的设计与实现不在本文的范畴了。

一、怎么生成优惠券

在生成优惠券之前,我们先来了解一下『优惠券模板』的概念。

顾名思义,按照模板去生成优惠券。

就好比工业生产流水线上的模具,只需注入原材料进行加工,即可制成成品。

因此,模板上携带了大量优惠券相关的信息,包括但不限于名称、时效性、各类优惠规则,以及优惠券面额等,模板本身也有标题,状态,创建人等基本信息。

当需要生成优惠券的时候,指定是哪套模板,然后填写准备要生成的券总数即可,亦可在生成券的环节,指定接收对象,将券的派发操作一并完成。

可能读者不禁会发问了:这样设计似乎有些多余,券模板和券实体重合的属性很多,何不直接跳过券模板的环节,直接生成优惠券呢?

这样做的原因有两个:

其一,不想重复输入相同的优惠券信息,只要输入一遍模板信息,即可实现批量生成券,能提高运营人员的工作效率;

其二,创建券模板和发送券实体是有两类不同权限的人完成的。可能更高权限的运营人员能掌握着创建模板的权限,普通的运营人员则只需要按模板发优惠券即可。

如下图,可反映出券模板和券实体的关系:
E-R

二、优惠规则的设计

上图涉及的内容基本上都能一目了然,接下来我们将重点放在优惠规则的设计上。

优惠规则无疑是优惠券系统的核心部分,能不能最大限度的适应市场运营需求,就看优惠规则实现得怎么样了。

显然,用穷尽法去实现市面上的优惠规则是不明智。

正所谓“世上唯一不变的就是变”,我们必须提炼出优惠规则的本质,才能“以不变应万变”。

笔者对市面上常见的优惠规则进行了调研,并结合自身业务需求,可以将优惠规则大致分成两大类:

1、计算型规则。形如“无门槛直降20元”,“满xx减xx”等,这些规则都暴露给终端用户,是显而易见的,让用户知晓这个优惠券是如何参与计算。

2、限制型规则。相较于计算型规则,限制型规则大多数情况下是隐性的。比如:限制某些用户领取,限制某套券模板最多能发放多少金额的优惠券,限制优惠券的渠道等。这类规则可以很好的支撑日常的运营工作。

“万物相生相克”,众多的优惠规则,也并不是都能共存的,这里就引入了规则『互斥性』的概念。当一个优惠规则与另一个优惠规则不能同时存在于一套模板里的时候,我们就认为这两个规则是互斥的,这在设计规则的时候也需要有所考虑。

其次,优惠规则也会讲究先后顺序,所以必然就带来了一个优惠规则的『优先级』属性,我们约定,数字越小,表示越优先,也就是按从小到大的顺序。

以下给出一张完整的规则表,信息量较大,笔者将做必要的解释。
规则表

规则表中,渠道限制、对象限制、金额限制和数量限制四者皆属于限制型规则,优先级排在了较前面。同时,也给出了参数说明,规则描述,相对于模板的关系以及互斥规则,这些都是一目了然的。

接下来的扣减规则和封顶规则同属于计算型规则,也算是优惠券的重中之重了。

笔者着重解释一下满减规则中的“阶梯满减”。我们平常会看到有这类说法:每满100元减10元,言下之意便是:满100元减10元,满200减20,以此类推,笔者将其称之为“阶梯满减”规则。

三、优惠规则编号的设计

规则表中有涉及好多数字,笔者设计了一套生成规则。

规则编号是int型,Java 编程语言中,int全长 32位,如下图所示:
规则编号

1、第一位是符号位,固定为0,且不允许出现 32位全是0的情况,即为正整数;

2、高8位是规则组别编号,理论上允许的数值范围是0~255,但是实际的业务规则是假设最多有15组优惠规则,每组优惠规则编号取10的倍数,范围即为 10~150;

3、第10位和11位作为备用,暂无实际用处,固定为00;

4、中间15位,存放规则组下的细则编号,允许的范围0~32767,但是实际业务规则是要达到两两互斥的目的,取值如下(以四位二进制为例):

0001

0010

0100

1000

结论:排除全为0的情况,那么有N位,就有N组两两互斥。如果组内组外互斥都考虑,那么可取值就更少了;

5、末6位存放规则组的优先级,允许的值范围是0~63,实际取值从1开始,考虑到之后会插入其他的规则组,会在每两个规则组别直接预留两个级别,初始的优先级设置为1,4,7,10,13,16…;

6、按照上述规则,根据既定的组别和优先级可以生成上表中的细则编号。

渠道限制 83888577

0 00001010 00 000000000100111 000001

用户类型限制 167775300

0 00010100 00 000000000110001 000100

指定用户限制 167776900

0 00010100 00 000000001001010 000100

总金额限制 251660487

0 00011110 00 000000000100011 000111

单位金额限制 251662535

0 00011110 00 000000001000011 000111

总量限制 335545290

0 00101000 00 000000000001111 001010

个人所获限制 335544778

0 00101000 00 000000000000111 001010

无门槛直减 419430989

0 00110010 00 000000000001001 001101

满减 419431565

0 00110010 00 000000000010010 001101

打折 419436813

0 00110010 00 000000001100100 001101

封顶规则 503323024

0 00111100 00 000000001100110 010000

四、优惠券系统程序设计

在做程序设计之前,我们必须把握住关于优惠券的三个主要动作:

1、管理。指的是对券模板的创建,规则设置,关闭等操作。当然,在给模板设置规则参数的时候,需要校验规则参数的合理性。

2、派发/领取。笔者将这两个操作进行了合并,两者的区别无非就是有没有绑定终端用户,在接口层面是可以合并的。通常,限制型规则会在此发挥作用,当触发了这两个操作的其中一个,在生成优惠券之前都将会先用限制型规则进行校验。

3、使用。就是将优惠券花出去,计算型规则会在此发挥作用,主要是判断满不满足券的使用条件,计算减免金额等。

综上,程序设计就靠这三个动作进行延展。

我们先来设计一下规则层。

根据规则表中定义的一系列规则,反映在程序中可以有两种形式:

一种是使用配置文件(通常是XML),然后程序去解析;

另一种则是直接使用枚举类(或者其他形式的类)。

第一种开发难度稍大,想做得比较强大的话,是需要花费不少功夫的。

对于优惠规则的定义和实现都是事先内置在程序中的,并不是非专业人员改变一下配置文件就能达到效果的。

所以基于此考虑,使用了第二种实现方式。如下所示即为规则定义:
这里写图片描述

Rulers含有五种重要的属性:规则编号(ruleNo),规则名称(ruleName),排序(sort),对应的Model Class对象,以及实现特定接口的serviceName。

接下来的三个方法也较为重要:通过规则编号直接找到对应的枚举,判断是否是计算型规则,规则是否有多参数,和券模板是1~*的关系就表示是多参数。

当然,也少不了持久化到数据库的各类Beans,每个Bean都会继承一个叫作SuperRule的抽象类,子类的属性都是规则表中提及到的。Rulers中的Model Class就是来自于此。由于规则较多,下面只展示SuperRule:
SuperRule
我们再来看看Service的定义:
RulerService
最顶层的BaseRuleService是规则基本的CRUD操作,使用了泛型R,继承自SuperRule。BaseRuleService有一个抽象实现,除了泛型R,还有一个Mapper(Mybatis)。

因为将规则分成了两大类,自然而然的就能派生出两个Service,分别对应计算型规则和限制型规则。

最后一个是对规则参数的校验,使用了泛型R,继承自SuperRule。

至此,接口的设计就囊括了上述所说的三种优惠券相关的操作,也就意味着,如果出现了一个新的规则,至多实现上述的三个Service(因为可能有既是限制型规则,又是计算型规则),不过大多数情况只要实现两个Service,然后在Rulers配置好此新规则即可。至于规则基本的CRUD操作,只要继承AbstractCouponRuleService,不需要额外花精力去实现。

这么多规则,自然是需要一个『工厂类』进行调度的,比如生成一个规则Bean实例,生成一个Service实例。
RulerFactory

五、总结

本文从业务设计,到程序设计,对优惠券系统做了一个比较全面清晰的阐述,如果读者正好也需要研发一个优惠券系统,这篇文章将会是很好的参考。

这里写图片描述


http://chatgpt.dhexx.cn/article/LNkiEV3P.shtml

相关文章

优惠券系统开发设计

目录 什么是优惠券系统 优惠券业务诉求 优惠券数据模型 什么是优惠券系统 优惠券系统是一种营销策略,通过发放优惠券来吸引顾客购买商品或服务。优惠券可以是折扣券、满减券、赠品券等形式,顾客在购买商品或服务时可以使用优惠券获得相应的优惠。优惠…

促销#卡券系统基本设计

整理卡券系统的分析设计,越发感悟到技术的存在是为业务服务的这句话,在这之前收集并认真学习了多个电商平台的卡券系统或功能,卡券系统是上层促销策略与底层促成交易生成有效订单的连接点,运营方面的各项策略最终是必须依托有效的…

如何设计一个优惠券系统

背景 部门为一个租房房源平台,为各个商家提供房源发布&C端曝光获客的功能,现在要构建一个优惠券系统,用于各个节假日节点进行商家营销活动。形式主要以商家在B端参与活动,对房源绑定优惠券,将租赁价格进行优惠&am…

大厂的优惠券系统是如何设计的?

1 Scenario 场景 电商系统的促销手段(Electronic Commerce Systems): 优惠券拼团砍价老带新 优惠券的种类 满减券直减券折扣券 优惠券系统的核心流程 发券 **发券的方式:**同步发送 or 异步发送 领券 谁能领? …

优惠券系统架构设计与实践

技术琐话 2022-01-20 12:03 以下文章来源于vivo互联网技术 ,作者Yan Chao vivo互联网技术. 分享 vivo 互联网技术干货与沙龙活动,推荐最新行业动态与热门会议。 一、业务背景 优惠券是电商常见的营销手段,具有灵活的特点,既可以…

python3.5 将py文件转换成EXE文件

方法其实就是利用pyinstaller和pywin32 1.安装pyinstaller 输入cmd进入windows命令提示符,如果没有设置python环境变量,则转到python安装目录的scripts目录下, 如果已经设置python环境变量,可以跳过上述步骤。然后输入 pip inst…

把python文件转exe文件 和 打包报错处理

今天,我教大家怎么把py文件转换成exe文件, 首先,我们要用到一个第三方库,他就是pyinstaller pip install pyinstaller zip包下载(CSDN)免费 Pyinstaller代码压缩包-Python文档类资源-CSDN下载 此外&am…

python封装成exe

最近写了一个小小的程序,需要进行封装exe,为了简单,就直接用了pyinstaller这个模块,对于python3.6版本的童鞋来说,简直方便的不要。下面就给大家介绍一下如何用pyinstaller去封装程序为exe程序。 首先,需要…

python如何封装成exe

python文件封装成exe 第一种:.py文件直接封装成exe第二种:整个项目封装成exe ) 第一种:.py文件直接封装成exe 1.cmd进入py文件所在的目录 备注:在py文件所在的目录下,按住shift鼠标右击,然后找到“在此处…

Python打包成exe文件_详细操作

Python打包成exe文件 前言一、安装pyinstaller1.1 安装pyinstaller,使用安装命令:1.2 如果遇到需要更新版本请输入:1.3 检查是否正确安装1.4 稍等,水一下; 二、python打包成exe文件(附带图标打包)2.1 第一种…

将Python文件转化为exe文件

第一步:首先安装相关工具 在Windos中打开命令行窗口 输入pip install pyinstaller 出现以下情况表示安装成功 第二步:打包成exe文件 若需将xxx.py文件打包,只需在终端执行: 注:终端需切换至xxx.py文件所在目录下。…

如何将python的.py文件转换为可执行的.exe文件。

首先,我写了一个print(“hello,world”).py文件。命名为hello.py保存在我的电脑C盘的C:\Users\ly目录下如图所示。 ps:尽量选择在这个文件夹下,如果选择其他盘的文件夹下,生成的.exe的dist文件夹也会出现在…

将.py文件转化为.exe文件

将.py文件转化为.exe文件首先需要第三方库 pyinstaller 1.如果没有安装pyinstaller,则在命令提示符输入 pip installer pyinstaller 如果已安装,则会显示 表示这几个都安装好了。 2.下载安装pyinstaler运行时所需windows扩展:pywin32 mham…

[272]如何把Python脚本导出为exe程序

文章目录 一.pyinstaller简介二.pyinstaller在windows下的安装三.打包四.小实例(windows下)附加 一.pyinstaller简介 pyinstaller将Python脚本打包成可执行程序,使在没有Python环境的机器上运行 最新版是pyinstaller 3.1.1。支持python2.7和…

把py转化成exe(干货)

问题提出: 无奈别人的电脑没有装python编译环境,无法运行py文件。   本教程为在window环境下,使用PyInstaller3.4将Python脚本打包成exe可执行程序。 使用命令: pip install pyinstaller   上图为成功安装效果图&#xff0…

简单3步将你的python转成exe格式

使用pyinstaller可以将你的.py文件直接转换成.exe格式,在没有部署python环境的windows机器上直接运行你的程序!! 废话不多说,直接上正文。 1. 在命令行用pip安装 pyinstaller包 pip install pyinstaller 2.下载安装pyinstaler…

.py文件转为.exe文件的方法

写完一个Python程序想给朋友看?朋友电脑里没Python运行不了? 别急,这篇文章来帮你。 把你的python文件转成exe文件,打开方便,瞬间提示一个档次。 (我个人也遇到过这样的问题,看了别人的博客解…

将Python程序打包成exe文件

我新写了一篇更加完整的文章,与这篇文章相比,它新增了两种打包方式:多python文件打包和含有资源文件的打包方式,具体请戳链接: 用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细&#x…

Python 将.py转换为.exe详解

本文是由熊猫大哥大的博客修改而来(所以就不能说是“原创”了) 原博客链接:Python学习笔记(15)-Python代码转换为exe可执行程序详解(下面会提到本文与其的一点不同) 建议看看原博客,再看此文,…

Python学习笔记(15)-Python代码转换为exe可执行程序详解

点此查看 零基础Python全栈文章目录及源码下载 本文目录 1. 简介2. pyInstaller安装配置2.1 下载PyInstaller2.2 下载后解压PyInstaller2.3 下载pywin322.4 安装pywin322.5 安装PyInstaller 3. 制作exe3.1 编写python文件3.2 将代码文件放至pyinstaller目录3.3 制作exe3.4 查看…