1. 项目概述
这个基于SpringBoot的前后端分离疫情防疫平台,是我在参与某高校信息化建设项目时开发的一套管理系统。平台采用Java技术栈构建后端服务,Vue.js实现前端交互,MySQL作为数据存储,实现了从疫情数据可视化到人员管控的全流程管理。
在实际开发过程中,我发现这类防疫系统有几个典型痛点:权限体系需要灵活适配不同机构的管理需求、疫情数据需要实时可视化展示、人员流动审批流程需要电子化。这个项目正是针对这些痛点设计的解决方案,目前已在多个单位落地应用。
2. 技术架构设计
2.1 整体技术栈选型
后端技术栈:
- 基础框架:Spring Boot 2.5 + Spring MVC
- ORM层:MyBatis-Plus 3.4.3(简化CRUD操作)
- 安全框架:Apache Shiro(轻量级权限控制)
- 日志系统:Log4j2(异步日志记录)
- 接口文档:Swagger UI(API可视化调试)
前端技术栈:
- 核心框架:Vue 2.6 + Vue Router + Vuex
- UI组件:Element UI + Layui(表单/表格组件)
- 可视化:ECharts 5.1(疫情数据图表)
- 构建工具:Webpack 4(模块打包)
数据库:
- MySQL 8.0(主数据库)
- Redis 6.2(缓存会话和热点数据)
选择这套技术栈主要基于以下考虑:
- Spring Boot的自动配置特性大幅减少了XML配置
- MyBatis-Plus的ActiveRecord模式提升开发效率
- Vue+ElementUI的组合能快速构建管理后台界面
- ECharts对疫情地图等可视化需求支持良好
2.2 前后端分离架构
采用经典的前后端分离模式:
code复制浏览器 -> Nginx(静态资源)
-> API网关(Spring Cloud Gateway)
-> 微服务集群
-> MySQL/Redis
前端通过Webpack打包生成静态资源,由Nginx直接托管。后端API采用RESTful风格设计,通过JWT进行身份认证。这种架构的优点是:
- 前后端可以并行开发
- 前端资源CDN加速提升加载速度
- 后端服务可独立扩展
3. 核心功能实现
3.1 权限管理系统
权限控制采用经典的RBAC(基于角色的访问控制)模型:
code复制用户 -> 角色 -> 菜单权限
数据库设计:
sql复制CREATE TABLE `sys_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(100) COMMENT '密码',
`salt` varchar(20) COMMENT '盐',
PRIMARY KEY (`user_id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统用户';
CREATE TABLE `sys_role` (
`role_id` bigint NOT NULL AUTO_INCREMENT,
`role_name` varchar(100) COMMENT '角色名称',
`remark` varchar(100) COMMENT '备注',
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色';
CREATE TABLE `sys_menu` (
`menu_id` bigint NOT NULL AUTO_INCREMENT,
`parent_id` bigint COMMENT '父菜单ID',
`name` varchar(50) COMMENT '菜单名称',
`url` varchar(200) COMMENT '菜单URL',
`perms` varchar(500) COMMENT '授权标识',
`type` int COMMENT '类型 0:目录 1:菜单 2:按钮',
PRIMARY KEY (`menu_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='菜单管理';
权限验证流程:
- 用户登录获取JWT Token
- 前端将Token存入Authorization头
- 后端通过Shiro拦截器校验权限
- 根据@RequiresPermissions注解验证接口权限
3.2 疫情数据可视化
采用ECharts实现的关键疫情看板:
javascript复制// 疫情地图配置
const option = {
tooltip: {
trigger: 'item',
formatter: '{b}: {c}例'
},
visualMap: {
min: 0,
max: 1000,
text: ['高', '低'],
realtime: false,
calculable: true,
inRange: {
color: ['#f5c0c0', '#dc3545']
}
},
series: [{
name: '确诊人数',
type: 'map',
map: 'china',
emphasis: {
label: {
show: true
}
},
data: [
{name: '北京', value: 342},
{name: '上海', value: 215},
// 其他地区数据...
]
}]
};
数据更新策略:
- 后端通过定时任务每小时获取最新疫情数据
- 使用Redis缓存热点数据减少数据库压力
- 前端通过WebSocket接收实时数据更新
3.3 人员流动管理
核心业务流程:
code复制用户提交申请 -> 管理员审核 -> 记录行程轨迹
关键代码实现(Spring Boot控制器):
java复制@RestController
@RequestMapping("/api/movement")
public class MovementController {
@Autowired
private MovementService movementService;
@PostMapping("/apply")
public Result apply(@Valid @RequestBody MovementApplyDTO dto) {
String username = SecurityUtils.getCurrentUsername();
return movementService.applyMovement(username, dto);
}
@GetMapping("/list")
@RequiresPermissions("movement:view")
public PageResult<MovementVO> list(MovementQuery query) {
return movementService.queryPage(query);
}
@PostMapping("/approve")
@RequiresPermissions("movement:approve")
public Result approve(@RequestBody ApproveDTO dto) {
return movementService.approveMovement(dto);
}
}
4. 开发实践与优化
4.1 性能优化方案
-
数据库层面:
- 为高频查询字段添加索引
- 使用EXPLAIN分析慢查询
- 大数据量表采用分库分表策略
-
缓存策略:
java复制@Cacheable(value = "epidemic:stats", key = "#province") public EpidemicStats getStatsByProvince(String province) { // 数据库查询逻辑 } -
前端优化:
- 组件按需加载
- ECharts数据集分片加载
- 启用Gzip压缩静态资源
4.2 安全防护措施
-
XSS防护:
java复制public class XssFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response); } } -
SQL注入防护:
- 全部使用MyBatis预编译语句
- 禁止拼接SQL字符串
- 定期使用SQLMap进行漏洞扫描
-
密码安全:
java复制// 密码加密存储 String salt = RandomStringUtils.randomAlphanumeric(20); String hashedPwd = new Sha256Hash(rawPassword, salt).toHex();
5. 部署与运维
5.1 服务器环境配置
推荐服务器配置:
- CPU: 4核以上
- 内存: 8GB以上
- 系统: CentOS 7.6+
依赖安装:
bash复制# JDK安装
yum install -y java-1.8.0-openjdk-devel
# MySQL安装
wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
rpm -ivh mysql80-community-release-el7-3.noarch.rpm
yum install -y mysql-community-server
# Redis安装
yum install -y redis
5.2 Docker部署方案
后端服务Dockerfile:
dockerfile复制FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD target/epidemic-system.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
使用Docker Compose编排:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 123456
ports:
- "3306:3306"
volumes:
- ./mysql-data:/var/lib/mysql
redis:
image: redis:6.2
ports:
- "6379:6379"
app:
build: .
ports:
- "8080:8080"
depends_on:
- mysql
- redis
6. 常见问题排查
6.1 典型问题解决方案
问题1:菜单权限不生效
- 检查Shiro配置中的过滤规则
- 确认数据库sys_role_menu表有对应记录
- 清除Redis中的权限缓存
问题2:ECharts地图不显示
- 确认已引入china.js地理数据
- 检查DOM容器宽度高度是否有效
- 查看浏览器控制台是否有资源加载错误
问题3:文件上传失败
- 检查Nginx上传大小限制(client_max_body_size)
- 确认服务器存储目录有写入权限
- 验证前端FormData是否正确构造
6.2 性能问题诊断
慢查询分析步骤:
- 开启MySQL慢查询日志
sql复制SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 1; - 使用pt-query-digest分析日志
- 通过EXPLAIN查看执行计划
- 添加适当索引或重构查询
7. 项目扩展方向
-
多租户支持:
- 通过schema分离不同机构数据
- 动态数据源路由实现
-
移动端适配:
- 开发微信小程序版本
- 基于Uniapp跨端方案
-
大数据分析:
- 集成Flink实时计算
- 使用Superset构建分析看板
这个项目在开发过程中遇到的挑战主要来自权限体系的灵活性和疫情数据的实时性要求。通过采用RBAC模型和WebSocket推送机制,最终实现了既满足功能需求又保证系统性能的解决方案。对于需要二次开发的同行,建议重点关注权限模块的设计,这是整个系统的基石。