简介面向Java毕业设计及前后端分离初学者基于SpringBootVue的停车场管理系统提供了一套可运行、可扩展的完整源码方案。后端以SpringBoot实现业务接口与安全配置前端采用Vue构建管理页面并配套SQL数据库脚本、答辩论文和使用说明文档覆盖停车位管理、用户信息与费用计算等核心场景。资源包共403个文件大小19.43MB以java、vue、js、xml等代码文件为主另有svg图标、css样式、sql脚本、docx论文、bat一键运行脚本目录分工明确下载后在Windows10/11环境下按步骤即可启动调试。目前已有51人学习浏览。项目经过导师指导与答辩评审达到98分代码风格规范部署教程详细既适合毕业设计参考也可用于课程实训或小型停车场管理需求改造。1. 拿到SpringBootVue停车场管理系统项目包第一步该做什么这个压缩包解压后大概率是四个部分SpringBoot后端目录、Vue前端目录、SQL数据库脚本外加论文和使用说明文档。大部分人拿到手的第一反应是赶紧导入IDE、启动项目但我建议你先忍住先把使用说明文档里的管理员账号、功能清单翻一遍把论文里的需求分析看一遍再动手跑。原因很实际答辩时老师问得最多的不是代码细节而是“你这个停车场系统有哪些模块、每个模块解决什么问题”这些答案写在文档里不写在代码里。先看懂再跑通比先跑通再看懂能少踩一半坑。这篇笔记就按这个顺序带你走完整流程理清技术选型和模块结构、配置环境、初始化数据库、把前后端跑起来、解决几个高频启动问题最后告诉你怎样把它变成一个答辩时讲得清楚的项目。2. 停车场管理系统技术拆解为什么这套组合在毕业设计里是安全牌SpringBoot配Vue在Java方向的毕业设计里出现频率最高不是因为它是唯一答案而是因为它刚好卡在“能讲清楚”和“工作量够”之间。SpringBoot负责后端接口Vue负责页面交互两者通过JSON通信前后端可以被拆开单独调试。相比十年前用JSP把页面和Java代码写在同一个工程里的做法这套组合对新手更友好后端只写接口不用管页面长什么样前端只管渲染和提交数据分工明确答辩时也容易把系统架构讲明白。这个组合也不是没有代价。前后端分离带来了跨域问题、需要Node环境、接口文档要自己维护但这些都属于可控成本。对于停车场管理系统这种业务逻辑以增删改查和计算为主的选题SpringBoot提供了一套足够标准的骨架Vue加上Element UI组件库能快速拼出后台管理界面。接下来先从架构和业务两个角度拆透这个系统。2.1 为什么SpringBoot搭Vue是这个选题的稳妥组合典型构成与服务端渲染的取舍先看SpringBoot这一侧。它把Spring生态里最常用的配置都做了自动装配过去SSH项目里烦人的XML配置被starter依赖替代内嵌Tomcat让项目可以用一条命令直接跑起来。对毕设来说这意味着你不必花大量时间在“怎么把项目部署到Tomcat”上而是把时间留给业务代码。停车场系统的后端通常分成四层Controller负责接收前端请求Service处理业务Mapper操作数据库Entity映射表结构。这个分层本身就是一个很好的答辩素材老师问“你的系统怎么设计的”把这四层的关系讲清楚就够撑住场面了。Vue这一侧承担的是页面渲染和用户交互。停车场管理系统涉及的界面不外乎登录页、车位状态看板、车辆管理列表、停车记录页、统计报表这些页面用Vue Router做路由跳转、Axios请求后端接口、Element UI提供现成的表格和表单组件。相比服务端渲染这种模式最大的好处是页面切换不需要刷新整个页面操作体验更接近现在的主流后台系统。RestController RequestMapping(/api/parking) public class ParkingRecordController { PostMapping(/entry) public Result entry(RequestBody EntryDTO dto) { // 入场核心逻辑查车位、写停车记录、更新车位状态 return Result.ok(parkingService.handleEntry(dto)); } PostMapping(/exit) public Result exit(RequestBody ExitDTO dto) { // 出场核心逻辑算时长、算费用、更新停车记录 return Result.ok(parkingService.handleExit(dto)); } }这段代码体现的是最常见的接口组织方式。Controller层只做参数接收和结果包装真正的计费逻辑下沉到Service层。好处是Controller保持轻薄逻辑可以被单元测试覆盖答辩时也能展示出你理解分层设计而不是把所有代码塞在一个方法里。注意这里URL统一以/api开头前端代理和后端路由都围绕这个前缀来做后面排查接口不通时会反复用到这个约定。2.2 停车场的核心业务模块与数据流转从车辆入场到订单结算停车场系统的业务模块看起来很多其实核心链路只有一条车辆入场、停车、出场结算。我一般会把功能拆成下面这几个模块来看模块核心功能典型接口风格登录认证管理员登录、权限校验POST /api/auth/login车位管理车位列表、状态变更、锁定释放GET /api/space/list、PUT /api/space/status车辆管理车牌登记、车辆信息维护POST /api/vehicle、GET /api/vehicle/list停车记录入场登记、出场结算、记录查询POST /api/parking/entry、POST /api/parking/exit计费规则按时长计算费用、阶梯价格GET /api/fee/rule、PUT /api/fee/rule统计报表营收统计、车位利用率GET /api/report/daily数据流转的顺序值得在答辩前自己画一遍管理员登录后在页面点“入场登记”前端把车牌号和车位编号通过POST请求发给后端ControllerService层先查车位是否空闲再把入场时间写入停车记录表同时把车位状态改为占用车辆出场时后端根据出场时间减去入场时间得到停车时长再匹配计费规则算出金额更新记录并把车位状态改回空闲。整个过程围绕着一张停车记录表展开其他的表都是为了支撑这条链路。为什么要单独建一张计费规则表而不是在代码里写死“10元/小时”因为停车场的收费策略经常变化比如首小时免费、夜间封顶、不同区域不同价一旦写死在代码里每次改价格都要重新编译部署。把它抽成表之后改价格只是改一条数据库记录系统的可维护性会好很多。这个设计取舍在答辩时非常加分我在第6章还会给出一个具体改造示例。3. 把项目包跑起来从数据库初始化到前后端同时在线很多人拿到项目包第一件事就是双击导入然后等报错。正确顺序应该是先确认环境对不对再初始化数据库再启动后端最后启动前端。每一步都能独立验证出了问题也知道去哪里看。下面按这个顺序走每一步都会告诉你命令干什么、参数怎么改。3.1 环境版本对照JDK、Maven、Node、MySQL怎么配不翻车先检查本机环境。SpringBoot版本决定了JDK要求如果是SpringBoot 2.xJDK 1.8就够用如果项目用的是SpringBoot 3.x就必须JDK 17以上。Vue项目也一样Vue CLI 4和5对Node版本有要求Node 14或16通常最稳装了太新的版本反而容易出现依赖兼容问题。这种版本匹配看起来像玄学本质上是构建工具的版本契约不值得硬刚。组件推荐版本用途JDK1.8 或 17看SpringBoot版本编译和运行后端Maven3.6 及以上管理后端依赖Node.js14 或 16运行前端构建工具MySQL5.7 或 8.0存储业务数据打开终端用下面一组命令确认环境java -version mvn -v node -v npm -v mysql --version每条命令能正常输出版本号说明对应组件已经加入PATH。哪个命令提示“command not found”就先配置那个组件的环境变量不要急着启动项目。常见错误是只装了IDE内置的JDK命令行里java命令不可用导致Maven打包失败。提示Node版本不要随意升级到最新的偶数版本老Vue项目依赖的node-sass或旧版webpack在高版本Node下编译会报一堆原生模块错误这是毕设项目里翻车率最高的环境问题之一。3.2 初始化数据库与修改SpringBoot配置数据库脚本一般在项目的sql目录或者根目录下文件名通常类似schema.sql或init.sql。先创建一个专用库再导入脚本CREATE DATABASE IF NOT EXISTS parking_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;mysql -u root -p parking_db sql/parking.sql第一句话是建库重点在于字符集用utf8mb4而不是utf8因为utf8mb4才能完整支持车牌号里的生僻字和特殊符号。第二句话把建表语句和初始化数据一起导入。导入之后可以用SHOW TABLES;确认表是否创建成功再用SELECT * FROM sys_user;之类的语句确认初始管理员账号数据存在账号密码通常在使用说明文档里有写。接下来改后端配置。打开后端资源目录下的application.yml核心部分通常是下面这样server: port: 8081 spring: datasource: url: jdbc:mysql://localhost:3306/parking_db?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai username: root password: 123456 jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8这段配置里最重要的一定是password它必须和你本机MySQL的真实密码一致否则启动必报Access denied。serverTimezoneAsia/Shanghai解决的是数据库时间与本地时间相差8小时的问题characterEncodingutf8解决中文乱码useSSLfalse是为了避免本地连接时SSL握手告警。如果项目用的是MyBatis Plus下方一般还会有一段下划线转驼峰的配置这个在第4章细讲。3.3 启动后端Maven命令与两种常见方式后端启动有两种方式。第一种是在IDEA里直接找到带有SpringBootApplication注解的主类右键运行适合平时开发调试能直接看到控制台日志。第二种是用Maven命令打包再运行更贴近部署场景mvn clean package -DskipTests java -jar target/停车场后端.jar-DskipTests的意思是跳过单元测试加快打包速度。如果pom.xml里配置了多个模块打包前先确认模块路径对不对。启动成功后日志里会看到Started Application in x.x seconds说明后端已经就绪。验证后端是否真的可用用一条curl命令curl http://localhost:8081/api/space/list返回JSON数据而不是连接失败说明接口通了。如果返回404说明端口和路径没对上如果连接被拒绝先回去看端口是不是8081。这一步验证通过之后再启动前端排查范围就缩小了一半。3.4 启动前端npm安装与Vue开发服务器前端目录下的关键文件是package.json所有依赖版本都在里面。第一次启动先安装依赖npm installnpm install把package.json里声明的依赖下载到node_modules目录。国内网络环境下这一步经常卡住或报ECONNRESET可以先把npm源切换到国内镜像npm config set registry https://registry.npmmirror.com换源后重新执行npm install即可。依赖装完启动开发服务器npm run serve启动成功后终端会显示访问地址默认是http://localhost:8080。打开浏览器看到登录页先用说明文档里的管理员账号登录。如果页面能够打开但接口请求全部失败去检查前端项目里的vue.config.js确认代理配置和目标端口是否和后端一致module.exports { devServer: { port: 8080, proxy: { /api: { target: http://localhost:8081, changeOrigin: true } } } }这里/api是前端所有请求的公共前缀target指向后端地址changeOrigin把请求头里的Host改成目标域名。前后端能同时在线就算把这个项目包真正跑起来了。4. 数据库设计与配置项这张停车账单是怎么算出来的停车场的业务逻辑不算复杂但数据库表设计直接决定代码好不好写、答辩能不能讲清楚。一个常见的问题是表建得太少所有字段堆在一张表里或者建得太多每张表之间关系说不清。下面这套设计是我看到的毕设项目里最普遍的结构。4.1 核心表结构与字段设计用户、车位、车辆、停车记录先看整体结构。停车场系统通常围绕四类核心数据用户、车位、车辆、停车记录。有些项目会把车辆信息并入停车记录不单独建车辆表这样能减少联表查询但会丢失“同一辆车的历史车牌信息”。一般我给的建议是停车记录里直接存车牌号字段车辆表看需求再加毕竟车辆信息在车位预约场景里才有价值。表名职责关键字段sys_user管理员账号id、username、password、roleparking_space车位id、space_no、area、statusparking_record停车记录id、plate_no、space_id、entry_time、exit_time、duration_minutes、fee_amountfee_rule计费规则id、rule_name、base_duration、base_price、hour_price、max_price核心表DDL可以这样建CREATE TABLE parking_space ( id bigint NOT NULL AUTO_INCREMENT, space_no varchar(20) NOT NULL COMMENT 车位编号, area varchar(50) DEFAULT NULL COMMENT 所属区域, status tinyint NOT NULL DEFAULT 0 COMMENT 0空闲 1占用 2锁定, created_time datetime DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY uk_space_no (space_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT车位表;parking_space的状态字段用tinyint而不是字符串是为了查询和索引更快代码里用一个枚举或常量类来对应0、1、2三种状态。唯一索引uk_space_no保证同一个车位编号不会重复登记。停车记录表是整条业务链路的核心它的字段设计直接影响计费逻辑好不好写CREATE TABLE parking_record ( id bigint NOT NULL AUTO_INCREMENT, plate_no varchar(20) NOT NULL COMMENT 车牌号, space_id bigint DEFAULT NULL COMMENT 车位id, entry_time datetime DEFAULT NULL COMMENT 入场时间, exit_time datetime DEFAULT NULL COMMENT 出场时间, duration_minutes int DEFAULT 0 COMMENT 停车时长(分钟), fee_amount decimal(10,2) DEFAULT 0.00 COMMENT 应收金额, status tinyint DEFAULT 0 COMMENT 0在停 1已离场, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT停车记录表;entry_time和exit_time一进一出duration_minutes由出场时计算后写入fee_amount保存最终金额。为什么要把计算的时长和金额存下来而不是每次查询时现算因为历史账单需要保留当时的计费结果如果之后改了价格规则历史记录也不应该跟着变。这一点答辩时能主动讲出来比背定义有说服力得多。4.2 连接串与MyBatis配置三个必调参数和一个容易忽略的参数后端配置文件里数据库连接串和持久层配置是最容易被反复折腾的地方。三个必调参数分别是字符集、时区、SSL开关。spring: datasource: url: jdbc:mysql://localhost:3306/parking_db?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai username: root password: 123456 jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8characterEncodingutf8保证程序往数据库写入中文时不会变问号serverTimezoneAsia/Shanghai保证时间字段读写不会偏移8小时useSSLfalse去掉本地开发时的SSL认证告警。这三个参数在MySQL 8.0下尤其重要。容易忽略的是spring.jackson的配置。后端返回给前端的日期格式默认可能是时间戳或带时区的ISO字符串前端显示出来就是一串难懂的数字或相差8小时的时间。加上date-format和time-zone之后前后端就统一用yyyy-MM-dd HH:mm:ss格式通信。如果项目用MyBatis一般还要确认下划线转驼峰配置是否打开mybatis: configuration: map-underscore-to-camel-case: true这个配置把数据库里的space_no自动映射成Java实体里的spaceNo不用每个字段手动写Results。不开这个配置最常见的现象是接口返回的字段全是null因为数据库列名和实体属性名对不上。遇到列表数据明明数据库里有值、接口却返回null先查这一项。5. 从拿到项目包到演示成功高频踩坑与排查清单就算环境版本都对第一次启动也大概率不会一帆风顺。下面5个坑是我看到出现频率最高的按“现象、原因、解决”写出你启动时碰到哪个就对着查哪个。5.1 后端启动报端口被占用前端页面数据一直加载不出来现象启动后端时日志直接报Web server failed to start. Port 8081 was already in use前端页面能打开但列表一直转圈接口请求超时。原因8081端口被另一个进程占用。常见情况是之前就有一次后端在后台跑着没停干净或者本机其他服务占用了这个端口。解决先查端口占用再决定杀进程还是改端口。macOS或Linux用lsof -i :8081Windows用netstat -ano | findstr 8081找到PID后结束进程。如果这个端口是系统服务在用的就干脆改掉server: port: 8082改完端口记得同步修改前端vue.config.js里的target地址否则前端代理仍然指向旧端口同样的报错会再出现一次。5.2 MySQL连接报错账号密码正确却连不上库现象后端启动日志报Access denied for user rootlocalhost (using password: YES)或者Public Key Retrieval is not allowed。原因前者一般是配置里密码和MySQL实际密码不一致后者是MySQL 8.0默认认证插件是caching_sha2_passwordJDBC驱动版本较老时需要额外参数才能完成认证。解决先确认密码无误。如果密码没问题且报的是Public Key Retrieval在连接串末尾加一个参数url: jdbc:mysql://localhost:3306/parking_db?useSSLfalseallowPublicKeyRetrievaltrueserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue允许客户端从服务端获取公钥完成认证。如果不想靠这个参数绕过也可以把MySQL用户的认证插件改回mysql_native_password但改认证插件会影响全局本地毕设项目加参数更省事。5.3 前端请求接口404或401路径、代理与跨域三件事现象后端用curl测试接口是通的前端页面上却拿不到数据F12控制台看到404、401或CORS错误。原因404是前端请求的URL前后端对不上401是登录接口返回token但请求头没带上CORS是因为前后端端口不同浏览器拦截了跨域响应。解决先看F12里请求的具体URL确认前缀和路径。如果URL对但401检查登录后是否有token存储和请求拦截器自动加Authorization头。如果报CORS优先在vue.config.js里配置代理而不是在后端硬开跨域。如果项目部署时前端和后端分离在不同域名再在后端加统一跨域配置Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/api/**) .allowedOrigins(*) .allowedMethods(GET, POST, PUT, DELETE); } }5.4 数据库中文乱码建库、建表、连接串三处要统一现象页面录入的中文名称、车牌号保存后变成问号刷新后依然是乱码直接查数据库看到的内容也是乱的。原因三处字符集不统一建库时用了latin1、建表时没指定字符集、连接串没加characterEncodingutf8。缺少任何一处都可能出现写入时乱码。解决统一改成utf8mb4。先改库再改表ALTER DATABASE parking_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; ALTER TABLE parking_space CONVERT TO CHARACTER SET utf8mb4;所有表都要执行一遍CONVERT然后确认连接串里是characterEncodingutf8而不是utf-8。如果已经写入的乱码数据需要先清理掉再重新录入乱码是编码错乱造成的不可逆损坏不要在错数据基础上继续测试。5.5 Maven依赖拉不下来镜像仓库与本地缓存的清理现象导入后端项目后pom.xml大量依赖报红命令行执行mvn clean package一直卡在下载进度或者提示某个依赖Could not transfer artifact。原因默认的Maven中央仓库在国外访问不稳定或者之前下载中断本地仓库里留下了lastUpdated结尾的损坏缓存文件。解决在Maven的settings.xml里配置国内镜像mirror idaliyunmaven/id mirrorOfcentral/mirrorOf namealiyun public/name urlhttps://maven.aliyun.com/repository/public/url /mirror配置后回到项目根目录执行mvn clean compile。如果还是报错把本地仓库里对应目录下的lastUpdated文件删掉再重新拉rm -rf ~/.m2/repository/com/example这个目录路径是示例实际操作时把报错依赖的包路径替换进去就好。6. 答辩与扩展把跑通的系统变成能讲清楚的项目6.1 演示前先做三件小事造数据、走链路、备截图系统能跑通只是第一步答辩现场演示才是关键。我建议提前一晚把这三件事做掉。第一件是准备演示数据在数据库里插入几条真实感的停车记录让统计报表有内容可看INSERT INTO parking_record (plate_no, space_id, entry_time, exit_time, duration_minutes, fee_amount, status) VALUES (京A12345, 1, 2025-04-01 08:30:00, 2025-04-01 10:30:00, 120, 20.00, 1);第二件是把主流程完整走一遍登录、新增车位、入场、出场、查看统计报表每一步都确认页面显示正常。第三件是准备三五张关键页面截图保存到手机真要遇到现场网络问题、投影仪抽风至少还有退路。6.2 一处小改造让答辩加分把计费规则从代码里抽出来大部分毕设项目的计费逻辑都写死在Service层里答辩时老师一旦问“价格改了怎么办”现场就容易被问住。最划算的改造是把计费逻辑改为读取fee_rule表先创建一个规则实体和Mapper再在计算费用的地方替换成查表逻辑。public BigDecimal calcFee(ParkingRecord record) { FeeRule rule feeRuleMapper.findByParkingType(record.getParkingType()); long minutes record.getDurationMinutes(); BigDecimal fee rule.getBasePrice(); if (minutes rule.getBaseDuration() * 60) { long extraHours (long) Math.ceil((minutes - rule.getBaseDuration() * 60) / 60.0); fee fee.add(rule.getHourPrice().multiply(BigDecimal.valueOf(extraHours))); } return fee; }这段逻辑从“写死规则”变成了“规则在表里”。答辩时讲到这一处只需要一句话“计费规则不写死在代码里改价格只需要改数据库配置不用重新部署。”这个加分点性价比极高改动量很小却能让老师觉得你真正理解了可扩展性。我自己的习惯是每次启动项目碰到问题都顺手记在一个文本备忘录里下一次换电脑、换项目直接翻出来照做能省不少时间。这套SpringBoot加Vue的停车场项目只要你按着数据库、后端、前端这个顺序来把上面的环境和排查清单过一遍基本都能顺顺当当跑起来。希望帮到你。本文还有配套的精品资源点击获取