ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Spring Boot+Vue宠物美容机构管理系统:从业务拆解到答辩加分全攻略

Spring Boot+Vue宠物美容机构管理系统:从业务拆解到答辩加分全攻略

宠物美容机构的“数字化改造”这几年已经成了毕业设计里的大热门。我刚帮一位学弟梳理完《基于springboot + vue宠物美容机构管理系统》这套题目,从选题、数据库设计到前后端联调全流程走了一遍,感触很深:这个题看似常规,但做得好不好、答辩能不能拿高分,差别其实非常大。它涉及真实业务场景中的预约排期、宠物档案、订单收费等核心模块,技术栈上正好覆盖Spring Boot后端 + Vue前端这套目前主流的前后端分离方案,非常适合用来证明你的全栈开发能力。

这篇博文我不会只给你堆需求文档,而是把“怎么能顺利做出来、哪些地方最容易翻车、答辩时老师到底会问什么”拆开讲透,希望能帮你少走弯路。

1. 项目全貌:宠物美容机构到底在忙什么

1.1 先看业务:一个宠物美容店的日常混乱

如果你去一家还没上系统的宠物美容店蹲一天,大概率会看到这样的场景:前台小姐姐一边接电话一边在本子上记预约,美容师忙完一只贵宾犬出来发现下一单客户早到了半小时,店员翻半天微信聊天记录才能找到某只猫咪上次洗澡用的什么香波,月底老板拿着纸质小票对账对得头大。

这些看似琐碎的细节,恰恰是“宠物美容机构管理系统”要解决的核心痛点。

  • 预约混乱:客户打电话/微信预约,店员手写登记,记错时间、日期撞档、爽约没人跟进是常态。
  • 档案缺失:每只宠物的品种、年龄、过敏史、常用美容项目、历史照片都散落在聊天记录里,换个人就接不上话。
  • 收费不清:不同的猫咪、狗狗体型不同,美容价格不同,还有办卡会员、套餐折扣,纯靠人工计算容易扯皮。
  • 员工绩效难统计:谁今天做了几个订单、业绩多少,月底很难快速算清楚。

所以这个系统绝不只是“增删改查”那么简单,它本质上是一个面向小型宠物服务门店的业务管理系统,需要覆盖从预约、接待、服务到收费、回访的完整闭环。

1.2 毕业设计为什么适合选这个题

我接触过不少做类似题目的同学,选择这个方向有几个非常实际的好处:

第一,业务复杂度适中。它比单纯的“图书管理系统”更有场景感,又比电商秒杀、大型SaaS系统简单太多。预约冲突、多角色权限、订单状态流转这几个点,属于“跳一跳够得着”的难度,既能展示能力,又不会做到一半做不下去。

第二,技术栈主流且完整。Spring Boot + Vue 这套前后端分离组合,是目前中小规模企业项目最常见的搭配之一。做完这个项目,你简历上可以写的东西很多:RESTful API设计、JWT登录鉴权、MyBatis Plus操作数据库、Vue Router路由权限、Axios请求封装……每个都是真实岗位面试会问的点。

第三,演示效果好。宠物美容涉及大量图片展示、日历预约交互、状态标签切换,做出来的界面比干巴巴的管理后台生动很多,答辩演示时观感很好,老师也容易理解业务价值。

2. 技术选型:Spring Boot + Vue 这套组合的前因后果

2.1 后端为什么选 Spring Boot 而不是 SSH/SSM

很多教材还在教 SSM(Spring + SpringMVC + MyBatis)整合,但实际工作里 Spring Boot 早就成了绝对主流。Spring Boot 的核心价值就是“简化配置、快速启动”——它内置了Tomcat,把纷繁复杂的XML配置换成自动配置和Starter依赖,你用idea新建一个项目,几步就能跑起来一个Web应用。

和传统方案相比,它的优势特别明显:

对比项SSM/SSH 传统方案Spring Boot
配置方式XML写一大堆,整合耗时自动配置,application.yml即可
启动方式需外部Tomcat,配置麻烦内置容器,jar包一键启动
依赖管理手工管理版本冲突Spring Boot Starter统一管理
学习门槛概念多、整合复杂上手快,聚焦业务开发
社区生态逐年萎缩当前主流,资料丰富

选 Spring Boot 还意味着答辩时你能非常自然地回答“为什么做这个技术选型”:因为它解决了传统SSM整合成本高、配置冗余、部署困难等实际问题,是目前企业级开发的通用标准。这句话一出来,老师就知道你不是随便选的。

2.2 前端为什么选 Vue 而不是 React

Vue 和 React 都是优秀的框架,但放在毕业设计这个场景,Vue 有三个别人比不了的点:

一是上手曲线平缓。Vue 的模板语法接近 HTML,渐进式架构让你可以从“在HTML里引入Vue使用”开始,再逐步到单文件组件、Vue Router、Pinia/Vuex。大部分同学从零到能写出完整后台管理界面,一到两周就能做到。

二是周边生态贴合业务。Element UI / Element Plus 这类组件库是专门为后台管理系统设计的:表格、表单、弹窗、日历、分页,都是开箱即用。你不需要花大量时间写CSS,装好组件库,页面效果就已经很专业了。

三是社区中文资料丰富。Vue 在国内前端市场的占有率很高,学习过程中遇到“组件不更新”“路由404”这类问题,搜中文基本就能直接找到答案。

当然,如果你对 React 更熟,或者导师指定用 React,那这个题目的前端也可以换成 React 实现,核心逻辑不变。不过从稳妥、快速、不容易卡壳的角度,Vue 确实是更省心的选择。

2.3 配套依赖怎么选

一个成熟的宠物美容管理系统,光有 Spring Boot + Vue 还不够,我在实际搭建时通常会配上这套组合:

  • MySQL 8.x:数据存储的主力,免费、稳定、资料多。
  • MyBatis Plus:在 MyBatis 基础上做了大量增强,单表CRUD不用写SQL,内置分页插件,能省很多体力活。
  • Spring Security 或 JWT:登录认证与权限控制。毕业设计一般推荐 JWT + 拦截器的方式,理解成本低,代码量也少一些。
  • Lombok:注解生成 getter/setter/构造器,让实体类非常简洁。
  • Redis(可选加分项):做验证码存储、缓存热门服务项目列表。如果还没用过Redis,它可以作为答辩时的一个亮点来介绍。
  • Element Plus / Axios / Vue Router / Pinia:前端基础四件套,分别负责UI、HTTP请求、路由管理、状态管理。
  • Hutool:一个Java工具类库,生成随机验证码、日期处理、Bean拷贝都很方便,减少自己写的工具代码。

这里我要强调一点:选型务必以“能跑通”为第一原则。很多同学喜欢在项目里堆砌一堆新技术,比如用Elasticsearch做搜索、用RabbitMQ做消息队列,结果把自己搞崩了,最后项目都跑不起来。毕业设计的核心是完整性和逻辑自洽,技术栈在精不在多。

3. 功能拆解与数据库设计:先把地基打牢

3.1 角色权限设计:谁在用这个系统

我把系统的使用者分成四类,每一类看到的界面和能做的操作完全不同:

角色核心权限典型操作
管理员(老板/店长)全部权限员工管理、服务项目定价、查看经营报表、数据统计
前台接待预约/接待/收费添加宠物档案、登记预约、处理到店、开具订单
美容师查看与执行查看今日预约、开始/完成服务、填写服务记录
客户(C端用户)自助查询与预约注册登录、维护自己的宠物信息、在线预约、查看消费记录

实际开发时,不一定需要完全独立的客户端小程序或App。如果是纯管理后台,可以内置一个“客户”角色,允许客户登录后查看自己的宠物和订单;如果学有余力,再做一个H5端或者微信小程序端作为加分项。

这种多角色权限设计非常重要,因为它直接关系到数据库字段设计、Vue Router动态路由和后端接口鉴权。答辩时老师特别喜欢问“怎么防止一个普通用户去调用管理员接口”,你准备好“后端接口基于角色校验 + 前端根据角色渲染菜单”这套回答,分数就稳了。

3.2 核心业务模块拆解

宠物美容机构管理系统的功能模块,我建议至少包含以下八个:

  1. 登录注册模块:用户名密码登录、JWT签发与校验、验证码、退出登录。
  2. 员工管理模块:管理员对员工账号的增删改查、角色分配、账号启停用。
  3. 宠物档案模块:宠物昵称、品种、性别、年龄、体重、毛色、过敏史、绝育情况、疫苗记录、宠物照片。
  4. 服务项目管理模块:服务名称、适用宠物体型、价格、耗时、所需美容师级别。
  5. 预约管理模块:客户选择服务项目和美容师、预约日期和时段、冲突校验、预约状态流转。
  6. 订单收费模块:到店后根据实际服务生成订单、支持会员折扣、订单明细展示、支付状态管理。
  7. 评价回访模块:客户对服务评分和评价、店长查看回访列表。
  8. 统计报表模块:营业额趋势、各服务项目销量排行、员工绩效、预约到店率。

这里重点说一下“预约管理”。预约是这个系统里最容易出彩、也最容易写崩的模块。你需要定义好状态枚举,我一般这样设计:

已预约(pending) -> 已到店(confirmed) -> 服务中(serving) -> 已完成(completed) -> 已取消(cancelled) -> 爽约(no_show)

状态流转必须严格限制,比如“已完成”的订单不能直接改成“已取消”,否则数据就乱了。

3.3 数据库表设计要点

数据库设计是毕业设计的地基,我强烈建议你先把E-R图画清楚再动手写代码。核心表至少要有这几张:

sys_user 用户表(员工+客户共用,通过role区分) pet 宠物档案表(归属客户,含品种、过敏史等) service_item 服务项目表(洗澡、美容、造型等) appointment 预约信息表(核心业务表) orders 订单表(到店消费后生成) order_detail 订单明细表(一个订单对应多条服务明细) review 评价表(关联订单)

以 appointment 表为例,字段设计大致如下:

id 主键 pet_id 宠物ID(关联pet表) user_id 客户ID(下单人) service_id 服务项目ID groomer_id 美容师ID(关联sys_user) appointment_date 预约日期 time_slot 时间段,比如"09:00-10:00" status 状态(pending/confirmed/...) remark 备注 create_time 创建时间 update_time 最后更新时间

这里有两个非常容易踩的坑,我提醒一下:

第一,外键约束到底用不用?很多教材喜欢强调外键,但在真实企业项目里,互联网公司普遍“不用数据库外键,而是在应用层维护数据一致性”,因为外键会影响高并发写入性能、让分库分表变得困难。毕业设计代码里可以不用外键,但必须在逻辑上保证关联字段有效,比如删除一个宠物之前,先检查它有没有未完成的预约。答辩时如果老师问“你为什么不用外键”,你可以这样回答:“为了系统的扩展性和性能考虑,采用应用层逻辑保证数据一致性,这也是目前企业开发的常见做法”。

第二,金额字段用什么类型?一定要用 decimal,不要用 float/double。浮点数在计算金额时会出现精度缺失,比如 0.1 + 0.2 != 0.3 的问题在Java和数据库中同样存在。虽然这个题目的订单量不会很大,但养成用 decimal 的习惯对你是加分项。

4. 后端实现:Spring Boot 的骨架搭建

4.1 项目结构与分层设计

一个清晰的后端包结构,是老师快速get到你代码水平的关键。我的习惯是这样:

com.example.petgrooming ├── controller # 控制层,接收请求,返回结果 ├── service # 业务层,核心逻辑 │ └── impl # 业务实现类 ├── mapper # MyBatis Plus 的 Mapper 接口 ├── entity # 实体类 ├── dto # 前端传参/返回对象 ├── config # 配置类(Cors、拦截器注册等) ├── common # 通用类(统一返回结果、异常处理、常量) ├── utils # 工具类(JWT工具、日期工具) └── PetApplication.java # 启动类

这里重点解释两个设计思路:

统一返回结果。我习惯定义一个Result<T>类,结构固定为{ code: 200, message: "success", data: ... }。这样前端Axios拦截器只需要统一处理后端返回结构,不用每个接口单独判断。好处是你后续加接口非常快,代码风格也一致。

全局异常处理。用@RestControllerAdvice定义一个全局异常处理器,把业务异常、参数校验异常、未知异常统一拦下来。否则你的接口一旦报错,前端拿到的就是一堆晦涩的堆栈信息,联调阶段会非常痛苦。

4.2 登录认证与权限拦截

这个系统包含多角色,权限控制是答辩一定会被问到的地方。我就用“JWT + 拦截器 + 注解”这套方案,逻辑非常简单清晰:

用户登录成功后,后端根据用户ID、用户名、角色生成一个 token,返回给前端。前端把 token 存在本地,之后每次请求都放在请求头的 Authorization 字段里传回。后端写一个拦截器,拦截所有/api/**请求,取出 token 校验签名和过期时间,把用户信息放到 ThreadLocal 里供后续使用。

核心代码示例如下:

// 登录接口核心逻辑 public Result<String> login(LoginDTO dto) { // 1. 校验验证码(如果有) // 2. 根据用户名查询用户 SysUser user = userMapper.selectOne( new LambdaQueryWrapper<SysUser>() .eq(SysUser::getUsername, dto.getUsername())); // 3. 校验密码(BCrypt加密对比) if (user == null || !BCrypt.checkpw(dto.getPassword(), user.getPassword())) { throw new BusinessException("用户名或密码错误"); } // 4. 生成JWT并返回 String token = JwtUtil.createToken(user.getId(), user.getUsername(), user.getRole()); return Result.success(token); }

拦截器的核心逻辑:

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token = request.getHeader("Authorization"); // 放行登录接口等白名单路径 if (request.getRequestURI().contains("/user/login")) return true; try { Claims claims = JwtUtil.parseToken(token); // 把用户信息存入ThreadLocal,供Service层获取当前用户 UserContext.setUser(claims); return true; } catch (Exception e) { // 返回401状态码 response.setStatus(401); return false; } }

再配合自定义注解@RequireRole("admin")在Controller方法上做细粒度控制,只有管理员能调用的接口就有了双重保障。这套设计紧凑且实用,代码量也不大,跟老师讲清楚“无状态认证、不需要服务端存储Session”这两点,就是很好的亮点。

4.3 预约冲突检测:先想清楚再写代码

预约是这个系统里业务性最强的功能。一个美容师在某个时间段只能服务一只宠物,所以后端在新增预约时必须做“冲突检测”。

我的实现思路是:查询该美容师在相同日期的排班状态,以及已存在的、时间区间重叠且状态不是“已取消”的预约记录,逐条比较时间段是否重叠。

// 判断两个时间段是否重叠的通用逻辑 public boolean isTimeSlotOverlap(String start1, String end1, String start2, String end2) { // 不重叠的条件:end1 <= start2 或 end2 <= start1 return !(end1.compareTo(start2) <= 0 || end2.compareTo(start1) <= 0); }

然后把美容师的排班表也纳入考虑,如果某天美容师是休息状态,前台应该压根选不到这个人。这样从源头避免冲突,用户看到的就是“该美容师当前时段不可选”,而不是提交之后才报错。

这块我建议你一定要自己手写,不要直接用数据库唯一索引去堵。因为“唯一索引只能防完全重复,防不了时间区间重叠”,你给老师讲清楚这个技术难点和处理逻辑,会让你的项目层次明显高于“CRUD搬运工”。

4.4 其他值得注意的后端细节

分页查询。列表页(比如订单列表、预约列表)数据可能会越来越多,绝不能用selectList一把梭。MyBatis Plus 的Page<T>+selectPage已经是标配写法,前端传页码、每页条数、搜索关键字,后端返回总分页结果。

时间参数接收。前端传日期和时间,如果用@RequestParam String appointmentDate接收,再手动解析,代码会很不优雅。正确的做法是配置@DateTimeFormat(pattern = "yyyy-MM-dd"),或者在全局配置了 Jackson 的日期格式后直接@RequestBody接收实体类。

密码加密存储。用户的密码一定要用 BCrypt 等加密算法处理,数据库里绝不能存明文。虽然这个项目是课程作业,但“不存明文密码”这一条在很多企业开发规范里是红线,你做到了就是一个出彩的小细节。

5. 前端实现:Vue 界面从零搭起来

5.1 工程结构与路由设计

前端我用 Vue 3 + Vite + Element Plus + Pinia 这套组合。Vite 启动速度快,开发体验比 Vue CLI 好很多,而且使用的人越来越多,答辩时也算是一个“技术新一点”的信号。

目录结构大致如下:

src/ ├── api/ # 每个模块的接口请求函数 ├── assets/ # 静态资源 ├── components/ # 通用组件 ├── layout/ # 主框架(侧边栏+顶栏+内容区) ├── router/ # 路由配置 ├── stores/ # Pinia状态管理 ├── views/ # 页面视图 │ ├── pet/ │ ├── appointment/ │ ├── order/ │ ├── user/ │ └── dashboard/ ├── utils/ # axios封装、工具函数 ├── App.vue └── main.js

路由这块强烈推荐使用动态路由:用户登录后,根据返回的角色信息,动态生成该角色可见的路由表,再router.addRoute注册进去。比如美容师登录后看不到“员工管理”菜单,管理员登录则全部可见。这会让你的系统显得非常专业,而且和 JWT 权限控制形成了前后端呼应。

5.2 Axios 封装与拦截器

Axios 请求封装是前端必须做好的基建。我的习惯是:

// utils/request.js const service = axios.create({ baseURL: '/api', timeout: 10000 }) // 请求拦截器:自动携带token service.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) { config.headers.Authorization = token } return config }) // 响应拦截器:统一处理业务码和报错 service.interceptors.response.use( response => { const res = response.data if (res.code === 200) { return res.data } if (res.code === 401) { // token失效,跳转登录页 router.push('/login') } ElMessage.error(res.message) return Promise.reject(new Error(res.message)) }, error => { ElMessage.error('网络异常,请稍后重试') return Promise.reject(error) } )

这样做的好处是:每个页面组件里写接口时不用关心token从哪来、后端报错怎么提示,所有公共逻辑都在拦截器里统一处理了。这也是企业项目里的常规写法,面试时能说得头头是道。

5.3 几个核心页面的实现思路

预约日历页面。我用了 Element Plus 的日历组件封装,左侧展示月历,右侧展示选中日期当天所有预约。日历格子可以自定义内容,比如有预约的日期下面显示小圆点。点击某一天,下方列表展示当天预约的宠物、美容师、服务项目、时段和状态。

宠物档案表单。这是体现系统专业感的重要页面。除了基础字段,我会把“过敏史”和“注意事项”做成多行文本,让用户可以录入详细备注。宠物照片上传用 Element Plus 的 Upload 组件,后端接收到 MultipartFile 后存到本地目录,把访问URL存进数据库。

订单结算页面。到店服务完成后,前台选择该预约对应订单,系统自动把预约时选择的服务项目带出,也可以追加其他服务。价格根据宠物体型和会员折扣自动计算,确认后生成订单。这个页面的状态流转逻辑要小心,成功支付后订单状态要同步更新回预约记录。

5.4 前后端联调与跨域问题

开发阶段跨域是绕不开的坑。最省事的方案是用 Vite 的代理功能:前端请求/api开头的路径时,Vite 帮我们把请求转发到http://localhost:8080。这样浏览器看到的始终是同源请求,不会触发跨域拦截。

// vite.config.js server: { port: 5173, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } }

后端同时也要配跨域配置,二选一即可,我在项目里通常两者都配,防止某个场景漏掉。后端的配置很简单:

@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }

6. 从零到演示:数据库初始化、启动与部署

6.1 数据库初始化

数据库脚本一定要提前写好,并且要保证“一键执行不报错”。我习惯把所有建表语句放在一个init.sql里,同时在注释里写明每张表的作用。除此之外,再准备一份data.sql,插入一批演示数据,比如10只宠物、5个美容师、一周的预约记录、若干订单。

这批数据不要随便造,要精心设计:有的宠物是泰迪、有的宠物是布偶猫;有的客户办了会员;有的预约是待确认、有的是已完成。这样一来,你演示的时候点开每个模块都有内容可看,而不是空表格,体验完全不同。

6.2 后端配置文件

application.yml是后端启动的关键,需要配置的数据源、MyBatis Plus 插件、JWT 密钥等都要写清楚:

server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/pet_grooming?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: 你自己的密码 driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印SQL,开发时很有用 global-config: db-config: logic-delete-field: deleted # 逻辑删除字段 logic-delete-value: 1 logic-not-delete-value: 0 jwt: secret: 一串足够长的随机字符串 expire: 604800 # 过期时间,单位秒,这里是一周

有几个细节我想特别叮嘱一下:数据库连接串里的characterEncoding=utf-8和serverTimezone=Asia/Shanghai一定要带上,否则中文乱码和日期偏差这两个问题够你排查半天。

6.3 前端启动与打包

前端开发时一条命令就能跑起来:

npm install npm run dev

如果 npm 安装很慢,建议先配置淘宝镜像源,不然一堆依赖下载中途卡住,非常影响心情。

如果你希望把项目打成前后端分离部署包,前端执行npm run build,生成dist目录,然后让 Nginx 指向前端静态文件,同时把/api反向代理到后端的 8080 端口。这部分尽管做,不会很难,但能让你在答辩时说“我的项目已经可以部署到Linux服务器上运行了”,加分效果很明显。

7. 踩坑实录:常见问题与排查思路

7.1 后端高频问题排查表

现象可能原因解决方案
启动时端口被占用8080被别的进程占用了修改server.port,或者用netstat -ano找出占用进程后杀掉
中文写入数据库变乱码数据库连接串缺少编码参数在url末尾加characterEncoding=utf-8
SQL打印一堆日志,性能慢MyBatis Plus 把所有SQL输出到控制台生产环境关闭log-impl
时间字段差8小时时区配置不对url里加serverTimezone=Asia/Shanghai
前端提交的中文变成乱码请求和响应的编码不一致全局Jackson配置UTF-8,前端请求头带Content-Type: application/json; charset=utf-8
同一个预约被重复下单未做冲突检测在Service层加事务与预约时间段重叠检查

7.2 前端高频问题排查表

现象可能原因解决方案
刷新页面出现404路由是history模式,Nginx没配fallbackNginx配置try_files $uri $uri/ /index.html;
请求通了但跨域报错代理配置没生效重启Vite服务,确认请求路径以/api开头
接口返回数据了,界面不刷新Vue响应式丢失检查是否直接用下标修改数组,改用reactive/ref的API更新

| 上传图片失败 | 后端文件保存路径不存在 | 启动前先创建好存储目录,或后端代码里自动创建 |

7.3 定位 Bug 的通用思路

我调试这个项目踩过不少坑,最后总结出一个通用排查套路:从前端请求开始一层层往后查。

首先打开浏览器开发者工具,确认请求有没有发出去、URL对不对、请求头有没有带token。然后看后端控制台,有没有进入对应的Controller、参数接收的是什么、SQL打印出来长什么样。最后看数据库里数据有没有变化,没变化说明逻辑没走通,变了说明功能本身是通的。

按照“前端 -> 后端 -> 数据库”顺序排查,90%的问题都能在10分钟内定位。千万不要一头扎进代码里瞎翻,更不要怀疑是环境问题,绝大多数情况都是我们自己的代码有疏漏。

8. 答辩加分:怎样把毕业设计讲成亮点

8.1 开场讲好系统价值,而不是背功能介绍

很多同学答辩开场就是“本系统实现了用户管理、预约管理、订单管理……”——老师已经听了无数遍,毫无记忆点。

我建议换一种讲法:从业务痛点切入。比如你这样说:“我调研了本地几家宠物美容门店,发现他们在预约排期、客户档案、收费统计上完全依赖手工记录,效率低而且容易出错。所以我设计了这个系统,把它拆成预约、档案、订单、统计四大核心流程……” 这样讲出来,老师立刻明白你做这个题目是真的思考过“为什么做”,而不只是为了凑毕业设计。

8.2 高频答辩问题提前准备

我把这道题目老师最爱问的几个问题整理如下:

老师常问问题建议回答方向
为什么用前后端分离?职责分离,后端只提供接口,前端关注交互,团队可并行开发,部署也更灵活
JWT和Session有什么区别?JWT无状态、可扩展、天然适配移动端,Session依赖服务端存储,集群环境下需要额外共享方案
怎么保证一个美容师同一时间只有一个预约?在后端Service层做时间重叠检测,加上数据库层面的唯一约束或Redis分布式锁作为兜底
数据库表之间是什么关系?宠物表与预约表是一对多,订单与明细是一对多,用户与宠物是一对多,用E-R图展示
如果客户量特别大,系统哪里会先成为瓶颈?数据库连接与单表查询、预约接口的并发写入,可通过加索引、Redis缓存、拆表等方式解决
这个系统还有哪些可以扩展的地方?增加微信小程序端、对接第三方支付、增加消息推送、用工作流引擎处理多级审批

每个问题你只要能说出一两句有深度的话,就已经超过很多照本宣科的同学了。千万不要死记硬背,要理解背后的逻辑,老师追问起来才不至于露馅。

8.3 演示时的节奏控制

演示环节控制在10分钟左右,我建议按这条路径走:登录 -> 看数据统计首页 -> 新增一只宠物档案 -> 给这只宠物预约一个美容服务 -> 演示冲突时提示不可选 -> 美容师账号登录查看今日预约 -> 完成服务并生成订单 -> 查看订单与营业额报表。

整条链路正好覆盖一遍核心业务闭环,也让老师直观看到“一个客户从建档到消费完成”的完整过程。用不同的浏览器各登一个角色账号,切换演示不需要来回退出登录,现场效果更流畅。

9. 最后一点私货:做完这个项目的几点真实感受

这个题目做完,我的最大感受是:它给我的锻炼远不止“写代码”本身。从分析一家宠物美容门店的真实运营流程,到设计一套合理的数据库结构,到前后端接口联调时反复沟通字段定义,再到最后打包部署给学弟演示——每一环都像一个小型真实项目的缩影。

如果你也是选了这个题目,我建议你给自己定一个两周冲刺计划:第一周搞定后端所有接口和数据库脚本,第二周集中做前端页面和联调。千万不要先做前端再做后端,否则联调时会发现接口字段根本对不上。更不要想着把代码写完再统一测,每天都应该保持“项目能正常运行”的状态,哪怕只完成一个模块,也要保证它能跑起来再进入下一个。

还有一个小建议:把你设计和踩坑的过程都记到开发日志里,不只是为了自己复盘,更是答辩时的好素材。当老师问“你遇到过什么难题”时,你说“前端日历组件回显已预约数据时状态不一致,最后通过重新设计接口返回结构解决的”,比任何空话都更有说服力。

这套系统做完,你会发现自己对 Spring Boot、Vue、MySQL 这套技术栈的理解上了一个台阶,也真正体会到了一个应用从零到可交付的全过程。剩下的就是打磨细节、准备答辩,祝你顺利。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进