010-53388338

美团买菜优惠券系统设计:功能、数据库、实现及扩展优化方案

分类:IT频道 时间:2026-02-22 00:15 浏览:15
概述
    一、功能概述    美团买菜系统的优惠券通用功能需要实现以下核心能力:  1.支持多种优惠券类型(满减、折扣、无门槛等)  2.支持多品类通用或特定品类限制  3.支持多商户/平台级优惠券  4.支持有效期管理  5.支持使用条件限制(如最低消费金额)  6.支持用户领取、使用、查询等全生命
内容
  
   一、功能概述
  
  美团买菜系统的优惠券通用功能需要实现以下核心能力:
  1. 支持多种优惠券类型(满减、折扣、无门槛等)
  2. 支持多品类通用或特定品类限制
  3. 支持多商户/平台级优惠券
  4. 支持有效期管理
  5. 支持使用条件限制(如最低消费金额)
  6. 支持用户领取、使用、查询等全生命周期管理
  
   二、数据库设计
  
   1. 优惠券表(coupon)
  ```sql
  CREATE TABLE `coupon` (
   `id` bigint NOT NULL AUTO_INCREMENT COMMENT 优惠券ID,
   `coupon_type` tinyint NOT NULL COMMENT 优惠券类型(1:满减,2:折扣,3:无门槛),
   `name` varchar(100) NOT NULL COMMENT 优惠券名称,
   `description` varchar(500) DEFAULT NULL COMMENT 优惠券描述,
   `discount_amount` decimal(10,2) DEFAULT NULL COMMENT 减免金额(满减/无门槛用),
   `discount_rate` decimal(5,2) DEFAULT NULL COMMENT 折扣率(折扣用),
   `min_order_amount` decimal(10,2) DEFAULT NULL COMMENT 最低使用金额,
   `valid_start_time` datetime NOT NULL COMMENT 有效期开始时间,
   `valid_end_time` datetime NOT NULL COMMENT 有效期结束时间,
   `total_count` int NOT NULL COMMENT 总发放数量,
   `remaining_count` int NOT NULL COMMENT 剩余数量,
   `status` tinyint NOT NULL COMMENT 状态(1:有效,2:无效,3:已过期),
   `create_time` datetime NOT NULL COMMENT 创建时间,
   `update_time` datetime NOT NULL COMMENT 更新时间,
   PRIMARY KEY (`id`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=优惠券表;
  ```
  
   2. 优惠券范围表(coupon_scope)
  ```sql
  CREATE TABLE `coupon_scope` (
   `id` bigint NOT NULL AUTO_INCREMENT,
   `coupon_id` bigint NOT NULL COMMENT 优惠券ID,
   `scope_type` tinyint NOT NULL COMMENT 范围类型(1:全品类,2:指定品类,3:指定商品),
   `scope_ids` varchar(1000) DEFAULT NULL COMMENT 范围ID(品类ID或商品ID列表,JSON格式),
   PRIMARY KEY (`id`),
   KEY `idx_coupon_id` (`coupon_id`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=优惠券范围表;
  ```
  
   3. 用户优惠券表(user_coupon)
  ```sql
  CREATE TABLE `user_coupon` (
   `id` bigint NOT NULL AUTO_INCREMENT,
   `user_id` bigint NOT NULL COMMENT 用户ID,
   `coupon_id` bigint NOT NULL COMMENT 优惠券ID,
   `status` tinyint NOT NULL COMMENT 状态(1:未使用,2:已使用,3:已过期),
   `get_time` datetime NOT NULL COMMENT 领取时间,
   `use_time` datetime DEFAULT NULL COMMENT 使用时间,
   `order_id` bigint DEFAULT NULL COMMENT 使用订单ID,
   `expire_time` datetime NOT NULL COMMENT 过期时间,
   PRIMARY KEY (`id`),
   KEY `idx_user_id` (`user_id`),
   KEY `idx_coupon_id` (`coupon_id`),
   KEY `idx_user_status` (`user_id`,`status`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=用户优惠券表;
  ```
  
   三、核心功能实现
  
   1. 优惠券发放
  
  ```java
  public class CouponService {
  
   @Autowired
   private CouponMapper couponMapper;
  
   @Autowired
   private UserCouponMapper userCouponMapper;
  
   /
   * 发放优惠券给用户
   * @param couponId 优惠券ID
   * @param userId 用户ID
   * @param quantity 发放数量(1或多个)
   * @return 发放结果
   */
   public Result issueCoupon(Long couponId, Long userId, Integer quantity) {
   // 1. 校验优惠券是否存在且有效
   Coupon coupon = couponMapper.selectById(couponId);
   if (coupon == null || coupon.getStatus() != 1) {
   return Result.fail("优惠券不存在或已失效");
   }
  
   // 2. 检查剩余数量
   if (coupon.getRemainingCount() < quantity) {
   return Result.fail("优惠券数量不足");
   }
  
   // 3. 发放优惠券给用户
   Date now = new Date();
   Date expireTime = calculateExpireTime(coupon);
  
   List userCoupons = new ArrayList<>();
   for (int i = 0; i < quantity; i++) {
   UserCoupon userCoupon = new UserCoupon();
   userCoupon.setUserId(userId);
   userCoupon.setCouponId(couponId);
   userCoupon.setStatus(1); // 未使用
   userCoupon.setGetTime(now);
   userCoupon.setExpireTime(expireTime);
   userCoupons.add(userCoupon);
   }
  
   // 批量插入
   userCouponMapper.batchInsert(userCoupons);
  
   // 4. 更新优惠券剩余数量
   couponMapper.decreaseRemainingCount(couponId, quantity);
  
   return Result.success("发放成功");
   }
  
   private Date calculateExpireTime(Coupon coupon) {
   // 根据优惠券有效期计算过期时间
   if (coupon.getValidEndTime().before(new Date())) {
   throw new RuntimeException("优惠券已过期");
   }
   return coupon.getValidEndTime();
   }
  }
  ```
  
   2. 优惠券查询(用户可用优惠券列表)
  
  ```java
  public List getAvailableCoupons(Long userId, BigDecimal orderAmount, Long categoryId) {
   // 1. 查询用户未使用且未过期的优惠券
   List userCoupons = userCouponMapper.selectByUserIdAndStatus(userId, 1);
  
   // 2. 过滤符合条件的优惠券
   return userCoupons.stream()
   .map(userCoupon -> {
   Coupon coupon = couponMapper.selectById(userCoupon.getCouponId());
   return new UserCouponDTO(userCoupon, coupon);
   })
   .filter(dto -> {
   // 检查有效期
   Date now = new Date();
   if (dto.getExpireTime().before(now)) {
   return false;
   }
  
   // 检查最低消费金额
   if (dto.getMinOrderAmount() != null && orderAmount.compareTo(dto.getMinOrderAmount()) < 0) {
   return false;
   }
  
   // 检查品类限制
   if (categoryId != null) {
   return checkCategoryScope(dto.getCouponId(), categoryId);
   }
  
   return true;
   })
   .collect(Collectors.toList());
  }
  
  private boolean checkCategoryScope(Long couponId, Long categoryId) {
   CouponScope scope = couponScopeMapper.selectByCouponId(couponId);
   if (scope == null) {
   return true; // 无范围限制
   }
  
   if (scope.getScopeType() == 1) { // 全品类
   return true;
   }
  
   if (scope.getScopeType() == 2) { // 指定品类
   try {
   List scopeIds = JSON.parseArray(scope.getScopeIds(), Long.class);
   return scopeIds.contains(categoryId);
   } catch (Exception e) {
   return false;
   }
   }
  
   return false;
  }
  ```
  
   3. 优惠券使用(订单结算时)
  
  ```java
  public Result useCoupon(Long userId, Long orderId, Long userCouponId) {
   // 1. 校验用户优惠券
   UserCoupon userCoupon = userCouponMapper.selectById(userCouponId);
   if (userCoupon == null || !userCoupon.getUserId().equals(userId) || userCoupon.getStatus() != 1) {
   return Result.fail("优惠券不可用");
   }
  
   // 2. 校验优惠券是否过期
   if (userCoupon.getExpireTime().before(new Date())) {
   return Result.fail("优惠券已过期");
   }
  
   // 3. 获取优惠券详情
   Coupon coupon = couponMapper.selectById(userCoupon.getCouponId());
  
   // 4. 更新用户优惠券状态
   userCoupon.setStatus(2); // 已使用
   userCoupon.setUseTime(new Date());
   userCoupon.setOrderId(orderId);
   userCouponMapper.updateById(userCoupon);
  
   // 5. 返回优惠券抵扣信息
   CouponDiscountDTO discount = new CouponDiscountDTO();
   discount.setCouponId(coupon.getId());
   discount.setCouponName(coupon.getName());
  
   switch (coupon.getCouponType()) {
   case 1: // 满减
   discount.setDiscountType(1);
   discount.setDiscountAmount(coupon.getDiscountAmount());
   break;
   case 2: // 折扣
   discount.setDiscountType(2);
   discount.setDiscountRate(coupon.getDiscountRate());
   break;
   case 3: // 无门槛
   discount.setDiscountType(3);
   discount.setDiscountAmount(coupon.getDiscountAmount());
   break;
   }
  
   return Result.success(discount);
  }
  ```
  
   4. 优惠券计算(订单金额计算)
  
  ```java
  public BigDecimal calculateOrderAmount(BigDecimal originalAmount, CouponDiscountDTO couponDiscount) {
   if (couponDiscount == null) {
   return originalAmount;
   }
  
   BigDecimal finalAmount = originalAmount;
  
   switch (couponDiscount.getDiscountType()) {
   case 1: // 满减
   finalAmount = originalAmount.subtract(couponDiscount.getDiscountAmount());
   break;
   case 2: // 折扣
   finalAmount = originalAmount.multiply(couponDiscount.getDiscountRate().divide(new BigDecimal(100)));
   break;
   case 3: // 无门槛
   finalAmount = originalAmount.subtract(couponDiscount.getDiscountAmount());
   break;
   }
  
   return finalAmount.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : finalAmount;
  }
  ```
  
   四、扩展功能考虑
  
  1. 优惠券叠加使用:
   - 添加规则表定义哪些优惠券可以叠加使用
   - 在结算时检查并应用多张优惠券
  
  2. 优惠券分享功能:
   - 生成分享链接或二维码
   - 记录分享关系链
  
  3. 优惠券核销:
   - 线下场景核销接口
   - 核销记录查询
  
  4. 优惠券统计与分析:
   - 发放数量、使用数量、核销率等统计
   - 用户领券行为分析
  
  5. 优惠券防刷:
   - 用户领券频率限制
   - 设备指纹校验
  
   五、性能优化建议
  
  1. 缓存优化:
   - 使用Redis缓存热门优惠券信息
   - 缓存用户可用优惠券列表
  
  2. 异步处理:
   - 优惠券发放采用异步消息队列处理
   - 优惠券过期检查使用定时任务批量处理
  
  3. 数据库优化:
   - 对常用查询字段添加索引
   - 考虑分表策略应对大数据量
  
  4. 接口限流:
   - 对领券接口进行限流,防止恶意刷券
  
   六、安全考虑
  
  1. 优惠券代码生成采用唯一且不可预测的算法
  2. 接口调用添加权限校验
  3. 关键操作记录操作日志
  4. 防止优惠券ID篡改(使用签名验证)
  
  以上方案提供了美团买菜系统优惠券通用功能的核心实现思路,可根据实际业务需求进行调整和扩展。
评论
  • 下一篇

  • Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 8192 bytes) in /www/wwwroot/www.sjwxsc.com/config/function.php on line 274