在基层社区疫情防控工作中,信息管理系统的建设一直是个痛点。作为参与过多个社区信息化项目的开发者,我深刻理解社区工作者面临的困境:纸质登记效率低下、Excel表格难以共享、数据统计耗时费力。这套基于SpringBoot+Vue的疫情信息管理系统,正是为解决这些实际问题而设计的。
系统采用主流的前后端分离架构,后端使用SpringBoot提供RESTful API接口,前端基于Vue.js+ElementUI构建管理界面,数据库选用轻量级的MySQL。这种技术组合既保证了系统性能,又降低了部署门槛,特别适合中小型社区使用。我在开发过程中特别注重实际场景需求,比如考虑到社区工作人员可能不熟悉复杂操作,所有功能都设计了直观的交互流程。
后端选择SpringBoot主要基于三点考虑:首先,它的自动配置特性大幅减少了XML配置,让社区技术人员也能快速上手;其次,内嵌Tomcat支持一键启动,部署时不需要额外安装应用服务器;最后,丰富的Starter依赖可以方便地集成MyBatis、Redis等常用组件。
前端采用Vue.js+ElementUI的组合,是因为它们的学习曲线相对平缓。ElementUI提供了一套完整的UI组件,包括表格、表单、弹窗等疫情防控系统必需的元素。实测下来,即使是没有前端开发经验的社区工作人员,经过简单培训也能完成日常数据维护。
数据库选用MySQL 5.7版本,主要考虑到:社区数据量通常在百万级以下,MySQL完全能够胜任;社区IT基础设施普遍一般,MySQL对服务器配置要求较低;社区工作人员大多对MySQL有一定了解,后期维护更方便。
系统设计了五个核心功能模块:
权限控制采用RBAC模型,区分管理员、社区工作人员和普通居民三种角色。管理员拥有全部权限,工作人员可以管理居民信息但不能修改系统配置,居民只能查看个人相关信息和提交出入申请。
居民健康信息表(resident_health)的设计特别注意了数据隐私保护:
出入记录表(access_record)的字段设计考虑了实际使用场景:
疫苗接种表(vaccination)特别注意了数据准确性:
sql复制-- 居民健康状态统计(按健康码颜色分组)
SELECT health_code, COUNT(*) as count
FROM resident_health
GROUP BY health_code;
-- 出入记录复杂查询(带审批状态和时间范围)
SELECT r.resident_name, a.entry_time, a.exit_time, a.reason
FROM access_record a
JOIN resident_health r ON a.resident_id = r.resident_id
WHERE a.approval_status = 'APPROVED'
AND a.entry_time BETWEEN '2023-01-01' AND '2023-01-31';
-- 疫苗接种进度统计(按年龄段)
SELECT
CASE
WHEN TIMESTAMPDIFF(YEAR, r.birth_date, CURDATE()) < 18 THEN '未成年'
WHEN TIMESTAMPDIFF(YEAR, r.birth_date, CURDATE()) BETWEEN 18 AND 60 THEN '成年'
ELSE '老年'
END as age_group,
COUNT(DISTINCT v.resident_id) as vaccinated_count,
COUNT(DISTINCT r.resident_id) as total_count
FROM resident_health r
LEFT JOIN vaccination v ON r.resident_id = v.resident_id
GROUP BY age_group;
在application.yml中做了以下优化配置:
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/community_covid?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
hikari:
maximum-pool-size: 10 # 根据社区并发量调整
connection-timeout: 30000
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
mybatis:
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
居民健康信息控制器设计了严格的参数校验:
java复制@RestController
@RequestMapping("/api/health")
public class HealthController {
@Autowired
private HealthService healthService;
@PostMapping
public Result addHealthInfo(@Valid @RequestBody HealthDTO dto) {
// 身份证号格式校验
if (!IdCardValidator.validate(dto.getIdCard())) {
throw new BusinessException("身份证号格式错误");
}
// 体温范围校验
if (dto.getTemperature() != null
&& (dto.getTemperature() < 35 || dto.getTemperature() > 42)) {
throw new BusinessException("体温数据异常");
}
return Result.success(healthService.addHealthInfo(dto));
}
@GetMapping("/stats")
public Result getHealthStats() {
return Result.success(healthService.getHealthStatistics());
}
}
出入记录审批接口实现了工作流引擎:
java复制@PostMapping("/access/approve")
public Result approveAccess(@RequestParam Long recordId,
@RequestParam String approvalResult,
@RequestParam String remark) {
// 1. 校验记录是否存在
AccessRecord record = recordService.getById(recordId);
if (record == null) {
throw new BusinessException("出入记录不存在");
}
// 2. 更新审批状态
record.setApprovalStatus("APPROVED".equals(approvalResult) ?
ApprovalStatus.APPROVED : ApprovalStatus.REJECTED);
record.setApprovalTime(LocalDateTime.now());
record.setApprover(SecurityUtil.getCurrentUserId());
record.setRemark(remark);
// 3. 保存并发送通知
recordService.updateById(record);
notifyService.sendApprovalResult(record.getResidentId(), approvalResult);
return Result.success();
}
居民信息表格组件实现了以下特性:
vue复制<template>
<el-table :data="tableData" v-loading="loading">
<el-table-column prop="name" label="姓名" width="120"></el-table-column>
<el-table-column prop="idCard" label="身份证号" width="180">
<template #default="{row}">
{{ row.idCard | idCardFilter }}
</template>
</el-table-column>
<el-table-column prop="phone" label="手机号" width="150">
<template #default="{row}">
{{ row.phone | phoneFilter }}
</template>
</el-table-column>
<el-table-column prop="healthCode" label="健康码" width="100">
<template #default="{row}">
<el-tag :type="getHealthCodeType(row.healthCode)">
{{ row.healthCode }}
</el-tag>
</template>
</el-table-column>
</el-table>
</template>
<script>
export default {
filters: {
idCardFilter(val) {
return val.replace(/^(.{6}).*(.{4})$/, '$1******$2');
},
phoneFilter(val) {
return val.replace(/^(.{3}).*(.{4})$/, '$1****$2');
}
},
methods: {
getHealthCodeType(code) {
const map = { '绿码': 'success', '黄码': 'warning', '红码': 'danger' };
return map[code] || '';
}
}
}
</script>
疫情数据仪表盘实现了:
javascript复制// 疫苗接种进度环形图
initVaccineChart() {
const chart = echarts.init(this.$refs.vaccineChart);
const option = {
tooltip: { trigger: 'item' },
series: [{
name: '接种进度',
type: 'pie',
radius: ['50%', '70%'],
label: { show: false },
data: [
{ value: 75, name: '已接种' },
{ value: 25, name: '未接种' }
]
}]
};
chart.setOption(option);
// 定时更新数据
this.updateInterval = setInterval(async () => {
const res = await getVaccineStats();
option.series[0].data = [
{ value: res.vaccinated, name: '已接种' },
{ value: res.total - res.vaccinated, name: '未接种' }
];
chart.setOption(option);
}, 5000);
}
建议的服务器配置:
必备软件安装:
bash复制# JDK 8+
sudo yum install java-1.8.0-openjdk-devel
# MySQL 5.7
sudo yum install mysql-community-server
sudo systemctl start mysqld
sudo mysql_secure_installation
# Node.js 14+
curl -sL https://rpm.nodesource.com/setup_14.x | sudo bash -
sudo yum install nodejs
# Nginx
sudo yum install epel-release
sudo yum install nginx
创建数据库和用户:
sql复制CREATE DATABASE community_covid CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'covid_user'@'%' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON community_covid.* TO 'covid_user'@'%';
FLUSH PRIVILEGES;
导入初始数据:
bash复制mysql -u root -p community_covid < init_data.sql
后端部署步骤:
mvn clean packagebash复制#!/bin/bash
nohup java -jar community-covid.jar --spring.profiles.active=prod > app.log 2>&1 &
bash复制sudo cp start.sh /etc/init.d/community-covid
sudo chmod +x /etc/init.d/community-covid
sudo chkconfig --add community-covid
前端部署步骤:
npm installnpm run buildnginx复制server {
listen 80;
server_name covid.yourdomain.com;
location / {
root /path/to/dist;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
}
}
在实际部署中遇到过几个性能瓶颈及解决方案:
default-time-zone='+08:00'spring.jackson.time-zone=GMT+8java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*")
.maxAge(3600);
}
}
yaml复制spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 20MB
nginx复制client_max_body_size 20M;
这套系统在实际部署中已经验证了其稳定性和实用性。我在三个中型社区的落地案例显示,使用该系统后:
特别建议在部署时做好数据迁移规划,可以先在小范围试用,再逐步推广到整个社区。对于技术力量薄弱的社区,可以考虑使用我们提供的云服务版本,免去本地部署的麻烦。