ARTICLE DETAIL

资讯详情

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

SpringBoot+Vue疾病防控系统平台设计与实现:从数据库到部署全流程

SpringBoot+Vue疾病防控系统平台设计与实现:从数据库到部署全流程 SpringBoot Vue 做的疾病防控综合系统平台几乎是 Java Web 方向毕设里最典型也最实用的一类选题。很多同学一听到这个题目就觉得是“大而全的管理系统”其实把它拆开看无非就是用户注册登录、健康信息上报、疫苗接种记录、资讯发布和数据统计这几个核心模块。真正的价值不在“多”而在于每个模块能不能讲清楚、跑通并且和数据库、SQL 脚本、接口文档对得上。这套内容适合两类人参考一是准备做 Java Web 毕设、想拿一个完整项目练手的人二是简历上需要一个前后端分离项目、想在面试里聊 SpringBoot 实际用法的人。如果你已经有了一些基础但没有把一个项目从数据库建表、后端接口、前端页面到部署完整走通过那这篇内容可以在你动手前把所有环节梳理干净减少试错成本。后面讲到的方案都是按一套可复现的常规做法展开的拿到源码和 SQL 脚本之后按这个思路去理解、去改、去扩展比自己对着代码猜要快得多。1. 项目整体设计与技术选型思路1.1 为什么选 SpringBoot Vue 这套组合先说技术栈。SpringBoot 在 Java Web 领域的地位不用多讲它内嵌 Tomcat、自动配置、约定大于配置能把以前 SSM 框架里一堆繁琐的 XML 配置省掉。Vue 的优势是组件化开发和前后端分离页面与后端通过 JSON 交互边界清晰。两者组合起来后端只负责提供 RESTful 接口前端只负责渲染页面和交互开发效率比 JSP Servlet 那套老方案高出一大截。在毕设阶段这套组合还有另外两个实际好处。第一是答辩好讲每一层都能单独拎出来SpringBoot 的自动配置、JWT 认证、Vue 的组件通信、路由守卫知识点覆盖面广评委老师问到哪一块你都有话可说。第二是就业认可度高现在企业里的 Java 项目尤其是中小型管理系统前后端分离 SpringBoot Vue 是主流形态做完这个项目后去看 SpringBoot 面试题很多都能对上号。有人会问为什么不选 JSP 或者 SSM我见过不少头歌上的 Java Web 课设还是老一套写 JSP 加 Servlet开发确实快但代码耦合重调试体验差论文里也很难写出深度。用 SpringBoot Vue哪怕模块比老项目少技术含量和工程化程度都是明显更高的。同类毕设里像“基于 Java Web 的健康饮食推荐系统”那种题目本质上也是这套架构无非换了一个业务领域。技术栈选对了后面的代码量和维护成本都能控制下来。1.2 业务模块拆解与用户角色疾病防控综合系统平台不是一个模糊的“管理系统”它至少要承载两类角色、两条业务线。第一类角色是普通用户。注册登录之后可以填写每日健康信息包括体温、咳嗽、乏力等症状标记、当前所在地和备注可以查看自己的历史上报记录可以查询自己的疫苗接种记录还可以浏览平台发布的防控资讯和科普文章。第二类角色是管理员。管理员负责审核用户、查看全量上报数据、维护疫苗批次与接种记录、发布资讯内容并通过数据看板查看整体趋势比如近一周上报人数、体温异常人数、各类症状分布占比等。有些需求里还会加一个“网格员”或“审核员”角色其实就是多一个 role 字段控制菜单显隐不需要单独建表。这两条业务线合在一起系统就不再是空壳。前端普通用户看到的是一套简洁的表单和记录后台管理员看到的是数据表格和统计图表。模块之间靠 user_id 这个外键逻辑串联结构清楚也方便在论文里画业务流程图。需要注意不要一上来就加很多花哨功能比如在线问诊、消息推送、GIS 地图毕设的核心是能完整跑通、能讲明白功能点多不等于完成度高。1.3 前后端分离架构与目录规划项目采用前后端分离我习惯分成 health-server 和 health-web 两个目录。后端是 Maven 单模块工程包结构固定为 controller、service、mapper、entity、config、common 六层前端用 Vue CLI 或 Vite 创建目录里放 views、router、api、store、components。这里有一个特别重要的经验开发顺序不要乱。我建议的顺序是“SQL 脚本 → 表结构 → 后端实体 → Mapper → Service → Controller → 接口文档 → 前端页面”。很多同学一上来就写后端接口写到一半才建表结果前端联调时发现接口参数对不上字段名也不统一返工成本极高。后端接口的 URL、请求参数、响应结构应该在建表之后、写前端之前就固定下来。如果你用的是 IDEA 创建 SpringBoot 项目可以直接用 Spring Initializr 勾选依赖后面再手动补 MyBatis Plus 和 JWT 相关依赖。Vue 工程创建好之后优先把 axios 封装和路由守卫写好这两个基础工具越早定下来后面写业务页面越顺手。2. 数据库设计与 SQL 脚本的实现细节2.1 核心数据表结构与字段设计这套系统的核心数据表我一般设计五张sys_user、health_report、vaccination_record、health_info、sys_admin_log。毕设里如果没有操作日志的需求sys_admin_log可以去掉但前面四张是必须有的。sys_user是用户主表字段包括 id、username、password、real_name、phone、id_card、role、avatar、status、create_time。这里有两个容易踩坑的地方。第一password 字段千万不要存明文哪怕项目简单也要用 BCrypt 加密数据库里存的是$2a$10$开头的哈希串后面写 JWT 登录时直接跟 Spring Security 的加密逻辑对齐。第二id_card 字段建议加唯一索引身份证号作为业务上识别“一个人是否重复注册”的关键标识比 username 更可靠。health_report是健康上报表字段建议id、user_id、report_date、temperature、cough、fatigue、is_normal、address、remark、create_time。temperature 用 decimal(4,1)比如 36.5而不是 floatcough 和 fatigue 用 tinyint(1) 表示 0/1is_normal 是综合判断结果也就是体温正常且无咳嗽乏力症状时置为 1。report_date 用 date 类型方便按天做统计去重同一用户同一天只能有一条记录这个唯一性在接口层做校验表结构上用普通索引即可。vaccination_record字段包括 id、user_id、vaccine_name、dose_number、hospital、vaccinate_date、create_time。疫苗名称不建议用字典表关联直接在业务表里存字符串因为毕设系统里疫苗种类有限做成字典反而增加联表复杂度。dose_number 表示第几针比如 1、2、3页面展示时按数字传给前端即可。health_info是资讯表字段为 id、title、summary、content、cover_image、type、publish_status、publish_time。其中 type 可以区分“科普知识”和“通知公告”publish_status 控制是否在前端展示。2.2 表关系、索引与命名约定表关系方面sys_user和health_report是一对多sys_user和vaccination_record也是一对多。我建议不要加物理外键原因很实际用 MySQL 的 InnoDB 物理外键虽然能保证约束但导入数据、删数据、联表查询时都比较死板毕设项目逻辑外键完全够用在 Mapper 里 JOIN 或嵌套查询即可。如果你论文里需要画 ER 图逻辑外键也能正常表达。索引方面不要每个字段都建索引反而拖慢写入。我一般只建三类sys_user.username唯一索引、sys_user.id_card唯一索引、health_report.report_date普通索引。最后一个索引在统计报表时特别重要。没有它查近 7 天上报趋势就会全表扫描数据量到几万条后响应会明显变慢。命名约定上表名用下划线小写实体类用驼峰MyBatis Plus 默认开启驼峰转换能自动把report_date映射为reportDate。这里要特别注意如果你在 SQL 脚本里表的字段名和实体类属性名不一致一定要在实体类上用TableField注解手动指定否则联调阶段会出现字段全是 null 的诡异问题。2.3 SQL 脚本编写方法和导入注意点SQL 脚本的编写顺序有讲究先 DROP 再 CREATE保证脚本可以重复执行。然后创建数据库、USE、创建表、插入初始化数据。字符集统一用 utf8mb4排序规则utf8mb4_general_ci引擎 InnoDB。初始管理员账号要插入一条数据username 为 adminpassword 为 BCrypt 加密后的哈希串不要写明文。下面给出一个简化但可直接参考的脚本片段DROP DATABASE IF EXISTS health_platform; CREATE DATABASE health_platform DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE health_platform; DROP TABLE IF EXISTS sys_user; CREATE TABLE sys_user ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT 主键, username VARCHAR(50) NOT NULL COMMENT 登录名, password VARCHAR(100) NOT NULL COMMENT BCrypt加密密码, real_name VARCHAR(50) DEFAULT NULL COMMENT 真实姓名, phone VARCHAR(20) DEFAULT NULL COMMENT 手机号, id_card VARCHAR(18) DEFAULT NULL COMMENT 身份证号, role TINYINT NOT NULL DEFAULT 1 COMMENT 角色 1普通用户 2管理员, avatar VARCHAR(255) DEFAULT NULL COMMENT 头像URL, status TINYINT NOT NULL DEFAULT 1 COMMENT 状态 1正常 0禁用, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_username (username), UNIQUE KEY uk_id_card (id_card) ) ENGINEInnoDB COMMENT 用户表; DROP TABLE IF EXISTS health_report; CREATE TABLE health_report ( id BIGINT NOT NULL AUTO_INCREMENT, user_id BIGINT NOT NULL, report_date DATE NOT NULL, temperature DECIMAL(4,1) NOT NULL, cough TINYINT NOT NULL DEFAULT 0, fatigue TINYINT NOT NULL DEFAULT 0, is_normal TINYINT NOT NULL DEFAULT 1, address VARCHAR(255) DEFAULT NULL, remark VARCHAR(500) DEFAULT NULL, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_report_date (report_date), KEY idx_user_id (user_id) ) ENGINEInnoDB COMMENT 健康上报表;导入时建议用 Navicat 或 MySQL 命令行执行source。如果你从别人手里拿到的 SQL 脚本在导入时报错优先排查三件事脚本头部是否包含了CREATE DATABASE语句、是否指定了 utf8mb4、外键依赖顺序是否合理。MySQL 5.7 和 8.0 对脚本的兼容性整体没问题但如果你用的驱动是 8.x连接串里记得加上时区和编码参数否则后面 SpringBoot 启动时会报错。3. 后端 SpringBoot 接口开发与接口文档编写3.1 项目搭建、核心依赖与配置用 IDEA 创建 SpringBoot 项目时Spring Initializr 里勾选 Spring Web、MySQL Driver、LombokJava 版本选 8 或 11 都行。SpringBoot 版本我建议固定用 2.7.x不要贪新。3.x 虽然很火但包名从 javax 迁到 jakarta很多老教程和老依赖会踩坑对毕设来说没必要折腾。项目创建完成后再手动引入 MyBatis Plus、JWT、Hutool 这几个依赖。核心配置文件application.yml如下server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/health_platform?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai username: root password: 123456 jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8 default-property-inclusion: non_null mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0 jwt: secret: your-long-secret-key expire: 604800这里有两个值得注意的配置。第一Jackson 的default-property-inclusion: non_null可以让返回 JSON 时自动忽略 null 字段这样前端拿到的数据结构更干净也避免答辩时被问“为什么返回一堆 null”。第二MyBatis Plus 的log-impl在开发阶段一定要打开SQL 打印到控制台能解决 70% 的联调问题上线前再关掉即可。如果在 IDEA 里想让项目启动有点辨识度可以用 SpringBoot Banner 生成器做一个自定义启动横幅把 ASCII 艺术字放到banner.txt。这东西不影响功能但答辩演示时能加分团队协作时也利于区分环境。3.2 核心接口设计与实现逻辑接口设计不用追求 RESTful 到极致按照业务模块划分即可。我列一下这套系统最核心的接口清单模块接口方法说明用户认证/api/auth/registerPOST注册用户认证/api/auth/loginPOST登录返回 JWT健康上报/api/report/submitPOST提交当天健康信息健康上报/api/report/myListGET分页查询我的上报记录健康上报/api/report/pageGET管理员分页查询全量记录疫苗接种/api/vaccine/myListGET查询我的接种记录疫苗接种/api/vaccine/addPOST管理员添加接种记录资讯模块/api/info/listGET获取资讯列表资讯模块/api/info/detailGET获取资讯详情数据统计/api/stats/trendGET近7天上报趋势以健康上报为例提交接口的 Controller 逻辑大概长这样RestController RequestMapping(/api/report) public class ReportController { Resource private ReportService reportService; PostMapping(/submit) public ResultString submit(RequestBody Valid ReportSubmitDTO dto) { Long userId UserContext.getUserId(); reportService.submit(userId, dto); return Result.success(上报成功); } }提交之前要判断当天是否已经上报这个逻辑放在 Service 里避免重复提交。如果发现同一天已有记录直接抛出业务异常由全局异常处理器转换成统一返回结构。判断体温是否正常、是否有咳嗽或乏力是在submit方法里计算好is_normal再落库而不是让前端传一个布尔值。这个细节看起来小但答辩时能体现你对“后端业务处理”的理解。统计接口的实现要注意查询效率。近 7 天趋势可以用一次GROUP BY report_date查出再用 Java 侧补齐没有数据的日期避免前端图表的 x 轴缺空。体温异常人数统计用SUM(CASE WHEN is_normal 0 THEN 1 ELSE 0 END)的方式一条 SQL 就能拿到多个汇总字段。3.3 接口文档从零写起接口文档对于毕设项目来说不是可选项。论文里需要截图、答辩时需要展示、前后端联调需要对齐没有文档就只能靠口口相传效率极低。文档不一定要用 Swagger。我见过很多项目集成 Knife4j 后接口列表倒是自动生成了但注释不写、参数说明不填生成的文档根本没法看。毕设项目我更建议手写一份 Markdown 接口文档结构固定、内容可控、导师看起来也舒服。如果你喜欢工具化一点可以在 Apifox 里调试接口后直接导出或者用 Cool Request 导出接口文档格式统一省去手敲的时间。工具导出有个问题——它只能导出你调试过的接口遗漏的接口需要你在文档里手动补充说明。接口文档建议按这个结构组织项目概述、通用说明Base URL、字符编码、认证方式、统一返回结构、每个模块的接口定义、错误码说明。每个接口必须写清楚 URL、请求方法、请求头、请求体 JSON 示例、响应体 JSON 示例、字段说明表格。下面给一个接口文档示例片段你可以直接套用### 1. 提交健康上报 - 接口地址POST /api/report/submit - 请求头Authorization: Bearer {token} - 请求体 { reportDate: 2024-06-01, temperature: 36.8, cough: 0, fatigue: 0, address: XX市XX区XX街道, remark: } - 字段说明 | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | reportDate | string | 是 | 上报日期格式 yyyy-MM-dd | | temperature | number | 是 | 体温保留一位小数 | | cough | int | 是 | 是否咳嗽0否 1是 | | fatigue | int | 是 | 是否乏力0否 1是 | | address | string | 否 | 当前所在地 | | remark | string | 否 | 备注信息 | - 响应示例 { code: 200, message: 上报成功, data: null }写接口文档时有一个习惯值得学习一边写代码一边更新文档不要等全部写完再补。因为等全部写完的时候你大概率已经忘了某些接口的参数设计初衷文档质量会直线下降。3.4 JWT 认证与权限控制的实现JWT 在这套系统里的流程并不复杂用户登录成功后后端根据用户 id 和角色生成 token前端把它存到 localStorage之后每次请求在 Authorization 头带上 token后端拦截器校验合法性并解析出用户信息。实现上可以用一个 HandlerInterceptor 配合 WebMvcConfigurer 来完成。Component public class JwtInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (OPTIONS.equalsIgnoreCase(request.getMethod())) { return true; } String token request.getHeader(Authorization); if (token ! null token.startsWith(Bearer )) { token token.substring(7); } // 解析token失败则直接返回401 Long userId JwtUtil.parseToken(token); if (userId null) { response.setStatus(401); return false; } UserContext.setUserId(userId); return true; } Override public void afterCompletion(...) { UserContext.clear(); } }需要放行的路径有/api/auth/register、/api/auth/login、资讯列表等不需要登录就能访问的接口。管理员接口还要单独校验角色可以在拦截器放行后由注解或 Controller 内判断角色字段来实现。这里不要过度设计用RequireRole自定义注解加 AOP 会引入额外的复杂度直接在需要管理员的接口里加一个角色判断方法简单可靠。如果项目里有文件上传需求比如上传 PDF 附件或头像可以再写一个全局过滤器对上传内容做基础校验防止文件名和内容里夹带 XSS 攻击脚本。这个在答辩时提一句“我在全局过滤器里做了上传文件的 XSS 过滤”就能把话题往安全方向引但不要写太复杂的安全框架进去毕设阶段把 SQL 注入和 XSS 的基本防护讲清楚就够。4. 前端 Vue 页面实现与前后端联调4.1 Vue 环境搭建与项目初始化Vue 环境配置是很多新手第一步就被卡住的地方。Node.js 一定要装 LTS 版本不要追求最新我用的是 18 或 20 都稳定。npm 在国内建议配淘宝镜像不然创建项目时下载依赖慢到怀疑人生。创建项目有两种方式Vue CLI 的vue create health-web或者 Vite 的npm create vitelatest health-web -- --template vue。Vite 启动更快用的人越来越多推荐用 Vite。项目初始化后安装核心依赖npm install axios vue-router pinia element-plus echarts这里有一个细节要提醒Element Plus 组件库体积不小如果全部按需引入会花很多时间配置毕设项目直接用全量引入就行页面一多省下的时间远比优化那几百 KB 首屏体积更值。安装好后把 Vue DevTools 插件装上浏览器里调试组件数据、路由状态会方便很多。4.2 核心页面与组件实现页面规划建议按功能走至少要有登录注册页、用户首页、健康上报页、我的记录页、管理员布局页和统计看板页。组件复用这块不要为了抽象而抽象把真正会重复的部分拆出来就够了比如分页表格、状态标签、日期选择器。登录页面用el-form做表单校验rules 里设置用户名必填、密码长度校验。登录成功后把 token 和用户角色存到 Pinia 或 localStorage。健康上报页面是企业关键页面表单字段对应接口请求体传参。体温用el-input-number控制精度 1 位小数症状用el-radio-group切换 0/1上报日期默认当天禁用未来日期。如果项目里每个用户都要看自己的上报状态用户首页可以做一个简单的统计卡片区近 7 天上报次数、异常天数、下一次上报倒计时。这里不需要真实计算直接调统计接口用返回值渲染即可。表格页面用el-table加el-pagination后端返回分页对象后把 total、records 对应到分页组件不要自己手写分页逻辑。如果后续想把系统扩展到移动端VSCode Vue 那套工程可以平移思路到 uni-app 上用同一套 vue 语法生成 H5 和小程序。毕设阶段不建议一上来就做三端先把 PC 端管理后台打磨好价值已经足够。Vue 组件里如果做自定义表单封装可以用自定义 v-model 的模式让父组件通过v-model直接绑定子组件值这也是面试环节常被问到的点。4.3 请求封装、路由守卫与动态路由axios 封装是整个前端工程的基石。baseURL 设置为/api开发环境通过 Vite 代理转发到后端 8080避免跨域生产环境由 Nginx 统一转发。请求拦截器里从 storage 取出 token 放到请求头响应拦截器统一判断 codecode 为 401 时清掉登录态跳转登录页code 非 200 时弹出消息提示。const service axios.create({ baseURL: /api, timeout: 10000 }) service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers[Authorization] Bearer token } return config }) service.interceptors.response.use(res { const { code, message, data } res.data if (code 200) { return data } if (code 401) { router.push(/login) } ElMessage.error(message || 请求失败) return Promise.reject(new Error(message)) })路由守卫写在router/index.js里beforeEach钩子检查目标路由是否需要登录权限。管理员后台的路由列表不写在静态路由表里而是等待登录后根据角色动态生成用router.addRoute来实现动态路由。这样普通用户通过 URL 直接跳转到管理页面时因为路由压根不存在会被守卫拦在登录页或 404 页。这就是 Vue 动态路由配合权限控制的常见思路。关于路由参数列表页跳转详情页时用 query 或 params 传递 id二选一就行不要混用。比如router.push({ path: /info/detail, query: { id: row.id } })在详情页通过route.query.id获取。这里的 id 如果是 Long 类型前端拿到的是字符串传回后端时没问题显示到表格里也不会丢精度算是绕开了 Long 精度问题的一个土办法。4.4 前后端联调与部署细节联调阶段最怕的不是接口报错而是接口“不报错但数据不对”。核对顺序应该是URL 是否正确、请求参数名是否与接口文档一致、响应结构是否与前端解析逻辑匹配。先用浏览器 F12 Network 面板看请求和响应很多问题一眼就能定位。部署方面前端执行npm run build生成 dist 目录丢到 Nginx 的 html 目录即可。这里有个大坑要提前说如果 Vue 路由用的 history 模式刷新二级页面会 404需要在 Nginx 里配置location / { try_files $uri $uri/ /index.html; }后端打包用mvn clean package -DskipTests生成 jar 后直接nohup java -jar health-server.jar 启动。如果机器上有 Docker也可以写一个 Dockerfile把 jar 打成镜像再跑一条命令就能启动整个服务这在简历上能写一笔“熟悉 Docker 部署 SpringBoot 项目”。数据库还是建议用宿主机 MySQL容器里跑数据库对毕设来说没必要数据备份和文件映射都要额外配置增加学习负担。5. 常见问题、排查技巧与答辩建议5.1 数据库与 SQL 脚本导入的坑第一个高频问题是连接数据库报时区错误或 SSL 错误。SpringBoot 连接 MySQL 8.x 时url 里必须写serverTimezoneAsia/Shanghai和useSSLfalse否则启动直接挂。第二个问题是 SQL 脚本导入乱码打开脚本文件时确认编码是 UTF-8Navicat 导入时也选 UTF-8表结构里字符集再强制定一次 utf8mb4三重保险。第三个问题比较隐蔽从别人那里拿到的初始化密码是明文比如123456但后端登录校验用的 BCrypt导致怎么都登录不上。遇到这种情况不要怀疑密码错误而是手动生成一个 BCrypt 哈希串更新到数据库。Hutool 工具类一行代码就能生成BCrypt.hashpw(123456)。这也是为什么我强烈建议 SQL 脚本里直接写哈希串别省这几分钟省下来的是联调阶段的一堆麻烦。5.2 跨域、端口与打包部署问题开发环境跨域不要在后端加CrossOrigin硬解更优雅的做法是前端 Vite 配置代理。Vite 项目在vite.config.js里加server: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } }这样前端请求/api/report/list会被代理到后端 8080浏览器看到的是同源请求不触发 CORS。如果后端接口确实需要支持跨域访问再写一个 CorsConfig 配置类统一允许即可但不要让 Controller 里到处贴CrossOrigin注解。端口占用是另一个常见问题。后端 8080 被占用要么改server.port要么在启动时用--server.port8081临时指定。前端 Vite 默认 5173如果被占用会自动换端口但换端口后接口代理配置如果写死 5173跨域问题会回来。还有一个容易被忽视的点SpingBoot 版本太高时某些 Starter 依赖会不兼容项目启动报各种 NoSuchMethodError解决方式就是固定用 2.7.x别在毕设阶段追新。5.3 联调不一致的典型问题与排查技巧后端接口返回正常但前端表格里显示不出来十有八九是字段名对不上。数据库的report_date经过 MyBatis Plus 驼峰映射变成reportDateJackson 序列化输出也是reportDate前端却按接口文档写了report_date自然取不到值。排查方法很简单F12 看接口响应体的实际字段名再和前端代码对比。想稳定解决就从接口文档开始统一约定前后端都按驼峰字段名来写。Long 类型精度丢失是第二个高频问题。Java 端 Long 类型的 id在序列化成 JSON 传给前端后JavaScript 的 Number 精度只有 53 位一旦 id 超过这个范围末两位就会变成 0。解决方案有两种一种是在 id 字段上加JsonSerialize(using ToStringSerializer.class)让 Long 以字符串形式输出另一种是接口文档里直接把 id 定义成 string。推荐第一种对代码侵入小也不影响数据库存储。时间格式不对是第三个坑。LocalDateTime 默认序列化是一串 T 分隔的格式非常难看。在application.yml里配置spring.jackson.date-format和time-zone后LocalDateTime 才会输出为yyyy-MM-dd HH:mm:ss。如果个别字段想用日期格式就在实体类字段上写JsonFormat(pattern yyyy-MM-dd)。这些细节不解决前端表格里的时间列就会是乱糟糟的 ISO 格式答辩展示观感差很多。5.4 毕设答辩要点与项目扩展方向答辩时不要照着 PPT 念评委老师更想听你“把一个点讲透”。我建议准备三条主线数据库设计思路、JWT 认证流程、数据可视化查询性能。比如被问到“这个系统有什么难点”不要说没有难点把“近 7 天趋势统计需要补全无数据日期”这种小问题讲出来反而显得你深入做过。如果被问到 SpringBoot 面试题里的经典问题比如自动配置原理可以从SpringBootApplication讲到spring.factories再提一句“ConditionalOnClass 按条件装配”这一段背熟面试和答辩都通用。这个项目的扩展方向其实很多。资讯模块想做得更完整可以接 Redis 缓存热点文章列表降低数据库压力用户提交通知可以引入 SpringBoot 整合 ActiveMQ 或 RabbitMQ做异步消息提醒头像和附件存储可以用 MinIO 替代本地目录既能锻炼分布式存储实践又不影响原有表结构做一些资讯文本分析时可以在 SpringBoot 里集成 HanLP 分词自动抽取关键词这个在论文里是很亮眼的功能。如果往可视化方向走可以引入 ECharts 地图做区域分布热力图比普通柱状图更有冲击力。资讯里如果要放科普视频前端用 video.js 播放 m3u8 流媒体格式也能实现。当我实际在做这类系统时我的习惯是先花半天把 SQL 脚本和接口文档定下来再开始写后端代码。拿到源码和文档之后也建议你先倒着读接口文档 → 表结构 → 核心接口实现 → 前端页面而不是直接双击运行。我见过太多人项目一跑就报错报错就换文件换完就删最后什么都没学到。让你通过答辩或者面试的不是项目跑得多顺而是你对某一条核心链路能不能从头讲到尾。最后再分享一个实用习惯接口文档里的响应体字段只要写清楚了类型和示例值前端同学基本不会每天追问“返回里的 xx 字段在哪”这类问题。这个习惯放大到团队协作里是提升开发效率最快的一招。
返回列表