1. 项目背景与核心价值
去年参与某市疾控中心信息化改造时,我第一次接触到传染病防控系统的真实运作场景。传统纸质流调表的最大痛点在于:当发现阳性病例后,需要人工回溯其14天内的活动轨迹,再逐个联系可能接触的人员——这个过程往往需要48小时以上。而我们要开发的这套新冠病毒密接者跟踪系统,正是为了解决这个时效性痛点。
这个基于SpringBoot+Vue的全栈系统实现了三大核心能力:
- 电子化流调信息采集(相比纸质表格效率提升300%)
- 自动化时空重合分析(通过算法自动识别密接者)
- 可视化传播链展示(用关系图谱呈现传播路径)
技术栈选择上,后端采用SpringBoot 2.7 + MyBatis Plus的组合,前端使用Vue 3 + Element Plus,数据库采用MySQL 8.0。这套技术组合在高校教学中具有典型性——既包含了JavaEE的核心技术栈,又融合了主流前端框架,非常适合作为计算机专业学生的毕业设计或课程设计选题。
提示:系统开发需要特别注意《个人信息保护法》相关规定,所有敏感数据必须加密存储,演示数据建议使用生成器伪造
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计解析
2.1 整体技术架构
系统采用经典的前后端分离架构:
code复制[浏览器] ←HTTP→ [Nginx] ←RESTful→ [SpringBoot] ←JDBC→ [MySQL]
↑ ↓
Vue.js Redis缓存
前端工程通过Vue CLI创建,采用多环境配置:
- dev环境:连接本地Mock服务器
- test环境:连接测试服务器
- prod环境:通过Nginx反向代理
后端工程特点:
- 分层架构:controller/service/dao三层结构
- 统一响应体:Result
封装 - 异常处理:@ControllerAdvice全局捕获
2.2 数据库设计要点
核心表结构设计考虑流行病学调查特点:
sql复制CREATE TABLE `close_contact` (
`id` bigint NOT NULL AUTO_INCREMENT,
`case_id` bigint COMMENT '确诊病例ID',
`contact_id` bigint COMMENT '密接者ID',
`contact_type` tinyint COMMENT '接触类型(1同空间/2同交通)',
`start_time` datetime COMMENT '接触开始时间',
`end_time` datetime COMMENT '接触结束时间',
`risk_level` tinyint COMMENT '风险等级',
PRIMARY KEY (`id`),
INDEX `idx_case` (`case_id`),
INDEX `idx_contact` (`contact_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
特别注意:
- 时间字段精确到分钟级(流行病学调查要求)
- 建立复合索引提升查询效率
- 使用utf8mb4字符集支持emoji表情
3. 核心功能实现细节
3.1 时空重合算法实现
判断密接者的核心算法逻辑:
java复制public List<CloseContact> checkContact(Person casePerson, List<Person> suspectList) {
return suspectList.stream()
.filter(suspect -> {
// 空间重合检测
boolean spaceMatch = checkSpaceOverlap(
casePerson.getLocations(),
suspect.getLocations());
// 时间窗口检测(14天)
boolean timeMatch = checkTimeWindow(
casePerson.getTimeLines(),
suspect.getTimeLines(),
14 * 24 * 60); // 转换为分钟
return spaceMatch && timeMatch;
})
.map(suspect -> buildContact(casePerson, suspect))
.collect(Collectors.toList());
}
算法优化技巧:
- 采用Geohash进行空间位置编码
- 使用Redis缓存近期活动轨迹
- 对批量查询采用并行流处理
3.2 可视化传播链实现
前端使用Vue+ECharts实现传播关系图:
vue复制<template>
<div ref="chart" style="width:800px;height:600px"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
mounted() {
const chart = echarts.init(this.$refs.chart);
chart.setOption({
series: [{
type: 'graph',
layout: 'force',
data: this.nodes,
links: this.links,
force: { repulsion: 100 }
}]
});
}
}
</script>
关键配置项:
- 确诊人员显示为红色节点
- 密接者按风险等级显示不同颜色
- 鼠标悬停显示接触详情
4. 典型问题与解决方案
4.1 轨迹数据量大导致的性能问题
在压力测试中发现,当处理超过10万条轨迹数据时,系统响应时间超过5秒。通过以下方案优化:
- 数据分片处理
java复制// 按时间范围分片查询
@Query(nativeQuery = true, value =
"SELECT * FROM location_data " +
"WHERE person_id = :personId " +
"AND time BETWEEN :start AND :end")
List<Location> findByPersonAndTimeRange(
@Param("personId") Long personId,
@Param("start") LocalDateTime start,
@Param("end") LocalDateTime end);
- 添加Redis缓存层
java复制@Cacheable(value = "recentLocations",
key = "#personId",
unless = "#result == null || #result.isEmpty()")
public List<Location> getRecentLocations(Long personId) {
// 数据库查询逻辑
}
- 使用Elasticsearch进行地理搜索
4.2 前端大数据量渲染卡顿
当关系图谱节点超过500个时,浏览器出现明显卡顿。解决方案:
- 采用Web Worker进行数据处理
javascript复制// worker.js
self.onmessage = (e) => {
const data = processComplexData(e.data);
self.postMessage(data);
};
// 主线程
const worker = new Worker('worker.js');
worker.postMessage(rawData);
- 实现节点聚合展示
javascript复制{
symbolSize: (val) => {
return val.isCluster ? 30 + val.count : 15;
}
}
- 增加LOD(Level of Detail)控制
5. 项目扩展与进阶方向
5.1 微信小程序集成
实际部署中发现流调人员更习惯使用移动设备,我们增加了微信小程序端:
- 使用uni-app跨端框架
- 实现扫码登记功能
- 集成腾讯地图SDK
关键技术点:
javascript复制// 获取地理位置
wx.getLocation({
type: 'gcj02',
success: (res) => {
this.latitude = res.latitude;
this.longitude = res.longitude;
}
});
5.2 智能预测功能
基于历史数据构建传播预测模型:
python复制# 使用Prophet进行传播预测
from prophet import Prophet
model = Prophet(seasonality_mode='multiplicative')
model.fit(df)
future = model.make_future_dataframe(periods=7)
forecast = model.predict(future)
部署方案:
- 使用Python Flask构建预测服务
- SpringBoot通过HTTP调用
- 结果缓存到Redis
6. 开发环境搭建指南
6.1 后端环境配置
- JDK 11+环境变量配置:
bash复制# 在~/.bashrc中添加
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk
export PATH=$JAVA_HOME/bin:$PATH
- Maven仓库加速配置(settings.xml):
xml复制<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
- 数据库初始化脚本:
sql复制CREATE USER 'epidemic'@'%' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON epidemic.* TO 'epidemic'@'%';
FLUSH PRIVILEGES;
6.2 前端环境问题排查
常见问题及解决方案:
- Node Sass编译报错:
bash复制# 卸载原有版本
npm uninstall node-sass
# 安装新版本
npm install sass --save-dev
- ESLint与Prettier冲突:
json复制// .eslintrc.js
rules: {
'prettier/prettier': [
'error',
{
endOfLine: 'auto',
}
]
}
- 跨域问题解决:
javascript复制// vue.config.js
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
}
7. 毕业设计实施建议
7.1 论文写作要点
技术类毕业论文建议结构:
- 绪论(含疫情防控背景)
- 关键技术分析(SpringBoot/Vue特点)
- 系统设计(含架构图、ER图)
- 核心算法实现(时空重合算法)
- 系统测试(压力测试结果)
- 总结与展望
图表规范建议:
- 使用PlantUML绘制时序图
- 数据库关系图使用MySQL Workbench生成
- 界面截图需带操作说明
7.2 答辩演示技巧
- 演示数据准备:
java复制// 使用Java Faker生成测试数据
Faker faker = new Faker(Locale.CHINA);
Person person = new Person();
person.setName(faker.name().fullName());
person.setPhone(faker.phoneNumber().cellPhone());
- 重点演示环节:
- 新增确诊病例操作
- 自动识别密接者过程
- 传播链可视化展示
- 常见问题准备:
- 如何保证数据隐私?
- 系统最大支持多少并发?
- 与同类系统相比的优势?
8. 项目部署实战
8.1 Docker容器化部署
后端Dockerfile示例:
dockerfile复制FROM openjdk:11-jre
COPY target/epidemic-0.0.1-SNAPSHOT.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
前端Nginx配置:
nginx复制server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://backend:8080;
}
}
8.2 持续集成方案
Jenkinsfile配置示例:
groovy复制pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'mvn clean package -DskipTests'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
}
stage('Deploy') {
steps {
sh 'docker build -t epidemic-backend .'
sh 'docker-compose up -d'
}
}
}
}
9. 项目经验与反思
在实际开发过程中,有几个关键教训值得分享:
- 时间处理陷阱:
java复制// 错误做法(时区问题)
LocalDateTime.parse("2023-01-01 12:00");
// 正确做法
DateTimeFormatter formatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm")
.withZone(ZoneId.of("Asia/Shanghai"));
- 前端性能监控:
javascript复制// 使用Performance API检测耗时
const start = performance.now();
// ...执行操作
const duration = performance.now() - start;
- 数据库连接池配置:
yaml复制spring:
datasource:
hikari:
maximum-pool-size: 20
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
这个项目让我深刻体会到,医疗信息化系统开发需要特别注重:
- 数据准确性(算法逻辑必须严谨)
- 系统稳定性(7×24小时运行)
- 操作便捷性(考虑一线人员使用场景)
对于学生开发者来说,建议先从简化版开始:
- 先实现单日接触追踪
- 再扩展多日回溯功能
- 最后增加预测等高级功能
