这个基于SpringBoot+Vue的网上购物商城系统是我在指导毕业设计过程中反复打磨的一个实战项目。作为电商类Java Web项目的典型代表,它完整实现了从商品展示、购物车管理到订单支付的全流程功能。采用前后端分离架构,后端使用SpringBoot 2.7 + MyBatis Plus,前端采用Vue 3 + Element Plus,数据库选用MySQL 8.0,是一套非常适合作为毕业设计或初级项目练手的解决方案。
在实际教学过程中发现,很多同学做电商系统时容易陷入几个误区:要么过度关注界面美观而忽略业务逻辑完整性,要么堆砌功能模块导致系统臃肿。这个项目经过多次迭代,保留了电商核心功能的同时保持了代码结构的清晰度。特别在权限控制(JWT)、缓存优化(Redis)和接口文档(Swagger)等企业级应用必备要素上都做了精心设计。
选择SpringBoot作为后端框架主要基于三点考虑:
spring-boot-starter-web依赖直接包含MVC核心组件spring-boot-starter-data-redis:集成Redis缓存spring-boot-starter-security:结合JWT做认证mybatis-plus-boot-starter:增强型ORM框架数据库选型时对比了MySQL和PostgreSQL:
Vue 3的组合式API相比选项式API更适合复杂交互场景:
javascript复制// 购物车数量控制示例
const handleCart = () => {
const cartItems = ref([])
const total = computed(() => cartItems.value.reduce((sum, item) => sum + item.price * item.quantity, 0))
const addItem = (product) => {
const existItem = cartItems.value.find(i => i.id === product.id)
existItem ? existItem.quantity++ : cartItems.value.push({...product, quantity: 1})
}
return { cartItems, total, addItem }
}
Element Plus作为UI库的优势:
采用JWT+Spring Security的方案,关键配置类:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/products").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager()));
}
}
常见问题处理:
@CrossOrigin注解商品表设计特别注意了扩展性:
sql复制CREATE TABLE `product` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`price` decimal(10,2) NOT NULL,
`stock` int NOT NULL DEFAULT '0',
`category_id` bigint NOT NULL,
`attributes` json DEFAULT NULL, -- 用于存储商品规格参数
PRIMARY KEY (`id`),
KEY `idx_category` (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
后台管理接口采用RESTful风格:
code复制GET /api/admin/products - 分页查询商品
POST /api/admin/products - 新增商品
PUT /api/admin/products/{id} - 更新商品
DELETE /api/admin/products/{id} - 删除商品
状态机设计保证订单流程严谨:
java复制public enum OrderStatus {
PENDING_PAYMENT(0, "待支付"),
PAID(1, "已支付"),
SHIPPED(2, "已发货"),
COMPLETED(3, "已完成"),
CANCELLED(-1, "已取消");
// 状态校验逻辑
public static boolean isValidTransition(int from, int to) {
// 实现状态转换规则校验
}
}
支付模块对接注意事项:
BigDecimal.compareTo()多级缓存架构设计:
缓存击穿解决方案:
java复制public Product getProductById(Long id) {
String cacheKey = "product:" + id;
// 1. 先查缓存
Product product = redisTemplate.opsForValue().get(cacheKey);
if (product == null) {
// 2. 获取分布式锁
RLock lock = redissonClient.getLock("lock:product:" + id);
try {
if (lock.tryLock(3, 10, TimeUnit.SECONDS)) {
// 3. 再次检查缓存(Double Check)
product = redisTemplate.opsForValue().get(cacheKey);
if (product == null) {
// 4. 查数据库
product = productMapper.selectById(id);
// 5. 回填缓存(设置随机过期时间防雪崩)
redisTemplate.opsForValue().set(cacheKey, product,
30 + (int)(Math.random() * 10), TimeUnit.MINUTES);
}
}
} finally {
lock.unlock();
}
}
return product;
}
索引优化方案:
(category_id, price)用于商品列表筛选order(user_id, create_time)避免回表查询FULLTEXT索引SQL优化示例:
sql复制-- 反例:N+1查询问题
SELECT * FROM orders WHERE user_id = 1; -- 获取10个订单
SELECT * FROM order_items WHERE order_id = ?; -- 循环执行10次
-- 正例:JOIN查询
SELECT o.*, oi.*
FROM orders o
LEFT JOIN order_items oi ON o.id = oi.order_id
WHERE o.user_id = 1;
推荐使用Docker Compose编排服务:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: mall
ports:
- "3306:3306"
volumes:
- ./mysql/data:/var/lib/mysql
redis:
image: redis:6
ports:
- "6379:6379"
volumes:
- ./redis/data:/data
app:
build: .
ports:
- "8080:8080"
depends_on:
- mysql
- redis
Nginx配置要点:
nginx复制server {
listen 80;
server_name mall.example.com;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://backend:8080;
proxy_set_header Host $host;
}
}
解决方案:
javascript复制// vue.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
}
}
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*")
.allowedHeaders("*");
}
}
常见坑点:
yaml复制spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
javascript复制const formData = new FormData()
formData.append('file', file)
formData.append('productId', productId)
axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
可拆分的服务模块:
使用Spring Cloud Alibaba组件:
基于ELK栈实现:
关键指标分析:
这个项目从技术选型到具体实现都经过实际验证,在指导学生的过程中不断完善。特别建议初学者重点关注三个核心流程:用户认证的JWT实现、商品详情页的缓存策略、订单状态机的设计模式。这些在企业级开发中都是通用性很强的技术点。