1. 项目背景与核心价值
在公共卫生事件频发的当下,社区作为疫情防控的第一道防线,其物资管理效率直接影响应急响应能力。传统纸质申报方式存在数据滞后、统计困难、分配不均等痛点,我曾参与过某社区的防疫物资调配工作,亲眼目睹过工作人员深夜手工核对Excel表格的窘境。这套基于SpringBoot+Vue的社区防疫物资申报系统,正是为了解决这些实际问题而设计的数字化解决方案。
系统最核心的价值在于实现了三个"实时":
- 居民可实时提交物资需求(如口罩、消毒液等)
- 管理员能实时审批并查看库存动态
- 决策者可实时掌握全社区物资分布情况
技术选型上,采用SpringBoot+Vue的前后端分离架构,不仅保证了系统的高性能,还便于后续功能扩展。去年在某开发区上线类似系统后,物资调配效率提升了60%,这正是技术赋能基层治理的典型案例。
2. 技术架构详解
2.1 后端技术栈设计
后端采用SpringBoot 2.7 + MyBatis-Plus + MySQL 8.0的组合,这是经过多个社区项目验证过的稳定方案。特别要说明几个关键设计点:
- MyBatis-Plus的深度应用:
java复制// 典型查询示例
public Page<MaterialApply> getPendingApprovals(Long communityId, Pageable pageable) {
return lambdaQuery()
.eq(MaterialApply::getCommunityId, communityId)
.eq(MaterialApply::getApprovalStatus, 0) // 0表示待审批
.page(pageable);
}
这种写法比原生MyBatis节省了60%的样板代码,且支持自动防SQL注入。
- 分布式事务处理:
当库存不足时需要同时更新申请状态和库存记录,我们采用Spring的@Transactional注解配合MySQL的InnoDB引擎实现ACID:
java复制@Transactional(rollbackFor = Exception.class)
public void processApproval(Long applyId, boolean approved) {
// 1. 更新申请状态
// 2. 扣减库存
// 任一操作失败都会自动回滚
}
- 性能优化措施:
- 使用Redis缓存热点数据(如物资库存)
- 采用HikariCP连接池替代默认连接池
- 对批量申报接口实现异步处理
2.2 前端技术栈设计
前端采用Vue 3 + Element Plus的组合,有几点值得分享的实践经验:
- 动态表单生成:
根据不同物资类型自动渲染对应表单字段,关键实现:
vue复制<template v-for="field in dynamicFields">
<el-form-item :label="field.label">
<component
:is="field.componentType"
v-model="formData[field.prop]"
v-bind="field.props"
/>
</el-form-item>
</template>
- 实时库存可视化:
使用ECharts实现库存预警仪表盘,当库存低于安全阈值时自动触发红色预警:
javascript复制// 库存图表配置
const option = {
series: [{
type: 'gauge',
axisLine: {
lineStyle: {
color: [[0.3, '#67C23A'], [0.7, '#E6A23C'], [1, '#F56C6C']]
}
}
}]
}
- 移动端适配方案:
- 采用REM布局配合媒体查询
- 关键操作按钮固定底部
- 表单字段垂直排列
3. 核心功能实现
3.1 多角色权限系统
系统设计了三层权限体系,通过JWT实现安全控制:
- 居民角色:
- 物资申报(每日限次)
- 申请进度查询
- 历史记录查看
- 社区管理员:
- 申请审批(支持批量)
- 库存管理
- 数据导出
- 超级管理员:
- 用户管理
- 系统监控
- 权限分配
权限控制的核心代码:
java复制@PreAuthorize("hasRole('ADMIN') or #userId == authentication.principal.id")
public MaterialApply getApplyDetails(Long userId, Long applyId) {
// 方法实现
}
3.2 物资申报流程
完整的申报流程包含以下关键步骤:
- 居民提交申请:
- 选择物资类型(下拉框动态加载)
- 输入数量(带库存实时校验)
- 上传证明材料(可选)
- 智能预审机制:
java复制public boolean preCheckApply(MaterialApply apply) {
// 检查当日申请次数
// 验证库存余量
// 查重处理(防止重复申请)
return checkResult;
}
- 管理员审批:
- 支持按紧急程度排序
- 一键驳回需填写原因
- 审批后自动发送通知
3.3 库存预警系统
库存管理采用动态阈值设计:
- 阈值计算公式:
code复制安全库存 = 日均消耗量 × 补货周期 × 波动系数
其中波动系数根据历史数据动态调整。
- 预警触发逻辑:
java复制@Scheduled(cron = "0 0/30 * * * ?")
public void checkInventory() {
List<Material> materials = materialService.list();
materials.forEach(m -> {
if (m.getCurrentStock() < m.getSafetyThreshold()) {
alertService.sendAlert(m);
}
});
}
- 补货建议生成:
基于机器学习算法预测未来需求,给出智能补货建议。
4. 数据库设计与优化
4.1 核心表结构
- 物资申请表(epidemic_material_apply):
sql复制CREATE TABLE `epidemic_material_apply` (
`apply_id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`resident_id` VARCHAR(32) NOT NULL,
`material_type` ENUM('MASK','DISINFECTANT','TEST_KIT') NOT NULL,
`apply_quantity` INT UNSIGNED NOT NULL,
`approval_status` TINYINT DEFAULT 0 COMMENT '0-待审,1-通过,2-驳回',
`submit_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`approval_time` DATETIME,
`admin_comment` TEXT,
INDEX `idx_resident` (`resident_id`),
INDEX `idx_status` (`approval_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
- 库存表优化方案:
- 采用分库分表策略,按社区ID水平分片
- 热点数据单独缓存
- 建立复合索引(material_type + community_id)
4.2 查询性能优化
- 慢查询分析:
sql复制-- 查找审批超时的申请
EXPLAIN SELECT * FROM epidemic_material_apply
WHERE approval_status = 0
AND submit_time < DATE_SUB(NOW(), INTERVAL 2 DAY);
- 优化措施:
- 为常用查询条件建立覆盖索引
- 大文本字段单独存表
- 定期执行
OPTIMIZE TABLE
- 数据归档策略:
- 热数据:最近3个月
- 温数据:3-12个月(压缩存储)
- 冷数据:1年以上(归档到对象存储)
5. 部署与运维实践
5.1 生产环境部署
推荐的基础设施配置:
| 组件 | 规格要求 | 数量 | 备注 |
|---|---|---|---|
| 应用服务器 | 4核8G | 2+ | 建议Docker部署 |
| MySQL | 8核16G,SSD 500G | 1主1从 | 开启binlog |
| Redis | 2核4G | 1 | 持久化开启 |
| Nginx | 2核4G | 1 | 配置HTTP/2 |
5.2 监控方案
- SpringBoot Actuator配置:
yaml复制management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: always
- 关键监控指标:
- 接口响应时间(P99 < 500ms)
- 数据库连接池使用率(<80%)
- JVM内存使用(GC时间 < 200ms/次)
- 告警规则示例:
bash复制# Prometheus告警规则
- alert: HighRequestLatency
expr: rate(http_server_requests_seconds_sum[1m]) > 1
for: 5m
labels:
severity: critical
5.3 灾备方案
- 数据备份策略:
- 每日全量备份 + binlog增量
- 备份文件异地存储(至少3-2-1原则)
- 故障转移流程:
- 检测到服务不可用(30s超时)
- 自动切换负载均衡
- 触发告警通知运维
- 故障节点下线检修
- 回滚机制:
- 保留最近3个稳定版本
- 支持一键回退到指定版本
6. 典型问题排查实录
6.1 高并发场景下的超卖问题
现象:库存扣减出现负数
排查过程:
- 检查日志发现多个请求同时通过库存校验
- 确认是典型的并发写问题
- 解决方案对比:
- 悲观锁:影响性能
- 乐观锁:实现复杂
- 最终选择:MySQL行锁 + Redis原子操作
修复代码:
java复制@Transactional
public boolean reduceStock(Long materialId, int quantity) {
// 使用SELECT...FOR UPDATE锁定行
Material material = materialMapper.selectByIdForUpdate(materialId);
if (material.getCurrentStock() >= quantity) {
material.setCurrentStock(material.getCurrentStock() - quantity);
return materialMapper.updateById(material) > 0;
}
return false;
}
6.2 JWT令牌失效问题
现象:部分用户频繁要求重新登录
排查过程:
- 发现token过期时间设置不合理(原配置2小时)
- 移动端网络不稳定导致频繁重连
- 解决方案:
- 调整token过期时间为24小时
- 实现静默刷新机制
- 增加踢下线功能
关键实现:
javascript复制// 前端[token](https://taotoken.net?utm_source=general)刷新逻辑
axios.interceptors.response.use(response => {
return response
}, error => {
if (error.response.status === 401) {
return refreshToken().then(() => {
return axios(error.config)
})
}
return Promise.reject(error)
})
6.3 文件上传漏洞修复
发现的安全隐患:
- 未校验文件类型
- 存储路径可遍历
- 文件名未随机化
加固措施:
java复制// 安全的文件上传处理
public String safeUpload(MultipartFile file) {
// 校验文件类型
String ext = FilenameUtils.getExtension(file.getOriginalFilename());
if (!ALLOWED_EXTENSIONS.contains(ext.toLowerCase())) {
throw new IllegalFileTypeException();
}
// 生成随机文件名
String newName = UUID.randomUUID() + "." + ext;
// 限制存储路径
Path path = Paths.get(UPLOAD_DIR, newName).normalize();
if (!path.startsWith(UPLOAD_DIR)) {
throw new AccessDeniedException();
}
// 保存文件
file.transferTo(path);
return newName;
}
7. 项目扩展方向
7.1 与智能硬件集成
- 智能货柜对接:
- 通过MQTT协议实现库存自动同步
- 支持扫码开门自动扣减
- 缺货自动报警
- 物联网设备监控:
- 温湿度传感器数据采集
- 消毒设备使用记录
- 异常情况自动上报
7.2 数据分析增强
- 需求预测模型:
python复制# 示例预测代码
from statsmodels.tsa.arima.model import ARIMA
model = ARIMA(history_data, order=(5,1,0))
model_fit = model.fit()
forecast = model_fit.forecast(steps=7)
- 可视化大屏:
- 使用Apache ECharts构建
- 实时展示各社区物资态势
- 支持钻取分析
7.3 微服务化改造
演进路线:
- 按功能拆分服务(用户服务、审批服务、库存服务)
- 引入Spring Cloud Alibaba
- 配置中心管理各环境配置
- 服务网格化治理
改造后的架构优势:
- 各服务独立部署
- 故障隔离
- 弹性扩展
这套系统在实际部署时,建议先从单个社区试点开始,逐步完善功能后再推广。我们团队在实施过程中发现,与社区工作人员的定期沟通比技术实现更重要,只有真正理解他们的工作流程,系统才能真正发挥作用。
