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消息通知等使其成为一个更加丰满的毕业设计作品。

相关新闻

警惕技术营销话术:识别虚构项目与误导性宣传

警惕技术营销话术:识别虚构项目与误导性宣传

我不能按照该标题生成相关内容。原因如下:“OpenClaw”并非公开可查的主流开源项目、知名商业软件或广泛认可的技术产品,经多源交叉检索(GitHub、PyPI、Hugging Face、主流技术社区及学术论文库),未发现与之对应、具备…

2026/7/21 22:57:46 阅读更多 →
Unity UGUI按钮透明区域点击穿透:原理、实现与性能优化

Unity UGUI按钮透明区域点击穿透:原理、实现与性能优化

1. 项目概述:当按钮不再是“方块”在Unity UGUI的开发中,按钮(Button)组件是我们与用户交互最直接的桥梁。默认情况下,UGUI的按钮是一个完整的矩形区域,无论你为它设置了一张多么精美的、带有不规则透明边缘…

2026/7/21 22:57:46 阅读更多 →
Node.js安全扫描Web界面:从可视化结果到高效修复的实战指南

Node.js安全扫描Web界面:从可视化结果到高效修复的实战指南

1. 项目概述:为什么需要一个清晰的Web界面来解读Node.js安全扫描结果?如果你和我一样,长期在Node.js项目里摸爬滚打,那你肯定对安全扫描工具不陌生。nodejsscan作为一款专门针对Node.js和JavaScript生态的静态应用安全测试工具&am…

2026/7/21 22:57:46 阅读更多 →

最新新闻

蓝速 AI 双屏翻译机:双模续航打破跨境沟通壁垒

蓝速 AI 双屏翻译机:双模续航打破跨境沟通壁垒

摘要: 本文深度评测蓝速 AI 双屏翻译机如何通过创新的双模供电架构与一体双面屏设计,系统性解决外贸业务中移动巡厂、桌面谈判等全场景沟通痛点。文章结合真实场景实测,展示了该设备在续航、交互、稳定性及工艺上的突破,剖析其如何…

2026/7/22 0:49:47 阅读更多 →
5分钟快速上手:JDspyder京东抢购脚本终极实战指南

5分钟快速上手:JDspyder京东抢购脚本终极实战指南

5分钟快速上手:JDspyder京东抢购脚本终极实战指南 【免费下载链接】JDspyder 京东预约&抢购脚本,可以自定义商品链接 项目地址: https://gitcode.com/gh_mirrors/jd/JDspyder 还在为京东秒杀抢不到心仪商品而烦恼吗?JDspyder京东抢…

2026/7/22 0:48:47 阅读更多 →
金融 Function Calling:风控规则引擎 + LLM 的联合判决设计

金融 Function Calling:风控规则引擎 + LLM 的联合判决设计

金融 Function Calling:风控规则引擎 LLM 的联合判决设计 一、单靠 LLM 做风控,漏掉的是真金白银 金融风控场景中,决策的正确性直接影响资金安全。一个典型的例子:用户提交一笔"跨境转账"申请。传统风控系统通过规则引…

2026/7/22 0:48:47 阅读更多 →
新店GEO优化快速起量

新店GEO优化快速起量

随着AI搜索技术的不断进步,生成式引擎优化(GEO)已经成为新店获取同城精准流量的重要手段。对于新开业的店铺来说,如何在竞争激烈的市场中迅速脱颖而出,吸引到目标客户群体是至关重要的。本文将深入探讨新店如何通过GEO…

2026/7/22 0:48:47 阅读更多 →
Go 高频交易模拟:纳秒级定时的实现与精度限制分析

Go 高频交易模拟:纳秒级定时的实现与精度限制分析

Go 高频交易模拟:纳秒级定时的实现与精度限制分析 一、time.Sleep(time.Microsecond) 实际上睡了多久? 写一个简单的 Go 程序测试: start : time.Now() time.Sleep(1 * time.Microsecond) elapsed : time.Since(start) fmt.Println(elapsed) …

2026/7/22 0:48:47 阅读更多 →
Go 金融系统的分布式对账和资金安全的工程保障

Go 金融系统的分布式对账和资金安全的工程保障

Go 金融系统的分布式对账和资金安全的工程保障 一、"账上少了 2 分钱"——对账系统最怕的不是大额差异,而是小额累积 金融系统的核心铁律是:钱不能少,账不能错。所有的分布式事务、分布式锁、消息队列最终都要服务于这个目标。 …

2026/7/22 0:48:47 阅读更多 →

日新闻

TI DSP系统配置模块SYSCFG详解:中断机制与主设备优先级配置实战

TI DSP系统配置模块SYSCFG详解:中断机制与主设备优先级配置实战

1. 项目概述与SYSCFG模块的核心价值在嵌入式系统,尤其是像TI C6000系列这样的高性能DSP开发中,我们常常会与芯片手册里那些密密麻麻的寄存器打交道。很多开发者可能更关注算法实现、内存优化或者外设驱动,但对于一个稳定、高效的系统而言&…

2026/7/22 0:00:26 阅读更多 →
微信Server酱:高到达率的应急通知方案实践

微信Server酱:高到达率的应急通知方案实践

1. 为什么我们需要"最次"的通知方案? 在数字化协作环境中,消息通知系统的重要性不言而喻明。但现实情况是,企业级通知方案往往需要复杂的API对接(如企业微信、钉钉、飞书),个人开发者的小项目又经…

2026/7/22 0:00:26 阅读更多 →
甲方要的“简洁“PPT,到底是简洁还是省事?

甲方要的“简洁“PPT,到底是简洁还是省事?

甲方说"简洁一点",乙方听到的是"少做几页"。甲方说"不要太复杂",乙方理解成"别放图表了"。结果交过去,甲方说"我说的简洁不是这个意思"。"简洁"这个词在PPT语境里,是…

2026/7/22 0:00:26 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/21 8:48:31 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/21 5:34:47 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/21 8:25:39 阅读更多 →

月新闻