1. 项目概述与核心需求
作为一名经历过多次电商项目实战的开发者,我深知一个网上购物系统的毕业设计需要平衡技术深度与业务完整性。这个基于SpringBoot+Vue的电商系统,核心在于构建一个稳定可靠的交易链路,同时避免过度设计带来的复杂度。
电商系统的本质是处理"人-货-场"的关系。在毕业设计中,我们需要聚焦三个核心角色:用户(购买者)、商家(销售者)、管理员(规则制定者)。每个角色都有其关键诉求:
- 用户希望流畅的购物体验和安全的支付环境
- 商家需要便捷的商品管理和订单处理能力
- 管理员则关注系统稳定性和数据一致性
2. 技术架构设计
2.1 技术选型决策
选择SpringBoot 2.7 + Vue 2.x的组合主要基于以下考虑:
- 成熟度:这两个版本都是经过长期验证的稳定版本,社区资源丰富
- 学习曲线:相比更新的版本,2.x系列文档更完善,适合毕业设计场景
- 扩展性:足够支撑电商系统的基本需求,又不会引入过多复杂性
数据库选择MySQL 8.0而非NoSQL,因为:
- 电商系统需要严格的ACID事务支持
- 商品、订单等数据关系明确,适合关系型数据库
- JSON类型的支持可以处理商品规格等半结构化数据
2.2 架构分层设计
采用经典的三层架构,但针对电商特点做了优化:
code复制表现层(Vue)
↓
应用层(SpringBoot)
↓
领域层(业务逻辑)
↓
基础设施层(MySQL/Redis)
特别增加了缓存层和异步处理层:
- 缓存层:使用Redis缓存热点数据(商品详情、用户信息)
- 异步层:通过事件机制处理非核心流程(如发送通知、记录日志)
3. 数据库详细设计
3.1 核心表结构优化
商品表的设计采用了"垂直分表"策略:
sql复制-- 商品基础表
CREATE TABLE `product` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '商品名称',
`category_id` int NOT NULL COMMENT '分类ID',
`price` decimal(10,2) NOT NULL COMMENT '销售价',
`market_price` decimal(10,2) COMMENT '市场价',
`stock` int NOT NULL DEFAULT '0' COMMENT '库存',
`sales` int DEFAULT '0' COMMENT '销量',
`status` tinyint DEFAULT '1' COMMENT '状态(1-上架,0-下架)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 商品详情表(大字段分离)
CREATE TABLE `product_detail` (
`product_id` bigint NOT NULL,
`description` text COMMENT '商品详情',
`specifications` json COMMENT '规格参数',
`after_service` varchar(500) COMMENT '售后服务',
PRIMARY KEY (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
这种设计避免了查询商品列表时加载大字段带来的性能问题。
3.2 订单表设计要点
订单系统采用"分表"策略设计:
sql复制-- 订单主表
CREATE TABLE `order` (
`order_no` varchar(32) NOT NULL COMMENT '订单号',
`user_id` bigint NOT NULL,
`total_amount` decimal(10,2) NOT NULL COMMENT '订单总额',
`payment_amount` decimal(10,2) NOT NULL COMMENT '实付金额',
`status` tinyint NOT NULL COMMENT '订单状态',
`payment_time` datetime COMMENT '支付时间',
`deliver_time` datetime COMMENT '发货时间',
PRIMARY KEY (`order_no`),
KEY `idx_user_id` (`user_id`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 订单明细表(按订单号分片)
CREATE TABLE `order_item_2023` (
`id` bigint NOT NULL AUTO_INCREMENT,
`order_no` varchar(32) NOT NULL,
`product_id` bigint NOT NULL,
`quantity` int NOT NULL COMMENT '购买数量',
`unit_price` decimal(10,2) NOT NULL COMMENT '单价',
PRIMARY KEY (`id`),
KEY `idx_order_no` (`order_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
/*!50100 PARTITION BY KEY (order_no) */;
订单明细表按年份分表,避免单表数据过大影响查询性能。
4. 核心业务实现
4.1 商品服务实现
商品详情查询采用多级缓存策略:
java复制public ProductDetailVO getProductDetail(Long productId) {
// 1. 查询本地缓存
ProductDetailVO detail = localCache.get(productId);
if (detail != null) {
return detail;
}
// 2. 查询Redis缓存
String redisKey = "product:" + productId;
detail = redisTemplate.opsForValue().get(redisKey);
if (detail != null) {
localCache.put(productId, detail); // 回填本地缓存
return detail;
}
// 3. 查询数据库
detail = assembleProductDetail(productId);
if (detail == null) {
return null;
}
// 4. 写入缓存
redisTemplate.opsForValue().set(redisKey, detail, 30, TimeUnit.MINUTES);
localCache.put(productId, detail);
return detail;
}
库存扣减采用乐观锁+重试机制:
java复制@Transactional
public boolean reduceStock(Long productId, int quantity) {
int retry = 3;
while (retry-- > 0) {
Product product = productMapper.selectById(productId);
if (product.getStock() < quantity) {
return false;
}
int rows = productMapper.updateStock(
productId,
product.getStock() - quantity,
product.getVersion()
);
if (rows > 0) {
return true;
}
}
throw new BusinessException("库存扣减失败");
}
4.2 订单服务实现
订单创建流程是系统最复杂的部分,需要处理:
- 库存预占
- 订单生成
- 购物车清理
- 支付准备
采用分布式锁保证原子性:
java复制public String createOrder(OrderCreateDTO dto) {
RLock lock = redissonClient.getLock("order:create:" + dto.getUserId());
try {
// 获取分布式锁
if (!lock.tryLock(5, 10, TimeUnit.SECONDS)) {
throw new BusinessException("操作频繁,请稍后重试");
}
// 1. 验证并锁定库存
lockStock(dto.getItems());
// 2. 生成订单号(时间戳+随机数+用户ID哈希)
String orderNo = generateOrderNo(dto.getUserId());
// 3. 创建订单主表
Order order = buildOrder(dto, orderNo);
orderMapper.insert(order);
// 4. 创建订单明细
createOrderItems(orderNo, dto.getItems());
// 5. 清理购物车
clearCart(dto.getUserId(), dto.getCartItemIds());
return orderNo;
} finally {
lock.unlock();
}
}
5. 前端关键实现
5.1 Vue组件设计
商品卡片组件采用组合式API设计:
vue复制<template>
<div class="product-card">
<img :src="product.image" @click="goDetail"/>
<div class="info">
<h3 @click="goDetail">{{ product.name }}</h3>
<div class="price">
<span class="current">¥{{ product.price }}</span>
<span class="original" v-if="product.marketPrice">¥{{ product.marketPrice }}</span>
</div>
<el-button type="primary" size="small" @click="addToCart">
加入购物车
</el-button>
</div>
</div>
</template>
<script setup>
const props = defineProps({
product: {
type: Object,
required: true
}
});
const emit = defineEmits(['add-cart']);
const goDetail = () => {
router.push(`/product/${props.product.id}`);
};
const addToCart = () => {
emit('add-cart', props.product.id);
};
</script>
5.2 购物车管理
购物车状态管理采用Pinia:
javascript复制// stores/cart.js
export const useCartStore = defineStore('cart', {
state: () => ({
items: [],
selected: []
}),
getters: {
totalCount: (state) => state.items.reduce((sum, item) => sum + item.quantity, 0),
selectedItems: (state) => state.items.filter(item => state.selected.includes(item.id))
},
actions: {
async fetchCart() {
const { data } = await api.getCartItems();
this.items = data;
},
async addItem(productId, quantity = 1) {
await api.addToCart(productId, quantity);
await this.fetchCart();
}
}
});
6. 系统安全设计
6.1 接口安全防护
采用JWT + 权限控制:
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()
.antMatchers("/api/user/**").hasRole("USER")
.antMatchers("/api/merchant/**").hasRole("MERCHANT")
.antMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
6.2 支付安全
支付流程采用双重验证:
- 前端参数签名
- 服务端回调验证
java复制@RestController
@RequestMapping("/api/payment")
public class PaymentController {
@PostMapping("/notify")
public String paymentNotify(@RequestBody PaymentNotifyDTO notify,
HttpServletRequest request) {
// 1. 验证签名
if (!signatureService.verify(request)) {
throw new SecurityException("签名验证失败");
}
// 2. 验证订单状态
Order order = orderService.getByOrderNo(notify.getOrderNo());
if (order == null) {
throw new BusinessException("订单不存在");
}
// 3. 处理支付结果
paymentService.processPayment(order, notify);
return "success";
}
}
7. 性能优化实践
7.1 缓存策略优化
采用多级缓存架构:
- 浏览器缓存静态资源
- Nginx缓存热点API
- Redis缓存业务数据
- 本地缓存高频访问数据
缓存更新策略:
java复制@CacheEvict(value = "product", key = "#productId")
public void updateProduct(Product product) {
productMapper.updateById(product);
// 异步更新搜索引擎
searchService.asyncUpdateProduct(product);
}
7.2 数据库优化
慢查询优化示例:
sql复制-- 优化前的订单查询
SELECT * FROM orders WHERE user_id = 123 AND status = 1;
-- 优化后的订单查询
SELECT o.order_no, o.total_amount, o.status,
(SELECT COUNT(*) FROM order_items WHERE order_no = o.order_no) as item_count
FROM orders o FORCE INDEX(idx_user_status)
WHERE user_id = 123 AND status = 1
LIMIT 10;
8. 测试策略
8.1 单元测试重点
订单服务测试用例:
java复制@SpringBootTest
class OrderServiceTest {
@Autowired
private OrderService orderService;
@Test
@Transactional
void createOrder_shouldSuccessWhenStockEnough() {
// 准备测试数据
Long productId = prepareProduct(100); // 库存100
Long userId = prepareUser();
// 构造请求
OrderCreateDTO dto = new OrderCreateDTO();
dto.setUserId(userId);
dto.setItems(List.of(
new OrderItemDTO(productId, 1)
));
// 测试方法
String orderNo = orderService.createOrder(dto);
// 验证结果
assertNotNull(orderNo);
Order order = orderMapper.selectByOrderNo(orderNo);
assertEquals(1, order.getStatus());
}
}
8.2 压力测试方案
使用JMeter模拟并发场景:
- 商品查询压测:1000并发持续5分钟
- 下单流程压测:500并发,阶梯式增加
- 支付回调压测:模拟第三方回调
关键指标监控:
- 平均响应时间 < 500ms
- 错误率 < 0.1%
- 系统资源利用率 < 70%
9. 部署方案
9.1 生产环境部署
采用Docker Compose部署:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:6
ports:
- "6379:6379"
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
- redis
frontend:
build: ./frontend
ports:
- "80:80"
volumes:
mysql_data:
9.2 监控方案
基础监控配置:
- Spring Boot Actuator健康检查
- Prometheus + Grafana监控
- ELK日志收集
关键监控指标:
- JVM内存使用
- 数据库连接池状态
- 接口响应时间
- 缓存命中率
10. 项目总结与建议
10.1 技术收获
通过这个项目,可以深入掌握:
- 分布式系统数据一致性解决方案
- 高并发场景下的性能优化技巧
- 前后端分离架构的最佳实践
- 电商系统的核心业务流程
10.2 改进方向
如果时间允许,可以考虑:
- 引入微服务架构拆分模块
- 增加推荐算法提升转化
- 实现多级库存体系
- 加入秒杀功能场景
10.3 毕业设计建议
- 先简后繁:先实现核心流程,再完善辅助功能
- 文档同步:开发过程中及时记录设计决策
- 测试驱动:为关键功能编写测试用例
- 性能考量:即使小规模系统也要考虑扩展性
- 安全第一:不要忽视基础的安全防护
在答辩准备时,建议重点展示:
- 系统架构设计思路
- 解决的技术难点
- 完整的购物流程演示
- 性能优化方案
- 安全防护措施