产品角度
    https://juejin.cn/post/6844903702742958094

    数据库设计

    1. CREATE TABLE `coupon` (
    2. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自动增加ID',
    3. `region_id` bigint(20) DEFAULT NULL COMMENT '所属区域',
    4. `type` int(11) DEFAULT NULL COMMENT '所属类型,1为满减',
    5. `name` varchar(32) DEFAULT NULL COMMENT '优惠券名称',
    6. `img` varchar(64) DEFAULT NULL COMMENT '图片的URL地址',
    7. `start_time` datetime DEFAULT NULL COMMENT '优惠券开始时间',
    8. `end_time` datetime DEFAULT NULL COMMENT '优惠券结束时间',
    9. `money` decimal(11,2) DEFAULT NULL COMMENT '优惠券金额,用整数,固定值目前。',
    10. `status` int(11) DEFAULT NULL COMMENT '状态,0表示未开始,1表示进行中,-1表示结束',
    11. `remarks` varchar(512) DEFAULT NULL COMMENT '优惠券的说明',
    12. `create_time` datetime DEFAULT NULL COMMENT '创建时间',
    13. `full_money` decimal(12,2) DEFAULT NULL COMMENT '金额满',
    14. PRIMARY KEY (`id`)
    15. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='优惠券基础配置表';
    1. CREATE TABLE `coupon` (
    2. `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT'ID',
    3. `title` varchar(64) NOT NULL COMMENT'优惠券标题(有图片则显示图片):无门槛50元优惠券 | 单品最高减2000元',
    4. `icon` varchar(128) DEFAULT NULL COMMENT'图片',
    5. `used`int(2) NOT NULL COMMENT'可用于:10店铺优惠券 11新人店铺券 20商品优惠券 30类目优惠券 60平台优惠券 61新人平台券',
    6. `type`int(2) NOT NULL DEFAULT'1'COMMENT'1满减券 2叠加满减券 3无门槛券(需要限制大小)',
    7. `with_special`int(2) NOT NULL DEFAULT'2'COMMENT'1可用于特价商品 2不能 默认不能(商品优惠卷除外)',
    8. `with_sn` varchar(36) DEFAULT NULL COMMENT'店铺或商品流水号',
    9. `with_amount` bigint(20) NOT NULL DEFAULT'0'COMMENT'满多少金额',
    10. `used_amount` bigint(20) NOT NULL COMMENT'用券金额',
    11. `quota`int(10) NOT NULL DEFAULT'1'COMMENT'配额:发券数量',
    12. `take_count`int(10) NOT NULL DEFAULT'0'COMMENT'已领取的优惠券数量',
    13. `used_count`int(10) NOT NULL DEFAULT'0'COMMENT'已使用的优惠券数量',
    14. `start_time` datetime NOT NULL COMMENT'发放开始时间',
    15. `end_time` datetime NOT NULL COMMENT'发放结束时间',
    16. `valid_type`int(1) NOT NULL DEFAULT'2'COMMENT'时效:1绝对时效(领取后XXX-XXX时间段有效) 2相对时效(领取后N天有效)',
    17. `valid_start_time` datetime DEFAULT NULL COMMENT'使用开始时间',
    18. `valid_end_time` datetime DEFAULT NULL COMMENT'使用结束时间',
    19. `valid_days`int(3) NOT NULL DEFAULT'1'COMMENT'自领取之日起有效天数',
    20. `status`int(1) NOT NULL DEFAULT'1'COMMENT'1生效 2失效 3已结束',
    21. `create_user` bigint(20) NOT NULL,
    22. `create_time` datetime NOT NULL COMMENT'创建时间',
    23. `update_user` bigint(20) NOT NULL,
    24. `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT'修改时间',
    25. PRIMARY KEY (`id`)
    26. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='优惠券表';
    1. CREATE TABLE `coupontrans_coupon` (
    2. `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '优惠券ID',
    3. `uid` bigint(20) NOT NULL DEFAULT 0 COMMENT '权益所有者',
    4. `balance` bigint(20) NOT NULL DEFAULT 0 COMMENT '优惠券金额: 金额类-优惠券金额;折扣类型-最大抵扣金额',
    5. `original_balance` bigint(20) NOT NULL DEFAULT 0 COMMENT '优惠原始金额: 金额类-优惠券金额;折扣类型-最大抵扣金额',
    6. `busi_source` bigint(20) NOT NULL DEFAULT 0 COMMENT '优惠券业务线类型: 100:少儿; 200:绘本VIP; 300:自拼; 400:精读课 600:数学课; 9900:商城优惠券',
    7. `commodity_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '对应优惠券类型',
    8. `coupon_group` varchar(255) NOT NULL DEFAULT '' COMMENT '对应优惠券组:',
    9. `coupon_flag` int(11) NOT NULL DEFAULT 0 COMMENT '优惠券类型:1-无限制,2-全互斥优惠券,3-同组可叠加',
    10. `off` int(11) NOT NULL DEFAULT 0 COMMENT '优惠券折扣',
    11. `minstd` bigint(20) NOT NULL DEFAULT 0 COMMENT '最低限额',
    12. `lastrepeat` bigint(20) NOT NULL DEFAULT 0 COMMENT '剩余可用次数',
    13. `repeatinit` bigint(20) NOT NULL DEFAULT 0 COMMENT '初始化试用次数',
    14. `usecn` bigint(20) NOT NULL DEFAULT 0 COMMENT '总共试用次数',
    15. `effect` bigint(20) NOT NULL DEFAULT 0 COMMENT '生效时间',
    16. `expire` bigint(20) NOT NULL DEFAULT 0 COMMENT '过期时间',
    17. `ct` bigint(20) NOT NULL DEFAULT 0 COMMENT '创建时间',
    18. `ut` bigint(20) NOT NULL DEFAULT 0 COMMENT '更新时间',
    19. `jdata` json DEFAULT NULL COMMENT 'json格式扩展字段',
    20. `title` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '标题',
    21. `ch` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '渠道',
    22. PRIMARY KEY (`id`),
    23. KEY `idx_uid_bs` (`uid`,`busi_source`),
    24. KEY `idx_ct` (`ct`),
    25. KEY `idx_commodity_id` (`commodity_id`)
    26. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=418230849963575 COMMENT='优惠券账户表';

      参考链接

    说明:现在电商白热化的程度,无论是生鲜电商还是其他的电商等等,都会有促销的这个体系,目的就是增加订单量与知名度等等
    那么对于Java开源生鲜电商平台而言,我们采用优惠券的这种方式进行促销。(补贴价格战对烧钱而言非常的恐怖的,太烧钱了)
    1. 优惠券基础信息表
    说明:任何一个优惠券或者说代金券都是有一个基础的说明,比如:优惠券名称,类型,价格,有效期,状态,说明等等基础信息。

    1. CREATETABLEcoupon (
    2. idbigint(20)unsignedNOTNULL AUTO_INCREMENTCOMMENT’自动增加ID’,
    3. region_idbigint(20)DEFAULTNULLCOMMENT’所属区域’,
    4. typeint(11)DEFAULTNULLCOMMENT’所属类型,1为满减’,
    5. namevarchar(32)DEFAULTNULLCOMMENT’优惠券名称’,
    6. imgvarchar(64)DEFAULTNULLCOMMENT’图片的URL地址’,
    7. start_time datetimeDEFAULTNULLCOMMENT’优惠券开始时间’,
    8. end_time datetimeDEFAULTNULLCOMMENT’优惠券结束时间’,
    9. moneydecimal(11,2)DEFAULTNULLCOMMENT’优惠券金额,用整数,固定值目前。’,
    10. statusint(11)DEFAULTNULLCOMMENT’状态,0表示未开始,1表示进行中,-1表示结束’,
    11. remarksvarchar(512)DEFAULTNULLCOMMENT’优惠券的说明’,
    12. create_time datetimeDEFAULTNULLCOMMENT’创建时间’,
    13. full_moneydecimal(12,2)DEFAULTNULLCOMMENT’金额满’,
    14. PRIMARYKEY (id)
    15. )ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT=’优惠券基础配置表’;
    1. CREATE TABLE `coupontrans_commodity_bindflag` (
    2. `id` bigint(20) NOT NULL DEFAULT 0 COMMENT '优惠券ID',
    3. `commodity_id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '优惠券类型',
    4. `package_id` bigint(11) NOT NULL DEFAULT 0 COMMENT '优惠券ID',
    5. `tag_str` varchar(64) NOT NULL DEFAULT '' COMMENT '对应类型',
    6. `coupon_flag` int(11) NOT NULL DEFAULT 0 COMMENT '优惠券类型:1-无限制,2-全互斥优惠券,3-同组可叠加,4-指定套餐类型;5-指定套餐ID;',
    7. `ct` bigint(20) NOT NULL DEFAULT 0 COMMENT '创建时间',
    8. `ut` bigint(20) NOT NULL DEFAULT 0 COMMENT '更新时间',
    9. PRIMARY KEY (`id`),
    10. KEY `idx_commodity_id` (`commodity_id`)
    11. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='优惠券使用类型';
    1. CREATE TABLE `coupontrans_coupon_log` (
    2. `id` bigint(20) NOT NULL AUTO_INCREMENT,
    3. `uid` bigint(20) NOT NULL DEFAULT 0 COMMENT '权益所有者',
    4. `coupon_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '优惠券ID',
    5. `logic_id` varchar(64) NOT NULL DEFAULT '' COMMENT '业务唯一ID',
    6. `uniqueid` varchar(64) NOT NULL DEFAULT '' COMMENT '操作唯一ID',
    7. `bussrc` int(11) NOT NULL DEFAULT 0 COMMENT '操作来源',
    8. `bussrc_operation` varchar(64) NOT NULL DEFAULT '' COMMENT '操作来源',
    9. `balance` bigint(20) NOT NULL DEFAULT 0 COMMENT '优惠券抵扣金额',
    10. `busi_source` bigint(20) NOT NULL DEFAULT 0 COMMENT '优惠券业务线类型: 100:少儿; 200:绘本VIP; 300:自拼; 400:精读课 600:数学课; 9900:商城优惠券',
    11. `commodity_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '对应优惠券类型',
    12. `before_balance` bigint(20) NOT NULL DEFAULT 0 COMMENT '优惠券操作金额',
    13. `ct` bigint(20) NOT NULL DEFAULT 0 COMMENT '创建时间',
    14. `ut` bigint(20) NOT NULL DEFAULT 0 COMMENT '更新时间',
    15. `note` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '备注',
    16. PRIMARY KEY (`id`),
    17. KEY `idx_uid` (`uid`),
    18. KEY `idx_couponId` (`coupon_id`),
    19. KEY `idx_ct` (`ct`),
    20. UNIQUE KEY `uniq_uniqueid` (`uniqueid`),
    21. KEY `logic_id` (`logic_id`)
    22. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=210001 COMMENT='优惠券账户变动流水表';

    说明:业务说可以规定某个区域,做优惠券,而且是纳新后才有,这样增加买家用户。价格可以后端进行设置。
    状态的意义在于,用户需要注册完成后,然后主动认领才有效,为什么要这样设计呢?目的只有一个:让用户在对APP这个软件玩一会儿,增加熟悉程度.
    2. 优惠券领取记录表
    说明:我们需要记录那个买家,什么时候进行的领取,领取的的时间,券的额度是多少等等,是否已经使用等信息

    1. CREATETABLEcoupon_receive (
    2. idbigint(20)unsignedNOTNULL AUTO_INCREMENTCOMMENT’自动增加ID’,
    3. buyer_idbigint(20)DEFAULTNULLCOMMENT’买家ID’,
    4. coupon_idbigint(20)DEFAULTNULLCOMMENT’优惠券编号’,
    5. coupon_moneydecimal(12,2)DEFAULTNULLCOMMENT’券额’,
    6. create_time datetimeDEFAULTNULLCOMMENT’领取时间’,
    7. full_moneydecimal(12,2)DEFAULTNULLCOMMENT’金额满’,
    8. statusint(11)DEFAULTNULLCOMMENT’状态,1为已使用,0为已领取未使用,-1为已过期’,
    9. PRIMARYKEY (id)
    10. )ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT=’优惠券领取记录表’;

    3.优惠券消费记录表
    说明:优惠券消费记录表,是需要知道那个买家,那个优惠券,那个订单使用了优惠券,这边有个特别注意的地方是,这个优惠券的执行在支付成功后的回调。

    1. CREATETABLEcoupon_logs (
    2. idbigint(20)unsignedNOTNULL AUTO_INCREMENTCOMMENT’自动增加ID’,
    3. buyer_idbigint(20)DEFAULTNULLCOMMENT’买家ID’,
    4. coupon_receive_idbigint(20)DEFAULTNULLCOMMENT’优惠券id’,
    5. order_numbervarchar(64)DEFAULTNULLCOMMENT’订单号’,
    6. order_original_amountdecimal(12,2)DEFAULTNULLCOMMENT’原订单金额’,
    7. coupon_amountdecimal(11,2)DEFAULTNULLCOMMENT’优惠券的金额’,
    8. order_final_amountdecimal(12,2)DEFAULTNULLCOMMENT’抵扣优惠券之后的订单金额’,
    9. create_time datetimeDEFAULTNULLCOMMENT’领取时间’,
    10. statusint(2)DEFAULT’0’COMMENT’日志状态: 默认为0,支付回调成功后为1’,
    11. PRIMARYKEY (id)
    12. )ENGINE=InnoDBDEFAULTCHARSET=utf8COMMENT=’优惠券消费记录表’;

    说明:相对而言,优惠券的难度不算大,重点的是业务方面的指导与学习,包括数据库的架构与设计等等,还有就是思路的学习。
    相关核心代码如下:
    APP需要后台提供以下几个接口:
    3.1 查询所有买家的优惠券。
    3.2 判断买家是否可以领取优惠券。
    3.3 买家主动领取优惠券

    1. /**
      • 优惠券controller
    2. */
    3. @RestController
    4. @RequestMapping(“/buyer/coupon”)
    5. publicclassCouponControllerextendsBaseController {

    6. privatestaticfinal Logger logger = LoggerFactory.getLogger(CouponController.class);

    7. @Autowired
    8. private CouponReceiveService couponReceiveService;

    9. @Autowired
    10. private UsersService usersService;

    11. /**
      • 查询买家所有优惠券
    12. *
    13. *@param request
    14. *@param response
    15. *@param buyerId
    16. *@return
    17. */
    18. @RequestMapping(value =”/list”, method = { RequestMethod.GET, RequestMethod.POST })
    19. public JsonResultgetCouponList(HttpServletRequest request, HttpServletResponse response, Long buyerId) {
    20. try {
    21. if (buyerId ==null) {
    22. returnnew JsonResult(JsonResultCode.FAILURE,”买家不存在”,””);
    23. }
    24. List result = couponReceiveService.selectAllByBuyerId(buyerId);
    25. returnnew JsonResult(JsonResultCode.SUCCESS,”查询成功”, result);
    26. }catch (Exception ex) {
    27. logger.error(“[CouponController][getCouponList] exception”, ex);
    28. returnnew JsonResult(JsonResultCode.FAILURE,”系统错误,请稍后重试”,””);
    29. }
    30. }

    31. /**
      • 判断买家是否可以领取优惠券
    32. *
    33. *@param request
    34. *@param response
    35. *@param buyerId
    36. *@return
    37. */
    38. @RequestMapping(value =”/judge”, method = { RequestMethod.GET, RequestMethod.POST })
    39. public JsonResultjudgeReceive(HttpServletRequest request, HttpServletResponse response, Long buyerId) {
    40. try {
    41. // 判断当前用户是否可用
    42. Users users = usersService.getUsersById(buyerId);
    43. if (users ==null) {
    44. logger.info(“OrderController.judgeReceive.buyerId “ + buyerId);
    45. returnnew JsonResult(JsonResultCode.FAILURE,”你的账号有误,请重新登录”,””);
    46. }
    47. int status = users.getStatus();
    48. if (UserStatus.FORBIDDEN == status) {
    49. returnnew JsonResult(JsonResultCode.FAILURE,”你的账号已经被禁用了,请联系公司客服”,””);
    50. }
    51. List result = couponReceiveService.selectByBuyerId(buyerId);
    52. if (CollectionUtils.isEmpty(result)) {
    53. result =new ArrayList();
    54. }
    55. returnnew JsonResult(JsonResultCode.SUCCESS,”查询成功”, result);
    56. }catch (Exception ex) {
    57. logger.error(“[CouponController][judgeReceive] exception”, ex);
    58. returnnew JsonResult(JsonResultCode.FAILURE,”系统错误,请稍后重试”,””);
    59. }
    60. }

    61. /**
      • 买家领取优惠券
    62. *
    63. *@param request
    64. *@param response
    65. *@param buyerId
    66. *@return
    67. */
    68. @RequestMapping(value =”/add”, method = { RequestMethod.GET, RequestMethod.POST })
    69. public JsonResultsaveCoupon(HttpServletRequest request, HttpServletResponse response, Long buyerId,
    70. Long couponId) {
    71. try {
    72. // 判断当前用户是否可用
    73. Users users = usersService.getUsersById(buyerId);
    74. if (users ==null) {
    75. logger.info(“OrderController.saveCoupon.buyerId “ + buyerId);
    76. returnnew JsonResult(JsonResultCode.FAILURE,”你的账号有误,请重新登录”,””);
    77. }
    78. //判断当前用户的状态是否可用
    79. int status = users.getStatus();
    80. if (UserStatus.FORBIDDEN == status) {
    81. returnnew JsonResult(JsonResultCode.FAILURE,”你的账号已经被禁用了,请联系公司客服”,””);
    82. }
    83. if (couponId ==null) {
    84. returnnew JsonResult(JsonResultCode.SUCCESS,”活动已经结束”,””);
    85. }
    86. //新增
    87. int result = couponReceiveService.insert(buyerId, couponId);
    88. if (result == -1) {
    89. returnnew JsonResult(JsonResultCode.SUCCESS,”领取失败,已经领取过优惠券了”,””);
    90. }elseif (result ==0) {
    91. returnnew JsonResult(JsonResultCode.FAILURE,”领取失败,活动已经结束”,””);
    92. }else {
    93. returnnew JsonResult(JsonResultCode.SUCCESS,”领取成功”,””);
    94. }
    95. }catch (Exception ex) {
    96. logger.error(“[CouponController][saveCoupon] exception”, ex);
    97. returnnew JsonResult(JsonResultCode.FAILURE,”系统错误,请稍后重试”,””);
    98. }
    99. }
    100. }

    最终总结:用户优惠券会发放在买家的APP中的个人中心里面,然后进行点击查看与领取,然后在支付的时候会自动显示出优惠券的数据,非常的灵活与方便。