高校电动车租赁系统:SpringBoot+Vue+MySQL前后端分离实战解析

发布时间:2026/10/13 11:39:58
高校电动车租赁系统:SpringBoot+Vue+MySQL前后端分离实战解析 1. 校园场景下的租赁需求为什么值得做成一个管理系统先聊点实际的。这两年高校校园面积普遍不小宿舍区、教学区、实验楼、食堂之间动辄一两公里走路嫌远、骑车又怕丢于是电动车在校园里成了刚需。很多学校周边的车行、校内创业团队都在做电动车出租生意但绝大多数还停留在本子登记微信沟通的阶段谁租了哪辆车、租了多久、该收多少钱、车还在不在全靠人工记。一旦车多了、订单密了这套模式必乱——还车时间记错、押金忘记退、车子被骑出校区联系不上人各种纠纷接踵而来。这个高校电动车租赁系统要解决的问题就是把上面这一摊子线下混乱搬到线上用一套标准化的业务流程管起来。它面向两类角色普通学生用户可以在线注册、浏览车辆、租车下单、结算费用管理员则负责车辆信息维护、订单审核、租用记录管理、用户管理。系统本质上是一个典型的信息管理系统但因为它带了租赁这个业务属性涉及订单状态变化、车辆状态流转、金额计算所以比纯粹的增删改查系统更有含金量也更适合作为课程设计或者毕业设计的选题。再说技术选型。项目用的是SpringBoot后端 Vue前端 MySQL数据库前端和后端完全分离通过 RESTful API 通信。这套组合在现在的 Java 课程设计、毕业设计里几乎算是标准答案了SpringBoot 让后端开发不用再面对一堆繁琐的 XML 配置内嵌 Tomcat 一键启动Vue 的组件化开发让前端页面维护起来很舒服MySQL 则免费开源、资料多、上手门槛低。对做毕设的同学来说这套技术栈还有一个隐形优势——面试和复试的时候面试官一听 SpringBootVueMySQL至少不会觉得你用的技术太陈旧。我后面会把这个项目从功能拆解、数据库设计、前后端对接、启动排错整个过程完整捋一遍目标就一个你拿到这套源码能在半小时内把它跑起来并且能说出每个模块背后的设计理由。2. 功能清单与数据库设计别急着写代码先把业务想透很多人拿到一套源码第一件事就是双击运行这其实是最错误的打开方式。我建议你先花半小时把项目的功能模块和数据库表结构过一遍。搞清楚这个系统到底有哪些角色、每个角色能干什么、数据是怎么流动的后面不管是跑通验证还是二次开发你都会从容很多。2.1 用户端与管理端的功能划分这一套系统从使用角色上分成前台和后台。前台对应普通学生用户后台对应管理员。两者的功能边界很清晰前台是产生数据的地方后台是消化数据的地方。前台用户端主要包含注册与登录学生通过手机号或学号注册账号登录后才能进行租车操作。这里要注意密码一般不做明文存储系统里会用 MD5 加盐或者 BCrypt 做哈希处理。车辆浏览与查询以列表或卡片形式展示可租车辆展示车牌号、车辆类型、电池续航、时租价格、押金金额、车辆状态。支持按品牌或状态筛选。发起租车选择车辆后提交租车申请系统生成订单。正常业务里这一步会检查车辆当前状态是否为可租防止一辆车被同时下单。归还车辆租用结束后提交还车申请系统根据租用时长计算费用并返回结算金额。个人中心查看自己的订单记录、历史租用详情、修改个人信息。后台管理端主要包含车辆管理对电动车信息做增删改查包括车辆编号、品牌型号、电池信息、日租/时租价格、押金、车辆图片、当前状态管理可租/已租/维修/下架。订单管理查看所有租车订单处理用户的租车/还车申请可对异常订单进行取消或标记。用户管理查看注册用户列表禁用或启用账号。公告管理发布系统公告、租车须知等前台用户可见。数据概览部分版本会有租车次数、营收等简单统计图表以折线图或柱状图展示。2.2 数据库核心表设计思路这个项目的数据库表数量一般控制在 5 到 8 张典型的核心表有这些表名主要字段作用说明userid, username, password, phone, id_card, role, create_time用户表存储学生和管理员账号role 字段区分角色vehicleid, vehicle_no, brand, model, type, battery, price_hour, price_day, deposit, status, image, description电动车信息表status 标识车辆状态orderid, order_no, user_id, vehicle_id, start_time, end_time, total_amount, status, create_time租车订单表记录每一次租借行为apply部分版本id, user_id, vehicle_id, apply_type, apply_time, status租车申请/还车申请表noticeid, title, content, create_time公告表这里面最有讲究的是订单状态字段。不要把它设计成简单的一个status字符串而是建议用数字或简短状态码表达业务状态。比如状态码0表示待取车、1表示租用中、2表示待归还、3表示已完成、4表示已取消。这种设计的好处是后端在代码里做状态流转判断时逻辑清晰写if (order.getStatus() 1)一眼就能看懂而且配合前后端枚举映射前端展示中文状态也方便。另一个需要留意的点是车辆状态与订单状态的联动。业务上一辆车被下单成功并取车后vehicle.status要从可租改成已租否则别人还能继续下单归还完成后又要从已租改回可租。这个联动如果只在前端做、后端接口没有兜底就会出现数据不一致的严重 bug。这套源码在顺序上做得比较规范前端只是触发请求真正的状态变更必须由后端接口在事务里完成。2.3 几个值得学习的业务细节我看了不少这类项目的实现有三个细节最考验作者水平也是你在答辩时能拿出来讲的点一是金额计算的精度问题。租赁费用涉及单价乘以时长时长往往精确到小时甚至半小时金额又会涉及小数。如果直接用double或float容易踩浮点数精度坑比如0.1 0.2不等于0.3。建议用BigDecimal做费用计算数据库里金额字段也建议用DECIMAL(10,2)而不是DOUBLE。这套项目在结算模块如果用了BigDecimal你答辨时一定要提这是加分项。二是押金逻辑。多数课程设计会把押金做成一个下单时冻结、还车后扣除租金并退还余额的简化方案。因为不涉及真实支付一般就是在订单表里加一个deposit_status字段或者在用户表里记余额。实现不复杂但能在设计说明里把为什么先收押金再还车后退还讲清楚说明你确实理解租赁业务的风险控制逻辑。三是车牌的基因。业务上电动车应该有一个唯一标识——车牌号或自编号。系统里要给它加唯一索引防止管理员重复录入这是数据库约束层面的最简单实践。3. SpringBoot后端从分层结构到鉴权接口的实现思路后端是整个系统的重头戏SpringBoot 项目拿到手你首先会看到一套非常清晰的分层结构。这一步要是搞明白了你就能顺着代码跑通整条请求链路。3.1 经典分层结构与包组织这套项目的后端包结构一般长这样com.example.campusrent ├── controller // 接收前端请求返回 JSON 数据 ├── service // 业务逻辑层接口 实现类 ├── dao/mapper // 数据访问层操作 MySQL 数据库 ├── entity/pojo // 实体类对应数据库表 ├── config // 配置类跨域、拦截器、静态资源等 ├── utils // 工具类JWT、时间格式化等 └── common/result // 统一返回结果封装这种分层的作用说白了就是各管一段Controller 只负责参数接收和响应返回不写业务逻辑Service 专注业务流程和事务控制Mapper 只做最简单的 SQL 操作。这样拆的好处是一旦出问题你知道去哪找代码想改需求你也知道动哪一层。很多学生写的项目最大的问题就是所有代码堆在 Controller 里一个方法几百行最后连作者自己都维护不了。以租车流程为例完整链路是这样的用户在前端页面点击租车按钮 → Vue 通过 Axios 把请求发送到/api/order/submit→ SpringBoot 的OrderController接收请求 → 调用OrderService.submitOrder(userId, vehicleId)→ Service 内部先查车辆状态、再更新车辆状态、最后生成订单记录整个过程加Transactional事务注解 → 返回统一 JSON 格式结果给前端。这一步链路能跑通整个后端你就理解大半了。3.2 登录鉴权怎么实现这是一个课程设计项目里最容易做得拉胯、同时也是最有说头的模块。很多低质量项目用的是前端登录后把用户名存在 Session 里的老办法——项目跑起来没问题但面试时一被问那你是怎么控制权限的就露馅。这套源码比较推荐的做法是JWTJSON Web Token无状态登录。大致流程是这样的用户提交账号密码后端校验通过后用用户的 id 和角色信息生成一个 token 返回给前端。前端把 token 存起来之后每次请求在请求头里带上Authorization: token。后端写一个拦截器Interceptor拦截除了登录注册之外的接口每次请求先校验 token 是否有效无效直接返回 401。用 JWT 的好处是后端不需要存 Session服务器水平扩展时不需要考虑 Session 同步问题而且 token 里带了角色信息管理员接口可以在拦截之后进一步校验角色权限。比如普通用户访问/admin/**的接口时可以直接拦截返回无权限。答辩时能把这个机制讲明白含金量直接高出同龄人一截。3.3 接口设计规范与统一返回体如果你看代码时发现所有接口的返回值都是一个固定格式比如{ code: 200, message: 操作成功, data: { ... } }那说明作者做了统一返回结果封装。这个设计看似简单但非常提升代码整洁度。前端 Axios 可以在拦截器里统一判断code是否为 200不是就弹错误提示不用每个接口单独写错误处理。这个习惯在真实企业项目里也是标配你二次开发时一定要保留。另一块是分页查询。车辆列表、订单列表这种数据量会增长的功能一定不能一次性把全表数据查出来返回。常见做法是使用PageHelper分页插件或者用 MyBatis-Plus 自带的分页功能后端接口接收pageNum和pageSize参数返回{total, list}这样的分页结果数据。前端配合 Vue 的表格组件展示页码。这套源码里车辆和订单模块基本都是这种模式你看mapper层相关 XML 或注解 SQL 时能直接看到分页逻辑。4. Vue前端页面、路由与接口如何拼成完整应用前端的核心任务就是把后端的接口数据变成用户能看懂、能操作的界面。这套项目的前端虽然是课程设计级别但麻雀虽小五脏俱全Vue 的核心机制基本都覆盖了。4.1 前端项目结构拆解vue-cli初始化的项目结构基本是固定的拿到手之后重点看src目录src ├── api // 封装的接口请求方法 ├── assets // 静态资源图片、样式 ├── components // 公共组件导航栏、车卡片等 ├── router // 前端路由配置 ├── store // Vuex 状态管理 ├── views // 页面组件首页、租车页、我的订单、后台管理各页 ├── App.vue └── main.js这套结构里最值得认真学的是api目录。作者一般会按模块拆分接口请求比如api/vehicle.js里封装所有车辆相关请求api/order.js里封装订单相关请求。每个方法就是一个返回 Promise 的 Axios 调用。这样做的好处是页面组件里不用直接写this.$axios.get(...)而是引一个语义化函数getVehicleList(params)既统一管理了接口地址也方便做拦截器统一处理错误。4.2 路由与权限控制Vue Router 的配置在课程设计里通常分两块前台页面路由和后台管理路由。前台包括登录页、注册页、首页、租车页、我的订单等后台包括车辆管理、订单管理、用户管理等。为了区分用户端和管理端常见的做法是使用meta字段标记角色再配合路由守卫做跳转拦截。路由守卫的逻辑很有说头。在router/index.js里通过beforeEach钩子判断用户没有 token 就访问需要登录的页面直接重定向到登录页普通用户访问 admin 开头的管理页面直接跳回首页并提示无权限。这段代码虽然只有十几行但已经把前端路由层面的权限控制讲清楚了。你要理解的是前端路由守卫只是用户体验层的保护真正的数据安全依然靠后端接口鉴权两者配合才算完善的权限体系。4.3 Axios封装与后端交互前端和后端的连接点是 Axios。这套项目通常会做一个request.js封装核心就是两个拦截器请求拦截器每次发送请求前从 localStorage 或 Vuex 里取 token放到config.headers上。这就是 JWT 鉴权的第一棒。响应拦截器拿到后端返回后先看code如果后端返回的是 401 就跳登录页如果是业务错误就直接调 Element UI 的Message组件弹出错误提示。这样每个页面调用接口时不用重复写错误弹窗代码。这里有个细节很多初学者看不懂为什么后端的接口地址都带/api前缀比如/api/user/login。因为开发环境下前端在localhost:8080后端在localhost:9090跨域请求需要后端通过CrossOrigin或者 CORS 配置类允许某来源访问。统一加/api前缀就是给后端配置统一前缀方便通过反向代理或拦截器统一处理后续部署到服务器还可以用 Nginx 把/api转发到后端服务。你启动项目时如果遇到跨域报错页面能打开但请求数据失败问题的根源多半在这里。4.4 Element UI页面搭建页面部分用的是 Element UI 组件库看代码时你会认识一批高频组件el-table展示管理列表数据、el-form做登录注册和车辆新增表单、el-dialog做编辑弹窗、el-pagination做分页组件、el-tag展示订单状态。这里我想提醒一点很多同学跑通项目后觉得前端不就是复制粘贴排个版吗这观念得改。你可以试着改一个东西体会一下比如把首页车辆卡片改成按时租价格从低到高排序前端你可以通过el-select加一个排序选项改vehicle.js里的请求参数后端对应在 Service 里加一个排序逻辑。这个前后端联动改一个功能的完整过程走一遍你对全栈开发的理解会上一个台阶。5. 打通最后一步环境配置、启动流程与真实踩坑记录好到这里理论部分基本讲完了。现在进入正题——怎么让这个可直接运行的项目在你电脑上真正跑起来。我尽量把每一步说细包括那些你自己瞎试可能要折腾半天的坑。5.1 需要安装的工具与环境项目跑起来需要四样东西JDK、Maven或使用 IDEA 内置、MySQL、Node.js。工具推荐版本说明JDK1.8 或 11SpringBoot 2.x 项目通用版本JDK 17 也能跑但可能有兼容问题MySQL5.7 或 8.0两者都行但 8.0 与 5.7 在驱动和连接配置上有差异见下方踩坑Node.js14.x 或 16.x经典稳定版本不要用 18 跑老项目node-sass 容易装不上Maven3.6用 IDEA 自带 Maven 也行重点是配好阿里云镜像IDEIDEA VSCodeJava 用 IDEA前端用 VSCode分头开发数据库准备方面项目根目录一般会提供sql文件夹里面是.sql脚本。用 Navicat 或者命令行执行mysql -u root -p campus_rent.sql或者更简单用 Navicat 新建数据库右键运行 SQL 文件。注意导入前先创建数据库字符集选utf8mb4否则中文容易乱码。5.2 修改后端配置文件后端配置集中在src/main/resources/application.yml里。拿到手主要改三块数据库连接信息、服务端口、JWT 密钥如果有的话。server: port: 9090 spring: datasource: url: jdbc:mysql://localhost:3306/campus_rent?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai username: root password: 你的数据库密码 driver-class-name: com.mysql.cj.jdbc.Driver核心注意点serverTimezoneAsia/Shanghai必须加不然 MySQL 8 经常报时区错误。useSSLfalse加上省事本地开发没必要用 SSL。MySQL 5.7 的驱动是com.mysql.jdbc.DriverMySQL 8 是com.mysql.cj.jdbc.Driver版本不匹配启动直接报ClassNotFoundException。如果 pom.xml 里引入的是mysql-connector-java8.x 而本地库是 5.7一般也能连但反过来不行。改完后在 IDEA 里打开项目等 Maven 把依赖下载完第一次可能要几分钟找到主启动类CampusRentApplication之类的类名右键 Run 就能启动后端。看到日志里出现Tomcat started on port(s): 9090就说明后端成功了。5.3 启动前端项目前端项目目录下打开终端按顺序执行npm install npm run servenpm install这一步最折磨人。如果网络不好或者 Node 版本与项目依赖不匹配经常报错。我的建议是直接用 npmmirror 镜像npm config set registry https://registry.npmmirror.com npm install如果报node-sass相关的错说明 Node 版本太新了。node-sass 是个坑王它依赖原生编译不同 Node 版本对应不同版本。最快的解决方案是换成 sassdart-sass或者用 nvm 切换到 Node 14。这里花点时间值得因为后面所有前端依赖安装都依赖这一步。启动成功后终端会显示App running at Local: http://localhost:8080浏览器打开就能看到项目页面了。默认管理员账号一般写在文档或数据库初始化脚本里常见如admin / 123456普通用户需要自己注册。5.4 真实踩坑记录这几个问题能拦下一半人我把这个项目调试过程中遇到频率最高的坑列一下按出现概率×崩溃程度排个序第一个坑MySQL 8 驱动与 5.7 配置混用。症状是后端启动直接报java.sql.SQLException或者ClassNotFoundException: com.mysql.jdbc.Driver。解决办法就是上面说的把驱动改成com.mysql.cj.jdbc.DriverURL 加上时区参数。另外 8.0 的密码加密方式默认是caching_sha2_password5.7 客户端连不上时可以在 MySQL 里执行ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密码;把加密方式改回传统模式。第二个坑端口被占用。前端默认 8080、后端默认 8080 或 9090。如果你电脑上已经跑着别的项目端口冲突会在启动日志里非常显眼Web server failed to start. Port 8080 was already in use.解决两条路改端口或者找到占用进程杀掉。建议直接改端口省事比如后端改成 9090前端vue.config.js里 devServer 端口改 8081。前后端端口不一样还有个附带好处你在浏览器里打开 8081 调试前端后端 9090 提供接口逻辑清晰不混乱。第三个坑前端开发环境跨域。症状是浏览器控制台报Access to XMLHttpRequest ... CORS错误。如果后端已经加了跨域配置仍然不行检查你的请求地址是不是写成了绝对地址http://localhost:9090/api/...。正确做法是在vue.config.js里配置代理module.exports { devServer: { proxy: { /api: { target: http://localhost:9090, changeOrigin: true } } } }这样前端请求/api/user/login会被自动转发到后端 9090 端口从浏览器视角看是同源请求不会触发跨域限制。这是前后端分离开发环境下最标准的做法。第四个坑数据库名或表名前缀不一致。项目给的 SQL 脚本里数据库名如果是campus_rent而你在 Navicat 里建库时写成了campusrent修改application.yml后如果还报Table xx.user doesnt exist那就是表名前缀不一致或导入脚本不完整。重新跑一遍完整 SQL 脚本确认所有表都建成功。第五个坑时间字段显示成英文格式或者相差 8 小时。这是时区和 JSON 序列化格式问题。后端在application.yml里配置spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8前端再用dayjs或直接new Date(str)格式化时间就正常了。5.5 启动后的第一次全流程验证项目起来后不要急着改代码先按真实用户路径走一遍确认核心链路是通的注册一个学生账号或直接用种子数据里的用户账号。如果报用户名已存在说明数据库里已经有数据换个用户名就行。登录后进入首页看车辆列表是否加载出数据。这里能验证跨域配置和车辆列表接口是否正常。选一辆状态为可租的车点击租车下单确认订单出现在我的订单里。在订单列表对这条订单执行归还看结算金额是否计算正确。用管理员账号登录进入后台看车辆管理、订单管理页面能否看到刚才操作的数据试着重置车辆状态或者修改车辆价格刷新前台页面确认数据同步变更。这五步走通说明项目核心功能正常。如果中途某一步数据没变化优先去后端控制台看有没有异常日志多半是请求接口报错而不会是什么玄学问题。6. 从能跑到能答辩亮点提炼与二次开发建议项目跑到这一步你已经比很多人强了——毕竟光是让这套前后端分离的项目跑起来就能拦住相当一部分环境搞不定的人。但说句实在话能跑只是门槛如果你想拿这篇源码做出自己的东西在答辩或面试时讲出亮点下面这几块值得花心思。6.1 答辩时可以拿出来讲的技术点不要一上来就说我用了 SpringBoot 和 Vue这种话任何一个人都会说。要有意识地把细节抛出来JWT 无状态鉴权 角色粒度控制说明你理解了 token 对比 session 的优势以及为什么管理员接口和用户接口要分开校验。统一返回体 全局异常处理这是规范的体现可以展示后端Result类和RestControllerAdvice全局异常拦截的代码位置。BigDecimal 金额计算一句话带过租赁费用结算用的是 BigDecimal 而不是 double避免精度丢失懂行的人立刻听得出来你是认真做过功课的。数据库索引与状态流转设计比如车辆编号唯一索引、订单状态和车辆状态的联动更新、事务控制。凡是你自己能解释为什么这么设计的点都是亮点。还有一个容易被忽视的加分项代码注释和命名规范。答辩时老师翻你的源码如果类名、方法名、变量名都是规范的驼峰命名、并且关键逻辑有注释印象分会差非常多。这套源码在这点上总体是过关的你二次开发时千万别把这条线丢了。6.2 从课程设计扩展到可用系统的方向如果时间充裕想把这个项目往上拔一个档次有几个性价比很高的扩展方向把押金和支付接到真实支付网关。接支付宝沙箱或微信支付沙箱是毕设里最出效果的功能之一。前端扫码支付、后端回调验签、订单状态自动流转一整套流程走下来你的系统就从演示版变成了可商用版。加入地图选车与定位。高校场景下车辆分布在校园不同停车点引入高德地图或百度地图的 JS API在页面上展示车辆位置租车时选择取车点归还时选择停车点。如果项目原本没有定位字段你可以给vehicle表加latitude、longitude两个字段后端加一个更新位置的接口就行。短信验证码登录。用阿里云短信 SDK 替换密码登录虽然价格极低但功能实现需要走前端发验证码—后端调用短信接口—校验验证码—自动登录的完整链路能写进文档里又是浓墨重彩的一笔。我个人比较推荐做地图相关的扩展因为技术上不复杂、演示效果好、老师问起来也容易答不过就是调用第三方地图 API 数据库存储经纬度 前端渲染标记点嘛。6.3 二次开发要保留的代码习惯最后说一点我在看学生代码时最介意的事情——拿到别人的项目改代码最容易出现的问题就是改崩了不知道自己改了什么。所以你在动代码前建议先给项目做一个 Git 初始化git init git add . git commit -m 初始版本原项目代码每完成一个功能改造就提交一次。这样不管改坏到哪里随时可以git reset回到上一个能跑的状态。不要觉得这是多余动作我见过太多同学把项目改得乱七八糟最后自己都救不回来然后哭着来找我老师我的项目昨天还能跑今天突然不行了——一问改了一堆东西没有版本管理。从一个能跑的项目到一个属于自己的作品版本管理就是那条最稳的底线。另外记得把application.yml里的数据库密码改成自己的以后不要把你的真实密码提交到公共仓库。虽然这只是一个课程设计项目但养成敏感信息不进版本库的意识对你以后进企业工作有帮助。可以用application-example.yml放一份脱敏配置再把真实的配置写进.gitignore。这些细节看似跟功能无关但恰恰是区分会写代码和有工程素养的分水岭。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询