在基层社区管理中,突发公共卫生事件的有效应对一直是难点痛点。传统纸质登记方式存在三大硬伤:数据更新滞后导致决策延误、信息孤岛阻碍跨部门协作、人工统计耗时且易出错。我们团队在参与某市社区防疫支援时,亲眼目睹工作人员凌晨三点还在手工汇总Excel表格的困境。
这套系统的设计初衷很明确——用技术手段解决三个核心问题:
典型应用场景举例:
采用前后端分离架构,这是经过多次线上验证的稳定方案。后端用SpringBoot提供RESTful API,前端Vue.js实现动态交互,两者通过JWT进行安全认证。特别说明选择理由:
SpringBoot的优势:
Vue的选型考量:
mermaid复制graph TD
A[前端Vue.js] -->|Axios请求| B[SpringBoot API]
B --> C[MyBatis ORM]
C --> D[MySQL 8.0]
B --> E[Redis缓存]
A --> F[ECharts可视化]
核心表设计遵循三范式且针对疫情场景优化:
sql复制CREATE TABLE `epidemic_dynamic` (
`dynamic_id` BIGINT PRIMARY KEY COMMENT '动态ID',
`community_code` VARCHAR(20) NOT NULL COMMENT '社区编码',
`report_date` DATE NOT NULL COMMENT '统计日期',
`current_cases` INT DEFAULT 0 COMMENT '现存确诊',
`new_suspected` INT DEFAULT 0 COMMENT '新增疑似',
`quarantine_num` INT DEFAULT 0 COMMENT '隔离人数',
`material_status` ENUM('充足','紧张','短缺') COMMENT '物资状态',
`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`update_operator` VARCHAR(32) COMMENT '操作人'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
设计亮点:
sql复制CREATE TABLE `resident_health` (
`health_id` BIGINT AUTO_INCREMENT PRIMARY KEY,
`resident_id` VARCHAR(18) NOT NULL COMMENT '身份证号',
`temperature` DECIMAL(3,1) CHECK (temperature BETWEEN 35.0 AND 42.0),
`symptom_flag` TINYINT(1) DEFAULT 0 COMMENT '有无症状',
`contact_history` TINYINT(1) DEFAULT 0 COMMENT '接触史',
`vaccine_status` VARCHAR(10) COMMENT '疫苗接种',
`geo_location` POINT SRID 4326 COMMENT '地理坐标',
KEY `idx_resident` (`resident_id`)
) ENGINE=InnoDB;
特殊处理:
采用渐进式表单设计提升填写体验:
前端关键代码:
vue复制<template>
<el-form @submit.prevent="submitForm">
<el-checkbox-group v-model="form.symptoms">
<el-checkbox label="fever">发热</el-checkbox>
<el-checkbox label="cough">咳嗽</el-checkbox>
</el-checkbox-group>
<div v-if="showDetailForm">
<el-input-number
v-model="form.temperature"
:precision="1"
:min="35"
:max="42"/>
</div>
</el-form>
</template>
后端处理逻辑:
java复制@PostMapping("/health-report")
public R submitReport(@RequestBody HealthReportDTO dto) {
// 1. 数据校验
if (dto.getTemperature() > 37.3) {
// 触发高温预警流程
warningService.notifyCommunityAdmin(dto.getResidentId());
}
// 2. 构建实体
ResidentHealth entity = new ResidentHealth();
BeanUtils.copyProperties(dto, entity);
entity.setGeoLocation(geoService.getCoordinate());
// 3. 持久化
healthService.save(entity);
// 4. 更新社区统计
dynamicService.updateCommunityStats(dto.getCommunityCode());
return R.ok().put("qrCode", generateCheckInCode());
}
基于ECharts实现四类核心图表:
性能优化技巧:
javascript复制// 热力图配置示例
option = {
tooltip: {},
visualMap: {
min: 0,
max: 10,
calculable: true
},
series: [{
type: 'heatmap',
data: heatData,
pointSize: 10,
blurSize: 5
}]
}
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Session | 服务端可控 | 不利于横向扩展 | 单体应用 |
| JWT | 无状态 | 无法即时失效 | 分布式系统 |
| OAuth2 | 第三方集成友好 | 实现复杂 | 开放平台 |
最终选择JWT+Redis的组合方案:
RBAC模型扩展实现:
java复制// 注解式权限控制
@PreAuthorize("hasRole('ADMIN') or hasPermission(#communityCode, 'WRITE')")
@PostMapping("/update-stats")
public R updateStats(@PathVariable String communityCode) {
// 业务逻辑
}
// 数据权限过滤
Wrapper<Resident> wrapper = new EntityWrapper<>();
if (!user.hasRole("SUPER_ADMIN")) {
wrapper.eq("community_code", user.getCommunityCode());
}
Docker Compose编排方案:
yaml复制version: '3'
services:
app:
image: openjdk:11-jre
ports:
- "8080:8080"
volumes:
- ./logs:/app/logs
depends_on:
- redis
- mysql
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
SpringBoot Actuator关键端点:
Prometheus监控配置示例:
yaml复制scrape_configs:
- job_name: 'community-app'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['app:8080']
MyBatis批量插入优化:
<foreach>标签批量操作xml复制<insert id="batchInsert">
INSERT INTO resident_health VALUES
<foreach collection="list" item="item" separator=",">
(#{item.healthId}, #{item.temperature}, ...)
</foreach>
</insert>
Vue响应式丢失问题:
this.$set()或重新赋值整个对象JWT续期策略:
这套系统在某社区试运行期间,将疫情信息处理时效从原来的8小时缩短到15分钟,物资调度准确率达到99.7%。特别提醒:开发时要注意居民隐私保护,所有敏感数据必须脱敏存储。