1. 项目背景与核心需求2020年以来的全球公共卫生事件让校园防疫管理面临前所未有的挑战。传统的人工登记、纸质报表方式在应对晨午检、行程追踪、健康打卡等高频次防疫需求时显得力不从心。某高校信息中心的张老师告诉我最忙的时候我们每天要处理近万份纸质健康表人工核对缺勤原因就要耗掉3个老师全天时间。这正是我们开发校园疫情防控系统的核心驱动力。系统需要实现以下关键能力多角色协同管理覆盖学生、辅导员、校医、宿管、校领导五类角色权限颗粒度精确到按钮级别。例如宿管只能查看本楼栋数据而校领导需要宏观统计视图。实时数据闭环从学生端的健康打卡到异常情况的自动预警再到处置结果的反馈形成完整的PDCA循环。实测显示将体温异常响应时间从平均4小时缩短至15分钟。非接触式核验集成二维码门禁系统通过微信小程序扫码实现课堂考勤、宿舍出入等场景的无接触登记降低交叉感染风险。关键设计原则在保证防疫效果的前提下尽可能减少对师生正常教学生活的干扰。比如采用静默打卡机制学生进入教学楼时自动完成定位签到无需主动操作。2. 技术架构设计解析2.1 前后端分离架构采用SpringBootVue的经典组合其优势在疫情防控这类需要快速迭代的系统中尤为明显前端技术栈Vue 2.x Element UI选用成熟的UI框架加速开发特别优化了表格组件以支持万级数据渲染Axios封装了带Token自动刷新的HTTP客户端处理401状态码时无缝跳转登录页ECharts实现疫情数据可视化支持按学院、班级、时间维度下钻分析后端技术栈SpringBoot 2.7简化配置内置Tomcat容器便于部署MyBatis-Plus 3.5极大简化CRUD操作其Wrapper条件构造器完美适配动态查询需求Hutool 5.8处理Excel导出等工具类需求导出一万条记录仅需2秒2.2 数据库设计要点MySQL 8.0的表结构设计有几个关键决策点分区表策略CREATE TABLE health_report ( id BIGINT PRIMARY KEY, student_id VARCHAR(20), temperature DECIMAL(3,1), report_time DATETIME ) PARTITION BY RANGE (TO_DAYS(report_time)) ( PARTITION p202301 VALUES LESS THAN (TO_DAYS(2023-02-01)), PARTITION p202302 VALUES LESS THAN (TO_DAYS(2023-03-01)) );按日期分区后查询最近7天数据的性能提升约40%。索引优化为(student_id, report_time)建立联合索引加速学生历史查询为location字段添加空间索引支持GIS地理围栏查询数据归档方案 使用Spring Batch定时任务每月将3个月前的数据迁移到历史表主表仅保留热数据。3. 核心功能实现细节3.1 健康打卡的并发处理早8点的打卡高峰时段系统面临约5000次/分钟的并发请求。我们通过以下方案确保稳定性Redis缓存预热// 提前加载学生基础信息到Redis PostConstruct public void initStudentCache() { ListStudent students studentMapper.selectList(null); students.forEach(s - redisTemplate.opsForValue().set(student:s.getId(), s)); }令牌桶限流算法RateLimiter(value 1000, key health:report) PostMapping(/report) public Result reportHealth(RequestBody HealthDTO dto) { // 业务逻辑 }异步日志记录Async(healthLogExecutor) public void asyncSaveLog(HealthLog log) { healthLogMapper.insert(log); }3.2 异常预警机制系统定义了三级预警规则预警级别触发条件通知方式一级(红色)体温≥37.3℃且来自高风险地区短信系统弹窗二级(黄色)连续2天未打卡微信模板消息三级(蓝色)出入异常区域邮件通知实现代码示例public void checkWarningRules(HealthReport report) { if (report.getTemperature() 37.3 riskAreaService.isRiskArea(report.getLocation())) { warningService.sendLevel1Warning(report); } // 其他规则判断... }4. 部署与性能优化4.1 多环境配置通过Spring Profiles实现环境隔离# application-dev.yml server: port: 8080 datasource: url: jdbc:mysql://localhost:3306/campus_epidemic_dev # application-prod.yml server: port: 80 datasource: url: jdbc:mysql://cluster-mysql:3306/campus_epidemic?useSSLfalse4.2 Jenkins自动化部署编写pipeline脚本实现一键部署pipeline { agent any stages { stage(Build) { steps { sh mvn clean package -DskipTests } } stage(Deploy) { steps { sshPublisher( publishers: [ sshPublisherDesc( configName: prod-server, transfers: [ sshTransfer( sourceFiles: target/*.jar, removePrefix: target, remoteDirectory: /opt/campus-epidemic ) ], execCommand: systemctl stop campus-epidemic mv /opt/campus-epidemic/*.jar /opt/campus-epidemic/backup cp /opt/campus-epidemic/new/*.jar /opt/campus-epidemic/ systemctl start campus-epidemic ) ] ) } } } }4.3 性能调优实战JVM参数优化java -jar -Xms512m -Xmx1024m -XX:UseG1GC \ -XX:MaxGCPauseMillis200 campus-epidemic.jarMyBatis二级缓存cache evictionLRU flushInterval60000 size1024 readOnlytrue/Nginx静态资源缓存location /static { alias /opt/campus-epidemic/static; expires 30d; add_header Cache-Control public; }5. 踩坑与解决方案5.1 微信定位漂移问题实际测试中发现部分Android手机在室内打卡时获取的GPS坐标会出现500-1000米的偏移。最终采用混合定位方案优先使用微信JSAPI获取坐标通过基站IP辅助定位结合WiFi指纹补偿修正核心代码function getAccurateLocation() { return new Promise((resolve) { wx.getLocation({ type: wgs84, success: (res) { if(isIndoor(res.accuracy)) { getNetworkLocation().then(netRes { resolve(mergeLocation(res, netRes)); }); } else { resolve(res); } } }); }); }5.2 批量导入性能瓶颈初期使用POI直接导入Excel时1万条数据需要近1分钟。优化方案采用EasyExcel替代POI开启批量插入模式增加进度回调通知优化后性能对比方案耗时(1万条)内存占用POI58s约800MBEasyExcel12s约150MB实现示例public void importExcel(MultipartFile file) { EasyExcel.read(file.getInputStream(), HealthData.class, new AnalysisEventListenerHealthData() { Override public void invoke(HealthData data, AnalysisContext context) { batchList.add(data); if (batchList.size() 500) { saveBatch(); } } // 其他方法... }).sheet().doRead(); }6. 安全防护措施6.1 接口防刷策略图形验证码使用Kaptcha生成扭曲文本验证码登录前必须验证行为验证异常操作时触发滑动拼图验证设备指纹通过Canvas指纹识别UA生成设备唯一ID6.2 数据脱敏处理在Controller层统一处理敏感字段RestControllerAdvice public class DataMaskAdvice implements ResponseBodyAdviceObject { Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { if(body instanceof Student) { ((Student) body).setIdCard(maskIdCard(((Student) body).getIdCard())); } return body; } private String maskIdCard(String idCard) { return idCard.replaceAll((\\d{4})\\d{10}(\\w{4}), $1****$2); } }7. 扩展与演进当前系统已在3所高校稳定运行6个月日均处理健康数据12万条。后续规划物联网集成对接智能体温枪自动上传测量数据预测分析基于历史数据建立疫情传播模型微服务改造将考勤、健康、消杀等模块拆分为独立服务我在实际部署中发现疫情防控系统的特殊性在于既要保证数据的实时性和准确性又要尽可能简化用户操作。我们的解决方案是在后台保持严谨的数据校验规则在前端通过智能默认值、历史记忆、位置感知等技术最大限度减少用户输入。例如自动填充上次打卡的体温值当差异超过1℃时才会要求手动确认。