1:新增知识库

2:新增es查询
3:修改proj的docker-compose文件
master
yangzhe123 2026-01-13 10:53:04 +08:00
parent 88a5b794fb
commit b712ff3fb4
38 changed files with 2886 additions and 70 deletions

View File

@ -11,7 +11,7 @@ services:
environment: environment:
- TZ=Asia/Shanghai - TZ=Asia/Shanghai
ports: ports:
- 6369:6379 - 6359:6379
networks: networks:
- tsg_tsg-bridge - tsg_tsg-bridge
volumes: volumes:
@ -19,6 +19,22 @@ services:
- /opt/ss/redis/data:/data - /opt/ss/redis/data:/data
command: redis-server /usr/local/etc/redis/conf/redis.conf command: redis-server /usr/local/etc/redis/conf/redis.conf
ss-es:
container_name: ss-es
image: docker.1ms.run/elasticsearch:8.12.2
environment:
- 'ELASTIC_PASSWORD=1234567a'
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- xpack.security.http.ssl.enabled=false
- xpack.security.enabled=false
- ES_SETTING_XPACK_SECURITY_ENABLED=false
ports:
- "9201:9200"
- "9400:9300"
networks:
- tsg_tsg-bridge
ss-proj: ss-proj:
container_name: ss-proj container_name: ss-proj
image: openjdk:21 image: openjdk:21
@ -34,6 +50,7 @@ services:
- TZ=Asia/Shanghai - TZ=Asia/Shanghai
depends_on: depends_on:
- ss-redis - ss-redis
- ss-es
entrypoint: java -cp "gunshi-project-ss-1.0-SNAPSHOT.jar:./lib/*" com.gunshi.project.ss.Main entrypoint: java -cp "gunshi-project-ss-1.0-SNAPSHOT.jar:./lib/*" com.gunshi.project.ss.Main
ss-datasync: ss-datasync:

View File

@ -230,4 +230,12 @@ public interface JcskGnssRMapper extends BaseMapper<JcskGnssR> {
</script> </script>
""") """)
Page<JcskGnssR> artificialPage(Page<Object> page,@Param("dto") JcskGnssRPageSo page1); Page<JcskGnssR> artificialPage(Page<Object> page,@Param("dto") JcskGnssRPageSo page1);
@Select("""
select t2.* from jcsk_gnss_b t1
join jcsk_gnss_r t2 on t1.cd = t2.cd
where t1.cd_nm = #{cdnm}
order by t2.tm desc limit 1
""")
JcskGnssR queryByCDNM(@Param("cdnm") String stationCode);
} }

View File

@ -81,4 +81,12 @@ public interface JcskSlRMapper extends BaseMapper<JcskSlR> {
""") """)
Page<JcskSlRHisVo> historyPage(Page<Object> page, JcskSlRPageSo page1); Page<JcskSlRHisVo> historyPage(Page<Object> page, JcskSlRPageSo page1);
@Select("""
select t2.* from jcsk_sl_b t1
join jcsk_sl_r t2 on t1.rscd = t2.rscd and t1.mpcd = t2.mpcd
where t1.dvcd = #{dvcd}
order by t2.mstm desc limit 1
""")
JcskSlR queryByDvcd(@Param("dvcd") String stationCode);
} }

View File

@ -384,4 +384,14 @@ GROUP BY dm
ORDER BY tm ORDER BY tm
""") """)
List<StRzVo> qeury8AmRz(@Param("dto") OsmoticQuerySo dto, @Param("stcd") String stcd); List<StRzVo> qeury8AmRz(@Param("dto") OsmoticQuerySo dto, @Param("stcd") String stcd);
@Select("""
select t2.* from jcsk_sy_b t1
join jcsk_sy_r t2 on t1.stcd = t2.stcd and t1.mpcd = t2.mpcd
where t1.dvcd = #{dvcd}
order by t2.mstm desc limit 1
""")
JcskSyR queryByDvcd(@Param("dvcd") String stationCode);
} }

11
pom.xml
View File

@ -115,6 +115,17 @@
<artifactId>spring-boot-starter-quartz</artifactId> <artifactId>spring-boot-starter-quartz</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>5.2.3</version>
</dependency>
<!-- <dependency>--> <!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>--> <!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-elasticsearch</artifactId>--> <!-- <artifactId>spring-boot-starter-data-elasticsearch</artifactId>-->

View File

@ -0,0 +1,89 @@
package com.gunshi.project.ss.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gunshi.core.result.R;
import com.gunshi.project.ss.entity.dto.BusinessRuleDto;
import com.gunshi.project.ss.model.BusinessRule;
import com.gunshi.project.ss.model.FileAssociations;
import com.gunshi.project.ss.service.BusinessRuleService;
import com.gunshi.project.ss.service.FileAssociationsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author lyf
* @since 2025-07-21
*/
@Tag(name = "业务规则库")
@RestController
@RequestMapping(value = "/businessRule")
public class BusinessRuleController extends AbstractCommonFileController {
@Autowired
private BusinessRuleService service;
@Autowired
private FileAssociationsService fileService;
@Operation(summary = "按id查询")
@GetMapping("/getById/{id}")
public BusinessRule getById(@PathVariable("id") Serializable id) {
return service.getOneById(id);
}
@Operation(summary = "新增")
@PostMapping("/add")
public R<BusinessRule> add(@RequestBody BusinessRule entity) {
service.add(entity);
if(entity.getFiles() != null){
fileService.saveFile(entity.getFiles(),getGroupId(),entity.getId().toString());
}
service.updateEsCache(entity);
return R.ok(entity);
}
@Operation(summary = "修改")
@PostMapping("/update")
public R<BusinessRule> update(@RequestBody BusinessRule entity) {
entity.setUpdateTm(new Date());
boolean flag = service.updateById(entity);
if(!flag){
throw new IllegalArgumentException("更新失败");
}
if(entity.getFiles() != null){
fileService.saveFile(entity.getFiles(),getGroupId(),entity.getId().toString());
}
service.updateEsCache(entity);
return R.ok(entity);
}
@Operation(summary = "删除")
@GetMapping("/delete/{id}")
public R<Boolean> delete(@PathVariable("id") Serializable id) {
service.deleteEsCache(id);
boolean flag = service.removeById(id);
fileService.deleteFile(getGroupId(),id.toString());
return R.ok(flag);
}
@Operation(summary = "分页")
@PostMapping("/pageByTm")
public R<Page<BusinessRule>> pageByTm(@RequestBody BusinessRuleDto dto) {
Page<BusinessRule> page = service.page(dto);
for (BusinessRule record : page.getRecords()) {
List<FileAssociations> files = fileService.getFiles(getGroupId(), record.getId().toString());
record.setFiles(files);
}
return R.ok(page);
}
@Override
public String getGroupId() {
return "businessRule";
}
}

View File

@ -1,70 +1,111 @@
package com.gunshi.project.ss.controller; package com.gunshi.project.ss.controller;
import com.alibaba.fastjson2.JSONObject;
import com.gunshi.core.result.R; import com.gunshi.core.result.R;
import com.gunshi.project.ss.common.mapper.StStbprpBMapper;
import com.gunshi.project.ss.common.model.JcskGnssB;
import com.gunshi.project.ss.common.model.JcskSlB;
import com.gunshi.project.ss.common.model.JcskSyB;
import com.gunshi.project.ss.common.model.StStbprpB;
import com.gunshi.project.ss.entity.es.EsObjectDocument;
import com.gunshi.project.ss.entity.so.RealRainBaseSo;
import com.gunshi.project.ss.entity.vo.AttResBaseVo;
import com.gunshi.project.ss.entity.vo.AttRvBaseVo;
import com.gunshi.project.ss.entity.vo.RealRainListVo;
import com.gunshi.project.ss.mapper.*;
import com.gunshi.project.ss.model.*;
import com.gunshi.project.ss.repository.TsgObjectRepository;
import com.gunshi.project.ss.service.*;
import com.gunshi.project.ss.timetask.JcskDataTask; import com.gunshi.project.ss.timetask.JcskDataTask;
import com.gunshi.project.ss.timetask.PaDataTask; import com.gunshi.project.ss.timetask.PaDataTask;
import com.gunshi.project.ss.timetask.StWaterDataTask; import com.gunshi.project.ss.timetask.StWaterDataTask;
import com.gunshi.project.ss.timetask.WarningRuleTask; import com.gunshi.project.ss.timetask.WarningRuleTask;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.text.ParseException; import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
@Tag(name = "后门") @Tag(name = "后门")
@RestController @RestController
@RequestMapping(value="/debug") @RequestMapping(value="/debug")
@Slf4j
public class DebugController { public class DebugController {
@Autowired
private TsgObjectRepository tsgObjectRepository;
@Autowired
private StStbprpBMapper stStbprpBMapper;//监测站点
@Autowired
private AttCctvBaseMapper attCctvBaseMapper;//视频站
@Autowired
private IaCDanadMapper iaCDanadMapper;//危险区
@Autowired
private ShpPlacementMapper shpPlacementMapper;//安置点
@Autowired
private BusinessRuleMapper businessRuleMapper;//业务规则库
@Autowired
private DispatchSchemeMapper dispatchSchemeMapper;//调度方案库
@Autowired
private ProjectSafetyMapper projectSafetyMapper;//工程安全知识库
@Autowired
private IaCBsnssinfoMapper iaCBsnssinfoMapper;//企事业单位
@Autowired
private IaCFlrvvlgMapper iaCFlrvvlgMapper;//沿河居民
@Autowired
private SoilMoistureStationMapper soilMoistureStationMapper;
@Autowired
private BusinessRuleService businessRuleService;
@Autowired
private DispatchSchemeService dispatchSchemeService;
@Autowired
private ProjectSafetyService projectSafetyService;
@Autowired
private ReservoirWaterService reservoirWaterService;//水库水位站(详细数据)
@Autowired
private RiverWaterService riverWaterService;//河道水位站
@Autowired
private RealRainService realRainService;//雨晴(雨量站详细信息)
@Autowired
private JcskSyBService jcskSyBService;
@Autowired
private JcskSlBService jcskSlBService;
@Autowired
private JcskGnssBService jcskGnssBService;// 位移日后可能表需要进行变更
@Autowired @Autowired
private PaDataTask paDataTask; private PaDataTask paDataTask;
@Autowired
private JcskDataTask jcskDataTask;
@Autowired
private WarningRuleTask warningRuleTask;
@Autowired
private StWaterDataTask stWaterDataTask;
@GetMapping("/syncWateData")
public String syncWateData() {
try {
stWaterDataTask.syncFlowToWater();
Thread.sleep(1000);
stWaterDataTask.syncWaterToReorganize();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "success";
}
@GetMapping("/syRegressionCaculate")
public String syRegressionCaculate(){
try {
jcskDataTask.calculate();
return "SUCCESS";
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@GetMapping("/warnRule")
public String warningRuleTast(){
try {
warningRuleTask.warningRuleExecute();
return "success";
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@GetMapping("/patask") @GetMapping("/patask")
public String patask(){ public String patask(){
try { try {
@ -75,14 +116,369 @@ public class DebugController {
} }
} }
@Operation(description = "同步一次渗压、渗流、位移的数据")
@GetMapping("/syncJcskData")
public R syncJcskData(){
jcskDataTask.syncGnssREightAmData();
jcskDataTask.syncSlREightAmData(); @Operation(description = "获取所有es数据")
@GetMapping("/findAll")
public R findAll(){
Iterable<EsObjectDocument> all = tsgObjectRepository.findAll();
return R.ok(all);
}
jcskDataTask.syncSyREightAmData();
return R.ok("ok"); @Operation(description = "删除所有es数据")
@GetMapping("/deleteAll")
public R deleteAll(){
tsgObjectRepository.deleteAll();
return R.ok();
}
@Operation(description = "数据结构的重建")
@GetMapping("/rebuild")
public R rebuild(){
// 1. 删除现有索引
ElasticsearchOperations elasticsearchOperations = getElasticsearchOperations();
if (elasticsearchOperations.indexOps(EsObjectDocument.class).exists()) {
elasticsearchOperations.indexOps(EsObjectDocument.class).delete();
log.info("索引删除成功");
}
// 2. 创建新索引
elasticsearchOperations.indexOps(EsObjectDocument.class).create();
log.info("索引创建成功");
// 3. 创建映射
elasticsearchOperations.indexOps(EsObjectDocument.class).putMapping();
log.info("映射创建成功");
return R.ok("重建索引成功");
}
// 需要注入ElasticsearchOperations
@Autowired
private ElasticsearchOperations elasticsearchOperations;
private ElasticsearchOperations getElasticsearchOperations() {
return elasticsearchOperations;
}
@Operation(description = "填充es数据")
@GetMapping("/cacheEs")
public R cacheEs(){
tsgObjectRepository.deleteAll();
List<EsObjectDocument> list = Lists.newArrayList();
//缓存雨量站
RealRainBaseSo realRainBaseSo = new RealRainBaseSo();
LocalDateTime now = LocalDateTime.now();
//设置当前时间
realRainBaseSo.setStm(now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
//计算一小时之后时间
LocalDateTime oneHourLater = now.plusHours(1);
realRainBaseSo.setEtm(oneHourLater.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
List<RealRainListVo> realRainList = realRainService.getRealRainList(realRainBaseSo);
for (RealRainListVo entity : realRainList) {
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(entity.getStcd());
esObjectDocument.setName(entity.getStnm());
esObjectDocument.setType("雨量站");
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
if(entity.getLgtd() != null){
esObjectDocument.setLgtd(new BigDecimal(entity.getLgtd()));
}
if(entity.getLttd() != null){
esObjectDocument.setLttd(new BigDecimal(entity.getLttd()));
}
list.add(esObjectDocument);
}
//缓存至es中
tsgObjectRepository.saveAll(list);
//清空list
list.clear();
//这是水库水位站
List<AttResBaseVo> attResBaseVos = reservoirWaterService.listV2();
//List<StStbprpB> rrList = stStbprpBMapper.getStbprbBySttp("RR");
for (AttResBaseVo entity : attResBaseVos) {
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(entity.getStcd());
esObjectDocument.setName(entity.getStnm());
esObjectDocument.setType("水库水位站");
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
if(entity.getLgtd() != null){
esObjectDocument.setLgtd(entity.getLgtd());
}
if(entity.getLgtd() != null){
esObjectDocument.setLttd(entity.getLttd());
}
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
//添加河道水位站
List<AttRvBaseVo> rvBaseVoList = riverWaterService.list();
for (AttRvBaseVo entity : rvBaseVoList) {
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(entity.getStcd());
esObjectDocument.setName(entity.getStnm());
esObjectDocument.setType("河道水位站");
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
if(entity.getLgtd() != null){
esObjectDocument.setLgtd(entity.getLgtd());
}
if(entity.getLgtd() != null){
esObjectDocument.setLttd(entity.getLttd());
}
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
//视频站
List<AttCctvBase> cctvList = attCctvBaseMapper.selectList(null);
for (AttCctvBase entity : cctvList) {
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(entity.getIndexCode());
esObjectDocument.setName(entity.getName());
esObjectDocument.setType("视频站");
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
if(entity.getLgtd() != null){
esObjectDocument.setLgtd(new BigDecimal(entity.getLgtd()));
}
if(entity.getLgtd() != null){
esObjectDocument.setLttd(new BigDecimal(entity.getLttd()));
}
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
//危险区
List<IaCDanad> dandList = iaCDanadMapper.selectList(null);
for (IaCDanad entity : dandList) {
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(entity.getDand());
esObjectDocument.setName(entity.getName());
esObjectDocument.setType("危险区");
esObjectDocument.setLgtd(null);
esObjectDocument.setLttd(null);
esObjectDocument.setGeojson(entity.getGeometry());
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
//安置点
List<ShpPlacement> shpList = shpPlacementMapper.selectList(null);
for (ShpPlacement entity : shpList) {
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(entity.getGid().toString());
esObjectDocument.setName(entity.getName());
esObjectDocument.setType("安置点");
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
esObjectDocument.setLgtd(entity.getLgtd() != null ? BigDecimal.valueOf(entity.getLgtd()) : null);
esObjectDocument.setLttd(entity.getLttd() != null ? BigDecimal.valueOf(entity.getLttd()) : null);
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
//调度方案库
List<DispatchScheme> dispatchRecordList = dispatchSchemeMapper.selectList(null);
for (DispatchScheme entity : dispatchRecordList) {
DispatchScheme oneById = dispatchSchemeService.getOneById(entity.getId());
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(String.valueOf(entity.getId()));
esObjectDocument.setName(entity.getName());
esObjectDocument.setType("调度方案库");
esObjectDocument.setLgtd(null);
esObjectDocument.setLttd(null);
esObjectDocument.setGeojson(null);
String jsonString = JSONObject.toJSONString(oneById);
esObjectDocument.setJsonStr(jsonString);
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
//业务规则库
List<BusinessRule> businessRules = businessRuleMapper.selectList(null);
for (BusinessRule entity : businessRules) {
BusinessRule oneById = businessRuleService.getOneById(entity.getId());
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(String.valueOf(entity.getId()));
esObjectDocument.setName(entity.getName());
esObjectDocument.setType("业务规则库");
esObjectDocument.setLgtd(null);
esObjectDocument.setLttd(null);
esObjectDocument.setGeojson(null);
String jsonString = JSONObject.toJSONString(oneById);
esObjectDocument.setJsonStr(jsonString);
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
// 工程安全知识库
List<ProjectSafety> projectSafeties = projectSafetyMapper.selectList(null);
for (ProjectSafety entity : projectSafeties) {
ProjectSafety oneById = projectSafetyService.getOneById(entity.getId());
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(String.valueOf(entity.getId()));
esObjectDocument.setName(entity.getName());
esObjectDocument.setType("工程安全知识库");
esObjectDocument.setLgtd(null);
esObjectDocument.setLttd(null);
esObjectDocument.setGeojson(null);
String jsonString = JSONObject.toJSONString(oneById);
esObjectDocument.setJsonStr(jsonString);
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
//企事业单位
List<IaCBsnssinfo> iaCBsnssinfos = iaCBsnssinfoMapper.selectList(null);
for (IaCBsnssinfo entity : iaCBsnssinfos) {
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(entity.getEicd());
esObjectDocument.setName(entity.getName());
esObjectDocument.setType("企事业单位");
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
if(entity.getLgtd() != null){
esObjectDocument.setLgtd(new BigDecimal(entity.getLgtd()));
}
if(entity.getLgtd() != null){
esObjectDocument.setLttd(new BigDecimal(entity.getLttd()));
}
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
List<IaCFlrvvlg> iaCFlrvvlgs = iaCFlrvvlgMapper.selectList(null);
for (IaCFlrvvlg entity : iaCFlrvvlgs) {
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(entity.getAvrcd());
esObjectDocument.setName(entity.getName());
esObjectDocument.setType("沿河居民点");
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
if(entity.getLgtd() != null){
esObjectDocument.setLgtd(new BigDecimal(entity.getLgtd()));
}
if(entity.getLgtd() != null){
esObjectDocument.setLttd(new BigDecimal(entity.getLttd()));
}
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
//土壤站
List<SoilMoistureStation> soilMoistureStations = soilMoistureStationMapper.selectList(null);
for (SoilMoistureStation entity : soilMoistureStations) {
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(String.valueOf(entity.getId()));
esObjectDocument.setName(entity.getStnm());
esObjectDocument.setType("土壤墒情站");
esObjectDocument.setLgtd(entity.getLgtd());
esObjectDocument.setLttd(entity.getLttd());
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
//流量站
// List<StStbprpB> qqList = stStbprpBMapper.select("QQ");
List<StStbprpB> qqList = stStbprpBMapper.getFlowStations();
for (StStbprpB entity : qqList) {
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(entity.getStcd());
esObjectDocument.setName(entity.getStnm());
esObjectDocument.setType("流量站");
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
if(entity.getLgtd() != null){
esObjectDocument.setLgtd(new BigDecimal(entity.getLgtd()));
}
if(entity.getLgtd() != null){
esObjectDocument.setLttd(new BigDecimal(entity.getLttd()));
}
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
//渗流
// List<OsmoticFlowDevice> osmoticFlowDevices = osmoticFlowDeviceMapper.selectList(null);
List<JcskSlB> jcskSlBS = jcskSlBService.getBaseMapper().selectList(null);
for (JcskSlB entity : jcskSlBS) {
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(entity.getDvcd());
esObjectDocument.setName(entity.getDvcd());
esObjectDocument.setType("渗流站");
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
if(entity.getLgtd() != null){
esObjectDocument.setLgtd(entity.getLgtd());
}
if(entity.getLgtd() != null){
esObjectDocument.setLttd(entity.getLttd());
}
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
//渗压
List<JcskSyB> jcskSyBS = jcskSyBService.getBaseMapper().selectList(null);
for (JcskSyB entity : jcskSyBS) {
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(entity.getDvcd());
esObjectDocument.setName(entity.getDvcd());
esObjectDocument.setType("渗压站");
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
if(entity.getLgtd() != null){
esObjectDocument.setLgtd(entity.getLgtd());
}
if(entity.getLgtd() != null){
esObjectDocument.setLttd(entity.getLttd());
}
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
//位移站
List<JcskGnssB> jcskGnssBS = jcskGnssBService.getBaseMapper().selectList(null);
for (JcskGnssB entity : jcskGnssBS) {
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(entity.getCd());
esObjectDocument.setName(entity.getCd());
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
esObjectDocument.setType("位移站");
esObjectDocument.setLgtd(entity.getLgtd());
esObjectDocument.setLttd(entity.getLttd());
list.add(esObjectDocument);
}
tsgObjectRepository.saveAll(list);
list.clear();
return R.ok("数据缓存成功");
} }
} }

View File

@ -0,0 +1,97 @@
package com.gunshi.project.ss.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gunshi.core.result.R;
import com.gunshi.project.ss.entity.dto.DispatchSchemeDto;
import com.gunshi.project.ss.model.DispatchScheme;
import com.gunshi.project.ss.model.FileAssociations;
import com.gunshi.project.ss.service.DispatchSchemeService;
import com.gunshi.project.ss.service.FileAssociationsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author lyf
* @since 2025-07-21
*/
@Tag(name = "调度方案库")
@RestController
@RequestMapping(value = "/dispatchScheme")
public class DispatchSchemeController extends AbstractCommonFileController {
@Autowired
private DispatchSchemeService service;
@Autowired
private FileAssociationsService fileService;
@Operation(summary = "按id查询")
@GetMapping("/getById/{id}")
public DispatchScheme getById(@PathVariable("id") Serializable id) {
return service.getOneById(id);
}
@Operation(summary = "获取全部数据")
@GetMapping("getAll")
public List<DispatchScheme> getAll() {
List<DispatchScheme> list = service.list();
for (DispatchScheme dispatchScheme : list) {
List<FileAssociations> files = fileService.getFiles(getGroupId(), dispatchScheme.getId().toString());
dispatchScheme.setFiles(files);
}
return list;
}
@Operation(summary = "新增")
@PostMapping("/add")
public R<DispatchScheme> add(@RequestBody DispatchScheme entity) {
service.add(entity);
if(entity.getFiles() != null){
fileService.saveFile(entity.getFiles(),getGroupId(),entity.getId().toString());
}
service.updateEsCache(entity);
return R.ok(entity);
}
@Operation(summary = "修改")
@PostMapping("/update")
public R<DispatchScheme> update(@RequestBody DispatchScheme entity) {
entity.setUpdateTm(new Date());
service.updateById(entity);
if(entity.getFiles() != null){
fileService.saveFile(entity.getFiles(),getGroupId(),entity.getId().toString());
}
service.updateEsCache(entity);
return R.ok(entity);
}
@Operation(summary = "删除")
@GetMapping("/delete/{id}")
public R<Boolean> delete(@PathVariable("id") Serializable id) {
service.deleteEsCache(id);
boolean flag = service.removeById(id);
fileService.deleteFile(getGroupId(),id.toString());
return R.ok(flag);
}
@Operation(summary = "分页")
@PostMapping("/pageByTm")
public R<Page<DispatchScheme>> pageByTm(@RequestBody DispatchSchemeDto dto) {
Page<DispatchScheme> page = service.page(dto);
for (DispatchScheme record : page.getRecords()) {
List<FileAssociations> files = fileService.getFiles(getGroupId(), record.getId().toString());
record.setFiles(files);
}
return R.ok(page);
}
@Override
public String getGroupId() {
return "dispatchScheme";
}
}

View File

@ -0,0 +1,52 @@
package com.gunshi.project.ss.controller;
import com.gunshi.core.result.R;
import com.gunshi.db.dto.DateTimeRangeSo;
import com.gunshi.project.ss.service.DocCenterService;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@Tag(name = "资料中心-数据报表")
@RestController
@RequestMapping(value = "/docReport")
public class DocReportController {
@Autowired
private DocCenterService docCenterService;
@PostMapping("/groupByType")
public R<Map<String,Long>> groupByType(@RequestBody DateTimeRangeSo dateTimeRangeSo){
Map<String,Long> map = docCenterService.groupByType(dateTimeRangeSo);
return R.ok(map);
}
@PostMapping("/groupByDept")
public R<Map<String,Long>> groupByDept(@RequestBody DateTimeRangeSo dateTimeRangeSo){
Map<String,Long> map = docCenterService.groupByDept(dateTimeRangeSo);
return R.ok(map);
}
@PostMapping("/groupBySecret")
public R<Map<String,Long>> groupBySecret(@RequestBody DateTimeRangeSo dateTimeRangeSo){
Map<String,Long> map = docCenterService.groupBySecret(dateTimeRangeSo);
return R.ok(map);
}
@PostMapping("/groupByVersion")
public R<Map<String,Long>> groupByVersion(@RequestBody DateTimeRangeSo dateTimeRangeSo){
Map<String,Long> map = docCenterService.groupByVersion(dateTimeRangeSo);
return R.ok(map);
}
@PostMapping("/groupByTm")
public R<Map<String,Long>> groupByTm(@RequestBody DateTimeRangeSo dateTimeRangeSo){
Map<String,Long> map = docCenterService.groupByTm(dateTimeRangeSo);
return R.ok(map);
}
}

View File

@ -8,8 +8,7 @@ import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gunshi.core.result.R; import com.gunshi.core.result.R;
import com.gunshi.project.ss.entity.vo.ForecastResultVo; import com.gunshi.project.ss.entity.vo.ForecastResultVo;
import com.gunshi.project.ss.model.ForecastProject; import com.gunshi.project.ss.model.*;
import com.gunshi.project.ss.model.ForecastResults;
import com.gunshi.project.ss.service.ForecastProjectService; import com.gunshi.project.ss.service.ForecastProjectService;
import com.gunshi.project.ss.service.ForecastResultsService; import com.gunshi.project.ss.service.ForecastResultsService;
import com.gunshi.project.ss.common.validate.markers.Insert; import com.gunshi.project.ss.common.validate.markers.Insert;
@ -146,6 +145,20 @@ public class ForecastProjectController {
return R.ok(result ? forecastProject : null); return R.ok(result ? forecastProject : null);
} }
@Operation(summary = "调度计算-闸门开放关闭时间")
@GetMapping("/caculate/{waterLevel}")
public R<List<ForecastDispatchCommand>> caculate(@PathVariable("waterLevel") String waterLevel) {
List<ForecastDispatchCommand> res = service.caculate(waterLevel);
return R.ok(res);
}
@Operation(summary = "调度计算-调度结果")
@GetMapping("/dispatch/result")
public R<ForecastDispatchResult> getDispatchResult(){
ForecastDispatchResult result = service.getDispatchResult();
return R.ok(result);
}
@Operation(summary = "根据方案id查看方案洪水预报结果") @Operation(summary = "根据方案id查看方案洪水预报结果")
@GetMapping("/getForecastProjectResults") @GetMapping("/getForecastProjectResults")

View File

@ -0,0 +1,84 @@
package com.gunshi.project.ss.controller;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Lists;
import com.gunshi.core.result.R;
import com.gunshi.project.ss.entity.es.EsObjectDocument;
import com.gunshi.project.ss.entity.so.RealRainBaseSo;
import com.gunshi.project.ss.entity.vo.RealRainListVo;
import com.gunshi.project.ss.repository.TsgObjectRepository;
import com.gunshi.project.ss.service.RealRainService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
@RestController
@RequestMapping("/globalSearch")
@Tag(name = "知识库-全局搜索接口")
public class GlobalSearchController {
@Autowired
private TsgObjectRepository tsgObjectRepository;
@Autowired
private RealRainService realRainService;
@GetMapping("findByName")
@Operation(description = "根据名称搜索")
public R<List<EsObjectDocument>> findByName(@RequestParam("name") String name) {
//reCacheRealRain();
Sort sort = Sort.by(
Sort.Order.asc("type"),
Sort.Order.asc("name")
);
List<EsObjectDocument> list = tsgObjectRepository.findByName(name,sort);
return R.ok(list);
}
/**
*
*/
private void reCacheRealRain(){
List<EsObjectDocument> byType = tsgObjectRepository.findByType("雨量站");
tsgObjectRepository.deleteAll(byType);
RealRainBaseSo realRainBaseSo = new RealRainBaseSo();
LocalDateTime now = LocalDateTime.now();
//设置当前时间
realRainBaseSo.setStm(now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
//计算一小时之后时间
LocalDateTime oneHourLater = now.plusHours(1);
realRainBaseSo.setEtm(oneHourLater.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
List<RealRainListVo> realRainList = realRainService.getRealRainList(realRainBaseSo);
List<EsObjectDocument> list = Lists.newArrayList();
for (RealRainListVo entity : realRainList) {
EsObjectDocument objectDocument = new EsObjectDocument();
objectDocument.setUnionCode(entity.getStcd());
objectDocument.setName(entity.getStnm());
objectDocument.setType("雨量站");
String jsonString = JSONObject.toJSONString(entity);
objectDocument.setJsonStr(jsonString);
if(entity.getLgtd() != null){
objectDocument.setLgtd(new BigDecimal(entity.getLgtd()));
}
if(entity.getLgtd() != null){
objectDocument.setLttd(new BigDecimal(entity.getLttd()));
}
list.add(objectDocument);
}
tsgObjectRepository.saveAll(list);
}
}

View File

@ -0,0 +1,111 @@
package com.gunshi.project.ss.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gunshi.core.result.R;
import com.gunshi.project.ss.entity.dto.ProjectSafetyDto;
import com.gunshi.project.ss.model.FileAssociations;
import com.gunshi.project.ss.model.ProjectSafety;
import com.gunshi.project.ss.model.ProjectSafetyType;
import com.gunshi.project.ss.service.FileAssociationsService;
import com.gunshi.project.ss.service.ProjectSafetyService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author lyf
* @since 2025-07-21
*/
@Tag(name = "工程安全知识库")
@RestController
@RequestMapping(value = "/projectSafety")
public class ProjectSafetyController extends AbstractCommonFileController {
@Autowired
private ProjectSafetyService service;
@Autowired
private FileAssociationsService fileService;
@Operation(summary = "按id查询")
@GetMapping("/getById/{id}")
public ProjectSafety getById(@PathVariable("id") Serializable id) {
ProjectSafety byId = service.getOneById(id);
return byId;
}
@Operation(summary = "新增")
@PostMapping("/add")
public R<ProjectSafety> add(@RequestBody ProjectSafety entity) {
service.add(entity);
if(entity.getFiles() != null){
fileService.saveFile(entity.getFiles(),getGroupId(),entity.getId().toString());
}
service.updateEsCache(entity);
return R.ok(entity);
}
@Operation(summary = "修改")
@PostMapping("/update")
public R<ProjectSafety> update(@RequestBody ProjectSafety entity) {
entity.setUpdateTm(new Date());
service.updateById(entity);
if(entity.getFiles() != null){
fileService.saveFile(entity.getFiles(),getGroupId(),entity.getId().toString());
}
service.updateEsCache(entity);
return R.ok(entity);
}
@Operation(summary = "删除")
@GetMapping("/delete/{id}")
public R<Boolean> delete(@PathVariable("id") Serializable id) {
service.deleteEsCache(id);
fileService.deleteFile(getGroupId(),id.toString());
boolean flag = service.removeById(id);
return R.ok(flag);
}
@Operation(summary = "分页")
@PostMapping("/pageByTm")
public R<Page<ProjectSafety>> pageByTm(@RequestBody ProjectSafetyDto dto) {
Page<ProjectSafety> result = service.page(dto);
for (ProjectSafety record : result.getRecords()) {
List<FileAssociations> files = fileService.getFiles(getGroupId(), record.getId().toString());
record.setFiles(files);
}
return R.ok(result);
}
@GetMapping("/listCategory")
public R<List<ProjectSafetyType>> listCategory() {
return R.ok(service.listCategory());
}
@GetMapping("/addCategory")
public R<ProjectSafetyType> addCategory(@RequestParam("name") String name) {
return R.ok(service.addCategory(name));
}
@PostMapping("/updateCategory")
public R<Boolean> updateCategory(@RequestBody ProjectSafetyType entity) {
return R.ok(service.updateCategory(entity));
}
@GetMapping("/delCategory/{id}")
public R<Boolean> delCategory(@PathVariable("id") Integer id) {
return R.ok(service.delCategory(id));
}
@Override
public String getGroupId() {
return "projectSafety";
}
}

View File

@ -0,0 +1,18 @@
package com.gunshi.project.ss.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
*
*/
@Data
@AllArgsConstructor
public class TimeCapacity {
private LocalDateTime time;
private BigDecimal capacity; // 万m³
}

View File

@ -0,0 +1,17 @@
package com.gunshi.project.ss.entity;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class TimeNetWater {
private LocalDateTime time;
private BigDecimal netWater;
public TimeNetWater(LocalDateTime time, BigDecimal netWater) {
this.time = time;
this.netWater = netWater;
}
}

View File

@ -0,0 +1,33 @@
package com.gunshi.project.ss.entity.es;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.math.BigDecimal;
@Data
@Document(indexName="ss_object")
public class EsObjectDocument {
@Id // 必须添加这个注解
private String id; // 字段名可以是id或自定义
@Field(type = FieldType.Text, store = true)
private String unionCode;
@Field(type = FieldType.Keyword, store = true)
private String name;
@Field(type = FieldType.Keyword, store = true)
private String type;
@Field(type = FieldType.Double, store = true)
private BigDecimal lgtd;
@Field(type = FieldType.Double, store = true)
private BigDecimal lttd;
@Field(type = FieldType.Text, store = true)
private String geojson;
@Field(type = FieldType.Text, store = true)
private String jsonStr;
}

View File

@ -0,0 +1,12 @@
package com.gunshi.project.ss.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gunshi.project.ss.model.BusinessRule;
/**
* @author lyf
* @since 2025-07-21
*/
public interface BusinessRuleMapper extends BaseMapper<BusinessRule> {
}

View File

@ -0,0 +1,12 @@
package com.gunshi.project.ss.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gunshi.project.ss.model.DispatchScheme;
/**
* @author lyf
* @since 2025-07-21
*/
public interface DispatchSchemeMapper extends BaseMapper<DispatchScheme> {
}

View File

@ -0,0 +1,12 @@
package com.gunshi.project.ss.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gunshi.project.ss.model.ProjectSafety;
/**
* @author lyf
* @since 2025-07-21
*/
public interface ProjectSafetyMapper extends BaseMapper<ProjectSafety> {
}

View File

@ -0,0 +1,11 @@
package com.gunshi.project.ss.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gunshi.project.ss.model.ProjectSafetyType;
/**
* @author lyf
* @since 2025-07-21
*/
public interface ProjectSafetyTypeMapper extends BaseMapper<ProjectSafetyType> {
}

View File

@ -0,0 +1,71 @@
package com.gunshi.project.ss.model;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.gunshi.core.dateformat.DateFormatString;
import com.gunshi.project.ss.common.validate.markers.Update;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* @author lyf
* @since 2025-07-21
*/
@Schema(description = "业务规则库")
@Data
@TableName("public.business_rule")
public class BusinessRule {
@TableId(value = "id", type = IdType.AUTO)
@Schema(description = "主键")
@NotNull(message = "id不能为空", groups = {Update.class})
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
@TableField(value = "name",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "规则名称")
private String name;
@TableField(value = "type",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "规则类型")
private Integer type; //水资源调度,防洪调度,工程安全,应急抢险,其他
@TableField(value = "tm",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "编制时间")
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD, timezone = "GMT+8")
private Date tm;
@TableField(value = "status",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "状态")
private Integer status; //0=已废弃1=生效中
@TableField(value = "content",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "简介")
private String content;
@TableField(value = "_create_tm", fill = FieldFill.INSERT,updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "创建时间")
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD_HH_MM_SS, timezone = "GMT+8")
private Date createTm;
@TableField(value = "_create_user",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "创建人")
private String createUser;
@TableField(value = "_update_tm",fill = FieldFill.INSERT_UPDATE)
@Schema(description = "更新时间")
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD_HH_MM_SS, timezone = "GMT+8")
private Date updateTm;
@TableField(exist = false)
private Integer fileCount;
@TableField(exist = false)
private List<FileAssociations> files;
}

View File

@ -0,0 +1,74 @@
package com.gunshi.project.ss.model;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.gunshi.core.dateformat.DateFormatString;
import com.gunshi.project.ss.common.validate.markers.Update;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* @author lyf
* @since 2025-07-21
*/
@Schema(description = "调度方案库")
@Data
@TableName(value = "dispatch_scheme", schema = "public")
public class DispatchScheme {
@TableId(value = "id", type = IdType.AUTO)
@Schema(description = "主键")
@NotNull(message = "id不能为空", groups = {Update.class})
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
@TableField(value = "name",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "方案名称")
private String name;
@TableField(value = "type",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "调度类型")
private Integer type; //防洪调度,兴利调度,生态调度,应急调度,其他
@TableField(value = "tm",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "编制时间")
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD, timezone = "GMT+8")
private Date tm;
@TableField(value = "status",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "状态")
private Integer status; //0=已废弃1=生效中
@TableField(value = "content",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "简介")
private String content;
@TableField(value = "_create_tm", fill = FieldFill.INSERT,updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "创建时间")
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD_HH_MM_SS, timezone = "GMT+8")
private Date createTm;
@TableField(value = "_create_user",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "创建人")
private String createUser;
@TableField(value = "_update_tm",fill = FieldFill.INSERT_UPDATE,updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "更新时间")
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD_HH_MM_SS, timezone = "GMT+8")
private Date updateTm;
@TableField(exist = false)
private Integer fileCount;
@TableField(exist = false)
private List<FileAssociations> files;
}

View File

@ -104,7 +104,7 @@ public class DocCenter {
private List<FileAssociations> files; private List<FileAssociations> files;
@TableField(exist = false) @TableField(exist = false)
@Schema(description = "一级资料类别代码") @Schema(description = "资料类别代码")
private List<String> CategoryCodes; private List<String> CategoryCodes;
} }

View File

@ -0,0 +1,66 @@
package com.gunshi.project.ss.model;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.gunshi.core.dateformat.DateFormatString;
import com.gunshi.project.ss.common.validate.markers.Update;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* @author lyf
* @since 2025-07-21
*/
@Schema(description = "工程安全知识库")
@Data
@TableName("public.project_safety")
public class ProjectSafety {
@TableId(value = "id", type = IdType.AUTO)
@Schema(description = "主键")
@NotNull(message = "id不能为空", groups = {Update.class})
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
@TableField(value = "name",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "标题")
private String name;
@TableField(value = "type",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "知识库类型")
private Integer type; //
@TableField(value = "tm",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "编制时间")
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD, timezone = "GMT+8")
private Date tm;
@TableField(value = "content",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "简介")
private String content;
@TableField(value = "_create_tm", fill = FieldFill.INSERT,updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "创建时间")
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD_HH_MM_SS, timezone = "GMT+8")
private Date createTm;
@TableField(value = "_create_user",updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "创建人")
private String createUser;
@TableField(value = "_update_tm",fill = FieldFill.INSERT_UPDATE,updateStrategy = FieldStrategy.NOT_NULL)
@Schema(description = "更新时间")
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD_HH_MM_SS, timezone = "GMT+8")
private Date updateTm;
@TableField(exist = false)
private Integer fileCount;
@TableField(exist = false)
private List<FileAssociations> files;
}

View File

@ -0,0 +1,28 @@
package com.gunshi.project.ss.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.gunshi.project.ss.common.validate.markers.Update;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* @author lyf
* @since 2025-07-21
*/
@Schema(description = "工程安全知识库类型")
@Data
@TableName("public.project_safety_type")
public class ProjectSafetyType {
@TableId(value = "id", type = IdType.AUTO)
@Schema(description = "主键")
@NotNull(message = "id不能为空", groups = {Update.class})
private Integer id;
@TableField(value = "name")
@Schema(description = "类型名称")
private String name;
}

View File

@ -0,0 +1,22 @@
package com.gunshi.project.ss.repository;
import com.gunshi.project.ss.entity.es.EsObjectDocument;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;
public interface TsgObjectRepository extends ElasticsearchRepository<EsObjectDocument, String> {
@Query("{\"wildcard\": {\"name\": {\"value\": \"*?0*\", \"case_insensitive\": true}}}")
List<EsObjectDocument> findByName(String name, Sort sort);
List<EsObjectDocument> findByType(String type);
EsObjectDocument findByUnionCodeAndType(String unionCode, String type);
}

View File

@ -0,0 +1,92 @@
package com.gunshi.project.ss.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gunshi.project.ss.entity.dto.BusinessRuleDto;
import com.gunshi.project.ss.mapper.BusinessRuleMapper;
import com.gunshi.project.ss.model.BusinessRule;
import com.gunshi.project.ss.model.FileAssociations;
import com.gunshi.project.ss.repository.TsgObjectRepository;
import com.gunshi.project.ss.util.EsCacheUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author lyf
* @since 2025-07-21
*/
@Service
public class BusinessRuleService extends ServiceImpl<BusinessRuleMapper, BusinessRule> {
@Autowired
private TsgObjectRepository tsgObjectRepository;
@Autowired
private FileAssociationsService fileAssociationsService;
public Page<BusinessRule> page(BusinessRuleDto dto) {
QueryWrapper<BusinessRule> queryWrapper = new QueryWrapper<>();
if(dto.getStm() !=null && dto.getEtm() !=null){
queryWrapper.between("tm", dto.getStm(), dto.getEtm());
}
if (dto.getName() != null) {
queryWrapper.like("name", dto.getName());
}
if (dto.getType() != null) {
queryWrapper.eq("type", dto.getType());
}
if(dto.getStatus() != null) {
queryWrapper.eq("status", dto.getStatus());
}
int pageNumber = dto.getPageSo().getPageNumber();
int pageSize = dto.getPageSo().getPageSize();
queryWrapper.orderByDesc("_update_tm");
Page<BusinessRule> pageParam = new Page<>(pageNumber, pageSize);
Page<BusinessRule> ret = page(pageParam, queryWrapper);
return ret;
}
public BusinessRule getOneById(Serializable id) {
BusinessRule businessRule = baseMapper.selectById(id);
if(businessRule != null) {
List<FileAssociations> files = fileAssociationsService.getFiles("businessRule", businessRule.getId().toString());
if(files == null){
businessRule.setFiles(new ArrayList<>());
businessRule.setFileCount(0);
}else{
businessRule.setFileCount(files.size());
businessRule.setFiles(files);
}
}
return businessRule;
}
public void updateEsCache(BusinessRule businessRule) {
EsCacheUtil.updateCache(tsgObjectRepository,
businessRule,
"业务规则库",
BusinessRule::getId,
BusinessRule::getName,
null,
null,
null
);
}
public void deleteEsCache(Serializable id) {
EsCacheUtil.deleteEsCache(tsgObjectRepository,id.toString(),"业务规则库");
}
public void add(BusinessRule entity) {
entity.setId(IdWorker.getId());
entity.setUpdateTm(new Date());
save(entity);
}
}

View File

@ -0,0 +1,95 @@
package com.gunshi.project.ss.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gunshi.db.dto.PageSo;
import com.gunshi.project.ss.entity.dto.DispatchSchemeDto;
import com.gunshi.project.ss.mapper.DispatchSchemeMapper;
import com.gunshi.project.ss.model.DispatchScheme;
import com.gunshi.project.ss.model.FileAssociations;
import com.gunshi.project.ss.repository.TsgObjectRepository;
import com.gunshi.project.ss.util.EsCacheUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author lyf
* @since 2025-07-21
*/
@Service
public class DispatchSchemeService extends ServiceImpl<DispatchSchemeMapper, DispatchScheme> {
@Autowired
private TsgObjectRepository tsgObjectRepository;
@Autowired
private FileAssociationsService fileAssociationsService;
public Page<DispatchScheme> page(DispatchSchemeDto dto) {
QueryWrapper<DispatchScheme> queryWrapper = new QueryWrapper<>();
if(dto.getStm() !=null && dto.getEtm() !=null){
queryWrapper.between("tm", dto.getStm(), dto.getEtm());
}
if (dto.getName() != null) {
queryWrapper.like("name", dto.getName());
}
if (dto.getType() != null) {
queryWrapper.eq("type", dto.getType());
}
if(dto.getStatus() != null){
queryWrapper.eq("status", dto.getStatus());
}
PageSo pageSo = dto.getPageSo();
int pageNumber = pageSo.getPageNumber();
int pageSize = pageSo.getPageSize();
queryWrapper.orderByDesc("_update_tm");
Page<DispatchScheme> pageParam = new Page<>(pageNumber, pageSize);
Page<DispatchScheme> ret = page(pageParam, queryWrapper);
return ret;
}
public DispatchScheme getOneById(Serializable id) {
DispatchScheme dispatchScheme = baseMapper.selectById(id);
if(dispatchScheme != null){
List<FileAssociations> files = fileAssociationsService.getFiles("dispatchScheme", dispatchScheme.getId().toString());
if(files == null){
dispatchScheme.setFiles(new ArrayList<>());
dispatchScheme.setFileCount(0);
}else{
dispatchScheme.setFileCount(files.size());
dispatchScheme.setFiles(files);
}
}
return dispatchScheme;
}
public void updateEsCache(DispatchScheme dispatchScheme) {
EsCacheUtil.updateCache(tsgObjectRepository,
dispatchScheme,
"调度方案库",
DispatchScheme::getId,
DispatchScheme::getName,
null,
null,
null
);
}
public void deleteEsCache(Serializable id) {
EsCacheUtil.deleteEsCache(tsgObjectRepository,id.toString(),"调度方案库");
}
public void add(DispatchScheme entity) {
entity.setId(IdWorker.getId());
entity.setUpdateTm(new Date());
save(entity);
}
}

View File

@ -5,12 +5,16 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gunshi.db.dto.DateTimeRangeSo;
import com.gunshi.project.ss.common.util.LocalDateTimeConverter;
import com.gunshi.project.ss.entity.so.DocCenterPageSo; import com.gunshi.project.ss.entity.so.DocCenterPageSo;
import com.gunshi.project.ss.mapper.DocCenterMapper; import com.gunshi.project.ss.mapper.DocCenterMapper;
import com.gunshi.project.ss.model.DocCategory; import com.gunshi.project.ss.model.DocCategory;
import com.gunshi.project.ss.model.DocCenter; import com.gunshi.project.ss.model.DocCenter;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.mapper.SysUserMapper; import com.ruoyi.system.mapper.SysUserMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -19,8 +23,8 @@ import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.*;
import java.util.List; import java.util.stream.Collectors;
@Service @Service
@Slf4j @Slf4j
@ -33,6 +37,9 @@ public class DocCenterService extends ServiceImpl<DocCenterMapper, DocCenter> {
@Autowired @Autowired
private SysUserMapper sysUserMapper; private SysUserMapper sysUserMapper;
@Autowired
private SysDeptMapper sysDeptMapper;
@Autowired @Autowired
private DocOperateLogService docOperateLogService; private DocOperateLogService docOperateLogService;
@ -180,4 +187,148 @@ public class DocCenterService extends ServiceImpl<DocCenterMapper, DocCenter> {
docOperateLogService.saveLog(docCenter,2); docOperateLogService.saveLog(docCenter,2);
return flag; return flag;
} }
public Map<String, Long> groupByType(DateTimeRangeSo dateTimeRangeSo) {
Map<String, Long> res = new HashMap<>();
List<DocCenter> list = lambdaQuery()
.ge(DocCenter::getCreateTime, dateTimeRangeSo.getStart())
.le(DocCenter::getCreateTime, dateTimeRangeSo.getEnd()).list();
//获取去重的所有资料分类ID
List<Long> categoryIds = list.stream().distinct().map(o -> {
return o.getDocCategoryId();
}).collect(Collectors.toList());
List<DocCategory> level3Category = docCategoryService.lambdaQuery().in(DocCategory::getId, categoryIds).list();
for (DocCategory docCategory : level3Category) {
long count = list.stream().filter(o -> {
return docCategory.getId().equals(o.getDocCategoryId());
}).count();
res.put(docCategory.getCategoryName(),count);
}
return res;
}
public Map<String, Long> groupByDept(DateTimeRangeSo dateTimeRangeSo) {
List<DocCenter> list = lambdaQuery()
.ge(DocCenter::getCreateTime, dateTimeRangeSo.getStart())
.le(DocCenter::getCreateTime, dateTimeRangeSo.getEnd()).list();
// 按用户ID分组再转换到部门
return list.stream()
.filter(doc -> doc.getUserId() != null)
.collect(Collectors.groupingBy(
DocCenter::getUserId, // 先按用户分组
Collectors.counting() // 统计每个用户的文档数
))
.entrySet().stream()
.collect(Collectors.toMap(
entry -> {
// 根据用户ID获取部门名称
Long userId = entry.getKey();
Long userDocCount = entry.getValue();
SysUser user = sysUserMapper.selectUserById(userId);
if (user == null || user.getDeptId() == null) {
return "未知部门";
}
SysDept dept = sysDeptMapper.selectDeptById(user.getDeptId());
return dept != null ? dept.getDeptName() : "未知部门";
},
Map.Entry::getValue, // 文档数量
Long::sum // 相同部门合并
));
}
public Map<String, Long> groupBySecret(DateTimeRangeSo dateTimeRangeSo) {
Map<String, Long> res = new HashMap<>();
List<DocCenter> list = lambdaQuery()
.ge(DocCenter::getCreateTime, dateTimeRangeSo.getStart())
.le(DocCenter::getCreateTime, dateTimeRangeSo.getEnd()).list();
List<Integer> secretLevel = list.stream().distinct().map(o -> {
return o.getSecretLevel();
}).collect(Collectors.toList());
for (Integer level : secretLevel) {
long count = list.stream().filter(o -> o.getSecretLevel().equals(level)).count();
if(level == 0){
res.put("公开",count);
}else if(level == 1){
res.put("秘密",count);
}else if(level == 2){
res.put("机密",count);
}
}
return res;
}
public Map<String, Long> groupByVersion(DateTimeRangeSo dateTimeRangeSo) {
List<DocCenter> list = lambdaQuery()
.ge(DocCenter::getCreateTime, dateTimeRangeSo.getStart())
.le(DocCenter::getCreateTime, dateTimeRangeSo.getEnd())
.list();
return list.stream()
.filter(doc -> doc.getDocVersion() != null) // 过滤null值
.collect(Collectors.groupingBy(
doc -> doc.getDocVersion().toString(), // 转为String作为key
Collectors.counting()
));
}
public Map<String, Long> groupByTm(DateTimeRangeSo dateTimeRangeSo) {
// 1. 查询数据
List<DocCenter> list = lambdaQuery()
.ge(DocCenter::getCreateTime, dateTimeRangeSo.getStart())
.le(DocCenter::getCreateTime, dateTimeRangeSo.getEnd())
.list();
// 2. 按年月分组统计
Map<String, Long> grouped = list.stream()
.collect(Collectors.groupingBy(
doc -> {
LocalDateTime createTime = doc.getCreateTime();
// 格式化为年月2025-11
return String.format("%d-%02d",
createTime.getYear(),
createTime.getMonthValue());
},
Collectors.counting()
));
// 3. 补全缺失的月份
return fillMissingMonths(grouped, dateTimeRangeSo.getStart(),dateTimeRangeSo.getEnd());
}
/**
*
*/
private Map<String, Long> fillMissingMonths(Map<String, Long> grouped, Date startDate, Date endDate) {
Map<String, Long> result = new LinkedHashMap<>(); // 保持插入顺序
// 将Date转换为LocalDateTime
LocalDateTime start = LocalDateTimeConverter.fromDate(startDate);
LocalDateTime end = LocalDateTimeConverter.fromDate(endDate);
// 调整到每月的第一天
LocalDateTime current = start.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
LocalDateTime lastMonth = end.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
// 遍历每个月份
while (!current.isAfter(lastMonth)) {
String monthKey = String.format("%d-%02d",
current.getYear(),
current.getMonthValue());
// 如果有数据则取数据否则为0
result.put(monthKey, grouped.getOrDefault(monthKey, 0L));
// 下一个月
current = current.plusMonths(1);
}
return result;
}
} }

View File

@ -1,11 +1,14 @@
package com.gunshi.project.ss.service; package com.gunshi.project.ss.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gunshi.project.ss.common.util.LocalDateTimeConverter;
import com.gunshi.project.ss.entity.TimeCapacity;
import com.gunshi.project.ss.entity.TimeNetWater;
import com.gunshi.project.ss.entity.vo.ForecastResultVo; import com.gunshi.project.ss.entity.vo.ForecastResultVo;
import com.gunshi.project.ss.mapper.ForecastProjectMapper; import com.gunshi.project.ss.mapper.ForecastProjectMapper;
import com.gunshi.project.ss.model.ForecastProject; import com.gunshi.project.ss.model.*;
import com.gunshi.project.ss.model.ForecastResults;
import com.itextpdf.io.font.PdfEncodings; import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.colors.DeviceRgb; import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.events.Event; import com.itextpdf.kernel.events.Event;
@ -36,9 +39,12 @@ import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.time.LocalDateTime;
import java.util.Date; import java.time.format.DateTimeFormatter;
import java.util.List; import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
/** /**
@ -57,6 +63,12 @@ public class ForecastProjectService extends ServiceImpl<ForecastProjectMapper, F
@Autowired @Autowired
private ForecastResultsService forecastResultsService; private ForecastResultsService forecastResultsService;
@Autowired
private StZvarlBService stZvarlBService;
@Autowired
private ForecastUseparamService forecastUseparamService;
/** /**
* @description: * @description:
* @param forecastProject * @param forecastProject
@ -155,6 +167,888 @@ public class ForecastProjectService extends ServiceImpl<ForecastProjectMapper, F
} }
} }
public List<ForecastDispatchCommand> caculate(String rz) {
BigDecimal openDoorFlow = new BigDecimal(5);//开闸门放水流量 5立方米/秒
ForecastTask forecastTask = new ForecastTask();
// 设置当前时间整点
LocalDateTime now = LocalDateTime.now();
LocalDateTime nowHour = now.withMinute(0).withSecond(0).withNano(0);
forecastTask.setNowTime(LocalDateTimeConverter.toDate(nowHour));
// 设置开始时间(当前时间减去一天)
LocalDateTime startTime = nowHour.minusDays(1);
forecastTask.setStartTime(LocalDateTimeConverter.toDate(startTime));
// 设置结束时间当前时间加上durationHours
LocalDateTime endTime = nowHour.plusHours(24);
forecastTask.setEndTime(LocalDateTimeConverter.toDate(endTime));
forecastTask.setForecastWarm(1);
forecastTask.setForecastPeriod(24); // 设置预报时长
List<ForecastResultVo> humanForecastResult = forecastResultsService.getHumanForecastResult(forecastTask);
if(humanForecastResult.isEmpty()){
throw new IllegalArgumentException("对不起,暂无预报数据");
}
//过滤出大于等于nowHour的数据
// 获取当前时间的格式化字符串与tm格式一致
String nowHourStr = nowHour.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
// 过滤出大于等于当前时间的数据(数据已按时间tm 从小到大排序)
List<ForecastResultVo> filteredResults = humanForecastResult.stream()
.filter(vo -> {
if (vo.getTm() == null || vo.getTm().isEmpty()) {
return false;
}
// 字符串比较(因为格式相同,可以直接比较)
return vo.getTm().compareTo(nowHourStr) >= 0;
})
.collect(Collectors.toList());
// filteredResults.stream().forEach(o ->{
// o.setYcRkQValue(new BigDecimal("10"));
// o.setYcCkQValue(new BigDecimal("0"));
// });
ForecastResultVo forecastResultVo = filteredResults.get(0);//a点
//b点为filteredResults的最后一条数据
//c点为waterLevel
BigDecimal waterLevel = new BigDecimal(rz);//c点
LocalDateTime start = null;
LocalDateTime end = null;
List<StZvarlB> stZvarlBList = stZvarlBService.list();
// 获取配置参数
List<ForecastUseparam> paramList = forecastUseparamService.list(new QueryWrapper<ForecastUseparam>().isNotNull("param_code").isNotNull("param_value"));
if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(paramList)) {
throw new IllegalArgumentException("温馨提示:当前洪水预报所依赖的数据尚不完整,请检查入参是否缺失。");
}
Map<String, String> paramMap = paramList.stream().collect(Collectors.toMap(ForecastUseparam::getParamCode, ForecastUseparam::getParamValue, (existing, replacement) -> existing));
if (paramMap.get("dt").isEmpty()) {
throw new IllegalArgumentException("温馨提示当前洪水预报所依赖的数据尚不完整请检查时间单元△T是否缺失。");
}
double dt = Double.parseDouble(paramMap.get("dt"));
BigDecimal timeInterval;
if(dt == 0.5){
timeInterval = new BigDecimal("1800");
}else{
timeInterval = new BigDecimal("3600");
}
if(forecastResultVo.getYcSwHValue().compareTo(waterLevel) > 0){
//如果实际水位已经大于了输入的水位的话,那么闸门开门时间就设置为当前时间
start = nowHour;//
//计算闸门关门时间
//计算a点库容
//库容单位 万m³
BigDecimal aKR = stZvarlBService.getWByZvarl(stZvarlBList,forecastResultVo.getYcSwHValue());
//计算c点库容
//库容单位 万m³
BigDecimal cKR = stZvarlBService.getWByZvarl(stZvarlBList,waterLevel);
//计算a库容 - c库容
//库容单位 万m³
BigDecimal aSubC = aKR.subtract(cKR);//此时库容为正
// 存储每个时间点的库容
List<TimeCapacity> timeCapacities = new ArrayList<>();
// a点的库容就是起始库容
BigDecimal currentCapacity = aKR;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime currentTime = LocalDateTime.parse(forecastResultVo.getTm(), formatter);
timeCapacities.add(new TimeCapacity(currentTime, currentCapacity));
// 从a点开始往后依次计算各时段末水库库容
for (int i = 0; i < filteredResults.size() - 1; i++) {
ForecastResultVo currentVo = filteredResults.get(i);
ForecastResultVo nextVo = filteredResults.get(i + 1);
// 获取预测入库流量和预测出库流量
BigDecimal ycRkQValue = currentVo.getYcRkQValue() != null ? currentVo.getYcRkQValue() : BigDecimal.ZERO;
BigDecimal ycCkQValue = currentVo.getYcCkQValue() != null ? currentVo.getYcCkQValue() : BigDecimal.ZERO;
// 计算公式Vt+1 = Vt + (预测入库流量 - 预测出库流量 - 5) * 时间间隔
// 注意单位转换流量是m³/s库容是万m³时间间隔是秒
BigDecimal flowDiff = ycRkQValue.subtract(ycCkQValue).subtract(openDoorFlow); // m³/s
BigDecimal volumeChange = flowDiff.multiply(timeInterval); // m³
// 转换为万m³1万m³ = 10000 m³
BigDecimal volumeChangeInTenThousand = volumeChange.divide(new BigDecimal(10000), 10, BigDecimal.ROUND_HALF_UP);
// 计算下一时段库容(从当前库容开始计算)
BigDecimal nextCapacity = currentCapacity.add(volumeChangeInTenThousand);
// 获取下一时间点
LocalDateTime nextTime = LocalDateTime.parse(nextVo.getTm(), formatter);
// 存储时间点和对应的库容
timeCapacities.add(new TimeCapacity(nextTime, nextCapacity));
// 为下一次循环更新当前库容
currentCapacity = nextCapacity;
}
// 找到【库容最后一次(前一整点库容>c对应的库容)≤c对应的库容】所对应的时间整点d
LocalDateTime dTime = null;
// 从后往前找要求找到一个时间点要求这个时间点前面第一个的库容要大于C对应库容
// 这个时间点之后的第一个时间点的库容要小于C点对应库容
for (int i = timeCapacities.size() - 1; i > 0; i--) {
TimeCapacity current = timeCapacities.get(i);
TimeCapacity previous = timeCapacities.get(i - 1);
// 检查条件:当前库容 ≤ c库容 且 前一库容 > c库容
if (current.getCapacity().compareTo(cKR) <= 0 &&
previous.getCapacity().compareTo(cKR) > 0) {
dTime = current.getTime();
break;
}
}
if(dTime == null){
//如果a~b之间不存在d点,则闸门关闭时间 = a时间点 + [(a~b之间净入库水量) + aSubC] /5先精确时分秒向上取整再精确到时分
//计算净入库水量
BigDecimal pureRKWater = BigDecimal.ZERO;//净入库水量
for(int i =0;i<filteredResults.size()-1;i++){
ForecastResultVo forecastResult = filteredResults.get(i);
BigDecimal ycRkQValue = forecastResult.getYcRkQValue() == null? BigDecimal.ZERO:forecastResult.getYcRkQValue();
BigDecimal ycCkQValue = forecastResult.getYcCkQValue() == null? BigDecimal.ZERO:forecastResult.getYcCkQValue();
BigDecimal gapQValue = ycRkQValue.subtract(ycCkQValue);
BigDecimal timeSum = gapQValue.multiply(timeInterval);
pureRKWater = pureRKWater.add(timeSum);
}
// aSubC是万m³需要转换为m³
BigDecimal aSubCInM3 = aSubC.multiply(new BigDecimal("10000")); // 转换为m³
// 计算公式:[(a~b之间净入库水量) + aSubC] / 5
// pureRKWater单位已经是m³因为timeInterval是秒流量是m³/s
BigDecimal totalWater = pureRKWater.add(aSubCInM3); // 总水量 = 净入库水量 + aSubC转换后的水量
// 除以5开闸门放水流量5立方米/秒)
BigDecimal timeSeconds = totalWater.divide(openDoorFlow, 10, BigDecimal.ROUND_HALF_UP);
// 先精确时分秒,向上取整
long timeSecondsLong = timeSeconds.setScale(0, BigDecimal.ROUND_UP).longValue();
// 计算闸门关闭时间 = a时间点 + 计算出的时间
LocalDateTime aTime = LocalDateTime.parse(forecastResultVo.getTm(), formatter);
LocalDateTime closeTime = aTime.plusSeconds(timeSecondsLong);
// 如果有秒数或者分钟数有小数部分即秒数不为0则分钟向上取整
if (closeTime.getSecond() > 0) {
// 分钟加1
closeTime = closeTime.plusMinutes(1);
}
// 再精确到时分分钟和秒设为0
closeTime = closeTime.withSecond(0).withNano(0);
end = closeTime;
}else{
/**
* d
* d<=ced(pse
* c - d ) / d-1 + 5 - d-1
* e~bf f-*
* eg = f/5 =e+g
*/
// 1. 找到d点在filteredResults中的索引
int dIndex = -1;
for (int i = 0; i < filteredResults.size(); i++) {
if (filteredResults.get(i).getTm().equals(dTime.format(formatter))) {
dIndex = i;
break;
}
}
// 获取d-1点的数据
ForecastResultVo dMinus1Vo = filteredResults.get(dIndex - 1);
// 获取d点的库容从timeCapacities中查找
BigDecimal dCapacity = null;
for (TimeCapacity tc : timeCapacities) {
if (tc.getTime().equals(dTime)) {
dCapacity = tc.getCapacity();
break;
}
}
// 计算c水位值对应的库容 - d点库容
BigDecimal capacityDiff = cKR.subtract(dCapacity); // 万m³
BigDecimal capacityDiffInM3 = capacityDiff.multiply(new BigDecimal("10000")); // 转换为m³
// 获取d-1点的入库流量和出库流量
BigDecimal dMinus1RkQ = dMinus1Vo.getYcRkQValue() != null ? dMinus1Vo.getYcRkQValue() : BigDecimal.ZERO;
BigDecimal dMinus1CkQ = dMinus1Vo.getYcCkQValue() != null ? dMinus1Vo.getYcCkQValue() : BigDecimal.ZERO;
// 计算d-1的出库流量 + 5 - d-1的入库流量
BigDecimal flowRateDiff = dMinus1CkQ.add(openDoorFlow).subtract(dMinus1RkQ); // m³/s
// 防止除数为0或负数
// if (flowRateDiff.compareTo(BigDecimal.ZERO) <= 0) {
// flowRateDiff = new BigDecimal("0.001"); // 设置一个很小的正数
// }
// 计算往前倒推的时长c水位值对应的库容 - d点库容) / d-1的出库流量 + 5 - d-1的入库流量
BigDecimal backwardSeconds = capacityDiffInM3.divide(flowRateDiff, 10, BigDecimal.ROUND_HALF_UP);
// 不进行四舍五入,若存在小数点则向下取整
long backwardSecondsLong = backwardSeconds.setScale(0, BigDecimal.ROUND_DOWN).longValue();
// 计算e点时间 = d点时间 - 倒推时长
LocalDateTime eTime = dTime.minusSeconds(backwardSecondsLong);
// 检查e点是否在filteredResults集合中存在
boolean eTimeExists = false;
ForecastResultVo ePointVo = null;
for (ForecastResultVo vo : filteredResults) {
LocalDateTime voTime = LocalDateTime.parse(vo.getTm(), formatter);
if (voTime.equals(eTime)) {
eTimeExists = true;
ePointVo = vo;
break;
}
}
// 精确到时分秒设为0
eTime = eTime.withSecond(0).withNano(0);
// 2. 计算e~b之间的净入库水量f
BigDecimal f = BigDecimal.ZERO;
// 找到e点在filteredResults中的索引
int eIndex = -1;
for (int i = 0; i < filteredResults.size(); i++) {
LocalDateTime voTime = LocalDateTime.parse(filteredResults.get(i).getTm(), formatter);
if (voTime.equals(eTime) || voTime.isBefore(eTime)) { // e点或之后的时间
eIndex = i;
}else{
break;
}
}
if (eIndex == -1) {
eIndex = 0; // 如果没找到,从第一个开始
}
// 计算e~b之间的净入库水量
for (int i = eIndex; i < filteredResults.size() - 1; i++) {
ForecastResultVo currentVo = filteredResults.get(i);
BigDecimal ycRkQValue = currentVo.getYcRkQValue() != null ? currentVo.getYcRkQValue() : BigDecimal.ZERO;
BigDecimal ycCkQValue = currentVo.getYcCkQValue() != null ? currentVo.getYcCkQValue() : BigDecimal.ZERO;
// (入库流量 - 出库流量) * 时间间隔
BigDecimal gapQValue = ycRkQValue.subtract(ycCkQValue);
if (i == eIndex) {
// 对于eIndex处的数据使用eTime与下一条数据的时间间隔
ForecastResultVo nextVo = filteredResults.get(i + 1);
LocalDateTime nextTime = LocalDateTime.parse(nextVo.getTm(), formatter);
// 计算eTime到nextTime的时间差小时
long minutesDiff = ChronoUnit.MINUTES.between(eTime, nextTime);
BigDecimal currentTimeInterval = BigDecimal.valueOf(minutesDiff).divide(BigDecimal.valueOf(60), 10, RoundingMode.HALF_UP);
BigDecimal timeSum = gapQValue.multiply(currentTimeInterval);
f = f.add(timeSum);
} else {
// 其他情况使用固定的timeInterval
BigDecimal timeSum = gapQValue.multiply(timeInterval);
f = f.add(timeSum);
}
}
// 3. 计算持续开闸时长g = f / 5
BigDecimal gSeconds = f.divide(openDoorFlow, 10, BigDecimal.ROUND_HALF_UP);
// 不进行四舍五入,若存在小数点则向下取整
long gSecondsLong = gSeconds.setScale(0, BigDecimal.ROUND_DOWN).longValue();
// 4. 计算闸门关闭时间 = e + g
LocalDateTime closeTime = eTime.plusSeconds(gSecondsLong);
// 如果有秒数或者分钟数有小数部分即秒数不为0则分钟向上取整
if (closeTime.getSecond() > 0) {
// 分钟加1
closeTime = closeTime.plusMinutes(1);
}
closeTime = closeTime.withSecond(0).withNano(0);
end = closeTime;
}
}else{
//若a<=c 则判断 a点水位对应库容 + a点 ~t点的净入库量c水位对应库容之间的大小关系 t再a~b之间任意一点包括a b
//1 若任意a点水位对应库容 + a点~t点的净入库量均<=c点对应的库容(这里对预测数据进行遍历 一条一条对比 不是累加和的对比),则不开闸
// 计算a点库容
BigDecimal aKR = stZvarlBService.getWByZvarl(stZvarlBList, forecastResultVo.getYcSwHValue());
// 计算c点库容
BigDecimal cKR = stZvarlBService.getWByZvarl(stZvarlBList, waterLevel);
boolean needToOpenGate = false; // 是否需要开闸的标志
// 遍历filteredResults中的每个点从a点到b点
for (int i = 0; i < filteredResults.size(); i++) {
// 计算从a点到当前点t的累计净入库量
BigDecimal netInflow = BigDecimal.ZERO;
// 注意这里需要累加从a点到当前点t-1的净入库量
for (int j = 0; j < i; j++) {
ForecastResultVo currentVo = filteredResults.get(j);
BigDecimal ycRkQValue = currentVo.getYcRkQValue() != null ? currentVo.getYcRkQValue() : BigDecimal.ZERO;
BigDecimal ycCkQValue = currentVo.getYcCkQValue() != null ? currentVo.getYcCkQValue() : BigDecimal.ZERO;
// (入库流量 - 出库流量) * 时间间隔
BigDecimal gapQValue = ycRkQValue.subtract(ycCkQValue).subtract(openDoorFlow);
BigDecimal timeSum = gapQValue.multiply(timeInterval);
netInflow = netInflow.add(timeSum);
}
// 计算a点水位对应库容 + a点~t点的净入库量
// 注意单位转换aKR是万m³netInflow是m³需要统一单位
BigDecimal netInflowInTenThousand = netInflow.divide(new BigDecimal(10000), 10, BigDecimal.ROUND_HALF_UP);
BigDecimal totalCapacityAtT = aKR.add(netInflowInTenThousand);
// 判断:如果任意一个时间点的总库容 > c点对应的库容则需要开闸
if (totalCapacityAtT.compareTo(cKR) > 0) {
needToOpenGate = true;
break; // 只要有一个点超过c点库容就需要开闸退出循环
}
}
if(needToOpenGate){
//表示要开闸
/**
* a~bt+1 = t +-*
*/
// 存储每个时间点的库容
List<TimeCapacity> timeCapacities = new ArrayList<>();
// a点的库容就是起始库容
BigDecimal currentCapacity = aKR;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime currentTime = LocalDateTime.parse(forecastResultVo.getTm(), formatter);
timeCapacities.add(new TimeCapacity(currentTime, currentCapacity));
// 从a点开始往后依次计算各时段末水库库容
for (int i = 0; i < filteredResults.size() - 1; i++) {
ForecastResultVo currentVo = filteredResults.get(i);
ForecastResultVo nextVo = filteredResults.get(i + 1);
// 获取预测入库流量和预测出库流量
BigDecimal ycRkQValue = currentVo.getYcRkQValue() != null ? currentVo.getYcRkQValue() : BigDecimal.ZERO;
BigDecimal ycCkQValue = currentVo.getYcCkQValue() != null ? currentVo.getYcCkQValue() : BigDecimal.ZERO;
// 计算公式Vt+1 = Vt + (预测入库流量 - 预测出库流量 - 5) * 时间间隔
// 注意单位转换流量是m³/s库容是万m³时间间隔是秒
BigDecimal flowDiff = ycRkQValue.subtract(ycCkQValue).subtract(openDoorFlow); // m³/s
BigDecimal volumeChange = flowDiff.multiply(timeInterval); // m³
// 转换为万m³1万m³ = 10000 m³
BigDecimal volumeChangeInTenThousand = volumeChange.divide(new BigDecimal(10000), 10, BigDecimal.ROUND_HALF_UP);
// 计算下一时段库容(从当前库容开始计算)
BigDecimal nextCapacity = currentCapacity.add(volumeChangeInTenThousand);
// 获取下一时间点
LocalDateTime nextTime = LocalDateTime.parse(nextVo.getTm(), formatter);
// 存储时间点和对应的库容
timeCapacities.add(new TimeCapacity(nextTime, nextCapacity));
// 为下一次循环更新当前库容
currentCapacity = nextCapacity;
}
//遍历从a点往后找第一次最接近于控制水位c的库容的时间整点t这里意味着t往后的一个整点时刻对应的水库库容>c水位对应库容
// 然后计算t0为刚好=c的时分点则按t0前的第一个整点时刻t往后计算出t0【计算所得的t~t0之间的持续时长其值不要四舍五入向下取整精确至时分】
LocalDateTime tTime = null;
int tIndex = -1;
//找到最接近于c点库容的整点时间位
for (int i = 0; i < timeCapacities.size(); i++) {
TimeCapacity currentTc = timeCapacities.get(i);
if (i < timeCapacities.size() - 1) {
TimeCapacity nextTc = timeCapacities.get(i + 1);
if (nextTc.getCapacity().compareTo(cKR) > 0) {
tTime = currentTc.getTime();
tIndex = i;
break;
}
}
}
if(tTime != null){
//计算t0
BigDecimal tCapacity = timeCapacities.get(tIndex).getCapacity();
BigDecimal capacityDiff = cKR.subtract(tCapacity); // 万m³
BigDecimal capacityDiffInM3 = capacityDiff.multiply(new BigDecimal("10000"));
// 找到t点的预测数据
ForecastResultVo tVo = null;
for (ForecastResultVo vo : filteredResults) {
LocalDateTime voTime = LocalDateTime.parse(vo.getTm(), formatter);
if (voTime.equals(tTime)) {
tVo = vo;
break;
}
}
if (tVo != null) {
BigDecimal tRkQ = tVo.getYcRkQValue() != null ? tVo.getYcRkQValue() : BigDecimal.ZERO;
BigDecimal tCkQ = tVo.getYcCkQValue() != null ? tVo.getYcCkQValue() : BigDecimal.ZERO;
// 计算流量差
BigDecimal flowRateDiff = tRkQ.subtract(tCkQ).subtract(openDoorFlow);
// 计算t到t0的持续时长
BigDecimal durationSeconds = capacityDiffInM3.divide(flowRateDiff, 10, BigDecimal.ROUND_HALF_UP);
long durationSecondsLong = durationSeconds.setScale(0, BigDecimal.ROUND_DOWN).longValue();
// 计算t0时间
LocalDateTime t0Time = tTime.plusSeconds(durationSecondsLong);
t0Time = t0Time.withSecond(0).withNano(0);
// 设置闸门开启时间
start = t0Time;
}
}
//假设t0为开闸时间
if(start != null){
//计算t0 ~X的累计净水量x为t0~b之间任意一点若任意t0~x之间的累计进水量均<=0那么t0为开闸时间假设成立
boolean t0Valid = true;
// 找到t0时间前面第一个时间整点t点
LocalDateTime t0PreTime = null;
// 从filteredResults中找到时间小于start的第一个时间点
for (int i = filteredResults.size() - 1; i >= 0; i--) {
LocalDateTime voTime = LocalDateTime.parse(filteredResults.get(i).getTm(), formatter);
if (voTime.isBefore(start)) {
t0PreTime = voTime;
break;
}
}
if (t0PreTime != null) {
// 计算从t0点到每个后续时间点的累计净水量
// 首先计算t0到第一个整点的时间间隔
java.time.Duration t0ToFirstInterval = java.time.Duration.between(start, tTime.plusSeconds(timeInterval.longValue()));
long t0ToFirstSeconds = t0ToFirstInterval.getSeconds();
// 获取t点的入库和出库流量
ForecastResultVo tVo = filteredResults.get(tIndex);
BigDecimal tRkQ = tVo.getYcRkQValue() != null ? tVo.getYcRkQValue() : BigDecimal.ZERO;
BigDecimal tCkQ = tVo.getYcCkQValue() != null ? tVo.getYcCkQValue() : BigDecimal.ZERO;
// 计算t0到第一个整点的净水量
BigDecimal gapQValueT0 = tRkQ.subtract(tCkQ).subtract(openDoorFlow);
BigDecimal t0ToFirstNetWater = gapQValueT0.multiply(new BigDecimal(t0ToFirstSeconds));
// 检查t0到第一个整点的净水量是否>0
if (t0ToFirstNetWater.compareTo(BigDecimal.ZERO) > 0) {
t0Valid = false;
}
// 如果t0到第一个整点的净水量<=0继续检查后续时间段
if (t0Valid) {
// 从tIndex+1开始检查后续时间段
for (int i = tIndex + 1; i < filteredResults.size() - 1; i++) {
ForecastResultVo currentVo = filteredResults.get(i);
BigDecimal ycRkQValue = currentVo.getYcRkQValue() != null ? currentVo.getYcRkQValue() : BigDecimal.ZERO;
BigDecimal ycCkQValue = currentVo.getYcCkQValue() != null ? currentVo.getYcCkQValue() : BigDecimal.ZERO;
BigDecimal gapQValue = ycRkQValue.subtract(ycCkQValue).subtract(openDoorFlow);
BigDecimal timeSum = gapQValue.multiply(timeInterval);
if (timeSum.compareTo(BigDecimal.ZERO) > 0) {
t0Valid = false;
break;
}
}
}
}
if (!t0Valid) {
// 如果t0假设不成立
LocalDateTime t0Time = start;
start = null;
//那么t~b之间就至少存在一个点x使得t0~x之间的累计净水量此时考虑开闸 >0则对比找出t0~x之间的累计净水量考虑开闸最大值所对应的时间点x0
//可以得到t0~x0之间的累计净水量Vt~x0再用Vt~X0/5 得到t点之前需要提前开闸的时长dt精确至时分存在小数点向上取整最终得到实际开闸时间j=t0 - dt
//砸门关闭时间计算公式如下
/**
* j>=ax0 < b x0~bk x0~b-* (x0)x0L = K/5,X0+L
* j>=Ax0 = bb
*/
// 计算t0~x之间的累计净水量考虑开闸
// 找到t点在filteredResults中的索引
int tIndexInFilter = -1;
for (int i = 0; i < filteredResults.size(); i++) {
LocalDateTime voTime = LocalDateTime.parse(filteredResults.get(i).getTm(), formatter);
if (voTime.equals(tTime)) {
tIndexInFilter = i;
break;
}
}
// 存储每个时间点的累计净水量
List<TimeNetWater> timeNetWaters = new ArrayList<>();
BigDecimal maxNetWater = BigDecimal.ZERO;
LocalDateTime x0Time = null;
// 计算从t点到每个后续时间点的累计净水量
if (tIndexInFilter != -1) {
// 首先计算t0到第一个整点的净水量考虑开闸
// 获取t点的流量数据
ForecastResultVo tVo = filteredResults.get(tIndexInFilter);
BigDecimal tRkQ = tVo.getYcRkQValue() != null ? tVo.getYcRkQValue() : BigDecimal.ZERO;
BigDecimal tCkQ = tVo.getYcCkQValue() != null ? tVo.getYcCkQValue() : BigDecimal.ZERO;
// 计算t0到第一个整点的净水量考虑开闸入库-出库-5
BigDecimal gapQValueT0 = tRkQ.subtract(tCkQ).subtract(openDoorFlow);
// 找到t0后面第一个整点时间
LocalDateTime firstWholeHourAfterT = null;
for (int i = 0; i < filteredResults.size(); i++) {
LocalDateTime voTime = LocalDateTime.parse(filteredResults.get(i).getTm(), formatter);
if (voTime.isAfter(t0Time)) {
firstWholeHourAfterT = voTime;
break;
}
}
if (firstWholeHourAfterT != null) {
long t0ToFirstSeconds = java.time.Duration.between(t0Time, firstWholeHourAfterT).getSeconds();
BigDecimal t0ToFirstNetWater = gapQValueT0.multiply(new BigDecimal(t0ToFirstSeconds));
// 存储t0到第一个整点的累计净水量
timeNetWaters.add(new TimeNetWater(firstWholeHourAfterT, t0ToFirstNetWater));
if (t0ToFirstNetWater.compareTo(maxNetWater) > 0) {
maxNetWater = t0ToFirstNetWater;
x0Time = firstWholeHourAfterT;
}
// 继续计算后续时间段的累计净水量
BigDecimal currentNetWater = t0ToFirstNetWater;
// 找到第一个整点在filteredResults中的索引
int firstIndex = -1;
for (int i = 0; i < filteredResults.size(); i++) {
LocalDateTime voTime = LocalDateTime.parse(filteredResults.get(i).getTm(), formatter);
if (voTime.equals(firstWholeHourAfterT)) {
firstIndex = i;
break;
}
}
if (firstIndex != -1) {
for (int i = firstIndex; i < filteredResults.size() - 1; i++) {
ForecastResultVo currentVo = filteredResults.get(i);
BigDecimal ycRkQValue = currentVo.getYcRkQValue() != null ? currentVo.getYcRkQValue() : BigDecimal.ZERO;
BigDecimal ycCkQValue = currentVo.getYcCkQValue() != null ? currentVo.getYcCkQValue() : BigDecimal.ZERO;
// 考虑开闸:入库-出库-5
BigDecimal gapQValue = ycRkQValue.subtract(ycCkQValue).subtract(openDoorFlow);
BigDecimal timeSum = gapQValue.multiply(timeInterval);
currentNetWater = currentNetWater.add(timeSum);
// 存储当前时间点的累计净水量
LocalDateTime nextTime = LocalDateTime.parse(filteredResults.get(i + 1).getTm(), formatter);
timeNetWaters.add(new TimeNetWater(nextTime, currentNetWater));
if (currentNetWater.compareTo(maxNetWater) > 0) {
maxNetWater = currentNetWater;
x0Time = nextTime;
}
}
}
}
}
if (x0Time != null) {
// 计算需要提前开闸的时长dt = Vt~x0 / 5
BigDecimal dtSeconds = maxNetWater.divide(openDoorFlow, 10, BigDecimal.ROUND_HALF_UP);
// 向上取整
long dtSecondsLong = dtSeconds.setScale(0, BigDecimal.ROUND_UP).longValue();
// 计算实际开闸时间j = t0 - dt
LocalDateTime jTime = t0Time.minusSeconds(dtSecondsLong);
// 精确到时分
jTime = jTime.withSecond(0).withNano(0);
// 检查j是否>=a
LocalDateTime aTime = LocalDateTime.parse(forecastResultVo.getTm(), formatter);
if ((jTime.isAfter(aTime) || jTime.equals(aTime))) {
start = jTime;
// 判断x0与b的关系
LocalDateTime bTime = LocalDateTime.parse(filteredResults.get(filteredResults.size() - 1).getTm(), formatter);
if (x0Time.isBefore(bTime)) {
// 计算x0~b之间的净入库水量k不考虑开闸
BigDecimal k = BigDecimal.ZERO;
// 找到x0在filteredResults中的索引
int x0Index = -1;
for (int i = 0; i < filteredResults.size(); i++) {
LocalDateTime voTime = LocalDateTime.parse(filteredResults.get(i).getTm(), formatter);
if (voTime.equals(x0Time)) {
x0Index = i;
break;
}
}
if (x0Index != -1) {
// 计算x0到下一个整点的时间间隔
if (x0Index < filteredResults.size() - 1) {
LocalDateTime nextTime = LocalDateTime.parse(filteredResults.get(x0Index + 1).getTm(), formatter);
long x0ToNextSeconds = java.time.Duration.between(x0Time, nextTime).getSeconds();
// 获取x0点的流量数据
ForecastResultVo x0Vo = filteredResults.get(x0Index);
BigDecimal x0RkQ = x0Vo.getYcRkQValue() != null ? x0Vo.getYcRkQValue() : BigDecimal.ZERO;
BigDecimal x0CkQ = x0Vo.getYcCkQValue() != null ? x0Vo.getYcCkQValue() : BigDecimal.ZERO;
BigDecimal x0ToNextNet = x0RkQ.subtract(x0CkQ).multiply(new BigDecimal(x0ToNextSeconds));
k = k.add(x0ToNextNet);
// 计算后续时间段的净入库水量
for (int i = x0Index + 1; i < filteredResults.size() - 1; i++) {
ForecastResultVo currentVo = filteredResults.get(i);
BigDecimal ycRkQValue = currentVo.getYcRkQValue() != null ? currentVo.getYcRkQValue() : BigDecimal.ZERO;
BigDecimal ycCkQValue = currentVo.getYcCkQValue() != null ? currentVo.getYcCkQValue() : BigDecimal.ZERO;
BigDecimal gapQValue = ycRkQValue.subtract(ycCkQValue);
BigDecimal timeSum = gapQValue.multiply(timeInterval);
k = k.add(timeSum);
}
}
// 计算持续开闸时长L = k / 5
BigDecimal LSeconds = k.divide(openDoorFlow, 10, BigDecimal.ROUND_HALF_UP);
// 向上取整
long LSecondsLong = LSeconds.setScale(0, BigDecimal.ROUND_UP).longValue();
// 计算闸门关闭时间 = x0 + L
LocalDateTime closeTime = x0Time.plusSeconds(LSecondsLong);
// 如果有秒数或者分钟数有小数部分即秒数不为0则分钟向上取整
if (closeTime.getSecond() > 0) {
// 分钟加1
closeTime = closeTime.plusMinutes(1);
}
// 精确到时分
closeTime = closeTime.withSecond(0).withNano(0);
end = closeTime;
}
} else if (x0Time.equals(bTime)) {
// x0 = b闸门关闭时间为b
end = bTime;
}
}else{
//如果j < a 的情况下
start = aTime;
//计算a~b之间的净入库水量
BigDecimal pureRKWater = BigDecimal.ZERO;
for (int i = 0; i < filteredResults.size() -1 ; i++) {
ForecastResultVo vo = filteredResults.get(i);
BigDecimal ycRKQValue = vo.getYcRkQValue() == null?BigDecimal.ZERO:vo.getYcRkQValue();
BigDecimal ycCKQValue = vo.getYcCkQValue() == null?BigDecimal.ZERO:vo.getYcCkQValue();
BigDecimal gapWaterValue = ycRKQValue.subtract(ycCKQValue).multiply(timeInterval);
pureRKWater = pureRKWater.add(gapWaterValue);
}
BigDecimal openSeconds = pureRKWater.divide(openDoorFlow,10,RoundingMode.HALF_UP);
long openSecondsLong = openSeconds.setScale(0,RoundingMode.UP).longValue();
LocalDateTime closeTime = start.plusSeconds(openSecondsLong);
end = closeTime.withSecond(0).withNano(0);
}
}
}
else{
//如果t0假设成立计算闸门关闭时间
//计算t0~b之间的净入库水量h t0~b点之间各时段入库流量-出库流量)*时间间隔再计算出t-点往后的持续开闸时长i = h/5确定闸门关闭时间end=i+t0
BigDecimal h = BigDecimal.ZERO; // t0~b之间的净入库水量
// 找到t0后面第一个整点时间在filteredResults中查找
LocalDateTime firstWholeHourAfterT0 = null;
for (int i = 0; i < filteredResults.size(); i++) {
LocalDateTime voTime = LocalDateTime.parse(filteredResults.get(i).getTm(), formatter);
if (voTime.isAfter(start) || voTime.isEqual(start)) {
// 找第一个大于等于start的时间点
firstWholeHourAfterT0 = voTime;
break;
}
}
// 计算t0到第一个整点的净入库水量
// 获取t点的流量数据
ForecastResultVo tVo = filteredResults.get(tIndex);
BigDecimal tRkQ = tVo.getYcRkQValue() != null ? tVo.getYcRkQValue() : BigDecimal.ZERO;
BigDecimal tCkQ = tVo.getYcCkQValue() != null ? tVo.getYcCkQValue() : BigDecimal.ZERO;
// 计算t0到第一个整点的时间间隔
long t0ToFirstSeconds = java.time.Duration.between(start, firstWholeHourAfterT0).getSeconds();
BigDecimal t0ToFirstTime = new BigDecimal(t0ToFirstSeconds);
// 计算t0到第一个整点的净入库水量
BigDecimal t0ToFirstNet = tRkQ.subtract(tCkQ).multiply(t0ToFirstTime);
h = h.add(t0ToFirstNet);
// 找到第一个整点时间在filteredResults中的索引
int firstWholeHourIndex = -1;
for (int i = 0; i < filteredResults.size(); i++) {
LocalDateTime voTime = LocalDateTime.parse(filteredResults.get(i).getTm(), formatter);
if (voTime.equals(firstWholeHourAfterT0)) {
firstWholeHourIndex = i;
break;
}
}
// 如果找到了第一个整点,继续计算后续时间段的净入库水量
if (firstWholeHourIndex != -1) {
for (int i = firstWholeHourIndex; i < filteredResults.size() - 1; i++) {
ForecastResultVo currentVo = filteredResults.get(i);
BigDecimal ycRkQValue = currentVo.getYcRkQValue() != null ? currentVo.getYcRkQValue() : BigDecimal.ZERO;
BigDecimal ycCkQValue = currentVo.getYcCkQValue() != null ? currentVo.getYcCkQValue() : BigDecimal.ZERO;
BigDecimal gapQValue = ycRkQValue.subtract(ycCkQValue);
BigDecimal timeSum = gapQValue.multiply(timeInterval);
h = h.add(timeSum);
}
}
// 计算持续开闸时长i = h / 5
BigDecimal iSeconds = h.divide(openDoorFlow, 10, BigDecimal.ROUND_HALF_UP);
// 向上取整
long iSecondsLong = iSeconds.setScale(0, BigDecimal.ROUND_UP).longValue();
// 计算闸门关闭时间 = t0 + i
LocalDateTime closeTime = start.plusSeconds(iSecondsLong);
// 如果有秒数或者分钟数有小数部分即秒数不为0则分钟向上取整
if (closeTime.getSecond() > 0) {
// 分钟加1
closeTime = closeTime.plusMinutes(1);
}
// 精确到时分分钟和秒设为0
closeTime = closeTime.withSecond(0).withNano(0);
end = closeTime;
}
}
}
}
if(start == null || end == null){
return new ArrayList<>();
}
ForecastDispatchCommand open = new ForecastDispatchCommand();
open.setCommandTime(start);
open.setIrrigationGate(1);
open.setFloodGate(1);
ForecastDispatchCommand close = new ForecastDispatchCommand();
close.setCommandTime(end);
close.setIrrigationGate(0);
close.setFloodGate(0);
List<ForecastDispatchCommand> res = new ArrayList<>();
res.add(open);
res.add(close);
return res;
}
@Autowired
private AttResBaseService attResBaseService;
public ForecastDispatchResult getDispatchResult() {
ForecastTask forecastTask = new ForecastTask();
// 设置当前时间整点
LocalDateTime now = LocalDateTime.now();
LocalDateTime nowHour = now.withMinute(0).withSecond(0).withNano(0);
forecastTask.setNowTime(LocalDateTimeConverter.toDate(nowHour));
// 设置开始时间(当前时间减去一天)
LocalDateTime startTime = nowHour.minusDays(1);
forecastTask.setStartTime(LocalDateTimeConverter.toDate(startTime));
// 设置结束时间当前时间加上durationHours
LocalDateTime endTime = nowHour.plusHours(24);
forecastTask.setEndTime(LocalDateTimeConverter.toDate(endTime));
forecastTask.setForecastWarm(1);
forecastTask.setForecastPeriod(24); // 设置预报时长
List<ForecastResultVo> humanForecastResult = forecastResultsService.getHumanForecastResult(forecastTask);
//过滤出大于等于nowHour的数据
// 获取当前时间的格式化字符串与tm格式一致
String nowHourStr = nowHour.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
// 过滤出大于等于当前时间的数据(数据已按时间tm 从小到大排序)
List<ForecastResultVo> filteredResults = humanForecastResult.stream()
.filter(vo -> {
if (vo.getTm() == null || vo.getTm().isEmpty()) {
return false;
}
// 字符串比较(因为格式相同,可以直接比较)
return vo.getTm().compareTo(nowHourStr) >= 0;
})
.collect(Collectors.toList());
// 获取配置参数
List<ForecastUseparam> paramList = forecastUseparamService.list(new QueryWrapper<ForecastUseparam>().isNotNull("param_code").isNotNull("param_value"));
if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(paramList)) {
throw new IllegalArgumentException("温馨提示:当前洪水预报所依赖的数据尚不完整,请检查入参是否缺失。");
}
Map<String, String> paramMap = paramList.stream().collect(Collectors.toMap(ForecastUseparam::getParamCode, ForecastUseparam::getParamValue, (existing, replacement) -> existing));
if (paramMap.get("dt").isEmpty()) {
throw new IllegalArgumentException("温馨提示当前洪水预报所依赖的数据尚不完整请检查时间单元△T是否缺失。");
}
double dt = Double.parseDouble(paramMap.get("dt"));
BigDecimal timeInterval;
if(dt == 0.5){
timeInterval = new BigDecimal("1800");
}else{
timeInterval = new BigDecimal("3600");
}
ForecastDispatchResult result = new ForecastDispatchResult();
BigDecimal maxRKQ = BigDecimal.ZERO;
LocalDateTime maxRKDate = null;
BigDecimal totalRKWater = BigDecimal.ZERO;
BigDecimal totalCKWater = BigDecimal.ZERO;
BigDecimal maxRz = BigDecimal.ZERO;
LocalDateTime maxRzDate = null;
BigDecimal overLimit = BigDecimal.ZERO;
LocalDateTime start = null;
LocalDateTime end = null;
AttResBase attResBase = attResBaseService.list().get(0);
BigDecimal flLowLimLev = attResBase.getFlLowLimLev();//汛限水位
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
for (int i = 0; i < filteredResults.size(); i++) {
ForecastResultVo vo = filteredResults.get(i);
if(i < filteredResults.size()-1){
//计算总入库水量和总出库水量
BigDecimal ycRkQValue = vo.getYcRkQValue();
BigDecimal ycCkQValue = vo.getYcCkQValue();
ycRkQValue = ycRkQValue.multiply(timeInterval).divide(new BigDecimal("10000")).setScale(2, BigDecimal.ROUND_HALF_UP);
totalRKWater = totalRKWater.add(ycRkQValue);
ycCkQValue = ycCkQValue.multiply(timeInterval).divide(new BigDecimal("10000")).setScale(2, BigDecimal.ROUND_HALF_UP);
totalCKWater = totalCKWater.add(ycCkQValue);
}
//最高库水位
if(vo.getYcSwHValue().compareTo(maxRz) > 0){
maxRz = vo.getYcSwHValue();
maxRzDate = LocalDateTime.parse(vo.getTm(),formatter);
}
//最大入库流量
if(vo.getYcRkQValue().compareTo(maxRKQ) >0){
maxRKQ = vo.getYcRkQValue();
maxRKDate = LocalDateTime.parse(vo.getTm(),formatter);
}
if(start == null){
if(vo.getYcSwHValue().compareTo(flLowLimLev) > 0){
start = LocalDateTime.parse(vo.getTm(),formatter);
}
}
if(vo.getYcSwHValue().compareTo(flLowLimLev) > 0){
//如果预测水位高于汛限水位
BigDecimal gap = vo.getYcSwHValue().subtract(flLowLimLev);
if(gap.compareTo(overLimit) > 0){
overLimit = gap;
}
}
if(start != null && end == null){
if(vo.getYcSwHValue().compareTo(flLowLimLev) <= 0){
end = LocalDateTime.parse(vo.getTm(),formatter);
}
}
}
result.setMaxInflow(maxRKQ);
if(maxRKQ.compareTo(BigDecimal.ZERO) == 0){
result.setMaxInflowDate(nowHour);
}else{
result.setMaxInflowDate(maxRKDate);
}
result.setExceedLimitStart(start);
result.setExceedLimitEnd(end);
if(start == null && end == null){
result.setExceedLimitValue(null);
}else{
result.setExceedLimitValue(overLimit);
}
result.setMaxReservoirLevel(maxRz);
result.setMaxReservoirLevelDate(maxRzDate);
result.setTotalInflowVolume(totalRKWater);
result.setTotalOutflowVolume(totalCKWater);
return result;
}
// 页码事件处理器 - 简化版本 // 页码事件处理器 - 简化版本
private static class PageNumberEventHandler implements IEventHandler { private static class PageNumberEventHandler implements IEventHandler {
private final PdfFont font; private final PdfFont font;

View File

@ -549,4 +549,8 @@ public class JcskGnssRService extends ServiceImpl<JcskGnssRMapper, JcskGnssR> {
int delete = this.baseMapper.delete(queryWrapper); int delete = this.baseMapper.delete(queryWrapper);
return delete > 0; return delete > 0;
} }
public JcskGnssR queryByCDNM(String stationCode) {
return this.baseMapper.queryByCDNM(stationCode);
}
} }

View File

@ -24,4 +24,8 @@ public class JcskSlRService extends ServiceImpl<JcskSlRMapper, JcskSlR> {
public Page<JcskSlRHisVo> historyPage(JcskSlRPageSo page) { public Page<JcskSlRHisVo> historyPage(JcskSlRPageSo page) {
return this.baseMapper.historyPage(page.getPageSo().toPage(),page); return this.baseMapper.historyPage(page.getPageSo().toPage(),page);
} }
public JcskSlR queryByDvcd(String stationCode) {
return this.baseMapper.queryByDvcd(stationCode);
}
} }

View File

@ -1073,4 +1073,8 @@ public class JcskSyRService extends ServiceImpl<JcskSyRMapper, JcskSyR> {
return closestTime != null ? rzMap.get(closestTime) : BigDecimal.ZERO; return closestTime != null ? rzMap.get(closestTime) : BigDecimal.ZERO;
} }
public JcskSyR queryByDvcd(String stationCode) {
return this.baseMapper.queryByDvcd(stationCode);
}
} }

View File

@ -340,6 +340,10 @@ public class OsmoticWarnRuleService extends ServiceImpl<OsmoticWarnRuleMapper, O
OsmoticWarnR entity = warnRService.queryMaxTmByType(type); OsmoticWarnR entity = warnRService.queryMaxTmByType(type);
return entity == null?null:entity.getTm(); return entity == null?null:entity.getTm();
} }
public List<OsmoticWarnRule> queryStationByType(Integer type) {
return lambdaQuery().eq(OsmoticWarnRule::getType,type).list();
}
} }

View File

@ -0,0 +1,140 @@
package com.gunshi.project.ss.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gunshi.project.ss.entity.dto.ProjectSafetyDto;
import com.gunshi.project.ss.mapper.ProjectSafetyMapper;
import com.gunshi.project.ss.mapper.ProjectSafetyTypeMapper;
import com.gunshi.project.ss.model.FileAssociations;
import com.gunshi.project.ss.model.ProjectSafety;
import com.gunshi.project.ss.model.ProjectSafetyType;
import com.gunshi.project.ss.repository.TsgObjectRepository;
import com.gunshi.project.ss.util.EsCacheUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author lyf
* @since 2025-07-21
*/
@Service
public class ProjectSafetyService extends ServiceImpl<ProjectSafetyMapper, ProjectSafety> {
@Autowired
private ProjectSafetyTypeMapper typeMapper;
@Autowired
private TsgObjectRepository tsgObjectRepository;
@Autowired
private FileAssociationsService fileAssociationsService;
public List<ProjectSafetyType> listCategory() {
QueryWrapper<ProjectSafetyType> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByAsc("id");
return typeMapper.selectList(queryWrapper);
}
public Page<ProjectSafety> page(ProjectSafetyDto dto) {
QueryWrapper<ProjectSafety> queryWrapper = new QueryWrapper<>();
if(dto.getType() !=null){
queryWrapper.eq("type", dto.getType());
}
if(dto.getStm() !=null && dto.getEtm() !=null){
queryWrapper.between("tm", dto.getStm(), dto.getEtm());
}
if (dto.getName() != null) queryWrapper.like("name", dto.getName());
int pageNumber = dto.getPageSo().getPageNumber();
int pageSize = dto.getPageSo().getPageSize();
queryWrapper.orderByDesc("_update_tm");
Page<ProjectSafety> pageParam = new Page<>(pageNumber,pageSize);
Page<ProjectSafety> ret = page(pageParam, queryWrapper);
return ret;
}
public ProjectSafetyType addCategory(String name) {
Long cnt = typeMapper.selectCount(new LambdaQueryWrapper<ProjectSafetyType>().eq(ProjectSafetyType::getName, name));
if (cnt == 0) {
ProjectSafetyType entity = new ProjectSafetyType();
entity.setName(name);
typeMapper.insert(entity);
return entity;
}else{
throw new IllegalArgumentException("名称重复,请检查");
}
}
public Boolean delCategory(Integer id) {
ProjectSafetyType type = typeMapper.selectById(id);
if (type == null) {
return false;
}
Long cnt = getBaseMapper().selectCount(new LambdaQueryWrapper<ProjectSafety>().eq(ProjectSafety::getType, type.getName()));
if (cnt > 0) {
throw new IllegalArgumentException("请先删除关联数据");
}
return typeMapper.deleteById(id) > 0;
}
@Transactional
public Boolean updateCategory(ProjectSafetyType entity) {
ProjectSafetyType projectSafetyType = typeMapper.selectById(entity.getId());
if (projectSafetyType == null) {
return false;
}
String oldName = projectSafetyType.getName();
//防止重复
Long cnt = typeMapper.selectCount(new LambdaQueryWrapper<ProjectSafetyType>().eq(ProjectSafetyType::getName, entity.getName()));
if(cnt > 0){
throw new IllegalArgumentException("名称重复,请检查");
}
projectSafetyType.setName(entity.getName());
boolean flag1 = typeMapper.updateById(projectSafetyType) > 0;
return true;
}
public ProjectSafety getOneById(Serializable id) {
ProjectSafety projectSafety = baseMapper.selectById(id);
if(projectSafety != null){
List<FileAssociations> files = fileAssociationsService.getFiles("projectSafety", projectSafety.getId().toString());
if(files == null){
projectSafety.setFiles(new ArrayList<>());
projectSafety.setFileCount(0);
}else{
projectSafety.setFileCount(files.size());
projectSafety.setFiles(files);
}
}
return projectSafety;
}
public void updateEsCache(ProjectSafety projectSafety) {
EsCacheUtil.updateCache(tsgObjectRepository,
projectSafety,
"工程安全知识库",
ProjectSafety::getId,
ProjectSafety::getName,
null,
null,
null
);
}
public void deleteEsCache(Serializable id) {
EsCacheUtil.deleteEsCache(tsgObjectRepository,id.toString(),"工程安全知识库");
}
public void add(ProjectSafety entity) {
entity.setId(IdWorker.getId());
entity.setUpdateTm(new Date());
save(entity);
}
}

View File

@ -2,6 +2,7 @@ package com.gunshi.project.ss.timetask;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gunshi.core.result.R;
import com.gunshi.db.dto.DateTimeRangeSo; import com.gunshi.db.dto.DateTimeRangeSo;
import com.gunshi.project.ss.common.model.*; import com.gunshi.project.ss.common.model.*;
import com.gunshi.project.ss.common.model.so.OsmoticQuerySo; import com.gunshi.project.ss.common.model.so.OsmoticQuerySo;
@ -17,15 +18,21 @@ import com.gunshi.project.ss.model.*;
import com.gunshi.project.ss.service.*; import com.gunshi.project.ss.service.*;
import com.gunshi.project.ss.util.DateTransforUtil; import com.gunshi.project.ss.util.DateTransforUtil;
import com.gunshi.project.ss.util.DateUtil; import com.gunshi.project.ss.util.DateUtil;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -97,9 +104,6 @@ public class JcskDataTask {
} }
// /**
// * 每5分钟扫描渗流。渗压、位移表 生成预警
// */
// @Scheduled(cron = "0 */30 * * * ?") // @Scheduled(cron = "0 */30 * * * ?")
// @Async // @Async
public void syncWarn(){ public void syncWarn(){
@ -117,16 +121,23 @@ public class JcskDataTask {
if(gnssMaxTm==null){ if(gnssMaxTm==null){
gnssMaxTm = yesterday; gnssMaxTm = yesterday;
} }
List<JcskSyR> syList = jcskSyRService.lambdaQuery().gt(JcskSyR::getMstm, syMaxTm).list(); //只查询已配置了的测点
List<JcskSlR> slList = jcskSlRService.lambdaQuery().gt(JcskSlR::getMstm, slMaxTm).list(); List<OsmoticWarnRule> syRules = osmoticWarnRuleService.queryStationByType(PRESS);
List<JcskGnssR> gnssList = jcskGnssRService.lambdaQuery().gt(JcskGnssR::getTm, gnssMaxTm).list(); List<OsmoticWarnRule> slRules = osmoticWarnRuleService.queryStationByType(FLOW);
for (JcskSyR jcskSyR : syList) { List<OsmoticWarnRule> gnssRules = osmoticWarnRuleService.queryStationByType(GNSS);
for (OsmoticWarnRule syRule : syRules) {
String stationCode = syRule.getStationCode();
JcskSyR jcskSyR = jcskSyRService.queryByDvcd(stationCode);
osmoticWarnRuleService.checkWarn(jcskSyR); osmoticWarnRuleService.checkWarn(jcskSyR);
} }
for (JcskSlR jcskSlR : slList) { for (OsmoticWarnRule slRule : slRules) {
String stationCode = slRule.getStationCode();
JcskSlR jcskSlR = jcskSlRService.queryByDvcd(stationCode);
osmoticWarnRuleService.checkWarn(jcskSlR); osmoticWarnRuleService.checkWarn(jcskSlR);
} }
for (JcskGnssR jcskGnssR : gnssList) { for (OsmoticWarnRule gnssRule : gnssRules) {
String stationCode = gnssRule.getStationCode();
JcskGnssR jcskGnssR = jcskGnssRService.queryByCDNM(stationCode);
osmoticWarnRuleService.checkWarn(jcskGnssR); osmoticWarnRuleService.checkWarn(jcskGnssR);
} }
} }

View File

@ -0,0 +1,140 @@
package com.gunshi.project.ss.util;
import com.alibaba.fastjson2.JSONObject;
import com.gunshi.project.ss.entity.es.EsObjectDocument;
import com.gunshi.project.ss.repository.TsgObjectRepository;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public class EsCacheUtil {
/**
*
* @param tsgObjectRepository
* @param id
* @param type
*/
public static void deleteEsCache(TsgObjectRepository tsgObjectRepository,
String id,
String type
) {
EsObjectDocument byUnionCodeAndType = tsgObjectRepository.findByUnionCodeAndType(id, type);
if(byUnionCodeAndType != null){
tsgObjectRepository.delete(byUnionCodeAndType);
}
}
/**
* ES
* @param repository
* @param entitys
* @param type
* @param idGetter
* @param nameGetter
* @param lgtdGetter
* @param lttdGetter
* @param geoJsonGetter
* @param <T>
*/
public static <T> void updateCacheList(TsgObjectRepository repository,
List<T> entitys,
String type,
Function<T, Object> idGetter,
Function<T, String> nameGetter,
Function<T, Object> lgtdGetter,
Function<T, Object> lttdGetter,
Function<T,Object> geoJsonGetter) {
if (repository == null || entitys == null || type == null) {
return;
}
List<EsObjectDocument> list = new ArrayList<>();
for (T entity : entitys) {
Object id = idGetter.apply(entity);
if (id == null) {
return;
}
String idStr = String.valueOf(id);
EsObjectDocument query = repository.findByUnionCodeAndType(idStr, type);
if (query != null) {
repository.delete(query);
}
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(idStr);
esObjectDocument.setName(nameGetter.apply(entity));
esObjectDocument.setType(type);
// 处理经纬度
esObjectDocument.setLgtd(convertCoordinate(lgtdGetter != null ? lgtdGetter.apply(entity) : null));
esObjectDocument.setLttd(convertCoordinate(lttdGetter != null ? lttdGetter.apply(entity) : null));
esObjectDocument.setGeojson(geoJsonGetter != null ? (String) geoJsonGetter.apply(entity):null);
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
list.add(esObjectDocument);
}
repository.saveAll(list);
}
public static <T> void updateCache(TsgObjectRepository repository,
T entity,
String type,
Function<T, Object> idGetter,
Function<T, String> nameGetter,
Function<T, Object> lgtdGetter,
Function<T, Object> lttdGetter,
Function<T,Object> geoJsonGetter) {
if (repository == null || entity == null || type == null) {
return;
}
Object id = idGetter.apply(entity);
if (id == null) {
return;
}
String idStr = String.valueOf(id);
EsObjectDocument query = repository.findByUnionCodeAndType(idStr, type);
if (query != null) {
repository.delete(query);
}
EsObjectDocument esObjectDocument = new EsObjectDocument();
esObjectDocument.setUnionCode(idStr);
esObjectDocument.setName(nameGetter.apply(entity));
esObjectDocument.setType(type);
// 处理经纬度
esObjectDocument.setLgtd(convertCoordinate(lgtdGetter != null ? lgtdGetter.apply(entity) : null));
esObjectDocument.setLttd(convertCoordinate(lttdGetter != null ? lttdGetter.apply(entity) : null));
esObjectDocument.setGeojson(geoJsonGetter != null ? (String) geoJsonGetter.apply(entity):null);
String jsonString = JSONObject.toJSONString(entity);
esObjectDocument.setJsonStr(jsonString);
repository.save(esObjectDocument);
}
private static BigDecimal convertCoordinate(Object coordinate) {
if (coordinate == null) {
return null;
}
if (coordinate instanceof BigDecimal) {
return (BigDecimal) coordinate;
} else if (coordinate instanceof String) {
try {
return new BigDecimal((String) coordinate);
} catch (NumberFormatException e) {
return null;
}
}
return null;
}
}

View File

@ -16,6 +16,8 @@ mybatis-plus:
update-strategy: always update-strategy: always
spring: spring:
main:
allow-bean-definition-overriding: true
servlet: servlet:
multipart: multipart:
max-file-size: 100MB max-file-size: 100MB

View File

@ -14,12 +14,15 @@ spring:
username: gunshiiot username: gunshiiot
password: 1234567a password: 1234567a
driver-class-name: org.postgresql.Driver driver-class-name: org.postgresql.Driver
elasticsearch:
uris:
- http://ss-es:9200
data: data:
redis: redis:
host: ss-redis host: ss-redis
port: 6379 port: 6379
#password: 1234567a #password: 1234567a
database: 4 database: 5
mybatis-plus: mybatis-plus:
configuration: configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl log-impl: org.apache.ibatis.logging.stdout.StdOutImpl