1. 项目概述
这个家具商城系统采用SpringBoot+Vue3前后端分离架构,是典型的B2C电商平台实现方案。作为全栈开发者,我选择这套技术栈主要基于三点考量:SpringBoot能快速搭建稳定可靠的后台服务,Vue3的组合式API更适合复杂前端交互,而家具品类特有的商品展示需求(如3D预览、材质切换)正好能发挥Vue3的响应式优势。
系统包含六大核心模块:商品展示(支持SKU切换)、购物车管理、订单处理、支付对接、会员中心和后台管理系统。其中家具类商品特有的参数化搜索(材质/尺寸/颜色)和场景化展示(AR预览)是区别于普通电商的技术难点。
2. 技术架构设计
2.1 后端技术选型
采用SpringBoot 2.7 + MyBatis Plus组合,相比原生MyBatis:
- 自动分页插件简化家具商品列表查询
- 条件构造器便捷实现多维度筛选(如
lambdaQuery().eq(Furniture::getMaterialType, "实木")) - 代码生成器快速产出商品SPU/SKU相关DAO
数据库选用MySQL 8.0,关键表设计注意点:
CREATE TABLE `furniture_sku` ( `id` bigint NOT NULL COMMENT '实木家具存在多规格', `spu_id` bigint NOT NULL COMMENT '商品集ID', `wood_type` varchar(20) COMMENT '木材类型', `size_json` json COMMENT '尺寸数据{width,height,depth}', `inventory` int DEFAULT 0 COMMENT '大件家具库存特殊管理', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;2.2 前端技术方案
Vue3组合式API带来明显优势:
<script setup>简化代码结构- 自定义Hook复用家具展示逻辑(如useFurnitureGallery)
- Pinia管理全局状态(购物车存储方案对比):
| 方案 | 适用场景 | 家具商城选择原因 |
|---|---|---|
| localStorage | 简单数据持久化 | 无法处理复杂SKU结构 |
| IndexedDB | 大量结构化数据 | 学习成本高 |
| Pinia+持久化插件 | 状态管理+适度持久化 | 完美匹配商品收藏需求 |
3. 核心功能实现
3.1 商品三维展示
通过model-viewer实现Web端3D预览:
<model-viewer src="/models/sofa.glb" camera-controls auto-rotate ar @click="handleMaterialChange"> </model-viewer>配套后端需特殊处理GLB模型文件:
@GetMapping("/models/{name}") public ResponseEntity<Resource> getModelFile( @PathVariable String name) { // 家具模型文件通常较大,需分块传输 return ResponseEntity.ok() .header(HttpHeaders.CONTENT_TYPE, "model/gltf-binary") .body(new ByteArrayResource(modelService.getBytes(name))); }3.2 智能推荐系统
基于用户行为的协同过滤改进方案:
# 家具推荐需考虑品类特殊性 def calculate_similarity(user1, user2): # 给材质偏好更高权重 material_weight = 0.6 style_weight = 0.3 price_weight = 0.1 return (material_score * material_weight + style_score * style_weight + price_score * price_weight)4. 特殊业务处理
4.1 大件物流计算
家具配送需要特殊处理:
public BigDecimal calculateDeliveryFee(FurnitureItem item, String address) { // 根据体积重量计算 BigDecimal volumetricWeight = item.getLength() .multiply(item.getWidth()) .multiply(item.getHeight()) .divide(new BigDecimal("6000"), 2, RoundingMode.UP); // 偏远地区附加费 if (remoteAreaService.isRemote(address)) { return volumetricWeight.multiply(new BigDecimal("15")); } return volumetricWeight.multiply(new BigDecimal("10")); }4.2 组装服务对接
第三方服务集成示例:
// 前端调用组装服务API const bookAssembly = async (orderId) => { try { const response = await axios.post('/api/assembly', { orderId, contactPhone: userInfo.phone, // 家具组装需要提供详细产品信息 items: cartItems.map(item => ({ productCode: item.skuCode, assemblyGuideUrl: item.manualUrl })) }); } catch (error) { // 特别处理大件家具的预约失败 if(error.response?.data?.code === 'FULL_SLOT') { showAssemblyFullDialog(); } } }5. 性能优化实践
5.1 商品列表缓存
采用多级缓存策略:
- Redis缓存热门分类(客厅/卧室家具)
@Cacheable(value = "hotCategory", key = "#root.args[0]") public List<FurnitureSPU> getByCategory(String category) { // 数据库查询 }- Caffeine缓存单品详情
# application.yml caffeine: spec: maximumSize=1000,expireAfterWrite=10m5.2 图片加载优化
针对家具高清图处理:
<template> <img v-lazy="adaptiveImageUrl" :data-srcset="` ${thumbnailUrl} 480w, ${mediumUrl} 1024w, ${originalUrl} 1920w `"> </template> <script setup> // 根据设备DPR动态选择图片 const adaptiveImageUrl = computed(() => { return window.devicePixelRatio > 1 ? props.highResUrl : props.standardUrl; }); </script>6. 部署注意事项
6.1 容器化部署
Dockerfile特殊配置点:
# 前端构建 FROM node:16 as frontend-builder WORKDIR /app COPY furniture-web/ . RUN npm install --registry=https://registry.npmmirror.com RUN npm run build # 后端镜像需包含字体库(商品详情生成图片用) FROM openjdk:11-jdk RUN apt-get update && apt-get install -y fonts-wqy-zenhei COPY --from=frontend-builder /app/dist /static COPY furniture-api/target/*.jar app.jar6.2 安全防护
家具商城特有的安全措施:
- 防爬虫策略:限制商品详情页访问频率
@RateLimiter(value = 5, key = "#skuId") @GetMapping("/detail/{skuId}") public FurnitureDetail getDetail(@PathVariable Long skuId) { //... }- 价格防篡改:订单提交时二次校验
// 前端提交的价格签名 const signPrice = (price, timestamp) => { return md5(`${price}${timestamp}${SECRET_KEY}`); };7. 扩展功能方向
7.1 AR实景预览
使用WebXR API的典型实现:
navigator.xr.requestSession('immersive-ar').then(session => { session.requestReferenceSpace('local').then((refSpace) => { // 加载家具模型 const furnitureAnchor = new XRAnchor( furnitureModel, refSpace.getTransformTo(floorSpace) ); session.addAnchor(furnitureAnchor); }); });7.2 材质编辑器
前端实现方案核心代码:
class MaterialEditor { private textureMaps: Map<string, Texture> = new Map(); async changeMaterial(part: string, newTexture: File) { const imageBitmap = await createImageBitmap(newTexture); const texture = this.gl.createTexture(); this.gl.texImage2D(..., imageBitmap); this.textureMaps.set(part, texture); this.render(); } }关键提示:家具类电商需特别注意移动端适配,建议使用
@vueuse/core的useBreakpoints实现响应式布局:const { isMobile } = useBreakpoints({ mobile: 0, desktop: 1024 })