1. 项目概述与背景
去年帮朋友开发家具电商平台时,我深刻体会到传统家具行业数字化转型的痛点。线下展厅成本高、产品更新慢,而现有电商平台又难以展示家具的材质细节和使用场景。这个基于SpringBoot+Vue的在线家具商城系统,正是为了解决这些实际问题而设计的全栈解决方案。
系统采用主流的前后端分离架构,后端使用SpringBoot提供RESTful API服务,前端基于Vue.js实现动态交互。特别针对家具商品的特点,我们强化了图片展示功能和3D预览支持,让线上购物体验更贴近实体店感受。数据库选用MySQL 8.0,利用其JSON字段特性存储家具的多维度规格参数。
提示:系统设计时特别考虑了教学用途,所有业务模块都保留了清晰的开发轨迹和注释,非常适合作为Java全栈开发的实战案例。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计
2.1 技术栈选型解析
后端技术矩阵:
- SpringBoot 2.7:简化配置,内置Tomcat容器
- Spring Security + JWT:实现无状态认证
- MyBatis-Plus:增强型ORM框架
- Redis 6.x:缓存热点数据和秒杀库存
- RabbitMQ:异步处理订单通知
前端技术组合:
- Vue 3 Composition API:更好的逻辑复用
- Element Plus:UI组件库
- Axios:HTTP请求封装
- Vue Router:前端路由管理
- Pinia:状态管理替代Vuex
java复制// 典型Controller示例
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping
public Result<List<Product>> listByCategory(@RequestParam Long categoryId) {
return Result.success(productService.listByCategory(categoryId));
}
}
2.2 数据库设计精要
用户体系设计
用户表采用密码哈希存储(BCrypt加密),配合JWT实现安全认证。特别添加了last_login_ip字段用于安全审计。
sql复制CREATE TABLE `sys_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(50) COLLATE utf8mb4_bin NOT NULL,
`password_hash` varchar(100) COLLATE utf8mb4_bin NOT NULL,
`email` varchar(100) COLLATE utf8mb4_bin NOT NULL,
`avatar` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
`status` tinyint NOT NULL DEFAULT '1',
`register_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`user_id`),
UNIQUE KEY `idx_username` (`username`),
UNIQUE KEY `idx_email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
商品特色字段
针对家具商品特性,设计了材质、颜色、尺寸等JSON字段:
sql复制ALTER TABLE `product`
ADD COLUMN `specs` JSON DEFAULT NULL COMMENT '规格参数{
"material": "实木",
"color": ["胡桃色","白色"],
"dimensions": {
"length": 180,
"width": 90,
"height": 75
}
}';
3. 核心功能实现
3.1 商品展示系统
采用多级缓存策略提升响应速度:
- 浏览器本地缓存静态资源
- Nginx缓存商品详情页
- Redis缓存热门商品数据
- MySQL持久化存储
java复制// 商品服务缓存实现
@Service
public class ProductServiceImpl implements ProductService {
@Cacheable(value = "products", key = "#productId")
public Product getById(Long productId) {
return baseMapper.selectById(productId);
}
@CacheEvict(value = "products", key = "#productId")
public void updateProduct(Product product) {
updateById(product);
}
}
3.2 购物车设计
前端采用Pinia管理购物车状态,后端Redis存储未登录用户购物车数据。关键实现点:
- 合并登录前后购物车项
- 实时计算总价和优惠
- 库存预检查机制
javascript复制// 前端购物车Store示例
export const useCartStore = defineStore('cart', {
state: () => ({
items: [],
selected: []
}),
getters: {
totalPrice() {
return this.selected.reduce((sum, item) =>
sum + (item.price * item.quantity), 0)
}
},
actions: {
async mergeCart() {
// 合并本地与服务器购物车
}
}
})
4. 订单支付流程
4.1 状态机设计
使用Spring StateMachine实现订单状态流转:
code复制[待支付] --支付成功--> [待发货]
--支付超时--> [已取消]
[待发货] --发货--> [待收货]
[待收货] --确认收货--> [已完成]
4.2 支付对接
集成支付宝沙箱环境和微信支付模拟接口,关键安全措施:
- 支付参数签名验证
- 支付结果异步通知
- 订单金额与服务端校验
java复制// 支付回调处理
@PostMapping("/pay/notify")
public String handlePayNotify(@RequestBody String notifyData) {
// 1. 验证签名
if(!alipaySignature.verify(notifyData)){
return "failure";
}
// 2. 处理业务逻辑
orderService.processPaySuccess(notifyData);
return "success";
}
5. 后台管理系统
5.1 商品管理
实现功能:
- 富文本编辑器(整合WangEditor)
- 批量导入/导出
- SKU组合管理
- 定时上下架
5.2 数据统计
使用ECharts实现可视化:
- 销售趋势图
- 热销商品排名
- 用户地域分布
- 退货率分析
javascript复制// 销售统计组件
<template>
<div ref="chart" style="width:100%;height:400px"></div>
</template>
<script setup>
import * as echarts from 'echarts'
import { onMounted, ref } from 'vue'
const chart = ref(null)
onMounted(async () => {
const res = await getSalesData()
const myChart = echarts.init(chart.value)
myChart.setOption({
xAxis: { data: res.months },
yAxis: {},
series: [{ data: res.values }]
})
})
</script>
6. 部署与优化
6.1 容器化部署
Docker Compose编排方案:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
volumes:
- ./mysql:/var/lib/mysql
redis:
image: redis:6-alpine
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
- redis
frontend:
build: ./frontend
ports:
- "80:80"
6.2 性能优化实战
- SQL优化案例:
sql复制-- 优化前(全表扫描)
SELECT * FROM orders WHERE status = 'PAID' AND create_time > '2023-01-01';
-- 优化后(复合索引)
CREATE INDEX idx_status_createtime ON orders(status, create_time);
- 前端懒加载:
vue复制<template>
<img v-lazy="product.image" alt="家具图片">
</template>
<script>
import { useLazyload } from '@vueuse/core'
useLazyload()
</script>
7. 开发经验与避坑指南
- 跨域问题:开发环境配置代理,生产环境使用Nginx反向代理
javascript复制// vue.config.js
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
}
- 日期处理:统一使用Java 8的LocalDateTime和前端day.js
java复制// 后端全局格式化
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ISO_DATE_TIME));
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
}
}
- 图片上传:使用阿里云OSS存储,前端实现压缩和预览
javascript复制// 图片压缩处理
async function compressImage(file) {
return new Promise((resolve) => {
const reader = new FileReader()
reader.onload = (event) => {
const img = new Image()
img.onload = () => {
const canvas = document.createElement('canvas')
// 压缩逻辑...
canvas.toBlob(resolve, 'image/jpeg', 0.8)
}
img.src = event.target.result
}
reader.readAsDataURL(file)
})
}
这个项目从技术选型到最终部署,每个环节都经过实际验证。特别建议在开发商品详情页时,优先实现图片懒加载和骨架屏,这对家具类商品的用户体验提升非常明显。数据库设计阶段就要考虑好扩展性,比如我们后来增加的定制家具功能,就受益于早期的JSON字段设计。
