
做毕设最怕什么不是写代码而是折腾到最后一刻发现项目跑不起来、数据库没数据、演示的时候处处是坑。SpringBoot Vue 房产销售系统这套完整项目源码、SQL脚本、接口文档都齐了就是冲着拿来能用去的。这个项目适合谁很简单正在做 Java Web 毕设、需要前后端分离项目练手、或者想了解房产销售业务怎么落地的同学。技术栈不花哨SpringBoot 3.x或 2.x看版本配 Vue2/3 都行MySQL 存储JWT 做登录鉴权前端管理后台加用户展示端该有的模块都齐——房源管理、预约看房、订单签约、公告发布、统计报表。我把这个项目从头到尾拆一遍从数据库设计到接口文档怎么组织再到部署运行中的坑和答辩展示要点一次讲清楚。1. 项目定位与功能全景1.1 核心需求解析房产销售系统说白了就是把线下的售楼处挪到线上。客户在小程序或网页上看房、预约、留资销售人员跟进客户、录入房源、管理签约。毕设级别不需要搞复杂的 ERP 逻辑但两端的业务闭环必须完整用户端能看能约管理端能管能卖。这套项目的定位非常明确管理后台 用户前端。用户前端负责展示楼盘信息、房源列表、户型图、价格区间注册登录后可以预约看房、收藏感兴趣的房源管理后台则给不同角色使用——管理员管账号、管数据销售人员管房源录入、处理预约、登记成交订单。需要注意的是这套系统本质上做的是房源信息流 商机跟进流不涉及真实的网签备案、贷款审批这些线下重流程。做毕设时在答辩中要能说清楚这个边界这恰恰是项目的合理范围。1.2 功能模块拆解我把这套系统的核心功能模块整理了一下各模块之间的关系如下用户认证模块注册、登录、JWT 生成与校验、刷新令牌、权限路由。管理端和用户端走同一套认证体系通过角色字段区分。房源管理模块房源信息的增删改查、上下架、图片上传、价格与户型字段维护。支持按区域、价格区间、户型、状态筛选。预约看房模块用户提交看房申请销售人员查看预约列表、确认或驳回预约附带联系时间、备注字段。订单签约模块预约确认后可创建订单关联房源与客户记录签约价格、付款方式、签约时间。公告管理模块管理员发布楼盘新闻、活动公告用户端展示动态。数据统计模块房源总数、成交数量、成交总额、按销售员排行通常用 ECharts 画柱状图和饼图。客户管理模块记录咨询客户信息留资跟进销售可以给自己的客户打标签、写跟进记录。这些模块拆出来之后开发顺序就有了先做认证再做房源 CRUD然后做预约与订单最后补统计和公告。每一块都是独立的表代码也是独立的分层。1.3 角色与权限设计常见的角色划分是三种系统管理员、销售顾问、普通用户客户。权限设计上不需要 Spring Security 的长篇配置用 JWT 配合拦截器做路由级别校验就够角色核心权限典型操作管理员全部权限账号管理、数据看板、房源上下架、公告管理销售顾问业务操作权限房源录入与编辑、预约处理、订单登记、跟进客户普通用户用户端权限浏览房源、预约看房、收藏房源、查看公告这套角色设计在答辩中有个好处可以顺着谁在什么场景下需要什么功能来讲比单纯背代码有说服力。数据库层面就是 users 表里加一个 role 字段路由守卫根据角色控制页面可见性。2. 技术架构与选型逻辑2.1 后端 SpringBoot 方案SpringBoot 当家花旦的地位不用多说。内嵌 Tomcat、自动配置简化了大量 XML 配置非常适合快速交付毕业设计。数据持久层用的是 MyBatis-Plus它对单表 CRUD 几乎免写 SQL分页插件直接传 pageNum、pageSize 就行。反馈说毕设中一点要有难度说明SpringBoot 的 Web 层本身不复杂真正的技术难点集中在三块JWT 无状态鉴权的拦截流程、多表关联查询的 SQL 写法、图片上传与静态资源映射。这三块我会在后面详述。依赖坐标大概这样Mavendependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3/version /dependency dependency groupIdcom.auth0/groupId artifactIdjava-jwt/artifactId version4.4.0/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency2.2 前端 Vue 方案前端用的是 Vue Element UI Axios ECharts组合稳得一批。Vue Router 做路由Vuex 或 Pinia 管理用户登录态Axios 统一封装请求拦截器把 token 加到请求头响应拦截器统一处理 401 跳转登录。管理端的页面结构大致是登录页 → 布局页左侧菜单 顶栏 → 各业务模块页面。用户端则是独立的页面首页展示楼盘 banner、房源列表页带筛选条件、房源详情页、个人中心。组件封装层面至少要抽出一个分页表格组件、一个图片上传组件、一个筛选表单组件。这样到写列表页和带条件的查询的时候就是拼积木效率翻倍。2.3 为什么选这套组合而不选别的你可能要问为什么不是 SpringCloud 微服务不是 JSP Servlet不是前后端不分离核心原因毕设考核的是完整度与业务逻辑不是架构炫技。单体应用 前后端分离已经足够体现设计能力。微服务拆五个服务出来光环境搭建就能耗掉半条命JSP 那套早就跟不上主流开发模式答辩时会被问倒前后端不分离的项目演示起来也不够现代。SpringBoot Vue 是当下 Java 开发岗位的主流技术栈这套练熟了简历上的项目经验是能写出东西的。3. 数据库设计与 SQL 脚本构建3.1 核心数据表结构房产销售系统不需要几十张表十张以内就是合理范围。核心表如下用户表 user字段类型说明idbigint主键自增usernamevarchar(50)登录账号passwordvarchar(100)BCrypt 加密后的密码rolevarchar(20)admin / seller / customernicknamevarchar(50)昵称phonevarchar(20)联系电话avatarvarchar(255)头像地址create_timedatetime创建时间房源表 house核心字段包括 title、cover、photos、area、price、layout户型、address、developer、status0下架、1上架、publish_time。注意 photos 建议用 JSON 数组存多个图片地址或者用逗号分隔不需要单独建一个图片表。预约表 appointment字段类型说明idbigint主键house_idbigint关联房源user_idbigint预约人appointment_timedatetime预约看房时间remarkvarchar(255)备注statusint0待确认、1已确认、2已驳回订单表 orders订单表的命名要注意order 是 MySQL 的关键字建议用 orders 或者在 mybatis-plus 里指定 TableName(orders)。字段包括 order_no订单编号、house_id、user_id、seller_id、total_price、payment_type、sign_date、status。公告表 notice、客户跟进表 customer_follow根据需要精简即可。3.2 表关系与关键 SQL 脚本表之间的关系并不复杂用户对房源是多对多用户可浏览收藏多个房源房源可被多个用户查看/预约这里通过预约表和收藏表中转。订单是房源和用户的关联同时加上售楼员字段。SQL 脚本里需要注意几点建库指定 utf8mb4 字符集防止中文乱码CREATE DATABASE IF NOT EXISTS house_sale DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;初始化账号要预置三个角色的账号各一个并且密码用 BCrypt 加密后的字符串存储。很多同学直接存明文答辩时被问到安全设计就卡壳存加密串成本很低印象分差距很大。房源表预置 8-10 条真实感强的数据价格、区域、户型要有差异。演示分页和筛选的时候才有素材。多表查询是最容易出 bug 的地方比如统计销售员成交总额SELECT u.nickname, COUNT(o.id) AS sale_count, IFNULL(SUM(o.total_price),0) AS total_amount FROM orders o LEFT JOIN user u ON o.seller_id u.id WHERE o.status 2 GROUP BY u.id ORDER BY total_amount DESC;3.3 SQL 脚本的使用场合拿到项目里的 SQL 文件后不要直接无脑执行。按流程来先建库改掉默认密码和端口避免和本地环境冲突。按依赖顺序执行建表语句user → house → appointment → orders → notice → 其他扩展表。执行初始化数据脚本确认账号能登录、房源数据和预约数据都在。用 Navicat 或 DataGrip 跑几条测试 SQL确认联表查询无异常。这套项目好在 SQL 脚本是完整的省掉了手工建表的步骤但理解表之间的关系依然很重要——答辩时老师可能随手打开数据库让你解释这段关联关系你得说得出来。4. 接口文档与后端核心实现4.1 RESTful 接口规范接口文档的组织方式按模块分组每个接口标注方法、路径、请求参数、返回结构。规范统一用 RESTful资源用名词复数操作靠 HTTP 方法区分。典型的接口清单如下模块方法路径说明认证POST/api/user/login登录返回 token认证POST/api/user/register注册房源GET/api/house/page分页查询房源房源GET/api/house/{id}房源详情房源POST/api/house/save新增/编辑房源房源PUT/api/house/status/{id}上下架预约POST/api/appointment/add提交预约预约GET/api/appointment/list预约列表订单POST/api/orders/sign签约创建订单统计GET/api/statistics/overview数据看板返回结构统一封装{ code: 200, msg: 操作成功, data: {} }统一返回结构用泛型模式写前端拿到 code 不为 200 时统一弹错误提示拦截器里处理 401 跳转登录页。4.2 JWT 登录鉴权的完整流程鉴权设计是毕设答辩必考项之一。这里的流程可以这样实现用户提交账号密码到 /api/user/login。后端从数据库查用户用 BCrypt 校验密码密文。校验通过后生成 JWTpayload 里放 userId、role、username密钥写死或放在配置文件中过期时间设 24 小时。后续请求在 Header 带 Authorization: Bearer token。后端自定义拦截器HandlerInterceptor在 preHandle 中解析 token。token 无效或过期直接返回 401全程无状态。Interceptor 注册时注意放行登录、注册、房源列表查询等无需鉴权的路径其他路径全部拦。这一块的代码量不大但能讲出为什么用 JWT 而不是 Session——这是因为前后端分离后后端不维护会话状态token 是适合跨域传递凭证的方式。4.3 房源图片上传与静态资源映射图片上传是毕设里高频功能。通常做法是前端用 Element 的 Upload 组件把图片文件 POST 到 /api/upload。后端接收 MultipartFile保存到本地目录比如项目根下的 upload/ 文件夹文件名用 UUID 重命名防止冲突。返回可访问的 URL比如 /upload/xxx.jpg。配置静态资源映射把 /upload/** 映射到实际磁盘路径。Override public void addResourceHandlers(ResourceHandlerRegistry registry) { String path System.getProperty(user.dir) /upload/; registry.addResourceHandler(/upload/**) .addResourceLocations(file: path); }这个小功能融入房源管理模块后整个项目可用性的观感直接提升一个档次。4.4 接口文档的编写接口文档是这套交付物里的加分项。常见方案有两种一种是 Markdown 文档按模块手写另一种是集成 Knife4j启动项目后自动生成 Swagger 文档。建议时间充裕就把 Knife4j 加上Controller 上补几个 Schema 注解答辩直接打开浏览器展示在线接口列表专业感拉满。手写接口文档也不能丢至少要把请求参数、返回示例写清楚方便项目交接时别人接手。5. 实操部署与踩坑记录5.1 本地运行步骤理论讲再多不如自己跑一遍。这个项目本地运行的顺序是准备环境JDK 8 或 11、Maven 3.6、MySQL 5.7 或 8.0、Node 14。导入数据库用 Navicat 执行项目里的 SQL 脚本确认库名和账号密码。后端配置修改在 application.yml 里改数据库地址、账号、密码。端口默认 8080要不起冲突就改 8081。启动后端开发环境直接 run Application.java看到 Started Application in x.xx seconds 即启动成功。前端依赖安装npm install如果网络慢可以用国内镜像源加速。启动前端npm run serve。默认端口 8080 和 8081 只要不同就万事大吉。浏览器访问前端地址用预置的管理员账号登录管理后台。部署 demo 的时候我习惯把后端端口改成 8081前端 Vue 的 devServer 配代理转发到 8081避开端口冲突的同时也解决跨域问题。// vue.config.js module.exports { devServer: { port: 8080, proxy: { /api: { target: http://localhost:8081, changeOrigin: true } } } }5.2 我实际踩过的坑数据库连接乱码。项目里 SQL 脚本是 utf8mb4但如果 MySQL 连接串忘了加characterEncodingutf8查询出来就有中文乱码。解决办法是给连接 URL 加上jdbc:mysql://localhost:3306/house_sale?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiMyBatis-Plus 逻辑删除没配导致数据删除报错。如果表里加了 deleted 字段没在实体类上配 TableLogicMapper 的 delete 操作会变成真正的物理删除。初始化项目跑起来后发现数据没了大概率是这个原因。前端路由刷新 404。原因是前端路由是 history 模式生产环境部署到 Nginx 后需要配置 try_files否则刷新页面就白屏。本地开发没有这个问题部署到服务器上才会遇到。JWT 拦截器把登录接口拦截了。这个很微妙因为你明明把登录路径放行了但如果路径写的是 /api/user/login而拦截器注册时匹配的是 /api/**那就会误判。必须仔细检查排除路径建议用excludePathPatterns(/api/user/login, /api/user/register, /upload/**)。分页查询传 pageNum 和 pageSize 但返回 null。遇到这种问题先确认 MyBatis-Plus 分页拦截器有没有注册漏配了分页插件就只是全量查询前端拿到的是整张表还分不了页。5.3 常见问题速查表现象可能原因排查方向启动报 8080 端口占用Tomcat 端口冲突后端 application.yml 改端口 / 查 netstat前端请求接口 404代理未配置或接口路径错误看 Network 面板请求的实际 URL登录一直失败密码加密方式不匹配确认前端没有二次加密、确认数据库密码密文是否有误图片上传后访问 404静态资源映射没生效检查后端的 addResourceHandlers 和实际路径打包后运行提示缺少主类打包插件配置不对确认 maven 的 spring-boot-maven-plugin 已配置6. 答辩演示与二次扩展建议6.1 演示顺序设计答辩演示时间一般只有 5-10 分钟顺序很关键1 分钟讲项目背景和毕业设计的选题意义一句话一带而过即可。2 分钟按功能模块逐个演示登录三种角色 → 管理员看看板 → 添加房源 → 用户注册登录预约 → 销售后台处理预约 → 登记订单。2 分钟打开数据库展示表关系和 SQL 脚本挑一个多表查询现场跑一遍 SELECT边跑边解释语句含义。1 分钟展示接口文档或在线 Swagger强调 RESTful 规范。演示过程中千万不要花时间去敲代码老师想看的是项目是一个整体、能跑、你能讲清楚每一块。6.2 二次扩展建议如果想让这个项目在答辩中更有竞争力可以低成本做一些增量看房预约的短信通知——这里接入一个模拟的短信服务即可按日志输出通知内容。成交趋势图——统计模块里加一个按月成交额折线图前端 ECharts 代码量很小但视觉效果好。房源地图展示——用高德地图开放平台把房源坐标标记到地图上前后端加起来一天能搞定。导入导出功能——房源数据 Excel 导入导出用 EasyExcel 依赖也是面试官喜欢的点。WebSocket 消息通知——预约被确认时用户端实时收到提醒Swagger 里再加个 websocket endpoint这个扩展技术含量直接上一个段位。6.3 写在最后的实践心得带过不少项目每次给毕设项目做技术选型我始终坚持一条项目是给人用的不是给代码看的。数据库有没有初始化数据、演示的时候有没有预先准备好的账号、接口文档是否齐全这些看起来不起眼实际决定了这个项目是能答辩的作品还是跑不动的代码堆。做这套房产销售系统最难的不是某一个功能本身而是把登录、房源、预约、订单、统计这样一个完整链路串起来跑通。源码在手不等于万事大吉你自己过一遍核心流程把这些逻辑真正转化成你自己的表达——到时候不论老师问 JWT 为什么不用 Session还是问订单表为什么这样设计你都能从业务和工程两个层面给出答案。这才是这份源码给你带来的真正价值。