SSM+Vue全栈果蔬商城开发实战

1. 项目概述:SSM+Vue全栈果蔬商城的技术架构

这个基于SSM(Spring+SpringMVC+MyBatis)和Vue.js的全栈项目,是一个典型的B2C电商平台实现。从技术选型来看,项目采用了Java生态中成熟的SSM框架作为后端支撑,配合前端领域流行的Vue.js框架,形成了前后端分离的现代化Web应用架构。这种组合既能保证后端业务逻辑的稳定处理,又能提供流畅的前端交互体验。

在实际开发中,这样的技术栈选择体现了几个关键考量:首先,SSM框架组合经过了大量企业级项目的验证,特别适合需要处理复杂业务逻辑的电商系统;其次,Vue.js的响应式特性和组件化开发模式,能够高效构建用户友好的商品展示和交易界面;最后,前后端分离的架构使得团队协作更加清晰,也便于后续的维护和扩展。

提示:虽然项目标题中只提到了SSM和Vue,但完整的电商系统通常还会涉及Redis缓存、消息队列、支付接口集成等组件,这些在具体实现时都需要考虑。

2. 环境准备与项目搭建

2.1 后端开发环境配置

后端基于SSM框架,需要准备以下环境:

  1. JDK 1.8或以上版本 - 这是运行Spring框架的基础
  2. Apache Maven 3.6+ - 用于依赖管理和项目构建
  3. Tomcat 8.5+或Jetty 9.4+ - 作为Servlet容器
  4. MySQL 5.7或MariaDB 10.3+ - 主要业务数据存储

在IDEA或Eclipse中创建Maven项目后,需要在pom.xml中配置SSM相关依赖。关键依赖包括:

  • Spring核心框架(spring-context, spring-webmvc)
  • MyBatis核心(mybatis, mybatis-spring)
  • 数据库连接(mysql-connector-java)
  • 其他工具类(jackson-databind用于JSON处理,commons-lang3等)

2.2 前端开发环境搭建

前端Vue.js环境需要:

  1. Node.js 14.x或以上版本
  2. Vue CLI 4.x或以上
  3. 推荐使用VS Code作为开发IDE,配合Vetur插件

创建Vue项目后,需要安装的核心依赖包括:

  • vue-router - 实现前端路由
  • axios - 处理HTTP请求
  • element-ui或vant - UI组件库
  • vuex - 状态管理

3. 数据库设计与实现

3.1 核心表结构设计

一个果蔬商城通常需要以下核心数据表:

  1. 用户表(user)

    CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL COMMENT '登录名', `password` varchar(100) NOT NULL COMMENT '密码', `phone` varchar(20) DEFAULT NULL COMMENT '手机号', `email` varchar(100) DEFAULT NULL COMMENT '邮箱', `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `idx_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
  2. 商品表(product)

    CREATE TABLE `product` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `category_id` bigint(20) NOT NULL COMMENT '分类ID', `name` varchar(100) NOT NULL COMMENT '商品名称', `sub_title` varchar(200) DEFAULT NULL COMMENT '商品副标题', `main_image` varchar(255) DEFAULT NULL COMMENT '主图', `sub_images` text COMMENT '子图,多个图片用逗号分隔', `detail` text COMMENT '商品详情', `price` decimal(10,2) NOT NULL COMMENT '价格', `stock` int(11) NOT NULL DEFAULT '0' COMMENT '库存', `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '状态:1-在售 0-下架', `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_category_id` (`category_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
  3. 订单表(order)

    CREATE TABLE `order` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `order_no` varchar(50) NOT NULL COMMENT '订单编号', `user_id` bigint(20) NOT NULL COMMENT '用户ID', `payment` decimal(10,2) DEFAULT NULL COMMENT '实付金额', `payment_type` tinyint(4) DEFAULT NULL COMMENT '支付类型', `postage` decimal(10,2) DEFAULT NULL COMMENT '运费', `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态:0-已取消 1-未付款 2-已付款 3-已发货 4-交易成功 5-交易关闭', `payment_time` datetime DEFAULT NULL COMMENT '支付时间', `send_time` datetime DEFAULT NULL COMMENT '发货时间', `end_time` datetime DEFAULT NULL COMMENT '交易完成时间', `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `idx_order_no` (`order_no`), KEY `idx_user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';

3.2 MyBatis映射文件配置

对于商品表的操作,典型的Mapper XML配置如下:

<!-- ProductMapper.xml --> <mapper namespace="com.fruit.mapper.ProductMapper"> <resultMap id="BaseResultMap" type="com.fruit.entity.Product"> <id column="id" property="id" jdbcType="BIGINT"/> <result column="category_id" property="categoryId" jdbcType="BIGINT"/> <result column="name" property="name" jdbcType="VARCHAR"/> <result column="sub_title" property="subTitle" jdbcType="VARCHAR"/> <!-- 其他字段映射 --> </resultMap> <select id="selectByPrimaryKey" resultMap="BaseResultMap"> select * from product where id = #{id} </select> <select id="selectByCategoryId" resultMap="BaseResultMap"> select * from product where category_id = #{categoryId} and status = 1 order by created desc </select> <update id="reduceStock"> update product set stock = stock - #{quantity} where id = #{productId} and stock >= #{quantity} </update> </mapper>

4. 后端核心功能实现

4.1 Spring MVC控制器设计

商品模块的典型Controller实现:

@RestController @RequestMapping("/product") public class ProductController { @Autowired private ProductService productService; @GetMapping("/{id}") public Result<Product> detail(@PathVariable Long id) { Product product = productService.getProductDetail(id); return Result.success(product); } @GetMapping("/category/{categoryId}") public Result<List<Product>> listByCategory( @PathVariable Long categoryId, @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize) { PageInfo<Product> pageInfo = productService.getProductsByCategory( categoryId, pageNum, pageSize); return Result.success(pageInfo.getList()) .withTotal(pageInfo.getTotal()); } @PostMapping("/reduceStock") public Result<Boolean> reduceStock(@RequestBody List<CartItem> cartItems) { boolean success = productService.reduceStock(cartItems); return success ? Result.success(true) : Result.error("库存不足"); } }

4.2 服务层与事务管理

商品服务的实现需要考虑事务一致性:

@Service public class ProductServiceImpl implements ProductService { @Autowired private ProductMapper productMapper; @Transactional @Override public boolean reduceStock(List<CartItem> cartItems) { // 先检查所有商品库存是否充足 for (CartItem item : cartItems) { Product product = productMapper.selectByPrimaryKey(item.getProductId()); if (product.getStock() < item.getQuantity()) { throw new BusinessException("商品["+product.getName()+"]库存不足"); } } // 扣减库存 for (CartItem item : cartItems) { int affectedRows = productMapper.reduceStock( item.getProductId(), item.getQuantity()); if (affectedRows == 0) { throw new BusinessException("扣减库存失败"); } } return true; } }

5. 前端Vue实现

5.1 商品列表组件

使用Vue+Element UI实现商品列表:

<template> <div class="product-list"> <el-row :gutter="20"> <el-col v-for="product in products" :key="product.id" :xs="12" :sm="8" :md="6" :lg="4"> <el-card :body-style="{ padding: '0px' }" shadow="hover"> <img :src="product.mainImage" class="product-image"> <div style="padding: 14px;"> <h4>{{ product.name }}</h4> <p class="sub-title">{{ product.subTitle }}</p> <div class="price">¥{{ product.price }}</div> <div class="bottom"> <el-button type="primary" size="small" @click="addToCart(product)"> 加入购物车 </el-button> </div> </div> </el-card> </el-col> </el-row> <el-pagination background layout="prev, pager, next" :total="total" :page-size="pageSize" @current-change="handlePageChange"> </el-pagination> </div> </template> <script> import { getProductsByCategory } from '@/api/product' export default { data() { return { products: [], pageNum: 1, pageSize: 12, total: 0 } }, created() { this.loadProducts() }, methods: { async loadProducts() { const res = await getProductsByCategory( this.$route.params.categoryId, this.pageNum, this.pageSize ) this.products = res.data this.total = res.total }, handlePageChange(pageNum) { this.pageNum = pageNum this.loadProducts() }, addToCart(product) { this.$store.dispatch('cart/addToCart', { productId: product.id, quantity: 1 }) } } } </script>

5.2 Vuex状态管理

购物车状态管理实现:

// store/modules/cart.js const state = { items: JSON.parse(localStorage.getItem('cartItems')) || [] } const mutations = { ADD_ITEM(state, item) { const existing = state.items.find(i => i.productId === item.productId) if (existing) { existing.quantity += item.quantity } else { state.items.push(item) } localStorage.setItem('cartItems', JSON.stringify(state.items)) }, REMOVE_ITEM(state, productId) { state.items = state.items.filter(i => i.productId !== productId) localStorage.setItem('cartItems', JSON.stringify(state.items)) }, CLEAR_CART(state) { state.items = [] localStorage.removeItem('cartItems') } } const actions = { addToCart({ commit }, item) { commit('ADD_ITEM', item) }, removeFromCart({ commit }, productId) { commit('REMOVE_ITEM', productId) }, clearCart({ commit }) { commit('CLEAR_CART') } } export default { namespaced: true, state, mutations, actions }

6. 前后端交互与API设计

6.1 RESTful API规范

项目采用RESTful风格设计API,主要端点包括:

资源GET(查询)POST(创建)PUT(更新)DELETE(删除)
/products获取商品列表创建新商品--
/products/{id}获取单个商品详情-更新商品信息删除商品
/categories获取所有分类添加新分类--
/cart获取购物车内容添加商品到购物车更新购物车商品数量从购物车移除商品
/orders获取订单列表创建新订单--
/orders/{id}获取订单详情-更新订单状态取消订单

6.2 Axios请求封装

前端对Axios的通用封装:

// src/utils/request.js import axios from 'axios' import { Message } from 'element-ui' import store from '@/store' // 创建axios实例 const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, timeout: 10000 }) // 请求拦截器 service.interceptors.request.use( config => { // 如果存在token,则每个请求都带上token if (store.getters.token) { config.headers['Authorization'] = `Bearer ${store.getters.token}` } return config }, error => { console.log(error) return Promise.reject(error) } ) // 响应拦截器 service.interceptors.response.use( response => { const res = response.data // 业务错误处理 if (res.code !== 200) { Message({ message: res.message || 'Error', type: 'error', duration: 5 * 1000 }) // 特定状态码处理 if (res.code === 401) { // 跳转到登录页 } return Promise.reject(new Error(res.message || 'Error')) } else { return res } }, error => { console.log('err' + error) Message({ message: error.message, type: 'error', duration: 5 * 1000 }) return Promise.reject(error) } ) export default service

7. 项目部署与优化

7.1 后端部署方案

推荐使用以下方式部署SSM后端:

  1. 传统WAR包部署

    # 打包 mvn clean package # 将target/*.war复制到Tomcat的webapps目录 cp target/fruit-shop.war /opt/tomcat/webapps/ # 启动Tomcat /opt/tomcat/bin/startup.sh
  2. Spring Boot内嵌容器部署如果改造为Spring Boot项目,可以使用:

    # 打包可执行JAR mvn clean package # 运行 java -jar target/fruit-shop.jar --spring.profiles.active=prod

7.2 前端部署优化

Vue项目生产环境部署前需要进行优化:

  1. 构建优化配置(vue.config.js)

    module.exports = { productionSourceMap: false, configureWebpack: { optimization: { splitChunks: { chunks: 'all', cacheGroups: { libs: { name: 'chunk-libs', test: /[\\/]node_modules[\\/]/, priority: 10, chunks: 'initial' }, elementUI: { name: 'chunk-elementUI', priority: 20, test: /[\\/]node_modules[\\/]_?element-ui(.*)/ } } } } } }
  2. Nginx配置示例

    server { listen 80; server_name fruitshop.example.com; location / { root /usr/share/nginx/html/fruit-shop; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://backend:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }

7.3 性能优化建议

  1. 数据库层面

    • 为常用查询字段添加合适索引
    • 对大表考虑分库分表策略
    • 使用连接池控制连接数(如HikariCP)
  2. 缓存策略

    @Service public class ProductServiceImpl implements ProductService { @Autowired private RedisTemplate<String, Object> redisTemplate; @Override public Product getProductDetail(Long id) { String cacheKey = "product:" + id; Product product = (Product) redisTemplate.opsForValue().get(cacheKey); if (product == null) { product = productMapper.selectByPrimaryKey(id); if (product != null) { redisTemplate.opsForValue().set( cacheKey, product, 30, TimeUnit.MINUTES); } } return product; } }
  3. 前端性能

    • 使用路由懒加载
    • 组件异步加载
    • 图片懒加载
    • 启用Gzip压缩

8. 常见问题与解决方案

8.1 跨域问题处理

在Spring MVC中配置全局跨域支持:

@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }

8.2 文件上传实现

商品图片上传的Controller实现:

@RestController @RequestMapping("/upload") public class UploadController { @Value("${file.upload-dir}") private String uploadDir; @PostMapping("/image") public Result<String> uploadImage(@RequestParam("file") MultipartFile file) { if (file.isEmpty()) { return Result.error("请选择文件"); } try { // 生成唯一文件名 String fileName = UUID.randomUUID() + file.getOriginalFilename().substring( file.getOriginalFilename().lastIndexOf(".")); // 确保目录存在 File dir = new File(uploadDir); if (!dir.exists()) { dir.mkdirs(); } // 保存文件 File dest = new File(uploadDir + fileName); file.transferTo(dest); // 返回访问路径 return Result.success("/uploads/" + fileName); } catch (IOException e) { e.printStackTrace(); return Result.error("上传失败"); } } }

8.3 表单重复提交处理

使用Redis实现简单防重:

@RestController @RequestMapping("/order") public class OrderController { @Autowired private RedisTemplate<String, String> redisTemplate; @PostMapping("/create") public Result<String> createOrder(@RequestBody OrderForm form, HttpServletRequest request) { // 获取用户token作为用户标识 String token = request.getHeader("Authorization"); if (token == null) { return Result.error("未登录"); } // 生成请求指纹:用户+商品+时间戳(分钟级) String fingerprint = token + ":" + form.getItems().stream() .map(i -> i.getProductId().toString()) .collect(Collectors.joining(",")) + ":" + System.currentTimeMillis() / (1000 * 60); // 检查是否已处理过相同请求 if (redisTemplate.opsForValue().setIfAbsent( "order:submit:" + fingerprint, "1", 5, TimeUnit.MINUTES)) { // 正常处理订单 return orderService.createOrder(form); } else { return Result.error("请勿重复提交订单"); } } }

9. 项目扩展方向

9.1 微服务化改造

随着业务增长,可以考虑将单体应用拆分为微服务:

  1. 服务拆分方案

    • 用户服务:处理用户注册、登录、个人信息
    • 商品服务:商品管理、分类管理、库存管理
    • 订单服务:订单创建、状态管理
    • 支付服务:集成各种支付渠道
    • 推荐服务:基于用户行为的商品推荐
  2. 技术选型

    • Spring Cloud Alibaba全家桶
    • Nacos作为注册中心和配置中心
    • Sentinel实现流量控制
    • Seata处理分布式事务

9.2 管理后台实现

基于Vue Element Admin实现管理后台:

  1. 核心功能模块

    • 商品管理:CRUD、上下架、库存调整
    • 订单管理:订单查询、状态修改、导出
    • 用户管理:用户查询、禁用/启用
    • 数据统计:销售数据可视化
  2. 典型页面实现

    <template> <div class="product-manage"> <el-card> <div slot="header"> <span>商品列表</span> <el-button type="primary" size="small" @click="handleCreate" style="float: right;"> 添加商品 </el-button> </div> <el-table :data="products" border> <el-table-column prop="id" label="ID" width="80"></el-table-column> <el-table-column prop="name" label="商品名称"></el-table-column> <el-table-column prop="price" label="价格" width="120"> <template slot-scope="scope"> ¥{{ scope.row.price }} </template> </el-table-column> <el-table-column prop="stock" label="库存" width="100"></el-table-column> <el-table-column prop="status" label="状态" width="100"> <template slot-scope="scope"> <el-tag :type="scope.row.status ? 'success' : 'danger'"> {{ scope.row.status ? '在售' : '下架' }} </el-tag> </template> </el-table-column> <el-table-column label="操作" width="180"> <template slot-scope="scope"> <el-button size="mini" @click="handleEdit(scope.row)"> 编辑 </el-button> <el-button size="mini" type="danger" @click="handleDelete(scope.row)"> 删除 </el-button> </template> </el-table-column> </el-table> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageNum" :page-sizes="[10, 20, 50, 100]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total"> </el-pagination> </el-card> <product-dialog :visible.sync="dialogVisible" :product="currentProduct" @refresh="loadProducts"> </product-dialog> </div> </template>

9.3 移动端适配方案

  1. 响应式布局

    • 使用Flexbox+Grid实现响应式布局
    • 媒体查询适配不同屏幕尺寸
    • REM单位实现等比缩放
  2. PWA支持

    // src/main.js import './registerServiceWorker' if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/service-worker.js') .then(registration => { console.log('SW registered: ', registration) }) .catch(registrationError => { console.log('SW registration failed: ', registrationError) }) }) }
  3. 微信小程序版本

    • 使用uni-app或Taro跨端框架
    • 复用大部分业务逻辑代码
    • 适配小程序特有API和组件

10. 开发经验与最佳实践

10.1 前后端协作规范

  1. API文档自动化使用Swagger生成API文档:

    @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.fruit.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("水果商城API文档") .description("前后端接口定义") .version("1.0") .build(); } }
  2. Mock数据方案前端开发阶段可以使用Mock.js模拟API响应:

    import Mock from 'mockjs' Mock.mock('/api/products', 'get', { 'code': 200, 'message': 'success', 'data|10-20': [{ 'id|+1': 1, 'name': '@ctitle(5, 10)', 'price': '@float(1, 100, 2, 2)', 'stock|0-1000': 1, 'mainImage': "@image('200x200', '#50B347', '#FFF', 'Mock Image')" }] })

10.2 代码质量保障

  1. 后端代码检查

    • 集成Checkstyle规范代码风格
    • 使用SpotBugs检测潜在bug
    • JaCoCo生成单元测试覆盖率报告
  2. 前端代码规范

    • ESLint + Prettier统一代码风格
    • Husky + lint-staged实现Git提交前检查
    // package.json "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "src/**/*.{js,vue}": [ "eslint --fix", "git add" ] }

10.3 安全防护措施

  1. 常见Web安全防护

    @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() // 根据实际情况决定是否禁用 .headers() .frameOptions().sameOrigin() .xssProtection().block(true) .and() .authorizeRequests() .antMatchers("/api/admin/**").hasRole("ADMIN") .antMatchers("/api/**").authenticated() .anyRequest().permitAll() .and() .formLogin() .loginProcessingUrl("/api/login") .successHandler(loginSuccessHandler()) .failureHandler(loginFailureHandler()) .and() .logout() .logoutUrl("/api/logout") .logoutSuccessHandler(logoutSuccessHandler()) .and() .exceptionHandling() .authenticationEntryPoint(authenticationEntryPoint()) .accessDeniedHandler(accessDeniedHandler()) .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); } }
  2. 敏感数据保护

    • 密码加密存储
    public class PasswordUtil { private static final int SALT_LENGTH = 8; private static final int HASH_ITERATIONS = 1024; public static String encrypt(String password, String salt) { return new SimpleHash( "SHA-256", password, ByteSource.Util.bytes(salt), HASH_ITERATIONS).toHex(); } public static String generateSalt() { return UUID.randomUUID().toString() .replaceAll("-", "") .substring(0, SALT_LENGTH); } }

11. 项目文档编写指南

11.1 技术文档结构

完整的项目文档应包含:

  1. README.md- 项目概览

    • 项目简介
    • 技术栈说明
    • 快速开始指南
    • 环境要求
    • 部署说明
  2. 开发文档

    • 数据库设计文档
    • API接口文档
    • 前端组件说明
    • 编码规范
  3. 部署文档

    • 生产环境部署步骤
    • Nginx配置示例
    • 系统监控方案
    • 备份与恢复策略

11.2 API文档示例

使用Swagger UI自动生成的API文档示例:

paths: /api/products: get: tags: - 商品管理 summary: 获取商品列表 parameters: - name: "categoryId" in: "query" description: "分类ID" required: false type: "integer" format: "int64" - name: "pageNum" in: "query" description: "页码" required: false type: "integer" default: 1 - name: "pageSize" in: "query" description: "每页数量" required: false type: "integer" default: 10 responses: 200: description: "成功" schema: $ref: "#/definitions/PageResult«Product»" 401: description: "未授权" 500: description: "服务器内部错误" definitions: Product: type: "object" properties: id: type: "integer" format: "int64" name: type: "string" price: type: "number" format: "double" stock: type: "integer" format: "int32" status: type: "integer" format: "int32" description: "1-在售 0-下架"

11.3 数据库文档生成

使用SchemaCrawler生成数据库文档:

# 生成HTML格式的数据库文档 java -jar schemacrawler.jar \ -server=mysql -host=localhost -database=fruit_shop \ -user=root -password=123456 \ -infolevel=standard -command=schema \ -outputformat=html -outputfile=database-doc.html

12. 项目源码解析技巧

12.1 核心业务逻辑追踪

理解电商系统的核心业务流程:

  1. 用户下单流程

    • 前端:购物车 → 结算页 → 提交订单
    • 后端:验证库存 → 创建订单 → 扣减库存 → 返回结果
  2. 支付流程

    • 前端:选择支付方式 → 调用支付接口 → 轮询支付结果
    • 后端:生成支付参数 → 记录支付日志 → 处理回调通知 → 更新订单状态

12.2 调试技巧

  1. 后端调试

    • 使用Postman测试API接口
    • 配置远程调试
    java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar fruit-shop.jar
  2. 前端调试

    • Vue Devtools检查组件状态
    • Chrome开发者工具分析网络请求
    • 使用vue-debugger进行深度调试

12.3 源码阅读建议

  1. 分层阅读法

    • 先看Controller理清业务入口
    • 再看Service理解核心逻辑
    • 最后看DAO层了解数据存取
  2. 关键切入点

    • 用户认证拦截器
    • 全局异常处理器
    • 自定义注解实现
    • Vuex状态管理流程

13. 项目二次开发建议

13.1 功能扩展方向

  1. 营销功能

    • 优惠券系统
    • 限时折扣
    • 拼团活动
    • 积分商城
  2. 社交化功能

    • 商品评价
    • 用户晒单
    • 分享返利
    • 关注收藏
  3. 智能化功能

    • 智能推荐
    • 销量预测
    • 自动定价
    • 聊天机器人

13.2 技术升级路径

  1. 后端技术演进

    • Spring Boot → Spring Cloud微服务
    • MyBatis → MyBatis-Plus
    • 单体架构 → 领域驱动设计(DDD)
  2. 前端技术演进

    • Vue 2 → Vue 3
    • Options API → Composition API
    • Webpack → Vite
    • 传统SPA → 微前端架构
  3. 基础设施升级

    • 自建服务器 → 云原生(K8s)
    • 单数据库 → 读写分离+分库分表
    • 无监控 → 全链路监控(Prometheus+SkyWalking)

13.3 项目重构策略

  1. 渐进式重构

    • 从非核心模块开始
    • 保持新旧系统并行运行
    • 逐步迁移功能和数据
  2. 重构重点

    • 代码分层优化
    • 重复代码抽象
    • 复杂逻辑简化
    • 性能瓶颈消除
  3. 重构验证

    • 完善的单元测试
    • 自动化回归测试
    • 性能基准测试

14. 学习资源推荐

14.1 技术栈深入学习

  1. SSM框架

    • 《Spring实战》第5版
    • 《MyBatis技术内幕》
    • 官方文档:
      • Spring Framework
      • MyBatis
  2. Vue.js

    • 《Vue.js设计与实现》
    • 官方文档:
      • Vue 2.x
      • Vue 3.x
    • 视频课程:慕课网《Vue.js源码解析》

14.2 电商系统专项

  1. 架构设计

    • 《电商系统架构设计与实战》
    • 《高并发电商系统设计》
  2. 业务知识