使用 Spring Boot + Vue.js 组合开发多商户商城(B2B2C平台)是一种高效的全栈技术方案,兼顾后端稳定性与前端灵活性。以下是该技术栈的核心实现思路、关键组件及典型场景的代码示例:
一、技术栈定位与优势
| 层级 | 技术选型 | 核心作用 |
|---|---|---|
| 后端 | Spring Boot(核心框架) Spring Cloud Alibaba(微服务治理) MyBatis-Plus(ORM) JWT(鉴权) Redis(缓存) | 提供高可用、可扩展的后端服务,支撑商家管理、交易、支付等复杂业务。 |
| 前端 | Vue.js 3(渐进式框架) Vue Router(路由) Pinia(状态管理) Vite(构建工具) Element Plus(UI组件库) | 实现响应式、模块化的前端界面,提升用户交互体验。 |
| 通信协议 | RESTful API(前后端分离) WebSocket(实时通知) | 解耦前后端,支持灵活的数据交互。 |
二、后端核心实现(Spring Boot)
1. 项目初始化
-
使用 Spring Initializr 创建基础项目,添加依赖:
xml<dependencies> <!-- Spring Boot Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- MyBatis-Plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3</version> </dependency> <!-- JWT --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.5</version> </dependency> <!-- Redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> </dependencies>
2. 商家入驻与商品管理
-
实体类设计 (
Shop.java,Product.java):java@Data @TableName("shop") // MyBatis-Plus 自动生成表 public class Shop { private Long id; private String name; // 店铺名称 private Integer status; // 审核状态(0:待审核, 1:已通过) private Date createTime; } @Data @TableName("product") public class Product { private Long id; private Long shopId; // 关联店铺ID private String name; private BigDecimal price; private Integer stock; // SKU库存 } -
商家审核接口(控制层示例):
java@RestController @RequestMapping("/api/shops") public class ShopController { @PostMapping("/apply") public ResponseEntity<String> applyShop(@RequestBody Shop shop) { shop.setStatus(0); // 默认待审核 shopService.save(shop); return ResponseEntity.ok("申请提交成功"); } @GetMapping("/{id}/products") public ResponseEntity<List<Product>> getShopProducts(@PathVariable Long id) { List<Product> products = productService.lambdaQuery() .eq(Product::getShopId, id) .list(); return ResponseEntity.ok(products); } }
3. 订单与支付流程
-
订单状态机(使用枚举管理状态流转):
javapublic enum OrderStatus { PENDING_PAYMENT(0, "待支付"), PAID(1, "已支付"), SHIPPED(2, "已发货"), COMPLETED(3, "已完成"), CANCELLED(4, "已取消"); private final int code; private final String desc; // 构造函数... } -
支付回调验证(集成微信支付示例):
java@RestController @RequestMapping("/api/payment") public class PaymentController { @PostMapping("/wechat/callback") public String wechatCallback(@RequestBody Map<String, String> data) { // 1. 验证签名(HMAC-SHA256) if (!WechatPayUtil.verifySign(data)) { return "FAIL"; } // 2. 更新订单状态为已支付 String orderId = data.get("out_trade_no"); orderService.updateStatus(orderId, OrderStatus.PAID); return "SUCCESS"; } }
三、前端核心实现(Vue.js 3)
1. 项目初始化
-
使用 Vite 创建 Vue 3 项目:
bashnpm create vite@latest mall-frontend -- --template vue cd mall-frontend npm install pinia element-plus @vueuse/core
2. 商家后台页面(商品列表)
-
组件结构 (
ShopProducts.vue):vue<template> <el-table :data="productList" stripe> <el-table-column prop="name" label="商品名称"></el-table-column> <el-table-column prop="price" label="价格"> <template #default="scope">¥{{ scope.row.price.toFixed(2) }}</template> </el-table-column> <el-table-column label="操作"> <template #default="scope"> <el-button size="small" @click="editProduct(scope.row)">编辑</el-button> <el-popconfirm title="确定下架?" @confirm="removeProduct(scope.row.id)"> <template #reference> <el-button size="small" type="danger">下架</el-button> </template> </el-popconfirm> </template> </el-table-column> </el-table> </template> <script setup> import { storeToRefs } from 'pinia'; import { useProductStore } from '@/stores/product'; const productStore = useProductStore(); const { productList } = storeToRefs(productStore); // 初始化加载数据 onMounted(async () => { await productStore.fetchProducts(); }); const removeProduct = async (id) => { await productStore.deleteProduct(id); }; </script>
3. 用户购物车逻辑
-
状态管理(Pinia Store) :
typescript// stores/cart.ts import { defineStore } from 'pinia'; export const useCartStore = defineStore('cart', { state: () => ({ items: [] as CartItem[], }), actions: { addItem(product: Product, quantity: number) { const existing = this.items.find(item => item.productId === product.id); if (existing) { existing.quantity += quantity; } else { this.items.push({ ...product, quantity }); } }, clear() { this.items = []; }, }, });
四、前后端协作关键点
1. 跨域问题解决
-
Spring Boot 配置 (允许指定域名访问):
java@Configuration public class CorsConfig { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:5173") // 前端开发地址 .allowedMethods("GET", "POST", "PUT", "DELETE") .allowCredentials(true); } }; } }
2. JWT 鉴权拦截器
-
Spring Boot 拦截器 (验证请求头中的 Token):
java@Component public class JwtAuthenticationInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token = request.getHeader("Authorization"); if (StringUtils.isBlank(token)) { response.setStatus(401); return false; } try { Claims claims = JwtUtil.parseToken(token); // 将用户信息存入上下文 UserContext.setCurrentUser(new User(claims.getSubject())); } catch (Exception e) { response.setStatus(401); return false; } return true; } }
五、进阶优化建议
| 方向 | 推荐方案 |
|---|---|
| 性能优化 | - 后端:Redis 缓存热门商品数据 - 前端:虚拟滚动(vue-virtual-scroll-list)处理长列表 |
| 实时通信 | 集成 WebSocket(Spring Boot + SockJS)推送订单状态变更 |
| 国际化 | 后端:MessageSource 多语言配置 前端:vue-i18n 动态切换语言 |
| 部署 | Docker Compose 编排(MySQL + Redis + Nginx + 后端服务) |
六、总结
Spring Boot + Vue.js 的组合能够高效覆盖多商户商城的核心需求:
- 后端:通过 Spring Boot 快速构建 RESTful API,结合 MyBatis-Plus 简化 CRUD,JWT 保障安全;
- 前端:Vue 3 + Pinia 实现组件化开发,Element Plus 加速 UI 构建,Vite 提升打包效率;
- 协作:清晰的接口规范(Swagger/OpenAPI)和跨域配置确保前后端无缝对接。
适合中小型电商团队快速迭代,后续可逐步引入微服务(Spring Cloud)、分布式事务(Seata)等架构升级。