news 2026/9/9 9:33:05

SpringBoot+Vue校园疫情防控管理系统:从需求拆解到部署答辩全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot+Vue校园疫情防控管理系统:从需求拆解到部署答辩全解析

做了这么多年的 Java 后端,带过的学生、看过毕设源码不计其数。要说最适合拿来当课设或毕设的题目,SpringBoot+Vue 校园疫情防控信息管理系统绝对算一个典型。它听起来有现实背景,做起来业务链路完整,技术栈又正好踩中现在企业里最主流的 Java 后端+前端分离开发模式。今天我不打算给你贴一堆网盘链接然后让你自己啃,而是把这个项目从需求拆解、数据库设计、前后端实现到部署答辩,一条线捋清楚。你拿到源码以后,能看懂它的每一层逻辑,也知道改哪里能变成自己的东西。

这套系统核心围绕“健康上报—行程审批—异常监测—统计分析”这条主线展开,角色上分成学生、教师/辅导员、管理员三层,后端用 SpringBoot + MyBatis-Plus + MySQL,前端用 Vue + Element UI + ECharts,登录认证走 JWT。下面我按一个实际项目的推进顺序,把每个环节的关键设计点和踩坑经验都讲透。

1. 这类系统为什么能成为毕设/课设的“常青树”

先聊一个很实际的问题:为什么每年都有人选这个方向。很多同学挑毕设题目,第一奥求是“能做出来、能讲清楚、能过答辩”。校园疫情管理系统恰恰在这三件事上得分很高。

1.1 需求真实,业务链路不是凭空编的

一个项目好不好,首先看业务有没有真实场景支撑。校园疫情防控信息管理系统对应的是实际管理痛点:每天要收集学生的健康信息、体温数据、行程轨迹,要审批返校/离校申请,要能快速知道某个班级某个时间段有多少人异常。这些需求不需要你绞尽脑汁去虚构,需求分析章节写起来非常自然,评审老师一看就知道这个系统解决的是真问题。

核心业务链条大概是这样:

  • 学生每日提交健康上报,包含体温、健康状况、是否去过风险区域等;
  • 辅导员可以查看本班学生的上报情况,对异常数据做标记和处理;
  • 学生发起请假/返校申请,提交行程信息,老师在线审批;
  • 管理员维护班级、用户、公告等信息,查看全校的统计报表;
  • 系统自动按日、按周、按班级统计上报率和异常人数,用图表展示。

这条链路把 CRUD(增删改查)做活了。它不是一个单纯的学生信息管理系统,而是有“提交—审批—统计”这种完整业务闭环的,做出来以后逻辑上很有说服力。

1.2 技术栈正好覆盖主流就业技能面

SpringBoot + Vue + MySQL 这个组合,在中小型管理系统里几乎是标准答案。Java 后端负责接口和业务逻辑,Vue 负责页面和交互,MySQL 负责数据存储,前后端通过 JSON 交互。作为一个学生项目,它既不会因为技术太偏门让评审看不懂,也不会因为难度太高做不完。

具体到细分技术点:

  • 后端:SpringBoot、MyBatis-Plus、JWT、BCrypt 密码加密、Lombok;
  • 前端:Vue 2 或 Vue 3、Vue Router、Axios、Element UI / Element Plus、ECharts;
  • 数据库:MySQL 5.7 或 8.0、Navicat 可视化工具。

这套技术组合在课设/毕设里属于“中规中矩又足够专业”的选择。你答辩时可以说“我用了 MyBatis-Plus 简化单表操作,用 JWT 做无状态登录认证,用 ECharts 做数据可视化”,每一项都能展开讲,不至于被问倒。

1.3 源码学习的正确姿势:先拆结构再动手改

很多同学拿到源码第一件事就是配环境、跑起来,跑通了就觉得自己会了,答辩时一问三不知。我的建议是拿到任何 SpringBoot+Vue 项目后,按这个顺序去读:

  1. 先看数据库脚本,把表结构和每张表的用途搞明白;
  2. 再看后端 Controller 层的接口列表,对照前端页面,理解每个页面调了哪些接口;
  3. 然后看 Service 层的业务方法,理解接口内部做了什么事;
  4. 最后看 Vue 的 router 配置和 api 目录,理清页面跳转和接口调用的对应关系。

源码只是素材,你把它跑起来、拆开看、改几个功能,它才是你的。

2. 系统拆解:角色权限与核心业务流

这个系统的业务设计,说白了就是“不同的人看到不同的功能,做不同的事”。我以最常见的三角色模型来拆。

2.1 三角色与权限边界

权限设计是所有管理系统的地基。这里我用的是基于角色的访问控制(RBAC模型),也就是 用户→角色→权限 的映射关系。

角色主要功能
学生每日健康上报、行程申报、查看个人记录、查看公告
辅导员/教师查看本班学生上报情况、异常记录处理、请假/返校审批
管理员班级管理、用户管理、全量数据统计、公告发布、系统配置

后端控制权限的常见做法是在 Controller 方法上加角色注解,比如@PreAuthorize("hasRole('ADMIN')"),或者在拦截器里判断当前登录用户的角色。前端则是用路由守卫,根据角色过滤可访问的页面。两层配合才安全,不能只靠前端隐藏按钮。

2.2 三大核心业务闭环

  1. 健康上报闭环:学生每天打开系统点“上报”,填体温、健康状态、行程,系统记录时间和日期。关键点是“一天只能报一次或者允许补报”,这在后端要设计好校验逻辑。

  2. 行程审批闭环:学生发起请假/返校申请→填写目的地、交通工具、往返时间→相关老师审批→审批结果反馈给学生。这里建议做成流程式状态:待审批、已通过、已驳回。

  3. 异常监测与统计闭环:管理员和老师能按班级、按日期维度查看上报率、异常人数、风险地区分布。统计页用图表展示,背后就是 GROUP BY 之类的 SQL 查询。

2.3 建议增加的“加分项”功能

如果时间允许,可以加这几个功能,论文和工作量都会更扎实:

  • Excel 批量导入学生名单;
  • 疫苗接种情况登记;
  • 隔离/健康监测人员名单管理;
  • 首页数据看板,展示今日上报人数、未报人数、异常人数;
  • 消息公告推送。

3. 技术选型:为什么是这套组合而不是别的

我经常被学生问:老师,我用 JSP 行不行?我只能说,你用它做课设确实简单,但技术上就有点拿不出手了。下面我具体讲讲这套技术栈选择的理由。

3.1 后端为什么选 SpringBoot

SpringBoot 的好处在于“约定大于配置”,你不用像以前写 SpringMVC 那样搞一堆 XML 配置。内嵌 Tomcat、自动配置、起步依赖,让项目可以快速启动。

在校园疫情系统这个项目里,后端的主要职责是:

  • 提供 RESTful API 接口;
  • 做参数校验和业务校验;
  • 操作 MySQL 数据库;
  • 生成登录令牌并校验权限;
  • 处理跨域请求。

SpringBoot 的生态足够完善,网上资料也全,碰到问题搜索还能找到很多解决方案。对课设/毕设来说,这是一种“确定性”。

MyBatis-Plus 我特别提一句,它对单表 CRUD 基本上零 XML,BaseMapper里自带增删改查方法,代码量能少一半。查询的时候用LambdaQueryWrapper写条件,比手写 SQL 直观得多。

3.2 前端为什么选 Vue + Element UI

Vue 的核心优势是组件化和响应式。页面结构清晰,代码维护容易。配合 Element UI(Vue 2)或 Element Plus(Vue 3),你不需要自己写 CSS,表格、表单、弹窗、日期选择器直接拿来用,快速就能拼出一个后台管理界面。

ECharts 是用来做统计图表的。上报率趋势、班级异常人数对比、人员状态分布,用折线图、柱状图、饼图展示以后,整个系统的专业感立刻提升一个档次。

3.3 MySQL 8.0 的版本选择

现在新项目我一般建议直接用 MySQL 8.0。原因:

  • 8.0 是长期支持版本,默认字符集utf8mb4,支持中文更好;
  • 性能比 5.7 有提升,支持窗口函数;
  • 云服务器上现在装的基本都是 8.0,你本地用 8.0 可以避免环境不一致。

但要注意,MySQL 8.0 的默认认证方式是caching_sha2_password,早一点的驱动版本会出现连不上、报Public Key Retrieval is not allowed这类错误。解决方案有两个:把驱动升级到mysql-connector-java 8.0.x,或者在 JDBC URL 上加allowPublicKeyRetrieval=true。这细节很多人装完连不上就是因为这个。

4. 数据库设计:表结构划分与字段逻辑

数据库设计决定了项目的地基稳不稳。我建表的原则是“一个业务实体一张表,状态变化用字段表达”。这套系统我建议规划以下这些核心表。

4.1 用户与基础信息表

sys_user(用户表)

字段类型说明
idbigint主键
usernamevarchar(50)登录名,唯一
passwordvarchar(100)BCrypt 加密后的密码
real_namevarchar(50)真实姓名
rolevarchar(20)角色:STUDENT / TEACHER / ADMIN
class_idbigint所属班级,学生必填
phonevarchar(20)手机号
statustinyint是否启用:1启用 0禁用
create_timedatetime创建时间

class_info(班级表)

字段类型说明
idbigint主键
class_namevarchar(100)班级名称
gradevarchar(20)年级
head_teacher_idbigint辅导员用户ID

注意:班级和辅导员是关联的,这样老师登录后就能只看到本班学生数据,数据隔离通过class_id实现。

4.2 健康上报与行程记录表

health_report(健康上报表)

字段类型说明
idbigint主键
student_idbigint学生ID
report_datedate上报日期
temperaturedecimal(4,1)体温
health_statusvarchar(20)健康状态:正常/异常
is_risk_areatinyint是否去过风险区域
risk_area_detailvarchar(255)风险区域详情
remarkvarchar(255)备注
create_timedatetime提交时间

这里的关键设计是student_id + report_date组成唯一索引,用来保证一个学生一天只能有一条上报记录。这是防止重复提交的数据库级兜底方案,光靠后端判断是不够的。

travel_record(行程记录表)

用于记录学生近期的行程轨迹,字段包括:出发地、目的地、交通方式、出发时间、到达时间。这张表可以和学生填报的行程信息关联,也方便行程排查。

leave_approval(请假/返校审批表)

字段类型说明
idbigint主键
student_idbigint学生 ID
typevarchar(20)请假/返校
start_timedatetime开始时间
end_timedatetime结束时间
destinationvarchar(255)目的地
transportvarchar(50)交通工具
reasonvarchar(500)事由
statusvarchar(20)待审批/通过/驳回
audit_user_idbigint审批人 ID
audit_remarkvarchar(255)审批意见
create_timedatetime创建时间

4.3 公告与日志表

notice(公告表):标题、内容、发布人、发布时间。用于管理员发布通知。

如果还想记录谁在什么时候登录过系统,可以加一张login_log表,这对答辩时讲“系统安全性”是一个加分点。

4.4 建表的几个实用建议

  • 逻辑删除:每张表加deleted字段(默认0),MyBatis-Plus 配置逻辑删除后,删除操作自动变成更新。
  • 时间字段:create_timeupdate_time建议统一,用datetime类型。
  • 不强制用外键:在项目里我一般不用物理外键,靠代码逻辑维护关联关系。理由:数据量大时外键有性能损耗,而且用 MyBatis-Plus 这类框架时,逻辑更自由。这也符合很多企业实际开发的做法。
  • 唯一索引用足:比如账号唯一、每日上报唯一,提前在数据库层面拦住脏数据。

5. SpringBoot 后端实现要点

跑通源码和看懂源码是两码事。我挑几个核心部分,讲一下实现思路和关键代码逻辑。

5.1 项目结构分层

一个典型的后端结构是这样的:

src/main/java/com/example/epidemic/ ├── config/ // 跨域、MyBatis-Plus 配置 ├── controller/ // 接口层 ├── service/ // 业务层 │ └── impl/ ├── mapper/ // MyBatis-Plus Mapper 接口 ├── entity/ // 实体类 ├── common/ // 统一返回结果、异常处理 │ ├── Result.java │ ├── ResultCode.java │ └── GlobalExceptionHandler.java ├── utils/ // JWT、日期工具 ├── interceptor/ // 登录拦截器

统一返回结果Result是一个细节但很重要的设计。所有接口都返回{ code, message, data }这种结构,前端 axios 拦截器可以统一处理错误,而不是每个接口各写各的。答辩时可以讲这个是“统一响应规范,降低前后端联调成本”。

5.2 JWT 登录认证链路

JWT 的逻辑并不复杂,本质就是用户登录成功后,后端签发一个带签名和过期时间的 token 字符串给前端,前端每次请求把它放在请求头里,后端验证 token 合法就能知道用户是谁。

关键实现点:

  1. 登录接口接收用户名和密码;
  2. 在数据库查用户,用 BCrypt 校验密码;
  3. 校验通过后,生成 JWT,把用户 ID、用户名、角色放进 token 的 claims 里;
  4. 前端把 token 存到 localStorage 或 sessionStorage;
  5. 后端写一个拦截器,拦截除登录接口以外的所有请求,从 Header 里取 token 并解析。

拦截器里解析完 token 以后,可以把当前用户信息放到ThreadLocalRequestContext中,这样在 Controller 和 Service 里随时能拿到当前登录用户的 ID,不用每个接口都传一个 userId 参数,这也是很多新手想不到的优化点。

5.3 健康上报接口的业务逻辑

这个接口是系统的核心,它要处理的不仅仅是“插入一条数据”,而是三道校验:

  1. 学生是否已登录(拦截器已处理);
  2. 今天是否已经上报过(查health_report表中是否存在student_id + report_date相同记录);
  3. 体温、健康状态是否填写完整。

判断已上报的逻辑用 MyBatis-Plus 的LambdaQueryWrapper非常简洁:

LambdaQueryWrapper<HealthReport> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(HealthReport::getStudentId, studentId) .eq(HealthReport::getReportDate, LocalDate.now()); HealthReport exist = healthReportMapper.selectOne(wrapper); if (exist != null) { throw new BusinessException("今日已上报,请勿重复提交"); }

这里我特别强调一点:查询条件一定要用LambdaQueryWrapper,不要直接用字符串拼字段名。一个是防止 SQL 注入,另一个是编译期就能发现字段名写错的低级问题。

5.4 统计报表 SQL 小技巧

统计报表的核心是“按维度分组汇总”。比如:

  • 统计每天的上报人数,按日期分组;
  • 统计各班级的异常人数,按班级分组;
  • 统计某个时间段内的上报率趋势。

上报率这个是典型的字段逻辑。因为不是所有学生都会上报,所以要先查班级总人数,再查已上报人数,两个相除。一条 SQL 大致如下:

SELECT c.class_name, COUNT(DISTINCT s.id) AS total_student, COUNT(DISTINCT h.student_id) AS reported_student FROM class_info c LEFT JOIN sys_user s ON s.class_id = c.id AND s.role = 'STUDENT' LEFT JOIN health_report h ON h.student_id = s.id AND h.report_date = #{date} GROUP BY c.id

这个 SQL 里的ON 后面加条件是重点,它和WHERE的区别在于:LEFT JOIN时放在ON后面的条件不会过滤左表数据,可以保留未上报的学生记录,从而得出“未上报人数”。很多新手在这里写成WHERE h.report_date = #{date},结果没上报的学生直接被过滤掉了,统计永远等于100%,这个坑要注意。

5.5 跨域问题与配置

前后端分离开发时,前端跑在http://localhost:8080(或 5173),后端跑在http://localhost:9090,端口不同就存在跨域。后端需要在 Config 类里配置 CORS:

@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }

注意allowedOriginPatterns("*")allowCredentials(true)要配合使用,只写前者不带后者,或者顺序不对,都会导致请求异常。这也是课设阶段最常见的跨域报错来源。

6. Vue 前端实现要点

6.1 vue 项目的标准搭建

现在创建 Vue 项目,我建议用官方脚手架。Vue 2 的话用vue create project-name,Vue 3 用npm create vite@latest。安装依赖之前,Node 环境一定要先配好。很多同学栽在npm install报错上,八成是 Node 版本和依赖不兼容。

这里给一个版本参考:

  • Vue 2.6 + Element UI 2.15 + Node 14/16
  • Vue 3.2 + Element Plus 2.x + Node 16/18

Vue 2 的生态资料多,很多毕设源码还是它;Vue 3 是趋势,但配套组件库的使用习惯和小细节跟 Vue 2 有差异。你要是拿现成源码,建议源码用什么版本你就用什么版本,不要自行升级大版本,否则一堆兼容性问题。

6.2 路由拆分与权限控制

前端路由的核心是把页面路径和组件映射起来。管理系统的路由一般分成两块:公共路由(登录页、首页)和需要登录的路由(不同角色的业务页面)。

Vue Router 守卫控制未登录跳转,逻辑很经典:

router.beforeEach((to, from, next) => { const token = localStorage.getItem('token') if (!token && to.path !== '/login') { next('/login') } else { next() } })

如果想做到角色级别的菜单控制,可以在路由的 meta 里配置角色,然后在生成菜单时过滤。比如:

{ path: '/report', component: ReportPage, meta: { title: '每日上报', roles: ['STUDENT'] } }

菜单渲染时filter(item => item.meta.roles.includes(currentRole)),就能实现学生看不到管理页面,管理员看到全部页面。

6.3 axios 封装与请求拦截

axios 封装对课设项目来说是一个“别人一看就觉得你专业”的点。把所有请求统一走一个实例,带上 token,处理错误码:

import axios from 'axios' import { ElMessage } from 'element-ui' import router from '@/router' const service = axios.create({ baseURL: '/api', // 开发环境走代理 timeout: 10000 }) service.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) { config.headers['Authorization'] = token } return config }) service.interceptors.response.use( response => { const res = response.data if (res.code !== 200) { ElMessage.error(res.message || '请求失败') return Promise.reject(new Error(res.message)) } return res.data }, error => { if (error.response && error.response.status === 401) { localStorage.removeItem('token') router.push('/login') } ElMessage.error('网络异常,请稍后重试') return Promise.reject(error) } ) export default service

这样封装以后,页面里请求接口只需写api.login(data).then(res => {...}),不用每个页面重复写 Header 设置和错误提示,代码干净很多。

6.4 开发阶段的前端代理配置

前后端联调阶段,前端请求http://localhost:9090/api/user/login,如果直接写绝对地址,就会跨域。更优雅的方案是在开发环境的vue.config.js(Vue 2)或vite.config.js(Vue 3)里配置代理。

Vite 写法:

export default defineConfig({ server: { port: 3000, proxy: { '/api': { target: 'http://localhost:9090', changeOrigin: true } } } })

这样前端请求/api/user/login,开发服务器会自动转发到后端的9090端口,从浏览器层面看不到跨域,同时又不用把完整地址写在代码里。以后部署时只要在 Nginx 再配一次代理,代码不用改,这也是企业里常见的做法。

6.5 ECharts 数据可视化页面

统计看板页面,建议用 ECharts 的折线图展示近14天上报率趋势,用饼图展示健康状态分布,用柱状图展示各班级异常人数。

ECharts 的使用套路是固定的:先npm install echarts,然后在组件里初始化:

import * as echarts from 'echarts' const chartDom = this.$refs.chartRef const myChart = echarts.init(chartDom) myChart.setOption({ title: { text: '近7日上报率' }, tooltip: { trigger: 'axis' }, xAxis: { type: 'category', data: this.reportRateTrend.dates }, yAxis: { type: 'value', max: 100, axisLabel: { formatter: '{value}%' } }, series: [{ name: '上报率', type: 'line', data: this.reportRateTrend.rates, smooth: true }] })

记得在组件销毁时调用myChart.dispose()释放资源,聊天记录里搜索过相关问题的都知道,不释放会导致切换页面后图表闪烁或者内存告警。

7. 从零部署:环境配置与高频踩坑点

7.1 JDK 与环境变量配置

后端是 SpringBoot,所以 JDK 至少 1.8,建议 1.8 或 11。JDK 装好后一定要配JAVA_HOMEPathCLASSPATH三个环境变量。很多同学反映java -version能运行,但 Maven 编译时找不到 JDK,多半是JAVA_HOME没有指向 JDK 安装根目录(而不是 bin 目录)。

7.2 MySQL 8.0 安装与连接细节

MySQL 安装完以后,有三件套要检查:

  1. 服务是否启动,Windows 下用net start mysql80或到服务管理器里手动启动;
  2. 数据库连接工具(Navicat / DataGrip)是否能连上;
  3. root 用户的密码要记清楚,忘记密码后要找回很麻烦。

连接配置里两个高频错误:

  • Public Key Retrieval is not allowed:JDBC URL 加allowPublicKeyRetrieval=true&useSSL=false
  • The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized:JDBC URL 加serverTimezone=Asia/Shanghai

这是因为 MySQL 8.0 和驱动对时区、SSL 的默认处理方式变了,不是你的密码错了。

7.3 SpringBoot 配置文件详解

后端核心配置文件是application.yml

server: port: 9090 spring: datasource: url: jdbc:mysql://localhost:3306/epidemic_system?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root password: 你的密码 driver-class-name: com.mysql.cj.jdbc.Driver jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: Asia/Shanghai mybatis-plus: configuration: map-underscore-to-camel-case: true 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

特别注意driver-class-name要写com.mysql.cj.jdbc.Driver,不要写以前旧的com.mysql.jdbc.Driver,后者在 MySQL 8.0 下会直接报错。

密码问题也别忽视:如果你的 MySQL root 密码带着特殊字符如@#,在 yml 里一定用单引号包起来,否则会被当成注释或者格式错误。

7.4 npm 依赖安装的版本坑

前端最常见的安装问题是 node-sass 下载失败。现在新项目我一般不推荐 node-sass,改用 dart-sass 或直接用设计好的 CSS 框架。但很多老源码还是用 node-sass,它有个著名毛病——对 Node 版本极其敏感。

我的建议:如果源码用的是 node-sass,就查清楚它要求的 Node 版本,然后用 nvm 切到对应版本。如果不想折腾,可以把源码里的 sass 相关依赖卸载,装sass(dart-sass)替代,绝大多数情况下代码不用改。

7.5 两种运行部署方式

  • 开发模式:后端 IDEA 跑Application,前端npm run serve,通过代理联调;
  • 部署模式:后端用 Maven 打包mvn clean package得到 jar 包,java -jar运行;前端npm run build生成 dist 静态目录。最终可以用 Nginx 托管前端静态文件,并把/api反向代理到后端端口。这一步做出来,答辩时长分不少。

8. 论文与答辩准备:另一半分数别丢

很多同学代码写完了,论文却一塌糊涂。课设/毕设不是一个纯工程活,文档是另外半壁江山。我建议论文围绕这几个部分展开。

8.1 论文结构建议

  1. 绪论:背景与意义、国内外现状、主要工作;
  2. 相关技术介绍:SpringBoot、Vue、MySQL、JWT、ECharts 各写一节能说明原理;
  3. 系统分析:可行性分析、需求分析、用例图、业务流程;
  4. 系统设计:总体架构、功能模块设计、数据库设计;
  5. 系统实现:按模块写界面截图 + 关键代码 + 实现说明;
  6. 系统测试:功能测试、测试用例表、测试结果;
  7. 总结与展望。

技术选型那一章,不要照抄百度百科。要用自己的话讲清楚“为什么选它”,比如“SpringBoot 简化了 Spring 应用的初始搭建和开发过程,内嵌 Tomcat,避免了部署时的外部容器依赖”。

8.2 图表怎么画才加分

论文里至少要有:总体架构图、系统功能结构图、用例图、数据库 ER 图、核心业务流程图、系统部署图。新手常用 Visio、ProcessOn、draw.io 画这些。不要画得太花哨,黑白线框风格在论文里反而最正式。

8.3 答辩演示的三大核心流程

演示环节不要每个功能都点一遍,有选择性地走完整闭环,给评委留下“系统是完整的”印象:

  1. 学生登录→每日健康上报→查看个人上报记录;
  2. 辅导员登录→查看本班上报统计→审批学生返校申请;
  3. 管理员登录→查看全校数据看板→发布公告。

每个流程演示完,简单说一句背后的实现逻辑,比如“审批通过后状态自动刷新,前端通过轮询或者重新请求接口获取最新数据”,比默默点按钮强太多。

8.4 答辩高频问题早做准备

按经验,评委大概率会问这些问题,我提前给了参考思路:

  • “为什么要选这个题目?”——从实际需求出发,说明业务痛点和系统价值。
  • “JWT 和 Session 有什么区别?”——JWT 无状态、可扩展、适合分布式;Session 存在服务器内存,多实例部署需要共享。简单讲清楚这点就很加分。
  • “如果用户并发量大了怎么办?”——加 Redis 缓存热点数据、数据库读写分离、分页查询、优化 SQL。作为课设能提到这个层面已经够了。
  • “上报率是怎么统计的?”——用一个班级的总人数做分母,查当天已上报的学生数做分子,利用 LEFT JOIN 保留未上报的学生记录。
  • “密码是怎么加密的?”——BCrypt 加盐哈希,明文密码不落库,每次校验用matches方法。

9. 最后讲几点我的真实体会

带过不少做这个题目的学生以后,我最大的感受是:做管理系统类项目,最大的分水岭不在技术难度,而在“细节完整度”。同样是白天上报功能,有的同学只是简单插一条记录,有的同学会考虑:重复提交怎么办、补报逻辑怎么处理、体温超过 37.3 要怎么标红提醒、辅导员端要显示哪些统计信息。这些细节加在一起,决定了你的系统是一个“课程作业”还是一个“能用的东西”。

我可以告诉你的是,如果你准备拿这套源码去学习或者直接用于课设/毕设,最值得投入时间的三个地方是:第一,把数据库表关系吃透,这是你论文和答辩的底气;第二,把 JWT 登录和路由守卫这条链路手写一遍,别纯靠复制;第三,把统计数据背后的 SQL 理解透,这会让你在工作面试时也有的说。

最后再分享一个小技巧:写前端页面的时候,把所有请求集中放到一个api.js文件里,而不是散落在各个 Vue 组件中。这样后面如果后端接口地址变了,你只改一个文件,不用满项目去翻。所有接手过这种项目的人,都会感谢你这种习惯。

技术选型和业务实现讲完以后,剩下的就是踏踏实实跑起来、改一改、理解透。这套项目做完,你对 SpringBoot 整套开发流程的认识,会比看十遍教学视频都扎实。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 9:32:56

电话号码的字母组合:回溯算法与DFS递归的经典入门题解

周末刷力扣的时候&#xff0c;碰到 57. 电话号码的字母组合 这道题。说实话&#xff0c;这道题在 力扣热题100 里算是一道非常经典的“回溯”入门题&#xff0c;但别看它难度标着Medium&#xff0c;其实核心思想并不复杂&#xff0c;很多刚接触 DFS回溯 的朋友容易被“映…

作者头像 李华
网站建设 2026/9/9 9:32:29

VS2019离线安装包处理全攻略:从rar解压到C++环境验证指南

简介&#xff1a;VS2019 C离线压缩包专为C开发者打造&#xff0c;是一个完整的Visual Studio 2019 C离线安装解决方案&#xff0c;可彻底摆脱网络限制&#xff0c;在断网环境中快速部署专业级C开发环境&#xff0c;尤其适合网络受限的企业内网、实验室或临时开发机场景。压缩包…

作者头像 李华
网站建设 2026/9/9 9:31:51

从magnitude读懂地震震级:能量、烈度与避险常识

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/9 9:31:18

药企AI研发赋能:监管合规与研发效率的协同落地路径

1. 这不是“AI画饼”&#xff0c;而是药企研发管线里正在跑的真实算力 最近跟三家做创新药的团队聊完&#xff0c;我桌上堆着六份不同格式的分子对接报告、四套刚跑完的ADMET预测结果截图&#xff0c;还有两台笔记本屏幕上并排开着AlphaFold2的结构比对窗口和自家化合物库的SMI…

作者头像 李华
网站建设 2026/9/9 9:28:40

Web自动化测试中Select下拉框操作全解:从原生select到自定义组件

刚开始写Web自动化测试用例的时候&#xff0c;我以为下拉框选择就是click一下再click一下&#xff0c;直到在某个后台系统里被“所属部门”这个Select下拉框卡了整整半天&#xff0c;才意识到这种常见的交互控件远比想象中复杂。这篇文章是Web自动化测试系列的第二篇&#xff0…

作者头像 李华
网站建设 2026/9/9 9:26:39

humanizer:面向人类行为逻辑的交互重构方法论

1. 项目概述&#xff1a;什么是 humanizer&#xff1f;它不是“拟人化”&#xff0c;而是真实可落地的交互能力重构最近在多个技术社区、设计工作坊和产品复盘会上&#xff0c;我反复听到一个词——humanizer。它不是某个具体软件的名字&#xff0c;也不是某家公司的新发布产品…

作者头像 李华