1. 项目背景与核心需求校园防疫信息管理系统是当前教育信息化建设中的重要组成部分。随着公共卫生事件的常态化管理传统纸质登记、人工统计的方式已经无法满足高校对疫情数据的实时监控和分析需求。这个基于SpringBoot和数据可视化的系统正是为了解决以下核心痛点数据分散难整合学生健康打卡、出入记录、核酸检测等数据分散在不同部门缺乏统一管理平台统计效率低下人工汇总Excel表格耗时耗力且容易出错预警响应滞后异常情况无法实时发现错过最佳处置时机决策缺乏依据管理者难以直观掌握校园整体防疫态势我在实际开发中发现一个优秀的防疫系统需要具备三个关键能力实时数据采集能力、智能分析预警能力和直观可视化展示能力。这也是本系统设计的出发点。2. 技术架构设计2.1 后端技术选型采用SpringBoot 2.7.x作为基础框架主要基于以下考虑自动配置特性大幅减少XML配置实测可节省约40%的初始化工作量内嵌Tomcat服务器部署简单特别适合校园IT环境完善的生态体系与MyBatis、Spring Security等组件无缝集成数据库选用MySQL 8.0关键配置参数# 优化连接池配置 spring.datasource.hikari.maximum-pool-size20 spring.datasource.hikari.connection-timeout30000 # 启用批量插入优化 rewriteBatchedStatementstrue2.2 前端可视化方案使用ECharts 5.3实现数据可视化其优势在于丰富的图表类型热力图展示人员密集度折线图反映疫情趋势变化动态渲染性能实测万级数据点流畅渲染移动端适配自动响应不同屏幕尺寸典型图表配置示例option { tooltip: { trigger: axis, formatter: function(params) { return 日期${params[0].name}br/异常人数${params[0].value} } }, xAxis: { type: category, data: dateList }, yAxis: { type: value }, series: [{ data: abnormalData, type: line, smooth: true, areaStyle: {} }] }3. 核心功能实现3.1 健康打卡模块采用分布式锁解决高并发提交问题Transactional public void submitHealthInfo(HealthDTO dto) { String lockKey health:lock: dto.getStudentId(); try { // 使用Redis分布式锁 boolean locked redisTemplate.opsForValue() .setIfAbsent(lockKey, 1, 30, TimeUnit.SECONDS); if (!locked) { throw new RuntimeException(操作过于频繁); } // 校验数据逻辑... healthMapper.insert(convertToEntity(dto)); } finally { redisTemplate.delete(lockKey); } }3.2 出入审批流程设计状态机管理审批流程public enum AuditState { PENDING(0), APPROVED(1), REJECTED(2); // 状态转换校验逻辑 public static void validateTransition(AuditState from, AuditState to) { if (from PENDING to REJECTED) return; if (from PENDING to APPROVED) return; throw new IllegalStateException(非法状态转换); } }4. 数据可视化实践4.1 疫情热力图实现结合地理信息系统展示人员密度将校园地图转换为GeoJSON格式使用ECharts GL渲染3D热力效果实时对接门禁系统数据源关键代码片段series: [{ type: heatmap, coordinateSystem: geo, data: convertToHeatData(accessRecords), pointSize: 10, blurSize: 15 }]4.2 移动端适配方案采用rem布局配合媒体查询media screen and (max-width: 768px) { .chart-container { width: 100vw; height: 60vh; } .legend-item { font-size: 0.8rem; } }5. 性能优化经验5.1 数据库优化建立复合索引提升查询效率CREATE INDEX idx_health_multi ON health_info (student_code, submit_time DESC);批量插入优化技巧Transactional public void batchInsert(ListHealthInfo list) { SqlSession session sqlSessionFactory.openSession(ExecutorType.BATCH); try { HealthMapper mapper session.getMapper(HealthMapper.class); for (HealthInfo info : list) { mapper.insert(info); } session.commit(); } finally { session.close(); } }5.2 缓存策略采用多级缓存架构本地Caffeine缓存高频访问的字典数据Redis缓存聚合统计结果使用Cacheable注解简化开发配置示例CacheConfig(cacheNames dailyReport) Service public class ReportServiceImpl implements ReportService { Cacheable(key #date) public DailyReportVO generateReport(LocalDate date) { // 复杂统计逻辑... } }6. 安全防护措施6.1 接口安全JWT认证实现方案Configuration EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers(/api/auth/**).permitAll() .anyRequest().authenticated() .and() .addFilter(new JwtAuthFilter(authenticationManager())); } }6.2 数据脱敏敏感信息处理策略public String maskPhone(String phone) { if (StringUtils.isEmpty(phone)) return ; return phone.replaceAll((\\d{3})\\d{4}(\\d{4}), $1****$2); }7. 部署实践7.1 容器化部署Dockerfile最佳实践FROM openjdk:11-jre WORKDIR /app COPY target/*.jar app.jar EXPOSE 8080 ENTRYPOINT [java,-jar,app.jar]7.2 监控方案Prometheus监控配置management: endpoints: web: exposure: include: health,info,metrics metrics: export: prometheus: enabled: true8. 踩坑实录时区问题MySQL默认时区导致时间显示异常解决方案jdbc连接串添加serverTimezoneAsia/ShanghaiMyBatis批量插入失效原因忘记在Mapper接口添加Param注解正确写法void batchInsert(Param(list) ListHealthInfo list);ECharts内存泄漏现象频繁切换图表导致页面卡顿修复在组件销毁时调用dispose()beforeDestroy() { this.chart.dispose() }SpringCache缓存穿透场景大量查询不存在的学生ID优化使用空对象缓存模式Cacheable(key #id, unless #result null) public Student getById(Long id) { return studentMapper.selectById(id); }这个项目让我深刻体会到一个好的管理系统不仅要有完善的功能更需要考虑实际使用场景。比如在疫情高峰期系统需要承受突发的访问压力在数据展示方面要让非技术人员也能一目了然。这些实战经验是教科书上很难学到的宝贵财富。