每年到了毕业设计最紧张的那个阶段,我就会看到好多人在同一个题目上拱来拱去——比如“健康医院门诊在线挂号系统”。SpringBoot + Vue + MySQL,源码、数据库、论文、部署文档一整套打包,这个组合几乎成了本科毕设的“标配模板”。但说实话,题目一样,做出来的东西质量和深度可以差出一大截。这篇文章不是我临时拼凑的项目说明书,而是我这两年陪跑多届毕设项目之后,把这类在线挂号系统的整体拆解、技术选型、数据库设计、并发扣号逻辑、前端联调、论文撰写和部署排坑全部摊开来复盘一遍。无论你现在是刚拿到题目还没动工,还是已经写完代码在赶论文,都可以从里面直接抄作业。
先把这个项目是什么讲清楚:它是一个典型的B端管理 + C端使用的双端系统,模拟的是医院门诊线上预约场景。患者可以在线浏览科室和医生、查看排班号源、提交预约、取消预约;医生端可以查看今日就诊名单并完成就诊操作;管理员端负责维护科室、医生、排班和统计报表。系统采用前后端分离架构,后端用SpringBoot提供RESTful接口,前端用Vue开发单页应用,MySQL负责数据持久化。对整个毕设来说,它解决的问题非常集中:把“线下窗口排队挂号”这件事搬到线上,并且把号源库存、用户预约、医生就诊这条业务闭环跑通。适合的读者也清晰——计算机相关专业要做Web开发类毕设的同学,或者想在简历里加一个完整全栈项目的初学者。
1. 项目整体设计与技术选型思路
1.1 为什么要用“在线挂号”做毕业设计
在线挂号这个题目最妙的地方,在于它看起来不复杂,却天然具备一个完整业务系统该有的所有要素:多角色权限、核心流程闭环、状态流转、库存竞争、数据统计。它不像纯商城项目那样堆砌商品和购物车,也不像博客系统那样只是CRUD四个字母,挂号系统的业务复杂度和工作量对本科阶段来说刚好卡在“做得出”和“有挑战”之间。
更重要的是,它的业务场景足够真实。你不需要向导师解释“这个系统为什么存在”,因为所有人都去医院挂过号,都知道排队难、号源紧张。场景真实意味着需求分析好写、功能边界好划、数据库设计有依据,答辩的时候老师也容易理解你的职责划分。真要做这个题目,我的建议是不要只做一个“增删改查展示页”,而是把精力压在预约的核心业务上:号源怎么扣、锁怎么防、状态怎么流转。这一段做扎实了,项目深度一下子就上去了。
1.2 技术栈选型:SpringBoot、Vue、MySQL各自的角色
先说SpringBoot。它解决的是后端开发效率问题。以前用SSH或者裸Servlet写后端,光是配置文件就够人喝一壶,SpringBoot通过自动装配和starter机制把大部分基础设施都拉齐了,你只需要关注Controller、Service、Mapper这三层业务代码。做毕设选它,一方面是因为企业招聘和研究生面试确实爱问,另一方面是因为它跟MyBatis-Plus结合起来,写增删改查能省下大量时间。
Vue这边,我认为选Vue 2还是Vue 3看个人基础和学校要求都行。Vue 2配Element-UI生态最成熟,网上资料和现成组件模板最多,遇到问题一搜就有答案;Vue 3配Element-Plus更现代,响应式性能更好,但部分老教程还停留在Vue 2,踩坑时资料没那么全。如果不是对新技术特别有执念,毕设求稳的话,Vue 2 + Element-UI也完全够用,核心思想是一样的——组件化、路由跳转、Axios请求后端、Vuex或Pinia管理登录状态。
MySQL承担的是数据持久化。挂号业务的所有数据几乎都是强关系型结构:用户、科室、医生、排班、预约记录,彼此之间有清晰的引用关系,用MySQL的InnoDB引擎来处理这类事务和约束非常合适。尤其是预约扣号这种需要“读-判断-扣减”的流程,数据库行锁和事务能保护数据不出错。
1.3 交付物结构:源码、数据库脚本、论文、部署文档怎么配合
拿到这种标题的毕业设计资源,千万别以为解压出来就能直接交,你得搞清楚这四件套各自的作用和内在关系。
源码是整个项目的运行本体,一般分backend和frontend两个目录,后端是Maven工程,前端是Vue工程。数据库脚本是建库建表和初始化数据的SQL文件,它决定了系统里默认有哪些用户、科室、医生和排班。论文是把整个项目从需求分析到测试验收写成文字版,也是你毕设得分的重头戏。部署文档则是环境配置、打包步骤、启动命令、Nginx反向代理这些运维层面的内容,一般还能顺带作为答辩演示的检查清单。
如果你拿到的是别人整理的完整资源,我强烈建议你先按部署文档跑通一遍,再逐步改写成自己的设计。直接改个名字就交,论文和代码对不上,答辩一问就露馅。正确做法是:先玩透系统,再按自己的理解重新梳理论文,把数据库表、接口、页面截图替换成与自己本地运行一致的结果。
2. 系统核心模块与角色功能拆解
2.1 三种角色的权限边界:患者、医生、管理员
在线挂号系统的用户角色基本可以固定为三类,权限模型用一张user表加role字段就能搞定,简单清晰,毕设阶段完全够用。我见过有人把三种角色拆成三张独立表,结果登录校验和关联查询绕了一大圈,其实没必要。
患者角色能做的事:注册、登录、浏览科室与医生、查看医生排班、提交预约、取消预约、查看个人预约记录和就诊状态。医生角色在患者功能基础上,还可以查看自己某天的排班以及预约了某个时段的患者列表,对患者完成就诊操作。管理员则是最高权限,负责科室信息的增删改、医生信息的维护、医生排班的生成与调整、号源总数设置、系统数据的统计查看。
实现权限控制时,前端和后端都要管。前端用Vue Router的meta信息配合beforeEach守卫,根据localStorage里的role字段控制页面能否访问;后端在拦截器里校验登录态,同时针对敏感接口做角色判断。别只依赖前端隐藏菜单,接口直接暴露的话,别人绕过页面照样能调。
2.2 患者端功能细节:从找医生到预约完成
患者端的核心路径是:登录 -> 首页选择科室 -> 科室下查看医生列表 -> 点进医生详情查看排班 -> 选择日期和时间段 -> 提交预约 -> 在“我的预约”里查看状态或取消。
这一步做产品设计的时候,要注意降低用户选择成本。比如科室列表可以带一个icon和科室简介,医生列表要展示头像、职称、擅长领域,排班表用日历加时间段的形式展示会比一个平铺表格要直观得多。预约提交时建议让用户二次确认,尤其是日期、时间段、挂号费这几个关键信息,提交成功之后弹一个带预约流水号的结果页,能大大提升真实感。
搜索功能虽然看起来是加分项,但实际很有用。你可以做一个组合搜索框,支持输入科室名称或者医生姓名,用MyBatis-Plus的like条件做模糊匹配。这个点虽然简单,但在论文里可以写进“系统功能需求”,答辩时也算一个亮眼的小功能。
2.3 医生端与管理员端:后台管理的核心逻辑
医生端和管理员端在功能上偏向“管理”,UI结构可以采用侧边栏布局。
医生端页面主要有:工作台(今日接诊概览)、排班查询、我的患者列表。点进患者列表后能看到每个患者的姓名、手机号、预约时段、预约号,旁边放一个“完成就诊”按钮。操作上要设计一个合理的状态流:预约成功后状态为待就诊,医生点击完成就诊后变为已完成,同时把患者信息标记为已处理。
管理员端功能要多一些:科室管理、医生管理、排班管理、数据统计。排班管理是整个后台最重要的一部分,管理员要先选医生、再选日期、再选时间段,同时设置该时间段的号源总数,或者直接按周模板批量生成排班。统计报表可以用ECharts画一个近7日预约量折线图和科室预约占比饼图,数据通过后端接口从预约表和排班表聚合而来。
2.4 完整业务流程串联:用户视角下的闭环
把流程串起来看会更清楚,我按一个患者第一次使用系统来走一遍:
患者注册并登录,进入首页选择“骨科”进入医生列表,看到李医生周三上午有余号,于是点预约,选“08:30-09:30”时段,系统检查剩余号源大于0,扣减一个号源,生成一条state为待就诊的预约记录。周三当天医生在医生端看到今日预约名单,患者到院后由医生点击完成就诊,状态变为已完成,号源记录保留不做回滚。如果患者在就诊前一天想取消,点取消按钮后预约状态变成已取消,同时排班表的剩余号源加1,供其他患者重新预约。
这个流程里最需要注意的就是“扣号”和“回滚”的闭环。很多同学只做了预约扣号,没做取消回滚,结果测试时发现号越挂越少。状态机思想在这里非常重要:预约记录有明确的初始状态、结束状态和流转条件,每次状态变更都在事务内完成,数据才可靠。
3. 数据库设计与核心表结构规划
3.1 数据模型与ER关系设计
在线挂号系统的实体不算多,核心实体是用户(user)、科室(department)、医生(doctor)、排班(schedule)、预约记录(appointment),有需要的话可以考虑加一个公告表或者管理员操作日志表。
实体之间的关系也比较直观:一个科室下有多个医生,一个医生有多个排班,一个排班可以被多个患者预约,一个患者可以有多条预约记录。画ER图时把这些关系连好,一篇论文的数据设计部分就站得住脚了。
关于user表和doctor表的关系,我见过两种做法。第一种是user和doctor完全分开,医生有自己的账号和医生信息表;第二种是只建一张user表,用role字段区分患者和医生,医生信息另外建一张doctor表,通过user_id关联。我比较推荐第二种,因为登录校验只需要查一张表,权限角色判断也更方便,同时医生的特有字段(科室、职称、擅长、简介)单独放doctor表,互不干扰。
3.2 核心表结构:user、department、doctor、schedule、appointment
下面给出一个可以直接参考的表结构设计思路,字段名和注释建议按这个风格来,清爽且容易翻译成论文里的表格。
user表(用户表)。核心字段:id、username、password、real_name、id_card、phone、role、avatar、create_time。password需要存BCrypt加密后的密文,role可以是1患者、2医生、3管理员。id_card属于敏感信息,但在医院场景里是合理字段,做毕设时注意脱敏显示即可。
department表(科室表)。核心字段:id、dept_name、dept_desc、location、create_time。location字段可以存“门诊楼3层302室”这类科室位置,能给系统增加一点真实感。
doctor表(医生表)。核心字段:id、user_id、dept_id、doctor_title、specialty、intro、avatar。dept_id关联科室表,doctor_title存主治医师/副主任医师这类职称,specialty存擅长领域,方便前端展示。
schedule表(排班表)。核心字段:id、doctor_id、work_date、time_slot、fee、total_slots、remain_slots、status。time_slot表示时间段,可以存“08:30-09:30”这种字符串,也可以用编号区分上午段和下午段。total_slots是总号源数,remain_slots是剩余号数,两者结合能支持号源统计。
appointment表(预约记录表)。核心字段:id、user_id、schedule_id、doctor_id、dept_id、appoint_no、appoint_time、visit_date、time_slot、status、remark。appoint_no可以生成一个业务流水号,比如日期加随机数。status用0待就诊、1已完成、2已取消。
3.3 关键索引与约束设计
表设计完了,下一步是索引和约束,这块很多毕设项目会忽略,但论文里写一笔是很加分的。
schedule表要建索引:医生ID(doctor_id)和就诊日期(work_date)联合索引,用于快速查询某医生某天的排班;appointment表要建唯一索引:user_id和schedule_id联合唯一,用来防止同一个用户对同一个排班重复预约。这个唯一索引是业务层面的硬约束,能配合代码做双重校验。
外键我建议不要物理启用,保持逻辑外键即可。也就是说表结构里不声明FOREIGN KEY,而是在代码里根据ID去关联查询。原因有两个:一是MyBatis-Plus处理逻辑删除时会受物理外键制约,二是物理外键在数据量大时会影响插入性能。你只要在数据库设计文档里画出关系,说明是逻辑关联,完全没问题。
3.4 号源库存与预约状态的流转规则
号源数和预约状态是整个系统最核心的数据词。
排班表的total_slots表示这个时段总共有多少号源,remain_slots表示还剩几个。每次预约成功要扣1,取消要回滚加1。这里要特别注意,剩余的号源不能小于0,需要在更新语句里加条件约束。
预约记录的status建议设计成几个可枚举的整型:0待就诊、1已完成、2已取消。状态流转规则要清晰:预约创建时置为0,医生完成就诊后置为1,用户在截止时间前取消则置为2。为了做时间限制,可以加一个取消截止时间字段,比如规定就诊前一天18点前允许取消;没有截止时间的话,用户就诊前一天下午还占着号源,系统就不太真实。
4. 后端关键实现:认证、排班、预约扣号与事务
4.1 JWT认证与拦截器设计,为什么不用Session
在线挂号这类前后端分离项目,登录状态我首选JWT。核心原因是后端接口要面向不同端口的前端服务,用Session需要处理跨域Cookie、存储共享这些麻烦事,而JWT是无状态的,token由前端持有,后端只负责签发和验签。
具体实现上,登录接口接收用户名和密码,用BCrypt校验密码,校验通过后用jwt工具类生成token,荷载里放userId和userRole,设置过期时间比如7200000毫秒(2小时)。前端把token存到localStorage,每次请求在Axios拦截器里加Authorization头。后端做一个拦截器,排除登录、注册、静态资源这些白名单路径,其余请求都校验token,解析出用户信息后放到ThreadLocal里,方便Service层获取当前用户ID。
为什么不直接每个接口传userId?因为接口暴露太随意,容易越权。通过token解析出的ID更安全,而且前端代码也更干净,不用到处拼参数。
4.2 排班生成与查询接口
排班有两种生成方式:管理员手动生成,或系统按规则批量生成。毕设阶段建议先做手动生成接口,也就是管理员在后台选择一个医生、一个日期、一个时间段,填入号源总数,提交后生成一条排班。如果你想在论文里写亮点,可以加一个“按周模板一键生成”功能,把每周的出诊模板存到数据库,跑一个循环批量插入下周排班。
查询排班的接口是患者端使用频率最高的接口。按科室查医生、按医生查排班、按日期过滤时间段,一般需要联表查询,返回的数据结构包含医生姓名、职称、科室名、时间、号源剩余情况。这里要注意分页参数和剩余号数大于0的条件。
4.3 预约扣号的核心代码与并发保护实操
预约扣号是整个系统最容易出错的点,也是答辩时老师最爱追问的点。新手最容易踩的坑是这样写的:先select查一下剩余号数,判断大于0,再update减1。这段逻辑在并发情况下会出问题——两个用户同时查到同一个排班剩余5个号,都判断大于0,然后都执行减1,最终只剩3个,但产生了两个预约成功记录,这叫超卖。
正确做法是把判断和扣减放在一条SQL里,依靠数据库的行锁来保证只有一个人能成功扣减:
// 排班Mapper中定义扣减方法 int decreaseRemainSlots(@Param("scheduleId") Long scheduleId); // XML中的SQL,条件里带上remain_slots > 0 <update id="decreaseRemainSlots"> update schedule set remain_slots = remain_slots - 1 where id = #{scheduleId} and remain_slots > 0 </update>Service层代码是这样组织的:
@Transactional(rollbackFor = Exception.class) public AppointmentDTO bookAppointment(AppointmentCreateDTO dto) { // 1. 判断排班是否存在且在可预约时间范围内 Schedule schedule = scheduleMapper.selectById(dto.getScheduleId()); if (schedule == null) { throw new BusinessException("排班不存在"); } // 2. 原子扣减号源 int rows = scheduleMapper.decreaseRemainSlots(schedule.getId()); if (rows == 0) { throw new BusinessException("手慢了,号源已被抢完"); } // 3. 创建预约记录 Appointment appointment = new Appointment(); appointment.setUserId(CurrentUser.getId()); appointment.setScheduleId(schedule.getId()); appointment.setDoctorId(schedule.getDoctorId()); appointment.setStatus(0); appointment.setAppointNo(generateAppointNo()); appointmentMapper.insert(appointment); // 4. 返回结果 return buildResult(appointment); }这段逻辑里有两层保护:MySQL在更新某一行时会对该行加排他锁,并发请求下第二个更新会等待,等到第一个事务提交后,它再执行update时发现remain_slots已经是0,于是rows为0,直接抛出业务异常。@Transactional保证扣减号和插入预约记录要么同时成功,要么同时回滚,不会出现号扣了但预约没生成的情况。
如果你的毕设想往分布式方向扩展,可以再加一层Redis分布式锁,先抢锁再操作数据库。但对这个项目来说,单机部署情况下上面的原子扣减方案已经够稳,而且论文里从这个角度讲并发控制,比堆一堆没跑过的方案要真实得多。
4.4 取消预约与号源回滚的注意事项
取消预约的逻辑核心是“先校验状态,再改状态,最后回滚号源”。
只允许取消status为0(待就诊)的预约,已经完成或已经取消的不允许重复操作。需要做一个时间校验,如果系统配置了取消截止时间,比如就诊前一天18:00前可以取消,那么要在执行前比较当前时间和截止时间。
业务代码同样要加事务。流程是:查询预约记录,判断归属人是否为当前用户(防止越权取消别人的号),判断状态字段,然后执行UPDATE appointment SET status = 2 WHERE id = ? AND status = 0,受影响行数为1才执行号源回滚,即update schedule set remain_slots = remain_slots + 1 where id = ?。
这里用“WHERE status = 0”这种条件更新,也是一种乐观锁思路,防止用户双击按钮或者两个请求同时到达造成重复取消。
5. 前端页面与前后端联调实践
5.1 前端工程结构怎么组织更清晰
Vue前端工程我建议的目录结构是这样的:src/views下按角色拆分页面,比如patient、doctor、admin三个文件夹;src/api下按模块封装接口请求函数;src/router里集中配置路由和路由守卫;src/store里管理登录用户信息。
这种按角色划分的方式能让多人协作或自己后期维护时迅速定位代码。组件方面,患者端可以复用医生卡片组件、排班表格组件、预约弹窗组件;管理端可以复用表格加搜索条这类后台布局。
组件复用的另一个好处是论文里的系统实现截图会比较统一,不会东一块西一块风格各异。
5.2 患者端关键交互与Axios请求封装
患者端的核心页面用Element-UI做起来相当快。首页可以用一个搜索框加科室卡片列表,点击科室跳转到医生列表页;排班表用表格展示日期、时间段、剩余号数、挂号费,剩余号数大于0时,“预约”按钮才可点击。
Axios请求要做统一封装。我一般封装一个request.js文件,里面创建axios实例,设置baseURL,在请求拦截器里加token,在响应拦截器里统一处理业务错误码。后端返回的数据结构建议统一为{ code: 200, message: "成功", data: {} }这种格式,前端判断code不是200就直接弹出错误提示,不用每个接口单独写异常逻辑。
预约提交的交互细节:点击预约按钮先弹确认框,展示医生姓名、日期、时间段和挂号费;点击确认后请求后端,成功提示“预约成功”,失败提示具体原因(比如号源不足或重复预约),然后刷新排班列表。
5.3 管理端统计报表的图表数据如何来
统计报表的图表展示不复杂,难点是后端怎么把数据聚合好。比如近7日预约量折线图,后端接口可以写一条SQL,按appointment表的appoint_time字段,用DATE_FORMAT按天分组统计数量:
SELECT DATE_FORMAT(appoint_time, '%Y-%m-%d') AS day, COUNT(*) AS total FROM appointment WHERE appoint_time >= #{startTime} GROUP BY day ORDER BY day科室占比饼图则需要join一下department表,按科室统计预约数量。这里要注意时间字段的时区问题,建议使用LocalDateTime并统一服务器时区,避免前端展示差8小时的怪现象。
统计接口建议独立放在admin模块下,只允许管理员角色访问,前端路由和按钮也配合做权限隐藏。
5.4 前后端联调中一定会遇到的那几个问题
前后端联调的时候,最常遇到的问题我基本都遇过一遍。一个是跨域问题,前端跑8080端口,后端跑9090端口,浏览器会拦截。要么在后端写一个全局CORS配置类,允许所有来源跨域;要么在本地开发时用Vue CLI的proxy配置把/api代理到后端地址。我建议两种方法都掌握,本地用proxy更接近线上表现,后端写CORS也顺手。
第二个是LocalDateTime格式问题。如果没有配置Jackson序列化,LocalDateTime默认会输出一串数组,前端根本没法用。需要加统一配置,或者给字段加@JsonFormat注解:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime appointTime;第三个是token失效之后页面还在显示数据。Axios响应拦截器里遇到401状态码要清理本地存储并跳转登录页,同时用Message提示“登录已过期,请重新登录”,否则用户会一头雾水。
6. 论文撰写、部署打包与常见问题排障
6.1 毕业设计论文章节结构怎么安排
在线挂号系统的论文结构大致是这样的:第一章绪论(背景意义、国内外研究现状、论文结构);第二章相关技术介绍(SpringBoot、Vue、MySQL、Element-UI等);第三章需求分析(可行性分析、功能需求、非功能需求、用例图);第四章系统设计(架构设计、功能设计、数据库设计、ER图、接口设计);第五章系统实现(按角色分模块展示截图和核心代码);第六章系统测试(测试环境、测试用例、测试结果分析);最后一章是总结与展望。
各章节的字数分配心里要有数:摘要一般300到500字,需求分析1500到2000字,系统设计3000到4000字,系统实现3000到4000字,测试部分1500到2500字。核心设计部分是本钱,不要把所有篇幅都花在技术介绍上,老师最反感大段复制技术博客的“相关技术”章节。
画图建议用专门的绘图工具,ER图、用例图、时序图、活动图都画出来。图表是论文的骨架,逻辑清楚的话,后面写文字只是填充血肉。
6.2 打包部署:本地到服务器的完整流程
部署这块,我给一个最稳的路径。后端用Maven打包:mvn clean package -DskipTests,得到Jar包。打成Jar包比WAR包省事,不用配外部Tomcat。前端在项目根目录执行npm run build,生成dist静态文件夹。本地测试时可以装一个Nginx,把dist目录指向Nginx的root,同时配置/api反向代理转发到后端的9090端口。服务器部署更简单,配置好JDK、MySQL、Nginx之后,把Jar包和dist文件夹传到服务器上就行。
Nginx的核心配置写出来供参考:
server { listen 80; server_name your-server-ip; root /opt/app/dist; index index.html; location /api/ { proxy_pass http://127.0.0.1:9090; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location / { try_files $uri $uri/ /index.html; } }这个配置里最重要的一项是try_files指令。如果你的前端路由用history模式,不写这句的话,在某个子路由页面刷新一下就会变成404。这是一个极少有配置文档会主动提醒你、但实际部署必踩的坑。
后端application.yml建议通过profiles区分开发环境(dev)和生产环境(prod),生产库的连接地址、账号密码单独配置,不要把测试库和正式库混在一起。数据库初始化直接用source命令导入SQL脚本,注意MySQL 8和MySQL 5在驱动配置上不一样:
spring: datasource: url: jdbc:mysql://localhost:3306/hospital_app?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=Asia/Shanghai username: root password: your_password driver-class-name: com.mysql.cj.jdbc.Driver6.3 常见问题排查速查表
下面整理一份我实际运行这类项目时碰到过的高频问题,直接对照着查,能省大量百度时间。
| 问题现象 | 可能原因 | 解决办法 |
|---|---|---|
| 后端启动失败,数据库连接报错 | 账号密码不对、端口不通、MySQL没启动 | 先用数据库客户端连接测试,确认网络和账号权限 |
| 数据库中文乱码 | 连接串没指定编码或建库不是utf8mb4 | 建库时指定utf8mb4,连接串加characterEncoding=utf8mb4 |
| 前端请求接口报跨域 | 后端没处理CORS,或前端代理没配置 | 后端写CORS配置类,或开发环境用proxy代理 |
| 预约并发时号源超卖 | 旧代码先查询再更新 | 改用上面第4.3节的原子扣减SQL |
| 接口返回的时间是数组或格式不对 | LocalDateTime序列化问题 | 加@JsonFormat注解或统一配置Jackson |
| 前端打包上线后刷新404 | 没配置try_files | Nginx配置里加try_files $uri $uri/ /index.html |
| 端口被占用 | 上次进程没关掉 | Windows用netstat -ano查PID并kill,Linux用lsof -i:端口 |
| token过期后前端无反应 | 响应拦截器没统一处理401 | 在Axios拦截器里跳转登录页并清空本地缓存 |
6.4 时区、路径和安全这些容易忽略的细节
最后说几个不算报错但影响体验的细节。时区问题一定配好,数据库连接串、服务器系统时区、Jackson序列化时区三处保持一致,推荐统一用Asia/Shanghai。上传图片如果用了本地上传方案,注意保存路径要可配置,不要写死绝对路径,前后端静态资源映射也配置好,否则部署到服务器后头像和科室图片全挂。
密码存储一定要用加密。明文密码一旦被老师抽查到,整个项目的专业分都会受影响。BCrypt是Spring Security里默认支持的加密方式,不用引入整个Security框架也能单独用。管理端登录建议加验证码,虽然只是几行代码,但在论文的“系统安全设计”小节里可以写上一笔,让安全设计不是空话。
带完这么多届类似的项目,我个人最深的体会是:在线挂号这个题目能覆盖的知识点其实比想象中扎实,从权限设计到库存管理,从接口联调到状态流转,每一环都能讲出技术点。很多同学做得不够好的地方,不在于功能少了多少页面,而在于核心链路没有做稳。预约能不能防超卖、取消能不能正确回滚、权限能不能控制到位,这三个问题只要你能在白板上给老师画清楚,答辩基本就稳了。如果你时间还够,可以再往智能推荐、在线报告查询、多院区支持这些方向延伸,但前提永远是把挂号、排班、号源这条主线做扎实。这个项目的扩展空间很大,把一个成熟的骨架吃透,后面再想往上加什么功能,都只是顺势而为的事。