010-53388338

美团买菜系统优惠券设计:功能、架构、风控及性能优化全解析

分类:IT频道 时间:2026-02-01 12:00 浏览:30
概述
    一、功能概述    美团买菜系统的优惠券通用功能需要实现以下核心能力:  1.支持多种类型优惠券(满减券、折扣券、无门槛券等)  2.跨品类商品通用(生鲜、日用品等)  3.灵活的发放与使用规则  4.有效的防刷与风控机制  5.清晰的用户展示与使用流程    二、系统架构设计    1.核
内容
  
   一、功能概述
  
  美团买菜系统的优惠券通用功能需要实现以下核心能力:
  1. 支持多种类型优惠券(满减券、折扣券、无门槛券等)
  2. 跨品类商品通用(生鲜、日用品等)
  3. 灵活的发放与使用规则
  4. 有效的防刷与风控机制
  5. 清晰的用户展示与使用流程
  
   二、系统架构设计
  
   1. 核心模块划分
  
  ```
  优惠券系统
  ├── 优惠券模板管理
  ├── 优惠券实例管理
  ├── 发放规则引擎
  ├── 使用规则引擎
  ├── 用户优惠券管理
  ├── 优惠券风控系统
  └── 优惠券统计与分析
  ```
  
   2. 数据库设计
  
  优惠券模板表(coupon_template)
  ```sql
  CREATE TABLE coupon_template (
   id BIGINT PRIMARY KEY AUTO_INCREMENT,
   name VARCHAR(100) NOT NULL COMMENT 优惠券名称,
   type TINYINT NOT NULL COMMENT 1-满减券 2-折扣券 3-无门槛券,
   discount_value DECIMAL(10,2) NOT NULL COMMENT 优惠金额/折扣率,
   min_order_amount DECIMAL(10,2) DEFAULT NULL COMMENT 最低订单金额(满减券用),
   valid_days INT NOT NULL COMMENT 有效期天数,
   scope TINYINT NOT NULL COMMENT 1-全品类 2-指定品类 3-指定商品,
   total_count INT NOT NULL COMMENT 总发放量,
   remaining_count INT NOT NULL COMMENT 剩余量,
   status TINYINT NOT NULL COMMENT 1-有效 0-失效,
   create_time DATETIME NOT NULL,
   update_time DATETIME NOT NULL
  );
  ```
  
  用户优惠券表(user_coupon)
  ```sql
  CREATE TABLE user_coupon (
   id BIGINT PRIMARY KEY AUTO_INCREMENT,
   user_id BIGINT NOT NULL COMMENT 用户ID,
   template_id BIGINT NOT NULL COMMENT 模板ID,
   coupon_no VARCHAR(32) NOT NULL COMMENT 优惠券编号,
   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 过期时间,
   INDEX idx_user (user_id),
   INDEX idx_status (status),
   INDEX idx_expire (expire_time)
  );
  ```
  
   三、核心功能实现
  
   1. 优惠券发放实现
  
  ```java
  // 发放优惠券服务
  public class CouponDistributionService {
  
   @Autowired
   private CouponTemplateRepository templateRepository;
  
   @Autowired
   private UserCouponRepository userCouponRepository;
  
   @Transactional
   public void distributeCoupon(Long templateId, List userIds) {
   // 1. 检查模板是否存在且有效
   CouponTemplate template = templateRepository.findById(templateId)
   .orElseThrow(() -> new RuntimeException("优惠券模板不存在"));
  
   if (template.getRemainingCount() <= 0 || template.getStatus() != 1) {
   throw new RuntimeException("优惠券模板不可用");
   }
  
   // 2. 为每个用户生成优惠券实例
   Date now = new Date();
   Date expireTime = new Date(now.getTime() + template.getValidDays() * 24 * 60 * 60 * 1000);
  
   List coupons = userIds.stream().map(userId -> {
   UserCoupon coupon = new UserCoupon();
   coupon.setUserId(userId);
   coupon.setTemplateId(templateId);
   coupon.setCouponNo(generateCouponNo());
   coupon.setStatus(1); // 未使用
   coupon.setGetTime(now);
   coupon.setExpireTime(expireTime);
   return coupon;
   }).collect(Collectors.toList());
  
   // 3. 批量保存并更新模板剩余数量
   userCouponRepository.saveAll(coupons);
   template.setRemainingCount(template.getRemainingCount() - userIds.size());
   templateRepository.save(template);
   }
  
   private String generateCouponNo() {
   // 生成唯一优惠券编号
   return UUID.randomUUID().toString().replace("-", "").substring(0, 16);
   }
  }
  ```
  
   2. 优惠券使用规则校验
  
  ```java
  // 优惠券使用规则校验服务
  public class CouponUsageValidator {
  
   @Autowired
   private CouponTemplateRepository templateRepository;
  
   @Autowired
   private UserCouponRepository userCouponRepository;
  
   public void validateCouponUsage(Long userId, Long couponId, BigDecimal orderAmount,
   List categoryIds, List productIds) {
   // 1. 检查优惠券是否存在且属于用户
   UserCoupon userCoupon = userCouponRepository.findByIdAndUserId(couponId, userId)
   .orElseThrow(() -> new RuntimeException("优惠券不存在或不属于当前用户"));
  
   if (userCoupon.getStatus() != 1) { // 未使用
   throw new RuntimeException("优惠券不可用");
   }
  
   if (userCoupon.getExpireTime().before(new Date())) {
   throw new RuntimeException("优惠券已过期");
   }
  
   // 2. 检查优惠券模板规则
   CouponTemplate template = templateRepository.findById(userCoupon.getTemplateId())
   .orElseThrow(() -> new RuntimeException("优惠券模板不存在"));
  
   // 检查最低订单金额
   if (template.getMinOrderAmount() != null && orderAmount.compareTo(template.getMinOrderAmount()) < 0) {
   throw new RuntimeException("订单金额不满足最低要求");
   }
  
   // 检查适用范围
   switch (template.getScope()) {
   case 1: // 全品类
   break;
   case 2: // 指定品类
   // 需要查询模板关联的品类并校验
   if (!isCategoriesMatch(template.getId(), categoryIds)) {
   throw new RuntimeException("优惠券不适用于当前商品品类");
   }
   break;
   case 3: // 指定商品
   // 需要查询模板关联的商品并校验
   if (!isProductsMatch(template.getId(), productIds)) {
   throw new RuntimeException("优惠券不适用于当前商品");
   }
   break;
   }
   }
  
   // 其他校验方法...
  }
  ```
  
   3. 优惠券计算服务
  
  ```java
  // 优惠券计算服务
  public class CouponCalculator {
  
   public BigDecimal calculateDiscount(BigDecimal orderAmount, CouponTemplate template) {
   switch (template.getType()) {
   case 1: // 满减券
   return template.getDiscountValue();
   case 2: // 折扣券
   return orderAmount.multiply(BigDecimal.valueOf(template.getDiscountValue()))
   .setScale(2, RoundingMode.DOWN);
   case 3: // 无门槛券
   return template.getDiscountValue();
   default:
   return BigDecimal.ZERO;
   }
   }
  
   public BigDecimal calculateFinalAmount(BigDecimal orderAmount, CouponTemplate template) {
   BigDecimal discount = calculateDiscount(orderAmount, template);
   return orderAmount.subtract(discount).max(BigDecimal.ZERO);
   }
  }
  ```
  
   四、前端交互流程
  
  1. 优惠券领取流程
   - 用户进入优惠券中心 → 查看可领取优惠券 → 点击领取 → 后端生成优惠券实例 → 返回领取结果
  
  2. 优惠券使用流程
   - 用户选择商品加入购物车 → 进入结算页 → 系统自动匹配可用优惠券 → 用户选择优惠券 → 系统校验并计算最终金额 → 提交订单
  
  3. 优惠券展示规则
   - 未使用:按有效期倒序排列
   - 已使用:展示使用时间和订单信息
   - 已过期:展示过期时间
  
   五、风控与防刷机制
  
  1. 发放限制
   - 同一用户同种优惠券领取上限
   - 每日/每周领取总量限制
   - 设备/IP限制
  
  2. 使用限制
   - 防止优惠券叠加使用(除非特别设计)
   - 防止订单拆分使用
   - 防止异常退款后重复使用
  
  3. 监控与报警
   - 实时监控优惠券领取和使用情况
   - 异常行为自动报警(如短时间内大量领取)
   - 定期审计优惠券使用数据
  
   六、性能优化建议
  
  1. 缓存策略
   - 热门优惠券模板缓存
   - 用户可用优惠券缓存
   - 优惠券规则校验结果缓存
  
  2. 异步处理
   - 优惠券发放采用消息队列异步处理
   - 优惠券使用统计异步更新
  
  3. 数据库优化
   - 用户优惠券表按状态和过期时间分区
   - 热门查询字段添加索引
   - 定期归档过期优惠券数据
  
   七、测试用例示例
  
  1. 正常场景
   - 领取并使用满减券
   - 领取并使用折扣券
   - 领取并使用无门槛券
  
  2. 边界场景
   - 订单金额刚好等于满减门槛
   - 订单金额略低于满减门槛
   - 优惠券刚好过期时使用
  
  3. 异常场景
   - 使用已使用的优惠券
   - 使用不存在的优惠券
   - 使用其他用户的优惠券
   - 叠加使用不可叠加的优惠券
  
  通过以上设计,可以实现一个功能完善、性能优良的美团买菜系统优惠券通用功能,满足业务需求并保证系统稳定性。
评论
  • 下一篇

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