简介:这是一套面向计算机、通信、人工智能等相关专业本科生的高质量毕业设计实战资源,聚焦智慧社区场景,基于SpringBoot后端与Vue前端构建全栈应用,解决社区管理数字化、服务智能化等实际问题,适用于毕业设计、课程大作业及初学者进阶学习。压缩包共866个文件,含165个Java核心业务类、46个Vue组件、151个JS交互逻辑、81个JPG/GIF/PNG界面素材、42个CSS样式文件、23个XML配置及1个完整SQL数据库脚本,另附演示视频MP4、启动脚本(.bat/.cmd)、基础配置文件(yml/properties)等,整体43.16MB,结构清晰、模块分明。已有236人下载学习,项目经答辩评审获98分,全部代码已调试通过并附带多套备份文件(如.vue.bak、.html.bak),包含登录、物业报修、公告管理、访客预约等典型功能模块,配套演示视频直观呈现操作流程,便于快速理解系统架构与运行逻辑。 Java毕业设计选什么题,每年都有人纠结到焦头烂额。我当时权衡了一圈,最后把方向定在“基于Springboot+Vue的智慧社区设计与实现”上:后端是主流的Java SpringBoot框架,前端是Vue,数据库用MySQL,业务上覆盖业主、物业、缴费、报修、访客这些真实小区场景,做出来的演示效果也不差。这篇就把我从选题、建表、前后端联调到录演示视频的完整套路梳理一遍,给打算做类似题目的同学一份可以直接抄的作业,也帮还在观望的读者判断这个题目到底适不适合自己。
1. 为什么选Springboot+Vue做智慧社区毕设:选型逻辑与需求拆解
1.1 智慧社区题目在毕业设计里为什么“能打”
智慧社区本质上是一类“多角色、多业务、多状态流转”的管理系统。相比图书管理、学籍管理这类单实体CRUD题目,它天然带更复杂的业务结构:一个小区里有业主、住户、物业管理员、访客,业务上有物业费缴纳、报修工单、访客登记、车位分配、公告发布、投诉建议。这意味着你的系统至少要覆盖四类角色、六到八个功能模块,数据库表十五张以上。
对毕业设计而言,“工作量”是答辩老师最看重的指标之一。工作量不够的题目,做得再花哨也容易在答辩时被一眼看穿;而工作量过饱和的题目,比如带微服务、分布式锁、消息队列的“高并发社区平台”,对大多数本科生来说又容易虎头蛇尾。智慧社区正好卡在中间:业务复杂度足够展示你的设计能力,技术难度又完全可控,只要认真做,源码、数据库脚本、演示视频三件套都能扎扎实实拿出来。
1.2 技术栈选型的真实考量
选SpringBoot+Vue,不是因为它时髦,而是因为它最能同时满足“稳妥完成”和“能讲清楚”两个要求。
SpringBoot让Java后端开发不需要纠结SSH那套繁琐的XML配置,内嵌Tomcat,一个jar包就能跑起来,主流教程多,遇到报错基本都能搜到解决办法。Vue是当前前端框架里对新手最友好的一个,双向绑定写表单页面效率极高,配合Element UI的组件库,列表页、表单页几乎可以批量产出。
前后端分离的开发模式,前端用Vue、后端用SpringBoot,恰好是当前Java岗位最常见的技术组合。答辩时老师问“为什么用这个不用那个”,你可以从生态成熟度、岗位匹配度、学习资料丰富度三个角度展开,比单纯说“大家都用”有说服力得多。
如果你基础一般,我不建议硬上Spring Cloud Alibaba、分布式事务、Elasticsearch这些大而全的东西。毕业设计的第一要务,是用稳妥的技术把功能做完整,把细节做扎实。技术亮点可以有,但一定是建立在你完全能讲清楚的基础上。
1.3 功能模块怎么划分才不过度设计
常见的智慧社区功能清单很长:业主管理、房产信息、车辆管理、车位分配、物业缴费、报修工单、访客登记、公告通知、投诉建议、设备巡检、数据统计大屏。如果全做,很容易每个模块都做半吊子,答辩时反而露馅。
我的建议是:核心模块做到位,锦上添花的模块宁可不做。基础版做七个模块就够:业主管理、车位管理、物业缴费、报修工单、访客登记、公告通知、数据统计。进阶版可以加投诉建议和设备巡检,再多就不建议了。
| 模块 | 基础版 | 进阶版 | 说明 |
|---|---|---|---|
| 业主管理 | 做 | 做 | 增删改查、状态禁用、角色区分 |
| 车位管理 | 做 | 做 | 车位分配、业主绑定 |
| 物业缴费 | 做 | 做 | 缴费单生成、模拟缴费 |
| 报修工单 | 做 | 做 | 业主提交、物业接单处理 |
| 访客登记 | 做 | 做 | 预约码、门卫确认 |
| 公告通知 | 做 | 做 | 管理员发布、业主查看 |
| 数据统计 | 做 | 做 | ECharts图表 |
| 投诉建议 | 可选 | 做 | 业主提交、物业回复 |
| 设备巡检 | 可选 | 做 | 巡检记录表格 |
这么划分的原因是:核心模块覆盖了“增删改查+状态流转+多角色权限+数据统计”这四类毕设必备要素,而可选模块只是重复同样的开发模式。把核心模块打磨好,比摊大饼铺一堆半成品强得多。
2. 数据库设计:从小区真实业务到可落地的表结构
2.1 先梳理业务,再画ER图,不要上来就建表
我见过太多同学上来就打开Navicat建表,建到一半发现表对不上,删了重建,反复折腾。正确顺序是先把业务关系理清楚。
智慧社区核心实体关系大概是这样的:
- 业主(用户)和房产是一对多关系,一户可以有多个成员,但一个业主可以有多个房产(投资房、自住房)。
- 车位的归属分两类:购买或租赁。一个业主可以买多个车位,也可以租临时车位。
- 缴费单和房产绑定,物业费按月生成,停车费按年或按月生成。
- 报修工单由业主发起,物业维修人员接单处理,中间有状态流转。
- 访客登记由业主发起,生成预约码,门卫在访客到达时确认放行。
把这些关系画出来,表结构就有了骨架。画图工具用draw.io或者ProcessOn都行,导出的ER图图片还能直接放进论文里,一举两得。
2.2 核心表结构示例:业主表、房产表、缴费表、报修表
我挑了四张最有代表性的表做示例,分别是用户表、房产表、缴费单表、报修工单表。这些表是智慧社区系统的骨架,你可以在基础上扩展字段。
用户表:
CREATE TABLE `sys_user` ( `id` bigint NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL COMMENT '登录账号', `password` varchar(100) NOT NULL COMMENT '密码(BCrypt加密)', `real_name` varchar(50) DEFAULT NULL COMMENT '真实姓名', `phone` varchar(20) DEFAULT NULL COMMENT '手机号', `role` tinyint NOT NULL DEFAULT '2' COMMENT '角色:1管理员 2业主 3维修工', `status` tinyint NOT NULL DEFAULT '1' COMMENT '状态:1正常 0禁用', `deleted` tinyint NOT NULL DEFAULT '0' COMMENT '逻辑删除:0未删 1已删', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';房产表:
CREATE TABLE `house` ( `id` bigint NOT NULL AUTO_INCREMENT, `user_id` bigint DEFAULT NULL COMMENT '业主用户ID', `building_no` varchar(20) DEFAULT NULL COMMENT '楼栋号', `unit_no` varchar(20) DEFAULT NULL COMMENT '单元号', `room_no` varchar(20) DEFAULT NULL COMMENT '房号', `area` decimal(10,2) DEFAULT NULL COMMENT '建筑面积(平米)', `status` tinyint NOT NULL DEFAULT '0' COMMENT '状态:0未入住 1已入住', `deleted` tinyint NOT NULL DEFAULT '0', `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='房产表';缴费单表:
CREATE TABLE `payment_bill` ( `id` bigint NOT NULL AUTO_INCREMENT, `house_id` bigint NOT NULL COMMENT '房产ID', `user_id` bigint NOT NULL COMMENT '缴费业主ID', `bill_type` tinyint NOT NULL COMMENT '账单类型:1物业费 2停车费 3其他', `amount` decimal(10,2) NOT NULL COMMENT '金额(元)', `bill_month` varchar(7) DEFAULT NULL COMMENT '账期,格式如2025-06', `status` tinyint NOT NULL DEFAULT '0' COMMENT '状态:0待支付 1已支付', `pay_time` datetime DEFAULT NULL COMMENT '支付时间', `deleted` tinyint NOT NULL DEFAULT '0', `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='缴费单表';报修工单表:
CREATE TABLE `repair_order` ( `id` bigint NOT NULL AUTO_INCREMENT, `user_id` bigint NOT NULL COMMENT '报修业主ID', `house_id` bigint DEFAULT NULL COMMENT '房产ID', `content` varchar(500) NOT NULL COMMENT '报修内容', `images` varchar(1000) DEFAULT NULL COMMENT '图片路径,多个用逗号分隔', `status` tinyint NOT NULL DEFAULT '0' COMMENT '状态:0待接单 1处理中 2已完成 3已评价', `handler_id` bigint DEFAULT NULL COMMENT '处理人ID', `handle_remark` varchar(500) DEFAULT NULL COMMENT '处理备注', `handle_time` datetime DEFAULT NULL COMMENT '处理完成时间', `deleted` tinyint NOT NULL DEFAULT '0', `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='报修工单表';2.3 字段设计的几条关键经验
金额字段用decimal(10,2),绝对不要用float或double。浮点数在Java和MySQL里都有精度问题,算电费、物业费这种涉及金额的场景,一分钱都不能差,decimal才能保证精确。
状态字段用tinyint加注释。比如缴费单状态0待支付 1已支付,报修状态0待接单 1处理中 2已完成。用整数而不是字符串的好处是:省空间、查询效率高、扩展方便。将来要加一个“已取消”状态,加一个数字就行,不用改表结构。
逻辑删除字段deleted必须加。虽然毕设项目一般不会真的删数据,但逻辑删除是工程实践里的规范做法。配上MyBatis-Plus的@TableLogic注解,查询时自动带上deleted=0条件,删除操作自动变成update,代码里完全无感。
统一加create_time和update_time。这俩字段不光是为了规范,做列表排序、按时间筛选、统计数据时都会用到。默认值用DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP,插入和更新时都不用手动管。
2.4 为什么适当冗余字段,而不是一味追求三范式
学校教的数据库设计强调三范式,但实际做工程,完全遵循三范式会很痛苦。比如缴费单表里冗余一个业主姓名,查缴费列表时就没必要join用户表;报修表里冗余房产地址,详情页就能一次查出来。
我设计时会在高频查询的表里冗余少量字段,代价是数据一致性需要靠代码保证。论文里可以写“在保证数据一致性的前提下,对部分高频查询字段做了适度反规范化设计”,答辩老师反而觉得你懂工程化。当然,冗余不是乱加,只在确实高频查询的场景下加,否则更新时反而麻烦。
3. 后端开发:SpringBoot接口链路里的那些关键细节
3.1 项目骨架与依赖版本选择
版本选择直接影响整个开发过程的顺利程度。SpringBoot用2.7.x版本,对应JDK8,这是目前教程最多、踩坑最少、各类兼容问题最少的一组搭配。不要一上来用SpringBoot 3.x,因为它强制要求JDK17,很多人的本机环境和教程示例还是JDK8,换版本会消耗大量时间,而这对毕设没有任何加分。
MyBatis-Plus要用3.5.x。这个版本的@TableLogic、分页插件、代码生成器都是稳定的。MySQL驱动用8.x,和MySQL 8.0数据库匹配。另外单独引入spring-security-crypto,只用它的BCrypt密码加密工具,不需要整套Spring Security框架。
核心依赖大概是这样:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-crypto</artifactId> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.18</version> </dependency> </dependencies>Hutool是我比较推荐的一个Java工具库,里面封装了JWT生成解析、加密解密、日期处理、文件上传等一堆常用功能,能省掉大量手写代码。
3.2 登录鉴权:JWT+拦截器的落地方式,而不是Spring Security
智慧社区有管理员、业主、维修工多角色,权限必须区分。但我不建议用Spring Security,原因是:它的过滤器链、认证管理器、安全配置类对新手来说太抽象,答辩时被追问底层原理,很容易卡壳。
更稳妥的方案是JWT+HandlerInterceptor:
- 登录成功后,后端用JWT生成token,把userId和role放进去,设置7天有效期。
- 前端把token存到localStorage,axios请求拦截器统一在请求头带上
Authorization: Bearer token。 - 后端写一个
AuthInterceptor实现HandlerInterceptor,在preHandle里校验token,解析出用户信息,放到ThreadLocal或request attribute里。 - 需要管理员权限的接口,用自定义注解
@RequireRole("admin"),在拦截器里读请求路径对应的角色要求,配置一个路径和角色的映射表就行。
JWT工具类用Hutool封装后非常简短:
public class JwtUtil { private static final String SECRET = "your-secret-key"; public static String createToken(Long userId, Integer role) { return JWT.create() .setPayload("userId", userId) .setPayload("role", role) .setExpiresAt(new Date(System.currentTimeMillis() + 7 * 24 * 60 * 60 * 1000)) .setKey(SECRET.getBytes()); } public static JWTValidator validate(String token) { return JWT.of(token).setKey(SECRET.getBytes()); } }拦截器的好处是逻辑清晰、代码量少、每一行你都能用自己的话讲明白。答辩的时候老师问“你token是怎么校验的”,你可以直接说“前端请求带token,拦截器先验签名,再验有效期,解析出userId放ThreadLocal,后面controller直接用”,这就够了。
3.3 报修、缴费、访客三条核心接口的示例与说明
报修工单是智慧社区里状态流转最完整的模块,能体现你处理“状态机”的能力。核心接口是三个:
业主提交报修,POST/api/repair,参数包含房产ID、报修内容、图片路径。这个接口要注意校验:业主只能提交自己房产下的报修,图片路径是上传接口返回的。
物业人员查看待接单列表,GET/api/repair/list?status=0。注意分页参数,MyBatis-Plus分页插件配置好后,传入pageNum和pageSize即可。
物业接单/完成,PUT/api/repair/{id}/handle。接单时更新handlerId和状态为处理中,完成时更新状态为已完成并写入handleTime。
图片上传这里有个小坑。如果没买云存储,直接用本地存储就行。在application.yml里配置上传路径,然后写一个静态资源映射:
@Configuration public class WebConfig implements WebMvcConfigurer { @Value("${upload.path}") private String uploadPath; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/upload/**") .addResourceLocations("file:" + uploadPath + "/"); } }这样前端用http://localhost:8080/upload/xxx.jpg就能直接访问图片,不用额外配置Nginx。
缴费模块要注意“幂等性”问题。业主点击缴费后,后端要先检查账单状态是不是待支付,如果已经是已支付,直接返回“该账单已支付”,避免重复扣费。用MyBatis-Plus的updateById加条件更新,或者先查后更,防止并发状态下重复支付。
访客登记模块的核心是状态流转:业主填访客信息生成预约码,访客到门口报预约码,门卫或业主确认后放行。预约码直接用UUID前六位,或者时间戳转36进制,不要自己写随机算法。访客表加一个visit_time记录实际到达时间,一个leave_time记录离开时间,就是完整的访客轨迹。
3.4 统一返回体与异常处理,体现代码规范
这个细节我强烈建议做。定义一个Result<T>类:
@Data public class Result<T> { private Integer code; private String message; private T data; public static <T> Result<T> ok(T data) { Result<T> r = new Result<>(); r.setCode(200); r.setMessage("success"); r.setData(data); return r; } public static <T> Result<T> error(String message) { Result<T> r = new Result<>(); r.setCode(500); r.setMessage(message); return r; } }再加一个全局异常处理器,用@RestControllerAdvice+@ExceptionHandler统一捕获业务异常、参数校验异常和兜底异常。这样所有controller的方法都返回Result,所有异常都走统一出口,前端只需要处理一种返回结构。
这个设计投入的代码量很少,但在论文的“系统实现”章节和答辩展示里都是实打实的亮点。老师如果问“你在项目里做过什么规范设计”,统一返回结构、全局异常处理、逻辑删除、参数校验,每一条都可以展开讲。
4. 前端开发:Vue页面从登录到数据大屏的搭建过程
4.1 Vue项目结构与初始化,Node版本别踩坑
前端建议直接用Vue CLI创建Vue 2项目,配合Element UI。为什么不用Vue 3?因为Element UI对Vue 2的兼容资料最全,遇到任何问题都能搜到解法;而Vue 3的Element Plus虽然也在成熟,但对新手来说查资料的成本略高。毕设求稳,选资料最多的组合。
Node版本要注意,建议用16.x。太高的Node 18/20版本在安装node-sass时容易报编译错误,搞心态。安装命令:
npm install -g @vue/cli vue create community-web cd community-web npm install element-ui axios vue-router@3 echartsVue Router注意用3.x版本,因为Vue 2只兼容Vue Router 3,装成4.x会直接报错。
目录结构建议这样分:
src/ ├── api/ # 接口请求函数,按模块拆分 ├── router/ # 路由配置 ├── store/ # 用户状态管理 ├── views/ # 页面组件 ├── components/ # 公共组件 ├── utils/ # axios封装、工具函数 └── App.vue4.2 路由守卫与菜单权限:前后端配合做权限控制
多角色系统的前端要配合路由守卫。登录后把token存localStorage,路由跳转前检查:
router.beforeEach((to, from, next) => { const token = localStorage.getItem('token'); if (to.path !== '/login' && !token) { next('/login'); } else { next(); } });菜单权限这块有个加分技巧:后端登录接口返回用户角色和权限列表,前端根据role动态渲染侧边栏菜单。不要把所有菜单放进静态配置里,然后靠v-if隐藏,那样不够“动态”。你可以写一个generateMenuByRole(role)函数,管理员渲染全部菜单,业主只渲染业主相关菜单,维修工只渲染工单处理菜单。
权限控制要前后端同时做。前端隐藏菜单只是体验问题,真正的安全控制必须放在后端接口上。答辩时可以说“前端动态菜单提升体验,后端拦截器保证接口安全”,这是完整的权限控制闭环。
4.3 表格页和表单页的组件化复用:提高开发效率的关键
智慧社区80%的页面是“搜索栏+表格+分页”的组合,以及“弹窗表单”。如果每个页面都从头写,代码量翻倍且大量重复。
我的做法是封装两个公共组件:
SearchTable组件:接收表格列配置、搜索条件、接口请求函数,内部处理分页、loading、刷新。页面只需要传配置和数据请求URL,表格就出来了。
DialogForm组件:接收表单字段配置、提交接口函数。内部处理弹窗开关、表单校验、提交状态。
表格列配置可以抽成一个单独的字段配置数组:
columns: [ { prop: 'realName', label: '业主姓名', width: 120 }, { prop: 'phone', label: '手机号', width: 140 }, { prop: 'buildingNo', label: '楼栋号', width: 100 }, { prop: 'roomNo', label: '房号', width: 100 }, { prop: 'status', label: '入住状态', type: 'tag', map: { 0: { text: '未入住', type: 'info' }, 1: { text: '已入住', type: 'success' } } } ]封装公共组件的好处,不只是减少代码量,更是答辩时能主动展示的亮点:“我做了组件抽象和复用”。老师最怕听到的是“每个页面都是复制粘贴改一改”,组件化设计直接证明你有工程化意识。
4.4 数据看板:用ECharts把“智慧感”拉满
智慧社区最出彩的页面通常是数据看板。我建议做一个全屏看板页,包含几个关键图表:小区入住率饼图、近7日报修数量折线图、缴费率柱状图、停车位占用率仪表盘。这些用ECharts实现都很简单,关键是要从后端接口拿真实数据,不要写死在前端。
后端提供一个统计接口,返回首页需要的汇总数据:
@GetMapping("/api/stats/overview") public Result<OverviewVO> overview() { OverviewVO vo = new OverviewVO(); vo.setTotalHouse(houseMapper.selectCount(null)); vo.setOccupiedHouse(houseMapper.selectCount(new LambdaQueryWrapper<House>() .eq(House::getStatus, 1))); vo.setMonthPayment(paymentBillMapper.sumAmountByMonth("2025-06")); vo.setPendingRepair(repairOrderMapper.selectCount(new LambdaQueryWrapper<RepairOrder>() .eq(RepairOrder::getStatus, 0))); return Result.ok(vo); }前端用ECharts渲染。答辩演示时,这个页面是全场的视觉高潮。注意图表不要纯静态,要配合真实数据的说明:“现在仪表盘显示入住率88%,是数据库里49户房产中43户已入住,这个数字是统计接口实时查出来的。”
5. 源码组织、数据库脚本与演示视频:让答辩评委一眼看懂你的工作量
5.1 源码目录怎么整理,README怎么写才算规范
毕设源码评审时,老师会从头到尾扫一遍项目目录,目录整洁程度直接影响印象分。建议按照后端、前端、数据库脚本、文档四个维度组织:
community-system/ ├── backend/ # SpringBoot后端 │ ├── src/main/java/... │ └── src/main/resources/ │ └── application.yml ├── frontend/ # Vue前端 │ ├── src/ │ └── package.json ├── sql/ │ └── community.sql # 建库建表+演示数据脚本 └── README.md # 项目说明文档后端包结构按controller/service/mapper/entity分层,这是最基础也最稳妥的方式。不要图省事把所有代码堆在一个包里,代码分层直接影响“可读性”评分。
README.md要写清楚四件事:项目介绍、环境要求(JDK8、MySQL8、Node16)、启动步骤、默认账号密码。这个文档写好了,是答辩前评审老师最先看的材料。参考格式:
# 智慧社区管理平台 ## 技术栈 - 后端:SpringBoot 2.7.18 + MyBatis-Plus 3.5.3 + JWT - 前端:Vue 2 + Element UI + ECharts - 数据库:MySQL 8.0 ## 环境要求 - JDK 1.8+ - Maven 3.6+ - MySQL 8.0 - Node 16.x ## 启动步骤 1. 导入 sql/community.sql 到 MySQL 2. 修改 application.yml 中数据库账号密码 3. 启动后端:mvn spring-boot:run 4. 启动前端:npm install && npm run serve 5. 访问 http://localhost:8081 ## 默认账号 - 管理员:admin / 123456 - 业主:zhangsan / 123456 - 维修工:repair1 / 1234565.2 数据库SQL脚本必须包含哪些内容
很多同学只导出一张空表,老师拿到脚本导入一看,所有表都是空的,演示起来毫无体验。正确的做法是:SQL脚本不仅要包含建库建表语句,还要包含初始化管理员账号和演示数据,每张业务表至少10条数据。
演示数据要“场景化”。比如业主表里要有李明、张三、王芳这些人,房产表里要有对应的楼栋单元房号,缴费单里要有几个月前的已支付记录和本月的待支付记录,报修表里要有待接单和处理中的工单。这样演示时点开任何页面都有数据,操作起来才有说服力。
密码字段直接用BCrypt加密后的字符串,不要明文。管理员密码初始化为BCrypt.hashpw("123456", BCrypt.gensalt()),用代码生成好放进去。
5.3 演示视频脚本:录什么、怎么录、怎么讲解
演示视频一般3到8分钟,超过10分钟答辩老师大概率快进。建议按下面的顺序录:
- 启动后端、前端,展示项目能正常运行(20秒)。
- 管理员登录,展示业主管理、房产管理、车位管理、缴费管理(2到3分钟)。
- 业主登录,展示报修提交、缴费操作、访客预约(1到2分钟)。
- 维修工登录,展示接单处理流程(1分钟)。
- 数据看板展示,说明统计数据的含义(30秒)。
- 收尾,简单总结系统功能。
录屏工具用OBS或者系统自带的录屏都行。关键在讲解方式:不要念操作步骤,要讲业务逻辑。比如“业主李师傅在App上提交了卫生间漏水报修,工单状态是待接单;切到管理员账号,可以看到这条工单,物业维修工接单后状态变成处理中,处理完成点完成,状态变成已完成,业主可以在前端查看处理结果。”这样讲解,体现的是你对系统业务流程的理解,而不是操作熟练度。
视频里如果接口报错或者页面崩溃,宁可重录这一段也不要硬剪进去。一遍没过就录两遍,示范视频的流畅度直接影响“系统完成度”的评价。
6. 踩过的坑与答辩追问应对
6.1 常见的报错和解决办法
我把我自己开发过程中遇到过的、以及帮别人排查过的典型问题整理了一下,集中在下面这些,你大概率也会踩到。
MySQL 8的驱动类名和时区问题。驱动类名要用com.mysql.cj.jdbc.Driver,不是旧的com.mysql.jdbc.Driver;jdbc url要带时区参数serverTimezone=Asia/Shanghai,否则会报时区错误。
前端端口占用。后端默认8080端口,前端Vue默认8080端口,两个服务会直接冲突。在vue.config.js里把前端端口改成8081:
module.exports = { devServer: { port: 8081, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } } }注意这里同时配了代理,开发时前端请求/api前缀的接口会自动转发到后端8080端口,这样避免了跨域问题。如果不用代理,后端就得配CORS,也麻烦。
LocalDateTime序列化问题。SpringBoot默认用Jackson序列化LocalDateTime,返回给前端的格式可能是一个数组,需要配置全局日期格式:
spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: Asia/Shanghai6.2 性能与安全方面容易被问到的点
答辩老师一定会问的问题之一:“密码是明文存储吗?”如果你用了BCrypt加密,就能很自然地回答。这里有个细节:单独引入spring-security-crypto包就能用BCrypt,不需要引入整套Spring Security。
还有几个高频追问:
- 分页是怎么实现的?回答MyBatis-Plus分页插件,底层是拦截器自动拼接
LIMIT语句。这里强调分页是SQL层面的,不是查出全部数据再内存分页。 - 数据库连接池用的什么?回答HikariCP,SpringBoot默认自带。可以补一句“它是目前性能最好的Java连接池,通过字节码优化减少了方法调用开销”。
- 文件上传怎么处理重名?回答文件名加UUID前缀,避免覆盖。
- 缴费接口如何防止重复提交?回答先检查状态再更新,利用数据库行锁或条件更新保证幂等。
6.3 答辩现场怎么回答“这个系统还有什么不足”
正确的姿势不是“没有不足”,而是主动承认有不足,并说出改进方向。这是一个很加分的策略。
- 目前是单机部署,没有做Redis缓存。如果用户量大,业主信息、公告列表这种热点数据可以缓存到Redis,减轻数据库压力。
- 支付是模拟的。真实环境要对接微信/支付宝支付,涉及签名、回调、幂等处理,是一个完整的金融级链路。
- 没有做WebSocket实时推送。报修状态变化目前是页面刷新或重新拉取数据,优化方向是WebSocket推送通知。
这么回答,一是显示你清楚系统边界,二是显示你能看到未来演进方向。比“我这个系统已经完美了”这种回答强太多。
我做完这个项目之后最大的体会是:毕业设计的核心不是“做出多牛的系统”,而是“能不能把整个业务流程和技术方案讲圆”。Springboot+Vue这个组合,配合智慧社区这类业务,恰好让你在有限时间内在“业务完整度”“技术覆盖面”“演示效果”三者之间找到一个比较理想的平衡点。如果你正在纠结选题,这个题目可以放心入;如果已经定了同类方向,照着上面这套思路做,至少在答辩前不会慌。
本文还有配套的精品资源,点击获取