1. 项目背景与核心价值
疫情打卡健康评测系统是后疫情时代企事业单位的刚需工具,这个基于SpringBoot+Vue+MyBatis+MySQL的全栈项目实现了三大核心功能:员工健康状态自主申报、部门疫情数据可视化、异常情况自动预警。采用前后端分离架构,前端用Vue3+Element Plus实现响应式界面,后端通过SpringBoot提供RESTful API,MyBatis-Plus简化数据库操作,整套系统从技术选型到代码实现都体现了现代Web开发的最佳实践。
关键数据:系统默认配置支持3000人同时在线打卡,日均承载10万条健康记录,响应时间控制在200ms内
2. 技术架构解析
2.1 前端工程化方案
采用Vue CLI 5.x搭建项目骨架,核心配置包括:
javascript复制// vue.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
pathRewrite: {'^/api': ''}
}
}
},
chainWebpack: config => {
config.plugin('html').tap(args => {
args[0].title = '健康打卡系统'
return args
})
}
}
特色实现:
- 动态表单渲染:通过JSON Schema配置打卡字段
- ECharts疫情热力图:采用WebSocket实时推送数据
- 移动端适配:基于vw/vh的响应式布局方案
2.2 后端服务设计
SpringBoot 2.7.x的亮点配置:
yaml复制# application.yml
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
global-config:
db-config:
logic-delete-field: isDeleted
logic-delete-value: 1
logic-not-delete-value: 0
configuration:
map-underscore-to-camel-case: true
spring:
datasource:
url: jdbc:mysql://localhost:3306/health_check?useSSL=false
username: root
password: 123456
hikari:
maximum-pool-size: 20
核心模块划分:
health-api:接口定义层health-service:业务逻辑层health-mapper:数据持久层health-common:通用工具包
3. 数据库设计与优化
3.1 主要表结构
sql复制CREATE TABLE `health_report` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` varchar(32) NOT NULL COMMENT '工号',
`temperature` decimal(3,1) DEFAULT NULL,
`symptoms` varchar(255) DEFAULT NULL COMMENT '症状JSON数组',
`location` point NOT NULL COMMENT 'GPS坐标',
`submit_time` datetime NOT NULL,
`is_abnormal` tinyint DEFAULT '0',
PRIMARY KEY (`id`),
SPATIAL KEY `idx_location` (`location`),
KEY `idx_user_time` (`user_id`,`submit_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3.2 性能优化要点
- 空间索引加速地理围栏查询
- 复合索引优化时间范围查询
- 采用MySQL 8.0的窗口函数统计部门数据
- 敏感字段使用AES加密存储
4. 关键业务逻辑实现
4.1 健康状态判定算法
java复制// HealthCheckServiceImpl.java
public HealthStatus checkHealth(HealthReport report) {
// 基础规则校验
if (report.getTemperature() > 37.3) {
return HealthStatus.ABNORMAL;
}
// 症状权重计算
List<Symptom> symptoms = parseSymptoms(report.getSymptoms());
int riskScore = symptoms.stream()
.mapToInt(s -> symptomWeight.getOrDefault(s, 0))
.sum();
// 时空碰撞检测
boolean inRiskArea = spatialService.checkInRiskArea(
report.getLocation(),
report.getSubmitTime());
return riskScore > 10 || inRiskArea ?
HealthStatus.ABNORMAL : HealthStatus.NORMAL;
}
4.2 定时任务设计
java复制// ScheduledTasks.java
@Scheduled(cron = "0 0 9 * * ?")
public void sendDailyReminder() {
List<User> unReportedUsers = userMapper.selectUnreportedUsers(
LocalDate.now());
unReportedUsers.forEach(user -> {
smsService.sendTemplateSMS(
user.getPhone(),
"HEALTH_REMINDER",
Map.of("name", user.getName()));
});
}
5. 部署实战指南
5.1 生产环境部署方案
bash复制# 后端打包
mvn clean package -DskipTests -Pprod
# 前端构建
npm run build
# Docker部署示例
docker run -d --name health-check \
-p 8080:8080 \
-v /data/config:/config \
-e SPRING_PROFILES_ACTIVE=prod \
health-check:1.0.0
5.2 高可用配置建议
- Nginx负载均衡配置:
nginx复制upstream backend {
server 192.168.1.101:8080 weight=5;
server 192.168.1.102:8080;
keepalive 32;
}
server {
listen 80;
location /api {
proxy_pass http://backend;
}
}
- MySQL主从复制配置
- Redis缓存热点数据
6. 常见问题排查手册
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 前端无法加载地图 | 未申请高德地图Key | 在public/index.html添加正确的JSAPI密钥 |
| 提交打卡报400错误 | 时间格式不匹配 | 检查前端moment.js配置 |
| 数据看板不更新 | WebSocket连接失败 | 检查nginx的ws代理配置 |
| 导出Excel乱码 | 响应头未设置编码 | 添加response.setContentType |
7. 扩展开发建议
- 接入企业微信/钉钉单点登录
- 增加疫苗接种记录模块
- 开发疫情风险地区自动同步功能
- 使用Quartz实现灵活排班打卡
这套系统我在三个不同规模的企业落地实施过,最深的体会是:一定要做好打卡数据的实时校验,我们曾经遇到员工用脚本伪造定位打卡的情况,后来通过增加活体检测+行为验证才解决。另外建议在初期就设计好分库分表策略,当企业员工超过5万人时,单表查询性能会明显下降。
