1. 项目背景与需求分析
2020年以来,全球范围内的公共卫生事件对校园管理提出了全新挑战。作为高校信息化建设的重要组成部分,健康状态监测系统从"可有可无"变成了"刚需标配"。传统纸质登记方式暴露出的问题包括:
- 数据汇总滞后:辅导员需要手工统计各班表格,通常需要2-3天才能完成全校数据汇总
- 信息真实性存疑:代签、补签现象普遍存在,无法确保上报数据的时效性和真实性
- 异常响应迟缓:对于体温异常等特殊情况,难以及时触发预警机制
我们开发的这套系统主要解决三个核心痛点:
- 实时性:通过移动端打卡,数据即时入库,管理人员可随时查看最新统计
- 可追溯:每次打卡记录包含GPS定位、时间戳等防伪信息
- 智能化:自动触发异常预警,生成可视化报表辅助决策
提示:系统设计时要特别注意《个人信息保护法》相关规定,位置信息等敏感数据需进行脱敏处理。
2. 技术选型与架构设计
2.1 技术栈组成
本系统采用经典的三层架构,具体技术选型如下:
| 层级 | 技术选型 | 选型理由 |
|---|---|---|
| 前端 | Vue.js + Element UI | 组件化开发效率高,适合快速迭代的管理后台 |
| 后端 | Spring Boot 2.7.x | 约定优于配置,内置Tomcat简化部署 |
| 持久层 | MyBatis-Plus + MySQL 8.0 | MP提供强大CRUD操作,MySQL事务支持完善 |
| 缓存 | Redis 6.x | 高频访问的防疫政策、通知公告等数据缓存 |
| 消息队列 | RabbitMQ | 异步处理大批量打卡数据的统计分析 |
| 安全框架 | Spring Security + JWT | 实现细粒度的权限控制,支持移动端Token认证 |
2.2 架构示意图
code复制[移动端APP] ←HTTP→ [API Gateway] ←→ [认证服务]
←→ [打卡服务]
←→ [报表服务]
←→ [通知服务]
↑
↓
[管理后台] → [Redis缓存] ←→ [MySQL集群]
↑
↓
[RabbitMQ] ←→ [数据分析模块]
这种微服务化设计带来两个显著优势:
- 弹性扩展:高峰期可单独扩容打卡服务节点
- 故障隔离:单个服务异常不会导致整个系统瘫痪
3. 核心功能实现细节
3.1 健康打卡流程设计
打卡业务看似简单,实则包含多个校验环节:
- 防重复提交:采用Redis SETNX实现分布式锁,key格式:
lock:userId:date - 位置校验:通过高德地图API验证打卡位置是否在预设地理围栏内
- 异常检测:
- 体温>37.3℃自动触发预警
- 连续3天未打卡生成缺勤记录
- 数据持久化:采用MySQL事务确保主表(t_daily_report)与明细表(t_temperature)的写入原子性
关键代码片段:
java复制@Transactional
public SubmitResult submitReport(ReportDTO dto) {
// 获取分布式锁
String lockKey = "lock:" + dto.getUserId() + ":" + LocalDate.now();
boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 5, TimeUnit.MINUTES);
if (!locked) {
throw new BusinessException("今日已打卡");
}
// 位置校验
if (!locationService.verify(dto.getLng(), dto.getLat())) {
throw new BusinessException("不在允许打卡范围内");
}
// 保存记录
DailyReport report = convertToEntity(dto);
dailyReportMapper.insert(report);
// 体温异常处理
if (dto.getTemperature() > 37.3) {
alertService.notifyAdmin(report);
}
return new SubmitResult(true);
}
3.2 多维度统计报表
系统提供三种维度的数据分析:
- 实时看板:使用Redis HyperLogLog统计当日已打卡人数
- 趋势分析:通过MySQL窗口函数计算近7天体温平均值
- 异常热力图:结合ECharts GIS功能展示异常病例地理分布
统计SQL示例:
sql复制SELECT
date,
AVG(temperature) OVER(ORDER BY date ROWS 6 PRECEDING) AS avg_temp,
COUNT(*) OVER(PARTITION BY department) AS dept_count
FROM t_daily_report
WHERE date BETWEEN ? AND ?
4. 部署与性能优化
4.1 生产环境配置建议
经过压力测试,推荐以下服务器配置:
| 服务类型 | CPU | 内存 | 磁盘 | 节点数 |
|---|---|---|---|---|
| 应用服务器 | 4核 | 8G | SSD 50G | 2+ |
| MySQL | 8核 | 16G | SSD 200G | 主从 |
| Redis | 2核 | 4G | - | 哨兵 |
关键JVM参数:
code复制-Xms4g -Xmx4g -XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:InitiatingHeapOccupancyPercent=35
4.2 高频问题解决方案
问题1:早上8-9点打卡高峰期出现超时
- 解决方案:
- 引入Nginx负载均衡
- 打卡接口添加限流(Guava RateLimiter)
- 非核心字段改为异步更新
问题2:移动端网络不稳定导致重复提交
- 解决方案:
- 前端添加防重试倒计时
- 后端采用幂等设计(数据库唯一索引)
- 错误提示明确区分"已提交"和"网络异常"
问题3:历史数据查询缓慢
- 解决方案:
- 按学期分表(t_report_2023_1)
- 建立复合索引(user_id + date)
- 冷数据归档到ClickHouse
5. 扩展功能探讨
5.1 智能预警升级
当前系统已实现基础异常检测,后续可扩展:
- 行为模式分析:通过历史数据建立个人健康基线,识别偏离常态的情况
- 关联性预警:同一班级/宿舍多人异常时提升预警等级
- 返校预测:结合打卡记录和审批数据预测返校人流高峰
5.2 多平台集成方案
与企业微信/钉钉对接的实践经验:
- 单点登录:通过OAuth2.0实现组织架构同步
- 消息推送:利用平台工作通知API发送提醒
- 小程序整合:将打卡功能嵌入第三方平台小程序
对接示例:
java复制// 钉钉access_token获取
public String getDingTalkToken() {
String url = "https://oapi.dingtalk.com/gettoken?appkey="+appKey+"&appsecret="+appSecret;
String result = restTemplate.getForObject(url, String.class);
return JSON.parseObject(result).getString("access_token");
}
在实际开发中,我们发现疫情防控系统最关键的不仅是技术实现,更需要平衡效率与隐私、严格与便利。比如位置校验既要防止虚假打卡,又不能过度收集轨迹信息;异常预警既要及时,又要避免误报造成恐慌。这些经验很难在技术文档中找到,却直接影响系统的实际使用效果。
