简介:这是一套基于SpringBoot与Vue.js开发的汽车租赁系统完整源码,面向计算机相关专业的课程设计、毕业设计及Java全栈入门者,可帮助读者快速搭建一套可运行的车辆租赁业务平台,涵盖用户管理、车辆信息维护、订单处理与权限控制等核心模块。压缩包共150个文件,约1.18MB,其中57个Java源文件承载后端业务逻辑,19个XML与2个YAML、2个properties负责框架与数据源配置,26张JPG与25张PNG提供界面素材,另有15个class编译文件及md说明文档,结构完整、层次清晰。该资源为个人98分高分大作业设计,已获导师指导认可并通过严格调试,确保可直接运行。目前已有146人学习关注,适合需要参考完整项目架构、学习Shiro权限整合与前后端分离开发思路的读者下载使用。
1. 从一份汽车租赁系统源码说起:它到底能跑通什么业务
如果你手头正好有一份基于 SpringBoot + Vue 的汽车租赁系统源码包,第一反应大概率是:这套东西能不能直接跑起来、能不能改成自己的项目、里面到底实现了哪些业务。我拿到这类源码的习惯是先不急着看代码,而是把业务链路在脑子里过一遍——汽车租赁的核心无非是车辆管理、门店管理、用户下单、订单审核、还车结算这几件事,剩下的都是围绕这条主线的增删改查和状态流转。
这份源码的价值在于它把「前后端分离 + 权限控制 + 订单状态机」这套组合拳完整落地了。前端用 Vue 做单页应用,后端 SpringBoot 提供 REST 接口,中间靠 JWT 或 Session 维持登录态,数据库一般是 MySQL。适合两类人:一是想拿一个真实业务场景练手前后端联调的新手,二是需要快速搭一个租赁类管理系统骨架的从业者。它不是一个玩具 demo,车辆、订单、用户、角色这几张核心表之间的关联足够你理解一个中型管理系统的分层逻辑。接下来我会按「怎么跑起来 → 关键模块怎么改 → 坑在哪」的顺序拆开讲。
2. 环境搭建与前后端启动:从 JDK 到 npm run serve 的完整链路
2.1 后端 SpringBoot 工程的依赖与配置
拿到源码先看后端目录结构,标准做法是src/main/java下按controller / service / mapper / entity分层,src/main/resources下放application.yml和mapper映射文件。启动前要确认三件事:JDK 版本、Maven 依赖、数据库连接。SpringBoot 2.x 一般配 JDK 8,2.7 以上或 3.x 建议 JDK 17,版本对不上会直接报Unsupported class file major version。
# application.yml 关键配置 server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/car_rental?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: your_password driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: mapper-locations: classpath:mapper/*.xml configuration: map-underscore-to-camel-case: true这段配置里serverTimezone必须显式指定,否则 MySQL 8 驱动会报时区错误;map-underscore-to-camel-case打开后数据库的create_time能自动映射到实体类的createTime,省掉大量手动映射。数据库要先手动建库再导入源码里的.sql文件,导入顺序是先建表再插初始数据,否则外键约束会拦你。
# 后端启动 mvn clean install -DskipTests mvn spring-boot:run-DskipTests是跳过测试类编译,很多源码包的测试类依赖了没提供的环境,不跳过会卡在编译阶段。启动成功后控制台会打印 Tomcat 端口,浏览器访问http://localhost:8080能看到接口返回或 404 都算正常,404 说明服务起来了只是没配首页。
2.2 前端 Vue 工程的安装与联调
前端目录一般叫vue-frontend或web,进去先看package.json里的依赖和脚本。Vue 2 项目用npm install后npm run serve,Vue 3 + Vite 的项目是npm run dev。装依赖时如果卡在node-sass或sass-loader,八成是 Node 版本太高,换到 Node 14 或 16 能过。
# 前端启动 npm install --registry=https://registry.npmmirror.com npm run serve--registry指定国内镜像源,能避开大部分下载超时。启动后默认跑在8080或8081,如果和后端端口撞了,改vue.config.js里的devServer.port。前后端联调的关键是代理配置,前端请求/api开头的路径要转发到后端:
// vue.config.js module.exports = { devServer: { port: 8081, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true, pathRewrite: { '^/api': '' } } } } }changeOrigin设为 true 是为了让后端收到的 Host 头是目标地址,避免某些鉴权逻辑校验失败;pathRewrite把/api前缀去掉,这样后端接口不用额外加统一前缀。联调时打开浏览器 F12,看 Network 里请求是 404 还是 401,404 查路径,401 查 token 有没有带上。
3. 核心业务模块拆解:车辆、订单与权限怎么串起来
3.1 车辆管理与订单状态流转
车辆表通常包含车牌号、品牌、型号、日租金、状态(可租/已租/维修)几个字段。订单表则记录用户、车辆、租期、总价、订单状态。状态流转是这类系统的核心逻辑,常见状态有:待支付、已支付、租赁中、已归还、已取消。后端在OrderService里用状态机或简单的 if-else 控制流转,前端根据状态渲染不同按钮。
// 订单状态流转核心逻辑 public void returnCar(Long orderId) { Order order = orderMapper.selectById(orderId); if (order.getStatus() != OrderStatus.RENTING) { throw new BusinessException("当前订单状态不允许还车"); } order.setStatus(OrderStatus.RETURNED); order.setReturnTime(new Date()); orderMapper.updateById(order); // 同步更新车辆状态为可租 Car car = carMapper.selectById(order.getCarId()); car.setStatus(CarStatus.AVAILABLE); carMapper.updateById(car); }这段代码的关键在于「先校验状态再操作」,很多源码包为了省事直接改状态,导致已取消的订单还能还车。BusinessException是自定义异常,配合全局异常处理器返回统一错误码。车辆状态和订单状态必须同步更新,否则会出现车已还但车辆仍显示已租的脏数据。
3.2 权限控制与 JWT 登录态
权限模块一般分角色:管理员、门店员工、普通用户。后端用 Spring Security 或拦截器 + JWT 实现。登录成功后返回 token,前端存 localStorage,每次请求在 header 里带Authorization: Bearer xxx。
// JWT 拦截器校验 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token = request.getHeader("Authorization"); if (token == null || !token.startsWith("Bearer ")) { response.setStatus(401); return false; } try { Claims claims = JwtUtil.parseToken(token.substring(7)); request.setAttribute("userId", claims.get("userId")); } catch (Exception e) { response.setStatus(401); return false; } return true; }substring(7)是去掉Bearer前缀,长度固定为 7。解析失败统一返回 401,前端拦截器捕获 401 后跳转登录页。这里有个常见坑:token 过期时间设太短,用户操作到一半被踢出;设太长又有安全风险,一般设 2 小时并配合刷新 token 机制。
3.3 数据库表关系与初始数据
核心表一般有user、car、order、role、menu五张。order表通过user_id和car_id关联用户和车辆。初始数据里通常有一个管理员账号,密码是加密后的,直接登录可能失败,需要用工具生成对应加密串替换。
| 表名 | 关键字段 | 说明 |
|---|---|---|
| user | id, username, password, role_id | 密码建议 BCrypt 加密 |
| car | id, plate_no, brand, daily_price, status | status 用枚举值 |
| order | id, user_id, car_id, start_date, end_date, total, status | 租期和总价需校验 |
| role | id, role_name | 管理员/员工/用户 |
导入 SQL 时注意字符集用utf8mb4,否则车牌里的特殊字符或用户昵称的 emoji 会乱码。初始管理员密码如果登录不上,用BCryptPasswordEncoder重新生成一个替换进去。
4. 避坑与排查:那些让项目跑不起来的常见问题
4.1 跨域报错 CORS
现象:前端请求后端接口,浏览器控制台报Access to XMLHttpRequest has been blocked by CORS policy。原因:前后端端口不同,浏览器同源策略拦截。解决:后端加全局跨域配置,或在 Controller 上加@CrossOrigin。推荐全局配置:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE") .allowCredentials(true) .maxAge(3600); } }注意allowedOriginPatterns和allowCredentials(true)同时用时不能用allowedOrigins("*"),否则启动报错。
4.2 数据库连接失败
现象:启动时报Communications link failure或Access denied for user。原因:MySQL 没启动、端口不对、密码错、或没建库。解决:先用命令行mysql -uroot -p确认能连上,再检查application.yml里的库名和密码。MySQL 8 还要确认driver-class-name是com.mysql.cj.jdbc.Driver,老版本驱动类名不带cj。
4.3 前端依赖装不上
现象:npm install卡住或报node-gyp错误。原因:Node 版本和依赖不匹配,或网络问题。解决:先node -v看版本,Vue 2 项目用 Node 14/16,Vue 3 项目用 Node 16+。换镜像源,删掉node_modules和package-lock.json重装。如果还不行,单独装node-sass对应版本。
4.4 接口 404 或 401
现象:前端能打开但数据加载不出来。原因:代理没配、路径写错、token 没带。解决:F12 看 Network,404 检查vue.config.js的 proxy 和pathRewrite;401 检查请求头有没有Authorization,以及 token 是否过期。后端可以在拦截器里打印请求路径,确认请求有没有到达。
4.5 打包后白屏
现象:npm run build后放到 SpringBoot 的static目录,访问白屏。原因:Vue 打包默认用绝对路径/,部署到子路径下资源找不到。解决:改vue.config.js里的publicPath为./,重新打包。
5. 二次开发与验证:把源码改成自己的项目
5.1 改造成本评估与切入点
拿到源码后不要急着大改,先跑通再动手。改造优先级建议:先改品牌和文案,再改业务字段,最后动核心逻辑。品牌文案改前端src/assets和index.html的 title;业务字段比如把「日租金」改成「月租金」,要同时改数据库字段、实体类、前端表单和列表展示。核心逻辑如订单状态机,改之前先把状态流转图画出来,确认每个状态的入口和出口。
5.2 接口验证与调试技巧
后端接口用 Postman 或 curl 单独测,不要依赖前端。先测登录拿 token,再带着 token 测其他接口。
# 登录拿 token curl -X POST http://localhost:8080/api/login -H "Content-Type: application/json" -d '{"username":"admin","password":"123456"}' # 带 token 查车辆列表 curl http://localhost:8080/api/car/list -H "Authorization: Bearer 你的token"这样能把前后端问题隔离开,接口通了再查前端。后端日志级别调到 DEBUG,能看到 SQL 执行情况,MyBatis 的 SQL 日志在application.yml里加logging.level.你的mapper包=debug。
5.3 一个具体技巧:用定时任务处理超时订单
租赁系统有个实际需求:订单创建后 30 分钟未支付自动取消。用 SpringBoot 的@Scheduled就能做,不用引入额外中间件。
@Component public class OrderTimeoutTask { @Autowired private OrderMapper orderMapper; // 每 5 分钟执行一次 @Scheduled(cron = "0 0/5 * * * ?") public void cancelTimeoutOrders() { Date deadline = new Date(System.currentTimeMillis() - 30 * 60 * 1000); List<Order> orders = orderMapper.selectList( new QueryWrapper<Order>() .eq("status", OrderStatus.UNPAID) .lt("create_time", deadline) ); for (Order order : orders) { order.setStatus(OrderStatus.CANCELLED); orderMapper.updateById(order); } } }cron表达式0 0/5 * * * ?表示每 5 分钟的第 0 秒执行。deadline是当前时间往前推 30 分钟,查出所有未支付且创建时间早于这个点的订单批量取消。注意启动类上要加@EnableScheduling,否则定时任务不生效。这个逻辑上线前要确认数据库时区和 JVM 时区一致,否则时间算出来会差 8 小时。
从那以后我每次拿到这类源码,都强制先跑通登录和一条完整业务链路,再动任何一行代码。希望帮到你。
本文还有配套的精品资源,点击获取