【Lilishop商城】No3-11.模块详细设计,促销模块(优惠券、满减、秒杀、积分)的详细设计

news2025/2/2 1:04:03

仅涉及后端,全部目录看顶部专栏,代码、文档、接口路径在: 

【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客


全篇会结合业务介绍重点设计逻辑,其中重点包括接口类、业务类,具体的结合源代码分析,读起来也不复杂~

谨慎:源代码中有一些注释是错误的,有的注释意思完全相反,有的注释对不上号,我在阅读过程中就顺手更新了,并且在我不会的地方添加了新的注释,所以在读源代码过程中一定要谨慎啊! 

目录

A1.优惠券

B1.M端(属于显式操作)

B2.S端(属于显式操作)

B3.B端(属于显式操作)

B4.consumer端(属于业务操作)

A2.券活动

B1.M端(属于显式操作)

A3.满减

B1.S端(属于显式操作)

B2.M端(属于显式操作)

 A4.秒杀

B1.M端(属于显式操作)

B2.S端(属于显式操作)

B3.B端(属于显式操作)

B4.consumer端(属于业务操作)

A5.A6.拼团和砍价(待记录)

A7.积分商品

B1.积分分类

C1.M端(属于显式操作)

 C2.B端(属于显式操作)

B2.积分商品

C1.M端(属于显式操作)

C1.B端(属于显式操作)


开始前先说一下,促销的各类管理上不是特别的难理解,只要理解各个表结构和页面需要的接口就行,重点在于促销活动的业务service类底层都是实现自一个接口,因为所有的促销都是有相似的通用逻辑(例如,增加促销、修改促销、初始化等等)。

A1.优惠券

B1.M端(属于显式操作)

这儿的接口没啥好说的

  • 获取优惠券列表、通过id获取优惠券详情、添加优惠券、修改优惠券、修改优惠券状态、批量删除
  • 查询全部分类列表(见商品分类,M端)
  • 分页获取商品sku列表(见商品,M端)

    ​   

B2.S端(属于显式操作)

这里的和M端的逻辑类似,只是有些属性需要修改

  • 获取优惠券列表、通过id获取优惠券详情、添加优惠券、修改优惠券、修改优惠券状态、批量删除
  • 获取店铺经营的分类(见商品分类,S端)
  • 分页获取商品Sku列表(见商品,S端)

   

    

B3.B端(属于显式操作)

这里的就是B端前台显示的,和用户已领取的;

但是 获取可领取优惠券列表 接口有点不方便,只返回了平台所有优惠券,并没有标注当前登录账号是否有该优惠券~

  • 获取可领取优惠券列表、获取当前会员的优惠券列表、会员领取优惠券

       

B4.consumer端(属于业务操作)

用户领取的优惠券有截止日期的,所以需要添加定时任务来操作会员优惠券的状态变为过期。

详见:cn.lili.timetask.handler.impl.coupon.CouponExecute

但是不明白,这里为什么用EveryDayExecute,按理说应该用每秒检测的,在线上看这也是按秒的,可能这里写错了~

/**
 * 优惠券状态监测
 *
 * @author Bulbasaur
 * @since 2021/5/24 10:08 上午
 */
@Component
public class CouponExecute implements EveryDayExecute {

    /**
     * 过期常量,过期后或者使用后一定时间内,删除无效的优惠券,物理删除
     */
    static final int EXPIRATION_DAY = 3;

    @Autowired
    private MemberCouponService memberCouponService;

    /**
     * 检测优惠券的使用时间,超期未使用则失效
     * 此方法用于领取*天后失效优惠券使用
     */
    @Override
    public void execute() {
        //业务 1
        //将过期优惠券从领取状态变更为过期状态
        LambdaUpdateWrapper<MemberCoupon> updateWrapper = new LambdaUpdateWrapper<MemberCoupon>()
                .eq(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.NEW.name())
                .le(MemberCoupon::getEndTime, new Date())
                .set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
        this.memberCouponService.update(updateWrapper);

        //业务 2
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - EXPIRATION_DAY);
        Date removeTime = calendar.getTime();
        //删除过期/已使用的优惠券(过期一定时间后物理删除)
        LambdaUpdateWrapper<MemberCoupon> deleteWrapper = new LambdaUpdateWrapper<MemberCoupon>()
                //如果结束时间小于 当前时间增加指定删除日期,则删除
                .le(MemberCoupon::getEndTime, removeTime);
        this.memberCouponService.remove(deleteWrapper);


    }

}

A2.券活动

根据优惠券添加券活动,关联的会员直接存到主表里面的scope里面,关联的券存到子表li_coupon_activity_item 里面。

这个业务就是给指定用户发放优惠券的,他的活动开始时间和结束时间其实没有用,在创建活动的时候就直接给指定用户发放了,并且即便活动未开始、活动已结束也可以使用,所以真正的业务效果是啥呢?TvT

B1.M端(属于显式操作)

  • 获取优惠券活动分页、通过id获取优惠券活动、添加优惠券活动、关闭优惠券活动
  • 获取优惠券列表(见优惠券,M端)
  • 会员分页列表(见会员,S端)

 

A3.满减

满减是由店铺发起的,运营M端可以关闭,其中满减里面回赠送包邮、优惠券、赠品~

包邮会在下单时满足条件的时候去掉邮费,赠送优惠券会在下单付款后赠送会员指定券(该券是店铺创建的活动券),赠品会在下单后生成赠品类型的子订单,价格为零。

同一个商品sku只能存在一个满减活动,所以不能存在多个全品类的满减活动~

满减活动失效是没有定时任务的,对于S端M端来说只是每次获取时进行判断,然后记录状态,表中并不存在状态这个字段,如果想要关闭满减活动,会直接将开始-截止日期清空的,这样会根据时间判断为已关闭。在B端只会在获取sku的详情时会获取该sku绑定的、有效的促销满减活动。

(私以为这样的设计不太合理,这样关闭是不会记录下来这个被关闭的满减活动的开始日期的。所以可以添加一个状态字段来记录,也方便。)

之后的促销活动:秒杀,也是这个逻辑的!

B1.S端(属于显式操作)

  • 根据条件分页查询满优惠活动、通过id获取、新增满优惠活动、修改满优惠活动、删除满优惠活动、修改满额活动状态
  • 获取店铺经营的分类(见商品分类,S端)
  • 分页获取商品Sku列表(见商品,S端)

 

  

B2.M端(属于显式操作)

  • 获取满优惠列表、获取满优惠详情、修改满额活动状态

  

 A4.秒杀

每一天的秒杀是由系统自动添加的,然后想参加的店铺可以往某个秒杀的某个时间里面添加商品sku,运营端可以删除商品sku或者关闭秒杀。

系统一开始就需要先往系统里面添加后几天秒杀,然后之后的每一天都添加秒杀。例如:12-01日系统一开始添加七天的秒杀到 12-08,第二天 12-02 会执行定时任务,继续添加秒杀直到 12-09,由于 12-03 到 12-08 已经添加了定时任务,就会跳过,只添加 12-09 的秒杀。(这只是简单逻辑哈,实际上是判断后7天哪天没有开启的秒杀就添加秒杀,因为已生成的秒杀可以关闭~)

买方B端可以查看秒杀列表,进行秒杀商品购买,秒杀商品即使不再秒杀列表里面也会限时秒杀信息的。秒杀列表只是一个快捷入口。 

B1.M端(属于显式操作)

  • 初始化秒杀活动、分页查询秒杀活动列表、通过id获取、修改秒杀活动、删除一个秒杀活动、操作秒杀活动状态
  • 获取秒杀活动申请列表、删除秒杀活动申请
  • 获取店铺经营的分类(见商品分类,S端)
  • 分页获取商品Sku列表(见商品,S端)

 

 

B2.S端(属于显式操作)

  • 获取秒杀活动列表、通过id获取秒杀活动信息、获取秒杀活动申请列表、通过id获取秒杀活动申请、添加秒杀活动申请、删除秒杀活动商品
  • 获取店铺经营的分类(见商品分类,S端)
  • 分页获取商品Sku列表(见商品,S端)

 

 

B3.B端(属于显式操作)

  • 获取当天秒杀活动信息、获取某个时刻的秒杀活动商品信息

 

B4.consumer端(属于业务操作)

每日定时任务,创建秒杀活动

详见:cn.lili.timetask.handler.impl.promotion.PromotionEverydayExecute

/**
 * 促销活动每日定时器
 *
 * @author Chopper
 * @since 2021/3/18 3:23 下午
 */
@Slf4j
@Component
public class PromotionEverydayExecute implements EveryDayExecute {

    /**
     * ES商品索引
     */
    @Autowired
    private EsGoodsIndexService esGoodsIndexService;
    /**
     * 系统设置
     */
    @Autowired
    private SettingService settingService;
    /**
     * 秒杀活动
     */
    @Autowired
    private SeckillService seckillService;

    /**
     * 将已过期的促销活动置为结束,添加秒杀活动
     */
    @Override
    public void execute() {
        try {
            //清除所有商品索引的无效促销活动
            this.esGoodsIndexService.cleanInvalidPromotion();
        } catch (Exception e) {
            log.error("清楚商品索引中无效促销异常", e);
        }
        try {
            //定时创建活动
            addSeckill();
        } catch (Exception e) {
            log.error("秒杀活动添加异常", e);
        }

    }

    /**
     * 添加秒杀活动
     * 从系统设置中获取秒杀活动的配置
     * 添加明天后的秒杀活动
     */
    private void addSeckill() {
        Setting setting = settingService.get(SettingEnum.SECKILL_SETTING.name());
        SeckillSetting seckillSetting = new Gson().fromJson(setting.getSettingValue(), SeckillSetting.class);
        log.info("生成秒杀活动设置:{}", seckillSetting);
        for (int i = 1; i <= SeckillService.PRE_CREATION; i++) {
            Seckill seckill = new Seckill(i, seckillSetting.getHours(), seckillSetting.getSeckillRule());

            //如果已经存在促销,则不再次保存
            if (seckillService.list(PromotionTools.checkActiveTime(seckill.getStartTime(), seckill.getEndTime(), PromotionTypeEnum.SECKILL, null, seckill.getId())).isEmpty()) {
                boolean result = seckillService.savePromotions(seckill);
                log.info("生成秒杀活动参数:{},结果:{}", seckill, result);
            }
        }
    }
}

A5.A6.拼团和砍价(待记录)

拼团和砍价也是只有买方小程序/APP端才有的业务,买方PC端是没有的。

拼团和砍价的详细业务来不及了解,后面记录。

A7.积分商品

积分商品也是只有买方小程序/APP端才有的业务,买方PC端是没有的。

积分商品的每个活动都包含一个商品sku,并且只由运营M端可以管理积分,店铺S端是不会管理的。添加为积分商品的商品sku下单后的金额为 0 ,也就是这单收益为 0 ,但是在店对账中会通过设置的积分结算金额再补给店铺,所以最终可以说是运营端出费的~~~(补充一下平台优惠券也是会在结算时补给店铺,具体补多少看优惠券里面店铺占比的~)

积分分类是为了买方B端进行的分类,和商品没关联的。

B1.积分分类

C1.M端(属于显式操作)

  • 获取积分商品分类分页、通过id获取积分商品分类、添加积分商品分类、修改积分商品分类、删除积分商品分类

 

 C2.B端(属于显式操作)

这个接口直接放到了买方端的积分商品里面,见积分商品,买方B端。

B2.积分商品

C1.M端(属于显式操作)

  • 分页获取积分商品、通过id获取积分商品详情、添加积分商品、修改积分商品、删除积分商品、修改积分商品状态

 

  

C1.B端(属于显式操作)

  • 分页获取积分商品、获取积分活动商品

  • 获取积分商品分类分页

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/104258.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

skynet开发一个猜数字游戏

skynet开发一个猜数字游戏游戏简介接口设计和实现agent服务接口room服务接口hall服务接口redis服务gate服务接口编写skynet的config文件游戏演示总结后言游戏简介 猜数字游戏目的是掌握 actor 模型开发思路。 规则&#xff1a; 满三个人开始游戏&#xff0c;游戏开始后不能退…

1.初识Node.js

由于浏览器中有Javascript解析引擎&#xff0c;所以写的javascript可以在浏览器中执行&#xff0c;不同的浏览器有不同的JS解析引擎。由于浏览器内置了DOM,BOM,AJAX这种API&#xff0c;所以JS才能使用他们。 Node.js和浏览器都可以为JS提供运行环境&#xff0c;可以使用Node.j…

【Python机器学习】神经网络中误差反向传播(BP)算法详解及代码示例(图文解释 附源码)

需要全部代码请点赞关注收藏后评论留言私信~~~ 误差反向传播学习算法 用神经网络来完成机器学习任务&#xff0c;先要设计好网络结构S&#xff0c;然后用训练样本去学习网络中的连接系数和阈值系数&#xff0c;即网络参数S&#xff0c;最后才能用来对测试样本进行预测。 在研…

智能驾驶进入新周期:从「定点量产」到「做大做强」

智能驾驶赛道已经进入一个全新的周期。 过去三年时间&#xff0c;中国本土供应商陆续进入乘用车前装量产赛道&#xff0c;部分企业实现了从0到1的量产突围&#xff0c;而一些领跑的本土供应商已率先进入规模化上车的新阶段。 从最初的技术突破、产品落地&#xff0c;到定点量…

干货 | IC模拟版图设计学习笔记,一文教你快速入门

模拟版图设计处于IC设计流程的后端&#xff0c;属于模拟IC设计岗位的一种。随着我国半导体行业的发展&#xff0c;IC模拟版图岗位的人才需求也越来越大。而每个芯片最终能够付诸于生产都离不开集成电路版图设计师的功劳&#xff0c;所以IC模拟版图工程师在芯片产业的发展过程中…

Nginx-反向代理

什么是反向代理 用户直接访问反向代理服务器就可以获得目标服务器的资源。这一过程叫反向代理 如何配置反向代理 修改nginx配置文件 1.切换到nginx的conf路径下操作nginx的配置文件 cd /usr/local/openresty/nginx/conf 1.1防止修改错误可以先备份一下配置文件 cp nginx.…

IO流2.0 缓冲流 序列化 字符打印 printf格式 压缩流

04 缓冲流Buffered 4.1字节缓冲流 4.2 字符缓冲流 newLine();在底层自动识别操作系统类别和换行符 其实就是输出换行符; 4.2.1 BufferedReader&#xff08;字符为单位 尽量用于文本文件&#xff09; 不要去操作 二进制文件[声音&#xff0c;视频 ], 可能造成文件损坏 throw…

三个月转行SLAM,他的心路历程

SLAM入门心路历程 来源&#xff1a;知乎作者—莫慢待 读了三年985的计算机硕士&#xff0c;做了很多项目&#xff0c;发现自己是一个菜鸡。c/object-c/python/java/matlab甚至还写过R&#xff0c;也就是项目需要什么写什么。自学能力算是很不错了&#xff0c;第一次创业自己写…

juc-2-锁应用/线程通信

目录 1 线程安全(库存超卖) 2 锁用法 2.1 同步方法 2.2.同步代码块 2.3 synchronized 作用于静态方法 总结 案例 静态成员变量 (synchronized锁非静态方法) 2.4ReentrantLock类是可重入、互斥、实现了Lock接口的锁 3 死锁产生与排查 4 线程间的&#xff08;等待与通知…

Hadoop实训任务3:HDFS和MapReduce综合操作

目录 1、启动Hadoop服务 2、创建文本文件 3、上传文本文件 4、显示文件内容 5、完成排序任务 6、计算最大利润和平均利润 7、统计学生总成绩和平均成绩 8、总结 1、启动Hadoop服务 在master虚拟机上执行命令&#xff1a; start-all.sh 启动hadoop服务进程 ​ ​ ​…

【嵌入式】构建嵌入式Linux系统(uboot、内核、文件系统)

知识架构及层次 Linux内核由三部分构成&#xff1a; Bootloader&#xff1a;启动引导系统&#xff08;可执行文件&#xff09;Kernel&#xff1a;内核&#xff08;可执行文件&#xff09;Root File System&#xff1a;根文件系统嵌入式Linux系统构成及启动略析 嵌入式 Linux …

Java八股文,YYDS!字节最新秋招面试题,“死记”这些你也可以斩获字节offer

Java 一面基本上都是基础题&#xff0c;同样是 CURD 的活&#xff0c;谁更熟练要谁&#xff0c;比如下面这些面试题&#xff0c;八股文越熟练越容易通过 Java 面试。 下面会给大家详解的介绍一下每个技术点的必问问题&#xff01; 一、Java 基础 1.JDK动态代理和CGLIB动态代…

C++图像的形态学操作

什么是图像的形态学操作&#xff1f; 使用数学形态学的基本运算&#xff0c;由计算机对图像进行分析&#xff0c;以达到所需结果的一种技术。 形态学&#xff0c;morphology, 形态学最初是生物学中研究动物和植物结构的一个分支&#xff0c;被引入图像处理领域后&#xff0c;图…

C语言 期末合集 pta

6-1 求最大的偶数和最小的奇数的差 分数 10 全屏浏览题目 切换布局 作者 王跃萍 单位 东北石油大学 求10个数中的最大的偶数和最小的奇数的差。 函数接口定义&#xff1a; int fun(int a[],int n); 函数fun中a、n是用户传入的参数&#xff0c;函数fun的功能是求a数组中的…

【LVGL学习笔记】(五)使用SquareLine Studio设计UI

LVGL全程LittleVGL&#xff0c;是一个轻量化的&#xff0c;开源的&#xff0c;用于嵌入式GUI设计的图形库。并且配合LVGL模拟器&#xff0c;可以在电脑对界面进行编辑显示&#xff0c;测试通过后再移植进嵌入式设备中&#xff0c;实现高效的项目开发。 LVGL中文教程手册&#…

点云地图构建及定位

点云地图构建及定位1. 回环检测1.1 基于Scan Context1.2 基于直方图2. 后端优化2.1 后端优化基本原理2.2 李群、李代数基本知识2.3 李群、李代数基本知识2.3.1 SO(3)\mathrm{SO}(3)SO(3) 对应的 BCH\mathrm{BCH}BCH 公式2.3.2 SE(3)\mathrm{SE}(3)SE(3) 对应的 BCH\mathrm{BCH}…

链式存储之:链表的引出及其简介

上篇博客&#xff0c;笔者讲解了一下顺序表ArrayList&#xff0c;对于ArrayList有想法的各位老铁可以看一下&#xff1a;值得思索的&#xff1a;ArrayList和线性表&#xff0c;你确定错过这次机会_念君思宁的博客-CSDN博客值得思索的&#xff1a;ArrayList和线性表&#xff0c;…

Html5 canvas创意特效合集

Canvas就像一块画布&#xff0c;我们可以通过调用脚本在Canvas上绘制任意形状&#xff0c;甚至是制作动画。本文就是收集了很多非常富有创意的一些canvas动画特效例子&#xff0c;这些例子都非常适合大家学习。 1.3D篝火动画特效 这款篝火特效是基于 three.js 和 canvas 制作的…

博实结将在创业板上会:计划募资25亿元,周小强为实际控制人

近日&#xff0c;深圳市博实结科技股份有限公司&#xff08;下称“博实结”&#xff09;在深圳证券交易所递交招股书&#xff08;上会稿&#xff09;&#xff0c;准备在创业板上市。据贝多财经了解&#xff0c;博实结将于2022年12月23日接受创业板上市委审议&#xff0c;一同上…

Vue3----props和emit的使用

作用&#xff1a;父组件通过 props 向下传递数据给子组件&#xff1b; 用途&#xff1a;当有一种类型的组件需要被使用多次&#xff0c;每一次的调用都只是特定的地方不同&#xff0c;就好像一张个人简介表&#xff0c;每次填的人的信息都不同&#xff0c;但是结构都是一样的。…