一、功能概述
优惠券管理是电商系统中重要的营销工具,叮咚买菜系统的优惠券管理功能应包括优惠券的创建、发放、使用、统计等全生命周期管理,支持多种类型的优惠券活动。
二、核心功能模块
1. 优惠券类型设计
- 满减券:满指定金额可减免
- 折扣券:按比例折扣
- 无门槛券:可直接使用
- 运费券:减免配送费用
- 品类券:限定商品类别使用
- 新人专享券:仅新用户可用
2. 优惠券创建与管理
```java
// 优惠券实体类示例
public class Coupon {
private Long id;
private String name;
private String type; // 类型:满减、折扣等
private BigDecimal discountAmount; // 减免金额或折扣比例
private BigDecimal minOrderAmount; // 最低订单金额
private Date startTime;
private Date endTime;
private Integer totalQuantity; // 总数量
private Integer remainingQuantity; // 剩余数量
private String applicableScope; // 适用范围:全平台/特定品类
private List excludeGoods; // 排除商品
private String userLevelLimit; // 用户等级限制
private String status; // 状态:未开始/进行中/已结束
// getters & setters
}
```
3. 优惠券发放方式
- 主动领取:用户在APP/小程序领取
- 系统自动发放:根据规则自动发放给符合条件的用户
- 分享发放:用户分享后获得
- 订单完成后发放:如评价后返券
4. 优惠券使用流程
1. 用户选择商品加入购物车
2. 结算时系统自动匹配可用优惠券
3. 用户选择使用或放弃优惠券
4. 系统验证优惠券有效性
5. 计算最终支付金额
三、技术实现方案
1. 数据库设计
```sql
CREATE TABLE coupon (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
type VARCHAR(20) NOT NULL,
discount_amount DECIMAL(10,2),
min_order_amount DECIMAL(10,2),
start_time DATETIME NOT NULL,
end_time DATETIME NOT NULL,
total_quantity INT,
remaining_quantity INT,
applicable_scope VARCHAR(255),
exclude_goods TEXT,
user_level_limit VARCHAR(50),
status VARCHAR(20) NOT NULL,
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_id BIGINT NOT NULL,
status VARCHAR(20) NOT NULL, -- 未使用/已使用/已过期
get_time DATETIME NOT NULL,
use_time DATETIME,
order_id BIGINT,
FOREIGN KEY (coupon_id) REFERENCES coupon(id)
);
```
2. 核心服务实现
优惠券发放服务
```java
@Service
public class CouponService {
@Autowired
private CouponRepository couponRepository;
@Autowired
private UserCouponRepository userCouponRepository;
// 用户领取优惠券
@Transactional
public boolean receiveCoupon(Long userId, Long couponId) {
Coupon coupon = couponRepository.findById(couponId)
.orElseThrow(() -> new RuntimeException("优惠券不存在"));
if (coupon.getRemainingQuantity() <= 0) {
throw new RuntimeException("优惠券已领完");
}
// 检查用户是否已有该优惠券
long count = userCouponRepository.countByUserIdAndCouponIdAndStatus(
userId, couponId, "UNUSED");
if (count > 0) {
throw new RuntimeException("您已领取过该优惠券");
}
// 创建用户优惠券记录
UserCoupon userCoupon = new UserCoupon();
userCoupon.setUserId(userId);
userCoupon.setCouponId(couponId);
userCoupon.setStatus("UNUSED");
userCoupon.setGetTime(new Date());
userCouponRepository.save(userCoupon);
// 更新优惠券剩余数量
coupon.setRemainingQuantity(coupon.getRemainingQuantity() - 1);
couponRepository.save(coupon);
return true;
}
// 自动发放优惠券(如新用户注册)
public void autoGrantCoupon(Long userId) {
// 查询符合条件的优惠券
List coupons = couponRepository.findByTypeAndStatus("NEW_USER", "ACTIVE");
for (Coupon coupon : coupons) {
UserCoupon userCoupon = new UserCoupon();
userCoupon.setUserId(userId);
userCoupon.setCouponId(coupon.getId());
userCoupon.setStatus("UNUSED");
userCoupon.setGetTime(new Date());
userCouponRepository.save(userCoupon);
}
}
}
```
优惠券使用服务
```java
@Service
public class OrderService {
@Autowired
private UserCouponRepository userCouponRepository;
@Autowired
private CouponRepository couponRepository;
// 使用优惠券
@Transactional
public Order useCoupon(Long userId, Long orderId, Long userCouponId) {
UserCoupon userCoupon = userCouponRepository.findByIdAndUserIdAndStatus(
userCouponId, userId, "UNUSED")
.orElseThrow(() -> new RuntimeException("优惠券不可用"));
Coupon coupon = couponRepository.findById(userCoupon.getCouponId())
.orElseThrow(() -> new RuntimeException("优惠券不存在"));
// 验证优惠券有效期
Date now = new Date();
if (now.before(coupon.getStartTime()) || now.after(coupon.getEndTime())) {
throw new RuntimeException("优惠券不在有效期内");
}
// 获取订单信息(简化版)
Order order = getOrderById(orderId);
// 验证订单金额是否满足条件
if (coupon.getMinOrderAmount() != null &&
order.getTotalAmount().compareTo(coupon.getMinOrderAmount()) < 0) {
throw new RuntimeException("订单金额不满足优惠券使用条件");
}
// 计算折扣后的金额
BigDecimal discountAmount = calculateDiscount(order, coupon);
order.setDiscountAmount(discountAmount);
order.setPayAmount(order.getTotalAmount().subtract(discountAmount));
// 更新优惠券状态
userCoupon.setStatus("USED");
userCoupon.setUseTime(new Date());
userCoupon.setOrderId(orderId);
userCouponRepository.save(userCoupon);
return order;
}
private BigDecimal calculateDiscount(Order order, Coupon coupon) {
switch (coupon.getType()) {
case "FIXED_AMOUNT":
return coupon.getDiscountAmount();
case "PERCENTAGE":
return order.getTotalAmount().multiply(
coupon.getDiscountAmount().divide(new BigDecimal(100)));
// 其他类型处理...
default:
return BigDecimal.ZERO;
}
}
}
```
3. 前端交互设计
1. 优惠券领取页面:
- 展示可领取的优惠券列表
- 显示优惠券面额、使用条件、有效期
- "立即领取"按钮
2. 我的优惠券页面:
- 分类展示:未使用/已使用/已过期
- 显示优惠券详细信息
- 使用按钮(结算时跳转)
3. 结算页面:
- 自动匹配可用优惠券
- 显示可用的优惠券列表
- 用户选择使用或放弃
四、关键业务规则
1. 优惠券有效期:严格验证使用时间是否在有效期内
2. 使用条件:验证订单金额是否满足最低消费要求
3. 适用范围:验证商品是否在优惠券适用范围内
4. 互斥规则:同一订单是否允许多张优惠券叠加使用
5. 退款处理:订单退款后优惠券是否返还
6. 防刷机制:防止用户通过非法手段大量领取优惠券
五、性能优化考虑
1. 缓存策略:
- 缓存热门优惠券信息
- 缓存用户可用优惠券列表
2. 数据库优化:
- 为常用查询字段建立索引
- 考虑分表策略(如按用户ID分表)
3. 异步处理:
- 优惠券发放可异步处理
- 优惠券使用统计可异步更新
六、扩展功能建议
1. 优惠券分享:用户可分享优惠券给好友
2. 优惠券组合:支持多张优惠券组合使用
3. 优惠券推荐:根据用户购买习惯推荐合适优惠券
4. AB测试:不同用户群体发放不同优惠券测试效果
5. 数据分析:优惠券使用情况分析,优化营销策略
七、安全考虑
1. 接口鉴权:所有优惠券相关接口需严格鉴权
2. 防刷机制:限制单个用户领取频率
3. 数据加密:敏感信息传输加密
4. 操作日志:记录优惠券发放、使用等关键操作
通过以上方案,可以实现叮咚买菜系统完整的优惠券管理功能,支持各种营销活动,提升用户活跃度和订单转化率。