资讯动态

SpringBoot+Vue校园洗衣机预约系统毕设全攻略

发布时间:2026/10/9 3:30:50 来源:尧图企业网站定制
开头十好几年前我念大学的时候洗一次衣服全凭运气。运气好到楼下刚好有空机运气不好得掐着表在楼道里蹲点看到有人拎着桶出来就赶紧冲进去。后来工作了回头帮学弟看毕业设计选题发现校园洗衣机预约这个题目年年都有人选但年年都有人做得一塌糊涂——有的只写了个增删改查有的把预约做成了排队却根本没处理并发还有的前后端直接各写各的联调的时候心态爆炸。这篇博文想跟你聊透一件事以基于SpringBootVue的校园洗衣机预约管理系统为题目从零到一做完、写好、答好辩最关键的是哪些环节。我会把需求拆解、技术选型、数据库设计、预约核心链路、前端工作量控制、论文答辩准备全部过一遍全程聚焦在这个东西究竟该怎么落地上而不是堆概念。不管你是刚拿到题目的应届生还是已经写了一半卡在并发和状态机上的老哥这篇文章应该都能让你少走不少弯路。一个预约系统看着简单不就是选时间、下单、扣费、使用吗真做起来你会发现最麻烦的根本不在业务逻辑本身而在于状态怎么流转、冲突怎么避免、超时怎么处理、异常怎么兜底。这些恰恰也是答辩时老师最爱追问的点。所以别急着撸代码先把下面的内容看完。1. 这个毕设题目到底在做什么——把预约和排队分清楚1.1 核心业务场景还原先想象一个真实的校园宿舍楼洗衣房假设一栋楼有6台洗衣机早中晚三个高峰期永远不够用。学生不想干等管理员想知道每台机器的使用情况运营方希望有人违约时能及时把资源释放出来。这个系统要解决的就是把人肉排队改成线上预约。学生可以在手机或电脑上看到每台洗衣机的空闲时段选择一个时间段下单到时候直接去扫码使用。核心角色只有两个学生端和管理端。学生端管预约、查看、取消、支付模拟管理端管设备、时段、订单、统计。这里必须先说清楚一件关键的事预约不是实时抢占而是分片调度。如果你做的是当前有机器空闲用户点了就能用那本质上只是把一个排队功能搬到了线上根本没有调度逻辑。真正有点含金量的做法是把一天切成若干个时间片比如30分钟一个用户在某个时间片上预订某台机器系统要保证同一个时间片上同一台机器只能被一个订单占用。这样才叫预约系统答辩时也站得住脚。1.2 功能列表里的隐藏要求毕设一般会要求写需求分析很多同学直接抄模板列一堆系统管理、用户管理、订单管理。这样写不是不行但很空。把需求落到具体动作上应该是这个颗粒度学生注册登录、浏览洗衣机列表包含当前状态和后续时段占用情况、按时间片预约、在线模拟支付、查看我的预约、取消未开始的预约、违约记录查看。管理员洗衣机信息维护新增、上下架、报修标记、时段配置每台机器每天拆成多少个时间片、订单管理查看、手动取消异常订单、基础数据统计日订单量、设备使用率。注意这里我有意没有加支付功能接入真实微信/支付宝这种模块。毕设项目做到模拟支付足够真实支付涉及商户号、回调、对账工作量会翻好几倍而且对毕业答辩没有任何加分。1.3 题目里的三个关键词怎么拆分把题目拆开看基于Java指的是后端语言SpringBoot是后端框架校园洗衣机预约是业务领域管理系统说明需要完整的管理后台界面。如果加了Vue就意味着你需要一个独立的前端工程而不是把页面塞在服务端模板里。很多同学纠结题目里写的是预约管理系统还是调度系统其实不用纠结。你在论文题目里写设计与实现系统名称写校园洗衣机预约管理系统然后在系统设计里明确提出基于时间片调度的预约方案这个逻辑就是完整的。毕业设计题目本身通常不是定死的答辩时老师看的是你做了什么而不是题目抠了几个字。2. 技术选型的真实逻辑——SpringBootVue之外你需要知道这些隐性成本2.1 为什么这个组合是毕业设计的地板答案SpringBoot Vue MyBatis Plus MySQL这个组合已经被验证过无数次是毕业设计领域最稳的组合没有之一。SpringBoot的好处是起步快、配置少。你不需要像Servlet时代那样写一堆web.xml配置也不用像SSM整合时候那样小心翼翼地处理各种bean之间的依赖关系。一个spring-boot-starter-web丢进来写个Controller就能跑。更重要的是SpringBoot的生态太成熟了遇到任何报错搜索引擎上几乎都能找到现成的解决办法。Vue这边选Vue 3还是Vue 2我的建议是直接Vue 3 Element Plus。Vue 2已经停止维护了新写的毕设项目没必要再用老技术。Element Plus组件库自带表格、表单、弹窗、时间选择器管理后台那些页面基本都是这些组件拼出来的开发效率非常高。下面这个表是我给不同模块的选型建议你可以直接参考模块推荐方案推荐理由后端框架Spring Boot 2.7.x或3.x稳定、教程多、资料好查持久层MyBatis Plus单表CRUD不用写SQL分页插件开箱即用数据库MySQL 5.7或8.0免费、经典、学校机房基本都有前端框架Vue 3 Vite构建速度快工程结构清晰UI组件库Element Plus和Vue 3配套后台管理界面全搞定权限认证JWT或Sa-Token无状态、容易理解和演示接口文档SpringDocOpenAPI 3写论文时可以截图当接口设计成果2.2 如果让你做调度系统要不要引入Redis和消息队列题目里有调度系统四个字很多同学就开始慌了想着是不是得用Redis存排队队列、用RabbitMQ做异步通知。我跟你说毕业设计不要为了技术而技术。预约调度这个场景本质是对时间片资源的并发竞争控制。MySQL的事务 唯一索引就足够解决了后面我会详细讲怎么实现。Redis可以锦上添花用来缓存洗衣机列表、做分布式锁但如果你的系统只是单机部署Redis加不加都无所谓加了反而要多维护一个中间件答辩的时候还得解释为什么用。消息队列就更没必要了。预约成功后的通知用短信或者邮件发送毕业设计直接不做通知或者做一个模拟通知接口打个日志就行了。把精力放在稳定性和核心逻辑上比堆砌中间件有意义得多。2.3 版本踩坑SpringBoot版本不是越高越好热词里有一句springboot版本太高这绝对是我见过最多的前置翻车点。我见过大量同学直接去官网下个最新版SpringBoot或者SpringBoot 3.2、3.3结果MyBatis Plus的starter还没适配或者Java版本不匹配项目一启动就报错浪费好几天。选版本的核心原则是稳定的组合优先于最新的版本。如果你用Java 8就老老实实选Spring Boot 2.7.x如果你用Java 17再考虑Spring Boot 3.x。JDK版本和SpringBoot版本是强关联的千万别混用。选好之后在pom.xml里固定版本号不要用SNAPSHOT版本也不要用Spring Initializr默认的最新版本就无脑开跑。还有一个实测有用的技巧把项目发到Gitee或GitHub上做版本管理每完成一个模块就提交一次出现改崩的情况可以直接回滚。答辩时老师如果看到你有规范的Git提交记录印象分会高不少。3. 数据库设计——一张预约表决定了这个项目的好坏3.1 核心表结构能少就少但每张都要立得住我见过很多同学一上来就设计十几张表什么菜单表、角色表、权限表、日志表把系统管理那套全搬过来。其实一个毕设项目核心表控制在6~7张完全够用。表越多写代码越累联调越痛苦论文里还得画一堆没实际内容的ER图。我建议的核心表如下user用户表。包含用户名、密码加密存储、角色学生/管理员、学号、手机号。washer洗衣机表。包含设备编号、所在楼栋、状态空闲/使用中/维护中。washing_time_slot时间段表。包含开始时间、结束时间、所属设备ID、是否已被预约。reservation预约订单表。这张表是整个系统的核心下面单独讲。violation_record违约记录表。记录用户未按时使用的行为用于管理端统计。用户表的角色别做成RBAC那一套毕设项目就两种角色用一个字段区分就够了。真做了用户-角色-权限三张表老师问了可能反而答不清楚。3.2 预约订单表状态字段是灵魂预约订单表决定了整个核心链路的质量字段设计建议如下id主键、user_id用户ID、washer_id洗衣机ID、time_slot_id时间段ID、status订单状态、create_time创建时间、pay_time支付时间、cancel_time取消时间、complete_time实际使用完成时间。这里最关键的字段是status。我建议用字符串存枚举值而不是存数字答辩的时候更方便解释。状态集合如下CREATED已创建待支付PAID已支付待使用IN_USE使用中COMPLETED已完成CANCELLED已取消EXPIRED已过期超过使用时间没来用为什么要有这么多状态因为预约系统的核心就是一个状态机每一种业务动作都对应一次状态迁移。写论文的时候状态图直接就是从这张表里提炼出来的不用额外编。3.3 唯一索引并发控制的第一道防线预约冲突是这个问题最核心的难点。两个同学同时点了同一个时间段同一台洗衣机数据库层面怎么阻止这里有个被反复验证的方案在reservation表上给(washer_id, time_slot_id, status)加一个唯一索引且status只允许CREATED和PAID状态参与唯一约束。由于MySQL的普通唯一索引不去重NULL值你可以在部分场景用done_flag这类字段做软删除配合。更简单稳妥的做法是用状态分离字段比如保留一个reservation_uniq_key只有在待支付和已支付状态下才写入具体值已完成或取消后置为NULL这样唯一索引就能天然地防止两个有效订单同时存在。很多同学会问为什么不在代码里先查询再插入因为先查再插是典型的并发漏洞两个请求同时进来都查到没有记录然后都插入成功冲突就发生了。唯一索引是数据库层面的硬约束是并发安全的第一道防线。time_slot表本身也可以加一个(washer_id, slot_date, slot_start)的唯一索引防止管理员重复创建时间段。3.4 用MyBatis Plus生成SQL语句的小技巧热词里有mybatisplus根据java实体类生成创建表的sql语句这个功能确实好用。你写好实体类之后在application.yml里配置mybatis-plus: global-config: db-config: id-type: auto然后启动项目把ddl-auto调成update这个配置在Spring JPA里很常见MyBatis Plus中更多是用SQL脚本管理。更实用的做法是在实体类上写好注解然后借助MyBatis Plus的代码生成器或者IDE的数据库工具直接对比生成表结构。不过我的习惯是手写SQL建表因为造数据、加索引、调整字段类型都更直观。实体类和表的关系用MyBatis Plus的TableName、TableId、TableField注解一一对应清楚即可这也是热词里有mybatisplus根据java实体类生成创建表的sql语句这个搜索需求的原因——大家都不想手写建表SQL但我建议至少看懂生成的SQL省得索引和字段类型搞错。4. 预约核心链路——状态机、并发控制、超时释放全拆解4.1 一次完整预约的流程把完整流程走一遍你会发现问题全在边界学生查看某台洗衣机的时间片列表选出空闲时间段。点击预约系统创建一条CREATED状态的订单。模拟支付成功后订单变成PAID。到了预约时间管理员扫码或在后台点击开始使用订单变成IN_USE。使用结束订单变成COMPLETED。如果学生预约了但超过开始时间还没使用系统定时任务把订单变成EXPIRED。注意第3步有个细节为什么不直接一步到位下单成功因为预约和支付是两个概念。预约只是占坑支付才是确认。如果预约后10分钟内不支付订单应该自动释放。这个逻辑让系统显得真实也是答辩时的加分点。4.2 状态机代码怎么组织状态机不要用if-else堆用一张状态流转表在代码里集中管理会更清晰。简单地用一个Map或者枚举类来实现public enum ReservationStatus { CREATED, PAID, IN_USE, COMPLETED, CANCELLED, EXPIRED; private static final MapReservationStatus, SetReservationStatus ALLOWED_TRANSITIONS Map.of( CREATED, Set.of(PAID, CANCELLED, EXPIRED), PAID, Set.of(IN_USE, CANCELLED, EXPIRED), IN_USE, Set.of(COMPLETED), COMPLETED, Set.of(), CANCELLED, Set.of(), EXPIRED, Set.of() ); public boolean canTransitionTo(ReservationStatus target) { return ALLOWED_TRANSITIONS.getOrDefault(this, Set.of()).contains(target); } }然后写一个通用的状态更新Service每次更新前先校验合法性Transactional public void changeStatus(Long reservationId, ReservationStatus target) { Reservation reservation reservationMapper.selectById(reservationId); if (!reservation.getStatus().canTransitionTo(target)) { throw new IllegalStateException(非法的状态流转: reservation.getStatus() - target); } reservation.setStatus(target); reservationMapper.updateById(reservation); }这样写的好处是所有状态流转逻辑集中在了一个地方测试也方便一秒钟能写出十几条状态流转的测试用例。答辩的时候老师问订单从已支付能变成已完成吗会不会有人直接跳过使用中——你把状态机的代码一展示配上流转图这个问题就答完了。4.3 并发控制的完整落地方案有了唯一索引还不够事务里还应该用乐观锁或者悲观锁来兜底。我的建议是在reservation表上加一个version字段更新时带上版本号。对于预约创建这个高竞争操作直接在插入时依赖唯一索引防止重复对于订单状态流转这种低频操作用update ... where id ? and version ?更新返回0则操作失败。为了加深理解我把方案对比列一下方案适用场景优点缺点唯一索引确保同一时间片、同一洗衣机没有重叠订单数据库层硬约束最简单可靠需要理解部分索引或NULL值技巧乐观锁version订单状态更新实现简单适合读多写少冲突多时需要重试并发高时体验稍差悲观锁select for update管理员修改设备信息、对账等写密集操作强一致不会更新失败锁等待可能拉长占用数据库连接时间毕业设计单机部署并发量不会真正很大但我建议至少把方案列在论文里证明你考虑过这个问题。在答辩现场能用一句话说清楚我用唯一索引兜底、乐观锁处理状态更新、Redis锁备用就足够过关了。4.4 定时任务超时自动释放预约后10分钟未支付自动取消到达开始时间未使用自动置为过期。这两个功能用SpringBoot自带的Scheduled就能搞定。Service public class ReservationTimeoutTask { Scheduled(fixedDelay 60000) public void expireUnpaidOrders() { LocalDateTime now LocalDateTime.now(); ListReservation expiredList reservationMapper.selectList( new LambdaQueryWrapperReservation() .eq(Reservation::getStatus, ReservationStatus.CREATED) .lt(Reservation::getCreateTime, now.minusMinutes(10)) ); for (Reservation reservation : expiredList) { changeStatus(reservation.getId(), ReservationStatus.CANCELLED); } } Scheduled(fixedDelay 60000) public void expireUnusedPaidOrders() { LocalDateTime now LocalDateTime.now(); ListReservation list reservationMapper.selectList( new LambdaQueryWrapperReservation() .eq(Reservation::getStatus, ReservationStatus.PAID) .apply(end_time {0}, now) ); for (Reservation reservation : list) { changeStatus(reservation.getId(), ReservationStatus.EXPIRED); } } }这个定时任务的查询条件要结合时间段表的结束时间记得在SQL里关联一下。注意Scheduled默认是单线程的如果你的任务耗时较长可能互相影响不过毕设场景下根本没有这个问题。定时任务的日志要打清楚方便测试时演示等了10分钟订单自动取消了这个效果。5. 前端工作量控制——Vue项目怎么搭才不拖后腿5.1 页面清单先列出来再动手很多同学做前端最大的问题是做着做着就开始调CSS调了一下午。毕设前端以功能完整、界面干净为目标不要追求像素级还原。页面清单建议如下登录注册页首页洗衣机列表 状态展示预约下单页选择洗衣机 选择时间段 状态流程我的预约页列表 取消 状态显示管理后台设备管理、时段管理、订单管理、统计报表就这五个页面所有功能都能承载。如果你用的组件库是Element Plus后端接口都通了之后前端工作量大概两天就能搞定。5.2 预约页的核心时间段选择器预约页是整个前端的重点。学生需要看到目标洗衣机在某一天的时段占用情况然后选择一个空闲时段。这个交互做得好系统就成功了一半。我的实现思路是这样的后端提供一个接口GET /api/washer/{id}/slots?date2024-06-01返回该洗衣机当天所有时间片每个时间片包含是否可预约状态。前端拿到数据后用Element Plus的el-table或el-card渲染成网格已被预约的时段置灰禁用空闲时段高亮可点击。这个交互是动态数据驱动UI的典型场景避免了学生直接选日期时间段再盲目下单然后被拒的情况。体验好很多代码量也不大。5.3 路由、状态管理、环境配置这三个常见坑Vue项目的三个高频问题热词里也都有vue路由、vue动态路由、vue安装及环境配置。路由这块毕设项目用静态路由就行不用强行搞动态路由。管理员页面用meta.requiresAdmin做路由守卫检查角色学生页面普通访问逻辑清晰也容易讲清楚。状态管理Pinia或Vuex建议只存用户信息其他数据都通过接口实时获取。不要让前端状态太复杂否则一处不同步就有bug。环境配置的坑主要在node_modules装不上、Vite版本与Node版本不匹配。解决办法很简单Node装18以上版本Vite用5.x锁死package.json的版本号。如果装了半天依赖还报错删掉node_modules和package-lock.json重新npm install能解决七成问题。项目跑起来之后开发时用localhost:5173连后端localhost:8080记得配一下Vite的proxy代理避免跨域这个三个小时之内必须搞定。5.4 接口联调别等后端全部完成再写前端前端和后端同时开工是最理想的我建议用Swagger/OpenAPI或者一个简单的接口文档先在前后端之间约定好请求和响应格式{ code: 200, message: success, data: { reservationId: 123, status: PAID } }统一响应体结构之后前端可以先用Mock数据把页面写完后端每个接口完成就联调一个。这样进度压力小很多不会出现最后一周疯狂联调的惨剧。6. 论文与答辩——系统设计之外同样要命的那些事6.1 画图比写代码更能体现工作量毕设论文里最重要的四张图分别是系统架构图、ER图、业务流程图、状态机图。这四张图画好论文主体就有了。架构图不用高级就是浏览器 - Vue前端 - SpringBoot后端 - MySQL这种分层结构但要把你实际用到的技术栈标清楚。ER图就是把第3节那6张表画出来标注主外键关系和字段类型。业务流程图是预约流程的完整描述登录、选时段、创建订单、支付、到店使用、完成。状态机图就是从订单状态枚举里提炼出来的六态流转图。这个项目最大的优点在于核心业务闭环完整从预约到支付到使用到超时释放可以自圆其说。答辩时用这张流程图为线索讲系统比按模块列表硬讲效果好得多。6.2 答辩高频问题提前准备好答案答辩老师的时间有限他们会挑最容易暴露问题的点问。我总结了一些高频问题答案要提前准备预约冲突你是如何解决的答案唯一索引并发兜底乐观锁如果两台手机同时抢最后一个空闲时段会发生什么答案一个成功一个被唯一索引拒绝返回友好提示为什么用状态机直接改状态不行吗答案防止非法流转业务逻辑清晰可测试性更好时间片是怎么定义和生成的答案每天由定时任务生成当天时段或管理后台批量生成系统能承受多大并发答案单机部署数据库连接池默认够用瓶颈在MySQL如果要做大可以用Redis缓存消息队列削峰但这不是本系统重点学生没来使用怎么办答案超时任务自动转EXPIRED记录违约用于统计这些问题答得上基本就没问题了。6.3 论文的创新点怎么写创新点是很多同学的痛点。不需要发明什么前沿算法你只要把系统设计里的亮点提炼成三个点即可第一时间片调度模型。把洗衣资源按时段切片实现精细化预约调度替代传统先到先得模式提高设备利用率。第二状态机驱动的订单全生命周期管理。用显式状态流转约束业务避免脏操作提升系统健壮性。第三并发冲突的数据库级解决方案。用唯一索引和乐观锁在不引入额外中间件的前提下保证同一时段不超卖适合中小规模部署场景。这三个点不管从哪个角度都踩在了你确实做了设计的事实上而且逻辑清晰。喂给老师的是一套完整的故事。6.4 效果展示录屏视频是最强辅助最后还有一个很实用的建议做一段5分钟左右的功能演示视频。用录屏工具把注册登录 - 查看洗衣机列表 - 预约下单 - 支付 - 后台管理 - 超时取消完整走一遍。视频放答辩PPT里或者直接存在电脑桌面。老师看代码看困了的时候放一段流畅的演示视频效果远胜于现场操作翻车。演示视频里可以加两个高光时刻一个是用两个浏览器账号同时抢同一个时段验证只有一个能成功另一个是把数据库里订单改坏展示异常处理逻辑。这两个演示能直观证明系统的稳定性也是你工作量的体现。7. 尾声做完这个项目之后还能怎么扩展如果你还有富余时间想给这个项目再加点分量我有几个方向供你参考难度从低到高排列加一个消息通知模块。预约成功后给用户手机发个模拟通知接口打日志即可时间快到了再发一次提醒。这个功能实现成本很低但会让系统显得非常完整。加一个数据可视化看板。用ECharts在管理后台展示每日订单量、设备使用率、高峰期分布这几张图。图表一放上去论文和答辩的档次瞬间提升。不用做复杂三张图足够。加一个简单的信用分系统。每个学生初始100分取消订单扣分按时使用加分信用分低于60限制预约。这个业务逻辑本身就是个独立的小亮点面试时也能讲。不过我得提醒你这些扩展都在核心链路完成之后再做千万不要本末倒置。预约、支付、状态流转、并发控制没做好之前任何花哨功能都是空中楼阁。毕设的核心永远是把主流程跑通、跑稳、跑得能自证。如果你正在做这个题目先照着第3节把表建好再把第4节的状态机和并发控制写完前端能跑通主流程论文画好四张图答辩准备完那一串高频问题——这个毕设就稳了。最后再分享一个我个人的经验别把问题想得太复杂也别把工程想得太简单按模块拆解、稳步推进这个项目完全可以成为你简历上一个拿得出手的作品。祝顺利。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑