
毕业设计选题这件事每年都会卡住一大票人。要么题目太理论做完没有落地感要么业务逻辑太简单答辩时候说不了几句就露怯。“SpringBootVue疫苗发布和接种预约系统”这个题目算是典型的中台型业务场景有管理后台、有用户前台、有预约流程、有库存和时段控制既踩中了公共卫生热点又覆盖了Java后端和Vue前端的主流技术栈用来做毕设、课设或者自己练手都非常合适。我以这个题目为骨架把从架构设计、数据库建表、后端接口、前端页面到部署上线的完整思路捋一遍顺便把实际开发过程中容易踩的坑和应对方案也一并写出来给后来的人当一份能直接照着抄的参考。1. 项目整体规划与技术选型1.1 为什么要选 SpringBoot Vue 这套组合先说结论这个组合在校园项目里几乎是“标准答案”但它确实不是滥用而是适合。SpringBoot解决了Java后端“配置地狱”的问题内嵌Tomcat打成jar包就能跑对部署环境要求极低学生能省下大量处理环境的时间。Vue则有清晰的生命周期和组件化机制配合Element UI这类组件库做管理后台的效率极高两天时间就能搭出像模像样的界面。前后端分离架构本身的好处在这个项目里体现得尤其明显。管理端是给疾控中心或医院工作人员用的功能密集、表单多、数据表格复杂用户端则是给普通市民用的以预约流程为主界面偏简洁。如果做成传统Thymeleaf模板混在一起权限控制、页面切换、接口复用都会很别扭。拆成前后端两个工程后开发时用Vue的devServer联调部署时前端打包成静态文件既可以丢到Nginx下也可以直接放进SpringBoot的static目录灵活性高很多。再从数据流角度讲疫苗预约这类系统天然适合RESTful风格的接口设计。疫苗信息查询、库存扣减、预约状态流转每一样都可以抽象成独立资源前端通过axios异步调用交互体验比表单提交时代好一个档次。你可以把整套系统理解成“一个中心化的数据管理后台 一个面向公众的自助服务入口”SpringBoot和Vue正好是这两端的理想载体。1.2 技术栈清单与关键选型理由这里列一份我当时实际使用的技术栈清单供参考中间每一项的选择都有对应理由。层次技术选型选择理由后端框架SpringBoot 2.7.x稳定、资料多避免3.x新特性带来的兼容坑ORM框架MyBatis Plus单表CRUD零SQL分页插件好用节省大量时间权限认证JWT Spring Interceptor无状态认证前端存Token适合前后端分离数据库MySQL 5.7 / 8.0免费、通用学校机房和云服务器都容易部署前端框架Vue 2 Element UI组件生态成熟中文文档完善毕设答辩接受度高HTTP客户端Axios拦截器统一处理Token和错误响应最常用的方案构建工具Maven / npm后端标准构建前端包管理没有额外学习成本我特意选了Vue2而不是Vue3原因很实际Element UI对Vue2的支持最完善网上组件示例大多基于Vue2学生碰到问题更容易搜到答案Vue3虽然新但Composition API上手曲线更陡毕设周期就那么几个月求稳比求新重要。如果已经熟练掌握了Vue3也可以换成Element Plus核心思路完全一致。值得一提的是MyBatis Plus这是后端的效率利器。默认提供了insert、selectById、updateById这些方法单表操作根本不用手写XML分页只需要new Page然后调用selectPage免去了自己写LIMIT和count查询的麻烦。不过多表关联查询还是得手写SQL这个不要偷懒绕过去答辩时极有可能被问到。2. 需求拆解与数据库设计2.1 系统角色与核心功能模块任何系统第一步都是理清角色。疫苗预约平台的用户主要分三类系统管理员、工作人员、普通用户。管理员负责账号管理、疫苗信息录入、公告发布等工作人员负责接种点的排班维护、预约审核如果开启、库存数量调整用户则在前台完成注册登录、浏览疫苗、选择时间段预约、查看接种记录。三大核心模块分别是疫苗管理、预约管理和用户管理。疫苗管理不只是一张疫苗表那么简单它要支撑的业务包括疫苗上架和下架、库存数量维护、适用年龄范围设定、接种剂次说明。做过实际项目的人都知道信息和业务要分离所以疫苗表只管静态属性库存和预约状态要用独立字段或独立表来管理否则并发一上来就会出现数据错乱。预约管理是这个系统真正复杂的地方。它既要考虑“时间冲突”同一个用户不能同时预约两个不同疫苗的相同时间段也要考虑“库存余量”疫苗库存不能被扣成负数还要处理“取消预约”后时段和库存的自动回退。这些逻辑在数据库层面设计不好后面写接口时会非常痛苦。用户管理相对标准但仍要注意密码存储不能明文后端用BCrypt或MD5加盐处理即可。为了避免过度设计我建议用角色字段区分管理员和普通用户而不是单独建一张复杂的权限表毕设阶段把JWT能校验角色就够了。2.2 核心数据表结构与设计思路这里给出我实际建表后的核心表清单应用户角色、疫苗信息、疫苗批次库存、预约记录、接种点排班、公告信息等维度组织。用户表sys_user字段名类型说明idbigint主键自增usernamevarchar(50)登录账号唯一索引passwordvarchar(100)BCrypt加密后的密码real_namevarchar(50)真实姓名id_cardvarchar(18)身份证号预约查询时用phonevarchar(20)手机号roletinyint0用户1工作人员2管理员create_timedatetime注册时间身份证号建议加唯一索引因为疫苗预约场景中身份证是用户身份的核心标识同时可以用来防止重复注册。但这里有个细节如果身份证字段被判重用户找回密码的流程就要顺带做一下不然注册时提示“该身份证已注册”用户会很困惑。疫苗信息表vaccine_info字段名类型说明idbigint主键vaccine_namevarchar(100)疫苗名称如“流感疫苗”manufacturervarchar(100)生产厂家vaccine_typevarchar(50)疫苗类型如灭活/减毒applicable_agevarchar(50)适用年龄如“18-59岁”dose_countint接种剂次数dose_intervalint剂次间隔天数descriptiontext疫苗说明statustinyint0下架1上架create_timedatetime录入时间值得注意的一点是疫苗名称和生产厂家在现实中是一对多的关系同一款疫苗可能有多批次的货。毕设一般不需要做到批号管理那么细但为了给答辩留有余地建议冗余一个“批次信息”字段列表或者单独建一张batch表在查询接口里返回。这样被问到“如果同一疫苗有多个批次库存怎么展示和扣减”时也可以从容应对。预约记录表appointment_record字段名类型说明idbigint主键user_idbigint预约用户IDvaccine_idbigint疫苗IDappointment_datedate预约日期time_slotvarchar(20)时段如“09:00-11:00”dose_noint第几剂次statustinyint0待接种1已接种2已取消3已过期remarkvarchar(255)备注如健康码异常情况create_timedatetime预约时间update_timedatetime更新时间预约记录表是整个系统的核心表它的设计直接决定后续很多接口的复杂度。我建议在(user_id, appointment_date, time_slot)上建联合唯一索引这样从数据库层面就能杜绝同一用户在同一时段预约两次的脏数据。另外用status字段做状态机流转所有接口都围绕状态做判断比删除记录干净得多。接种点/排班表vaccination_site字段名类型说明idbigint主键site_namevarchar(100)接种点名称addressvarchar(255)详细地址open_timevarchar(50)开放时间描述max_count_per_dayint每日最大预约人数current_usedint当日已预约人数这张表与预约记录表通过site_id关联。不过这里有一个关键设计选择每日剩余名额是在排班表上直接做加减还是另建一张“日期-时段-余量”表如果是毕设我建议直接用排班表的current_used字段做扣减配合MySQL的行锁机制写起来简单性能也足够如果想体现设计水平可以拆出appointment_slot表每个时段一行记录预约时用乐观锁update余量被问到并发问题时更容易展示出思考深度。建完这几张表整个系统的数据通路基本就闭环了用户注册→登录→查看疫苗列表→选定接种点和时间→生成预约记录→扣减库存→工作人员核销接种→更新状态。数据库表之间用外键在概念层关联即可物理外键可加可不加加了写删除接口时要格外小心别被外键约束卡住。3. 后端接口设计与核心业务实现3.1 接口列表与权限划分后端接口的规划可以按照“面向用户的接口”和“面向管理的接口”两条线来理。面向用户POST /api/user/register 注册POST /api/user/login 登录GET /api/vaccine/list 获取已上架疫苗列表GET /api/vaccine/detail/{id} 获取疫苗详情GET /api/site/list?date2025-06-01 获取指定日期的可用接种点和余量POST /api/appointment/create 提交预约GET /api/appointment/myList 查看我的预约记录PUT /api/appointment/cancel/{id} 取消预约GET /api/announcement/list 获取公告列表面向管理POST /api/admin/vaccine/save 新增/修改疫苗PUT /api/admin/vaccine/status 上下架疫苗GET /api/admin/appointment/page 分页查询预约记录PUT /api/admin/appointment/complete 核销接种GET /api/admin/statistics/overview 预约人数统计POST /api/admin/site/save 维护接种点信息权限控制方面我在SpringBoot里用了一个很朴素的方案登录时后端根据账号角色生成JWTJWT里带userId和role前端请求时在axios拦截器里把Token塞进Header。后端写一个LoginInterceptor只校验Token是否存在和有效角色判断则放在Controller方法上预置一个RequireRole注解通过HandlerInterceptor逐个方法校验。这么做的好处是代码量少逻辑清晰答辩时也好解释——每个接口的权限边界一目了然。3.2 预约接口的并发与状态设计预约接口是整个项目最重要的一个接口也最容易被问到“如果两个人同时抢最后一个名额怎么办”。我实际使用的方案是“数据库行锁 原子更新”。先给排班记录加锁扣减count时使用以下SQL逻辑UPDATE vaccination_site SET current_used current_used 1 WHERE id #{siteId} AND current_used max_count_per_day这行SQL的妙处在于它是一次原子操作。MySQL在更新一行时会对该行加锁两个并发请求即使同时进来也会被串行执行第二个请求执行update时会因为current_used已经等于max_count而影响行数为0从而判断余量不足。完全不用Java代码里先select再update否则高并发下一定出现超卖。插入预约记录时同样要用联合唯一索引兜底// 伪代码示意 try { appointmentMapper.insert(appointment); return Result.success(预约成功); } catch (DuplicateKeyException e) { return Result.error(当前时段已预约请勿重复提交); }数据库唯一索引是最后一道防线即使接口层判断漏了数据库也会拦截重复的(user_id, appointment_date, time_slot)。这属于典型的“接口做校验、数据库做兜底”的双层保险。还有一点容易忽略取消预约后这个名额要能够“还回去”。业务上看如果用户上午9点取消下午的预约名额在当天仍然可以被其他人约走。因此取消预约接口不仅要修改预约记录status2还必须同步执行UPDATE vaccination_site SET current_used current_used - 1 WHERE id #{siteId}不过要注意这个扣减只在status从“待接种”变为“已取消”时执行否则重复点击取消按钮会导致余量被多释放。接口里加上状态判断只有“待接种”状态才允许流转到“已取消”修改时带上条件status0返回行数为0就说明状态已变更过无需重复处理。3.3 可用性与扩展点接种记录与统计报表除了预约主流程两个加分项非常值得做接种记录查询和管理端统计报表。接种记录可以基于预约记录做不需要单独建表我的做法是给appointment_record加一个completed_time字段工作人员完成核销时更新时间戳并置status1。用户端“我的接种记录”查询时只需select where user_id ? and status 1结果天然就是历史接种凭证附带剂次信息前端展示为卡片列表即可。统计报表方面可以用一条SQL完成核心数据的抽取SELECT vaccine_name, COUNT(*) AS total_count, SUM(CASE WHEN status 0 THEN 1 ELSE 0 END) AS pending_count, SUM(CASE WHEN status 1 THEN 1 ELSE 0 END) AS completed_count FROM appointment_record WHERE appointment_date BETWEEN #{startDate} AND #{endDate} GROUP BY vaccine_id, vaccine_name这种按疫苗维度的汇总结果后台用ECharts柱状图就能画出来视觉效果好又足够支撑答辩时的“数据可视化”论题。如果还想展示按日期的趋势图再按appointment_date分组就行同样一条SQL解决。这里真心建议不要在统计上堆砌太多接口毕设阶段有两三个图表就可以了。精力有限优先把主流程打磨顺远比做一堆半成品图表更能提升答辩通过率。4. Vue 前端页面设计与交互实现4.1 前端工程结构与路由规划前端工程我用Vue CLI创建整个src目录按功能做分层src/ ├── api/ # 所有axios请求模块 │ ├── user.js │ ├── vaccine.js │ └── appointment.js ├── router/index.js # 路由定义 ├── store/ # Vuex状态管理或Pinia ├── views/ │ ├── admin/ # 管理端页面 │ ├── user/ # 用户端页面 │ └── login.vue ├── utils/request.js # axios封装 └── main.js路由设计上我做了登录守卫和角色分流。未登录用户只能访问登录页和疫苗公告页登录后进入用户首页管理员登录后跳/admin/dashboard并渲染一套不同的侧边栏菜单。这里用到Vue Router的beforeEach钩子每次跳转读取localStorage里的Token有Token放行没有就强制转到登录页。值得一提的是主菜单要动态生成根据用户角色过滤如果只有管理员能看到的“系统管理”菜单普通用户就不应该在侧边栏出现这个体验细节很加分。关于Vue版本我建议用Vue2组件库用Element UI。Element UI的el-menu、el-table、el-form、el-dialog这四件套覆盖管理后台90%的场景。用户端则不依赖Element UI自己写样式更灵活让界面看起来更贴近真实市民服务的简洁风格。4.2 axios封装与Token管理axios封装是整个前端的公共基础工程处理不当会引发一堆连锁问题。我在utils/request.js里做了三件事第一统一请求前缀通过axios.defaults.baseURL /api这样联调和部署时不用每个接口单独改路径。第二请求拦截器自动加Token从localStorage取出token放到config.headers.Authorization字段后端通过这个字段解析用户身份。第三响应拦截器统一处理错误和401如果业务code!200直接Message.error弹出后端返回的msg如果后端返回401则清除本地Token并跳转登录页。这里有个部署相关的细节后面会讲到开发时前端端口为8080后端接口为9090存在跨域问题。我在开发环境下用Vue CLI的devServer.proxy把/api代理到http://localhost:9090前后端联调时不需要后端开启CORS部署到生产环境后前端文件由Nginx或其他Web服务托管同域名访问天然不存在跨域这一套逻辑在实践里是最干净的。Token存储不要用sessionStorage刷新页面就没了用户每次打开浏览器都要重新登录体验很差。localStorage里存着即可配合JWT的过期机制安全性和体验都能兼顾。4.3 核心页面流程拆解用户端核心流程页面大体有四个疫苗列表、预约页、预约记录、个人中心。疫苗列表页用卡片或表格展示已上架的疫苗每张卡片上显示疫苗名称、接种剂次、适用人群重点标记“有货”或“约满”。预约按钮的可用状态要和后端数据联动下架的疫苗不能点。预约页是整个前端的重头戏。用户选中某个疫苗后页面展示接种点列表每个接种点下方显示可预约日期选了日期后再展示当天可用余量。我建议时间段的展示做成表格形式列是上午/下午行是具体时段每个格子显示剩余名额点击选中后提交预约。预约记录页相对简单用列表展示用户的预约单每条显示疫苗名称、预约时间、接种点、状态待接种状态下显示“取消预约”按钮已接种状态显示“完成”。管理端这边核心页面有五个工作台、疫苗管理、预约管理、站点管理、数据统计。疫苗管理用el-table展示所有疫苗数据提供编辑弹窗、上下架按钮预约管理支持按日期、疫苗、状态筛选分页展示每一行有“核销接种”操作数据统计页用ECharts折线图和柱状图展示近一周预约趋势。页面设计上不需要刻意追求酷炫Element UI默认风格已经足够整洁。真正要花心思的是交互流程的闭环比如用户取消预约后列表里的状态要即时刷新库存也要同步变化这些联动关系在前端通过重新拉取接口实现简单直接。5. 关键业务流程闭环演示5.1 从疫苗发布到用户预约的完整时序整个业务的主链路可以这样串起来第一步管理员登录后台在疫苗管理页点击“新增疫苗”录入疫苗名称、厂家、适用年龄、剂次间隔等信息保存后疫苗状态默认为上架。第二步管理员维护接种点信息设置每日最大预约人数和开放时段。此时用户端刷新疫苗列表新疫苗就会出现。第三步用户注册并登录进入疫苗列表页点击一个疫苗的“预约接种”系统加载对应疫苗支持的接种点列表和最近几天的日期并实时显示每天余量。第四步用户选择一个日期和时段确认预约前端提交预约请求。后端此时执行前面说的“行锁扣减唯一索引兜底”成功后返回预约单信息。第五步预约当天用户到达接种点工作人员在后台搜索用户身份证号或预约单号查到待接种记录后点击“核销接种”记录状态从待接种变为已接种completed_time被写入。第六步系统根据预约记录生成接种凭证用户可在“我的接种记录”里查看第几剂次和下次接种时间。这套主链路走通后系统就有了完整的业务闭环。我建议在开发时按照这个顺序推进先做后端接口用Postman测试通过后再做前端页面效率比前后端同时铺要高得多。5.2 多剂次疫苗与时间间隔的约束逻辑流感疫苗和HPV疫苗通常不止一针所以多剂次预约是一个必须处理的场景。我的实现思路是在用户选择预约某款疫苗时后端自动查该用户最近一条“已预约或已接种”记录如果没有历史记录说明是首针允许直接预约第一剂如果有已接种记录且剂次数小于总剂次计算当前日期与上次接种日期的间隔天数若大于等于配置的dose_interval则允许预约下一剂否则直接返回“未到接种时间”。这个判断逻辑放在后端前端只是展示“可预约”或“未到时间”的提示。前端页面最好也展示出“您当前已接种第1剂下一剂可预约日期是X月X日”这样的文案既提升体验也避免用户反复试探接口。我踩过一个坑只判断了剂次没有判断同款疫苗再次接种。结果用户打完第一针第二天又去约同一款疫苗的第二针系统直接放行幸亏在测试阶段发现了。后来我在预约接口里增加了一道拦截查询该用户同类疫苗最近一条status1或status0的记录取最新一条判断间隔天数。千万不要小看这个逻辑疫苗系统的专业性很大程度上就体现在这些细节约束里。5.3 预约取消与余量回退的联动处理预约取消在业务上要考虑得比表面复杂。用户视角是“我点取消列表消失”系统视角是“预约记录状态变更 当日余量释放 如果涉及多剂次预约还要重置下次接种资格判断”。我在取消接口里实际操作如下// 伪代码 AppointmentRecord record appointmentMapper.selectById(id); if (record null) return Result.error(预约记录不存在); if (record.getUserId() ! currentUserId) return Result.error(无权操作); if (record.getStatus() 0) { appointmentMapper.updateStatus(id, 2); // 待接种 - 已取消 siteMapper.decreaseUsed(record.getSiteId()); // 余量回退 return Result.success(取消成功); } return Result.error(当前状态不可取消);注意updateStatus只针对status0做条件更新这样即使两个请求同时来取消也只有一个能成功另一个返回“当前状态不可取消”不会出现重复释放余量的问题。这种“乐观更新”的思路在整个系统多处复用比如核销接种、上下架疫苗都可以用类似的条件更新来处理。用户端取消按钮的展示也要谨慎。已接种的、已取消的、已过期的记录一律不展示取消按钮只有待接种状态才展示。前端做判断是一种防线后端再校验是第二道防线双保险缺一不可。6. 部署运行方法与常见问题排查6.1 本地开发环境配置速览环境准备这块我按最小依赖整理了一份清单JDK 1.8别用17试试SpringBoot2.7配JDK17偶尔有兼容小坑Maven 3.6MySQL 5.7或8.0Node.js 14Vue2用14/16都没问题开发者工具IDEA、VSCodeMySQL这边有个容易卡住新手的地方数据库的时区配置。在SpringBoot的application.yml里连接串建议写成spring: datasource: url: jdbc:mysql://localhost:3306/vaccine_system?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 123456serverTimezoneAsia/Shanghai不加的话查询日期字段经常差8个小时排查起来特别容易让人恼火。别问我怎么知道的数据库时区能在半夜把你逼疯。后端启动时如果遇到端口冲突在application.yml里改server.port即可默认9090。前端启动则使用npm run serve。6.2 前端打包放进SpringBoot的实操细节前端开发完毕打包时使用npm run build生成dist目录。dist目录就是一个纯静态资源文件夹有三种方式部署。最简单的一种是直接把dist目录拷贝到SpringBoot的src/main/resources/static下重新打包后端jar就能通过同一个端口访问页面和接口。这个问题实现起来简单但坑在路径上。Vue默认的publicPath是/部署到SpringBoot后可能出现静态资源404。解决方式是在vue.config.js里设置module.exports { publicPath: ./, outputDir: dist }相对路径的好处是不管部署在哪个目录下只要index.html和static目录保持相对关系资源就能正确加载。同时需要注意Vue路由如果用到history模式刷新子路由页面会404因为SpringBoot不知道如何解析前端路由请求直接落到后端返回404。最简单稳妥的办法是router里不要用history直接使用hash路由URL后面带个#号刷新不会404。如果想好看一点用history模式需要在后端加一个转发规则把所有非/api路径转发到index.htmlController public class PageForwardController { RequestMapping(value /{path:[^\\.]*}) public String forward() { return forward:/index.html; } }这个方案我在实际项目中验证过没问题但要留意不要拦截了/api开头和带.的资源路径所以上面的正则过滤掉了包含点的路径。如果不想写这些配置用hash模式最省心。6.3 高频报错与排查思路速查表我把毕设和实训里遇到过且频率最高的五类问题整理成表方便遇到时直接对照排查。现象可能原因解决方案前端请求接口报404baseURL路径不对或代理没有生效检查vue.config.js的proxy配置确认/api前缀登录成功后刷新页面登录态丢失Token存放在sessionStorage换成localStorage存储Token预约时提示“当前时段已预约”但用户从没预约过联合唯一索引中的日期比较异常检查前端传的日期字符串与后端LocalDate格式是否一致后台查询预约列表很慢没有建立索引给appointment_record的user_id、vaccine_id、appointment_date建普通索引日期显示相差8小时数据库连接的serverTimezone配置缺失在jdbc url上加serverTimezoneAsia/Shanghai前端访问后端跨域开发环境下proxy配置不正确统一用devServer.proxy不要依赖后端CORS取消预约后库存没变decreaseUsed只在status0时才执行检查接口中状态条件是否完备另外还有一类隐蔽问题容易被忽略后端返回的日期格式。默认的Date序列化结果在Vue里显示是一长串时间戳或者带T的UTC格式很不好看。建议配置统一格式化spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8再提醒一次多表关联查询时MyBatis Plus的Mapper里如果涉及到自定义SQL字段名和数据库列名的映射容易踩坑。建议使用Results注解或者开启map-underscore-to-camel-case否则查出来的实体属性全是null排查起来很浪费时间。7. 从项目到答辩的经验总结与扩展方向做到这里整个系统的核心功能已经闭环你可以自豪地说这是一个能跑、能演示、能讲清楚业务逻辑的完整项目。但如果想让答辩更从容还有几个扩展方向非常值得深入。第一个方向是消息通知。预约成功后给用户发送短信或站内消息取消预约时也通知来体现系统的体验完善度。站内信用一张表即可短信接入阿里云短信SDK也不复杂。有了这一步系统就从一个“预约工具”升级成了“有服务感知的平台”。第二个方向是数据统计的可视化增强。除了按疫苗统计还可以加入按周、按月维度的预约趋势按接种点维度统计完成率。图表的维度越多讲解业务时的故事越完整能让答辩的老师看到你具备数据分析和产品思维能力。第三个方向是“疫苗批次管理和追溯”。现实场景中疫苗从厂家到接种点有完整的冷链物流和批号管理链条。如果能给疫苗表加一个batch_no字段关联接种记录中加入批号信息讲解时就能聊“如果某批次疫苗出现质量问题如何追溯接种者”这就触及了公共卫生行业的真实痛点是很大的加分项。第四个方向是并发能力的优化。如果被问到“系统上线后访问量暴增怎么办”可以从“预约接口增加Redis分布式锁”“把排班余量提前缓存到Redis”“对高频查询接口做本地缓存”这几个角度聊。虽然毕设里不一定全实现但能讲清楚思路就已经达到加分效果了。我个人做这类全栈项目最深的感触是对学生项目而言功能多不一定加分逻辑闭环和细节取舍才真正加分。疫苗发布与接种预约这个选题天然具备“信息发布、预约建模、并发控制、状态机流转、可视化展示”这些高密度知识点把主链路做透、把设计理由讲清它不只是一份能过查重的代码更是一段你能在面试和答辩中自信讲出来的实践经历。最后再分享一个小技巧项目里所有状态值不要用裸数字散落在代码里可以定义一个常量类或枚举类统一管理比如AppointmentStatusEnum包含PENDING(0)、COMPLETED(1)、CANCELED(2)、EXPIRED(3)。这样代码可读性大幅提升也能避免你写接口时把数字搞混。把代码当作作品去打磨它会成为你简历上比任何证书都有说服力的注脚。