IT频道
美团买菜系统:优惠券多场景通用功能设计与实现
来源:     阅读:43
网站管理员
发布于 2025-09-23 23:45
查看主页
  
   一、功能概述
  
  美团买菜系统的优惠券通用功能需要支持多种类型的优惠券(满减券、折扣券、无门槛券等)在多个业务场景(商品购买、配送费减免、特定品类优惠等)下的通用使用。
  
   二、系统架构设计
  
   1. 优惠券服务模块
  - 优惠券核心服务:处理优惠券的创建、发放、查询、核销等核心逻辑
  - 优惠券规则引擎:动态解析和执行优惠券使用规则
  - 优惠券状态管理:跟踪优惠券的生命周期(未使用、已使用、已过期等)
  
   2. 数据库设计
  ```sql
  -- 优惠券模板表
  CREATE TABLE coupon_template (
   id BIGINT PRIMARY KEY AUTO_INCREMENT,
   name VARCHAR(100) NOT NULL,
   type TINYINT NOT NULL COMMENT 1-满减券 2-折扣券 3-无门槛券,
   discount_type TINYINT COMMENT 1-金额 2-比例,
   discount_value DECIMAL(10,2) NOT NULL,
   min_order_amount DECIMAL(10,2) DEFAULT 0,
   valid_days INT COMMENT 有效期天数,
   valid_start_time DATETIME,
   valid_end_time DATETIME,
   user_limit INT DEFAULT 1 COMMENT 每人限领数量,
   total_count INT NOT NULL,
   remaining_count INT NOT NULL,
   product_scope TINYINT COMMENT 1-全品类 2-指定品类 3-指定商品,
   product_ids TEXT COMMENT 指定商品ID列表,
   category_ids TEXT COMMENT 指定品类ID列表,
   status TINYINT DEFAULT 1 COMMENT 1-有效 0-无效,
   create_time DATETIME NOT NULL,
   update_time DATETIME NOT NULL
  );
  
  -- 用户优惠券表
  CREATE TABLE user_coupon (
   id BIGINT PRIMARY KEY AUTO_INCREMENT,
   user_id BIGINT NOT NULL,
   template_id BIGINT NOT NULL,
   coupon_code VARCHAR(32) NOT NULL,
   status TINYINT DEFAULT 0 COMMENT 0-未使用 1-已使用 2-已过期,
   order_id BIGINT COMMENT 关联订单ID,
   get_time DATETIME NOT NULL,
   use_time DATETIME,
   expire_time DATETIME NOT NULL,
   FOREIGN KEY (template_id) REFERENCES coupon_template(id)
  );
  ```
  
   三、核心功能实现
  
   1. 优惠券发放
  ```java
  public class CouponService {
  
   // 发放优惠券给用户
   public UserCoupon grantCoupon(Long userId, Long templateId) {
   CouponTemplate template = couponTemplateRepository.findById(templateId)
   .orElseThrow(() -> new RuntimeException("优惠券模板不存在"));
  
   // 检查用户是否已达到领取上限
   long userCount = userCouponRepository.countByUserIdAndTemplateId(userId, templateId);
   if (userCount >= template.getUserLimit()) {
   throw new RuntimeException("已达到领取上限");
   }
  
   // 创建用户优惠券
   UserCoupon userCoupon = new UserCoupon();
   userCoupon.setUserId(userId);
   userCoupon.setTemplateId(templateId);
   userCoupon.setCouponCode(generateCouponCode());
   userCoupon.setStatus(0); // 未使用
   userCoupon.setGetTime(new Date());
   userCoupon.setExpireTime(calculateExpireTime(template));
  
   // 更新模板剩余数量
   couponTemplateRepository.decreaseRemainingCount(templateId);
  
   return userCouponRepository.save(userCoupon);
   }
  
   private Date calculateExpireTime(CouponTemplate template) {
   if (template.getValidDays() != null && template.getValidDays() > 0) {
   return DateUtils.addDays(new Date(), template.getValidDays());
   }
   return template.getValidEndTime();
   }
  }
  ```
  
   2. 优惠券使用规则校验
  ```java
  public class CouponRuleValidator {
  
   public boolean validateCouponUsage(UserCoupon userCoupon, Order order) {
   CouponTemplate template = couponTemplateRepository.findById(userCoupon.getTemplateId())
   .orElseThrow(() -> new RuntimeException("优惠券模板不存在"));
  
   // 检查有效期
   if (userCoupon.getExpireTime().before(new Date())) {
   throw new RuntimeException("优惠券已过期");
   }
  
   // 检查订单金额是否满足最低要求
   if (template.getMinOrderAmount() > 0 &&
   order.getTotalAmount().compareTo(template.getMinOrderAmount()) < 0) {
   throw new RuntimeException("订单金额不满足最低要求");
   }
  
   // 检查商品/品类限制
   if (template.getProductScope() != null) {
   switch (template.getProductScope()) {
   case 1: // 全品类
   break;
   case 2: // 指定品类
   if (!checkCategoryMatch(order, template.getCategoryIds())) {
   throw new RuntimeException("优惠券不适用于订单中的商品");
   }
   break;
   case 3: // 指定商品
   if (!checkProductMatch(order, template.getProductIds())) {
   throw new RuntimeException("优惠券不适用于订单中的商品");
   }
   break;
   }
   }
  
   return true;
   }
  
   private boolean checkCategoryMatch(Order order, String categoryIds) {
   // 实现品类匹配逻辑
   return true;
   }
  
   private boolean checkProductMatch(Order order, String productIds) {
   // 实现商品匹配逻辑
   return true;
   }
  }
  ```
  
   3. 优惠券核销
  ```java
  public class OrderService {
  
   @Transactional
   public Order createOrderWithCoupon(OrderCreateRequest request, Long couponId) {
   // 1. 查询用户优惠券
   UserCoupon userCoupon = userCouponRepository.findByIdAndUserId(couponId, request.getUserId())
   .orElseThrow(() -> new RuntimeException("优惠券不存在或不属于该用户"));
  
   // 2. 验证优惠券使用条件
   couponRuleValidator.validateCouponUsage(userCoupon, convertToOrder(request));
  
   // 3. 计算订单金额
   Order order = convertToOrder(request);
   applyCouponDiscount(order, userCoupon);
  
   // 4. 更新优惠券状态
   userCoupon.setStatus(1); // 已使用
   userCoupon.setUseTime(new Date());
   userCoupon.setOrderId(order.getId());
   userCouponRepository.save(userCoupon);
  
   // 5. 保存订单
   return orderRepository.save(order);
   }
  
   private void applyCouponDiscount(Order order, UserCoupon userCoupon) {
   CouponTemplate template = couponTemplateRepository.findById(userCoupon.getTemplateId())
   .orElseThrow(() -> new RuntimeException("优惠券模板不存在"));
  
   switch (template.getType()) {
   case 1: // 满减券
   order.setTotalAmount(order.getTotalAmount().subtract(template.getDiscountValue()));
   break;
   case 2: // 折扣券
   order.setTotalAmount(order.getTotalAmount().multiply(
   new BigDecimal(1 - template.getDiscountValue().doubleValue())));
   break;
   case 3: // 无门槛券
   order.setTotalAmount(order.getTotalAmount().subtract(template.getDiscountValue()));
   break;
   }
  
   // 确保金额不为负
   if (order.getTotalAmount().compareTo(BigDecimal.ZERO) < 0) {
   order.setTotalAmount(BigDecimal.ZERO);
   }
   }
  }
  ```
  
   四、前端交互设计
  
   1. 优惠券列表展示
  ```javascript
  // 伪代码示例
  function fetchCoupons() {
   api.get(/api/coupons/my)
   .then(response => {
   const usableCoupons = response.data.filter(coupon =>
   coupon.status === 0 && new Date(coupon.expireTime) > new Date()
   );
   const expiredCoupons = response.data.filter(coupon =>
   coupon.status === 0 && new Date(coupon.expireTime) <= new Date()
   );
   const usedCoupons = response.data.filter(coupon => coupon.status === 1);
  
   renderCoupons(usableCoupons, usable);
   renderCoupons(expiredCoupons, expired);
   renderCoupons(usedCoupons, used);
   });
  }
  ```
  
   2. 订单结算页优惠券选择
  ```javascript
  function applyCoupon(couponId) {
   api.post(/api/orders/calculate, {
   cartItems: getCartItems(),
   couponId: couponId
   }).then(response => {
   updateOrderSummary(response.data);
   });
  }
  
  function renderCouponSelector(coupons) {
   const selector = document.getElementById(coupon-selector);
   selector.innerHTML = coupons.map(coupon => `
  

  
¥${coupon.discountValue}

  

  
${coupon.name}

  
${coupon.minOrderAmount > 0 ?
   `满${coupon.minOrderAmount}元可用` : 无门槛}

  

  
有效期至: ${formatDate(coupon.expireTime)}

  

   `).join();
  }
  ```
  
   五、关键技术点
  
  1. 分布式锁:在高并发场景下,使用Redis分布式锁防止优惠券超发
  ```java
  public class CouponLock {
   private static final String LOCK_PREFIX = "coupon:lock:";
  
   public boolean tryLock(Long templateId, long expireTime) {
   String key = LOCK_PREFIX + templateId;
   return redisTemplate.opsForValue().setIfAbsent(key, "1", expireTime, TimeUnit.SECONDS);
   }
  
   public void unlock(Long templateId) {
   String key = LOCK_PREFIX + templateId;
   redisTemplate.delete(key);
   }
  }
  ```
  
  2. 异步消息处理:使用消息队列处理优惠券发放和状态变更通知
  ```java
  @KafkaListener(topics = "coupon-events")
  public void handleCouponEvent(CouponEvent event) {
   switch (event.getType()) {
   case GRANTED:
   // 处理优惠券发放事件
   break;
   case USED:
   // 处理优惠券使用事件
   break;
   case EXPIRED:
   // 处理优惠券过期事件
   break;
   }
  }
  ```
  
  3. 缓存优化:对热门优惠券模板进行缓存
  ```java
  @Cacheable(value = "couponTemplates", key = "  templateId")
  public CouponTemplate getCouponTemplate(Long templateId) {
   return couponTemplateRepository.findById(templateId).orElse(null);
  }
  ```
  
   六、测试方案
  
  1. 单元测试:测试优惠券规则引擎的各种边界条件
  2. 集成测试:测试优惠券发放、查询、核销的全流程
  3. 压力测试:模拟高并发场景下的优惠券领取和使用
  4. 异常测试:测试过期优惠券、不符合条件的优惠券使用等场景
  
   七、部署与监控
  
  1. 监控指标:
   - 优惠券发放成功率
   - 优惠券核销率
   - 优惠券系统响应时间
   - 优惠券库存预警
  
  2. 日志记录:
   - 优惠券发放日志
   - 优惠券使用日志
   - 优惠券状态变更日志
  
  3. 报警机制:
   - 优惠券库存不足报警
   - 优惠券系统错误率过高报警
   - 优惠券核销异常报警
  
  通过以上设计,美团买菜系统可以实现一个灵活、高效、可扩展的优惠券通用功能,支持多种业务场景下的优惠券使用需求。
免责声明:本文为用户发表,不代表网站立场,仅供参考,不构成引导等用途。 IT频道
购买生鲜系统联系18310199838
广告
相关推荐
菜东家生鲜配送系统:破痛点、显优势,助企业战略转型
源本生鲜:以全链路数据闭环驱动精细化运营与利润增长
万象生鲜配送系统:智能比价、决策支持与采购优化全解析
观麦系统破局生鲜配送:从经验主义到数据智能的变革
智能调度助力生鲜配送:省时增效,降本提质新路径