1. 项目概述与背景
疫情健康上报管理系统是基于SSM框架开发的毕业设计项目,旨在解决疫情期间健康数据采集、分析和管理的实际问题。这个系统在2020年新冠疫情爆发后变得尤为重要,当时各类机构急需一套能够快速部署、易于使用的健康监测解决方案。
我选择SSM框架(Spring+SpringMVC+MyBatis)作为技术栈,主要考虑到它的轻量级特性和良好的社区支持。对于学生项目而言,SSM框架学习曲线相对平缓,文档丰富,能够快速实现功能开发。同时,这个技术组合在企业级应用中也相当常见,作为毕业设计既展示了技术能力,又具备实际应用价值。
2. 系统核心功能设计
2.1 疫情数据上报模块
数据上报是整个系统的基础功能,我设计了多角色上报机制:
- 个人用户:通过Web端或移动端提交每日健康状态
- 管理员:批量导入机构人员数据
- 部门负责人:审核并确认部门成员健康状况
关键数据字段包括:
java复制public class HealthReport {
private Integer id;
private Integer userId;
private Date reportDate;
private Float temperature; // 体温
private Integer healthStatus; // 1-正常 2-疑似 3-确诊
private String location; // 当前所在地
private String contactHistory; // 接触史
// 其他字段和getter/setter
}
注意:体温字段使用Float类型而非Double,既满足精度要求又节省存储空间。实际开发中要特别注意浮点数的精度处理。
2.2 疫情数据分析模块
数据分析模块采用了ECharts进行可视化展示,主要包含:
- 实时统计面板:显示当日上报率、异常人数等关键指标
- 趋势分析:按时间维度展示疫情发展曲线
- 热力图:基于地理位置展示疫情分布
核心SQL查询示例:
sql复制SELECT
DATE_FORMAT(report_date,'%Y-%m-%d') AS day,
COUNT(*) AS total,
SUM(CASE WHEN health_status > 1 THEN 1 ELSE 0 END) AS abnormal
FROM health_report
WHERE report_date BETWEEN #{startDate} AND #{endDate}
GROUP BY day
ORDER BY day
2.3 健康打卡管理
打卡管理实现了以下特性:
- 定时提醒功能(Quartz定时任务)
- 打卡记录补签机制
- 异常状态预警(邮件/短信通知)
定时任务配置示例:
xml复制<!-- 每天上午9点执行打卡提醒 -->
<bean id="remindJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.epidemic.job.RemindJob"/>
</bean>
<bean id="remindTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="remindJob"/>
<property name="cronExpression" value="0 0 9 * * ?"/>
</bean>
3. 技术实现细节
3.1 SSM框架整合
项目采用标准的SSM架构:
- Spring 5.x - IOC容器和事务管理
- SpringMVC - Web层框架
- MyBatis 3.x - 持久层框架
- Maven - 依赖管理
关键整合配置:
java复制@Configuration
@EnableWebMvc
@ComponentScan("com.epidemic")
@PropertySource("classpath:db.properties")
public class AppConfig implements WebMvcConfigurer {
@Bean
public DataSource dataSource() {
DruidDataSource ds = new DruidDataSource();
ds.setUrl(env.getProperty("jdbc.url"));
// 其他配置...
return ds;
}
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource());
factory.setMapperLocations(
new PathMatchingResourcePatternResolver()
.getResources("classpath:mappers/*.xml"));
return factory.getObject();
}
}
3.2 前后端交互设计
前端采用Bootstrap+JQuery组合,通过AJAX与后端交互。我设计了统一的响应格式:
java复制public class Result<T> {
private Integer code; // 200成功,其他失败
private String msg;
private T data;
// 构造方法和getter/setter
}
@RestController
@RequestMapping("/api/report")
public class ReportController {
@PostMapping
public Result submitReport(@RequestBody HealthReport report) {
try {
reportService.save(report);
return Result.success();
} catch (Exception e) {
return Result.error(500, "提交失败");
}
}
}
3.3 安全控制
系统实现了基于拦截器的权限控制:
java复制public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String token = request.getHeader("Authorization");
if(!authService.validateToken(token)) {
response.sendError(401, "未授权");
return false;
}
return true;
}
}
同时使用MD5加盐存储密码:
java复制public class PasswordUtil {
private static final String SALT = "epidemic2023";
public static String encrypt(String raw) {
return DigestUtils.md5DigestAsHex((SALT + raw).getBytes());
}
}
4. 部署与运维方案
4.1 环境要求
- JDK 1.8+
- MySQL 5.7+
- Tomcat 8.5+
- Redis(可选,用于缓存)
4.2 数据库初始化
核心表结构设计:
sql复制CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
`real_name` varchar(50) DEFAULT NULL,
`department` varchar(100) DEFAULT NULL,
`role` tinyint(4) DEFAULT '1' COMMENT '1-普通用户 2-管理员',
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `health_report` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`report_date` date NOT NULL,
`temperature` float DEFAULT NULL,
`health_status` tinyint(4) DEFAULT '1',
`location` varchar(255) DEFAULT NULL,
`contact_history` text,
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_user_date` (`user_id`,`report_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
4.3 性能优化实践
-
数据库层面:
- 添加适当的索引
- 对大表进行分表(按时间或机构)
- 使用连接池(Druid)
-
应用层面:
- 启用MyBatis二级缓存
- 热点数据Redis缓存
- 静态资源CDN加速
-
前端优化:
- 资源压缩合并
- 懒加载长列表
- 本地缓存常用数据
5. 常见问题与解决方案
5.1 数据上报延迟
现象:高峰期系统响应变慢,上报延迟
排查:
- 检查数据库监控,发现CPU使用率过高
- 分析慢查询日志,定位到未使用索引的统计查询
- 检查连接池配置,发现最大连接数设置过小
解决方案:
- 为常用查询字段添加复合索引
- 调整Druid连接池参数:
properties复制# 初始连接数
druid.initialSize=5
# 最大连接数
druid.maxActive=50
# 获取连接等待超时时间
druid.maxWait=60000
5.2 定时任务失效
现象:健康打卡提醒有时不触发
原因:Quartz配置为内存模式,集群部署时会有问题
解决方案:改用JDBC存储模式
java复制@Bean
public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setDataSource(dataSource);
factory.setQuartzProperties(quartzProperties());
factory.setOverwriteExistingJobs(true);
return factory;
}
private Properties quartzProperties() {
Properties prop = new Properties();
prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate");
prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
return prop;
}
5.3 并发提交问题
现象:用户快速点击可能产生重复数据
解决方案:前端防抖+后端幂等控制
javascript复制// 前端防抖处理
$('#submitBtn').click(_.debounce(function() {
submitForm();
}, 1000));
// 后端幂等控制
@PostMapping
public Result submitReport(@RequestBody HealthReport report) {
// 检查当天是否已提交
if(reportService.exists(report.getUserId(), report.getReportDate())) {
return Result.error(400, "今日已提交");
}
// 其他逻辑...
}
6. 项目扩展方向
在实际应用中,可以考虑以下增强功能:
- 移动端适配:开发微信小程序或APP版本
- 大数据分析:集成Hadoop/Spark进行更复杂的疫情预测
- 物联网集成:对接智能体温计等设备自动采集数据
- 多租户支持:实现SAAS化部署模式
- 区块链存证:关键数据上链确保不可篡改
这个项目从技术选型到功能实现都充分考虑了实际应用场景,作为毕业设计既展示了完整的开发能力,又具备转化为实际产品的潜力。我在开发过程中最大的体会是:好的系统设计必须平衡功能完备性和用户体验,特别是在疫情这种特殊场景下,系统的易用性和稳定性往往比复杂功能更重要。
