刚带完一届毕业设计里面就有三个学生不约而同选择了“基于SpringBoot的智慧医疗平台”这个方向。说实话这个题目放到前几年可能还有点追热点但放在今年它已经从一个“看起来高级”的毕设选题变成了一个真正能落地、有业务深度、还能在答辩时讲出东西来的实战项目。原因很简单它天然包含了多角色权限、高并发预约、敏感数据安全、在线支付与问诊流程等一堆真实工程问题而这些恰恰是SpringBoot这个框架最能发挥优势的场景。这篇内容我打算不只是给你贴代码而是把整个“基于SpringBoot的智慧医疗平台”从选题拆解、功能设计、数据库建模、核心技术点落地到常见坑位完整梳理一遍。不管你是准备拿它做毕业设计还是工作中要接手类似的互联网医院项目都可以参考并且能直接复用。我尽量用做过项目的人的口吻来讲该有的细节一个不少。1. 项目梳理与设计思路1.1 智慧医疗平台到底在解决什么问题先别急着建工程、写Controller得先想明白你做的这个系统业务上是给谁用的、解决的是什么痛点。我用一句话总结“智慧医疗平台”的本质它是在传统就医流程之上用互联网手段把挂号、问诊、缴费、报告查询、复诊随访这些环节搬到线上同时把区域内多家医疗机构的健康数据打通让医生能跨院调阅患者档案让患者少跑腿。这也是为什么标题里会有“互联网医院综合服务平台”“区域医疗健康信息管理”“远程诊疗系统”这三个关键词。它们并不是三个割裂的系统而是一个平台的三层能力互联网医院面向患者端的在线服务入口包括预约挂号、在线问诊、报告查询、药品配送。区域医疗健康信息管理面向区域内医疗机构的数据汇聚与共享包括居民健康档案、电子病历、检验检查结果的互联互通。远程诊疗系统面向医生端与医联体协作场景包括远程会诊、双向转诊、影像阅片、视频问诊。毕设能不能拿高分很大程度上取决于你对这三层关系的理解是否清晰。如果你只做一个“挂号系统”那和十年前的课程设计没有区别但如果你能把在线问诊、健康档案、预约挂号、医生排班这几个模块真正串起来形成一个业务闭环那这个项目就能在答辩时讲出“平台级”的感觉。1.2 技术选型为什么是SpringBoot而不是别的很多同学在选型时会有困惑现在微服务那么火毕设是不是得上Spring Cloud Alibaba我的建议是分情况。如果你的题目是“基于SpringBoot的智慧医疗平台”那核心框架锁定SpringBoot是合理的。SpringBoot的优势在于它把Spring生态的繁琐配置做了大量简化让你能集中精力去实现业务逻辑而不是花两周时间折腾XML配置。再加上内嵌Tomcat、自动装配、Starter机制、Actuator监控这些特性对一个中小型平台来说刚刚好。而Spring Cloud那套服务注册发现、配置中心、网关、熔断更适合多团队、多服务、大规模流量的场景。作为毕设单体应用的SpringBoot工程反而更容易把业务做深做透。我通常会建议学生做成“单体优先、模块化拆分”的结构一个Maven多模块工程按功能拆成common、system、business、api这几个模块后续真要拆微服务边界也已经画好了。选型的时候还有一个容易忽略的点版本问题。SpringBoot 2.x和3.x差异不小尤其3.x强制要求JDK17并且底层是Jakarta EE命名空间(javax改成了jakarta)。目前大部分高校的毕设环境和开源资料仍然以2.7.x为主我建议不要盲目追新。用SpringBoot 2.7.13这个版本配JDK8或者JDK11网上资料多出了问题也好排查。1.3 整体功能模块规划这个平台的用户角色我建议至少有四类患者、医生、管理员、运营人员。四类角色对应四种不同前端入口和权限粒度。患者端微信小程序或H5核心功能是注册登录、实名认证、预约挂号、在线问诊、报告查询、缴费、健康档案查看。医生端Web端或App端核心功能是排班管理、问诊接诊、电子病历书写、开立处方、检验检查申请、远程会诊发起。管理后台超级管理员、医院管理员、科室管理员核心功能是机构管理、科室管理、医生审核、号源池管理、数据统计。运营端内容发布、公告管理、满意度回访、投诉处理。这里我特别想提醒的是毕设的评分点往往不在于功能多而在于“完整闭环”。比如你做在线问诊就不能只是发个消息至少要有“问诊订单生成 - 医生接诊 - 图文对话 - 医生书写病历 - 开立处方 - 患者确认缴费 - 药品配送或到院自取”这样一个全流程。任何一个环节断了答辩老师一追问你就会露出破绽。2. 数据库设计与核心表结构2.1 数据库选型与字符集规范平台数据以关系型数据为主推荐使用MySQL 8.0。建库时统一使用utf8mb4字符集和utf8mb4_general_ci排序规则。注意utf8mb4和utf8是有本质区别的utf8在MySQL里最多支持3字节存不了emoji表情而患者昵称、签名里可能出现emoji用utf8就会报错。数据库命名规范也值得花两分钟统一一下。表名我习惯用业务域前缀比如sys_user、sys_role、his_doctor、his_patient、reg_schedule、reg_order、diag_consult、emr_record、med_prescription。一个清晰的命名规范能让后端的Mapper.xml和Entity类可读性提升一大截。2.2 核心业务表设计思路我挑几张最关键的表来拆解一下设计思路。用户体系相关表建议把用户基础信息和角色扩展信息分开。sys_user表只存登录凭证包括user_id、username、password、phone、status、create_time这些字段his_patient表和his_doctor表分别存患者和医生的扩展信息比如患者的身份证号、医保卡号、过敏史医生的执业编号、所属科室、职称、排班状态。这样设计的好处是角色可以扩展以后加一个“药师”角色不用动sys_user表。号源排班与预约挂号表这是整个平台并发压力最大的表。reg_schedule表记录某个医生某一天某个时间段的排班字段包括schedule_id、doctor_id、dept_id、schedule_date、time_slot、total_slots、remain_slots、status。reg_order表记录患者的预约订单包括order_no、patient_id、schedule_id、visit_status、pay_status、create_time。最关键的是预约操作一定要在事务里同时完成“插入订单”和“扣减号源”两个动作而且要加行锁防止超卖。这个问题我后面在并发控制里专门讲。问诊与病历表diag_consult表记录一次在线问诊会话包含consult_id、patient_id、doctor_id、consult_type、status、start_time、end_time。emr_record表是电子病历主表包含emr_id、visit_id、patient_id、doctor_id、chief_complaint、present_illness、diagnosis、advice这些字段。这里我建议加上一个version字段做乐观锁因为病历可能被多次修改没有版本控制就会出现“覆盖丢失”。处方与支付表med_prescription表是处方主表med_prescription_item表是处方明细。处方表和问诊表是一对一关系和药品库存表是多对多关系。支付订单表pay_order建议独立出来包含order_no、biz_type、biz_order_no、amount、pay_status、pay_channel、pay_time。把支付单和业务单分离是电商系统里非常成熟的做法好处是后续对账清晰一个业务单允许多次支付尝试也不会污染业务数据。2.3 权限模型设计RBAC加数据权限平台涉及患者隐私和医生执业数据权限控制不能马虎。基础模型用RBAC也就是用户-角色-权限的三级模型。sys_user和sys_role之间是用户角色关联表sys_role和sys_menu之间是角色菜单关联表。认证方式用JWT登录成功后把用户ID和角色集合写进token后端通过拦截器解析token并校验接口权限。但光有RBAC还不够数据权限也要处理。比如一个医生只能看自己患者的病历一个科室主任可以看本科室所有医生的排班一个医院管理员只能维护本医院的科室和医生。我的做法是设计了一个DataScope注解在Service层方法上标注数据权限级别然后在MyBatis的SQL中动态拼接机构过滤条件。这样能避免一个医生通过修改请求参数越权查看其他医院的数据。3. SpringBoot核心技术点落地3.1 理解自动配置与Starter机制问十个SpringBoot面试题九个会问自动装配原理。在做项目的过程中我建议你亲手验证一下这个机制而不是只背结论。当你启动一个SpringBoot应用时SpringBootApplication注解会自动引入EnableAutoConfiguration。这个注解通过Import导入AutoConfigurationImportSelector它会扫描所有jar包中META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件把里面的配置类全部加载进来。但加载不等于生效每个配置类基本都有ConditionalOnClass、ConditionalOnMissingBean之类的条件注解。比如DataSourceAutoConfiguration只有当classpath下存在javax.sql.DataSource类并且容器中还没有用户自定义的DataSource时它才会自动配置一个连接池。理解这个机制至少有三个实际用处排查“为什么我配了数据源但没生效”这类问题时能知道从ConditionEvaluatedReport里看命中条件。自己写一个Starter给别人用的时候知道怎么通过AutoConfiguration.imports文件注册。面试被问到“SpringBoot为什么简化了配置”时能给出准确的底层答案。3.2 常用注解与分层规范在项目里我习惯严格分成五层Controller层、Service层、Mapper层、Entity层、DTO/VO层。每个层级的职责边界要清楚。Controller层只做参数接收和结果封装不要写业务逻辑。统一返回Result 对象包括code、message、data三个字段。Service层做业务逻辑编排加上Transactional声明式事务。Mapper层只做数据访问。DTO是入参对象VO是出参对象Entity是数据库映射对象三者不要混用。为什么强调这个因为很多毕设代码把Entity直接返回给前端导致用户的密码哈希、手机号、身份证号这些敏感字段全部暴露在接口响应里。正确做法是用VO剔除敏感字段后再返回。RestController RequestMapping(/api/v1/patient) public class PatientController { Resource private PatientService patientService; GetMapping(/profile) public ResultPatientProfileVO getProfile(RequestParam Long patientId) { PatientProfileVO profile patientService.getProfile(patientId); return Result.success(profile); } }Service public class PatientServiceImpl implements PatientService { Resource private PatientMapper patientMapper; Override Transactional(rollbackFor Exception.class) public PatientProfileVO getProfile(Long patientId) { Patient patient patientMapper.selectById(patientId); if (patient null) { throw new BizException(患者不存在); } // Entity转VO剔除敏感字段 return PatientProfileVO.fromEntity(patient); } }3.3 多数据源与读写分离配置智慧医疗平台里“区域医疗健康信息管理”这个模块免不了要对接多个数据库。比如用户库、业务库、日志库或者一个前置机库和一个主业务库。SpringBoot本身默认单数据源多数据源需要自己配置。我的做法是用ConfigurationProperties配合MapperScan指定不同包下的Mapper走不同数据源。核心思路是定义两个DataSource Bean一个primaryDataSource一个secondaryDataSource然后通过Primary标记主数据源再为另一个数据源指定独立的SqlSessionFactory。Configuration public class DataSourceConfig { Bean Primary ConfigurationProperties(prefix spring.datasource.primary) public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } Bean ConfigurationProperties(prefix spring.datasource.secondary) public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } Bean Primary public SqlSessionFactory primarySqlSessionFactory( Qualifier(primaryDataSource) DataSource dataSource) throws Exception { SqlSessionFactoryBean factoryBean new SqlSessionFactoryBean(); factoryBean.setDataSource(dataSource); return factoryBean.getObject(); } }然后通过MapperScan(basePackages com.hospital.business.mapper, sqlSessionFactoryRef primarySqlSessionFactory)和MapperScan(basePackages com.hospital.region.mapper, sqlSessionFactoryRef secondarySqlSessionFactory)把不同包的Mapper路由到不同数据源。这里有一个坑如果你同时引用了多个数据源SpringBoot的DataSourceAutoConfiguration会自动配置逻辑如果你不加Primary标记启动时会出现“Expected single matching bean but found 2”的报错。所以多数据源场景下Primary必须明确。3.4 定时任务在平台中的实际应用智慧医疗平台里有两个场景必须用定时任务一个是预约挂号“超时未支付自动取消并释放号源”另一个是医生排班“次日号源自动放号”。我用SpringBoot自带的Scheduled注解来完成没有引入Quartz。原因是这两个任务都是单机、单任务、逻辑简单Scheduled足够。如果后续要分布式部署再考虑引入XXL-JOB。Component public class OrderTimeoutTask { Resource private RegOrderService regOrderService; Scheduled(cron 0 */5 * * * ?) public void cancelTimeoutOrders() { // 查询创建超过30分钟且未支付的预约订单 ListRegOrder timeoutOrders regOrderService.listTimeoutOrders(30); for (RegOrder order : timeoutOrders) { regOrderService.cancelOrder(order.getOrderId(), 超时未支付系统自动取消); } } }cron表达式是定时任务的灵魂五段和六段的区别、?和*的区别、星期和日不能同时指定这些基本概念得搞清楚。比如“0 */5 * * * ?”表示每5分钟触发一次而“0 0 1 * * ?”表示每天凌晨1点触发。还有一个容易忽略的点Scheduled默认是单线程串行执行的。如果一个任务跑太久会阻塞其他任务的执行。解决方法是在配置类里设置一个线程池或者加上Async注解。4. 核心业务模块的实现与难点攻坚4.1 在线问诊模块不只是聊天在线问诊是互联网医院的核心业务。很多学生以为就是做一个WebSocket群聊这是大误区。在线问诊本质上是“异步加同步混合”的医疗咨询流程。我实现的流程是患者在问诊页面选择科室和医生创建问诊订单并支付或使用免费咨询券医生端收到待接诊提醒点击接诊后双方进入图文会话。会话通过WebSocket实现消息推送消息内容同时落库到message表保证历史记录可追溯。医生在会话中可以发起“开立电子病历”和“开立处方”操作患者端收到通知后可查看并确认缴费。这里的技术难点有两个。第一个是会话状态管理一次问诊有“待支付、待接诊、进行中、待评价、已完成、已关闭”六个状态每个状态之间流转都有严格校验不能出现“待支付直接变成已完成”这种逻辑漏洞。第二个是WebSocket的鉴权WebSocket握手时拿不到Header里的JWT所以需要在握手拦截器中解析token校验通过后才允许建立连接。public class WebSocketAuthInterceptor implements HandshakeInterceptor { Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, MapString, Object attributes) { if (request instanceof ServletServerHttpRequest) { ServletServerHttpRequest servletRequest (ServletServerHttpRequest) request; String token servletRequest.getServletRequest().getParameter(token); // 解析JWT校验身份 if (token ! null JwtUtil.validateToken(token)) { attributes.put(userId, JwtUtil.getUserId(token)); return true; } } return false; } }4.2 预约挂号模块并发控制的经典战场预约挂号的业务逻辑不复杂但是并发场景很典型。同一个医生的号源数量有限比如上午放30个号如果30个患者同时点预约系统必须保证只有30个人能成功剩下的人拿到“号源不足”的提示。最危险的写法是先查号源是否充足再插入订单再更新号源余量。这种“先查后写”的模式在并发场景下一定会超卖。正确做法是直接执行带条件的更新语句让数据库的行锁来保证原子性。Transactional(rollbackFor Exception.class) public RegOrder createOrder(Long scheduleId, Long patientId) { // 扣减号源只有当余量大于0时才更新成功 int updated regScheduleMapper.decreaseRemainSlots(scheduleId); if (updated 0) { throw new BizException(号源不足预约失败); } // 创建挂号订单 RegOrder order new RegOrder(); order.setOrderNo(generateOrderNo()); order.setScheduleId(scheduleId); order.setPatientId(patientId); order.setStatus(UNPAID); regOrderMapper.insert(order); return order; }对应的SQL是update iddecreaseRemainSlots UPDATE reg_schedule SET remain_slots remain_slots - 1 WHERE schedule_id #{scheduleId} AND remain_slots 0 /update这条SQL利用了数据库的行锁和原子更新特性同一时刻只有一个事务能成功更新这一行天然避免了超卖问题。这个方法既用于线上挂号也适用于以后做秒杀类业务是并发控制里非常经典的做法。4.3 电子病历与远程会诊的联动设计电子病历不只是记录文字它还要和远程会诊打通。会诊医生看不到患者的完整档案就没法给出准确的会诊意见。我设计的流程是基层医院医生发起会诊申请时从电子病历系统中拉取患者的基本信息、诊断记录、检验报告、影像报告生成一份“会诊摘要包”。上级医院的专家接到会诊任务后可以先调阅这份摘要包然后通过视频或者图文的方式给出会诊结论结论自动归档到患者的电子病历中。技术上的核心是“数据聚合接口”。这个接口要跨表查询患者的多维度数据包括his_patient、emr_record、lis_report、ris_report、med_prescription等多张表。我建议在Service层做一个聚合服务用MapStruct或者手动Bean拷贝将多张表的Entity合并成一个MedicalRecordAggregateVO一次性返回给前端。不要图省事直接在Controller里多次调用Mapper那样会产生N次数据库查询而且事务边界不清晰。远程会诊模块如果想要更有深度可以接入一个开源或商用的音视频SDK比如Zego、声网、腾讯TRTC。毕设阶段不需要自己实现音视频传输但要做“会诊房间”的概念会诊记录表保存roomId和channelId医生和专家通过同一个房间号加入视频会议平台只需要记录会议的开始和结束时间。4.4 区域健康档案的共享与隐私保护区域医疗健康信息管理的关键词是“共享”但医疗数据的共享一定是“可控共享”。不能因为全区打通了任何一个医生都能随便看所有患者的病历。我设计了一个“授权调阅”机制。当医生需要跨机构调阅某患者的健康档案时系统先检查是否有患者本人的授权记录。授权记录包括授权时间、授权范围、授权期限。患者通过App或小程序可以查看“谁在什么时间调阅了我的档案”并且可以随时撤销授权。这个功能虽然在毕设里实现起来不复杂但它能体现你对医疗信息化行业合规要求的理解程度答辩时是很加分的点。数据层面对敏感字段进行加密存储。身份证号、手机号这类信息采用AES加密后入库查询时通过注解或者组合工具类解密。更稳妥的做法是引入国密SM4加密但考虑到团队技术栈熟悉度毕设用AES也够。5. 系统安全、性能优化与部署5.1 接口鉴权与JWT的最佳实践JWT是SpringBoot后端项目里最常见的鉴权方案。平台里我用了jjwt这个库来生成和解析token。流程是用户登录成功后服务端生成一个包含userId和角色的token有效期设为2小时返回给前端。前端在每次请求的Authorization头中带上token后端通过拦截器解析校验。拦截器的关键代码逻辑是先从请求头中取出token调用JwtUtil解析如果解析失败或过期返回401如果解析成功把userId放入ThreadLocal或RequestAttribute供后面的Controller和Service使用。有一个实际坑必须注意JWT是无状态的服务端无法主动让token失效。如果用户的账号被管理员禁用已经签发的token在有效期内仍然可以访问接口。解决办法是在Redis里维护一个“token黑名单”或者“用户状态缓存”拦截器在校验JWT之后再查一下Redis确认该用户没有被禁用。虽然多一次Redis查询但安全性提升明显。5.2 敏感数据脱敏与操作日志审计医疗平台的敏感数据非常多接口返回值如果直接暴露患者身份证号一旦泄露就是事故。我建议在VO层统一处理脱敏或者在Jackson序列化的CustomSerializer中处理。简单的方式是写一个SensitiveField注解在返回字段上标注然后注册一个ObjectMapper的SerializerModifier。比如身份证号只显示前4位和后4位手机号只显示前3位和后4位。操作日志审计同样不能少。医生对电子病历的每一次修改、每一次调阅患者档案的记录、管理员对账号的每次禁用操作都要写入operation_log表包括操作人、操作时间、操作类型、请求参数、IP地址和操作结果。用一个AOP切面统一记录即可不要在各Service方法里手动写一遍日志代码。Aspect Component public class OperationLogAspect { Resource private OperationLogMapper operationLogMapper; Around(annotation(operationLog)) public Object around(ProceedingJoinPoint joinPoint, Log operationLog) throws Throwable { long startTime System.currentTimeMillis(); try { Object result joinPoint.proceed(); saveLog(joinPoint, operationLog, null, System.currentTimeMillis() - startTime); return result; } catch (Throwable e) { saveLog(joinPoint, operationLog, e.getMessage(), System.currentTimeMillis() - startTime); throw e; } } }5.3 Redis在平台缓存与高并发中的角色Redis在这个项目里的作用很大我用在了三个场景短信验证码存储、接口缓存、预约订单超时自动关闭的延迟处理。短信验证码发送验证码后以phone为key存入Redis设置5分钟过期校验时比对并删除。热门科室和医生信息查询量远大于修改量适合缓存。用Redis的Hash结构缓存医生列表并设置合理的过期时间避免缓存雪崩。超时订单处理除了用Scheduled轮询外更高效的方式是使用Redis的过期键监听或者ZSet延迟队列。把订单号放入ZSetscore设为超时时间戳后台线程每次都查当前时间到score之间的数据然后触发取消逻辑。public void addTimeoutOrder(String orderNo, long timeoutSeconds) { long expireTime System.currentTimeMillis() timeoutSeconds * 1000; redisTemplate.opsForZSet().add(timeout:orders, orderNo, expireTime); }但要注意Redis键过期监听默认情况下是异步的而且可能会丢事件医疗场景下不建议过度依赖它。实用主义的做法是Redis延迟队列作为第一道关卡定时任务兜底扫描双保险才能确保所有超时订单都能被关闭。5.4 前后端分离与部署上线SpringBoot天然适合前后端分离开发。前端我用的是Vue3加Element Plus后端只提供纯JSON接口通过CORS配置允许前端跨域访问。部署方案上我通常会打成jar包直接部署到一台Linux服务器上用systemd或者Docker管理进程。这里有一个容易被毕设学生忽略的问题如果前后端部署在不同端口需要处理跨域。一般在SpringBoot里配置一个CorsFilter即可或者在网关层统一处理。我还遇到过部署后前端能打开、但接口全部401的情况排查后发现问题出在配置了跨域但没放行OPTIONS预检请求。这个问题很典型后面常见问题里再细说。6. 常见问题与避坑实录6.1 SpringBoot版本选择的坑这个坑在开篇已经提到了但值得再展开。SpringBoot 3.x相比2.x不仅是版本号变化底层Servlet API换成了Jakarta命名空间很多老项目的包名从javax.servlet变成了jakarta.servlet代码里如果还在用javax前缀会直接编译报错。另外SpringBoot 3.0要求JDK17如果你的电脑装的是JDK8那就只能选择2.7.x。版本选择的建议是不追新、用稳定。2.7.x是2.x系列的最终版本Bug修复完整、社区资料海量和新手常看的教程兼容度最高。如果项目中用了Activiti/Flowable这类工作流引擎或者有些老的第三方SDK它们对SpringBoot 3的适配可能不完善这也是选择2.7.x的另一个理由。6.2 自动装配失效怎么排查这个问题的典型表现是明明在pom.xml中引入了某个Starter但项目启动后报错找不到对应的Bean。排查路径我建议按顺序来确认Maven依赖是否真的下载到了本地仓库有时候是网络问题导致依赖缺失。查看启动类的位置和包结构。SpringBoot默认扫描启动类所在包及其子包如果配置类放在启动类所在包之外扫描不到。解决方式是加ComponentScan指定扫描范围但更好的做法是让所有业务代码都放在启动类子包下。查看ConditionEvaluationReport。在配置文件中设置debugtrue启动日志中会输出所有自动配置的命中与未命中原因逐行看Condition的匹配情况。检查是否被自己的配置覆盖。自动配置类通常有ConditionalOnMissingBean注解如果你手动定义了一个同类型Bean自动配置就会失效。6.3 接口响应慢的排查路径如果某个接口响应超过3秒我会按以下步骤排查先用Arthas trace命令定位耗时方法确认是慢在SQL还是慢在外部调用。如果是SQL慢用EXPLAIN分析执行计划检查是否有全表扫描。大部分慢SQL都是因为表数据量增长后没有命中索引。比如预约挂号表里where条件经常用schedule_id和patient_id就应该建对应的联合索引。ALTER TABLE reg_order ADD INDEX idx_schedule_id (schedule_id); ALTER TABLE reg_order ADD INDEX idx_patient_id (patient_id);如果慢在主表查询返回数据量太大则需要做分页和查询字段裁剪。很多同学喜欢直接SELECT *一旦表有20个字段数据量大时这就是性能灾难。正确的做法是只查询需要的字段用DTO接收。6.4 前端同学接手SpringBoot项目的配合建议现在很多毕设是几个人一起做的前端同学接收到一个陌生的SpringBoot项目后最常问的问题是“我能不能直接改代码”。我的回答是能但要先看几个关键文件再动手。先看pom.xml了解项目用了哪些依赖和SpringBoot版本再看application.yml确认端口、数据库连接、Redis配置这些基础信息然后看Controller层的接口路径前缀和返回结构这个决定了前端怎么封装请求最后看拦截器和过滤器因为绕不开登录鉴权。前后端联调阶段有个约定值得坚持所有接口统一返回Result 结构前端封装一个axios拦截器统一处理code为200的成功响应和401的token失效跳转。一旦前后端约定好这个标准联调效率会高很多不会出现各写各的、接口返回结构五花八门的情况。写在最后做智慧医疗平台这类系统最大的收获不是学会了一个框架而是把一个看似复杂的业务场景拆解成可以落地的模块再把每个模块的技术难点逐个攻克。SpringBoot在这里只是一个工具真正值钱的是你对业务的理解和对技术方案的取舍。从我带过的学生来看这个题目做成精品的关键点有三条一是业务流程闭环要完整二是数据安全和并发控制要用心三是答辩时能把“为什么这么设计”讲清楚。希望在动手之前你能把这篇内容里提到的几个重点模块先梳理一遍画好流程图和表结构再开始写代码。这样后面开发过程中你会少走很多弯路。