1. 项目背景与技术选型
去年指导过一位计算机专业学生的毕业设计,他选择了"基于SpringBoot+Vue的手机销售网站"作为课题。这个选题非常典型——既包含了电商系统的通用功能模块,又能体现前后端分离架构的现代开发模式。对于计算机相关专业的毕业生来说,通过这个项目可以系统掌握企业级应用开发的全流程技能。
技术栈选择上,我们采用:
- 后端:SpringBoot 2.7 + MyBatis-Plus + MySQL 8.0
- 前端:Vue 3 + Element Plus + Axios
- 辅助工具:Maven 3.8 + Redis 6.2
这种组合在2023年企业级Java开发中占比超过62%(据JetBrains开发者调查报告),具有以下优势:
- SpringBoot的自动配置特性大幅减少了XML配置
- Vue的响应式开发模式比传统jQuery更高效
- MyBatis-Plus的代码生成器可节省80%的CRUD代码量
- Element Plus提供了可直接复用的专业级UI组件
2. 系统架构设计
2.1 整体架构
采用经典的三层架构:
code复制表现层(Vue) ←HTTP→ 业务层(SpringBoot) ←JDBC→ 数据层(MySQL)
↑ ↑
Redis RabbitMQ
2.2 数据库设计
核心表结构(简化版):
sql复制CREATE TABLE `phone` (
`id` bigint PRIMARY KEY AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '手机名称',
`price` decimal(10,2) NOT NULL COMMENT '售价',
`stock` int NOT NULL DEFAULT 0 COMMENT '库存',
`specs` json DEFAULT NULL COMMENT '规格参数JSON'
);
CREATE TABLE `order` (
`id` varchar(32) PRIMARY KEY COMMENT '订单号',
`user_id` bigint NOT NULL,
`total_amount` decimal(10,2) NOT NULL,
`status` tinyint NOT NULL DEFAULT 0 COMMENT '0-待支付 1-已支付'
);
CREATE TABLE `order_detail` (
`id` bigint PRIMARY KEY AUTO_INCREMENT,
`order_id` varchar(32) NOT NULL,
`phone_id` bigint NOT NULL,
`quantity` int NOT NULL
);
特别注意:价格字段必须使用decimal类型,float/double会导致精度丢失。这是电商系统最容易踩的坑之一。
3. 核心功能实现
3.1 商品展示模块
前端采用Vue3的Composition API:
javascript复制// PhoneList.vue
const state = reactive({
phones: [],
pagination: {
current: 1,
pageSize: 10,
total: 0
}
});
const fetchPhones = async () => {
const res = await axios.get('/api/phones', {
params: {
page: state.pagination.current,
size: state.pagination.pageSize
}
});
state.phones = res.data.records;
state.pagination.total = res.data.total;
};
后端SpringBoot接口:
java复制@RestController
@RequestMapping("/api/phones")
public class PhoneController {
@Autowired
private PhoneService phoneService;
@GetMapping
public Result<Page<Phone>> list(
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size) {
return Result.success(phoneService.page(new Page<>(page, size)));
}
}
3.2 购物车实现
关键技术点:
- 未登录用户使用localStorage存储
- 已登录用户同步到服务端Redis
- 采用Hash结构存储:
user:cart:{userId} -> {phoneId:quantity}
java复制// CartService.java
public void addToCart(Long userId, Long phoneId, Integer num) {
String key = "user:cart:" + userId;
if (redisTemplate.opsForHash().hasKey(key, phoneId.toString())) {
redisTemplate.opsForHash().increment(
key, phoneId.toString(), num);
} else {
redisTemplate.opsForHash().put(
key, phoneId.toString(), num.toString());
}
}
3.3 订单支付流程
典型状态机设计:
code复制待支付 → 支付成功 → 发货中 → 已完成
↓
取消订单
分布式事务处理方案:
- 本地消息表+定时任务
- 使用Seata AT模式(适合毕业设计演示)
java复制@GlobalTransactional
public String createOrder(OrderDTO orderDTO) {
// 1. 扣减库存
stockService.deduct(orderDTO.getPhoneId(), orderDTO.getQuantity());
// 2. 创建订单
Order order = new Order();
BeanUtils.copyProperties(orderDTO, order);
orderMapper.insert(order);
// 3. 记录支付任务
paymentTaskService.createTask(order.getId());
return order.getId();
}
4. 典型问题解决方案
4.1 跨域问题
前后端分离项目必遇问题,解决方案:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.maxAge(3600);
}
}
4.2 图片上传
采用阿里云OSS存储示例:
java复制public String upload(MultipartFile file) {
String fileName = UUID.randomUUID() +
file.getOriginalFilename().substring(
file.getOriginalFilename().lastIndexOf("."));
OSS ossClient = new OSSClientBuilder().build(
endpoint, accessKeyId, accessKeySecret);
ossClient.putObject(bucketName, fileName,
file.getInputStream());
ossClient.shutdown();
return "https://" + bucketName + "." + endpoint + "/" + fileName;
}
4.3 性能优化实践
-
缓存策略:
- 商品详情:Redis缓存 + 本地缓存Caffeine
- 热点数据:预先加载到Redis
-
查询优化:
java复制@Cacheable(value = "phone", key = "#id") public Phone getById(Long id) { return getById(id); } -
前端优化:
- 图片懒加载
- 路由懒加载
- 组件按需引入
5. 项目部署方案
5.1 开发环境
推荐组合:
- 后端:IDEA + Lombok插件
- 前端:VSCode + Volar插件
- 数据库:Docker运行MySQL
- 测试:Postman + Swagger UI
5.2 生产部署
- 后端打包:
bash复制mvn clean package -DskipTests
- 前端构建:
bash复制npm run build
- 使用Docker Compose编排:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
ports:
- "3306:3306"
redis:
image: redis:6.2
ports:
- "6379:6379"
app:
build: .
ports:
- "8080:8080"
depends_on:
- mysql
- redis
6. 答辩准备建议
-
技术亮点提炼:
- 前后端分离架构的优势
- 缓存策略对性能的提升
- 订单模块的分布式事务处理
-
演示重点:
- 商品搜索(Elasticsearch可加分)
- 购物车同步机制
- 支付流程的完整性
-
常见问题准备:
- 为什么选择Vue而不是React?
- 如何保证库存扣减的准确性?
- 系统能承受多大的并发量?
这个项目我指导的学生最终获得了优秀毕业设计。关键不在于功能有多复杂,而在于:
- 技术栈组合的合理性
- 对业务场景的深入理解
- 对典型问题的解决方案
- 完整的文档和规范的代码
建议在GitHub上建立私有仓库管理代码,使用Issues跟踪开发任务,这对答辩展示也是加分项。
