优惠券系统-第一章-系统设计

article/2025/10/29 0:35:20

优惠券系统介绍

         优惠券在很多系统会用到,本文结合项目实战谈谈优惠券系统怎么做。分为四个章节,第一个章节只介绍优惠券的设计,在第二章介绍优惠券的领取与补券,第三章设计一个类似京东的领券中心、活动中心,第四章聊聊优惠券使用。

优惠券整体流程图

       优惠券整体流程使用流程如下图所示。注:下面这个图来自网络。

       

      如上图所示,优惠券是先新建,然后由系统领导或者财务相关人员审核通过,再绑定活动发放出去。实际使用情况一般是运营小姐姐发邮件申请活动,审批通过后开发小哥哥直接配置线上活动,没有审批这个环节,这个环节比较简单,后面就不多介绍了。

优惠券设计

      优惠券的设计原则就是尽量使单独的业务分割开来,首先就可以想到优惠券本身是一张表,我们叫做coupon_base,其次还需要一张用户表与优惠券的关联表,来记录用户与优惠券的关系叫做coupon_user,这里为了解耦业务,如果过多信息(比如用户)放在coupon_base上,后面表会无法控制的变大。

      有了这两个表讨论一个问题,就是优惠券肯定是每个用户领完后有自己的券,所以量会很大。那么优惠券是先生成后给用户领取,还是用户领取的时候给用户生成呢?肯定是先生成后给用户领取,因为用户领取是一个高并发的操作,不宜做过多的业务逻辑进去,尽量简化用户领券的逻辑,简化成一个步骤最好,那就是从提前生成的"券池"中拿一个券SN号即可。

      选择了将券生成后给用户领,每次配券只需要配一个券的模板,指定券的数量,然后开始生成,就需要一个模板表。这个表的名字可以是coupon_model或者coupon_act,这里我用的coupon_act。一共三张表,coupon_act记录了优惠券基本,coupon_base保存了生成后的券,coupon_user记录用户和券的关系。如下图所示:

     第一张表coupon_act表,里面coupon_num是要生成的券数量,act_status是状态,coupon_money_min是优惠券使用的最低门栏,就是所谓的“满减金额”,订单满coupon_money_min即可减去coupon_value金额。这里注意类型coupon_type如果是“直接券”类型,即可不限制满减,直接抵扣订单金额,可以根据你的业务需求加类型,笔者只用到这两种。

CREATE TABLE `coupon_act` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号',`act_sn` varchar(50) NOT NULL COMMENT '活动码',`coupon_name` varchar(255) DEFAULT NULL COMMENT '活动名称',`coupon_desc` varchar(255) DEFAULT NULL COMMENT '活动描述',`act_status` int(11) NOT NULL COMMENT '活动状态 1:未启用 2:已启用 3:已中止 4:已过期 5 生成中',`coupon_num` int(11) NOT NULL DEFAULT '0' COMMENT '优惠券数量',`limit_type` int(4) NOT NULL DEFAULT '0' COMMENT '1 固定时间范围过期,2 领券后固定时间过期',`limit_day` int(4) NOT NULL DEFAULT '0' COMMENT '优惠券限制使用天数:0不限制',`coupon_type` int(11) DEFAULT NULL COMMENT '优惠券类型 1:满减卷 2: 直减券',`coupon_money_min` int(11) DEFAULT NULL COMMENT '最少使用金额 0:不限制(单位:分,依赖coupon_type)',`coupon_money_max` int(11) DEFAULT NULL COMMENT '最大使用金额 0:不限制(单位:分,依赖coupon_type)',`coupon_value` int(11) NOT NULL DEFAULT '0' COMMENT '优惠券面值',`coupon_start_time` datetime DEFAULT NULL COMMENT '优惠券开始时间',`coupon_end_time` datetime DEFAULT NULL COMMENT '优惠券结束时间',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',PRIMARY KEY (`id`) USING BTREE,UNIQUE KEY `IDXU_coupon_activity_act_sn` (`act_sn`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='优惠券主表';

下面是第二张表coupon_base,记录生成后的券,字段大部分继承自coupon_act(主表,也称之为模板表)。优惠券的coupon_sn号是生成时产生的分布式唯一ID,刚生成完coupon_status状态是1,被领取后是2,已使用与过期是4。coupon_base表还记录领取时间和使用时间。

CREATE TABLE `coupon_base` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号',`act_sn` varchar(50) NOT NULL COMMENT '活动编号',`coupon_sn` varchar(50) NOT NULL COMMENT '优惠券号',`coupon_name` varchar(255) DEFAULT NULL COMMENT '优惠券名称',`coupon_desc` varchar(255) DEFAULT NULL COMMENT '优惠券描述',`coupon_status` int(11) DEFAULT '1' COMMENT '优惠券状态 1:未领取 2:已领取,未使用  3:已使用 4:已过期 5:已冻结 6:已作废',`coupon_type` int(11) DEFAULT NULL COMMENT '优惠券类型 1:满减卷 2: 直减券',`coupon_money_min` int(11) DEFAULT NULL COMMENT '最少使用金额 0:不限制(单位:分,依赖coupon_type)',`coupon_money_max` int(11) DEFAULT NULL COMMENT '最大使用金额 0:不限制(单位:分,依赖coupon_type)',`coupon_value` int(11) NOT NULL DEFAULT '0' COMMENT '优惠券面值',`coupon_start_time` datetime DEFAULT NULL COMMENT '优惠券开始时间',`coupon_end_time` datetime DEFAULT NULL COMMENT '优惠券结束时间',`draw_time` datetime DEFAULT NULL COMMENT '领取时间',`use_time` datetime DEFAULT NULL COMMENT '使用时间',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',PRIMARY KEY (`id`) USING BTREE,UNIQUE KEY `unx_coupon_base_sn` (`coupon_sn`),KEY `idx_act_sn_coupon_status` (`act_sn`,`coupon_status`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='优惠券主表';

还有一张表是coupon_user,记录用户领取优惠券的信息,其中biz_source记录用户领券途径,可能是用户参与活动领取,biz_code记录某个活动id号,还一种情况可能是手动给某个用户补偿券,这个字段根据自身需求拓展。

CREATE TABLE `coupon_user` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号',`coupon_sn` varchar(50) NOT NULL COMMENT '优惠券号',`biz_code` varchar(50) DEFAULT NULL COMMENT '活动来源码',`biz_source` int(11) DEFAULT '0' COMMENT '业务来源:1活动领取,2手动赠送',`user_id` varchar(50) DEFAULT NULL COMMENT '用户ID',`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',PRIMARY KEY (`id`) USING BTREE,KEY `idx_user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户领卷表';

优惠券的生成与装载

       优惠券先生成后领取必然有一个问题需要处理就是"领重"问题,防止多个用户同时取得同一个券。我们将生成的券放入redis中,以list存储。每次用户从缓存中取券,我们只将券的SN号放入list队列。并不是全部放入redis,可以一次放几千张,部分代码参见如下。

//生成优惠券代码
public DataTransferObject<Void> startCouponActivity(Integer id) {DataTransferObject<Void> dto = new DataTransferObject();//取得coupon_act中的券模板CouponActivityEntity entity = couponActivityServiceImpl.getCouponActivity(id);try {//防止重复点击keyString sendKey = PromotionCacheConstant.COUPON_PRODUCT_KEY + id;long result = redisOperations.setnx(sendKey,"1");if (result != 1) {return new DataTransferObject("优惠券生成中,请勿操作");}redisOperations.expire(sendKey,PromotionCacheConstant.COUPON_PRODUCT_TIME);//由于生成券耗时,这里用的异步生成taskExecutor.execute(() -> {LogUtil.info(LOGGER,"生成券任务开始执行了,couponActId:{}",entity.getId());List<CouponBaseEntity> allCouponBaseEntityList = Collections.emptyList();try {//修改coupon_act状态,生成中CouponActivityRequest updateEntity = new CouponActivityRequest();updateEntity.setId(entity.getId());updateEntity.setActStatus(CouponActStatusEnum.PRODUCING.getCode());couponActivityServiceImpl.updateCouponActivity(updateEntity);//生成券,这个方法里面就是批量插入allCouponBaseEntityList = couponActivityServiceImpl.startCouponActivity(entity);//生成完毕后,修改coupon_act状态updateEntity.setCouponNum(entity.getCouponNum());updateEntity.setActStatus(CouponActStatusEnum.PRODUCED.getCode());couponActivityServiceImpl.updateCouponActivity(updateEntity);} catch (Exception e) {LogUtil.error(LOGGER,"生成券优惠券活动异常,{}",e);} finally {//删除防止并发的keyredisOperations.del(sendKey);//加载优惠券缓存队列if(!Check.NuNCollection(allCouponBaseEntityList)){couponBaseService.fillCacheCouponSnQueueForCreate(entity.getActSn(), allCouponBaseEntityList);}}});} catch (Exception e) {dto.setErrorMsg("生成券优惠券活动异常");}return dto;}

 上面就是生成优惠券的代码,在finally代码块中有“fillCacheCouponSnQueueForCreate”方法就是将生成券加入到缓存中,详细代码见下面。

//将生成的券,加入缓存
public void fillCacheCouponSnQueueForCreate(String actSn, List<CouponBaseEntity> appendList){try{//如果无可用券,放入缓存标志位,用余判断某个券是否用完,不查库,直接查缓存if(Check.NuNCollection(appendList)){redisOperations.set(PromotionCacheConstant.getCacheCouponOverKey(actSn),PromotionCacheConstant.COMMON_LABEL);LogUtil.warn(logger, "可用优惠券已使用完("+actSn+")");return;}//有券,删除keyredisOperations.del(PromotionCacheConstant.getCacheCouponOverKey(actSn));if(!Check.NuNCollection(appendList)){String couponBaseQueueKey = PromotionCacheConstant.getCacheCouponQueueKey(actSn);appendList.parallelStream().forEach(base->{//缓存注意,是两步操作,将每个券的详情放入缓存,再将券号放入list队列,后面当用户领取时,直接从缓存中查券的信息,然后也将缓存删除redisOperations.set(base.getCouponSn(), JsonEntityTransform.Object2Json(base));redisOperations.lpush(couponBaseQueueKey,base.getCouponSn());});}} catch (Exception e){LogUtil.error(logger,"填充优惠券码队列失败,error:{}",e);}}

上面的代码,说明了券的生成和向redis的队列中加载券。下一章介绍优惠券的领取与补券。


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

相关文章

优惠券系统思考

一 序&#xff1a; 有个老的优惠券系统业务侧要接手重构&#xff0c;听了下评审&#xff0c;还是觉得有些着急&#xff0c;产品没有想好想要&#xff0c;就开始设计原型。好的需求文档&#xff1a;我觉得要分几部分&#xff1a;系统概述、名词术语定义&#xff0c;整体流程&…

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

作者&#xff1a;vivo互联网开发团队-Yan Chao 一、业务背景 优惠券是电商常见的营销手段&#xff0c;具有灵活的特点&#xff0c;既可以作为促销活动的载体&#xff0c;也是重要的引流入口。优惠券系统是vivo商城营销模块中一个重要组成部分&#xff0c;早在15年vivo商城还是单…

谈谈优惠券系统的设计

优惠券系统的核心在于各种券种的管理&#xff0c;发放和使用。 通常的设计角度是从终端用户出发&#xff0c;所谓“所见即所得”&#xff0c;终端用户所见到的形形色色的优惠券&#xff0c;正是开发整个系统的挑战所在。 可以想象&#xff0c;为了配合不同形式的线上、线下活…

优惠券系统开发设计

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

促销#卡券系统基本设计

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

如何设计一个优惠券系统

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

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

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

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

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

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

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

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

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

python封装成exe

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

python如何封装成exe

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

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

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

将Python文件转化为exe文件

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

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

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

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

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

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

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

把py转化成exe(干货)

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

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

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

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

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