☰
Spring Boot宠物寄养系统实战:从业务建模到退租一体化开发
2026/10/10 3:16:50 网站建设 项目流程

自己带猫,平时出差就头疼,在职考编那阵子更是猫毛都要薅秃了。后来朋友推荐了个宠物家庭寄养平台,把猫送去一个有经验的家庭寄养主家里,每天给我发视频,我才算真正松口气。这个“计算机毕设java宠物寄养系统 萌宠在线寄养与退租一体化平台”,说白了就是把这种模式做成一个Web系统——你可以把它理解成一个“宠物版短租平台”:宠物主在上面找寄养家庭、下单、入住、到期退租,寄养主在后台管理订单、更新宠物动态。

做毕设或者自己学框架的人,拿这个题目来练手是再合适不过的。它不像电商系统那么复杂,但麻雀虽小五脏俱全:用户端、寄养主端、管理员端三个角色,加上预订、状态流转、费用计算、退租处理这些核心业务,基本上把SpringBoot后端开发的常用技能点全串起来了。这篇文章我就用一名开发者的视角,把这类系统从需求拆解到代码落地,再到实际踩坑的记录,原原本本整理一遍。

1. 项目核心逻辑拆解:从“寄养”和“退租”两个关键词看业务边界

1.1 标题背后的真实业务模型

先别看技术,先把业务想明白。宠物寄养系统的核心并不只是“把宠物放那儿寄养”那么简单。从用户角度想一遍:我作为宠物主,要寄养一只猫,我得先看到有哪些家庭可以提供寄养服务,每个家庭在哪些时间段有空位、能接受什么品种、家里环境怎么样、费用多少。选定之后下单,寄养主确认,这时候订单变成“已确认”状态。送猫过去之后,订单进入“寄养中”。等到约定的结束日期,宠物主人接回宠物,完成结算,订单状态变为“已完成”——这就是完整的寄养生命周期。

“退租”这个词很多人一开始不理解,以为就是用户退款、取消订单。其实在宠物寄养场景里,“退租”更像酒店退房——寄养到期,宠物主人把宠物接走,交付回执,结算费用,释放寄养家庭的容量。所以这个系统里面至少要包含两个容易搞混的操作链路:一个叫“取消订单”,也就是没开始寄养或者中途因为特殊原因终止;另一个叫“退租结算”,也就是正常结束寄养流程。这两条链路在数据库设计、接口设计和代码实现上,逻辑完全不同,但很多人做毕设的时候混在一起做,结果状态机一跑起来自己都看不懂了。

所有以“租”为场景的周期型业务,都逃不开一个核心设计:租期状态机。一个订单从创建到归档,至少要经历待确认、已确认、寄养中、待退租、已完成这几个状态。加上异常终止,还有已取消这个兜底状态。退租它不是一个单纯的动作,而是一个过程——先是寄养主在后台发起退租确认,系统自动计算费用,然后用户确认结算,最后释放寄养资源。这个“退租过程”被拆成接口和表结构,才是这个系统真正有价值的地方。

1.2 为什么选Spring Boot而不是别的技术栈

做毕设的同学经常纠结技术选型,其实要先想清楚一个问题:毕设的评分标准是什么?不是看你会多少高大上的中间件,而是看你有没有完整地掌握一个主流技术栈,并且能把它合理地用在一个业务场景里。Spring Boot作为Java生态里最主流的后端框架,光这一条就足够说服导师。它把Spring那一大套配置自动初始化好了,用起来像搭积木——加一个web依赖,写一个Controller,立刻就能跑起来,你的注意力能集中在业务逻辑而不是捏配置文件上。

再加上SpringMVC处理请求、Spring事务管住数据库状态流转、MyBatis帮你做ORM映射,这一套组合在一起,是当前国内公司里最常见的后端开发模式之一。你毕设用的技术,最好跟公司里在用的主流技术保持一致,这样答辩的时候导师问起来你也有底气——这不是我把一个奇奇怪怪的框架套进来,而是整个行业都在走的路子。

家庭式寄养这个业务本身也不复杂到需要微服务架构。一台MySQL、一个SpringBoot应用、一个前端页面就够了。你硬要用SpringCloud那套搞,反而把简单的学生项目搞复杂,业务建模深度还上不去。选SpringBoot,本质上是选“把精力花在业务本身”。

1.3 适合什么人来做,值不值得重视

如果你是CS或者软工专业的毕业生,手头正好拿了这个题,那它是个性价比非常高的选题。首先,宠物经济是当下热点,评审不会觉得题材过时;其次,功能模块清晰,前后端能拆能合,工作量好预估;最后,它牵扯到订单、资金、状态、权限,这些都是企业级开发的基本功,写进简历里也不丢人。

如果是自学SpringBoot练手,这种业务模式更是天然的学习用具。因为它强制你去思考“数据是怎么流转的”而不是“页面长什么样”。我现在还建议:做这个项目,至少要把设计数据库的时间留够,甚至先画一遍状态机图再动手写代码。逻辑理顺了,代码量其实是水到渠成的事。

2. 技术架构与准备工作:模块设计、角色权限、前端选型

2.1 三大角色的权限边界

一个成熟的宠物寄养业务系统,必然有三种身份:宠物主(普通用户)、寄养家庭(寄养主)、平台管理员。别看只是一个毕设项目,三种角色的权限划分如果不做,后面很容易乱套。

  • 宠物主:注册登录、维护宠物档案、浏览寄养家庭列表、下单、查看寄养日志、发起退租。
  • 寄养主:维护寄养房屋/服务信息、设置可寄养时间段、接单/拒单、每日记录宠物动态、发起退租确认。
  • 管理员:审核寄养主资质、处理用户投诉、管理全平台订单、统计数据。

SpringBoot里做权限控制,主流方案是SpringSecurity或者Shiro。学生项目我建议直接用SpringSecurity配合JWT做无状态认证,前端每次请求带上Token,后端用一个拦截器校验角色。如果你觉得SpringSecurity配置有点重,还有一个省事的办法:写一个简单的拦截器+自定义注解,每个接口上标一下角色类型,也能达到“够用”的权限隔离效果。但为了学东西,我建议还是过一遍SpringSecurity的完整流程。

2.2 前端和后端的“分工协作”

后端毫无疑问是SpringBoot主打,前端方案有两条路可以选。第一条路是传统服务端渲染:SpringBoot集成Thymeleaf模板,前端拿Bootstrap和JQuery做交互。这条路的好处是部署简单,一个jar包全搞定,对前端基础薄弱的同学特别友好。第二条路是前后端分离:Vue2或Vue3负责页面,SpringBoot只提供JSON接口,好处是界面做得好看,接近未来实际工作的开发模式,但是需要你把跨域、Token存储、打包部署这些东西一并学清楚。

如果让我给第一次做毕设的同学推荐,我推荐泰党版本:Thymeleaf + Bootstrap,后面加一个Vue作为点缀。答辩的时候你能说清两种方案,反而比只用一种更显深度。当然你得会一点Vue才行,那就写两个页面demo:一个用原生HTML,一个用Vue组件,对比展示数据绑定逻辑。教授不傻,他知道你会什么。

2.3 开发环境怎么搭不踩坑

最省心的搭配是这样的:

  • JDK 8 或 JDK 11(SpringBoot 2.x)
  • Maven 3.6+
  • MySQL 5.7 或 8.0
  • Redis(可选,用来做缓存和订单防重复提交)
  • IDEA + Navicat

这里提醒一下:如果你机器上JDK版本跟Maven编译级别对不上,会抛各种奇奇怪怪的错。比如JDK17配合旧版Maven,动不动就编译失败,很多人卡在这一步以为代码写错了,其实是工具链版本不配套。我的建议是不要用最新版,用教材和教程里最主流的版本组合,稳定压倒一切。

3. 数据库设计实战:六张核心表如何撑起整个寄养流程

3.1 表结构的逻辑闭环

宠物寄养系统的数据模型,算是中型业务系统的一个典型Mini版本。我直接按表来说。

用户表(user):主键自增id,用户名,密码(BCrypt加密),手机号,角色字段(0-宠物主,1-寄养主,2-管理员),头像地址,创建时间,状态是否启用。这里有个细节:寄养主其实是从普通用户里衍生出来的,所以别单独建一张寄养主表,在用户表里加角色和审核状态足够,刻意分开反而增加join复杂度。

宠物档案表(pet):id,用户id(外键),宠物名,品种,年龄,体重,是否绝育,性格备注,疫苗记录,照片URL。为什么需要宠物档案?因为寄养家庭下单前需要判断“能不能接”——比如有的寄养主不接受大型犬,有的家庭不愿意接打过疫苗的宠物。把宠物资料结构化存好,才支撑起筛选和匹配。

寄养家庭表(home):id,寄养主id(外键),寄养地址(脱敏后展示),城市,收费单价(元/天),可收宠物的品种类别,家庭环境照片,服务介绍,评分,审核状态(待审核/通过/驳回)。这张表本质上是平台的“供给侧商品”,所有下单流程都围绕它转。

寄养订单表(order):id,订单编号(唯一业务号),宠物id(外键),寄养家庭id(外键),下单用户id(外键),寄养开始日期,寄养结束日期,单价,总金额(根据天数和单价自动计算),状态字段(待确认/已确认/寄养中/待退租/已完成/已取消),下单时间,更新通知时间,取消原因。这是整个系统的流量核心。

寄养动态表(daily_record):id,订单id(外键),寄养主id(外键),日期,早晚喂食记录,遛弯/清理记录,照片,备注文字。这个模块最出彩,它让寄养“看得见”,是平台体验的重要加分项。

退租记录表(checkout_record):id,订单id(外键),退租操作人id,退租类型(正常到期/提前退租),结算金额,退款金额,手续费,实际起始时间,实际结束时间,状态,退租说明。这张表把“退租”变成了一个可追溯的流程,而不是在订单表里改个字段就完事。

3.2 订单状态机的数据库表达

状态字段别用int裸存。我见过很多代码,状态存1、2、3,写到最后自己都忘记1代表什么了。要么用枚举类管理,要么就用字符串存“WAIT_CONFIRM/ CONFIRMED / CARING / WAIT_CHECKOUT / COMPLETED / CANCELED”,可读性凭空高出一截。数据库字段里别嫌字符串长,谁读谁舒服。

状态迁移在程序里控制更稳妥,纯靠数据库容易漏约束。但至少要在表设计时把主键、外键、索引设计明白,不然查询性能会崩。订单表必须给“用户id+状态”“寄养家庭id+状态”“宠物id+订单时间”建立联合索引,避免写SQL的时候全表扫。

3.3 金额和日期,最容易出事故的两处

金额字段一律用decimal,千万别用float或double。寄养费用模板变成浮点之后,0.1+0.2这种经典坑能直接让人怀疑人生。关于日期的处理,基本规则是:存日期用datetime(除非只关心天),传给前端用字符串,不回传毫秒时间戳。很多同学就是在这里没守住,导致前端展示日期差了8小时,改了三次bug才知道是时区问题。

另外退租计算费用时要考虑跨天、半天这种边界。比如寄养日期是8月1日至8月5日,那到底是按五天还是四天算?按平台常见规则,首日当天不算费或者尾日不算费,两种算法跟业务方确认一下。做毕设至少要在代码里写清楚这个规则,不能含糊。哪怕简单到按结束日期减开始日期除以86,400秒算天数,都要有明确的注释说明。

3.4 一个容易忽略的重要表

别忘了操作日志表。寄养平台是涉及安全感和信任感的业务,用户最在意“我的宠物到底经历了什么”。后台任何关键操作——接单、拒单、取消、退租、金额调整——都应该记录一条操作日志。这个表字段很简单,就是操作人id、订单id、操作类型、操作前状态、操作后状态、操作时间、备注。有了它,答辩时被问“如果寄养主说订单是用户取消的,用户说是寄养主取消的,怎么办?”,你就可以笑着拿出这条链路。这一个小小的点,非常拉分。

4. 核心功能实现细节:下单、动态记录、退租的落地逻辑

4.1 下单流程的“库存校验”

下单接口看起来简单,直觉反应就是insert一条订单。但仔细想想,你得先确认这个寄养家庭在目标日期段内可接单。怎么判断可接单?无非是查该家庭所有“已确认”和“寄养中”的订单,分析它们的时间段跟你想要的时间段有没有重叠。重叠判断很多人写不对,其实就一个标准公式:

旧订单开始时间 < 新订单结束时间 && 旧订单结束时间 > 新订单开始时间

这个判断两行代码,但很多人用错方向,用了一大堆ifelse还查漏查错。真正正确的做法是SQL直接操作:在订单表里查询该家庭是否存在某个订单状态不是已取消,且时间段冲突的记录,如果有,就不能下单。

数据库层面还可以做个“唯一索引”吗?不行,因为时间段是重叠的,没法当唯一键。那就只能靠代码层保证。不过加一层Redis分布式锁,以家庭id和日期段为key,锁住再判断再下单,能同时防并发。毕设项目可以不搞这么细,但你自己要具备这个意识。

4.2 退租一体化流程的代码走通

退租这个功能,我单独拿一节说,是因为很多毕设做这个系统就是在退租模块上翻车。

用户付款到“待退租”状态,接下来应该发生什么?正常逻辑是:寄养主开始办退租,系统根据结束日期计算本次实际费用。假如有提前退租的,要按“不足整日按一天计算”之类的规则算清费用。再扣除平台佣金(比如10%),剩余就是寄养主收入。宠物主那边,如果有预付押金,还要按规则处理退押或扣减。

我把这段事务代码简化成流程是三步:更新订单状态、写退租记录表、回滚寄养容量(也就是确认某个时间段的空位释放)。这三步要么全成功,要么全失败,必须包装在一个@Transactional里面。很多同学在这个接口里忘加事务,结果订单状态改了退租记录没有,退租都完成了库存还没释放,整个系统乱成一锅粥。

4.3 前端页面展示和动态记录回填

用Thymeleaf做服务端渲染时,你可以在页面里直接用th:each循环订单列表,再嵌套循环每个订单对应的宠物动态卡片。需要注意的地方是:动态记录一般是一天多条,你展示的时候要按日期倒序、只展示最近7天——多了页面会卡。给寄养主写动态的入口最好做成日历模式:哪天没写记录,日期上就标个红点,点击进去补录。这个交互就算面面俱到,几乎就是市面上成熟宠物App的做法。

图片上传又是一个易翻车点。如果你的系统要支持多张照片,一定先把文件上传目录配好,写到项目根目录以外的独立存储路径里,然后数据库存的是相对路径(比如/upload/pet/20250301_猫01.jpg),访问时再用资源映射暴露出来。很多同学图省事把图片转成Base64存数据库,看起来简单,结果一个订单几十张图把MyBatis慢到拖垮整个页面——大忌。

4.4 定时任务怎么来辅助业务

退租虽然是可以由用户主动触发的操作,但系统最好还能每天自动扫描一遍所有“寄养中”且结束日期小于今天的订单,自动弹成“待退租”。这种定时任务用SpringBoot自带的@Scheduled就能搞定,每天凌晨2点跑一次,写个Mapper扫描过期未退租的订单,统一更新状态。

注意:凡是定时任务涉及状态更新的,都要考虑重入问题。跑了一半服务器重启了怎么办?最简单的解法是每次任务启动时,在某张表里记录“本次任务批次号”,更新时加上批次号判断,保证同一批任务不会重复执行覆盖其他数据。这一点写进答辩的亮点里,能镇住不少评委。

5. 针对高频简历提问的细节:并发、安全、报表的话术整理

5.1 并发场景的处理思路

问的你“下单时如果两个用户同时看中同一个家庭的同一天怎么办?”这不是凭空刁难,而是后端开发躲不开的痛点。我梳理三种方法:乐观锁版本号、悲观锁SELECT FOR UPDATE、Redis分布式锁。学生毕设阶段用第三种最容易讲清楚:Redis里加锁key,例如lock:careorder:home_{id}:20250301-20250305,锁超时时间一定要设,避免死锁,业务执行完再释放锁。

同时并行校验一定要在锁里面做,不能让两个请求同时通过校验再排队插入——那是伪并发控制,直接穿帮。

5.2 接口安全与防刷思路

对外暴露的接口一定要做入参校验,起码用@Validated注解配合DTO校验,不要拿实体类直接接收前端参数。用户操作必须校验归属权——“这只宠物是当前登录用户的吗?这个订单是当前登录用户的吗?”这两处校验必须写在接口层,否则会发生越权操作。我在很多实习生的代码里都见过这种洞,一个id改一下就变成操作别人的订单了,在当时还引起过不小的麻烦,所以养成习惯非常关键。

密码加密用BCrypt,不加盐手动拼字符,用SpringSecurity自带的BCryptPasswordEncoder就不是做法了。

5.3 报表统计怎么让答辩加分

寄养平台很自然能引导出统计报表需求:本月订单数量、热门寄养城市Top5、寄养主接单排行、宠物种类分布。用一条SELECT COUNT(*) FROM order WHERE create_time BETWEEN ... GROUP BY home_id就能实现后端统计接口,前端再配一个ECharts折线图和柱状图,项目整体效果瞬间提升一个档次。这一步成本低、视觉效果好,千万别省略。

别去搞那些造不出真实数据的假图表,把系统跑起来,在数据库里造一个月的数据量,让页面上的报表真的动起来,那个视觉效果是任何静态截图都无法替代的。很多人到答辩前才发现时间都花在了“复杂记忆点”上,真不如把这种基础又亮眼的模块做得扎实。

6. 我的实操体会与避坑经验总结

文章写到这里,我已经把宠物寄养系统从业务建模到代码落地给捋了一遍。这些内容不是凭空想出来的,很多是从当年自己做的那些“血泪教训”里总结出来的。比如最开始做退租,我图快直接在订单状态字段上改值,根本没建退租记录表,结果导师一问“退租时扣费明细在哪展示?”我当场愣住——回去重构了整整一个通宵。从那以后我就确立一个规矩:类似账号资产、订单资费这种跟钱相关的流程,一定单独留一张明细记录表,一个动作就是一张表的事件,绝不偷偷改字段。

还有一个小技巧分享给正在做的人:开发阶段一定要写单元测试,至少把订单状态流转和费用计算这两个核心Service的测试写了。不夸张地说,有测试兜底,你后面改一天代码可以直接跑一遍,两分钟发现改崩了什么地方,比手动点页面测一天高效太多。特别是到了最后几天,项目越加功能越容易互相牵扯,测试就是你最后的防线。

这个项目后面能扩展的方向其实很多:比如接入微信小程序做移动端下单、增加寄养全程远程视频查看功能、对接支付网关实现线上支付、利用消息队列做通知系统。不过这些都是后话,核心还是先把订单链条走通,把SpringBoot这套后端体系熟练起来,后面加功能都是复制粘贴的活了。

做项目跟养宠物其实挺像的,急不得。你今天写的每一行代码、调通的每一个状态流转,都在给最终的系统“注入营养”。等项目跑起来,恰好也能把宠物安稳地托付给一家靠谱的人,那这份功夫就没白费。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询