SpringBoot+Vue超市管理系统毕业设计实战:从零搭建前后端分离项目

📅 2026/7/21 22:57:06
SpringBoot+Vue超市管理系统毕业设计实战:从零搭建前后端分离项目
很多同学在做毕业设计时面对一个完整的项目需求常常感到无从下手尤其是需要整合前后端技术栈时。本文将手把手带你从零开始完成一个功能完整、代码规范、可直接运行的“鲜享超市管理系统”。这个项目采用主流的SpringBoot后端和Vue前端涵盖了用户管理、商品管理、订单处理等核心业务模块。无论你是Java初学者还是对Vue不太熟悉通过本文的详细拆解和完整源码你都能一步步搭建起来轻松搞定毕设同时掌握企业级项目开发的核心流程。1. 项目背景与核心概念1.1 什么是超市管理系统超市管理系统是一个典型的企业级信息管理系统MIS它通过计算机技术对超市的日常运营活动如商品进货、销售、库存、员工及会员信息等进行统一、高效的管理。其核心目标是替代传统的手工记账模式减少人为错误提高运营效率并为管理者提供数据支持以辅助决策。1.2 为什么选择 SpringBoot Vue 技术栈这是一个非常经典且高效的“前后端分离”架构组合在当前的Web开发中占据主流地位。SpringBoot (后端)作为Java领域最流行的微服务框架它极大地简化了Spring应用的初始搭建和开发过程。通过“约定大于配置”的理念和丰富的Starter依赖开发者可以快速构建独立运行、生产级别的应用无需过多关注繁琐的XML配置。它内置了Tomcat服务器并完美集成了MyBatis、Spring Security等常用组件。Vue.js (前端)是一套用于构建用户界面的渐进式JavaScript框架。它易于上手核心库只关注视图层并且拥有非常活跃的生态系统如Vue Router、Vuex、Element UI。Vue的数据驱动和组件化开发模式使得构建复杂、交互丰富的前端应用变得清晰且高效。前后端分离的优势前后端通过RESTful API接口进行数据交互职责清晰。后端专注于业务逻辑、数据安全和接口提供前端专注于页面渲染和用户体验。这种模式有利于并行开发、独立部署和后期维护。1.3 鲜享超市管理系统功能概述我们的项目将实现一个基础但功能完备的超市管理后台主要包含以下模块系统管理用户登录/注销、角色权限管理如管理员、普通员工。商品管理商品的增删改查、分类管理、库存数量与预警。采购管理记录商品采购入库信息关联供应商。销售管理前台收银模拟生成销售订单更新库存。会员管理会员信息注册、积分管理。数据统计简单的销售报表、商品销量排行等可视化图表。2. 环境准备与版本说明在开始编码之前请确保你的开发环境已就绪。以下是本文示例所使用的环境你可以根据实际情况进行调整。2.1 后端开发环境操作系统Windows 10/11, macOS 或 Linux (本文命令以Windows为例)JDKJava 17 (推荐) 或 Java 8。确保java -version命令能正确输出。构建工具Apache Maven 3.6。确保mvn -v命令能正确输出。集成开发环境 (IDE)IntelliJ IDEA (社区版或旗舰版) 或 Eclipse。IDEA对SpringBoot支持更好强烈推荐。数据库MySQL 5.7 或 8.0。本文使用 MySQL 8.0。数据库管理工具Navicat, DBeaver 或 IDEA 自带的数据库工具。2.2 前端开发环境Node.js版本 16.x 或 18.x (LTS版本)。这是运行Vue和npm的基础。安装后可通过node -v和npm -v检查。包管理工具npm (随Node.js安装) 或 yarn。前端IDEVisual Studio Code (VSCode) 或 WebStorm。VSCode轻量且插件丰富是前端开发首选。Vue脚手架Vue CLI 或 Vite。本文使用更现代的 Vite 作为构建工具。2.3 项目技术栈版本明细为了确保依赖兼容性以下是核心依赖的版本你可以在创建项目时参考。后端 (SpringBoot) 主要依赖!-- 在 pom.xml 中 -- parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.7.18/version !-- 选择一个稳定的版本 -- /parent dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jdbc/artifactId /dependency !-- 使用 MyBatis-Plus 简化数据库操作 -- dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency !-- MySQL 驱动 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies前端 (Vue 3) 主要依赖通过Vite创建项目时选择 Vue 3 和 TypeScript/JavaScript。我们将使用 Element Plus 作为UI组件库。# 项目创建后安装核心依赖 npm install element-plus --save npm install axios --save # 用于HTTP请求 npm install vue-router4 --save # 路由 npm install pinia --save # 状态管理替代Vuex3. 项目初始化与数据库设计3.1 创建SpringBoot后端项目打开 IntelliJ IDEA选择File - New - Project。选择Spring Initializr填写项目信息Name: supermarket-manageLocation: 你的项目存放路径Type: MavenLanguage: JavaGroup: com.freshArtifact: supermarketPackage name: com.fresh.supermarketJava: 17在Dependencies中勾选Spring Web,Spring Data JDBC,MySQL Driver,Lombok。其他依赖我们稍后在pom.xml中手动添加。点击FinishIDEA会自动生成项目并下载依赖。3.2 设计数据库表结构在MySQL中创建一个名为fresh_supermarket的数据库。以下是几个核心表的设计示例用户表 (sys_user):CREATE TABLE sys_user ( id bigint NOT NULL AUTO_INCREMENT COMMENT 主键, username varchar(50) NOT NULL COMMENT 用户名, password varchar(100) NOT NULL COMMENT 密码, nickname varchar(50) DEFAULT NULL COMMENT 昵称, email varchar(100) DEFAULT NULL COMMENT 邮箱, phone varchar(20) DEFAULT NULL COMMENT 手机号, avatar varchar(200) DEFAULT NULL COMMENT 头像, status tinyint DEFAULT 1 COMMENT 状态1正常0禁用, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_0900_ai_ci COMMENT用户表;商品表 (product):CREATE TABLE product ( id bigint NOT NULL AUTO_INCREMENT COMMENT 商品ID, product_code varchar(50) NOT NULL COMMENT 商品编码, product_name varchar(100) NOT NULL COMMENT 商品名称, category_id bigint DEFAULT NULL COMMENT 分类ID, price decimal(10,2) NOT NULL COMMENT 售价, cost_price decimal(10,2) DEFAULT NULL COMMENT 成本价, stock int NOT NULL DEFAULT 0 COMMENT 库存, stock_warn int DEFAULT 10 COMMENT 库存预警值, unit varchar(20) DEFAULT NULL COMMENT 单位如瓶袋, image varchar(200) DEFAULT NULL COMMENT 商品图片, description text COMMENT 商品描述, status tinyint DEFAULT 1 COMMENT 状态1上架0下架, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_product_code (product_code) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_0900_ai_ci COMMENT商品表;商品分类表 (category)、订单表 (order)、订单详情表 (order_item)、会员表 (member)等表结构类似可根据业务逻辑扩展。建议先画出E-R图理清关系。3.3 配置后端项目添加 MyBatis-Plus 依赖将上一节pom.xml中的mybatis-plus-boot-starter依赖添加到项目的pom.xml文件中。配置数据库连接编辑src/main/resources/application.yml文件。server: port: 8080 # 后端服务端口 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/fresh_supermarket?useUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/Shanghai username: root # 你的数据库用户名 password: 123456 # 你的数据库密码 jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8 # MyBatis-Plus 配置 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 控制台打印SQL生产环境关闭 global-config: db-config: id-type: auto # 主键自增 logic-delete-field: deleted # 全局逻辑删除字段名如果表中有此字段 logic-delete-value: 1 # 逻辑已删除值 logic-not-delete-value: 0 # 逻辑未删除值 mapper-locations: classpath*:/mapper/**/*.xml # XML映射文件位置4. 后端核心功能开发我们以商品管理模块为例演示完整的后端开发流程。4.1 创建实体类 (Entity)在com.fresh.supermarket.entity包下创建Product.java。package com.fresh.supermarket.entity; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import java.math.BigDecimal; import java.time.LocalDateTime; Data TableName(product) // 对应数据库表名 public class Product { TableId(type IdType.AUTO) // 主键自增 private Long id; private String productCode; private String productName; private Long categoryId; private BigDecimal price; private BigDecimal costPrice; private Integer stock; private Integer stockWarn; private String unit; private String image; private String description; private Integer status; TableField(fill FieldFill.INSERT) // 插入时自动填充 private LocalDateTime createTime; TableField(fill FieldFill.INSERT_UPDATE) // 插入和更新时自动填充 private LocalDateTime updateTime; }4.2 创建Mapper接口在com.fresh.supermarket.mapper包下创建ProductMapper.java。MyBatis-Plus 提供了强大的通用 Mapper无需编写 XML。package com.fresh.supermarket.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.fresh.supermarket.entity.Product; import org.apache.ibatis.annotations.Mapper; Mapper public interface ProductMapper extends BaseMapperProduct { // 继承 BaseMapper 后基本的 CRUD 方法已自动实现 // 如需复杂查询可在此定义方法并在对应 XML 中实现 }4.3 创建服务层接口和实现接口com.fresh.supermarket.service.ProductService.javapackage com.fresh.supermarket.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.fresh.supermarket.entity.Product; import com.fresh.supermarket.vo.ProductQueryVO; public interface ProductService extends IServiceProduct { // 分页条件查询商品 PageProduct pageQuery(PageProduct page, ProductQueryVO queryVO); }实现类com.fresh.supermarket.service.impl.ProductServiceImpl.javapackage com.fresh.supermarket.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fresh.supermarket.entity.Product; import com.fresh.supermarket.mapper.ProductMapper; import com.fresh.supermarket.service.ProductService; import com.fresh.supermarket.vo.ProductQueryVO; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; Service public class ProductServiceImpl extends ServiceImplProductMapper, Product implements ProductService { Override public PageProduct pageQuery(PageProduct page, ProductQueryVO queryVO) { LambdaQueryWrapperProduct wrapper new LambdaQueryWrapper(); // 根据查询条件动态构建SQL if (StringUtils.isNotBlank(queryVO.getProductName())) { wrapper.like(Product::getProductName, queryVO.getProductName()); } if (queryVO.getCategoryId() ! null) { wrapper.eq(Product::getCategoryId, queryVO.getCategoryId()); } if (queryVO.getStatus() ! null) { wrapper.eq(Product::getStatus, queryVO.getStatus()); } // 按创建时间倒序 wrapper.orderByDesc(Product::getCreateTime); return this.page(page, wrapper); } }4.4 创建控制器 (Controller)在com.fresh.supermarket.controller包下创建ProductController.java提供 RESTful API。package com.fresh.supermarket.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fresh.supermarket.common.Result; import com.fresh.supermarket.entity.Product; import com.fresh.supermarket.service.ProductService; import com.fresh.supermarket.vo.ProductQueryVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; RestController RequestMapping(/api/product) public class ProductController { Autowired private ProductService productService; // 新增商品 PostMapping public Result save(RequestBody Product product) { boolean success productService.save(product); return success ? Result.success(新增成功) : Result.error(新增失败); } // 根据ID删除商品 DeleteMapping(/{id}) public Result delete(PathVariable Long id) { boolean success productService.removeById(id); return success ? Result.success(删除成功) : Result.error(删除失败); } // 更新商品信息 PutMapping public Result update(RequestBody Product product) { boolean success productService.updateById(product); return success ? Result.success(更新成功) : Result.error(更新失败); } // 根据ID查询商品详情 GetMapping(/{id}) public Result getById(PathVariable Long id) { Product product productService.getById(id); return Result.success(product); } // 分页条件查询商品列表 GetMapping(/page) public Result page(RequestParam(defaultValue 1) Integer pageNum, RequestParam(defaultValue 10) Integer pageSize, ProductQueryVO queryVO) { PageProduct page new Page(pageNum, pageSize); PageProduct resultPage productService.pageQuery(page, queryVO); return Result.success(resultPage); } }其中Result是一个统一返回结果封装类ProductQueryVO是查询条件视图对象需要自行创建。4.5 运行与测试后端API在IDEA中找到主启动类SupermarketApplication运行main方法。控制台看到Tomcat started on port(s): 8080即启动成功。使用Postman或Apifox等工具测试接口。GEThttp://localhost:8080/api/product/page?pageNum1pageSize10POSThttp://localhost:8080/api/product(Body: JSON格式的商品数据)测试增删改查接口是否正常。5. 前端Vue项目开发5.1 创建Vue项目并安装依赖打开终端如VSCode的终端执行以下命令# 使用 Vite 创建 Vue 项目 npm create vuelatest # 按照提示操作项目名设为 supermarket-frontend # 选择 Vue, TypeScript(可选)不选其他默认配置即可。 cd supermarket-frontend # 安装核心依赖 npm install npm install element-plus axios vue-router4 pinia # 安装 Element Plus 图标库可选 npm install element-plus/icons-vue # 启动开发服务器 npm run dev访问http://localhost:5173看到Vue欢迎页即成功。5.2 配置路由和状态管理路由配置在src/router/index.ts中配置页面路由。import { createRouter, createWebHistory } from vue-router import Login from ../views/Login.vue import Layout from ../layout/Index.vue import ProductList from ../views/product/List.vue const routes [ { path: /login, name: Login, component: Login }, { path: /, component: Layout, redirect: /product, children: [ { path: /product, name: Product, component: ProductList }, // ... 其他路由如会员管理、订单管理等 ] } ] const router createRouter({ history: createWebHistory(), routes }) export default router状态管理 (Pinia)创建用户状态存储src/stores/user.ts用于管理登录状态、token等。全局配置在src/main.ts中引入 Element Plus 和 路由。import { createApp } from vue import ElementPlus from element-plus import element-plus/dist/index.css import * as ElementPlusIconsVue from element-plus/icons-vue import App from ./App.vue import router from ./router import { createPinia } from pinia const app createApp(App) app.use(createPinia()) app.use(router) app.use(ElementPlus) // 注册图标组件 for (const [key, component] of Object.entries(ElementPlusIconsVue)) { app.component(key, component) } app.mount(#app)5.3 开发商品列表页面创建src/views/product/List.vue实现商品的分页查询和表格展示。template div classproduct-container el-card !-- 搜索区域 -- el-form :inlinetrue :modelqueryParams classdemo-form-inline el-form-item label商品名称 el-input v-modelqueryParams.productName placeholder请输入商品名称 clearable / /el-form-item el-form-item label商品状态 el-select v-modelqueryParams.status placeholder请选择 clearable el-option label上架 :value1 / el-option label下架 :value0 / /el-select /el-form-item el-form-item el-button typeprimary clickhandleQuery查询/el-button el-button clickresetQuery重置/el-button el-button typesuccess clickhandleAdd新增商品/el-button /el-form-item /el-form !-- 商品表格 -- el-table :datatableData border stylewidth: 100% el-table-column propproductCode label商品编码 width120 / el-table-column propproductName label商品名称 / el-table-column propprice label售价(元) width100 / el-table-column propstock label库存 width80 / el-table-column propstatus label状态 width80 template #defaultscope el-tag :typescope.row.status 1 ? success : info {{ scope.row.status 1 ? 上架 : 下架 }} /el-tag /template /el-table-column el-table-column propcreateTime label创建时间 width180 / el-table-column label操作 width200 fixedright template #defaultscope el-button sizesmall clickhandleEdit(scope.row)编辑/el-button el-button sizesmall typedanger clickhandleDelete(scope.row)删除/el-button /template /el-table-column /el-table !-- 分页组件 -- div classpagination-container el-pagination v-model:current-pagequeryParams.pageNum v-model:page-sizequeryParams.pageSize :page-sizes[10, 20, 50, 100] :totaltotal layouttotal, sizes, prev, pager, next, jumper size-changehandleSizeChange current-changehandleCurrentChange / /div /el-card !-- 新增/编辑商品对话框 -- ProductDialog refproductDialogRef refreshgetList / /div /template script setup langts import { ref, reactive, onMounted } from vue import { ElMessage, ElMessageBox } from element-plus import ProductDialog from ./components/ProductDialog.vue import { getProductPage, deleteProduct } from /api/product // 表格数据 const tableData ref([]) const total ref(0) // 查询参数 const queryParams reactive({ pageNum: 1, pageSize: 10, productName: , status: null }) // 获取商品列表 const getList async () { try { const res await getProductPage(queryParams) tableData.value res.data.records total.value res.data.total } catch (error) { console.error(获取商品列表失败:, error) } } // 查询 const handleQuery () { queryParams.pageNum 1 getList() } // 重置查询 const resetQuery () { queryParams.productName queryParams.status null handleQuery() } // 分页大小改变 const handleSizeChange (val: number) { queryParams.pageSize val getList() } // 当前页改变 const handleCurrentChange (val: number) { queryParams.pageNum val getList() } // 新增商品 const productDialogRef ref() const handleAdd () { productDialogRef.value.open() } // 编辑商品 const handleEdit (row: any) { productDialogRef.value.open(row) } // 删除商品 const handleDelete (row: any) { ElMessageBox.confirm(确认删除该商品吗, 提示, { confirmButtonText: 确定, cancelButtonText: 取消, type: warning }).then(async () { await deleteProduct(row.id) ElMessage.success(删除成功) getList() }).catch(() {}) } // 初始化 onMounted(() { getList() }) /script style scoped .pagination-container { margin-top: 20px; display: flex; justify-content: flex-end; } /style对应的API请求层src/api/product.ts需要封装axios。import request from /utils/request import type { ProductQueryVO } from /types/product // 分页查询商品 export function getProductPage(params: ProductQueryVO) { return request({ url: /api/product/page, method: get, params }) } // 根据ID删除商品 export function deleteProduct(id: number) { return request({ url: /api/product/${id}, method: delete }) } // 新增商品 export function addProduct(data: any) { return request({ url: /api/product, method: post, data }) } // 更新商品 export function updateProduct(data: any) { return request({ url: /api/product, method: put, data }) }6. 前后端联调与跨域处理当前后端运行在不同端口前端5173后端8080时浏览器会因同源策略阻止请求需要解决跨域问题。6.1 后端解决跨域 (推荐)在SpringBoot后端添加一个全局跨域配置类。package com.fresh.supermarket.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; Configuration public class CorsConfig { Bean public CorsFilter corsFilter() { CorsConfiguration config new CorsConfiguration(); // 允许所有域名进行跨域调用生产环境应指定具体前端地址 config.addAllowedOriginPattern(*); // 允许跨越发送cookie config.setAllowCredentials(true); // 放行全部原始头信息 config.addAllowedHeader(*); // 允许所有请求方法跨域调用GET, POST, PUT, DELETE等 config.addAllowedMethod(*); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }6.2 前端配置代理 (开发环境)在Vue项目的vite.config.ts中配置代理将API请求转发到后端。import { defineConfig } from vite import vue from vitejs/plugin-vue export default defineConfig({ plugins: [vue()], server: { port: 5173, proxy: { /api: { target: http://localhost:8080, // 后端地址 changeOrigin: true, rewrite: (path) path.replace(/^\/api/, ) // 根据后端路径决定是否重写 } } } })配置后前端发起的/api/product/page请求会被代理到http://localhost:8080/api/product/page。6.3 联调测试确保后端SpringBoot应用在8080端口运行。前端运行npm run dev。在前端页面操作如点击查询观察浏览器开发者工具F12的“网络(Network)”标签页查看请求是否成功数据是否正确返回。7. 常见问题与排查思路在开发过程中你可能会遇到以下典型问题问题现象可能原因排查思路与解决方案后端启动失败端口被占用8080端口已被其他程序如另一个SpringBoot应用、Tomcat使用。1. 在application.yml中修改server.port。2. 命令行执行netstat -ano | findstr :8080(Windows) 或lsof -i:8080(Mac/Linux) 找到进程并结束。前端npm run dev报错端口被占用5173端口被占用。1. 在vite.config.ts中修改server.port。2. 同样使用命令查找占用进程。数据库连接失败1. MySQL服务未启动。2.application.yml中数据库连接信息URL、用户名、密码错误。3. 数据库驱动版本不匹配。1. 检查MySQL服务状态并启动。2. 仔细核对配置注意时区参数serverTimezone。3. 确认pom.xml中MySQL驱动版本与安装的MySQL版本兼容。前端请求后端API返回4041. 后端Controller路径映射错误。2. 跨域未配置或代理配置错误。3. 后端服务未启动。1. 检查Controller的RequestMapping和方法的GetMapping等注解路径。2. 检查后端CorsConfig是否生效或前端代理配置是否正确。3. 确认后端控制台无报错且已成功启动。前端页面空白控制台JS报错1. 组件引入路径错误。2. Vue/Element Plus版本兼容性问题。3. TypeScript类型错误。1. 检查import语句路径是否正确。2. 检查package.json依赖版本尝试重新安装node_modules(rm -rf node_modules npm install)。3. 根据控制台错误信息定位代码。MyBatis-Plus 插入/更新时自动填充时间字段不生效未配置元对象处理器。创建一个配置类实现MetaObjectHandler接口重写insertFill和updateFill方法并在实体类字段上使用TableField(fill FieldFill.INSERT)等注解。前端表格数据不显示1. API请求未成功数据未获取到。2. 表格绑定的prop与接口返回字段名不一致。3. 响应数据结构与预期不符。1. 在浏览器开发者工具“网络”中查看API请求响应。2. 核对表格列prop与接口返回的字段名。3. 检查后端Result封装类结构前端axios响应拦截器是否正确提取了data。8. 项目部署与上线建议8.1 后端打包与运行打包在项目根目录执行mvn clean package -DskipTests会在target目录生成supermarket-0.0.1-SNAPSHOT.jar。运行将jar包上传至服务器使用命令java -jar supermarket-0.0.1-SNAPSHOT.jar运行。可使用nohup或配置为系统服务保持后台运行。生产环境配置创建application-prod.yml覆盖数据库连接、日志级别等配置运行时可指定激活该配置文件java -jar supermarket-0.0.1-SNAPSHOT.jar --spring.profiles.activeprod。8.2 前端打包与部署打包在前端项目根目录执行npm run build生成静态文件在dist目录。部署将dist目录下的所有文件放置到任何静态Web服务器中如Nginx、Apache或SpringBoot项目的static目录。Nginx配置示例server { listen 80; server_name your-domain.com; # 你的域名或IP location / { root /path/to/your/dist; # dist目录路径 index index.html index.htm; try_files $uri $uri/ /index.html; # 支持Vue Router的history模式 } # 代理后端API请求 location /api/ { proxy_pass http://localhost:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }8.3 安全与性能最佳实践接口安全身份认证集成Spring Security JWT为API接口添加登录校验。权限控制实现基于角色的访问控制RBAC使用注解如PreAuthorize(hasRole(ADMIN))控制接口访问。参数校验使用Validated和NotBlank、Size等注解对入参进行校验。SQL防注入坚持使用MyBatis-Plus的Wrapper或#{}预编译严禁字符串拼接SQL。代码规范分层清晰严格遵循Controller - Service - Mapper的分层架构各司其职。统一响应使用Result类统一封装所有接口的返回格式。全局异常处理使用ControllerAdvice和ExceptionHandler捕获并处理异常返回友好的错误信息。日志记录使用SLF4J Logback记录关键业务日志、错误日志便于排查问题。数据库优化索引为高频查询条件如product_code,product_name和关联字段建立索引。字段设计选择合适的数据类型避免使用text类型作为查询条件。事务管理在涉及多个写操作如创建订单同时扣减库存的方法上添加Transactional注解保证数据一致性。前端优化API封装所有HTTP请求应通过统一的axios实例发出便于添加请求/响应拦截器处理token、错误等。组件复用将可复用的UI和逻辑抽离成组件。路由懒加载使用() import(...)语法实现路由懒加载提升首屏加载速度。构建优化合理配置Vite的打包策略对第三方库使用CDN。通过以上步骤你已经完成了一个SpringBootVue超市管理系统从零到有的核心开发流程。这个项目麻雀虽小五脏俱全涵盖了企业级应用开发的主要环节。你可以在此基础上继续扩展会员、订单、统计报表等功能模块并引入更高级的技术如Redis缓存、Elasticsearch搜索、WebSocket消息通知等使其成为一个更加丰满的毕业设计作品。