1. 项目背景与核心价值
去年双十一期间,我注意到本地商圈有家奶茶店推出了"买一送一"活动,但直到活动结束当天,店门口才挂出促销海报。这种低效的传统营销方式让我萌生了开发商家优惠活动小程序的想法。经过三个月的开发迭代,我们团队基于SpringBoot和微信小程序生态,打造了一个连接商家与消费者的数字化营销平台。
这个项目的核心价值在于解决了传统优惠活动的三大痛点:
- 信息不对称:消费者无法及时获取周边商家的优惠信息
- 参与门槛高:商家需要投入大量人力进行地推宣传
- 效果难追踪:无法量化评估营销活动的实际效果
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 整体技术栈选型
我们采用前后端分离架构,主要技术组件包括:
| 层级 | 技术选型 | 版本 | 选型理由 |
|---|---|---|---|
| 前端 | 微信小程序 | 2.16.1 | 免安装、用户基数大、开发成本低 |
| 后端 | SpringBoot | 2.5.6 | 快速构建、自动配置、内嵌Tomcat |
| 数据库 | MySQL | 8.0.26 | ACID支持、高并发性能 |
| ORM | MyBatis | 3.5.7 | SQL可控性强、动态SQL支持 |
| 缓存 | Redis | 6.2.5 | 优惠券秒杀、活动预热 |
2.2 关键架构决策
2.2.1 微信小程序与后端通信
采用HTTPS+JWT的认证方案,关键实现代码:
java复制// JWT生成工具类
public class JwtUtil {
private static final String SECRET = "your-secret-key";
private static final long EXPIRATION = 86400L; // 24小时
public static String generateToken(UserDetails userDetails) {
return Jwts.builder()
.setSubject(userDetails.getUsername())
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000))
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
}
}
2.2.2 高并发场景处理
针对秒杀类活动,我们设计了三级缓存策略:
- 本地缓存:Caffeine存储热点商品信息
- 分布式缓存:Redis集群存储库存信息
- 数据库:最终数据持久化
库存扣减的原子性操作示例:
java复制public boolean reduceStock(Long productId, int quantity) {
String lockKey = "product_lock:" + productId;
try {
// 分布式锁防止超卖
boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS);
if (!locked) return false;
// Lua脚本保证原子性
String script = "if redis.call('get', KEYS[1]) >= ARGV[1] then " +
"return redis.call('decrby', KEYS[1], ARGV[1]) " +
"else return -1 end";
Long result = redisTemplate.execute(
new DefaultRedisScript<>(script, Long.class),
Collections.singletonList("stock:" + productId),
String.valueOf(quantity));
return result != null && result >= 0;
} finally {
redisTemplate.delete(lockKey);
}
}
3. 核心功能实现
3.1 优惠活动管理模块
3.1.1 活动创建流程
商家用户创建优惠活动的完整时序:
- 前端校验表单数据
- 调用后端活动创建API
- 服务层验证商家权限
- 生成活动唯一ID
- 持久化到MySQL
- 预热到Redis
- 返回创建结果
关键实体设计:
java复制@Entity
@Table(name = "preferential_activities")
public class PreferentialActivity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 64)
private String title;
@ManyToOne
@JoinColumn(name = "merchant_id")
private Merchant merchant;
@Enumerated(EnumType.STRING)
private ActivityType type;
@Column(name = "start_time")
private LocalDateTime startTime;
@Column(name = "end_time")
private LocalDateTime endTime;
@Lob
private String content;
// 其他字段和方法...
}
3.1.2 活动推送机制
我们实现了三种推送策略:
- 地理围栏
