ARTICLE DETAIL

资讯详情

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

SpringBoot+Vue健康管理系统全栈开发与部署实战

SpringBoot+Vue健康管理系统全栈开发与部署实战 简介本资源是一套完整的健康管理系统毕业设计实现方案面向计算机相关专业本科生及初级全栈开发者解决课程设计、毕业论文与求职项目展示中缺乏可运行、模块完备的Spring BootVue双端系统的问题。压缩包共含前端Vue代码、后端Spring Boot源码、MySQL数据库文件及详细部署文档总计8.21MB各类文件协同支撑系统从开发到上线的全流程实践。已有1639人学习下载具备较强的教学参考价值与工程复用性。读者可直接导入IDE运行前后端服务快速掌握用户权限控制、健康档案CRUD、多维度健康评估算法集成、随访任务调度、咨询问答交互及健康百科内容管理等核心业务逻辑代码结构清晰模块划分明确数据库设计符合第三范式配套部署文档涵盖环境配置、SQL初始化、跨域处理与Nginx反向代理配置要点显著降低二次开发门槛。 又到了课程设计和毕业设计交作业的高峰期很多同学卡在同一个位置上题目叫“基于SpringBootVue的健康管理系统”代码能跑起来但要问清楚每个文件为什么要这么写、数据库为什么建这些表、最后怎么部署到服务器就有点懵了。这篇文章我打算把整个项目从设计到落地完整拆一遍——包括数据库表结构设计、SpringBoot后端接口怎么组织、Vue前端怎么对接、最后如何在服务器上跑起来连打包命令和Nginx配置都给出来。无论你是要照着做课程设计还是想完整走一遍全栈项目的流程这篇文章都能直接拿来当参考。我最早做这类系统的时候也踩过不少坑数据库表设计得一塌糊涂、前端跨域调不通、部署之后接口404这些问题在学校里没人教只能自己一个个排查。所以这篇文章不只是贴代码更重要的是把每个关键选择背后的原因讲清楚让你以后遇到类似问题能自己判断而不是只会复制粘贴。1. 项目整体设计与技术选型1.1 技术栈怎么选才不给自己挖坑先说结论SpringBoot 2.7.x Vue 2.x或Vue 3.x MySQL 8.0 MyBatis-Plus这个组合是课程设计和毕业设计里最稳的方案没有之一。很多人一开始就纠结版本看到网上教程说SpringBoot 3.0出了就非要上最新的结果折腾半天发现JDK版本不对、依赖下载不下来、各种配置类跟教程对不上。这里我明确说一句除非你有充足的时间去踩坑否则课程设计老老实实用SpringBoot 2.7.x系列。2.7是SpringBoot 2.x的最后一个大版本既兼容JDK 8也能跑在JDK 11、17上生态成熟、教程丰富、遇到问题随便一搜就有答案。SpringBoot 3.0之后强制要求JDK 17很多学校机房电脑装的还是JDK 8光这一条就能劝退大半人。前端框架的选择上如果你有Vue基础直接上Vue 3 Element Plus组件库新、风格现代、面试聊起来也加分。如果你之前看的是Vue 2的教程或者觉得自己基础比较薄弱那用Vue 2 Element UI也完全没问题网上资源更多遇到问题更容易找到解决方案。我自己做这个项目的时候用的是Vue 2没别的原因就是当时资料的坑少什么都能搜到。现在回头看Vue 3的生态已经很成熟了新项目完全可以直接上。数据库方面推荐MySQL 8.0。8.0的窗口函数、JSON支持等特性虽然在这个项目里用不上但它是当前最主流的关系型数据库毕业后实习大概率也会用到。ORM框架我强烈建议用MyBatis-Plus不是因为它比MyBatis好多少而是因为它在MyBatis的基础上帮你把单表增删改查全部封装好了写一个Mapper接口继承BaseMapper什么selectById、selectList、insert、deleteById这些方法直接就能用省掉大量写XML和注解的时间。课程设计的核心是展示完整的业务逻辑不是展示你会写多少条SQL把节省下来的时间花在功能完善上价值更高。1.2 功能模块怎么划分才既完整又不过度设计健康管理系统听起来很宽泛但落到课程设计这个场景核心就四个字增删改查。不过同样是增删改查有人做得像demo有人做得像作品区别就在于模块划分的颗粒度和业务逻辑的完整度。我建议把系统拆成这几个模块用户登录注册模块、个人健康档案模块、健康记录管理模块包括体检指标、体重、血压、心率等、健康评估与建议模块、系统管理模块用户管理、数据统计。每个模块控制在“够用、能讲清楚、演示效果好”的范围内别贪多。有的人为了显得高大上硬塞一个在线问诊或者视频咨询功能结果视频模块开发两星期还没搞定最后连最基础的功能都演示不完整这种本末倒置的事情我见得太多。从技术角度看各个模块又对应不同的开发重点。登录注册模块对应的是JWT Token认证、密码加密存储、前端路由守卫这部分是面试官最爱问的健康档案模块对应的是前后端表单交互、数据校验、日期处理健康记录模块重点展示列表分页、条件查询、图表展示健康建议模块可以做成简单规则引擎——比如根据用户的BMI指数和血压值在后台匹配对应的健康建议文案输出。如果要把“健康”这个主题做得更直观还可以在首页加一个数据看板用ECharts展示体重趋势、血压变化的折线图演示效果直接上一个台阶。功能模块这块我的经验是先列清单再排优先级。把必须有的核心功能增删改查放在第一位把加分功能图表、数据统计、导出放在第二位把不切实际的功能实时通讯、智能推荐、硬件对接直接砍掉除非你确实有能力和时间做完。数据库设计是整个系统的地基地基没打好后面写再多代码都是白搭。课程设计的数据库设计不需要像生产环境那样考虑极端复杂的情况但至少要满足三个要求表之间的关联关系清晰、每个字段类型和长度合理、代码里用到的字段都能在表中找到对应。我按最小可用原则设计了四张核心表用户表、健康档案表、健康记录表、健康建议表。用户表存登录信息健康档案表存用户的基本身体信息身高、体重、血型、过敏史等跟用户表是1对1的关系健康记录表存每次的体检指标血压、心率、血糖等跟用户表是1对多的关系健康建议表存健康建议文案可以由管理员维护也可以由系统根据健康记录自动生成。用户表和健康记录表之间加一个索引查询会快很多。虽然课程设计阶段数据量不大索引有没有感知不出来但养成建索引的习惯面试时被问到数据库优化也能多个案例。时间字段统一用datetime类型更新时间字段配置ON UPDATE CURRENT_TIMESTAMP这样每次修改记录时MySQL会自动更新时间省得代码里手动set。2. 核心功能模块与代码落地2.1 后端如何优雅地写增删改查后端代码的组织方式我建议严格遵循分层架构Controller层负责接收请求和返回响应Service层负责业务逻辑Mapper层Dao层负责数据库操作。虽然是老生常谈但真有很多人把所有代码堆在Controller里一个方法几百行看着就头疼。以健康记录模块为例Controller层的接口设计应该是这样的RestController RequestMapping(/api/record) public class HealthRecordController { Resource private HealthRecordService healthRecordService; PostMapping(/add) public Result add(RequestBody HealthRecord record) { return healthRecordService.addRecord(record); } DeleteMapping(/{id}) public Result delete(PathVariable Integer id) { return healthRecordService.deleteRecord(id); } PutMapping(/update) public Result update(RequestBody HealthRecord record) { return healthRecordService.updateRecord(record); } GetMapping(/list) public Result list(RequestParam Integer pageNum, RequestParam Integer pageSize, RequestParam(required false) Long userId) { return healthRecordService.pageQuery(pageNum, pageSize, userId); } }这里有几个细节值得注意。第一统一返回Result对象。Result对象是前后端约定的数据格式一般包含code状态码、message提示信息、data业务数据三个字段。有了统一格式前端处理响应时只需要判断code是否为200不用每个接口单独写一套逻辑。第二方法用PostMapping、DeleteMapping等注解区分HTTP方法一个接口只做一件事语义清晰。第三RequestBody接收JSON格式的参数前端传对象时不需要手动拼接参数配合Vue的请求库非常方便。Service层的实现要体现业务逻辑。比如添加一条健康记录时需要判断用户是否存在、参数是否合法。更新记录时要校验记录是否属于当前登录用户防止越权操作。删除记录之前同样要做归属校验。这些看似细小的逻辑正是加分的关键也是面试时能讲的点。前端再好看后端逻辑一团浆糊一问细节就露馅。MyBatis-Plus的使用上我建议至少手动写两条SQL比如多表联查的接口。虽然BaseMapper封装了单表的CRUD但实际业务中经常需要关联查询比如查询健康记录时同时带出用户的姓名和手机号。这种场景用MyBatis-Plus的注解Select写一条联查SQL或者直接在XML文件里写反而更直接。我习惯在Mapper接口里用注解写简单SQLMapper public interface HealthRecordMapper extends BaseMapperHealthRecord { Select(SELECT r.*, u.nickname FROM health_record r LEFT JOIN sys_user u ON r.user_id u.id WHERE r.user_id #{userId} ORDER BY r.record_date DESC) ListHealthRecordVO selectRecordWithUser(Param(userId) Long userId); }2.2 用户登录与Token校验怎么实现登录功能是几乎所有管理系统都绕不开的模块面试官也特别喜欢问。这个项目的登录功能我推荐用JWTJSON Web Token的方式实现相比传统的Session方案JWT无状态、支持跨域、前后端分离架构下更友好。流程是这样的用户提交用户名和密码后端校验通过后生成一个Token返回给前端前端把Token存在localStorage里每次请求时在请求头中携带后端通过拦截器校验Token是否有效。Token的生成和校验核心代码如下Component public class JwtUtil { private final String secret your-secret-key; public String generateToken(Long userId, String username) { return Jwts.builder() .setSubject(username) .claim(userId, userId) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() 1000 * 60 * 60 * 24)) .signWith(SignatureAlgorithm.HS256, secret) .compact(); } public Claims parseToken(String token) { return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody(); } }这里要提醒几个重点。第一secret密钥在生产环境一定不能明文写在代码里要用环境变量或者配置文件引用。课程设计阶段写在配置类里可以接受但要在博文里提一下这个问题显得你考虑到了安全性。第二设置过期时间不要设得太长24小时是常见的做法有些项目会用双Token机制accessToken refreshToken课程设计阶段做单Token就够。第三密码存储一定不能存明文用MD5加盐或者BCrypt加密。MD5本身虽然不够安全但加上盐值后基本满足课程设计的要求。BCrypt是更优的选择它在SpringSecurity里有现成的工具类如果你不想引入SpringSecurity那套组合也可以直接用BCryptPasswordEncoder来做加密。拦截器的实现也很简单写一个HandlerInterceptor在preHandle方法里从请求头取出Token校验成功放行失败返回401。Component public class JwtInterceptor implements HandlerInterceptor { Resource private JwtUtil jwtUtil; Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token request.getHeader(Authorization); if (token null || token.isEmpty()) { response.setStatus(401); return false; } try { Claims claims jwtUtil.parseToken(token); request.setAttribute(userId, claims.get(userId)); return true; } catch (Exception e) { response.setStatus(401); return false; } } }然后在WebMvcConfigurer里注册拦截器并配置放行路径比如登录接口、注册接口不拦截其余接口都要校验。2.3 前端仓库结构、路由与页面实现Vue前端的开发我建议从官方脚手架开始不要自己手动去配Webpack。如果你是Vue 2就用vue-cli创建项目如果你是Vue 3用Vite创建速度更快体验更好。创建完之后在项目里安装axiosHTTP请求库、vue-router路由、Element UI或Element Plus组件库、ECharts图表。前端的核心骨架是路由配置。路由不仅负责页面跳转还承担了登录校验的功能。我用vue-router的路由守卫实现“未登录跳转登录页”router.beforeEach((to, from, next) { const token localStorage.getItem(token); if (to.path ! /login !token) { next(/login); } else { next(); } });axios请求封装也很重要。我习惯把axios实例单独封装成一个request.js文件统一设置baseURL和请求拦截器import axios from axios const request axios.create({ baseURL: /api, timeout: 10000 }) request.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers.Authorization token } return config }) request.interceptors.response.use( response { const res response.data if (res.code ! 200) { Message.error(res.message) return Promise.reject(new Error(res.message)) } return res }, error { Message.error(网络异常请检查后端服务是否启动) return Promise.reject(error) } ) export default request这里有个细节要说明开发环境下baseURL: /api配合Vue的代理配置来实现跨域请求。在vue.config.js里写代理把前端的/api路径转发到后端8080端口这样浏览器层面不存在跨域问题后端也不用额外配置CORS。这种方案既简单又安全避免了直接暴露后端地址。页面实现方面健康记录页面是最核心的业务页面。我在表格基础上加上BMI计算和趋势图表。BMI计算放在computed里根据身高体重实时计算computed: { bmi() { if (!this.height || !this.weight) return 0 const heightM this.height / 100 return (this.weight / (heightM * heightM)).toFixed(1) } }用computed而不是method的好处是它依赖的响应式数据变化时会自动重新计算而且有缓存性能更好。这个知识点前面提到热搜里有“vue computed”所以我特意放出来面试的时候被问“computed和watch有什么区别”也有东西可以说。Vue页面里的表格、表单、弹窗等交互组件用Element UI/Element Plus的现成组件拼接即可。重点要关注的是数据流从后端接口拿数据后要设置loading状态处理分页参数提交表单时做表单校验。把这些基础交互相逻辑理顺页面就成功了一大半。3. 数据库设计、数据准备与脚本管理3.1 建库建表与初始化数据脚本数据库这部分我单独拿出来讲是因为太多人忽视它导致后面写代码时被各种字段问题卡住。一个正经项目数据库要能脱离代码独立存在拆开来也能看懂这才是合格的设计。建库建表建议用Navicat、DataGrip等可视化工具操作操作完把SQL脚本导出保存。但你的项目要想让老师或者面试官直接跑起来SQL脚本必须放在项目目录下。我习惯放在sql/init.sql在项目结构上明确标注出来。数据库名称我用health_system字符集统一用utf8mb4而不是utf8。utf8mb4是utf8的超集支持存储emoji和更多特殊字符MySQL 8.0里这是默认选项。字段注释一定要写清楚这不是给数据库看的是给半年后的自己看的。健康记录表的设计我给出完整的建表SQLCREATE TABLE health_record ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键, user_id bigint(20) NOT NULL COMMENT 用户ID, record_date date NOT NULL COMMENT 记录日期, systolic int(11) DEFAULT NULL COMMENT 收缩压mmHg, diastolic int(11) DEFAULT NULL COMMENT 舒张压mmHg, heart_rate int(11) DEFAULT NULL COMMENT 心率次/分, blood_sugar decimal(5,2) DEFAULT NULL COMMENT 血糖mmol/L, weight decimal(5,2) DEFAULT NULL COMMENT 体重kg, remark varchar(500) DEFAULT NULL COMMENT 备注, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id), KEY idx_user_date (user_id, record_date) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT健康记录表;注意几个细节体重和血糖用decimal而不float避免浮点数精度问题索引建在user_id和record_date的联合索引上因为查询场景基本都是“某个人某段时间的记录”record_date用date类型而不是datetime因为健康记录本来就是按天记录的不需要时分秒。3.2 怎么造出自然又充分的测试数据数据库设计好了如果一张表里空荡荡的你做出来的前端页面也是空荡荡的演示效果极差。所以我会专门造一批测试数据让页面跑起来有东西可看。造数有个诀窍不是随便插入几条数据而是按业务场景来。比如你需要演示“健康趋势分析”那就得有一张健康记录表里连续录了几个月的血压数据演示“BMI计算”就得有一个用户身高体重恰好处于肥胖或偏瘦区间的记录演示“用户管理”就得有几个不同角色的用户账号。造数时要让数据之间有关联性不能这周的数据和上周的数据断档。写SQL插入数据时我有几个习惯。第一条主键id不用指定让它自增即可。第二条时间字段的插入有讲究比如健康记录里的record_date可以写成DATE_SUB(CURDATE(), INTERVAL 30 DAY)这样的表达式这样脚本在任何时间执行生产出来的数据都是最近30天的页面展示非常自然。第三条密码字段在插入时不能直接写明文要用代码中对应的加密方式处理。如果你用的是MD5加盐那插入时要写加盐后的值如果是BCrypt加密要用BCrypt生成的哈希值。你可以在登录接口调试时先把代码里的加密方法跑一遍生成一条测试数据再手动插进数据库这样一个可用的测试账号就造好了。我喜欢在部署文档里特别说明“默认账号和密码”方便验收的人直接登录。比如管理员账号admin/123456测试用户zhangsan/123456。这些初始数据都写在init.sql里别人clone项目后一条命令就能把数据环境搭起来。3.3 数据库脚本的导入导出与版本管理课程设计阶段可能没那么讲究但如果你准备项目交接或者打算简历里写这个项目我建议从一开始就养成数据库脚本版本管理的习惯。最简单的做法是修改表结构就新建一个sql/update.sql文件把这次改了哪些字段写清楚而不是直接改init.sql。这样做的好处是哪天表结构改崩了能回滚两个环境之间的数据能同步过去。真正到公司里开发数据库变更都要走审批流程脚本就是唯一的凭证。虽然课程设计用不上这么复杂但习惯提前养成找工作的时候能跟面试官多聊两句。工具方面Navicat可以把数据库导出为SQL文件选择“结构和数据”一起导出。DataGrip则是JetBrains出品的如果你已经用IDEA直接用DataGrip连MySQL会很舒服。IDEA自带Database面板也能直接执行SQL脚本不需要额外安装工具。导出脚本时注意编码如果脚本里有中文注释必须把编码选成UTF-8否则别人执行的时候看到一堆乱码搞得心态爆炸。4. 本地启动到线上部署全流程4.1 本地把项目跑起来需要几步我从一个全新的空环境来演示这样如果你电脑上什么都还没装照做就能跑通。第一步安装环境。JDK 8、MySQL 8.0、Node.js 14、IDEA社区版Ultimate都行。注意安装MySQL的时候记住root密码后面配置SpringBoot连接要用。Node.js安装很简单一路next。安装完成后打开命令行执行node -v验证是否成功。第二步导入数据库脚本。打开Navicat新建连接填上localhost、3306、root和密码新建数据库名字叫health_system字符集选utf8mb4。右键数据库运行SQL文件选择项目里的init.sql执行四张表和测试数据就全出来了。第三步启动后端。用IDEA打开后端项目等待Maven依赖下载完成。修改application.yml里的数据库用户名和密码为你自己的。找到主类名字一般是HealthApplication右键运行看到控制台输出“Started HealthApplication”就说明启动成功了。验证一下接口是否可用浏览器访问http://localhost:8080/api/user/list如果返回JSON数据后端就没问题。第四步启动前端。用命令进入前端项目目录执行npm install。因为npm默认源在国外下载慢是常态建议先设置淘宝镜像npm config set registry https://registry.npmmirror.com能快好几倍。安装完成后执行npm run serve看到编译成功的提示后浏览器访问localhost:8081或者Vite提示的地址页面就能出来了。如果页面出现了但接口报错大概率是代理没配好。我前面说的vue.config.js代理只要baseURL是/api而且代理配置正确应该能通过浏览器DevTools看到请求是localhost:8081发起的再转发到localhost:8080。前端网络请求的调试按F12打开DevTools看Network面板里的请求状态红色报错基本就是后端没启动或者接口路径不对链路问题一查一个准。4.2 打包部署到Linux服务器的完整过程本地能跑只是第一步很多同学毕业论文里写了个部署但压根没真整过。我建议有条件的话租一台最便宜的云服务器1核2G就够跑这个项目把部署过程完整走一遍。后端打包很简单在项目根目录执行mvn clean package -DskipTests执行完后target目录下会生成一个health-system-0.0.1-SNAPSHOT.jar文件。这个jar包就是整个后端项目的可执行文件通过java -jar health-system-0.0.1-SNAPSHOT.jar启动。上传到服务器时我习惯用/opt/health-server/这个目录把所有部署相关的东西放在里面管理起来清晰。前端打包npm run build执行完后dist目录下就是前端静态文件把它上传到服务器的/opt/health-web/dist目录。接下来配置Nginx。先安装它在Ubuntu上是apt install nginxCentOS上是yum install nginx。装好后修改配置文件/etc/nginx/sites-available/default路径根据系统略有不同server { listen 80; server_name 你的服务器IP; location / { root /opt/health-web/dist; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }这个配置里有两个关键点。第一try_files $uri $uri/ /index.html;这句是为了解决Vue打包部署后刷新页面404的问题。因为Vue是单页应用路由切换是前端的事刷新时浏览器会向服务器请求对应路径而服务器上根本没有这个路径所以需要让它回退到index.html由前端路由再接管。第二proxy_pass http://127.0.0.1:8080/;注意末尾有斜杠表示把请求路径中/api开头的部分在转发时去掉“/api”前缀。如果你的后端接口是/api/user/list那nginx转发给后端的其实是/user/list跟本地开发时通过代理转发一样的效果。如果你的代码里接口路径本身不带/api前缀那这里就不用加斜杠直接写proxy_pass http://127.0.0.1:8080;即可斜杠要不要加是Nginx配置里最经典的坑我当年在这上面栽过跟头。配置好后执行nginx -t检查语法然后systemctl reload nginx加载配置。再启动后端jar建议用jdk的nohup方式后台运行nohup java -jar health-system-0.0.1-SNAPSHOT.jar app.log 21 。最后把云服务器的安全组和防火墙把80端口放行。浏览器访问http://服务器IP能看到页面就算部署成功了。4.3 部署经验日志查看与进程管理部署完不是终点你得学会看日志、管进程。后端日志是最重要的排障依据jar包启动失败、接口报错全部信息都在后台日志里。用nohup启动的话日志输出到app.logtail -100 app.log就能看到最近100行。如果是systemd管理的服务用journalctl -u health查看日志。我推荐用systemd配置成服务后可以设置开机自启、异常自动重启这样更稳妥。systemd服务配置示例[Unit] DescriptionHealth Management Server Afternetwork.target [Service] ExecStart/usr/bin/java -jar /opt/health-server/health-system-0.0.1-SNAPSHOT.jar Restartalways Userroot [Install] WantedBymulti-user.target把这段内容保存到/etc/systemd/system/health.service然后执行systemctl daemon-reload、systemctl enable health、systemctl start health服务就托管到systemd了。以后查看状态用systemctl status health看日志用journalctl -u health -f优雅停止用systemctl stop health。部署时还有个很容易被忽略的问题服务器MySQL的远程连接权限。默认情况下MySQL root用户只允许localhost登录但应用和数据库在同一台机器上所以这个问题不涉及。但如果你的数据库和应用不在同一台机器上就需要给应用创建一个远程访问账号并且设置授权的IP限制千万别直接用root远程登录。5. 常见问题排查与避坑经验5.1 开发期高频报错整理开发阶段遇到报错太正常了我把这个项目里最高频的错误整理成了一个速查表方便你遇到问题直接对号入座。先看数据库连接类的报错。Access denied for user rootlocalhost一般是密码错误或者用户权限问题检查application.yml里的账号密码是否跟本机MySQL一致。Public Key Retrieval is not allowed是连接MySQL 8.0时常见的问题在数据库连接URL后面加上allowPublicKeyRetrievaltrueuseSSLfalse就能解决。还有一个非常隐蔽的问题是时区报错提示The server time zone value is unrecognized处理方法是连接URL上加上serverTimezoneAsia/Shanghai。再看后端启动类的报错。比如Port 8080 was already in use说明有别的程序占用了8080端口Mac/Linux用lsof -i:8080、Windows用netstat -ano | findstr 8080找到占用进程并结束它。Consider defining a bean of type xxxMapper in your configuration一般是Mapper接口没加Mapper注解或者启动类上没加MapperScan扫描。这个报错每天都会看到但解法来来回回就那么几个记住就行。5.2 前后端联调时最容易翻车的几个点前后端联调是很多新手最痛苦的一环。本地开发和线上部署都可能遇到跨域问题但排查思路完全不同。开发阶段跨域问题的排查顺序是第一确认vue.config.js里代理是否配置正确改了配置要重启npm run serve才能生效。第二确认前端请求的baseURL是否以/api开头代理匹配的是路径前缀。第三确认后端接口路径是否跟代理目标完全对应。如果你代理配置/api到http://localhost:8080那么前端请求/api/user/list就会被转发到http://localhost:8080/user/list后端接口的GetMapping路径应该是/user/list而不是/api/user/list这是新手最容易搞混的点。线上部署阶段跨域问题基本是通过Nginx的反向代理解决原理跟开发阶段的代理类似。如果线上遇到了请求不到数据的问题先在服务器上直接curl一下后端接口curl http://127.0.0.1:8080/user/list看接口是否正常返回如果正常问题定位在Nginx配置如果不正常问题定位在后端服务。5.3 部署后的运行维护事项部署完成只是开始运行期间还会遇到各种问题。前端页面白屏首先看浏览器控制台报什么错如果是Failed to load resource: 404多半是静态资源路径不对排查Nginx的root配置是否指向了dist目录以及Vue打包时base配置是否设置成了./相对路径。接口全部404优先检查Nginx里location /api/的proxy_pass是否写对了。有些同学把后端jar包重启了但没重新加载Nginx配置也会导致类似问题nginx -t检查语法后要执行systemctl reload nginx才能真正生效。登录时验证码或者登录接口报错先看后端日志里有没有异常堆栈有的话顺着堆栈往下查。要是日志里根本没有请求记录说明请求压根没到后端问题还在Nginx代理那一层。数据库连接时断时续大概率是连接池配置问题。MySQL默认wait_timeout是8小时如果连接池没有相应的空闲回收机制长时间不操作后再访问就报连接超时。这个问题在课程设计阶段不容易暴露但如果你把项目挂服务器上两三天再访问就会遇到。解决办法是在SpringBoot的配置文件中设置连接池空闲回收时间比如Druid的minEvictableIdleTimeMillis和timeBetweenEvictRunsMillis或者将MySQL的wait_timeout改大。这个问题在面试时被问到的概率也不低最好能说出来。我实际操作中的经验是部署完成后一定要写一个README.md把启动步骤、默认账号、配置文件修改的地方全部记下来。不要高估自己的记忆力隔一个月再回来维护项目看到陌生的代码和配置如果没有文档光想起来当初为什么这么配就能花掉半天。写了文档下次部署或者交接给别人的时候直接复制命令就行省心太多。这个项目虽然叫“健康管理系统”但本质上是一套最标准的前后端分离全栈应用。把这类项目完整做一遍SpringBoot的接口开发、MyBatis-Plus的数据操作、Vue的组件化开发、Nginx的部署配置你都能过一遍手基础的技术栈算是彻底打通了。后面如果你还有精力可以往里面加一些新的东西比如用ECharts做更丰富的可视化报表、用WebSocket做实时健康数据推送、或者接一个AI大模型接口来做健康建议的自动生成——这些扩展方向都能让这个项目在答辩的时候更有亮点。最后再分享一个小技巧代码写完后花点时间把项目结构整理得清清楚楚接口注释写完整README写到位这件小事在答辩和面试时带给你的回报远超你的想象。本文还有配套的精品资源点击获取
返回列表