1. 项目概述
这个基于Spring Boot和Vue.js的自助甜品商城系统,是我最近完成的一个电商类项目实战。作为一个全栈开发者,我选择这个甜品主题是因为发现目前市场上专门针对甜品垂直领域的电商平台并不多见,而甜品消费又有着明显的季节性特征和个性化需求。
系统采用现在主流的B/S架构,前端使用Vue.js构建响应式界面,后端基于Spring Boot框架,数据库选用MySQL 8.0。整个开发周期约3个月,从需求分析到最终上线测试,期间遇到了不少值得分享的技术挑战和解决方案。
2. 技术选型与架构设计
2.1 后端技术栈
选择Spring Boot作为后端框架主要基于以下几个考虑:
- 快速启动:内置Tomcat服务器,无需复杂配置即可运行
- 自动配置:根据项目依赖自动配置Spring应用
- 丰富的starter:整合了Spring Data JPA、Spring Security等常用组件
// 典型的Spring Boot启动类配置 @SpringBootApplication @MapperScan("com.dessert.mapper") public class DessertApplication { public static void main(String[] args) { SpringApplication.run(DessertApplication.class, args); } }数据库访问层使用MyBatis-Plus而非原生MyBatis,主要看中它提供的:
- 通用CRUD操作
- 强大的条件构造器
- 分页插件
- 代码生成器
2.2 前端技术栈
Vue 3.x作为前端框架的优势:
- 组件化开发:提高代码复用率
- 响应式数据绑定:简化DOM操作
- Vue Router:实现SPA体验
- Vuex:集中式状态管理
// 典型的Vue组件结构 export default { data() { return { desserts: [], loading: true } }, async created() { const res = await getDessertList() this.desserts = res.data this.loading = false } }2.3 系统架构图
客户端层(Browser/App) ↓ 表现层(Vue.js + Element UI) ↓ API网关(Spring Cloud Gateway) ↓ 业务层(Spring Boot) ↓ 数据访问层(MyBatis-Plus) ↓ 数据存储层(MySQL + Redis)3. 核心功能实现
3.1 用户认证模块
采用JWT(JSON Web Token)实现无状态认证,关键设计点:
- Token有效期设置为2小时
- 使用HS512算法签名
- 前端通过axios拦截器自动携带Token
// JWT生成核心代码 public String generateToken(Long userId, String username, String role) { Date now = new Date(); Date expiryDate = new Date(now.getTime() + 7200000); // 2小时有效期 return Jwts.builder() .setSubject(userId.toString()) .claim("username", username) .claim("role", role) .setIssuedAt(now) .setExpiration(expiryDate) .signWith(SignatureAlgorithm.HS512, secret) .compact(); }3.2 商品展示模块
实现要点:
- 多维度分类(按口味、季节、价格等)
- 支持模糊搜索
- 分页查询优化
// MyBatis-Plus分页查询示例 public Page<Dessert> getDessertPage(Integer pageNum, Integer pageSize, String keyword) { Page<Dessert> page = new Page<>(pageNum, pageSize); LambdaQueryWrapper<Dessert> wrapper = new LambdaQueryWrapper<>(); wrapper.like(StringUtils.isNotBlank(keyword), Dessert::getName, keyword); return dessertMapper.selectPage(page, wrapper); }3.3 购物车与订单模块
购物车设计考虑:
- 未登录用户使用浏览器本地存储
- 已登录用户同步到服务端
- 采用Redis缓存热门商品库存
订单状态机设计:
待支付 → 已支付 → 制作中 → 配送中 → 已完成 ↓ 已取消4. 关键问题与解决方案
4.1 高并发下的库存扣减
采用Redis + 数据库事务的方案:
- 预减Redis库存
- 创建订单
- 异步同步数据库
@Transactional public boolean reduceStock(Long dessertId, Integer quantity) { // 1. Redis预减库存 long stock = redisTemplate.opsForValue().decrement("dessert:stock:" + dessertId, quantity); if (stock < 0) { redisTemplate.opsForValue().increment("dessert:stock:" + dessertId, quantity); return false; } // 2. 数据库实际扣减 int affected = dessertMapper.reduceStock(dessertId, quantity); if (affected == 0) { redisTemplate.opsForValue().increment("dessert:stock:" + dessertId, quantity); throw new BusinessException("库存不足"); } return true; }4.2 支付模块集成
对接支付宝沙箱环境的关键配置:
# 支付宝配置 alipay.app-id=2021000122600000 alipay.gateway=https://openapi.alipaydev.com/gateway.do alipay.merchant-private-key=你的私钥 alipay.alipay-public-key=支付宝公钥 alipay.notify-url=/api/pay/callback4.3 性能优化实践
- Nginx配置静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 30d; add_header Cache-Control "public"; }- 启用MyBatis-Plus二级缓存
@Configuration @MapperScan("com.dessert.mapper") @EnableCaching public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; } }5. 系统测试与部署
5.1 测试策略
采用分层测试策略:
- 单元测试:JUnit + Mockito
- 接口测试:Postman + Swagger
- 压力测试:JMeter
5.2 典型测试用例
用户登录测试数据:
| 测试场景 | 输入数据 | 预期结果 | 实际结果 |
|---|---|---|---|
| 正确登录 | 正确用户名密码 | 登录成功 | 通过 |
| 错误密码 | 正确用户名+错误密码 | 提示密码错误 | 通过 |
| 空用户名 | 用户名为空 | 提示输入用户名 | 通过 |
5.3 部署方案
生产环境采用Docker Compose编排:
version: '3' services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root volumes: - ./mysql/data:/var/lib/mysql redis: image: redis:6.0 ports: - "6379:6379" backend: build: ./backend ports: - "8080:8080" depends_on: - mysql - redis frontend: build: ./frontend ports: - "80:80"6. 项目总结与改进方向
这个项目让我对电商系统的核心流程有了更深入的理解。在开发过程中,有几个特别值得注意的经验点:
库存一致性:最初没有考虑分布式事务,导致出现过超卖情况,后来引入Redis+消息队列才彻底解决。
支付回调:支付宝的异步通知需要做好幂等处理,避免重复通知导致业务异常。
前端性能:图片懒加载和组件按需加载对首屏性能提升明显。
后续改进方向:
- 引入Elasticsearch实现更强大的商品搜索
- 增加用户行为分析实现精准推荐
- 开发微信小程序端扩大用户覆盖面
整个项目从技术选型到最终上线,每个环节都让我收获颇丰。特别是面对高并发场景时的解决方案,让我对分布式系统有了更直观的认识。