一、项目背景:疫情防控数字化的必然趋势
在新冠疫情常态化防控背景下,传统流行病学调查面临着信息收集慢、轨迹追溯难、管理效率低三大核心痛点。据疫情防控统计显示,2023年仍有超过50%的地区采用纸质登记和人工排查方式,导致密接者信息更新不及时、轨迹追溯不准确、资源分配不合理,而防疫人员也缺乏系统化的信息管理工具。
为破解这一困境,基于Spring Boot的新冠病毒密接者跟踪系统应运而生。系统以"信息实时化、追溯精准化、管理智能化"为核心目标,采用B/S架构构建一体化疫情防控管理平台,整合用户轨迹管理、核酸检测管理、疫苗预约管理、口罩预订管理等核心功能,建立"管理员统筹-用户参与"的双层应用模式,推动疫情防控从"传统人工式"向"数字化、智能化、精准化"转型。
二、技术架构:疫情防控系统的全栈技术选型
项目围绕"稳定性优先、安全性强、响应快"三大原则,选用成熟且贴合疫情防控需求的技术栈:
| 技术模块 | 具体工具/技术 | 核心作用 |
|---|---|---|
| 后端框架 | Spring Boot 2.x | 快速构建高效API接口,处理疫情防控核心业务逻辑 |
| 前端技术 | 前端框架 + 模板引擎 | 构建清晰直观的管理界面,适配多角色操作 |
| 数据库 | MySQL 8.0 | 安全存储用户信息、轨迹数据、检测记录等敏感数据 |
| 开发工具 | Eclipse | 集成开发环境,提高开发效率 |
| 安全框架 | Spring Security | 保障系统数据安全,防止信息泄露 |
| 服务器 | Tomcat | 轻量级应用服务器,支持快速部署 |
三、项目全流程:6步完成疫情防控系统开发
3.1 第一步:需求分析——明确系统核心价值
针对传统疫情防控的"效率低、精度差"痛点,系统聚焦"轨迹精准记录、检测及时跟踪、资源合理分配",明确双角色的核心需求:
3.1.1 功能性需求
-
双角色权限体系
- 管理员:字典管理、地点管理、公告信息管理、用户轨迹管理、核酸检测管理、口罩管理、口罩预订管理、医护人员管理、疫苗管理、疫苗预约管理、用户管理;
- 用户:个人信息维护、轨迹上报、核酸检测查询、疫苗预约、口罩预订、公告查看。
-
核心业务功能
- 用户轨迹全生命周期管理:从轨迹记录、地点关联到风险分析;
- 核酸检测闭环管理:检测安排→结果录入→状态跟踪→统计分析;
- 疫苗预约流程:疫苗信息发布→用户预约→接种安排→记录归档;
- 防疫物资管理:口罩库存管理、预订分配、发放跟踪;
- 信息发布系统:疫情公告、政策通知、防控指南。
3.1.2 非功能性需求
- 系统性能:支持1000+用户同时使用,关键操作响应时间<1秒;
- 数据安全:敏感信息加密存储,严格的权限控制机制;
- 可靠性:7×24小时稳定运行,关键数据多重备份;
- 易用性:界面简洁明了,操作流程简单直观。
3.2 第二步:系统设计——构建整体架构
系统采用分层设计思想,确保各模块职责清晰、可维护性强:
3.2.1 系统总体架构
-
前端架构
- 基于响应式设计,适配不同设备访问;
- 组件化开发,提高代码复用性;
- 实时数据更新,提升用户体验。
-
后端架构
- 基于Spring Boot实现RESTful API;
- 统一异常处理机制,提供友好错误提示;
- 接口权限验证,保障系统安全。
-
数据持久层
- MyBatis实现数据库操作,SQL优化;
- 数据库事务管理,保证数据一致性;
- 敏感数据加密存储。
3.2.2 核心数据库设计
系统设计12张核心数据表,覆盖疫情防控全业务场景:
| 表名 | 核心字段 | 作用 |
|---|---|---|
| 用户表(user) | id、yonghu_name、yonghu_phone、jiankang_types | 存储用户基本信息和健康状态 |
| 地点表(location) | id、didian_name、didian_types | 存储风险地点信息 |
| 用户轨迹表(user_track) | id、yonghu_id、didian_id、guiji_time | 记录用户行程轨迹 |
| 核酸检测表(nucleic_test) | id、yonghu_id、jiance_types、jiance_time | 管理核酸检测记录 |
| 疫苗表(vaccine) | id、yimiao_name、yimiao_types、yimiao_number | 存储疫苗库存信息 |
| 疫苗预约表(vaccine_appointment) | id、yonghu_id、yimiao_id、yimiaoyuyue_types | 管理疫苗预约流程 |
| 口罩表(mask) | id、kouzhao_name、kouzhao_types、kouzhao_number | 管理口罩库存信息 |
| 口罩预订表(mask_booking) | id、yonghu_id、kouzhao_id、yueding_number | 管理口罩预订分配 |
| 医护人员表(medical_staff) | id、yihu_name、yihu_phone、yihu_id_number | 存储医护人员信息 |
| 公告信息表(announcement) | id、gonggao_name、gonggao_types、gonggao_content | 存储系统公告 |
| 字典表(dictionary) | id、dic_code、dic_name、code_index | 管理系统字典数据 |
| 管理员表(admin) | id、username、password、role | 存储管理员账号信息 |
3.3 第三步:后端核心功能实现——Spring Boot架构
基于Spring Boot框架实现系统核心业务逻辑,重点突破"轨迹管理""检测跟踪""资源分配"三大核心场景:
3.3.1 用户轨迹管理功能实现
@RestController
@RequestMapping("/api/track")
public class TrackController {
@Autowired
private TrackService trackService;
/**
* 记录用户轨迹
*/
@PostMapping("/record")
public ResponseEntity<?> recordTrack(@RequestBody TrackRecordDTO trackDTO,
@RequestHeader("userId") Long userId) {
try {
// 参数校验
if (trackDTO.getDidianId() == null || trackDTO.getGuijiTime() == null) {
return ResponseEntity.badRequest().body("地点ID、轨迹时间不能为空");
}
// 记录轨迹
UserTrack track = trackService.recordTrack(trackDTO, userId);
return ResponseEntity.ok("轨迹记录成功");
} catch (Exception e) {
return ResponseEntity.internalServerError()
.body("轨迹记录失败:" + e.getMessage());
}
}
/**
* 获取用户轨迹历史
*/
@GetMapping("/history")
public ResponseEntity<?> getTrackHistory(
@RequestHeader("userId") Long userId,
@RequestParam String startDate,
@RequestParam String endDate) {
try {
List<UserTrackVO> tracks = trackService.getTrackHistory(userId, startDate, endDate);
return ResponseEntity.ok(tracks);
} catch (Exception e) {
return ResponseEntity.internalServerError()
.body("获取轨迹历史失败:" + e.getMessage());
}
}
/**
* 密接者分析
*/
@PostMapping("/contact/analysis")
public ResponseEntity<?> analyzeCloseContacts(@RequestBody ContactAnalysisDTO analysisDTO) {
try {
List<CloseContactVO> contacts = trackService.analyzeCloseContacts(analysisDTO);
return ResponseEntity.ok(contacts);
} catch (Exception e) {
return ResponseEntity.internalServerError()
.body("密接者分析失败:" + e.getMessage());
}
}
}
@Service
@Transactional
public class TrackServiceImpl implements TrackService {
@Autowired
private UserTrackMapper trackMapper;
@Autowired
private UserMapper userMapper;
@Autowired
private LocationMapper locationMapper;
@Override
public UserTrack recordTrack(TrackRecordDTO dto, Long userId) {
// 1. 验证用户存在
User user = userMapper.selectByPrimaryKey(userId);
if (user == null) {
throw new RuntimeException("用户不存在");
}
// 2. 验证地点存在
Location location = locationMapper.selectByPrimaryKey(dto.getDidianId());
if (location == null) {
throw new RuntimeException("地点不存在");
}
// 3. 构建轨迹记录
UserTrack track = new UserTrack();
track.setYonghuId(userId);
track.setDidianId(dto.getDidianId());
track.setGuijiTime(dto.getGuijiTime());
track.setInsertTime(new Date());
track.setCreateTime(new Date());
// 4. 保存轨迹记录
trackMapper.insert(track);
// 5. 更新用户健康状态(如果地点为风险地区)
if (location.getDidianTypes() == 2) { // 风险地区
user.setJiankangTypes(2); // 设为风险状态
userMapper.updateByPrimaryKey(user);
}
return track;
}
@Override
public List<UserTrackVO> getTrackHistory(Long userId, String startDate, String endDate) {
// 构建查询条件
UserTrackExample example = new UserTrackExample();
example.createCriteria()
.andYonghuIdEqualTo(userId)
.andGuijiTimeBetween(
java.sql.Date.valueOf(startDate),
java.sql.Date.valueOf(endDate)
);
example.setOrderByClause("guiji_time DESC");
// 执行查询
List<UserTrack> tracks = trackMapper.selectByExample(example);
// 转换为VO对象,包含关联信息
return tracks.stream()
.map(track -> {
UserTrackVO vo = new UserTrackVO();
BeanUtils.copyProperties(track, vo);
// 获取地点信息
Location location = locationMapper.selectByPrimaryKey(track.getDidianId());
if (location != null) {
vo.setLocationName(location.getDidianName());
vo.setLocationType(location.getDidianTypes());
}
return vo;
}).collect(Collectors.toList());
}
@Override
public List<CloseContactVO> analyzeCloseContacts(ContactAnalysisDTO dto) {
// 1. 获取确诊用户轨迹
UserTrackExample example = new UserTrackExample();
example.createCriteria()
.andYonghuIdEqualTo(dto.getConfirmedUserId())
.andGuijiTimeBetween(dto.getStartTime(), dto.getEndTime());
List<UserTrack> confirmedTracks = trackMapper.selectByExample(example);
List<CloseContactVO> closeContacts = new ArrayList<>();
// 2. 分析每个轨迹点的密接者
for (UserTrack confirmedTrack : confirmedTracks) {
// 查找同一时间段在同一地点的其他用户
List<UserTrack> contactTracks = trackMapper.selectCloseContacts(
confirmedTrack.getDidianId(),
confirmedTrack.getGuijiTime(),
dto.getTimeWindow()
);
// 转换为密接者VO
for (UserTrack contactTrack : contactTracks) {
if (!contactTrack.getYonghuId().equals(dto.getConfirmedUserId())) {
CloseContactVO contact = new CloseContactVO();
contact.setUserId(contactTrack.getYonghuId());
contact.setLocationId(contactTrack.getDidianId());
contact.setContactTime(contactTrack.getGuijiTime());
contact.setRiskLevel(calculateRiskLevel(confirmedTrack, contactTrack));
// 获取用户信息
User user = userMapper.selectByPrimaryKey(contactTrack.getYonghuId());
if (user != null) {
contact.setUserName(user.getYonghuName());
contact.setUserPhone(user.getYonghuPhone());
}
closeContacts.add(contact);
}
}
}
return closeContacts;
}
/**
* 计算风险等级
*/
private Integer calculateRiskLevel(UserTrack confirmedTrack, UserTrack contactTrack) {
long timeDiff = Math.abs(confirmedTrack.getGuijiTime().getTime() -
contactTrack.getGuijiTime().getTime());
long minutesDiff = timeDiff / (1000 * 60);
if (minutesDiff <= 30) {
return 1; // 高风险
} else if (minutesDiff <= 120) {
return 2; // 中风险
} else {
return 3; // 低风险
}
}
}
3.3.2 核酸检测管理功能实现
@RestController
@RequestMapping("/api/nucleic")
public class NucleicTestController {
@Autowired
private NucleicTestService testService;
/**
* 录入检测结果
*/
@PostMapping("/result")
public ResponseEntity<?> recordTestResult(@RequestBody TestResultDTO resultDTO,
@RequestHeader("adminId") Long adminId) {
try {
// 参数校验
if (resultDTO.getYonghuId() == null || resultDTO.getJianceTypes() == null) {
return ResponseEntity.badRequest().body("用户ID、检测结果不能为空");
}
// 录入结果
NucleicTest test = testService.recordTestResult(resultDTO);
return ResponseEntity.ok("检测结果录入成功");
} catch (Exception e) {
return ResponseEntity.internalServerError()
.body("检测结果录入失败:" + e.getMessage());
}
}
/**
* 获取用户检测历史
*/
@GetMapping("/history")
public ResponseEntity<?> getTestHistory(
@RequestParam Long userId,
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
try {
PageResult<TestHistoryVO> result = testService.getTestHistory(userId, page, size);
return ResponseEntity.ok(result);
} catch (Exception e) {
return ResponseEntity.internalServerError()
.body("获取检测历史失败:" + e.getMessage());
}
}
/**
* 统计检测数据
*/
@GetMapping("/statistics")
public ResponseEntity<?> getTestStatistics(@RequestParam String date) {
try {
TestStatisticsVO statistics = testService.getTestStatistics(date);
return ResponseEntity.ok(statistics);
} catch (Exception e) {
return ResponseEntity.internalServerError()
.body("获取检测统计失败:" + e.getMessage());
}
}
}
@Service
@Transactional
public class NucleicTestServiceImpl implements NucleicTestService {
@Autowired
private NucleicTestMapper testMapper;
@Autowired
private UserMapper userMapper;
@Override
public NucleicTest recordTestResult(TestResultDTO dto) {
// 1. 验证用户存在
User user = userMapper.selectByPrimaryKey(dto.getYonghuId());
if (user == null) {
throw new RuntimeException("用户不存在");
}
// 2. 构建检测记录
NucleicTest test = new NucleicTest();
test.setYonghuId(dto.getYonghuId());
test.setJianceTypes(dto.getJianceTypes());
test.setJianceTime(dto.getJianceTime() != null ? dto.getJianceTime() : new Date());
test.setInsertTime(new Date());
test.setCreateTime(new Date());
// 3. 保存检测记录
testMapper.insert(test);
// 4. 更新用户健康状态
user.setJiankangTypes(dto.getJianceTypes() == 1 ? 1 : 3); // 1:阴性-健康, 其他:阳性-感染
userMapper.updateByPrimaryKey(user);
return test;
}
@Override
public PageResult<TestHistoryVO> getTestHistory(Long userId, int page, int size) {
// 分页配置
PageHelper.startPage(page, size);
// 构建查询条件
NucleicTestExample example = new NucleicTestExample();
example.createCriteria().andYonghuIdEqualTo(userId);
example.setOrderByClause("jiance_time DESC");
// 执行查询
List<NucleicTest> tests = testMapper.selectByExample(example);
PageInfo<NucleicTest> pageInfo = new PageInfo<>(tests);
// 转换为VO对象
List<TestHistoryVO> voList = tests.stream()
.map(test -> {
TestHistoryVO vo = new TestHistoryVO();
BeanUtils.copyProperties(test, vo);
// 获取用户信息
User user = userMapper.selectByPrimaryKey(test.getYonghuId());
if (user != null) {
vo.setUserName(user.getYonghuName());
}
return vo;
}).collect(Collectors.toList());
return new PageResult<>(voList, pageInfo.getTotal());
}
@Override
public TestStatisticsVO getTestStatistics(String date) {
TestStatisticsVO statistics = new TestStatisticsVO();
statistics.setDate(date);
// 统计总检测数
NucleicTestExample totalExample = new NucleicTestExample();
totalExample.createCriteria().andJianceTimeLike(date + "%");
statistics.setTotalTests(testMapper.countByExample(totalExample));
// 统计阳性数
NucleicTestExample positiveExample = new NucleicTestExample();
positiveExample.createCriteria()
.andJianceTimeLike(date + "%")
.andJianceTypesEqualTo(2); // 阳性
statistics.setPositiveTests(testMapper.countByExample(positiveExample));
// 统计阴性数
NucleicTestExample negativeExample = new NucleicTestExample();
negativeExample.createCriteria()
.andJianceTimeLike(date + "%")
.andJianceTypesEqualTo(1); // 阴性
statistics.setNegativeTests(testMapper.countByExample(negativeExample));
// 计算阳性率
if (statistics.getTotalTests() > 0) {
double positiveRate = (double) statistics.getPositiveTests() / statistics.getTotalTests() * 100;
statistics.setPositiveRate(Double.parseDouble(String.format("%.2f", positiveRate)));
}
return statistics;
}
}
3.3.3 疫苗预约管理功能实现
@RestController
@RequestMapping("/api/vaccine")
public class VaccineController {
@Autowired
private VaccineService vaccineService;
/**
* 疫苗预约
*/
@PostMapping("/appointment")
public ResponseEntity<?> makeAppointment(@RequestBody AppointmentDTO appointmentDTO,
@RequestHeader("userId") Long userId) {
try {
// 参数校验
if (appointmentDTO.getYimiaoId() == null) {
return ResponseEntity.badRequest().body("疫苗ID不能为空");
}
// 执行预约
VaccineAppointment appointment = vaccineService.makeAppointment(appointmentDTO, userId);
return ResponseEntity.ok("疫苗预约成功");
} catch (Exception e) {
return ResponseEntity.internalServerError()
.body("疫苗预约失败:" + e.getMessage());
}
}
/**
* 获取可预约疫苗列表
*/
@GetMapping("/available")
public ResponseEntity<?> getAvailableVaccines() {
try {
List<VaccineVO> vaccines = vaccineService.getAvailableVaccines();
return ResponseEntity.ok(vaccines);
} catch (Exception e) {
return ResponseEntity.internalServerError()
.body("获取疫苗列表失败:" + e.getMessage());
}
}
}
3.4 第四步:前端界面实现——疫情防控主题平台
基于现代前端技术构建用户界面,贴合疫情防控系统的"专业、清晰、易用"需求:
3.4.1 核心界面设计
-
管理员后台:
- 数据看板:关键指标统计、疫情趋势图表;
- 轨迹管理:用户轨迹查询、密接者分析;
- 检测管理:检测结果录入、统计报表;
- 疫苗管理:库存管理、预约统计;
- 物资管理:口罩库存、预订分配;
- 系统管理:用户管理、字典配置;
-
用户前端:
- 个人中心:基本信息、健康状态;
- 轨迹上报:地点选择、时间记录;
- 检测查询:历史记录、结果查看;
- 疫苗预约:疫苗选择、时间安排;
- 物资预订:口罩预订、领取记录;
- 公告查看:疫情通知、防控指南。
3.4.2 设计亮点
- 数据可视化:使用图表展示疫情数据趋势;
- 实时状态更新:健康状态、检测结果实时同步;
- 智能预警:风险自动识别和预警提示;
- 移动端适配:支持手机端便捷操作。
3.5 第五步:系统测试——确保系统稳定性
通过多维度测试验证系统功能完整性、性能稳定性和数据安全性:
3.5.1 功能测试
| 测试场景 | 测试用例 | 预期结果 | 实际结果 |
|---|---|---|---|
| 轨迹记录 | 用户记录行程轨迹 | 记录成功,状态更新 | 功能正常 |
| 密接分析 | 分析确诊者密接人员 | 准确识别密接者 | 分析准确 |
| 检测录入 | 管理员录入检测结果 | 结果保存,状态同步 | 录入成功 |
| 疫苗预约 | 用户预约疫苗接种 | 预约成功,库存更新 | 预约成功 |
3.5.2 性能测试
- 并发测试:模拟500用户同时操作系统,响应时间<2秒;
- 数据查询测试:查询万条轨迹记录,分页响应迅速;
- 统计分析测试:大数据量统计计算,结果准确。
3.5.3 安全测试
| 测试项 | 测试方法 | 预期结果 | 实际结果 |
|---|---|---|---|
| 数据权限 | 用户尝试访问他人数据 | 访问被拒绝 | 权限控制有效 |
| 敏感数据 | 检查数据库敏感信息 | 加密存储 | 加密有效 |
| 接口安全 | 测试接口越权访问 | 访问被拦截 | 安全防护有效 |
3.6 第六步:部署优化——提升系统性能
系统部署和性能优化措施:
- 集群部署:多节点部署,提高系统可用性;
- 数据库优化:读写分离,查询优化;
- 缓存策略:Redis缓存热点数据;
- 安全加固:网络安全配置,数据备份;
- 监控告警:系统监控,异常告警。
四、毕业设计复盘:疫情防控系统开发总结
4.1 技术难点与解决方案
- 轨迹数据分析:开发高效的密接者识别算法;
- 数据一致性:通过事务管理保证关键操作原子性;
- 系统性能:优化大数据量查询性能;
- 安全性:严格的权限控制和数据加密。
4.2 项目创新点
- 智能风险预警:基于轨迹数据的自动风险识别;
- 可视化数据分析:直观展示疫情发展趋势;
- 全流程管理:覆盖从检测到治疗的完整流程;
- 移动便捷性:支持移动端随时上报和查询。
五、项目资源与社会价值
5.1 项目资源
- 完整源代码及技术文档
- 数据库设计文档
- 系统部署指南
- 用户操作手册
- API接口文档
5.2 社会价值
- 提升防控效率:数字化管理大幅提升工作效率;
- 精准溯源:准确快速的密接者识别;
- 资源优化:合理分配检测和疫苗资源;
- 科学决策:数据支撑的疫情防控决策。
如果本文对您的Spring Boot学习、疫情防控系统毕业设计有帮助,欢迎点赞 + 收藏 + 关注,后续会分享更多社会服务类项目实战经验!