一、功能概述
优惠券管理功能是电商平台提升用户活跃度、促进销售的重要工具。叮咚买菜系统的优惠券管理功能应包括优惠券的创建、发放、使用、统计等全生命周期管理。
二、核心功能模块
1. 优惠券类型管理
- 满减券:满指定金额可减免
- 折扣券:按比例折扣
- 无门槛券:可直接使用
- 运费券:减免配送费用
- 品类券:限定商品类别使用
- 新人券:仅限新用户使用
2. 优惠券创建与配置
```java
// 优惠券实体类示例
public class Coupon {
private Long id;
private String name;
private String type; // COUPON_TYPE_ENUM
private BigDecimal discountAmount; // 减免金额
private BigDecimal discountRate; // 折扣率
private BigDecimal minOrderAmount; // 最低订单金额
private Date startTime;
private Date endTime;
private Integer totalQuantity; // 总数量
private Integer remainingQuantity; // 剩余数量
private String适用范围; // ALL/CATEGORY/SKU
private List适用商品ID;
private String适用用户类型; // ALL/NEW/VIP等
// getters and setters
}
```
3. 优惠券发放方式
- 主动领取:用户在APP/小程序主动领取
- 系统发放:根据规则自动发放(如新用户注册、生日等)
- 分享发放:用户分享后获得
- 订单完成后发放:满足条件后发放下张优惠券
4. 优惠券使用流程
1. 用户选择商品加入购物车
2. 进入结算页面时显示可用优惠券
3. 用户选择使用或放弃使用
4. 系统验证优惠券有效性
5. 计算最终支付金额
5. 优惠券状态管理
- 未领取
- 已领取未使用
- 已使用
- 已过期
- 已作废
三、技术实现方案
1. 数据库设计
```sql
CREATE TABLE coupon_template (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
type VARCHAR(20) NOT NULL, -- FULL_REDUCTION, DISCOUNT, FREE_SHIPPING等
discount_amount DECIMAL(10,2),
discount_rate DECIMAL(5,2),
min_order_amount DECIMAL(10,2),
total_quantity INT NOT NULL,
remaining_quantity INT NOT NULL,
start_time DATETIME NOT NULL,
end_time DATETIME NOT NULL,
scope_type VARCHAR(20) NOT NULL, -- ALL, CATEGORY, SKU
scope_ids VARCHAR(1000), -- 逗号分隔的ID
user_type VARCHAR(20), -- ALL, NEW, VIP等
status VARCHAR(20) NOT NULL, -- ENABLED, DISABLED
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,
coupon_template_id BIGINT NOT NULL,
status VARCHAR(20) NOT NULL, -- AVAILABLE, USED, EXPIRED
order_id BIGINT, -- 使用订单ID
get_time DATETIME NOT NULL,
use_time DATETIME,
expire_time DATETIME NOT NULL,
FOREIGN KEY (coupon_template_id) REFERENCES coupon_template(id)
);
```
2. 核心服务实现
```java
@Service
public class CouponService {
@Autowired
private CouponTemplateRepository couponTemplateRepository;
@Autowired
private UserCouponRepository userCouponRepository;
// 创建优惠券模板
public CouponTemplate createCouponTemplate(CouponTemplateDTO dto) {
// 参数校验
// 保存到数据库
CouponTemplate template = new CouponTemplate();
// 设置属性...
return couponTemplateRepository.save(template);
}
// 用户领取优惠券
@Transactional
public UserCoupon领取优惠券(Long userId, Long templateId) {
CouponTemplate template = couponTemplateRepository.findById(templateId)
.orElseThrow(() -> new RuntimeException("优惠券不存在"));
if (template.getRemainingQuantity() <= 0) {
throw new RuntimeException("优惠券已领完");
}
// 检查用户是否符合领取条件
// ...
// 创建用户优惠券记录
UserCoupon userCoupon = new UserCoupon();
userCoupon.setUserId(userId);
userCoupon.setCouponTemplateId(templateId);
userCoupon.setStatus("AVAILABLE");
userCoupon.setExpireTime(template.getEndTime());
// 更新优惠券模板剩余数量
template.setRemainingQuantity(template.getRemainingQuantity() - 1);
couponTemplateRepository.save(template);
return userCouponRepository.save(userCoupon);
}
// 获取用户可用优惠券列表
public List getAvailableCoupons(Long userId) {
return userCouponRepository.findByUserIdAndStatusAndExpireTimeAfter(
userId, "AVAILABLE", new Date());
}
// 使用优惠券
@Transactional
public void useCoupon(Long userId, Long couponId, Long orderId) {
UserCoupon userCoupon = userCouponRepository.findByIdAndUserId(couponId, userId)
.orElseThrow(() -> new RuntimeException("优惠券不存在或不属于该用户"));
if (!"AVAILABLE".equals(userCoupon.getStatus())) {
throw new RuntimeException("优惠券不可用");
}
if (userCoupon.getExpireTime().before(new Date())) {
throw new RuntimeException("优惠券已过期");
}
// 更新优惠券状态
userCoupon.setStatus("USED");
userCoupon.setUseTime(new Date());
userCoupon.setOrderId(orderId);
userCouponRepository.save(userCoupon);
}
}
```
3. 优惠券核销接口
```java
@RestController
@RequestMapping("/api/coupon")
public class CouponController {
@Autowired
private CouponService couponService;
@PostMapping("/use")
public ResponseEntity<?> useCoupon(
@RequestParam Long userId,
@RequestParam Long couponId,
@RequestParam Long orderId) {
try {
couponService.useCoupon(userId, couponId, orderId);
return ResponseEntity.ok().build();
} catch (Exception e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
@GetMapping("/available")
public ResponseEntity> getAvailableCoupons(@RequestParam Long userId) {
List coupons = couponService.getAvailableCoupons(userId);
return ResponseEntity.ok(coupons);
}
}
```
四、前端实现要点
1. 优惠券领取页面:
- 展示可领取的优惠券列表
- 显示优惠券有效期、使用条件
- "立即领取"按钮
2. 结算页面优惠券选择:
- 显示用户拥有的可用优惠券
- 支持按金额、类型筛选
- 单选框选择要使用的优惠券
- 显示使用优惠券后的实付金额
3. 我的优惠券页面:
- 分类展示:未使用/已使用/已过期
- 显示优惠券详细信息
- 过期倒计时提醒
五、安全与风控考虑
1. 防止优惠券滥用:
- 限制单个用户领取数量
- 限制同一设备/IP领取频率
- 优惠券使用后不可退还
2. 数据一致性:
- 使用数据库事务确保优惠券发放和使用操作的原子性
- 考虑使用分布式锁防止并发问题
3. 异常处理:
- 优惠券过期检查
- 优惠券使用范围验证
- 订单金额是否满足使用条件验证
六、扩展功能
1. 优惠券分享功能:
- 生成分享链接或二维码
- 记录分享关系链
- 分享奖励机制
2. 优惠券组合使用:
- 支持多张优惠券叠加使用(需设计复杂的规则引擎)
3. 优惠券效果分析:
- 统计优惠券发放、使用、核销率
- 分析优惠券对订单金额、频次的影响
- A/B测试不同优惠券策略的效果
七、部署与监控
1. 监控指标:
- 优惠券发放数量/成功率
- 优惠券使用率
- 优惠券相关错误率
2. 告警机制:
- 优惠券库存不足告警
- 优惠券使用异常告警
3. 日志记录:
- 详细记录优惠券的发放、使用操作
- 记录用户领取行为用于分析
通过以上方案,叮咚买菜系统可以实现一个完整、高效、安全的优惠券管理功能,有效提升用户活跃度和平台销售额。