1. 项目背景与核心价值
去年参与某社区防疫系统升级时,我深刻体会到基层疫情管理的信息化痛点。社区工作人员还在用Excel手工统计居民健康信息,每天要处理上百条微信报备,经常出现数据重复或遗漏。这个基于SpringBoot+Vue的全栈项目,正是为解决这类场景而生。
系统采用前后端分离架构,后端用SpringBoot2提供RESTful API,前端Vue3构建管理界面,MyBatis-Plus操作MySQL8.0数据库。相比传统JSP方案,这种组合让社区工作人员在手机端就能完成信息登记,自动生成统计报表,效率提升至少3倍。特别适合5000人以下的中小型社区使用。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构解析
2.1 后端技术栈选型
选择SpringBoot2而非最新3.0版本是经过实际验证的决策。在社区服务中心的Windows Server环境下,JDK8的兼容性更为稳定。我们通过spring-boot-starter-web快速构建了以下核心模块:
java复制// 疫情上报API示例
@RestController
@RequestMapping("/api/health")
public class HealthReportController {
@Autowired
private HealthReportService reportService;
@PostMapping
public Result submitReport(@Valid @RequestBody HealthReportDTO dto) {
return reportService.processReport(dto);
}
}
MyBatis-Plus的Lambda查询方式大幅简化了数据操作:
java复制// 使用QueryWrapper构建条件查询
public Page<HealthReport> getReportsByCondition(ReportQuery query) {
return page(new Page<>(query.getPage(), query.getSize()),
Wrappers.<HealthReport>lambdaQuery()
.eq(query.getStatus() != null, HealthReport::getStatus, query.getStatus())
.between(query.getStartDate() != null, HealthReport::getReportDate,
query.getStartDate(), query.getEndDate())
);
}
2.2 前端工程化实践
Vue3组合式API让复杂表单开发更高效。这个健康申报表单组件采用了Element Plus:
vue复制<script setup>
const form = reactive({
name: '',
temperature: null,
symptoms: [],
contactHistory: false
})
const rules = {
temperature: [
{ validator: (_,v,cb) => v>=35&&v<=42?cb():cb('请输入35-42之间数值') }
]
}
</script>
通过Vite构建工具,冷启动时间控制在800ms内,比传统webpack快4倍。特别优化了移动端适配,社区工作人员用手机浏览器也能流畅操作。
3. 核心功能实现细节
3.1 疫情数据看板设计
采用ECharts实现动态数据可视化,关键点在于处理时间序列数据:
java复制// 后端统计逻辑
public List<StatsVO> get7DayTrend() {
return baseMapper.selectMaps(
"SELECT report_date as date, COUNT(*) as total,
SUM(is_abnormal) as abnormal
FROM health_report
WHERE report_date >= DATE_SUB(CURDATE(), INTERVAL 6 DAY)
GROUP BY report_date"
).stream().map(StatsVO::new).collect(Collectors.toList());
}
前端使用hook封装图表逻辑:
javascript复制export function useTrendChart(container) {
const chart = ref(null)
onMounted(() => {
chart.value = echarts.init(container.value)
fetchData().then(data => {
chart.value.setOption({
xAxis: { data: data.map(d => d.date) },
series: [
{ data: data.map(d => d.total) },
{ data: data.map(d => d.abnormal) }
]
})
})
})
}
3.2 异常预警机制
通过Spring Scheduler实现定时扫描:
java复制@Scheduled(cron = "0 0/30 8-20 * * ?")
public void checkAbnormalReports() {
List<HealthReport> reports = list(Wrappers.<HealthReport>query()
.eq("status", 0)
.eq("temperature", ">", 37.3));
reports.forEach(report -> {
smsService.sendAlert(report.getPhone());
update().set("status", 1).eq("id", report.getId()).update();
});
}
4. 数据库优化实践
4.1 MySQL8.0特性应用
利用窗口函数优化分页查询:
sql复制SELECT * FROM (
SELECT *, ROW_NUMBER() OVER(ORDER BY report_date DESC) as rn
FROM health_report
) t WHERE rn BETWEEN 1001 AND 1050;
使用JSON字段存储动态症状信息:
java复制@TableField(typeHandler = FastjsonTypeHandler.class)
private List<String> symptoms;
4.2 索引设计规范
建立了复合索引提升查询效率:
sql复制ALTER TABLE health_report
ADD INDEX idx_community_status (community_id, status, report_date);
5. 部署与运维要点
5.1 多环境配置管理
通过Spring Profiles实现配置隔离:
yaml复制# application-dev.yml
server:
port: 8080
datasource:
url: jdbc:mysql://localhost:3306/epidemic?useSSL=false
5.2 前端部署优化
配置Nginx静态资源缓存:
nginx复制location / {
try_files $uri $uri/ /index.html;
expires 1d;
}
location /assets {
expires 1y;
add_header Cache-Control "public";
}
6. 踩坑实录与解决方案
-
MyBatis-Plus版本冲突:
使用3.5.1版本时遇到TypeHandler注册问题,降级到3.4.3后解决。建议锁定版本:xml复制<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.3.4</version> </dependency> -
Vue3响应式丢失:
在解构props时会丢失响应性,改用toRefs解决:javascript复制const { form } = toRefs(props) -
MySQL时区问题:
必须在连接字符串明确指定时区:yaml复制url: jdbc:mysql://localhost:3306/epidemic?serverTimezone=Asia/Shanghai
7. 扩展建议
-
微信小程序接入:
可增加uniapp版本,复用现有API。实测改造工作量约40人日。 -
智能预警升级:
接入温度计IoT设备数据,自动触发预警阈值调整。 -
多级权限控制:
增加街道级管理员视图,使用Spring Security实现数据隔离。
这个项目最让我惊喜的是Vue3的Composition API与SpringBoot的协同效率。在后续迭代中,我们引入了WebSocket实现实时数据看板,将疫情数据延迟从原来的15分钟降低到10秒内。对于需要快速响应防疫需求的社区,这套技术栈值得推荐。
