ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SpringBoot+Vue中医问诊系统源码:从表设计到前后端联调避坑指南

SpringBoot+Vue中医问诊系统源码:从表设计到前后端联调避坑指南 简介这是一份面向高校课程设计与毕业设计场景的基于SpringBootVue的中医院问诊系统完整源码包采用前后端分离架构内置数据库脚本与启动脚本。系统运行环境基于JDK1.8、MySQL 5.7、Maven 3.3.9可在Windows/Mac下直接启动适合需要快速搭建可演示项目、完成系统设计或进行二次开发的学生与开发者使用。资源包共857个文件约23.37MB其中包含220个java文件、158个vue组件并配有svg图标、jpg图片、js逻辑、xml配置等覆盖后端接口、前端页面与数据库结构sql脚本可直接导入bat脚本辅助环境安装与启动压缩包目录层次清晰便于定位核心代码与配置内容。目前已有78人学习下载资源已在作者环境中测试通过。获取后可获得完整可运行系统包括前后端分离的代码工程、数据库初始化脚本、运行启动脚本等能够直接用于课设答辩或作为毕设基础进行功能扩展节省从零搭建项目的时间。1. SpringBootVue 的中医院问诊系统课设答辩能跑通才算第一步做课程设计最怕的不是写代码而是答辩前一晚发现项目跑不起来。这套基于 SpringBootVue 的中医院问诊系统源码正好补上这个缺口后端用 SpringBoot 做分层接口前端用 Vue 做页面交互挂号、问诊、病历、处方、缴费一条线走完拿来即改即用。它不是光能点几个页面的展示型 demo数据库、鉴权、路由守卫、接口联调都齐整理成自己的课设或毕设完全够用。适合两类人一是 Java 课程设计不知道做什么、想直接抄作业的在校生二是想快速了解前后端分离项目长什么样的入门者。不过源码能跑只是起点答辩老师问「为什么这么设计」时你得能讲出数据流和表结构才行。2. 问诊系统核心拆解从挂号到开方的数据流与表设计2.1 角色与业务闭环这个系统在模拟什么现实流程中医院问诊系统和普通商城系统最大的区别在于业务链条更长角色更明确。打开源码先看实体类和数据库脚本不要急着跑起来。这套系统的角色大致分三类患者前端注册登录、医生后台接诊、管理员管理医生和药品。业务主线是患者挂号 - 医生接诊 - 填写病历与脉象 - 开中药处方 - 缴费结算这五个环节对应前端五个页面后端五个模块。理解业务闭环后看代码会轻松很多。比如患者挂号时系统要判断该时段医生是否已有排班记录医生接诊时要能拉出患者历史病历列表开处方时要从前端传入的药品 id 列表反查库存。这些逻辑在源码里都有对应实现你在答辩时顺着「挂号信息表 - 病历表 - 处方明细表」这条线讲老师基本不会再深挖。2.2 数据库设计中医问诊场景下要拆几张表源码的 SQL 脚本里核心表大概有七张用户表、医生表、科室表、挂号记录表、病历表、药品表、处方明细表。其中最容易忽略的是病历表和处方明细表。中药处方不是一条记录存完的通常一张处方对应多条药材明细每条明细有药材名、剂量、用法这样设计是为了支持「一帖药里多味药材」的查询与打印需求。CREATE TABLE medical_record ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 病历ID, patient_id bigint(20) NOT NULL COMMENT 患者ID关联用户表, doctor_id bigint(20) NOT NULL COMMENT 医生ID关联医生表, appointment_id bigint(20) DEFAULT NULL COMMENT 挂号记录ID, diagnosis varchar(500) DEFAULT NULL COMMENT 中医诊断如肝郁气滞, pulse varchar(255) DEFAULT NULL COMMENT 脉象记录, tongue varchar(255) DEFAULT NULL COMMENT 舌苔记录, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT病历表; CREATE TABLE prescription_item ( id bigint(20) NOT NULL AUTO_INCREMENT, prescription_id bigint(20) NOT NULL COMMENT 处方主表ID, medicine_name varchar(100) NOT NULL COMMENT 中药名称, dosage varchar(50) DEFAULT NULL COMMENT 剂量如10g, usage_method varchar(255) DEFAULT NULL COMMENT 用法如水煎服, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT处方明细表;这里有几个字段是中医问诊特有的比如脉象和舌苔普通门诊系统不会设计这两个字段。如果你要复现或用在自己课设里建议保留它们答辩时这就是亮点——说明你理解中医辨证的录入需求。另外注意所有表都用utf8mb4而不是utf8否则 MySQL 8.0 下 emoji 或生僻字写入会报错。外键在课设里可以不用物理外键靠 Service 层维护逻辑关联就够了后续删数据也方便。2.3 后端分层与鉴权登录拦截是怎么实现的源码后端是典型的三层结构Controller 接收请求、Service 处理业务、Mapper 操作数据库。这套结构在课设答辩里最好讲因为老师一定会问「为什么分层」。标准答法Controller 只做参数校验和结果封装不写 SQLService 处理事务和业务规则Mapper 只负责持久化这样改数据库方言不用动上层代码。登录鉴权部分值得单独看因为这是面试和答辩的高频问题。常见做法是用 JWT 生成 token前端登录后存到 localStorage每次请求带在Authorization头里后端用一个拦截器统一校验。Component public class AuthInterceptor implements HandlerInterceptor { Autowired private StringRedisTemplate redisTemplate; Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 放行登录接口和静态资源 if (request.getRequestURI().contains(/login) || request.getRequestURI().contains(/register)) { return true; } String token request.getHeader(Authorization); if (token null || token.isEmpty()) { response.setStatus(401); return false; } // 从 Redis 校验 token 是否有效而不是只解 JWT String userId redisTemplate.opsForValue().get(token: token); if (userId null) { response.setStatus(401); return false; } // 把用户信息放到 ThreadLocal供 Service 层获取当前登录人 UserContext.set(Long.parseLong(userId)); return true; } Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { UserContext.clear(); } }这段逻辑要注意两个点。第一UserContext用ThreadLocal存当前用户但请求结束后必须clear()否则 Tomcat 线程池复用线程会导致用户串号这是典型的线上 bug 也是答辩加分点。第二把 token 存 Redis 比纯 JWT 好因为你可以主动让 token 失效比如管理员禁用某个医生账号时删掉对应的 key。源码如果没用 Redis 而是纯 JWT你可以按上面这段改造工作量不大但讲出来含金量明显不同。前端侧对应的是路由守卫源码的router/index.js里一般有类似逻辑判断localStorage.getItem(token)是否存在没有就跳回登录页。这就是前后端分离项目的双保险——后端接口有拦截器前端页面有路由守卫缺一个都不完整。2.4 前端页面流转Vue 路由参数怎么传递问诊上下文前端部分建议重点看路由设计。问诊系统里有一个很典型的场景患者列表页点击「接诊」按钮跳到问诊页同时要带着患者 id、挂号 id 过去。新手很容易用query传参地址栏变成?patientId123刷新页面后参数还在但体验不好更规范的做法是用params配合动态路由。// 路由定义 const routes [ { path: /consult, name: Consult, component: () import(../views/consult/Index.vue), meta: { requiresAuth: true } } ] // 跳转时传参 this.$router.push({ name: Consult, params: { patientId: this.patientId, appointmentId: this.appointmentId } }) // 问诊页接收 created() { this.patientId this.$route.params.patientId this.appointmentId this.$route.params.appointmentId }用params传参时有一个坑刷新页面参数会丢失因为params不像query那样拼在 URL 上。所以在created里接收参数后要么立刻存到sessionStorage要么再次调用接口根据挂号 id 重新拉取患者信息。源码里如果用的是query也没关系不影响功能但答辩时主动说出这个刷新丢参的问题和解决方案老师会觉得你真的跑过、想过而不是只抄了代码。另外Vue 组件里的异步请求建议统一封装 axios 实例而不是每个页面单独import axios。源码里通常有utils/request.js里面做了拦截器请求前加 token响应后统一处理 401 跳登录页。这里需要确认一下请求拦截器里 token 的 key 和后端Authorization头能不能对上对不上就是联调 401 的根源。3. 把源码跑起来环境对齐、数据库导入与前后端联调3.1 环境版本对齐先看 pom.xml 和 package.json源码能跑的前提是环境版本对得上这是课设翻车第一大户。建议拿到源码后不要急着npm install先打开pom.xml看 SpringBoot 父版本再打开package.json看 Vue 版本和 Node 要求最后看application.yml里的数据库配置。常见组合是 SpringBoot 2.7 JDK8 MyBatis-Plus MySQL 5.7/8.0前端 Vue2 Element-UI Node 14。组件推荐版本说明JDK1.8 或 11SpringBoot 2.x 对 JDK8 支持最好Maven3.6.3IDEA 自带也可以MySQL5.7 或 8.0注意驱动配置和时区Node.js14.x 或 16.xVue2 项目不建议用 Node18npm6.x/8.x与 Node 版本配套版本不匹配的症状很明显Maven 依赖下载失败、node-sass编译报错。尤其是node-sassNode 版本过高会直接build失败因为原生模块编译不通过。如果你的本机 Node 是 18 或 20优先装一个 Node14 再用别在原版本上硬扛。3.2 数据库初始化导入 SQL 与账号配置源码包里的db目录或根目录下一般有一个init.sql用数据库工具导入即可。命令行导入也挺方便mysql -u root -p init.sql导入后确认一下有哪些库和表重点看看是否有初始管理员账号数据。有些源码会自带一条admin用户密码可能是admin123或 MD5 加密后的密文如果登录不了多半是密码加密方式不对去application.yml看密码校验用的什么算法。接着改数据库连接配置server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/tcm_hospital?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: yourpassword redis: host: localhost port: 6379 mybatis-plus: mapper-locations: classpath*:mapper/**/*.xml configuration: map-underscore-to-camel-case: trueserverTimezoneAsia/Shanghai务必加上MySQL 8.0 不设置时区会报错或者时间差八小时。如果你的源码里用了 Redis 做登录态那本地还得装一个 Redis Windows 版或直接用 Docker 起一个别漏了这一步。启动后如果界面全白、接口全 401优先怀疑 Redis 没连上。3.3 后端启动与接口自测IDEA 里的三个确认动作用 IDEA 导入后端工程等待 Maven 下载依赖。下载完成后启动前做三个确认一是检查 Lombok 插件是否安装源码里大量类的 getter/setter 依赖它二是确认application.yml里server.port没有被本机占用三是看启动类上有没有MapperScan注解没有的话 Mapper 接口扫描不到启动不报错但接口调用时说找不到 Bean。启动成功后访问接口文档或直接试登录接口。源码如果集成了 Swagger访问http://localhost:8080/swagger-ui/index.html能看到接口列表这是最快验证后端是否正常的方式。没有 Swagger 的话用浏览器直接访问登录接口的 GET 方式会 405这种状态说明服务活了。curl -X POST http://localhost:8080/api/auth/login \ -H Content-Type: application/json \ -d {username:admin,password:admin123}正常会返回一个 JSON里面带token字段。拿到 token 后再去调别的接口比如GET /api/doctor/list在 Header 里加上Authorization: Bearer token值看能否查出来数据。这一步通过说明后端和数据库是通的问题只可能在前端联调环节。3.4 前端启动npm install 与接口代理配置前端工程一般在web或front目录下按顺序执行npm install npm run serve如果npm install卡住或 node-sass 报错常见处理是换镜像源npm config set registry https://registry.npmmirror.com npm install注意npm install成功后必须确认node_modules目录真实存在有些情况下 npm 显示成功但依赖缺失启动时会报Module not found错误。启动前端后访问http://localhost:8081端口取决于你在vue.config.js里的配置登录页能出来就成功了一半。前后端分离项目联调的关键是代理配置。前端开发服务器默认跑在 8081后端在 8080跨域问题靠vue.config.js的 devServer 转发解决module.exports { devServer: { port: 8081, proxy: { /api: { target: http://localhost:8080, changeOrigin: true, pathRewrite: { ^/api: /api } } } } }changeOrigin: true的作用是让后端认为请求来自同源地址不加的话某些情况下后端拿不到正确的 Host 头。pathRewrite一般保持原路径除非后端接口前缀不同比如前端请求/api/login而后端是/auth/login那就要写成^/api: 。这里改完要重启npm run serve因为vue.config.js修改后不会热更新。登录时如果 Network 面板里请求地址是http://localhost:8081/api/auth/login且返回 200说明代理生效如果 404 或 500检查后端路径是不是在/auth下面而不是/api/auth。4. 避坑指南源码跑通前最容易翻车的五个地方4.1 端口冲突8080 被占用导致后端启动假失败现象后端启动日志显示Port 8080 was already in use但过一会儿又提示启动成功。原因某些 Windows 服务或之前残留的 Java 进程占用了 8080SpringBoot 本身启动失败后自动退出但 IDEA 控制台保留了部分日志看起来像启动成功。解决先用命令查占用进程再改端口或杀掉进程。netstat -ano | findstr 8080 taskkill /PID 进程号 /F改端口也可以application.yml里把server.port改成 8082然后同步改vue.config.js里的代理 target。我一般倾向直接杀进程因为改端口要动两处漏一处就白改。4.2 MySQL 8.0 连接报错Public Key Retrieval 与时区问题现象后端启动时报Public Key Retrieval is not allowed或The server time zone value Öйú±ê׼ʱ¼ä is unrecognized。原因MySQL 8.0 默认用 caching_sha2_password 认证JDBC 驱动首次连接需要获取公钥同时 8.0 对时区更敏感连接串不带时区就直接报错。解决连接串加两个参数。url: jdbc:mysql://localhost:3306/tcm_hospital?useSSLfalseallowPublicKeyRetrievaltrueserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue在本地开发环境可以开生产环境不建议。另外确认驱动坐标是不是mysql-connector-j8.x老项目用mysql-connector-java5.x 在新版 MySQL 上会连不上。4.3 node-sass 编译失败版本和 Node 不匹配现象前端npm install或npm run serve时提示node-sass报错一堆gyp字样。原因node-sass是原生模块需要针对当前 Node 版本重新编译Node 版本过高18时没有对应预编译包就会走源码编译然后失败。解决优先降 Node 版本而不是换sass编译方式。Windows 上用 nvm-windows 装一个 Node 14nvm install 14.21.3 nvm use 14.21.3然后删除node_modules和package-lock.json重新装rm -rf node_modules package-lock.json npm install如果源码里用的是dart-sasssass包而不是node-sass这个问题基本不会遇到。所以拿到源码先看package.json。4.4 登录后跳转成功但接口 401token 传递逻辑断链现象前端登录成功跳转到首页但所有列表接口都返回 401 未授权。原因登录成功后 token 存到了localStorage但 axios 请求拦截器里没有把 token 取出来加到请求头或者后端要求的 Header 名称不是Authorization。解决打开前端的utils/request.js确认拦截器长什么样axios.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers.Authorization token } return config })同时对比后端拦截器读的是Authorization还是token字段两边的 key 必须完全一致大小写都不能差。4.5 Swagger 访问 404 或空白页拦截器没放行现象后端启动正常但访问/swagger-ui/index.html是 404或者页面出来但接口列表加载失败。原因自定义拦截器拦截了/swagger-ui/**和/v3/api-docsSpringBoot 的静态资源路径没被放行。解决在拦截器preHandle里把接口文档相关路径全部放行if (request.getRequestURI().contains(/swagger-ui) || request.getRequestURI().contains(/v3/api-docs)) { return true; }如果是 SpringBoot 3.x 项目Swagger 路径可能是/swagger-ui/**和/v3/api-docs/**别只放行一个前缀。放行完成后重启后端Swagger 能出页面接口调试的效率会高很多。5. 答辩实战把项目讲出设计感再用反编译捞回源码答辩和验收时老师不关心你代码写了多少行关心的是「你能不能说清楚」。我的建议是准备一条主线讲法挂号怎么产生数据 - 接诊怎么查病历 - 处方怎么落库配合页面演示走下来。讲的时候主动点出三件事一是数据库设计里病历和处方明细拆了两张表理由是一对多关系要支持一味药多个明细二是登录鉴权用拦截器加Redis比纯JWT多一个可控失效能力三是前端路由守卫和后端拦截器做了双保险。这三个点无论源码原本是否实现你只要能讲明白就是有效设计。如果源码里有 jar 包或部署包比如tcm-hospital.jar而你拿到的是编译产物没有完整源码可以用反编译工具捞回来。IDEA 自带 FernFlower 反编译器直接打开 jar 包就能看到源码或者用 CFR 命令行处理。这是很多 Java 课设源码包的真实形态——里面放的是可运行的 jar 而不是工程源码这时候反编译是唯一能还原代码的办法。java -jar cfr.jar tcm-hospital.jar --outputdir ./src反编译出来的代码能看懂逻辑但 Mapper XML、前端工程这些不一定能完整还原所以要优先保证源码包里有前端web目录。从那以后我每次拿到课设源码都强制走一遍固定流程先看pom.xml和package.json确认版本再导 SQL、改连接配置最后跑后端、起前端、过一遍登录和核心接口全部通过才敢说「源码可运行」。这套流程走完新坑就少了大半希望帮到你。本文还有配套的精品资源点击获取
返回列表