# 黑石咀水库系统详细设计文档 # 第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 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 units) { // 构建流域拓扑关系 return topology; } public List getUpstreamUnits(Long unitId) { // 获取上游流域单元 return upstreamUnits; } public List 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 calculateNetRainfall(DesignStormResult designStorm, WatershedUnit watershed) { // 净雨计算逻辑 List 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, WatershedUnit watershed) { // 单位线法洪水计算 FloodHydrograph hydrograph = new FloodHydrograph(); // 获取单位线 UnitHydrograph unitHydrograph = getUnitHydrograph(watershed.getUnitCode()); // 卷积计算 List 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 divideCalculationUnits(WatershedUnit watershed) { // 小流域计算单元划分 List units = new ArrayList<>(); // 基于DEM数据进行单元划分 List 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 calculateThiessenWeights( List stations, WatershedUnit watershed) { // 泰森多边形权重计算 Map weights = new HashMap<>(); // 创建泰森多边形 List 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 createThiessenPolygons(List 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 calculateIDWWeights( List stations, WatershedUnit watershed) { // 反距离权重插值 Map weights = new HashMap<>(); // 生成流域内网格点 List 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 calculateIUH(WatershedUnit watershed, List units) { // 瞬时单位线计算 List 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 routeFloodWave(List inflow, BigDecimal k, BigDecimal x, BigDecimal dt) { // 马斯京根法河道演进 List 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 rules, Map sensorData) { WarningResult result = new WarningResult(); List 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 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 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 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 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 getWarningTrend(int days) { // 预警趋势分析 List 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 objects = assessObjectRepository.findByRegion(dto.getRegion()); task.setAssessObjects(objects); // 设置考核指标 List 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 getPendingTasks(Long userId) { // 获取用户待办任务 User user = userRepository.findById(userId) .orElseThrow(() -> new RuntimeException("用户不存在")); return assessTaskRepository.findByAssessorAndStatus(user, 1); } public List getResult(Long taskId) { // 获取考核结果 AssessTask task = assessTaskRepository.findById(taskId) .orElseThrow(() -> new RuntimeException("任务不存在")); List 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 getObjectsByRegion(String region) { // 按区域获取考核对象 return assessObjectRepository.findByRegion(region); } public List getObjectsByType(String objectType) { // 按类型获取考核对象 return assessObjectRepository.findByObjectType(objectType); } public void assignToTask(Long taskId, List objectIds) { // 分配考核对象到任务 AssessTask task = assessTaskRepository.findById(taskId) .orElseThrow(() -> new RuntimeException("任务不存在")); List 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 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 getPlaceTree() { // 获取防治点树形结构 List places = prePlaceRepository.findAllByOrderByParentIdAsc(); return buildTree(places, null); } private List buildTree(List places, Long parentId) { List 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 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 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); } } ``` 这些功能设计完整地覆盖了黑石咀水库系统的核心业务需求,包括基础数据管理、算法模型建设、预警功能、县级用户管理和系统改进功能,为系统的开发和实施提供了详细的技术指导。