叮咚买菜优惠券系统:全周期管理设计与技术实现
分类:IT频道
时间:2025-12-22 10:35
浏览:33
概述
一、功能概述 优惠券管理是电商平台的重要营销工具,叮咚买菜系统的优惠券管理功能应包含优惠券的创建、发放、使用、统计等全生命周期管理,支持多种优惠类型和发放方式。 二、核心功能模块设计 1.优惠券类型管理 -满减券:满指定金额减固定金额 -折扣券:按比例折扣(如8折)
内容
一、功能概述
优惠券管理是电商平台的重要营销工具,叮咚买菜系统的优惠券管理功能应包含优惠券的创建、发放、使用、统计等全生命周期管理,支持多种优惠类型和发放方式。
二、核心功能模块设计
1. 优惠券类型管理
- 满减券:满指定金额减固定金额
- 折扣券:按比例折扣(如8折)
- 无门槛券:可直接使用的固定金额券
- 运费券:抵扣配送费用的专用券
- 品类券:限定商品品类使用的优惠券
2. 优惠券创建与配置
```java
// 优惠券实体类示例
public class Coupon {
private Long id;
private String name; // 优惠券名称
private String type; // 优惠券类型
private BigDecimal amount; // 优惠金额/折扣比例
private BigDecimal minOrder; // 最低使用门槛
private Date startTime; // 生效时间
private Date endTime; // 失效时间
private Integer totalCount; // 发放总数
private Integer remainCount;// 剩余数量
private String适用范围; // 全场/指定品类/指定商品
private String userScope; // 全用户/新用户/指定用户
// getters & setters
}
```
3. 优惠券发放方式
- 自动发放:
- 新用户注册赠送
- 用户首次下单赠送
- 特定节日/活动自动发放
- 手动发放:
- 后台批量导入用户发放
- 通过分享链接/二维码领取
- 参与活动获得
4. 优惠券使用流程
1. 用户领取优惠券(主动领取或系统推送)
2. 优惠券存入用户账户(可查看可用优惠券列表)
3. 用户下单时选择可用优惠券
4. 系统验证优惠券有效性(时间、范围、门槛等)
5. 计算最终订单金额
5. 优惠券状态管理
- 未使用
- 已使用
- 已过期
- 已作废
三、数据库设计
```sql
-- 优惠券表
CREATE TABLE coupon (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
type VARCHAR(20) NOT NULL COMMENT 满减/折扣/无门槛/运费券,
amount DECIMAL(10,2) NOT NULL,
min_order DECIMAL(10,2) DEFAULT 0,
start_time DATETIME NOT NULL,
end_time DATETIME NOT NULL,
total_count INT DEFAULT 0,
remain_count INT DEFAULT 0,
scope_type VARCHAR(20) COMMENT 全场/品类/商品,
scope_ids VARCHAR(1000) COMMENT 适用范围ID集合,
user_scope VARCHAR(20) COMMENT 全用户/新用户/指定用户,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
status TINYINT DEFAULT 1 COMMENT 1-有效 0-无效
);
-- 用户优惠券表
CREATE TABLE user_coupon (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
coupon_id BIGINT NOT NULL,
get_time DATETIME DEFAULT CURRENT_TIMESTAMP,
use_time DATETIME,
order_id BIGINT,
status TINYINT DEFAULT 0 COMMENT 0-未使用 1-已使用 2-已过期 3-已作废,
FOREIGN KEY (coupon_id) REFERENCES coupon(id)
);
```
四、核心业务逻辑实现
1. 优惠券发放服务
```java
public class CouponService {
// 批量发放优惠券
public void batchIssueCoupons(List userIds, Long couponId) {
Coupon coupon = couponRepository.findById(couponId)
.orElseThrow(() -> new RuntimeException("优惠券不存在"));
if (coupon.getRemainCount() <= 0) {
throw new RuntimeException("优惠券已发放完毕");
}
for (Long userId : userIds) {
UserCoupon userCoupon = new UserCoupon();
userCoupon.setUserId(userId);
userCoupon.setCouponId(couponId);
userCoupon.setStatus(0); // 未使用
userCouponRepository.save(userCoupon);
// 更新剩余数量
coupon.setRemainCount(coupon.getRemainCount() - 1);
couponRepository.save(coupon);
}
}
// 用户领取优惠券
public void userReceiveCoupon(Long userId, Long couponId) {
// 验证优惠券是否存在且可领取
Coupon coupon = validateCoupon(couponId);
// 检查用户是否已有该优惠券
if (userCouponRepository.existsByUserIdAndCouponIdAndStatus(userId, couponId, 0)) {
throw new RuntimeException("您已领取过该优惠券");
}
// 发放优惠券
UserCoupon userCoupon = new UserCoupon();
userCoupon.setUserId(userId);
userCoupon.setCouponId(couponId);
userCoupon.setStatus(0);
userCouponRepository.save(userCoupon);
// 更新剩余数量
coupon.setRemainCount(coupon.getRemainCount() - 1);
couponRepository.save(coupon);
}
}
```
2. 优惠券使用验证
```java
public class CouponValidator {
public boolean validateCouponUsage(Long userId, Long couponId, BigDecimal orderAmount) {
UserCoupon userCoupon = userCouponRepository.findByUserIdAndCouponIdAndStatus(userId, couponId, 0);
if (userCoupon == null) {
return false;
}
Coupon coupon = couponRepository.findById(couponId)
.orElseThrow(() -> new RuntimeException("优惠券不存在"));
// 检查有效期
Date now = new Date();
if (now.before(coupon.getStartTime()) || now.after(coupon.getEndTime())) {
return false;
}
// 检查使用门槛
if (coupon.getMinOrder().compareTo(BigDecimal.ZERO) > 0 &&
orderAmount.compareTo(coupon.getMinOrder()) < 0) {
return false;
}
return true;
}
}
```
3. 订单结算时优惠券计算
```java
public class OrderService {
public Order calculateOrderWithCoupon(Order order, Long couponId) {
if (couponId == null) {
return order;
}
// 验证优惠券
if (!couponValidator.validateCouponUsage(order.getUserId(), couponId, order.getTotalAmount())) {
throw new RuntimeException("优惠券不可用");
}
Coupon coupon = couponRepository.findById(couponId)
.orElseThrow(() -> new RuntimeException("优惠券不存在"));
// 计算优惠金额
BigDecimal discountAmount = BigDecimal.ZERO;
if ("DISCOUNT".equals(coupon.getType())) {
// 折扣券计算
discountAmount = order.getTotalAmount()
.multiply(new BigDecimal("0." + coupon.getDiscountRate()))
.setScale(2, RoundingMode.HALF_UP);
} else {
// 满减/无门槛券
discountAmount = coupon.getAmount();
}
// 确保折扣后金额不小于0
BigDecimal finalAmount = order.getTotalAmount().subtract(discountAmount);
order.setFinalAmount(finalAmount.max(BigDecimal.ZERO));
// 标记优惠券为已使用
userCouponRepository.updateStatusToUsed(order.getUserId(), couponId);
return order;
}
}
```
五、前端交互设计
1. 优惠券领取页面
- 展示可用优惠券列表
- 显示优惠券详情(面额、有效期、使用条件)
- "立即领取"按钮
- 领取成功提示
2. 优惠券使用页面
- 订单结算页显示可用优惠券
- 支持按条件筛选优惠券
- 选择优惠券后实时计算优惠后金额
- 显示优惠券使用限制提示
3. 我的优惠券页面
- 分类展示(可用/已使用/已过期)
- 优惠券详情查看
- 优惠券使用记录
六、系统优化考虑
1. 高并发处理:
- 优惠券领取接口限流
- 使用Redis缓存热门优惠券信息
- 数据库乐观锁防止超发
2. 数据一致性:
- 事务管理确保优惠券发放和使用操作的原子性
- 定时任务清理过期优惠券
3. 监控与报警:
- 监控优惠券发放和使用量
- 预警优惠券库存不足情况
4. 扩展性设计:
- 支持未来新增优惠券类型
- 灵活配置优惠券规则
七、测试用例示例
1. 正常流程测试:
- 用户领取优惠券并成功使用
- 验证订单金额计算正确
2. 异常流程测试:
- 尝试使用过期优惠券
- 使用不满足门槛的优惠券
- 重复使用已使用的优惠券
3. 边界条件测试:
- 刚好满足满减门槛的订单
- 优惠券使用时间边界(生效前/失效后)
4. 性能测试:
- 高并发下优惠券领取
- 大量优惠券数据查询
通过以上设计实现,叮咚买菜系统的优惠券管理功能将能够支持复杂的营销场景,提升用户转化率和复购率,同时保证系统的稳定性和数据一致性。
评论