资讯动态

gpmall 营销服务(coupon-service)实战解析:营销活动、优惠券与优惠码的数据库设计与服务建模

发布时间:2026/10/13 2:48:45 来源:尧图企业网站定制
后端电商微服务前端【免费下载链接】gpmall【咕泡学院实战项目】-基于SpringBootDubbo构建的电商平台-微服务架构、商城、电商、微服务、高并发、kafka、Elasticsearch项目地址https://gitcode.com/gh_mirrors/gp/gpmall点击查看免费下载导读本文以 gpmall 电商微服务项目中coupon-service/README.md营销服务设计文档为核心系统讲解营销活动与优惠券的业务场景、功能需求、核心服务接口划分以及tb_sale_acti、tb_sale_rule、tb_sale_coupon、tb_sale_coupon_code、tb_queue_msg五张核心表的完整设计。读者将理解 gpmall 中满减/满折/满赠活动规则如何落地、优惠券如何通过冻结-解冻状态机配合订单生命周期、优惠码如何批量生成与兑换并看到该模块在源码中的实际建模情况含其草稿定位的局限。模块定位营销服务在 gpmall 中的角色在 gpmall 微服务架构中coupon-service营销服务承担的是电商平台最核心的运营工具——营销活动与优惠券的管理和计算职责。与订单、支付、商品等交易主链路服务不同营销服务属于典型的横向支撑型业务它不直接面对终端用户而是通过 RPC 接口被OrderService订单服务等上游服务调用在用户下单、结算、支付的关键节点上完成算优惠的动作。从仓库目录结构看coupon-service沿用了 gpmall 各业务域统一的api / provider 双层拆分模式coupon-api对外发布的 Dubbo 接口定义与 DTO数据传输对象供订单等其他服务依赖coupon-provider营销服务的实际提供者Provider包含 Spring Boot 启动类、Druid 数据源配置、MyBatis 实体与 Mapper、营销策略类等sketch-sql四张核心业务表的 MySQL 建表脚本草稿Navicat 导出格式README.md本文所依据的模块设计文档其中明确标注了关键前提——优惠券 coupon-api 模块目前仍为草稿不建议 install 到本地包使用。也就是说该模块当前更接近设计稿 数据表雏形的阶段业务代码尚未完整实现这一点在阅读下文接口与实体时会反复印证。模块的技术底座与其他 provider 保持一致coupon-provider/pom.xml引入了dubbo、zookeeper/curator-recipes注册中心、mybatis-spring-boot-starter、druid、tk.mybatis mapper、pagehelper、redisson等依赖启动类CouponProviderApplication通过ComponentScan(basePackages com.gpmall.coupon)与MapperScan(com.gpmall.coupon.dal.persistence)完成包扫描数据源由 DruidConfig.java 以spring.datasource前缀绑定配置。业务场景营销服务要解决什么问题原设计文档将营销服务的场景划分为活动与优惠券两大部分两者相互关联、共同构成完整的营销闭环。活动场景活动是营销的场。用户在活动期间购买参与活动的商品即可享受优惠价格满减、满折等同时用户可以通过浏览活动页领取优惠券实现逛活动页 → 领券 → 下单核销的转化路径。优惠券场景优惠券是营销的券其生命周期覆盖领取 → 使用 → 核销/释放。文档列举了五种领券方式新用户注册送券通过系统自动绑定优惠券降低新用户首单门槛消费满额送券用户订单金额消费满一定数值后自动发放优惠券促进复购管理后台绑定运营人员在管理端手工为用户绑定优惠券定向营销活动页点击送券在活动落地页直接领取批量生成兑换码凭码领券支持线下/异业渠道发放兑换码用户凭码兑换适合大规模投放。在使用侧用户下单时可以选择一张或多张优惠券而已使用的优惠券在订单成功支付或取消订单之前不可再次使用——这条约束直接决定了下文优惠码表status字段的冻结中状态设计是营销服务与订单服务协作的基石。功能需求活动与优惠券的能力清单活动需求允许管理人员创建、修改、删除营销活动活动可针对单一具体商品也可以是覆盖全部商品的全场活动允许查询正在进行中的活动列表以及所有活动列表对应IActivityQueryService的queryAll与queryActiveActivityList活动具有起止时间活动类型包括满减、满赠、满折、秒杀等。文档对前三类给出了明确定义类型规则说明满减订单金额满足指定数值时减金额满赠订单金额满足指定数值时赠送产品满折订单金额满足指定数值时按总金额打折计算在源码中这一枚举被建模为SaleTypeEnumSaleTypeEnum.javapublic enum SaleTypeEnum { FULL_REDUCE, // 满减 FULL_DISCOUNT, // 满折 FULL_GIFT // 满赠商品 }可以看到当前枚举只落地了满减/满折/满赠三类文档中提到的秒杀尚未进入代码实现属于预留能力。优惠券需求允许管理人员创建、修改、删除优惠券对应ICouponCoreService中的 admin 系列注释购物车结算时获取用户可用的优惠券列表对应ICouponQueryService.queryActiveByUserId创建订单后检查优惠券是否满足使用条件满足则锁定已勾选的优惠券将其设置为冻结状态待订单支付完成或取消订单后再次修改优惠券状态。第三条需求是整个营销服务与订单服务协作的核心契约文档给出了明确的服务交互描述OrderService 传递活动 id、优惠码 code 给 SaleServiceSaleService 冻结优惠券、计算优惠金额返回优惠总金额、赠送产品 id、营销类型等数据给 OrderService由 OrderService 处理后续业务。这条契约表明优惠金额的计算归属营销服务而订单后续的落库与支付流程仍由 OrderService 负责营销服务只做判定 冻结 算钱这三件事。服务接口划分API 层设计含草稿定位说明coupon-api模块按核心操作 / 查询两个维度拆分了四个 Dubbo 接口全部位于com.gpmall.coupon包下且文档与源码均标注了**此接口暂为草稿**活动服务IActivityCoreService.java 负责活动的写操作public interface IActivityCoreService { CreateActiResponse create(CreateActiRequest request); // 创建营销活动 void update(); // 修改活动 void delete(); // 删除活动 }IActivityQueryService.java 负责活动的读操作public interface IActivityQueryService { List queryAll(); // 查询所有活动 List queryActiveActivityList(); // 查询正在进行中的活动 void checkActivityIsValid(Integer id); // 检查创建订单时传递的活动id是否有效 }其中checkActivityIsValid对应订单创建链路中校验活动是否真实有效的防伪需求——订单服务在接收用户传来的活动 id 后必须先经营销服务校验避免伪造活动参与优惠。优惠券服务ICouponCoreService.java 是优惠券生命周期的心脏集中体现了冻结/解冻与发券逻辑public interface ICouponCoreService { // admin创建/修改/删除优惠券 void freezeCoupon(); // 订单支付过程中 冻结优惠券 void unfreezeCoupon(); // 订单取消后, 解冻优惠券 void generateCouponCode(Integer couponId); // 根据优惠券id生成优惠码 void dispatchCoupon(Integer couponId, Integer... userId); // 派发优惠券 void exchangeCoupon(); // 优惠码兑换优惠券 }ICouponQueryService.java 提供查询与校验public interface ICouponQueryService { void queryAll(); // 查询所有优惠券 void queryAllByUserId(); // 根据userId查询所有优惠券 void queryActiveByUserId(); // 根据userId查询所有可用优惠券 void checkCouponIsValid(Integer... ids); // 检查创建订单时传递的优惠券id是否有效 }DTO 与参数校验草稿阶段已经落地了两个代表性 DTO可窥见其设计思路CreateActiRequest.java 继承自gpmall-commons的AbstractRequestAbstractRequest.java通过重写requestCheck()实现创建活动时的参数校验public class CreateActiRequest extends AbstractRequest { private String name; private SaleTypeEnum saleType; private String desc; Override public void requestCheck() { if (StringUtils.isEmpty(name)) { throw new ValidateException(缺少name参数); } if (saleType null) { throw new ValidateException(缺少type参数); } } }UseCouponRequest.java 以订单明细列表作为入参携带ListOrderItemDtoOrderItemDto.java 定义了orderId、priceBigDecimal、num三个字段——这正是SaleStrategy判定是否满 X所需的原始输入。策略基类 SaleStrategy.java 已预留抽象方法public abstract class SaleStrategy { public abstract boolean match(UseCouponRequest request); // 匹配规则是否满足满减/满折条件 public abstract void perform(); // 执行优惠计算 }从结构看设计者意图用策略模式承载满减/满折/满赠三类算法的差异对应SaleTypeEnum的三个枚举值但具体策略子类尚未实现属于明确的待办区域。数据库设计五张核心表数据库设计是本模块最完整、最可落地的部分原文档给出了五张表的字段草图仓库sketch-sql/目录下同时提供了四张业务表的完整建表 SQLtb_sale_acti.sql、tb_sale_rule.sql、tb_sale_coupon.sql、tb_sale_coupon_code.sqlprovider 侧的 MyBatis 实体类dal/entitys也与之一一对应。以下按表逐一展开。1. 营销活动表 tb_sale_acti活动主表记录一次营销活动的基本信息与生命周期。字段类型说明idbigint主键自增namevarchar(255)活动名称非空typetinyint活动类型statustinyint状态0 未开始、1 进行中、2 已结束start_time / end_timedatetime活动起止时间descvarchar(255)活动描述created / updateddatetime创建/更新时间对应实体 SaleActivity.java其中status注释为0 未开始 1 进行中 2 已结束。完整的建表语句见 tb_sale_acti.sql。status的三态设计配合start_time/end_time天然支撑IActivityQueryService.queryActiveActivityList()的进行中活动查询。2. 活动规则关联表 tb_sale_rule这是营销服务最关键的一张表承载满 X 减 Y / 满 X 折 / 满 X 赠 Z的具体规则数值通过acti_id关联活动实现一个活动、多条阶梯规则的模型。字段类型说明idbigint主键自增acti_idbigint活动 id若是优惠券规则此字段为 nullitem_idbigint满足规则条件的商品 idfull_pricedecimal(10,2)满金额阈值discount_pricedecimal(10,2)抵扣金额discount_ratedecimal(10,2)折扣比例gift_item_idbigint赠送产品 idoverlapbit(1)是否可叠加规则默认 b0descvarchar(255)规则描述created / updateddatetime创建/更新时间对应实体 SaleRule.java建表脚本见 tb_sale_rule.sql。几个关键设计点值得展开acti_id 可空注释明确活动规则需要绑定 acti_id如果是优惠券规则此字段为 null。这意味着优惠券同样挂在规则表上——优惠券通过rule_id指向一条tb_sale_rule从而实现满减券对应 discount_price、折扣券对应 discount_rate等券种复用同一套规则数值结构item_id 支持单品级活动字段可空为空时即全场活动非空时限定具体商品恰好支撑文档中单一具体商品 / 全场活动两种活动形态overlap 控制叠加bit(1) 类型决定该规则能否与其他优惠叠加是多券并行计算的前提开关三值字段互斥使用full_price是门槛满 Xdiscount_price、discount_rate、gift_item_id分别对应满减、满折、满赠三类产出由活动的type即SaleTypeEnum决定取用哪个字段。3. 优惠券表 tb_sale_coupon优惠券主表描述券本身名称、类型、有效期、数量并通过rule_id关联具体优惠规则。字段类型说明idbigint主键自增namevarchar(100)优惠券名称非空descvarchar(255)优惠券描述typetinyint券类型1 满减券、2 通用 0 元减价券rule_idbigint关联的规则 idis_visiblebit(1)是否可用默认 b1countint可生成的优惠码数量grab_start_time / grab_end_timedatetime抢券起止时间领券中心备用start_time / end_timedatetime优惠券有效期created / updateddatetime创建/更新时间对应实体 SaleCoupon.java建表脚本见 tb_sale_coupon.sql。注意两点rule_id在注释中直接写为优惠金额实际语义是关联的规则 id对应tb_sale_rule表结构体现的是券 → 规则 → 数值的二级关联grab_start_time/grab_end_time注释明确为抢券开始时间领券中心备用即预留了定点抢券这种高并发营销玩法但当前并未使用is_visible是运营侧上下架开关控制券是否对用户可见可领。4. 优惠码表 tb_sale_coupon_code优惠码是批量发券的载体这张表记录了码的完整生命周期状态机是整个营销模块中状态设计最精细的一张表字段类型说明idbigint主键自增codevarchar(255)优惠码按码领券coupon_idbigint关联的优惠券 idstatustinyint0 未领取、1 已领取未使用、2 冻结中、3 已使用、4 已过期user_idbigint关联用户order_idbigint消费的订单明细 idconsume_timedatetime使用时间created / updateddatetime创建/更新时间对应实体 SaleCouponCode.java建表脚本见 tb_sale_coupon_code.sql。状态机与订单生命周期的对应关系是这张表的设计精髓也是前文优惠券需求第 3 条的落地载体状态值含义触发时机0未领取批量生成兑换码后、用户凭码兑换前1已领取未使用用户凭码领取 / 系统派发后2冻结中用户下单选中该券OrderService 调 SaleService 冻结3已使用订单支付成功优惠正式核销4已过期超过有效期未使用其中2 冻结中正是文档强调的已使用的优惠券在订单成功支付或取消订单之前不可再次使用下单时从 1 → 2冻结支付成功后 2 → 3已使用订单取消后 2 → 1解冻对应ICouponCoreService的freezeCoupon()/unfreezeCoupon()。order_id记录了冻结它的订单保证一张券在同一时刻只可能被一个订单占用。5. 消息队列消息表 tb_queue_msg异常消息补偿这是营销模块针对分布式事务可靠性的补充设计。字段草图如下字段类型说明idbigint主键queuevarchar队列名称topicvarchar队列主题methodvarchar执行的方法argsvarchar方法参数finish_timedatetimehandle 执行完成时间createddatetime创建时间对应实体 QueueMsg.java。其作用正如文档注释所言消息队列消息表异常消息补偿。在微服务环境下冻结优惠券→生成订单→支付成功→核销横跨多个服务任何一环失败都可能导致券状态与订单状态不一致。这张表以队列名 topic 方法名 参数记录待补偿的 MQ 消息finish_time标记处理完成时间供补偿程序如定时任务扫描未完成记录、重新投递执行。coupon-provider/service/MQMessageHandler.java的类注释处理订单支付成功的 MQ 信息印证了营销服务确实计划通过 MQ 消费订单支付成功事件来驱动券状态流转。模块现状与落地局限基于以上源码梳理需要对该模块给出客观的现状评估API 层为草稿README 明确声明coupon-api 模块目前仍为草稿不建议 install 到本地包使用四个服务接口中的多数方法只有签名与注释尚无 provider 侧的Service实现类coupon-provider下目前仅有MQMessageHandler空类与SaleStrategy抽象基类数据层最完整四张业务表的实体、Mapper 接口与 XML位于 dal/persistence以及 sketch-sql 建表脚本均已就绪是全模块中可直接复用/运行的部分策略模式已定型SaleTypeEnumSaleStrategy的枚举定类型、策略做算法骨架已确立后续只需为满减/满折/满赠各实现一个策略子类并注册即可订单协作契约已定义OrderService 传活动 id 与优惠码 codeSaleService 冻结券、算优惠、回传优惠金额/赠品 id/营销类型这一接口契约与tb_sale_coupon_code的状态机完全吻合可作为后续双端联调的基准。从全仓视角看前端 coupon.vue我的优惠页目前仅展示您目前还没有优惠券的空态占位路由与入口已预留这进一步说明营销服务的端到端打通仍处于设计先行、实现待续的阶段。若要在本仓库基础上继续推进该模块合理路径是先以sketch-sql完成建库再按IActivityCoreService→ICouponCoreService的顺序补齐 provider 实现并以SaleStrategy策略子类作为优惠计算的扩展点最后通过 MQ 消费订单支付事件完成券状态机闭环。赞分享后端电商微服务前端【免费下载链接】gpmall【咕泡学院实战项目】-基于SpringBootDubbo构建的电商平台-微服务架构、商城、电商、微服务、高并发、kafka、Elasticsearch项目地址https://gitcode.com/gh_mirrors/gp/gpmall点击查看免费下载相关推荐10分钟上手card.io-iOS-SDKiOS开发者必备的信用卡OCR解决方案10分钟上手card.io iOS SDKiOS开发者必备的信用卡OCR解决方案 card.io iOS SDK是一款开源的信用卡OCR扫描工具能帮助iOS移动开发计算机视觉eShop促销系统优惠券、折扣码与促销活动eShop促销系统优惠券、折扣码与促销活动 引言电商促销的挑战与机遇 在当今竞争激烈的电商环境中一个强大的促销系统是企业成功的关键因素。eShop作为基于后端电商前端微服务Amazing-QR生成优惠券二维码营销活动工具的终极指南Amazing QR生成优惠券二维码营销活动工具的终极指南 想要为你的营销活动制作吸引人的优惠券二维码吗 Amazing QR 是 Python 生态中图像处理上一篇SD-WebUI Forge 提示词权重与长提示词分块指南下一篇komorebi manage 命令深度解析强制接管前台窗口并纳入平铺管理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑