高校师生健康信息管理一直是校园管理中的重点难点。记得去年帮某高校部署这套系统时,他们的校医室主任拿着厚厚的登记本苦笑:"每天要统计5000多人的体温数据,光是整理报表就要加班到凌晨。"这正是传统健康管理方式的典型痛点——效率低下、容易出错、数据利用率低。
我们开发的这套SpringBoot+Vue+MySQL师生健康信息管理系统,正是为了解决这些实际问题。系统采用前后端分离架构,后端使用SpringBoot提供RESTful API接口,前端基于Vue.js构建响应式界面,MySQL作为数据存储引擎。在新冠疫情期间,系统日均处理健康上报数据超过2万条,异常体温预警响应时间缩短至15分钟内,统计报表生成效率提升20倍。
选择SpringBoot作为后端框架主要基于三个考量:
前端选用Vue.js而非React/Angular的原因是:
数据库采用MySQL 8.0版本,主要利用其:
code复制[前端层] Vue.js + ElementUI
↑↓ HTTP/HTTPS
[API网关层] Spring Cloud Gateway
↑↓
[业务层] SpringBoot + MyBatis-Plus
↑↓
[数据层] MySQL + Redis缓存
↑
[安全层] JWT + Spring Security
提示:实际部署时建议将Redis用于高频访问的数据缓存(如健康打卡状态),可降低数据库压力约40%
用户表(sys_user)采用纵向分表设计:
sql复制CREATE TABLE `sys_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '雪花算法ID',
`username` varchar(50) COLLATE utf8mb4_bin NOT NULL COMMENT '登录账号',
`password` varchar(100) COLLATE utf8mb4_bin NOT NULL COMMENT 'BCrypt加密',
`role_code` varchar(20) COLLATE utf8mb4_bin NOT NULL COMMENT '角色编码',
`dept_id` int DEFAULT NULL COMMENT '院系ID',
`last_login_time` datetime DEFAULT NULL COMMENT '最后登录',
`status` tinyint DEFAULT '1' COMMENT '状态(0禁用)',
PRIMARY KEY (`user_id`),
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
权限控制采用RBAC模型:
@PreAuthorize("hasRole('HEALTH_ADMIN')")核心表(health_report)设计要点:
java复制@Entity
@Table(name = "health_report")
public class HealthReport {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long reportId;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
@Column(precision = 3, scale = 1)
private BigDecimal temperature;
private Integer symptoms; // 位运算存储
@Column(columnDefinition = "GEOMETRY")
private Geometry travelPath;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
private LocalDateTime submitTime;
}
踩坑记录:初期使用VARCHAR存储行程信息,后来发现LIKE查询性能极差,改用空间索引后查询速度提升8倍
前端关键代码(Vue3+TS):
typescript复制const submitHealth = async () => {
try {
const geo = await getLocation(); // 获取地理坐标
const res = await api.submitReport({
temperature: form.value.temp,
symptoms: selectedSymptoms.value,
location: geo
});
if(res.code === 200) {
ElMessage.success('提交成功');
// 实时更新本地打卡状态
store.commit('updateDailyStatus', true);
}
} catch (err) {
ElMessage.error(`提交失败: ${err.message}`);
}
}
后端处理逻辑:
采用定时任务+缓存策略:
java复制@Scheduled(cron = "0 0 23 * * ?") // 每晚23点执行
public void generateDailyReport() {
// 1. 从Redis获取当日缓存数据
String cacheKey = "health:stats:" + LocalDate.now();
Object cached = redisTemplate.opsForValue().get(cacheKey);
// 2. 无缓存时查询数据库
if(cached == null) {
List<HealthStats> stats = healthMapper.selectDailyStats();
redisTemplate.opsForValue().set(cacheKey, stats, 6, TimeUnit.HOURS);
}
// 3. 生成可视化JSON
JSONObject report = new JSONObject();
report.put("abnormalCount", countAbnormalCases());
report.put("departmentStats", buildDeptStats());
// 4. 存入统计表
statsMapper.insert(new StatsLog(report));
}
推荐服务器规格:
ini复制innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
max_connections = 200
Nginx前端配置示例:
nginx复制server {
listen 80;
server_name health.yourschool.edu.cn;
location / {
root /var/www/health-front;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://localhost:8080;
proxy_set_header X-Real-IP $remote_addr;
}
}
接口响应优化:
java复制@Cacheable(value = "userStats", key = "#userId")
public UserHealthStats getUserStats(Long userId) {
// 复杂查询逻辑
}
数据库优化:
前端优化:
javascript复制const Report = () => import('./views/Report.vue')
现象:每天8:00-9:00出现接口超时
解决方案:
java复制@PostMapping("/submit")
public Result submit(@RequestBody ReportDTO dto) {
mqTemplate.convertAndSend("health.queue", dto);
return Result.success("已接收数据");
}
常见原因:
应对策略:
javascript复制// 备用定位方案
const getFallbackLocation = () => {
return axios.get('https://api.ip.sb/geoip')
.then(res => ({
lat: res.data.latitude,
lng: res.data.longitude
}));
};
微信小程序接入:
javascript复制wx.requestSubscribeMessage({
tmplIds: ['体温异常提醒模板ID']
})
大数据分析扩展:
物联网整合:
这套系统在某高校实际运行一年后,健康数据填报率从68%提升至99%,疫情追踪效率提高40倍。最大的收获是:好的技术方案必须理解真实的管理场景,我们的院系分级审核功能就是根据校医室的实际工作流程反复调整了三次才最终定型。