gunshi-project-ss/deprecated/详细设计文档.md

2041 lines
64 KiB
Markdown
Raw Normal View History

# 黑石咀水库系统详细设计文档
# 第4章 项目总体设计
## 4.1 总体架构
### 4.1.1 四层分布式体系架构
黑石咀水库系统作为湖北省山洪灾害监测预报预警"四预"系统的重要组成部分,采用面向服务的架构模型,建立了完整的"基础支撑层-数据支撑层-业务支撑层-业务应用层"分布式体系架构。
#### 架构层次设计
**基础支撑层**
- **感知设备体系**:集成雨量站、水位站、图像站、末端预警站等监测设备
- **传输网络架构**:水利专网和互联网双通道数据传输
- **基础资源平台**:基于省政务云水利专区的计算资源、存储资源、安全资源和资源调度服务
- **设备接入管理**:通过`StPptnR`、`StRsvrR`、`StRiverR`等实体模型实现设备数据的标准化接入
**数据支撑层**
- **多源数据整合**:建设汇聚库、主题库、基础库、共享库、专题库五级数据体系
- **数据治理平台**:对各类基础数据、地理空间数据、监测预报数据进行集成、存储、处理、共享
- **数据同步机制**:通过`DataTaskHsz`定时任务实现5分钟间隔的多源数据同步
- **数据质量控制**:实现数据清洗、验证、标准化处理
**业务支撑层**
- **算法模型体系**
- 小流域分布式水文模型集成(`flood_algorithm`库)
- 简化淹没范围与水深分析模型
- GRIB2气象数据处理模型`ForecastService`
- 空间数据分析模型JTS集成
- **应用支撑平台**
- GIS引擎基于JTS的空间数据处理能力
- 微服务管理Spring Boot 3.x原生微服务支持
- 数据支撑平台MyBatis-Plus 3.5.7 ORM框架
- 消息中心:`MessageCenterService`预警消息管理
- 文件管理MinIO/S3兼容对象存储
**业务应用层**
- **预报系统**:气象预报和洪水预测功能
- **预警系统**:多级别、多类型的预警信息管理
- **预演系统**:考核评估和演练管理
- **预案系统**:应急响应和决策支持
### 4.1.2 技术架构实现
#### 微服务架构设计
系统采用Spring Boot 3.x微服务架构实现服务的模块化部署和独立扩展
```java
@GunShiApplication
@MapperScan(basePackages = {"com.gunshi.**.mapper", "com.gunshi.**.model"})
@EnableMPP
@EnableCaching
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
```
#### 分层架构模式
**控制器层**132个REST API控制器提供统一的HTTP接口服务
- 统一异常处理:`MyE500UnknownExceptionResolver`
- 参数验证JSR-303验证注解
- API文档Swagger 3.0自动生成
**服务层**:业务逻辑处理核心
- 事务管理:`@Transactional(rollbackFor = Exception.class)`
- 缓存策略:`@Cacheable`和`@CacheEvict`注解
- 异步处理:`@Async`和`@Scheduled`注解
**数据访问层**基于MyBatis-Plus的数据持久化
- Lambda查询类型安全的查询构建
- 动态SQL灵活的查询条件组合
- 分页插件:高效的数据分页处理
#### 数据流转架构
```
外部数据源 → HTTP API → 数据同步任务 → 数据清洗 → PostgreSQL
实时数据表 → 历史数据表 → 整编数据表(小时/天)
Redis缓存 → 业务服务调用 → 前端展示
```
## 4.2 网络架构
### 4.2.1 多网络区域架构设计
根据云平台整体架构规划,系统网络接入采用多区域隔离设计,包括互联网接入区、政务外网接入区,每个接入区的业务处理网络彼此隔离。
#### 政务外网及专网区实现
**网络分区设计**
- **接入区**:提供专线接入湖北省水利厅专网
- 荆楚水库API`jcskPath: http://64.97.142.113:8002/shareddata/api/v1/monitdata`
- Token认证`jcskToken` API访问令牌管理
- IP白名单`reloadCache`动态缓存清理机制
- **核心交换区**:完成各功能分区之间数据流量的高速交换
- 数据库主从同步PostgreSQL主备架构
- Redis缓存集群多实例缓存服务
- 负载均衡基于docker-compose的服务编排
- **运维区**:提供远程运维接入服务
- SSH远程访问`deploy_rsa`密钥认证
- 日志监控:应用日志和系统日志统一管理
- 性能监控:数据库和应用性能指标监控
- **管理区域**:提供数据中心整体的管理功能
- 用户管理基于RuoYi框架的权限管理
- 配置管理:多环境配置文件管理
- 审计日志:操作日志和安全审计
#### 安全隔离区实现
**容器化安全隔离**
```yaml
services:
hsz:
image: openjdk:21
container_name: hsz
network_mode: host
restart: no
volumes:
- /root/gunshiApp/hsz:/app
environment:
- SPRING_PROFILES_ACTIVE=dev
- TZ=Asia/Shanghai
```
**网络安全配置**
- 网络模式:`network_mode: host`实现负载分担
- 端口管理统一的服务端口管理24205
- 访问控制基于Token的API访问控制
### 4.2.2 外部网络集成
#### 三网接入支持
**多网络接入架构**
- **电信接入**通过外部API配置支持电信网络接入
- **联通接入**:多网络负载均衡和冗余设计
- **移动接入**:移动网络接入支持
**外部API集成体系**
```yaml
# 气象数据API
shqxjsCloudowrCnPath: http://shqxjs.cloudowr.cn/service/
# 水库数据API
owrsvrPath: http://owrsvr.cloudowr.cn/
# IP白名单管理
reloadCache: http://223.75.53.124:8002/shareddata/sys/whitelists/reloadCache
# 数据同步API
apiPath: http://223.75.53.141:8000/shzh/monitdata/datasync/getData
# 预警信息API
shqxjsWarnPath: http://223.75.53.141:8000/shzh/met/zyqxfw/api/warning/getGroupWarning
```
## 4.3 部署架构
### 4.3.1 容器化部署架构
#### 前端服务器配置
**VPC部署设计**
- 独立VPC环境分配弹性IP
- 集群技术实现负载分担和高可用
- 等保三级安全要求WAF、防DDOS、IPS等安全服务
**网络优化配置**
```yaml
server:
port: 24205
servlet:
context-path: /gunshiApp/hsz
compression:
enabled: true
mime-types: application/javascript,text/css,application/json,application/xml,text/html,text/xml
```
#### 后端服务器配置
**独立VPC部署**
- 后端服务器在单独的VPC不分配弹性IP
- 内部IP地址交互提高安全性
- 云防火墙安全隔离
**容器编排配置**
- 基础镜像:`openjdk:21`
- 数据存储:`/root/gunshiApp/hsz:/app`
- 时区配置:`TZ=Asia/Shanghai`
- 环境配置:`SPRING_PROFILES_ACTIVE=dev`
### 4.3.2 数据引擎部署
#### PostgreSQL主备架构
**主数据库配置**
```yaml
spring:
datasource:
dynamic:
datasource:
master:
url: jdbc:postgresql://postgres:5432/hsz?stringtype=unspecified
username: gunshiiot
password: 1234567a
driver-class-name: org.postgresql.Driver
```
**备用数据库配置**
- 主从同步基于PostgreSQL流复制
- 故障转移:自动主备切换机制
- 连接池HikariCP高性能连接管理
#### 缓存系统部署
**Redis集群配置**
```yaml
data:
redis:
host: redis
port: 6379
database: 4
```
**缓存策略**
- 会话管理:用户登录状态缓存
- 查询缓存:热点数据查询优化
- 分布式缓存:多实例数据一致性
## 4.4 数据架构
### 4.4.1 数据源体系
#### 行业外数据源
**气象数据源**
- 数据来源:省气象局气象监测雨量和预报雨量
- 接入方式:`shqxjsCloudowrCnPath` API接口
- 数据类型GRIB2气象文件、实时监测数据
- 处理服务:`ForecastService`气象预报处理
**水文数据源**
- 数据来源:省水文处水文监测雨量
- 接入方式荆楚水库API专线接入
- 数据类型:降雨量、水位、流量
- 同步频率5分钟定时同步
**水库数据源**
- 数据来源:省水库处水库监测数据
- 接入方式:`owrsvrPath` API接口
- 数据类型:水库水位、蓄水量
- 处理机制:实时数据和历史数据分离
#### 行业内数据源
**基础地理数据**
- 数据来源中国水科院提供的107条小流域风险隐患调查数据
- 数据类型:空间地理数据、流域边界、风险隐患要素
- 处理方式GIS空间分析和可视化
**行政区划数据**
- 数据来源:各区县水利局提供的行政区划信息
- 数据类型:行政区划边界、责任人信息
- 管理服务:`StAddvcdDService`行政区划管理
### 4.4.2 数据支撑平台
#### 数据处理能力
**气象文件处理**
- GRIB2文件解析`grb.RainGrib2Layer`网格数据模型
- 雷达数据处理:短临预报数据处理
- 网格计算基于JTS的空间插值算法
**数据计算分析**
- 面雨量计算:泰森多边形权重计算
- 时间序列分析:历史数据趋势分析
- 多维分析基于MyBatis-Plus的数据统计
**算法模型对接**
- 洪水算法库:`flood_algorithm`库集成
- 空间分析JTS几何计算引擎
- 预测模型:气象预报和水文预测模型
#### 数据交换共享平台
**数据同步机制**
```java
@Async
@Scheduled(fixedRate = 5, timeUnit = TimeUnit.MINUTES)
public void getPptnData() // 5分钟雨量数据同步
@Async
@Scheduled(fixedRate = 5, timeUnit = TimeUnit.MINUTES)
public void getRiverData() // 5分钟水情数据同步
```
**数据汇聚中心**
- 25个县区山洪监测数据汇聚
- 一站双发数据采集机制
- 数据质量控制和异常处理
### 4.4.3 数据库体系
#### 基础数据库设计
**实体模型体系**
- 监测数据模型:`StPptnR`、`StRsvrR`、`StRiverR`
- 预警数据模型:`MessageCenter`、`OsmoticWarnR`
- 业务数据模型:`AssessTask`、`PrePlace`、`ByPlan`
**数据关系设计**
- 一对多关系:防治对象与监测设备关系
- 多对多关系:考核任务与考核对象关系
- 层级关系:行政区划层级结构
#### 专题数据库设计
**预报专题库**
- 气象预报数据24小时预报和逐小时预报
- 网格降雨数据基于GIS的空间网格数据
- 历史比对数据:历史同期数据对比分析
**预警专题库**
- 预警规则配置:`OsmoticWarnRule`预警规则管理
- 预警消息记录:分级预警消息存储
- 预警统计分析:预警频次和类型统计
### 4.4.4 数据应用体系
#### 水雨情监测应用
**实时监测功能**
- 实时数据展示:`StPptnRRealService`实时降雨监测
- 历史数据查询:`StPptnRService`历史数据检索
- 数据统计报表:多维度数据统计分析
**监测站点管理**
- 站点信息管理:监测站点基本信息维护
- 站点状态监控:设备运行状态实时监控
- 数据质量评估:监测数据质量评估和报警
#### 预报应用专题
**天气预报功能**
- GRIB2数据处理专业气象文件解析
- 网格降雨量计算:空间插值算法
- 预报结果展示:多时间尺度预报展示
**洪水预报功能**
- 水位预测:基于历史数据的水位预测
- 流量预测:基于水文模型的流量预测
- 风险评估:洪水风险评估和预警
#### 预警应用专题
**多级预警机制**
- 水位预警:超校核水位、超设计水位、超汛限水位
- 渗压预警:渗流压力监测和预警
- 降雨预警:强降雨监测和预警
**预警消息管理**
- 消息推送:基于角色的预警消息推送
- 状态管理:预警消息的确认和处理状态
- 统计分析:预警数据统计和分析
## 4.5 安全架构
### 4.5.1 总体安全策略
#### 数据安全策略
**敏感数据保护**
- 数据库连接加密PostgreSQL SSL连接
- API访问认证基于Token的身份认证
- 密码安全:数据库密码加密存储
**输入数据安全**
- XSS防护自定义Jackson反序列化器
- SQL注入防护MyBatis-Plus参数化查询
- 输入验证JSR-303验证注解
#### 系统安全策略
**访问控制**
- 基于角色的权限控制RuoYi框架集成
- API访问控制Token认证机制
- 数据访问控制:基于用户权限的数据访问
**审计安全**
- 操作日志记录:用户操作行为审计
- 系统日志监控:系统运行状态监控
- 安全事件审计:安全事件记录和分析
### 4.5.2 网络安全等级保护
#### 等保三级要求
**网络安全防护**
- 网络隔离:政务外网和互联网区域隔离
- 访问控制基于IP和端口的访问控制
- 入侵检测:网络入侵检测和防护
**数据安全防护**
- 数据加密:敏感数据传输和存储加密
- 数据备份:定期数据备份和恢复
- 数据完整性:数据完整性校验和验证
**应用安全防护**
- 应用防火墙Web应用防火墙防护
- 漏洞管理:定期漏洞扫描和修复
- 安全编码:安全编码规范和检查
### 4.5.3 安全技术体系
#### 计算环境安全
**容器安全**
- Docker容器隔离进程和网络隔离
- 镜像安全:基础镜像安全扫描
- 运行时安全:容器运行时监控
**应用安全**
- Spring Security安全框架集成
- 会话管理:安全的会话管理机制
- 异常处理:统一的异常处理机制
**数据安全**
- 数据库安全PostgreSQL安全配置
- 文件安全MinIO对象存储安全
- 缓存安全Redis缓存安全配置
#### 安全区域边界
**网络边界安全**
- 防火墙:网络边界防火墙防护
- 负载均衡:安全的负载均衡配置
- DDoS防护分布式拒绝服务攻击防护
**应用边界安全**
- API网关统一的API访问控制
- 请求限流API访问频率限制
- 参数验证:输入参数严格验证
### 4.5.4 安全管理体系
#### 安全策略管理
**安全策略制定**
- 数据安全策略:敏感数据保护策略
- 网络安全策略:网络安全防护策略
- 应用安全策略:应用系统安全策略
**安全管理制度**
- 访问控制制度:基于角色的访问控制
- 数据管理制度:数据分类和管理制度
- 应急响应制度:安全事件应急响应流程
#### 安全运维管理
**安全监控**
- 实时监控:系统安全状态实时监控
- 日志审计:安全日志审计和分析
- 异常检测:安全异常行为检测
**安全维护**
- 漏洞修复:定期漏洞扫描和修复
- 安全更新:系统和应用安全更新
- 备份恢复:数据备份和恢复演练
## 4.6 数据流向
### 4.6.1 数据采集流程
#### 多源数据采集
**山洪5分钟雨量监测数据**
- 数据源全省74个县的山洪5分钟雨量监测数据
- 采集方式:一站双发形式,确保数据可靠性
- 处理机制:`DataTaskHsz.getPptnData()`定时同步
- 数据存储:`StPptnR`实时数据表和`StPptnRH`历史数据表
**气象1小时雨量监测数据**
- 数据源省气象局Oracle数据库
- 采集方式:先上报到省气象局,再通过数据汇集与共享平台同步
- 处理机制GRIB2文件解析和网格化处理
- 数据存储:`ForecastService`处理后的网格数据
**水库1小时雨量监测数据**
- 数据源省水库处SqlServer数据库
- 采集方式:通过数据汇集与共享平台同步
- 处理机制:`DataTaskHsz.getRiverData()`定时同步
- 数据存储:`StRsvrR`水库水位数据表
#### 数据质量控制
**数据验证机制**
- 完整性检查:数据字段完整性验证
- 格式检查:数据格式和类型验证
- 范围检查:数据值范围合理性验证
**数据清洗流程**
- 异常数据处理:识别和处理异常数据
- 重复数据去重基于时间戳和设备ID去重
- 数据标准化:统一数据格式和单位
### 4.6.2 数据处理流程
#### 实时数据处理
**实时数据流入**
```
外部API → HTTP请求 → 数据解析 → 数据验证 → PostgreSQL存储
Redis缓存更新 → 业务服务消费 → 前端实时展示
```
**数据同步机制**
```java
@Async
@Scheduled(fixedRate = 5, timeUnit = TimeUnit.MINUTES)
public void getPptnData() {
// HTTP请求获取数据
// 数据解析和验证
// 批量保存到数据库
// 更新Redis缓存
}
```
#### 历史数据处理
**数据整编处理**
- 小时数据整编基于5分钟数据生成小时统计数据
- 天数据整编:基于小时数据生成天统计数据
- 月数据整编:基于天数据生成月统计数据
**数据归档策略**
- 实时数据保留最近30天实时数据
- 历史数据:长期保存历史整编数据
- 统计数据:保存各类统计数据
### 4.6.3 数据应用流程
#### 业务数据应用
**预报数据应用**
- 气象预报数据GRIB2文件处理和网格化展示
- 洪水预报数据:基于水文模型的洪水预测
- 预警数据应用:基于阈值的预警信息发布
**管理数据应用**
- 考核数据管理:`AssessTaskService`考核任务管理
- 防治对象管理:`PrePlaceService`防治点管理
- 维护管理:`MentencePlanService`维护计划管理
#### 对外数据共享
**数据接口服务**
- REST API标准化的数据访问接口
- 文件导出Excel、PDF等格式数据导出
- 实时推送WebSocket实时数据推送
**数据安全保障**
- 访问控制:基于权限的数据访问
- 数据脱敏:敏感信息脱敏处理
- 审计日志:数据访问日志记录
## 4.7 技术路线
### 4.7.1 微服务架构
#### 服务拆分策略
**业务模块化**
- 按业务领域划分:预报、预警、预演、预案
- 按数据类型划分:监测数据、管理数据、统计数据
- 按用户角色划分:管理员、县级用户、普通用户
**技术组件化**
- 数据同步组件:`DataTaskHsz`定时任务组件
- 预警处理组件:`MessageCenterService`预警消息组件
- 预报计算组件:`ForecastService`气象预报组件
#### 服务治理机制
**服务注册发现**
- Spring Boot原生服务注册
- 配置中心:多环境配置管理
- 健康检查:服务健康状态监控
**服务间通信**
- HTTP REST同步服务调用
- 异步消息:基于消息队列的异步处理
- 事件驱动:基于事件的松耦合架构
### 4.7.2 云计算技术
#### 云平台部署
**政务云集成**
- 省政务云水利专区部署
- 专属云平台和云产品
- 独立物理机房安全保障
**容器化部署**
- Docker容器化部署
- docker-compose服务编排
- 持续集成和持续部署
#### 云原生技术
**微服务支持**
- Spring Boot 3.x微服务框架
- 云原生配置管理
- 弹性伸缩和负载均衡
**DevOps实践**
- 自动化构建Maven构建工具
- 自动化测试JUnit单元测试
- 自动化部署:容器化部署脚本
## 4.8 接口设计
### 4.8.1 用户接口设计
#### REST API接口
**接口标准化**
- RESTful设计符合REST架构风格
- 统一响应格式JSON格式标准化响应
- 错误处理:统一的异常处理机制
**API文档管理**
```java
@OpenAPIDefinition(
servers = {
@Server(url = "http://localhost:24105/gunshiApp/hsz", description = "本地测试环境"),
@Server(url = "http://local.gunshiiot.com:18083/gunshiApp/hsz", description = "线上测试环境")
}
)
```
**接口分组管理**
- 按业务模块分组:预报、预警、管理、系统
- 按用户角色分组:管理员、县级用户、普通用户
- 按功能类型分组:查询接口、管理接口、统计接口
#### 前端集成接口
**数据查询接口**
- 实时数据查询:`/api/realtime/data`
- 历史数据查询:`/api/history/data`
- 统计数据查询:`/api/statistics/data`
**业务操作接口**
- 预警发布接口:`/api/warning/publish`
- 考核管理接口:`api/assessment/manage`
- 系统管理接口:`/api/system/manage`
### 4.8.2 外部接口设计
#### 气象数据接口
**GRIB2数据获取**
```java
@Value("${shqxjsCloudowrCnPath}")
private String shqxjsCloudowrCnPath;
```
**数据处理流程**
- 文件获取从气象服务器获取GRIB2文件
- 数据解析:解析气象网格数据
- 结果计算:计算面雨量和预报结果
#### 水文数据接口
**荆楚水库API**
```java
@Value("${jcskPath}")
private String jcskPath; // 荆楚水库API路径
@Value("${jcskToken}")
private String jcskToken; // API访问令牌
```
**数据同步机制**
- Token认证API访问安全认证
- IP白名单访问IP地址控制
- 重试机制:网络异常重试处理
### 4.8.3 内部接口设计
#### 服务层接口
**业务服务接口**
- 预报服务:`ForecastService`气象预报服务
- 预警服务:`MessageCenterService`预警消息服务
- 考核服务:`AssessTaskService`考核任务服务
**数据服务接口**
- 实时数据服务:`StPptnRRealService`实时数据服务
- 历史数据服务:`StPptnRService`历史数据服务
- 统计数据服务:各种统计数据服务
#### 数据访问接口
**Mapper接口设计**
- 基础CRUD继承`BaseMapper`基础操作
- 自定义查询:复杂业务查询方法
- 动态SQL基于条件的动态查询构建
**缓存接口设计**
- 查询缓存:`@Cacheable`查询结果缓存
- 更新缓存:`@CacheEvict`缓存更新和清除
- 分布式缓存Redis分布式缓存支持
# 第5章 功能设计
## 5.1 梳理集成基础数据
### 5.1.1 设计思路
为梳理集成完整的、准确的、权威的湖北山洪灾害基础数据,需对基础数据进行全量调研和评估,分析其质量、完整性、准确性,识别可能存在的数据缺失、错误或不一致等问题。
#### 数据质量评估体系
**数据完整性评估**
- 必填字段检查:确保关键字段不为空
- 数据范围验证:验证数据在合理范围内
- 时间连续性检查:确保时间序列数据的连续性
**数据准确性评估**
- 数据一致性检查:跨表数据一致性验证
- 业务逻辑验证:基于业务规则的逻辑验证
- 异常值检测:识别和处理异常数据
**数据权威性评估**
- 数据来源确认:确认数据来源的权威性
- 数据更新机制:确保数据的及时更新
- 数据版本管理:维护数据的历史版本
### 5.1.2 防治对象调查评价成果集成
#### 调查评价成果数据管理
**防治对象数据模型**
```java
// 防治点实体模型
public class PrePlace {
private Long id;
private String placeName; // 防治点名称
private String placeCode; // 防治点编码
private String placeType; // 防治点类型
private String location; // 地理位置
private String riskLevel; // 风险等级
// ... 其他字段
}
```
**防治部位详细管理**
```java
// 防治部位实体模型
public class PrePlaceDetail {
private Long id;
private Long placeId; // 关联防治点ID
private String detailName; // 部位名称
private String detailType; // 部位类型
private String status; // 状态
// ... 其他字段
}
```
#### 成果数据集成实现
**调查评价成果报告管理**
- 文档存储基于MinIO的对象存储
- 元数据管理:文档的基本信息和分类
- 版本控制:文档版本管理和历史追踪
**图集管理系统**
- 图像存储:防治对象相关图像存储
- 空间关联:图像与防治对象的空间关联
- 展示管理:图集的在线展示和查询
**成果数据管理**
- 电子数据:结构化数据存储和管理
- 纸质数据:纸质文档的数字化管理
- 照片数据:相关照片的存储和管理
### 5.1.3 风险隐患调查与影响分析成果集成
#### 风险隐患数据模型设计
**风险隐患要素数据**
```java
// 风险隐患要素实体
public class RiskHazard {
private Long id;
private String hazardCode; // 隐患编码
private String hazardType; // 隐患类型
private String hazardName; // 隐患名称
private String location; // 位置信息
private String riskLevel; // 风险等级
private Geometry geometry; // 空间几何信息
// ... 其他字段
}
```
**断面数据管理**
```java
// 断面数据实体
public class SectionData {
private Long id;
private String sectionCode; // 断面编码
private String sectionName; // 断面名称
private String riverCode; // 河流编码
private BigDecimal elevation; // 高程
private Geometry sectionLine; // 断面线几何
// ... 其他字段
}
```
#### 成果报表管理实现
**重点关注对象详查名录表**
- 对象管理:重点防治对象的详细信息管理
- 风险评估:对象风险评估和等级划分
- 监测关联:与监测设备的关联管理
**防治对象-监测设备关系表**
- 关系映射:防治对象与监测设备的对应关系
- 设备信息:监测设备的基本信息和状态
- 数据关联:监测数据与防治对象的关联
**山洪灾害防治对象名录**
- 名录管理:防治对象的统一名录管理
- 分类管理:按类型、区域等分类管理
- 状态管理:防治对象的状态跟踪
**跨沟道路、桥涵、塘(堰)坝调查成果表**
- 设施管理:跨沟设施的管理和维护
- 安全评估:设施安全状况评估
- 风险分析:设施对山洪的影响分析
### 5.1.4 数据治理入库和应用集成
#### 数据治理流程设计
**数据提取阶段**
- 多源数据采集:从不同数据源提取原始数据
- 数据格式转换:统一数据格式和编码
- 数据质量检查:初步的数据质量评估
**数据清洗阶段**
- 异常数据处理:识别和处理异常数据
- 重复数据去重:基于业务规则的去重处理
- 数据标准化:统一数据标准和规范
**数据整合阶段**
- 数据关联:建立数据间的关联关系
- 数据融合:多源数据的融合处理
- 数据验证:业务逻辑验证和一致性检查
**数据转换阶段**
- 数据映射:源数据到目标数据的映射
- 数据计算:派生数据的计算和生成
- 数据聚合:数据的汇总和聚合处理
**数据解耦和重组阶段**
- 数据分层:按业务需求进行数据分层
- 数据分区:按时间和区域进行数据分区
- 数据索引:建立高效的数据索引
**数据入库阶段**
- 批量导入:高效的数据批量导入
- 事务管理:确保数据导入的事务一致性
- 完整性检查:数据完整性和一致性验证
#### 数据治理服务实现
**数据质量监控服务**
```java
@Service
public class DataQualityService {
public DataQualityReport checkDataQuality(String dataType) {
// 数据质量检查逻辑
return qualityReport;
}
public List<DataAnomaly> detectAnomalies(String dataset) {
// 异常数据检测逻辑
return anomalyList;
}
}
```
**数据标准化服务**
```java
@Service
public class DataStandardizationService {
public StandardizedData standardizeData(RawData rawData) {
// 数据标准化处理逻辑
return standardizedData;
}
public ValidationResult validateStandards(StandardizedData data) {
// 标准验证逻辑
return validationResult;
}
}
```
### 5.1.5 小流域治理单元建档立卡
#### 小流域基础信息管理
**小流域治理单元数据模型**
```java
// 小流域治理单元实体
public class WatershedUnit {
private Long id;
private String unitCode; // 单元编码
private String unitName; // 单元名称
private String area; // 流域面积
private String riverLength; // 河流长度
private String avgElevation; // 平均高程
private Geometry boundary; // 流域边界
// ... 其他字段
}
```
**基础信息梳理功能**
- 全省1309个小流域治理单元基础信息管理
- 流域特征参数计算和管理
- 空间拓扑关系建立和维护
#### 监测站点信息集成
**雨量(水位)站点信息管理**
```java
// 监测站点实体
public class MonitoringStation {
private Long id;
private String stationCode; // 站点编码
private String stationName; // 站点名称
private String stationType; // 站点类型
private BigDecimal longitude; // 经度
private BigDecimal latitude; // 纬度
private Geometry location; // 空间位置
// ... 其他字段
}
```
**站点关联管理**
- 空间关联:监测站点与小流域的空间关联
- 数据关联:监测数据与小流域的数据关联
- 状态监控:监测站点运行状态监控
#### 降雨预报成果数据集成
**网格化降雨预报数据**
```java
// 降雨预报网格数据实体
public class RainfallGrid {
private Long id;
private String gridCode; // 网格编码
private BigDecimal rainfall; // 降雨量
private String forecastTime; // 预报时间
private Integer forecastHour; // 预报小时数
private Geometry gridGeometry; // 网格几何
// ... 其他字段
}
```
**预报成果管理功能**
- 网格数据存储和管理
- 时间序列预报数据管理
- 空间插值和计算功能
#### 流域关系管理
**流域拓扑关系建立**
```java
@Service
public class WatershedRelationService {
public WatershedTopology buildTopology(List<WatershedUnit> units) {
// 构建流域拓扑关系
return topology;
}
public List<WatershedUnit> getUpstreamUnits(Long unitId) {
// 获取上游流域单元
return upstreamUnits;
}
public List<WatershedUnit> getDownstreamUnits(Long unitId) {
// 获取下游流域单元
return downstreamUnits;
}
}
```
**空间分析算法**
- 河流网络提取基于DEM数据的河流网络提取
- 流域边界识别:小流域边界的自动识别
- 拓扑关系生成:上下游关系的自动生成
## 5.2 算法模型建设方案
### 5.2.1 模型建模范围确定
#### 小流域设计暴雨计算
**暴雨参数计算模型**
```java
@Service
public class DesignStormService {
public DesignStormResult calculateDesignStorm(String watershedCode,
int returnPeriod) {
// 基于《湖北省暴雨统计参数等值线图集》计算设计暴雨
DesignStormResult result = new DesignStormResult();
// 计算标准历时点雨量均值
BigDecimal tenMinMean = calculate10MinMean(watershedCode);
BigDecimal oneHourMean = calculate1HourMean(watershedCode);
BigDecimal sixHourMean = calculate6HourMean(watershedCode);
BigDecimal twentyFourHourMean = calculate24HourMean(watershedCode);
// 计算设计暴雨
result.setTenMinDesign(calculateDesignRainfall(tenMinMean, returnPeriod));
result.setOneHourDesign(calculateDesignRainfall(oneHourMean, returnPeriod));
result.setSixHourDesign(calculateDesignRainfall(sixHourMean, returnPeriod));
result.setTwentyFourHourDesign(calculateDesignRainfall(twentyFourHourMean, returnPeriod));
return result;
}
private BigDecimal calculateDesignRainfall(BigDecimal mean, int returnPeriod) {
// 设计暴雨计算逻辑
return mean.multiply(getFrequencyFactor(returnPeriod));
}
}
```
**暴雨时程分配模型**
- 时程分配模式:基于典型暴雨过程的时程分配
- 时间步长处理:按小时或更小时间步长分配
- 空间分布:考虑暴雨空间分布的不均匀性
#### 小流域设计洪水计算
**净雨计算模型**
```java
@Service
public class NetRainfallService {
public List<NetRainfall> calculateNetRainfall(DesignStormResult designStorm,
WatershedUnit watershed) {
// 净雨计算逻辑
List<NetRainfall> netRainfallList = new ArrayList<>();
// 初损计算
BigDecimal initialLoss = calculateInitialLoss(watershed);
// 下渗计算
BigDecimal infiltrationRate = calculateInfiltrationRate(watershed);
// 净雨过程计算
for (StormData stormData : designStorm.getStormData()) {
NetRainfall netRainfall = new NetRainfall();
netRainfall.setTime(stormData.getTime());
netRainfall.setGrossRainfall(stormData.getRainfall());
netRainfall.setNetRainfall(calculateNetAmount(
stormData.getRainfall(), initialLoss, infiltrationRate));
netRainfallList.add(netRainfall);
}
return netRainfallList;
}
}
```
**单位线法洪水计算**
```java
@Service
public class UnitHydrographService {
public FloodHydrograph calculateFloodHydrograph(List<NetRainfall> netRainfall,
WatershedUnit watershed) {
// 单位线法洪水计算
FloodHydrograph hydrograph = new FloodHydrograph();
// 获取单位线
UnitHydrograph unitHydrograph = getUnitHydrograph(watershed.getUnitCode());
// 卷积计算
List<BigDecimal> discharge = new ArrayList<>();
for (int i = 0; i < netRainfall.size(); i++) {
BigDecimal q = BigDecimal.ZERO;
for (int j = 0; j <= i; j++) {
q = q.add(netRainfall.get(j).getNetRainfall()
.multiply(unitHydrograph.getOrdinate(i - j)));
}
discharge.add(q);
}
hydrograph.setDischarge(discharge);
return hydrograph;
}
}
```
**经验公式法洪水计算**
```java
@Service
public class EmpiricalFormulaService {
public BigDecimal calculatePeakDischarge(WatershedUnit watershed,
int returnPeriod) {
// 经验公式法计算洪峰流量
BigDecimal area = new BigDecimal(watershed.getArea());
BigDecimal coefficient = getCoefficient(watershed, returnPeriod);
BigDecimal exponent = getExponent(watershed);
// Q = C * A^n
return coefficient.multiply(area.pow(exponent));
}
private BigDecimal getCoefficient(WatershedUnit watershed, int returnPeriod) {
// 根据水文分区和重现期获取系数
return coefficientRepository.findByWatershedAndReturnPeriod(
watershed.getHydrologicalZone(), returnPeriod);
}
}
```
#### HEC-RAS二维水动力学模型
**淹没范围分析模型**
```java
@Service
public class InundationAnalysisService {
public InundationResult analyzeInundation(WatershedUnit watershed,
FloodHydrograph hydrograph, int returnPeriod) {
// HEC-RAS二维水动力学模型调用
InundationResult result = new InundationResult();
// 模型输入准备
ModelInput input = prepareModelInput(watershed, hydrograph);
// 调用HEC-RAS模型
ModelOutput output = callHECRASModel(input);
// 结果处理
result.setInundationArea(output.getInundationArea());
result.setMaxDepth(output.getMaxDepth());
result.setInundationMap(output.getInundationMap());
result.setVelocityMap(output.getVelocityMap());
return result;
}
private ModelOutput callHECRASModel(ModelInput input) {
// 调用HEC-RAS模型的实现
// 这里可以集成外部HEC-RAS计算引擎
return hcrasEngine.run(input);
}
}
```
**不同重现期洪水分析**
- 50年一遇洪水中等风险洪水淹没分析
- 100年一遇洪水高风险洪水淹没分析
- 300年一遇洪水极高风险洪水淹没分析
### 5.2.2 小流域分布式水文模型精细建模
#### 小流域计算单元划分
**计算单元属性提取**
```java
@Service
public class CalculationUnitService {
public List<CalculationUnit> divideCalculationUnits(WatershedUnit watershed) {
// 小流域计算单元划分
List<CalculationUnit> units = new ArrayList<>();
// 基于DEM数据进行单元划分
List<Subcatchment> subcatchments = extractSubcatchments(watershed);
for (Subcatchment subcatchment : subcatchments) {
CalculationUnit unit = new CalculationUnit();
unit.setUnitCode(generateUnitCode(subcatchment));
unit.setArea(subcatchment.getArea());
unit.setAvgSlope(calculateAvgSlope(subcatchment));
unit.setFlowLength(calculateFlowLength(subcatchment));
unit.setCentroid(subcatchment.getCentroid());
unit.setBoundary(subcatchment.getBoundary());
// 提取其他属性
unit.setLandUseType(extractLandUseType(subcatchment));
unit.setSoilType(extractSoilType(subcatchment));
unit.setVegetationCover(extractVegetationCover(subcatchment));
units.add(unit);
}
return units;
}
private BigDecimal calculateAvgSlope(Subcatchment subcatchment) {
// 基于DEM计算平均坡度
return demAnalyzer.calculateAvgSlope(subcatchment);
}
private BigDecimal calculateFlowLength(Subcatchment subcatchment) {
// 计算流径长度
return flowAnalyzer.calculateFlowLength(subcatchment);
}
}
```
**小流域统一编码**
```java
@Service
public class WatershedCodingService {
public String generateWatershedCode(WatershedUnit watershed) {
// 小流域统一编码生成
StringBuilder code = new StringBuilder();
// 省级编码
code.append("42"); // 湖北省编码
// 市级编码
code.append(String.format("%02d", watershed.getCityCode()));
// 县级编码
code.append(String.format("%02d", watershed.getCountyCode()));
// 流域编码
code.append(String.format("%03d", watershed.getRiverBasinCode()));
// 小流域编码
code.append(String.format("%04d", watershed.getUnitNumber()));
return code.toString();
}
}
```
#### 面雨量权重值计算
**泰森多边形权重计算**
```java
@Service
public class ThiessenPolygonService {
public Map<String, BigDecimal> calculateThiessenWeights(
List<MonitoringStation> stations, WatershedUnit watershed) {
// 泰森多边形权重计算
Map<String, BigDecimal> weights = new HashMap<>();
// 创建泰森多边形
List<Polygon> thiessenPolygons = createThiessenPolygons(stations);
// 计算每个站点在流域内的权重
Geometry watershedBoundary = watershed.getBoundary();
for (int i = 0; i < stations.size(); i++) {
Polygon stationPolygon = thiessenPolygons.get(i);
// 计算站点多边形与流域的交集
Geometry intersection = stationPolygon.intersection(watershedBoundary);
// 计算权重
BigDecimal stationArea = new BigDecimal(intersection.getArea());
BigDecimal watershedArea = new BigDecimal(watershedBoundary.getArea());
BigDecimal weight = stationArea.divide(watershedArea, 8, RoundingMode.HALF_UP);
weights.put(stations.get(i).getStationCode(), weight);
}
return weights;
}
private List<Polygon> createThiessenPolygons(List<MonitoringStation> stations) {
// 创建泰森多边形
// 使用JTS的Voronoi图算法
GeometryFactory geometryFactory = new GeometryFactory();
// 创建站点点集
Coordinate[] coordinates = stations.stream()
.map(station -> station.getLocation().getCoordinate())
.toArray(Coordinate[]::new);
// 生成Voronoi图
VoronoiDiagramBuilder voronoiBuilder = new VoronoiDiagramBuilder();
voronoiBuilder.setSites(coordinates);
Geometry voronoiDiagram = voronoiBuilder.getDiagram(geometryFactory);
// 提取多边形
return extractPolygons(voronoiDiagram);
}
}
```
**反距离权重插值**
```java
@Service
public class IDWInterpolationService {
public Map<String, BigDecimal> calculateIDWWeights(
List<MonitoringStation> stations, WatershedUnit watershed) {
// 反距离权重插值
Map<String, BigDecimal> weights = new HashMap<>();
// 生成流域内网格点
List<Coordinate> gridPoints = generateGridPoints(watershed);
for (Coordinate gridPoint : gridPoints) {
BigDecimal totalWeight = BigDecimal.ZERO;
BigDecimal weightedRainfall = BigDecimal.ZERO;
// 计算每个站点对网格点的权重
for (MonitoringStation station : stations) {
BigDecimal distance = calculateDistance(gridPoint,
station.getLocation().getCoordinate());
// 避免除零错误
if (distance.compareTo(BigDecimal.ZERO) == 0) {
distance = new BigDecimal("0.0001");
}
// 权重 = 1 / distance^2
BigDecimal weight = BigDecimal.ONE.divide(
distance.pow(2), 8, RoundingMode.HALF_UP);
totalWeight = totalWeight.add(weight);
weightedRainfall = weightedRainfall.add(
weight.multiply(station.getCurrentRainfall()));
}
// 计算网格点降雨量
BigDecimal gridRainfall = weightedRainfall.divide(totalWeight,
2, RoundingMode.HALF_UP);
weights.put(getGridPointCode(gridPoint), gridRainfall);
}
return weights;
}
}
```
#### 蒸散发量计算
**潜在蒸散发计算**
```java
@Service
public class EvapotranspirationService {
public BigDecimal calculatePET(EtData data) {
// 潜在蒸散发计算Penman-Monteith方程
BigDecimal delta = calculateSlopeVaporPressure(data.getTemperature());
BigDecimal gamma = calculatePsychrometricConstant(data.getPressure());
BigDecimal u2 = data.getWindSpeed();
BigDecimal es = calculateSaturationVaporPressure(data.getTemperature());
BigDecimal ea = calculateActualVaporPressure(data.getTemperature(),
data.getRelativeHumidity());
BigDecimal rn = data.getNetRadiation();
BigDecimal g = data.getSoilHeatFlux();
// Penman-Monteith方程
BigDecimal numerator = delta.multiply(rn.subtract(g))
.add(K_CONSTANT.multiply(rho_AIR.multiply(CP_AIR).multiply(u2)
.multiply(es.subtract(ea))));
BigDecimal denominator = delta.add(gamma.multiply(
BigDecimal.ONE.add(C_D_CONSTANT.multiply(u2))));
return numerator.divide(denominator, 2, RoundingMode.HALF_UP);
}
private BigDecimal calculateSlopeVaporPressure(BigDecimal temperature) {
// 饱和水汽压斜率计算
BigDecimal temp = temperature.add(BigDecimal.valueOf(237.3));
BigDecimal numerator = BigDecimal.valueOf(4098).multiply(
BigDecimal.valueOf(0.6108).multiply(
BigDecimal.valueOf(17.27).multiply(temperature).divide(temp,
8, RoundingMode.HALF_UP).exp()));
BigDecimal denominator = temp.pow(2);
return numerator.divide(denominator, 8, RoundingMode.HALF_UP);
}
}
```
**实际蒸散发计算**
```java
public BigDecimal calculateAET(BigDecimal pet, BigDecimal soilMoisture,
BigDecimal fieldCapacity) {
// 实际蒸散发计算
BigDecimal moistureRatio = soilMoisture.divide(fieldCapacity,
8, RoundingMode.HALF_UP);
if (moistureRatio.compareTo(BigDecimal.ONE) >= 0) {
return pet; // 土壤水分充足,实际蒸散发等于潜在蒸散发
} else {
// 土壤水分不足,按比例减少
return pet.multiply(moistureRatio);
}
}
```
#### 产流模型参数确定
**SCS-CN产流模型**
```java
@Service
public class SCSModelService {
public BigDecimal calculateSCSRunoff(BigDecimal rainfall,
BigDecimal cn, BigDecimal initialAbstraction) {
// SCS-CN产流模型
BigDecimal s = BigDecimal.valueOf(25400).divide(cn,
8, RoundingMode.HALF_UP).subtract(BigDecimal.valueOf(254));
BigDecimal ia = initialAbstraction.multiply(s);
if (rainfall.compareTo(ia) <= 0) {
return BigDecimal.ZERO; // 降雨小于初损,无产流
}
BigDecimal numerator = rainfall.subtract(ia).pow(2);
BigDecimal denominator = rainfall.subtract(ia).add(s);
return numerator.divide(denominator, 2, RoundingMode.HALF_UP);
}
public BigDecimal calculateCNValue(LandUseType landUse, SoilType soil,
BigDecimal antecedentMoisture) {
// CN值计算
// 基于土地利用类型、土壤类型和前期湿度条件
return cnTableRepository.findByLandUseAndSoil(landUse, soil, antecedentMoisture);
}
}
```
**Green-Ampt渗透模型**
```java
@Service
public class GreenAmptService {
public BigDecimal calculateInfiltration(BigDecimal time, BigDecimal initialMoisture,
BigDecimal saturatedMoisture, BigDecimal hydraulicConductivity,
BigDecimal suctionHead, BigDecimal cumulativeInfiltration) {
// Green-Ampt渗透模型
BigDecimal thetaS = saturatedMoisture;
BigDecimal thetaI = initialMoisture;
BigDecimal deltaTheta = thetaS.subtract(thetaI);
BigDecimal Ks = hydraulicConductivity;
BigDecimal psi = suctionHead;
BigDecimal F = cumulativeInfiltration;
// Green-Ampt方程
BigDecimal numerator = Ks.multiply(time).multiply(deltaTheta).multiply(psi).add(F);
BigDecimal denominator = F.add(Ks.multiply(time).multiply(deltaTheta));
BigDecimal newF = numerator.divide(denominator, 8, RoundingMode.HALF_UP);
return newF.subtract(F); // 当前时段渗透量
}
}
```
#### 单位线提取
**瞬时单位线计算**
```java
@Service
public class InstantaneousUnitHydrographService {
public List<BigDecimal> calculateIUH(WatershedUnit watershed,
List<CalculationUnit> units) {
// 瞬时单位线计算
List<BigDecimal> iuh = new ArrayList<>();
// 计算流域特征参数
BigDecimal avgSlope = calculateAvgSlope(units);
BigDecimal avgFlowLength = calculateAvgFlowLength(units);
BigDecimal avgVelocity = calculateAvgVelocity(avgSlope);
// 计算汇流时间
BigDecimal tc = avgFlowLength.divide(avgVelocity,
8, RoundingMode.HALF_UP);
// Nash瞬时单位线模型
int n = 2; // 线性水库数
BigDecimal k = tc.divide(BigDecimal.valueOf(n),
8, RoundingMode.HALF_UP); // 水库蓄量常数
// 生成单位线纵坐标
for (int t = 0; t < 100; t++) {
BigDecimal ordinate = calculateNashIUHOrdinate(t, n, k);
iuh.add(ordinate);
}
return iuh;
}
private BigDecimal calculateNashIUHOrdinate(int t, int n, BigDecimal k) {
// Nash瞬时单位线纵坐标计算
if (t == 0) return BigDecimal.ZERO;
BigDecimal numerator = BigDecimal.ONE.pow(n - 1);
BigDecimal denominator = BigDecimal.valueOf(factorial(n - 1))
.multiply(k.pow(n));
BigDecimal timeTerm = BigDecimal.valueOf(t).pow(n - 1);
BigDecimal expTerm = BigDecimal.valueOf(-t).divide(k,
8, RoundingMode.HALF_UP).exp();
return numerator.multiply(timeTerm).multiply(expTerm).divide(denominator,
8, RoundingMode.HALF_UP);
}
}
```
#### 河道演进模型参数确定
**马斯京根法河道演进**
```java
@Service
public class MuskingumRoutingService {
public List<BigDecimal> routeFloodWave(List<BigDecimal> inflow,
BigDecimal k, BigDecimal x, BigDecimal dt) {
// 马斯京根法河道演进
List<BigDecimal> outflow = new ArrayList<>();
// 计算演进系数
BigDecimal c0 = calculateC0(k, x, dt);
BigDecimal c1 = calculateC1(k, x, dt);
BigDecimal c2 = calculateC2(k, x, dt);
// 初始条件
outflow.add(inflow.get(0)); // 假设初始出流等于入流
// 演进计算
for (int i = 1; i < inflow.size(); i++) {
BigDecimal qOut = c0.multiply(inflow.get(i))
.add(c1.multiply(inflow.get(i - 1)))
.add(c2.multiply(outflow.get(i - 1)));
outflow.add(qOut);
}
return outflow;
}
private BigDecimal calculateC0(BigDecimal k, BigDecimal x, BigDecimal dt) {
BigDecimal denominator = k.multiply(BigDecimal.valueOf(2).multiply(x).subtract(BigDecimal.ONE))
.add(dt);
return dt.subtract(k.multiply(x)).divide(denominator,
8, RoundingMode.HALF_UP);
}
private BigDecimal calculateC1(BigDecimal k, BigDecimal x, BigDecimal dt) {
BigDecimal denominator = k.multiply(BigDecimal.valueOf(2).multiply(x).subtract(BigDecimal.ONE))
.add(dt);
return dt.add(k.multiply(x)).divide(denominator,
8, RoundingMode.HALF_UP);
}
private BigDecimal calculateC2(BigDecimal k, BigDecimal x, BigDecimal dt) {
BigDecimal denominator = k.multiply(BigDecimal.valueOf(2).multiply(x).subtract(BigDecimal.ONE))
.add(dt);
return BigDecimal.ONE.subtract(denominator).divide(denominator,
8, RoundingMode.HALF_UP);
}
}
```
### 5.3 预警功能设计
### 5.3.1 动态预警指标设计
**预警规则配置模型**
```java
// 预警规则实体
public class OsmoticWarnRule {
private Long id;
private String ruleName; // 规则名称
private String ruleType; // 规则类型1-渗压2-渗流3-位移
private String deviceCode; // 设备编码
private BigDecimal threshold1; // 一级阈值
private BigDecimal threshold2; // 二级阈值
private BigDecimal threshold3; // 三级阈值
private String logicRelation; // 逻辑关系AND/OR
private Integer status; // 状态0-禁用1-启用
// ... 其他字段
}
```
**预警条件判断算法**
```java
@Service
public class WarningRuleService {
public WarningResult evaluateWarningRules(List<OsmoticWarnRule> rules,
Map<String, BigDecimal> sensorData) {
WarningResult result = new WarningResult();
List<WarningEvent> events = new ArrayList<>();
for (OsmoticWarnRule rule : rules) {
if (rule.getStatus() == 0) continue; // 跳过禁用规则
BigDecimal currentValue = sensorData.get(rule.getDeviceCode());
if (currentValue == null) continue;
// 评估预警级别
int level = evaluateWarningLevel(rule, currentValue);
if (level > 0) {
WarningEvent event = new WarningEvent();
event.setRuleId(rule.getId());
event.setRuleName(rule.getRuleName());
event.setLevel(level);
event.setCurrentValue(currentValue);
event.setThreshold(getThresholdForLevel(rule, level));
event.setTimestamp(LocalDateTime.now());
events.add(event);
}
}
result.setEvents(events);
result.setHasWarning(!events.isEmpty());
return result;
}
private int evaluateWarningLevel(OsmoticWarnRule rule, BigDecimal value) {
if (rule.getThreshold3() != null && value.compareTo(rule.getThreshold3()) > 0) {
return 3; // 三级预警
} else if (rule.getThreshold2() != null && value.compareTo(rule.getThreshold2()) > 0) {
return 2; // 二级预警
} else if (rule.getThreshold1() != null && value.compareTo(rule.getThreshold1()) > 0) {
return 1; // 一级预警
}
return 0; // 无预警
}
}
```
### 5.3.2 预警发布系统设计
**预警消息管理**
```java
@Service
public class MessageCenterService {
public void publishWaterLevelWarning(List<StRsvrR> waterLevelData) {
// 水位预警发布
for (StRsvrR data : waterLevelData) {
// 检查水位预警条件
if (checkWaterLevelWarning(data)) {
MessageCenter message = new MessageCenter();
message.setTitle("水位预警");
message.setContent(String.format("%s水库水位预警当前水位%.2fm,超过警戒水位",
data.getStnm(), data.getRz()));
message.setWarningLevel(calculateWarningLevel(data));
message.setStationCode(data.getStcd());
message.setCreateTime(LocalDateTime.now());
message.setStatus(0); // 未读状态
// 保存预警消息
save(message);
// 推送给相关用户
pushToUsers(message);
}
}
}
public void publishOsmoticWarning(OsmoticWarnR warnData, String description) {
// 渗压预警发布
MessageCenter message = new MessageCenter();
message.setTitle("渗压预警");
message.setContent(String.format("%s渗压预警%s",
warnData.getDeviceName(), description));
message.setWarningLevel(warnData.getWarningLevel());
message.setDeviceCode(warnData.getDeviceCode());
message.setCreateTime(LocalDateTime.now());
message.setStatus(0);
save(message);
pushToUsers(message);
}
}
```
**用户推送机制**
```java
@Service
public class UserPushService {
public void pushToUsers(MessageCenter message) {
// 根据预警级别和用户角色推送消息
List<User> targetUsers = getTargetUsers(message);
for (User user : targetUsers) {
// 创建用户消息记录
UserMessage userMessage = new UserMessage();
userMessage.setUserId(user.getId());
userMessage.setMessageId(message.getId());
userMessage.setReadStatus(0); // 未读状态
userMessage.setPushTime(LocalDateTime.now());
userMessageRepository.save(userMessage);
// 实时推送WebSocket或其他推送机制
if (user.isOnline()) {
pushRealTimeNotification(user, message);
}
}
}
private List<User> getTargetUsers(MessageCenter message) {
// 根据预警级别确定目标用户
switch (message.getWarningLevel()) {
case 3: // 三级预警(最高级别)
return userRepository.findByRoleIn(Arrays.asList("ADMIN", "COUNTY_MANAGER"));
case 2: // 二级预警
return userRepository.findByRole("COUNTY_MANAGER");
case 1: // 一级预警
return userRepository.findByRoleIn(Arrays.asList("COUNTY_MANAGER", "FIELD_STAFF"));
default:
return Collections.emptyList();
}
}
}
```
### 5.3.3 预警统计分析
**预警统计服务**
```java
@Service
public class WarningStatisticsService {
public WarningStatistics getMonthlyStatistics(int year, int month) {
// 月度预警统计
WarningStatistics stats = new WarningStatistics();
// 查询当月预警数据
List<MessageCenter> warnings = messageCenterRepository
.findByYearAndMonth(year, month);
// 按类型统计
stats.setWaterLevelCount(warnings.stream()
.filter(w -> "水位预警".equals(w.getTitle()))
.count());
stats.setOsmoticCount(warnings.stream()
.filter(w -> "渗压预警".equals(w.getTitle()))
.count());
// 按级别统计
stats.setLevel1Count(warnings.stream()
.filter(w -> w.getWarningLevel() == 1)
.count());
stats.setLevel2Count(warnings.stream()
.filter(w -> w.getWarningLevel() == 2)
.count());
stats.setLevel3Count(warnings.stream()
.filter(w -> w.getWarningLevel() == 3)
.count());
return stats;
}
public List<WarningTrend> getWarningTrend(int days) {
// 预警趋势分析
List<WarningTrend> trends = new ArrayList<>();
LocalDate endDate = LocalDate.now();
LocalDate startDate = endDate.minusDays(days);
for (LocalDate date = startDate; date.isBefore(endDate); date = date.plusDays(1)) {
WarningTrend trend = new WarningTrend();
trend.setDate(date);
trend.setCount(messageCenterRepository.countByDate(date));
trends.add(trend);
}
return trends;
}
}
```
## 5.4 县级用户功能设计
### 5.4.1 考核管理系统
**考核任务工作流程**
```java
@Service
public class AssessTaskService {
public AssessTask createTask(AssessTaskDTO dto) {
// 创建考核任务
AssessTask task = new AssessTask();
BeanUtils.copyProperties(dto, task);
task.setStatus(0); // 未启动状态
task.setCreateTime(LocalDateTime.now());
// 分配考核对象
List<AssessObject> objects = assessObjectRepository.findByRegion(dto.getRegion());
task.setAssessObjects(objects);
// 设置考核指标
List<AssessIndicator> indicators = assessIndicatorRepository.findByTaskType(dto.getTaskType());
task.setIndicators(indicators);
return assessTaskRepository.save(task);
}
@Transactional
public String startTask(Long taskId) {
// 启动考核任务
AssessTask task = assessTaskRepository.findById(taskId)
.orElseThrow(() -> new RuntimeException("任务不存在"));
if (task.getStatus() != 0) {
throw new RuntimeException("任务状态不允许启动");
}
task.setStatus(1); // 进行中状态
task.setStartTime(LocalDateTime.now());
// 通知考核对象
notifyAssessObjects(task);
assessTaskRepository.save(task);
return "任务启动成功";
}
public List<AssessTask> getPendingTasks(Long userId) {
// 获取用户待办任务
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("用户不存在"));
return assessTaskRepository.findByAssessorAndStatus(user, 1);
}
public List<AssessResultVo> getResult(Long taskId) {
// 获取考核结果
AssessTask task = assessTaskRepository.findById(taskId)
.orElseThrow(() -> new RuntimeException("任务不存在"));
List<AssessResult> results = assessResultRepository.findByTaskId(taskId);
return results.stream().map(result -> {
AssessResultVo vo = new AssessResultVo();
vo.setObjectName(result.getObjectName());
vo.setIndicatorName(result.getIndicatorName());
vo.setScore(result.getScore());
vo.setComment(result.getComment());
return vo;
}).collect(Collectors.toList());
}
}
```
**考核对象管理**
```java
@Service
public class AssessObjectService {
public List<AssessObject> getObjectsByRegion(String region) {
// 按区域获取考核对象
return assessObjectRepository.findByRegion(region);
}
public List<AssessObject> getObjectsByType(String objectType) {
// 按类型获取考核对象
return assessObjectRepository.findByObjectType(objectType);
}
public void assignToTask(Long taskId, List<Long> objectIds) {
// 分配考核对象到任务
AssessTask task = assessTaskRepository.findById(taskId)
.orElseThrow(() -> new RuntimeException("任务不存在"));
List<AssessObject> objects = assessObjectRepository.findByIdIn(objectIds);
task.setAssessObjects(objects);
assessTaskRepository.save(task);
}
}
```
### 5.4.2 权限管理系统
**基于角色的权限控制**
```java
@Service
public class PermissionService {
public boolean hasPermission(Long userId, String permission) {
// 检查用户权限
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("用户不存在"));
return user.getRoles().stream()
.flatMap(role -> role.getPermissions().stream())
.anyMatch(p -> p.getCode().equals(permission));
}
public List<String> getUserPermissions(Long userId) {
// 获取用户权限列表
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("用户不存在"));
return user.getRoles().stream()
.flatMap(role -> role.getPermissions().stream())
.map(Permission::getCode)
.distinct()
.collect(Collectors.toList());
}
}
```
### 5.5 系统改进功能
### 5.5.1 防治点管理
**防治点树形结构管理**
```java
@Service
public class PrePlaceService {
public List<PrePlaceTreeVo> getPlaceTree() {
// 获取防治点树形结构
List<PrePlace> places = prePlaceRepository.findAllByOrderByParentIdAsc();
return buildTree(places, null);
}
private List<PrePlaceTreeVo> buildTree(List<PrePlace> places, Long parentId) {
List<PrePlaceTreeVo> tree = new ArrayList<>();
for (PrePlace place : places) {
if ((parentId == null && place.getParentId() == null) ||
(parentId != null && parentId.equals(place.getParentId()))) {
PrePlaceTreeVo vo = new PrePlaceTreeVo();
vo.setId(place.getId());
vo.setName(place.getPlaceName());
vo.setCode(place.getPlaceCode());
vo.setType(place.getPlaceType());
vo.setChildren(buildTree(places, place.getId()));
tree.add(vo);
}
}
return tree;
}
public List<PrePlaceDetail> getPlaceDetails(Long placeId) {
// 获取防治点详细信息
return prePlaceDetailRepository.findByPlaceId(placeId);
}
}
```
### 5.5.2 维护管理功能
**维护计划管理**
```java
@Service
public class MentenancePlanService {
public MentenancePlan createAnnualPlan(MentenancePlanDTO dto) {
// 创建年度维护计划
MentenancePlan plan = new MentenancePlan();
BeanUtils.copyProperties(dto, plan);
plan.setStatus(0); // 未启动状态
plan.setCreateTime(LocalDateTime.now());
// 创建维护详情
List<MentencePlanDetail> details = dto.getDetails().stream()
.map(detailDto -> {
MentenancePlanDetail detail = new MentenancePlanDetail();
BeanUtils.copyProperties(detailDto, detail);
detail.setPlan(plan);
return detail;
})
.collect(Collectors.toList());
plan.setDetails(details);
return mentenancePlanRepository.save(plan);
}
public void updatePlanStatus(Long planId, Integer status) {
// 更新计划状态
MentenancePlan plan = mentenancePlanRepository.findById(planId)
.orElseThrow(() -> new RuntimeException("计划不存在"));
plan.setStatus(status);
if (status == 1) {
plan.setStartTime(LocalDateTime.now());
} else if (status == 2) {
plan.setEndTime(LocalDateTime.now());
}
mentenancePlanRepository.save(plan);
}
}
```
这些功能设计完整地覆盖了黑石咀水库系统的核心业务需求,包括基础数据管理、算法模型建设、预警功能、县级用户管理和系统改进功能,为系统的开发和实施提供了详细的技术指导。