校园健康监测系统采用前后端分离架构,后端基于SpringBoot+MyBatis技术栈实现RESTful API服务,前端使用Vue.js框架构建响应式管理界面。系统整体采用MVC设计模式,实现业务逻辑与视图展示的清晰分离。
选择SpringBoot作为后端框架主要基于以下考虑:
数据库选用MySQL 8.0版本,主要优势包括:
系统核心模块包括:
各模块间通过Spring事件机制解耦,例如当学生提交体温异常记录时,系统会自动触发通知事件,由专门的消息处理器推送给班主任。
学生健康档案表(student_health)关键字段:
sql复制CREATE TABLE `student_health` (
`id` bigint NOT NULL AUTO_INCREMENT,
`student_id` varchar(20) NOT NULL COMMENT '学号',
`name` varchar(50) NOT NULL,
`gender` char(1) DEFAULT NULL,
`birth_date` date DEFAULT NULL,
`blood_type` varchar(10) DEFAULT NULL,
`allergy_history` text COMMENT '过敏史',
`chronic_disease` text COMMENT '慢性病史',
`emergency_contact` varchar(50) DEFAULT NULL,
`emergency_phone` varchar(20) DEFAULT NULL,
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_student_id` (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
针对高频查询场景采取以下优化措施:
sql复制ALTER TABLE `daily_health_check`
ADD INDEX `idx_class_date` (`class_id`, `check_date`);
sql复制CREATE TABLE `student_health_detail` (
`health_id` bigint NOT NULL,
`medical_history` text,
`family_disease` text,
PRIMARY KEY (`health_id`)
) ENGINE=InnoDB;
xml复制<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
采用Apache POI处理Excel导入,关键代码实现:
java复制@PostMapping("/import")
public R importHealthData(@RequestParam("file") MultipartFile file) {
try {
Workbook workbook = WorkbookFactory.create(file.getInputStream());
Sheet sheet = workbook.getSheetAt(0);
List<StudentHealth> healthList = new ArrayList<>();
for (Row row : sheet) {
if (row.getRowNum() == 0) continue; // 跳过标题行
StudentHealth health = new StudentHealth();
health.setStudentId(row.getCell(0).getStringCellValue());
health.setName(row.getCell(1).getStringCellValue());
// 其他字段处理...
healthList.add(health);
}
if (!healthList.isEmpty()) {
studentHealthService.batchInsert(healthList);
}
return R.ok("导入成功");
} catch (Exception e) {
log.error("导入异常", e);
return R.error("导入失败: " + e.getMessage());
}
}
基于Quartz实现定时体温检测任务:
java复制public class TemperatureAlertJob implements Job {
@Autowired
private HealthCheckService healthCheckService;
@Override
public void execute(JobExecutionContext context) {
LocalDate today = LocalDate.now();
List<AbnormalTemperature> abnormals = healthCheckService
.checkAbnormalTemperature(today);
if (!abnormals.isEmpty()) {
abnormals.forEach(abnormal -> {
// 发送企业微信通知
wechatService.sendAlertToTeacher(
abnormal.getClassId(),
abnormal.getStudentName(),
abnormal.getTemperature()
);
});
}
}
}
采用RBAC模型,通过Spring Security实现:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/api/health/**").hasAnyRole("TEACHER", "ADMIN")
.antMatchers("/api/report/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
敏感字段采用AES加密存储:
java复制public class DataEncryptor {
private static final String KEY = "健康监测系统密钥";
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
public static String encrypt(String data) {
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
// 初始化向量处理...
return Base64.getEncoder().encodeToString(
cipher.doFinal(data.getBytes())
);
} catch (Exception e) {
throw new RuntimeException("加密失败", e);
}
}
}
使用Docker Compose编排服务:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/health_system
frontend:
build: ./frontend
ports:
- "80:80"
volumes:
mysql_data:
集成Prometheus监控指标:
java复制@Configuration
public class MetricsConfig {
@Bean
MeterRegistryCustomizer<PrometheusMeterRegistry> configureMetrics() {
return registry -> registry.config().commonTags(
"application", "health-monitoring-system"
);
}
}
在实际开发过程中,有几个关键点需要特别注意:
xml复制<select id="selectHealthRecords" resultType="HealthRecord">
SELECT * FROM health_record
<where>
<if test="classId != null">
AND class_id = #{classId}
</if>
<if test="startDate != null and endDate != null">
AND record_date BETWEEN #{startDate} AND #{endDate}
</if>
</where>
ORDER BY record_date DESC
LIMIT #{offset}, #{pageSize}
</select>
java复制@Slf4j
@Service
public class HealthCheckService {
public void processDailyCheck() {
try {
// 业务逻辑...
log.info("每日健康检查处理完成,共处理{}条记录", count);
} catch (Exception e) {
log.error("健康检查处理异常", e);
throw new BusinessException("处理失败");
}
}
}
这个系统在实际部署后,能够有效管理5000+学生的健康数据,日均处理健康打卡记录约3000条,异常体温检测响应时间控制在5秒以内。通过合理的索引设计和缓存策略,即使在学期初的高并发时段,系统也能保持稳定的响应性能。