1. 项目背景与核心价值
心脏病数据分析系统是医疗信息化领域的重要应用方向。根据世界卫生组织统计,心血管疾病是全球首要死因,每年导致约1790万人死亡。传统的心脏病诊断主要依赖医生经验,而数据分析系统能够通过算法模型挖掘潜在规律,辅助医生进行更精准的诊断决策。
这个SpringBoot+Vue的全栈系统实现了从数据采集、存储到分析可视化的完整闭环。后端采用Java技术栈处理复杂的医疗数据分析算法,前端通过Vue实现友好的可视化交互,为心血管科室医生提供了高效的数字化工作平台。
2. 技术架构设计
2.1 整体技术选型
后端技术栈:
- SpringBoot 2.7.x:提供RESTful API和核心业务逻辑
- MyBatis-Plus 3.5.x:简化数据库操作
- MySQL 8.0:存储患者基础信息和诊断数据
- Redis 6.x:缓存高频访问的分析结果
- Swagger 3.0:API文档自动化生成
前端技术栈:
- Vue 3.x:前端主框架
- Element Plus:UI组件库
- ECharts 5.x:数据可视化
- Axios:HTTP请求处理
开发环境:
- JDK 17
- Node.js 16.x
- Maven 3.8.x
2.2 系统模块划分
code复制com.heart.analysis
├── config # 配置类
├── controller # API接口
├── service # 业务逻辑
│ ├── impl # 实现类
├── dao # 数据访问
├── entity # 实体类
├── dto # 数据传输对象
├── util # 工具类
└── exception # 异常处理
3. 核心功能实现
3.1 患者数据管理模块
数据库表设计:
sql复制CREATE TABLE `patient_info` (
`id` bigint NOT NULL AUTO_INCREMENT,
`patient_id` varchar(32) NOT NULL COMMENT '病历号',
`name` varchar(50) NOT NULL,
`gender` tinyint NOT NULL COMMENT '0-女 1-男',
`age` int NOT NULL,
`height` decimal(5,2) COMMENT '身高(cm)',
`weight` decimal(5,2) COMMENT '体重(kg)',
`blood_pressure` varchar(20) COMMENT '血压',
`medical_history` text COMMENT '病史',
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_patient_id` (`patient_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
SpringBoot接口示例:
java复制@RestController
@RequestMapping("/api/patient")
@Api(tags = "患者管理")
public class PatientController {
@Autowired
private PatientService patientService;
@PostMapping
@ApiOperation("新增患者")
public Result addPatient(@Valid @RequestBody PatientDTO dto) {
return Result.success(patientService.addPatient(dto));
}
@GetMapping("/{id}")
@ApiOperation("获取患者详情")
public Result getPatient(@PathVariable Long id) {
return Result.success(patientService.getById(id));
}
}
3.2 心电图数据分析模块
核心算法流程:
- 数据预处理(去噪、归一化)
- QRS波群检测
- ST段分析
- 心律失常分类
- 风险评分计算
关键实现代码:
java复制public class ECGAnalysisService {
public AnalysisResult analyze(ECGData data) {
// 1. 小波变换去噪
double[] denoised = WaveletDenoiser.process(data.getSignal());
// 2. 使用Pan-Tompkins算法检测QRS波
QRSDetectionResult qrs = new PanTompkins().detect(denoised);
// 3. 计算ST段偏移量
STAnalysis stAnalysis = new STAnalyzer().analyze(qrs);
// 4. 心律失常分类
ArrhythmiaType type = new Classifier().classify(qrs);
// 5. 计算风险评分
RiskScore score = RiskEvaluator.evaluate(stAnalysis, type);
return new AnalysisResult(qrs, stAnalysis, type, score);
}
}
4. 可视化功能实现
4.1 Vue心电图展示组件
vue复制<template>
<div class="ecg-container">
<div ref="chart" style="width:100%;height:400px"></div>
</div>
</template>
<script>
import * as echarts from 'echarts'
export default {
props: ['ecgData'],
mounted() {
this.initChart()
},
methods: {
initChart() {
const chart = echarts.init(this.$refs.chart)
const option = {
tooltip: { trigger: 'axis' },
xAxis: {
type: 'category',
data: this.ecgData.timePoints
},
yAxis: { type: 'value' },
series: [{
data: this.ecgData.values,
type: 'line',
smooth: true,
lineStyle: { width: 1 }
}]
}
chart.setOption(option)
}
}
}
</script>
4.2 患者数据看板
vue复制<template>
<el-row :gutter="20">
<el-col :span="8" v-for="(item,index) in stats" :key="index">
<el-card shadow="hover">
<div class="card-title">{{item.title}}</div>
<div class="card-value">{{item.value}}</div>
<div class="card-footer">
<span :class="item.trend >=0 ? 'up':'down'">
{{item.trend >=0 ? '↑' : '↓'}} {{Math.abs(item.trend)}}%
</span>
<span>较上月</span>
</div>
</el-card>
</el-col>
</el-row>
</template>
5. 系统安全与性能优化
5.1 医疗数据安全措施
- 数据传输加密:
java复制@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requiresChannel()
.requestMatchers(r -> r.getHeader("X-Forwarded-Proto") != null)
.requiresSecure();
}
}
- 敏感数据脱敏:
java复制public class DataMaskUtil {
public static String maskName(String name) {
if(StringUtils.isEmpty(name)) return "";
return name.charAt(0) + "**";
}
public static String maskIdCard(String idCard) {
if(StringUtils.isEmpty(idCard) || idCard.length() < 8) return idCard;
return idCard.substring(0,3) + "****" + idCard.substring(idCard.length()-4);
}
}
5.2 性能优化实践
- MyBatis二级缓存配置:
xml复制<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="localCacheScope" value="STATEMENT"/>
</settings>
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
- 接口响应优化:
java复制@GetMapping("/analysis/{id}")
@Cacheable(value = "ecgAnalysis", key = "#id")
public AnalysisResult getAnalysisResult(@PathVariable Long id) {
// 复杂计算过程
return heavyCalculationService.calculate(id);
}
6. 部署与运维方案
6.1 生产环境部署
Docker Compose配置示例:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PWD}
MYSQL_DATABASE: heart_analysis
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
redis:
image: redis:6-alpine
ports:
- "6379:6379"
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
- redis
frontend:
build: ./frontend
ports:
- "80:80"
volumes:
mysql_data:
6.2 监控配置
SpringBoot Actuator集成:
properties复制# application-prod.properties
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
management.endpoint.metrics.enabled=true
management.metrics.export.prometheus.enabled=true
7. 开发经验与避坑指南
-
医疗数据精度问题:
- 心电数据存储使用DECIMAL(10,6)确保精度
- 避免使用float/double进行关键计算
-
时间序列数据处理技巧:
- 使用环形缓冲区处理实时心电数据流
- 采用降采样策略减少前端渲染压力
-
跨域解决方案:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*")
.allowedHeaders("*")
.maxAge(3600);
}
}
-
Element Plus表格性能优化:
- 大数据量使用虚拟滚动
- 复杂表格拆分子组件
-
MyBatis批量插入优化:
java复制@Transactional
public void batchInsert(List<ECGData> list) {
SqlSession session = sqlSessionTemplate.getSqlSessionFactory()
.openSession(ExecutorType.BATCH, false);
try {
ECGMapper mapper = session.getMapper(ECGMapper.class);
for (ECGData data : list) {
mapper.insert(data);
}
session.commit();
} finally {
session.close();
}
}