ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SpringBoot+Vue+MySQL全栈毕业设计:大学生租房平台从需求到部署完整实战

SpringBoot+Vue+MySQL全栈毕业设计:大学生租房平台从需求到部署完整实战 毕业设计年年都有但“大学生租房平台”这个选题我在带毕设和面试候选人的过程中见的频率相当高。原因很简单它属于典型的信息管理系统类项目业务逻辑清晰但不单薄技术栈覆盖全面既能体现 CRUD 基础又能深入权限控制、文件上传、订单状态机这类进阶点用来做 SpringBoot Vue MySQL 全栈毕业设计再合适不过。这篇文章不打算站在讲台上给你念 PPT而是尽量以拿过这套题目、也带过这套题目的过来人视角把“大学生租房平台”从需求拆解到数据库设计从后端接口到前端页面从本地联调到部署上线的完整链路捋一遍。源码、数据库脚本、论文结构和部署文档这些东西你自己下载下来对着看是一回事知道每一步为什么这么做、遇到问题怎么排查是另一回事。下面我按实际做项目的顺序来聊。1. 项目整体需求拆解与技术选型思路1.1 为什么选“租房平台”作为毕业设计题目选题好坏直接决定后面三个月的写代码体验。对比常见的图书管理系统、商城系统、博客系统大学生租房平台有一个非常大优势——业务角色天然分为两类房东和租客。有角色区分就必然有权限控制的需求有房源信息就必然有图片存储与展示的需求有看房、签约流程就必然有订单状态流转的需求。这些点组合起来正好覆盖 SpringBoot 后端、Vue 前端、MySQL 数据库三者的核心考点又不至于复杂到半年做不完。单纯做一套 CRUD 系统答辩时老师问几个业务逻辑问题就容易卡壳。租房平台天然具备几条完整的业务链用户注册登录、房东发布房源、租客浏览搜索房源、提交看房预约、线下看房后签约下单、订单状态更新、个人中心管理、后台管理员审核。每一条链都可以单独拿出来讲设计思路和实现细节这就让论文有话可写答辩有内容可讲。从市场热度看“租房”是大学生群体最关心的话题之一尤其大四毕业季、研究生入学季都有大量租房需求。做这个题目的现实意义不需要编造论文的“研究背景”和“意义”章节写起来非常顺不容易被老师质疑选题价值。1.2 技术栈选型背后的考量SpringBoot 2.7.x Vue 2 MySQL 5.7这套技术栈不是随便选的我遇到过太多用最新版本来做项目结果被各种兼容性问题折磨的案例。先说版本问题再解释选型逻辑。SpringBoot 版本选择 2.7.x不要一上来就选 3.x。SpringBoot 3 基于 JDK 17要求 Jakarta EE 命名空间很多老教程里的 javax.servlet 全部要改成 jakarta.servlet在线程池、AOP、数据库驱动层面也有不少细微差别。大部分毕业设计论文的模板、参考代码、视频教程都基于 SpringBoot 2.x你选了 3.x 很可能遇到“代码一模一样但启动报错”的尴尬。2.7.x 是 2.x 系列的最后一个维护版本成熟稳定学习资料最丰富对 JDK 8 友好完全够用。前端框架选择 Vue 2.6.x 加 Element UI。Vue 3 虽然已经发布多年但 Vue 3 的生态配置方式、Element Plus 的组件用法和网上大量 Vue 2 教程存在差异。毕设阶段追求的是把业务功能完整做出来而不是尝鲜新框架。Vue 2 配合 Element UI组件丰富、中文文档齐全、问题搜索秒出答案是最稳的组合。数据库选择 MySQL 5.7。MySQL 8.0 的 caching_sha2_password 认证插件经常导致 navicat、老版本驱动连接时报错5.7 的 mysql_native_password 则没有这个问题。虽然 5.7 已经停止更新但作为毕设完全够用等以后工作中再接触 8.0 也不迟。如果你电脑里已经装了 8.0那就把驱动版本和连接 URL 里的 useSSL、allowPublicKeyRetrieval 参数配好不强行卸载重装。1.3 功能模块划分与角色权限模型整个平台按用户角色划分三个端租客端、房东端、管理员端。很多同学做这个题目时容易把权限做得过于粗糙比如所有登录用户看到同一套界面这就失去了项目亮点。租客端核心功能注册登录、浏览房源列表、按区域/价格/户型条件搜索、查看房源详情、收藏房源、提交看房预约、查看预约状态、在线签约下单、评价房源、个人资料维护。房东端核心功能注册登录、发布房源含多图上传、管理自己的房源列表、下架/上架房源、查看收到的看房预约、确认或拒绝预约、处理租客订单、查看收益统计。管理员端核心功能后台登录独立于前台的权限拦截、用户管理禁用/启用账号、房源审核新发布房源需审核通过才在前台展示、预约管理、订单管理、公告管理。权限控制的实现方式这是必考点。后端通过拦截器统一校验登录状态登录成功后返回 token用 JWT前端将 token 存到 localStorage 并在 axios 请求头中携带。后端接口通过注解或拦截器判断角色比如/api/house/save这个接口要求登录用户角色为 landlord管理员接口要求 role 为 admin。答辩时老师大概率会问“不同角色的用户如何限制访问权限”这个实现链路你必须说得清楚。2. 数据库设计与核心表结构详解2.1 数据表设计的整体规划数据库是整个系统的地基。地基没打好后面写代码时表之间关联混乱、字段缺失返工成本极高。我建议在写代码之前先把表结构完整设计出来并在数据库脚本中标清楚主键、外键、索引、字段注释。核心数据表可以规划为以下 8 张user用户表存放租客和房东的用户信息house房源表存放房源基础信息house_image房源图片表一张房源对应多张图片appointment看房预约表租客预约房东看房order订单表租客签约租房订单favorite收藏表租客收藏的房源comment评价表租客对房源的评价notice公告表平台公告信息如果你还想做后台管理端的账号体系可以单独建一张admin表或者复用 user 表加一个role字段并用一个特殊标记区分。我更推荐单独建 admin 表这样前台用户登录和后台管理员登录两套鉴权逻辑完全隔离后端写起来更清晰答辩时展现的设计思路也更合理。2.2 核心表字段设计与字段类型选择用户表的关键字段不要只放 username 和 password。一个完整的用户表至少应该包含id、username、password加密存储、nickname、phone、avatar、role0 租客 / 1 房东、status0 正常 / 1 禁用、create_time、update_time。password 字段务必须用 BCryptPasswordEncoder 加密绝不能明文存储。这既是安全要求也是论文中可以拿出来讲的亮点。数据库字段长度方面password 存放加密后的哈希串长度设为 100 比较稳妥不要图省事设成 20。房源表是整个系统的核心字段设计直接体现你对业务的理解。建议字段包含id、user_id房东 id 外键、title、description、house_type户型如整租/合租、area面积、rent月租金、deposit押金、province、city、district、address、longitude、latitude做地图展示时用、status0 待审核 / 1 已上架 / 2 已下架、create_time、update_time。可以在district rent house_type上建联合索引因为租客端搜索时最常用的筛选条件就是这几个。订单表字段设计要注意状态字段的语义。我的建议是status 用 0 待支付、1 已支付、2 已入住、3 已退租、4 已取消枚举值表示。订单还要关联 house_id、user_id租客、appointment_id可选标识订单从哪个看房预约转化而来、start_time、end_time租期、total_amount。这个表是系统的交易主链路答辩时老师问“订单状态如何流转”你能够把一个订单从创建到取消全过程的 status 变化讲清楚就是不错的亮点。2.3 外键与索引设计的经验之谈数据库外键要不要加这个问题在开发圈里一直有争议。我的观点是毕设阶段不要大量使用物理外键约束但要在逻辑上维护关联关系。理由很简单物理外键约束会影响删除和更新操作的灵活性比如你想删除一条房源记录但订单表中关联了该房源外键约束会直接拦截删除操作导致你要先处理完订单表的数据才能删逻辑变得非常绕。但逻辑外键关联一定要做也就是说在 house 表里保留 user_id 字段创建这个字段的索引外键就是最常用的查询条件查询时用 left join 或单独查询 user 表来获取房东信息。这样既保证了数据操作灵活又能通过索引保证查询性能。在论文的数据库设计章节里你可以用表格列出外键关系然后补充一句话“本设计从实际业务扩展性考虑采用逻辑外键方式维护表间关系”老师看了会认为你有工程经验。3. 后端 SpringBoot 核心实现与关键接口设计3.1 项目初始化与分层架构后端工程的结构清晰程度直接影响指导老师对论文代码部分的评价。我的建议是遵循阿里编码规范的分层结构com.example.rental ├── config配置类CORS、拦截器、Knife4j ├── controller接口入口层 ├── service业务逻辑层 ├── mapper数据访问层 ├── entity实体类 ├── dto数据传输对象接收前端参数 ├── vo视图对象返回前端数据 ├── common统一返回结果、错误码、异常处理 ├── utils工具类JWT、文件上传等统一返回结果这个点特别容易被忽略但非常重要。前端每次请求后端的返回格式应该是一致的比如{ code: 200, message: 操作成功, data: {} }所以你需要定义一个Result类泛型设计包含 code、message、data 三个字段。controller 层所有接口都返回这个 Result前端 axios 封装里统一判断 code 是否为 200非 200 弹出 message。这种设计在答辩时可以理直气壮地说“采用了前后端分离架构下的统一响应格式设计”。3.2 登录鉴权与 JWT 的完整实现登录接口的实现流程要清楚。用户提交 username 和 password后端通过 username 查询用户用 BCryptPasswordEncoder 的 matches 方法校验密码。密码校验通过后生成 JWT tokentoken 里可以放入 userId 和 role然后返回给前端。前端后续请求都在 header 中携带 Authorization: token。JWT 工具类的核心代码大致长这样Component public class JwtUtils { Value(${jwt.secret}) private String secret; Value(${jwt.expire}) private Long expire; // 生成token public String generateToken(Integer userId, String role) { Date now new Date(); Date expiryDate new Date(now.getTime() expire * 1000); return Jwts.builder() .setSubject(String.valueOf(userId)) .claim(role, role) .setIssuedAt(now) .setExpiration(expiryDate) .signWith(SignatureAlgorithm.HS256, secret) .compact(); } // 解析token获取userId public Integer getUserId(String token) { Claims claims Jwts.parser() .setSigningKey(secret) .parseClaimsJws(token) .getBody(); return Integer.valueOf(claims.getSubject()); } // 校验token是否有效 public boolean validateToken(String token) { try { Jwts.parser().setSigningKey(secret).parseClaimsJws(token); return true; } catch (Exception e) { return false; } } }拦截器实现登录拦截这段逻辑建议背下来。实现 HandlerInterceptor 接口preHandle 方法中从请求头获取 token校验通过则放行否则返回 401 错误。登录接口和注册接口要排除在外前端静态资源也建议排除。角色权限控制我采用的方式是自定义注解RequireRole(landlord)拦截器里先做登录校验再通过 HandlerMethod 获取注解判断当前用户角色是否匹配。这种方式代码简洁答辩时讲解也很清晰。3.3 房源发布与图片上传的完整实现房源发布功能涉及一个关键技术点图片上传。前端通过 Element UI 的 el-upload 组件选择多张图片向后端发起 multipart/form-data 类型的请求。后端接口接收 MultipartFile 数组逐个保存到服务器本地指定目录比如 D:/upload/ 或项目资源目录返回访问路径再把房源信息和图片路径一起保存到数据库。图片上传的存储路径设计要注意一个坑如果你把图片存在项目 resources 目录下打包成 jar 后路径就失效了。更稳妥的做法是把图片存到一个独立的磁盘目录然后通过配置虚拟路径映射让前端能够访问。比如在 SpringBoot 中配置Configuration public class WebMvcConfig implements WebMvcConfigurer { Value(${file.upload-dir}) private String uploadDir; Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/upload/**) .addResourceHandler(file: uploadDir /); } }这样上传的图片可以通过http://localhost:8080/upload/xxx.jpg直接访问。3.4 看房预约与订单状态流转看房预约和订单状态流转是这个项目里业务逻辑最复杂、也是最值得展开讲的两个功能。预约流程租客在房源详情页点击“预约看房”填写期望看房时间和联系电话提交后生成 appointment 记录status 为 0 待确认。房东端收到预约消息后可以点击确认status 变为 1或拒绝status 变为 2。预约确认状态会通过前端轮询或刷新页面更新显示。这里涉及一个后端设计细节租客提交预约前应该先判断该房源是否已经存在待确认或已确认的预约冲突避免同一时段重复预约。不过毕设阶段简单处理为“每个房源同一时间段只允许一个待确认预约”即可不用引入真正的排班系统。订单流程租客看房满意后在详情页点击“立即签约”后端生成 order 记录。租客点击“确认入住”后状态变为已入住到达退租时间后变为已退租。订单状态变化的核心逻辑都写在 service 层方法内部使用状态机式判断避免状态乱跳。比如只有“待支付”才能变“已支付”“已支付”才能变“已入住”。3.5 后台管理端的核心接口管理员端接口相对简单但需要一套独立的鉴权逻辑。管理员登录走 admin 表登录成功后同样生成 JWT但 token 中包含的角色字段为 admin。后台管理端接口统一加上RequireRole(admin)注解。房源审核接口的设计有个值得说的点新房源默认为待审核状态前台列表查询接口只返回 status 为 1已上架的房源。管理员审核通过时把 status 改为 1如果不通过则改为 3 并填写审核失败原因。这个流程干净清晰也体现你对实际业务的思考。4. 前端 Vue 核心页面实现与前后端联调4.1 前端工程结构与路由设计前端工程使用 Vue CLI 4.x 创建目录结构如下src ├── apiaxios 请求封装与各模块接口定义 ├── assets静态资源 ├── components公共组件 ├── router路由配置 ├── storeVuex 状态管理 ├── views页面组件 │ ├── home前台首页 │ ├── house房源列表/详情 │ ├── rent租客端功能 │ ├── landlord房东端功能 │ ├── admin后台管理 │ └── login登录注册 ├── utils工具类token存储、时间格式化 ├── App.vue └── main.js路由配置要做权限校验这个用 Vue Router 的路由守卫实现。核心逻辑在router/index.js的beforeEach中代码如下router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (to.meta.requiresAuth !token) { next(/login) return } if (to.meta.role) { const role localStorage.getItem(role) if (role ! to.meta.role) { next(/403) return } } next() })每个路由配置时可以通过 meta 标记是否需要登录、需要哪个角色。比如房东端发布房源页面meta: { requiresAuth: true, role: landlord }后台管理页面meta: { requiresAuth: true, role: admin }。路由守卫逻辑虽然简单但配合后端拦截器形成了双重防护答辩时非常加分。4.2 axios 封装与请求拦截器axios 封装建议单独建一个 request.js 文件。主要做三件事baseURL 配置、请求拦截器携带 token、响应拦截器统一处理业务码。import axios from axios import { Message } from element-ui import router from ../router const request axios.create({ baseURL: /api, timeout: 10000 }) request.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers[Authorization] token } return config }) request.interceptors.response.use( response { const res response.data if (res.code ! 200) { Message.error(res.message || 请求失败) if (res.code 401) { localStorage.removeItem(token) router.push(/login) } return Promise.reject(new Error(res.message)) } return res }, error { Message.error(网络异常请稍后重试) return Promise.reject(error) } )这里有个开发环境联调的小技巧。前端开发服务器默认在 8080 端口后端接口在 8080 端口存在跨域问题。后端的解决方案是配置 CORS 拦截器或CrossOrigin前端的解决方案是在 vue.config.js 中配置 devServer 代理把/api开头的请求转发到后端地址module.exports { devServer: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } }推荐优先用前端代理方案因为生产环境部署时前端打包后交给 Nginx 托管Nginx 里同样配置/api反向代理到后端服务思路是一致的。前端代理和后端 CORS 二选一就行两个都配有时候反而会出问题。4.3 核心页面房源列表与搜索条件房源列表页是整个前端最核心的页面。实现思路页面加载时调用房源列表接口获取所有已上架房源数据循环渲染为卡片列表。搜索区放置区域下拉框、户型下拉框、租金区间输入框点击搜索按钮后重新请求列表接口将筛选条件作为请求参数传过去。一个要注意的细节是后端的分页查询接口建议统一返回分页对象包含 total总条数、records当前页数据、current当前页码、size每页条数。前端用 Element UI 的 el-pagination 组件展示分页切换页码时更新查询参数并重新调用接口。我见过不少同学把分页逻辑做成前端一次性拉全量数据然后前端自己切片。这样数据量小的时候确实能跑但答辩时老师问“数据量达到一万条时性能如何”就会一脸尴尬。后端分页是最基本的工程素养MyBatis Plus 的分页插件只需要几行配置就能实现。4.4 房源详情页与图片轮播房源详情页包含图片轮播、基本信息、房东信息、预约按钮、签约按钮。图片轮播使用 Element UI 的 el-carousel 组件即可。详情页的关键是数据加载逻辑。通过路由参数拿到 houseId调用getHouseDetail(houseId)接口获取详情。这里我建议把基本信息放在 JSON 里一次返回而不是多次请求。后端可以定义一个 HouseDetailVO 类把房源字段、图片列表、房东信息都组装进去一次查出来返回给前端。前端组件只有一次网络请求页面渲染速度快逻辑也好理解。房东信息旁边可以考虑加一个收藏按钮和评价展示区域。收藏功能的接口设计是POST /api/favorite/{houseId}通过 JWT 获取当前用户身份保存收藏关联。要注意重复收藏的校验后端在保存前先查一下是否已存在该用户与该房源的收藏记录。4.5 房东管理与租客中心页面房东端的管理页面比较简单。房源管理页是一个表格列展示房源标题、租金、户型、状态、操作。操作按钮根据状态动态显示待审核状态不能操作已上架状态显示“下架”已下架状态显示“上架”。租客端的订单管理页展示当前登录用户的所有订单、候选状态、操作按钮。已取消和已退租的订单操作列为空。前端通过 v-if 控制按钮显隐即可不需要额外复杂逻辑。需要注意的重点是前端操作按钮的显示要与后端状态流转逻辑一致避免前后端状态值对应不上。5. 从源码到论文如何把项目高效梳理成毕业设计5.1 论文结构与写作顺序建议很多同学代码写完发现论文还没动于是匆匆找一个模板套内容结果论文质量和代码完全不匹配被老师打回修改。我的建议是论文写作按照七个章节来组织第一章 绪论写研究背景、目的意义、国内外研究现状、本设计主要工作第二章 相关技术介绍写 SpringBoot、Vue、MySQL、Element UI、JWT 等第三章 系统分析写可行性分析、需求分析、用例图、用例描述、功能需求和非功能需求第四章 系统设计写总体架构设计、功能模块设计、数据库设计重点画 ER 图和表结构第五章 系统实现写核心功能模块的实现过程配合核心代码截图和运行效果截图第六章 系统测试写测试目的、测试方法、测试用例设计、测试结果第七章 总结与展望写完成的工作、收获、不足和后续改进方向写论文和写代码的顺序应该是反过来的。先画用例图梳理角色和功能再画 ER 图确定表结构然后设计接口文档前后端并行开发最后根据实现效果截图补充第五章。很多同学的用例图是代码写完后才补的补的时候会发现用例图里的功能代码里根本没实现改来改去非常痛苦。5.2 系统测试部分怎么写系统测试部分建议先写测试用例表再写测试过程与结果。不要只写单元测试更不要不写直接跳过去。测试用例表至少应该覆盖以下场景编号测试模块测试步骤预期结果实际结果01用户注册输入用户名、密码点击注册注册成功跳转登录页符合预期02用户登录输入正确账号密码点击登录登录成功进入首页符合预期03用户登录输入错误密码点击登录提示密码错误符合预期04房源发布填写房源信息上传图片点击发布提示提交成功待平台审核符合预期05房源检索选择区域、价格区间点击搜索显示符合条件房源符合预期06预约看房未登录点击预约看房跳转登录页符合预期07预约看房已登录填写看房时间提交预约预约成功状态待确认符合预期08签约下单对已上架房源点击签约生成订单状态待支付符合预期09后台审核管理员对房源进行审核审核通过后房源状态变为已上架符合预期测试结果部分不要只是干巴巴地写“测试全部通过”。分功能模块在表格中列出测试结论配合两三个关键测试截图再补充一下浏览器兼容性测试结果比如 Chrome、Edge 下页面显示正常这部分内容就丰满多了。5.3 答辩前需要准备的高频问题答辩时老师大概率会针对代码和设计提问把这几个问题提前准备充分能大大降低临场紧张感。第一个问题你这个项目的角色权限是怎么实现的回答思路前端通过路由守卫控制页面访问权限后端通过拦截器加注解校验接口权限前端控制的是用户体验后端控制的是数据安全。第二个问题密码是怎么存储的回答思路使用 Spring Security 自带的 BCryptPasswordEncoder 进行加密每次加密得到的哈希值不同数据库里不存明文密码即使数据库泄露用户密码也不会直接暴露。第三个问题Token 过期怎么处理回答思路本项目采用 JWT 前端路由守卫的方案Token 过期后后端返回 401前端响应拦截器捕获后清除本地 token 并跳转登录页。如果让我改进可以引入 Refresh Token 机制但考虑到项目定位目前方案已经够用。第四个问题首页房源数据量很大你怎么优化查询性能回答思路首先数据库层面建立联合索引其次后端做分页查询不在一个接口里返回全量数据另外可以考虑加 Redis 缓存热门房源数据。答出前两点已经是及格线以上。6. 开发环境搭建与部署全过程记录6.1 本地开发环境版本锁定环境问题在毕设类项目中造成的返工率远高于写业务代码。我在帮学生排查问题时遇到最多的是 MySQL 连不上、Node 版本不兼容、Maven 依赖下载失败这三件事。推荐一套本地开发环境的稳定组合JDK 1.8、Maven 3.6.3、MySQL 5.7、Node 14.x 或 16.x、Vue CLI 4.x、IDEA 2022 或 2023。这套组合互相之间的兼容性已经被验证过无数次。MySQL 安装时有一个关键点容易踩坑安装完成后要用命令行或 Navicat 测试连接。如果 root 密码设置后忘记了在 my.ini 配置文件里加一行 skip-grant-tables重启 MySQL 可以免密进入改完密码后把这行删掉再重启。这是排查 MySQL 连接问题的常见手段建议提前掌握。6.2 数据库初始化与测试数据拿到项目后第一步不是启动后端而是先执行数据库脚本。在使用 Navicat 新建数据库时字符集选择 utf8mb4排序规则选择 utf8mb4_general_ci然后运行项目提供的 SQL 文件。如果项目只有建表语句没有测试数据你需要自己造一批不然前后台页面全是空荡荡的看起来非常潦草。造测试数据有个捷径使用 Python 的 Faker 库批量生成模拟数据几十个房源信息、几十个用户信息几秒钟就能生成完毕。比如生成 50 个用户、120 套房源、200 条收藏记录、50 条订单记录前端列表页、后台管理页、图表统计页面的展示效果一下子就有了。注意测试数据要贴近实际不要写“abc123”这种明显敷衍的内容指导老师和评阅老师打开页面第一眼就会看到这些数据。6.3 Maven 打包与前端 build 的完整流程本地开发调试没问题后就到了部署环节。很多同学只会在 IDEA 里点 Run不会打生产包这个短板在毕业设计答辩的“演示环境”环节会非常尴尬。后端的部署流程是这样的在 IDEA 右侧 Maven 面板中先执行 clean再执行 package会在 target/ 目录下生成 jar 包。如果不想用 IDEA 面板也可以在项目根目录执行命令行mvn clean package -DskipTests生成的 jar 包在服务器上使用java -jar xxx.jar启动。如果担心端口被占用用nohup java -jar xxx.jar app.log 21 方式后台启动。如果服务器内存紧张可以加 JVM 参数限制内存占用java -Xms256m -Xmx512m -jar xxx.jar前端部署流程在项目根目录执行npm run build会生成 dist 目录。将 dist 目录拷贝到 Nginx 的 html 目录下然后配置 Nginx把前端静态页面和/api接口请求区分开location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }注意try_files这行配置很重要。Vue Router 默认使用 history 模式刷新页面时如果 Nginx 没有这行配置会出现 404 错误。加了这行配置所有非文件请求都会回退到 index.html由前端路由接管。6.4 数据库脚本导出与部署文档的整理数据库脚本的导出推荐用 Navicat 的“转储 SQL 文件”功能选择“结构和数据”同时导出。这样别人拿到项目后直接执行一个 SQL 文件就能完成数据库初始化不用手动建库建表。部署文档的写法建议按照从零到一的顺序先写环境要求JDK、MySQL、Node 版本再写数据库初始化步骤然后写后端启动步骤接着写前端构建步骤最后写访问方式默认账号密码列表。每一步都配上截图让完全不了解这个项目的同学照着文档也能把系统跑起来。部署文档在论文的“附录”中也可以附上一份指导老师会认为项目可复现性很强。7. 常见运行问题与排查技巧实录7.1 后端启动报错端口被占用这个问题几乎每个同学都会遇到。启动 SpringBoot 项目时提示 Port 8080 was already in use通常是上一次运行没有正常结束或者电脑上有其他程序占用了 8080 端口。排查方法分三步第一步Windows 下打开命令行执行netstat -ano | findstr 8080找到占用 8080 端口的进程 PID第二步在任务管理器里找到对应进程并结束任务第三步如果确认是 Java 进程也可以直接改后端配置文件里的端口号比如改成 8081。修改后记得前端的代理配置 target 也要同步修改。7.2 数据库连接失败Access denied for user启动后端报 Access denied for user root 时大概率是密码错误但也有一种隐蔽情况数据库连接 URL 中配置了错误的数据库名而该用户对该库没有访问权限。检查顺序先确认 application.yml 中的 url 写法是jdbc:mysql://localhost:3306/rental?useUnicodetruecharacterEncodingutf8useSSLtrueserverTimezoneAsia/Shanghai再确认用户名密码是否正确最后确认 MySQL 服务有没有启动。MySQL 5.7 和 8.0 的连接 URL 略有不同。8.0 需要追加allowPublicKeyRetrievaltrue否则部分客户端连接时会报 Public Key Retrieval is not allowed 错误。建议你在 application.yml 的 url 后面把常用参数都加上减少环境差异导致的问题url: jdbc:mysql://localhost:3306/rental?useUnicodetruecharacterEncodingutf8useSSLtrueserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue7.3 前端启动报错Module not foundnpm run serve报 Module not found 错误大部分原因是没有安装依赖。拿到一个全新的 Vue 项目后第一件事永远是执行npm install而且一定要在项目根目录执行不要放错目录。如果 install 过程中报权限错误Windows 下用管理员身份打开命令行重新执行。如果npm install已经执行过还是报模块缺失先删除 node_modules 目录和 package-lock.json 文件重新执行npm install。有时 npm 缓存导致依赖安装不完整npm cache clean --force清理缓存后重装也能解决。node_modules 目录特别大的时候不要在编解码工具里直接删除速度慢且容易报文件占用错误用命令行rmdir /s /q node_modules更高效。7.4 Vue 打包后布局异常错乱这个问题是热搜词里的高频痛点。本地开发npm run serve一切正常npm run build后部署到服务器样式全部错乱图片也不显示。根本原因是打包后的静态资源路径默认是相对路径而部署到服务器后页面可能不在根目录。解决方案是在 vue.config.js 中设置publicPath: ./module.exports { publicPath: ./, outputDir: dist, assetsDir: static }打包出的 CSS 和 JS 资源会使用相对路径本地部署到子目录也能找到资源。这个配置在取论文部署部分时值得单独提一下属于典型的经验坑。7.5 跨域问题前端请求接口 404 或 No Access-Control-Allow-Origin前端开发环境和后端接口地址不一致时浏览器会拦截跨域请求。处理手段有两种第一种后端配置 CORS 全局跨域支持第二种前端配置 devServer 代理转发。我推荐直接用前端代理方案。使用前端代理时前端代码里 axios 请求的 baseURL 写成/api而不是http://localhost:8080这样浏览器看到的是同源请求不会有跨域拦截实际请求经过 Webpack DevServer 转发到了后端。生产环境部署到 Nginx 后同样通过location /api反向代理过去。一条路走到底不需要在后端额外处理跨域。7.6 数据库导入 SQL 时报错SQL 文件导入时报错大多数是 1064 语法错误原因可能是本地 MySQL 版本比 SQL 脚本使用的版本低比如脚本用了 8.0 的语法或新特性在 5.7 上执行报错。还有一种高频错误是字段名是 MySQL 关键字比如order、desc、status导入时需要用反引号包围。如果你后续要手动修改数据库脚本避免用 keyword 作为字段名可以在 MySQL 官方文档查询保留字列表。7.7 打包后图片显示不出来后端上传的图片存放在本地磁盘目录通过虚拟路径映射访问。前端页面访问图片时如果图片地址是http://localhost:8080/upload/xxx.jpg本地开发没问题部署到服务器后你把后端接口地址改成了服务器 IP但 Vue 页面的图片地址可能还是 localhost自然显示不出来。建议图片地址不要写死可以在 Vue 的全局配置里维护一个 baseUrl 变量图片地址用 baseUrl 相对路径拼接。每次更换环境只需要修改一个配置文件不用全局搜索替换。更优雅的方案是使用 Nginx 托管上传目录通过静态资源 URL 访问图片但毕设阶段维护一个公共配置变量完全够用。8. 这套项目还能怎么扩展与加分如果时间充裕或者想让自己在答辩中更有优势以下几个方向可以在基础功能之上做增量扩展。第一个方向是数据可视化。管理员后台加一个统计面板展示房源数量趋势、订单成交量、用户增长情况用 ECharts 绘制折线图和柱状图。这个功能的数据接口很容易实现SQL 里按日期分组统计即可但视觉效果和项目完整度提升非常明显。第二个方向是消息通知。当租客提交看房预约时房东端收到预约提醒当管理员审核通过房源时房东收到审核通过提醒。实现上可以引入 WebSocket或者简单用系统内站内信。WebSocket 的引入会让项目的技术层次提升不少论文中相关技术的章节也能多写两页。第三个方向是 Redis 缓存。热门房源列表、首页轮播图等请求频率高、实时性要求不高的数据可以缓存到 Redis设置 5 分钟的过期时间。这个优化在数据量大时效果显著也是面试时常见的考点。第四个方向是接入地图定位。房源发布时前端通过地图 API 选取经纬度或地址搜索首页房源列表展示时点击地图图标可以定位到具体位置。地图 API 的引入让整个项目从“单纯的信息系统”升级为“信息 位置服务”在毕业设计评审中容易获得更高的印象分。我在实际带这个项目的过程中最深的一个体会是毕业设计的基础功能谁都能做核心的差距在于有没有把每一步的技术选型和实现逻辑想明白。不要满足于把代码跑通而是要把每段代码的设计理由记在脑子里这样论文里每一章写起来都有底气答辩时每一个问题都能接得住。按照这篇文章的顺序从数据库脚本到后端代码从前端页面到部署上线一步一个脚印走完你收获的不仅是毕业设计一个“通过”的结果更是对整个全栈开发流程的一次完整认知升级。
返回列表