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

2041 lines
64 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 黑石咀水库系统详细设计文档
# 第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);
}
}
```
这些功能设计完整地覆盖了黑石咀水库系统的核心业务需求,包括基础数据管理、算法模型建设、预警功能、县级用户管理和系统改进功能,为系统的开发和实施提供了详细的技术指导。