From 410c5268c12598a7fbf0b486edaf606cc3ad9924 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 20 Apr 2026 11:40:28 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SdAlongDetailController.java | 83 +++ .../platform/env/entity/vo/BatchDeleteAo.java | 20 + .../yfd/platform/env/entity/vo/DataParam.java | 20 + .../env/entity/vo/SdAlongDetailVO.java | 39 ++ .../platform/env/entity/vo/WtrvDataVo.java | 25 + .../yfd/platform/env/entity/vo/WtrvInfo.java | 66 ++ .../env/mapper/AlongDetailMapper.java | 143 +++++ .../env/mapper/SdWtrvdrtpSMapper.java | 36 ++ .../env/service/AlongDetailService.java | 48 ++ .../service/impl/AlongDetailServiceImpl.java | 597 ++++++++++++++++++ .../platform/utils/CollectionExtUtils.java | 257 ++++++++ .../src/main/resources/application-devtw.yml | 8 +- 12 files changed, 1338 insertions(+), 4 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/env/controller/SdAlongDetailController.java create mode 100644 backend/src/main/java/com/yfd/platform/env/entity/vo/BatchDeleteAo.java create mode 100644 backend/src/main/java/com/yfd/platform/env/entity/vo/DataParam.java create mode 100644 backend/src/main/java/com/yfd/platform/env/entity/vo/SdAlongDetailVO.java create mode 100644 backend/src/main/java/com/yfd/platform/env/entity/vo/WtrvDataVo.java create mode 100644 backend/src/main/java/com/yfd/platform/env/entity/vo/WtrvInfo.java create mode 100644 backend/src/main/java/com/yfd/platform/env/mapper/AlongDetailMapper.java create mode 100644 backend/src/main/java/com/yfd/platform/env/mapper/SdWtrvdrtpSMapper.java create mode 100644 backend/src/main/java/com/yfd/platform/env/service/AlongDetailService.java create mode 100644 backend/src/main/java/com/yfd/platform/env/service/impl/AlongDetailServiceImpl.java create mode 100644 backend/src/main/java/com/yfd/platform/utils/CollectionExtUtils.java diff --git a/backend/src/main/java/com/yfd/platform/env/controller/SdAlongDetailController.java b/backend/src/main/java/com/yfd/platform/env/controller/SdAlongDetailController.java new file mode 100644 index 0000000..4be5593 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/controller/SdAlongDetailController.java @@ -0,0 +1,83 @@ +package com.yfd.platform.env.controller; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.env.entity.vo.BatchDeleteAo; +import com.yfd.platform.env.entity.vo.WtrvInfo; +import com.yfd.platform.env.service.AlongDetailService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +@RestController +@RequestMapping("/sw/alongDetail") +@Tag(name = "沿程水温变化二级数据接口") +@Validated +public class SdAlongDetailController { + + @Resource + private AlongDetailService alongDetailService; + + + @PostMapping("/GetKendoListCust") + @Operation(summary = "查询沿程水温变化二级数据列表") + public ResponseResult getKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + DataSourceResult result = alongDetailService.processKendoList(dataSourceRequest, null, new Page<>()); + return ResponseResult.successData(result); + } + + @PostMapping("/updateWtrvRData") + @Operation(summary = "修改表层水温日数据") + public ResponseResult updateWtrvRData(@RequestBody Map updateData) { + alongDetailService.updateWtrvRData(updateData); + return ResponseResult.success(); + } + + @PostMapping("/day/GetKendoListCust") + @Operation(summary = "查询出库水温日数据") + public ResponseResult getKendoDayListCust(@RequestBody DataSourceRequest dataSourceRequest) { + DataSourceResult result = alongDetailService.processDayKendoList(dataSourceRequest, null, new Page<>(), null); + return ResponseResult.successData(result); + } + + @PostMapping("/drtp/GetKendoListCust") + @Operation(summary = "查询出库水温周旬月季年数据") + public ResponseResult getKendoDrtpListCust(@RequestBody DataSourceRequest dataSourceRequest) { + DataSourceResult result = alongDetailService.processDrtpKendoList(dataSourceRequest, null, new Page<>(), null); + return ResponseResult.successData(result); + } + + @PostMapping("/drtp/removeKendoByIds") + @Operation(summary = "删除出库水温周旬月季年数据") + public ResponseResult removeKendoByIds(@RequestBody BatchDeleteAo batchDeleteAo) { + alongDetailService.removeKendoByIds(batchDeleteAo); + return ResponseResult.success(); + } + +// @PostMapping("/qgc/GetKendoListCust") +// @Operation(summary = "环保部查询出入库水温、出入库流量、入库水温、天然水温、降雨、气温数据") +// public ResponseResult getQgcKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { +// DataSourceResult result = alongDetailService.getQgcKendoListCust(dataSourceRequest); +// return ResponseResult.successData(result); +// } + + @GetMapping("/qgc/stcdCheck") + @Operation(summary = "判断出库水温站、垂向水温站或者低温水减缓设施所属的电站是否有出库水温站、垂向水温站和低温水减缓设施") + public ResponseResult getQgcStcdCheck(@RequestParam String stcd) { + WtrvInfo result = alongDetailService.getWtrvInfoByStcd2(stcd); + return ResponseResult.successData(result); + } + + @GetMapping("/qgc/stcdCheck2") + @Operation(summary = "判断出库水温站、垂向水温站所属的电站是否有出库水温站、垂向水温站") + public ResponseResult getQgcStcdCheck2(@RequestParam String stcd) { + WtrvInfo result = alongDetailService.getWtrvInfoByStcd3(stcd); + return ResponseResult.successData(result); + } +} diff --git a/backend/src/main/java/com/yfd/platform/env/entity/vo/BatchDeleteAo.java b/backend/src/main/java/com/yfd/platform/env/entity/vo/BatchDeleteAo.java new file mode 100644 index 0000000..f4dfafb --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/entity/vo/BatchDeleteAo.java @@ -0,0 +1,20 @@ +package com.yfd.platform.env.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +@Data +@Schema(description = "批量删除参数") +public class BatchDeleteAo implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "数据类型") + private String dataType; + + @Schema(description = "删除数据列表") + private List dataList; +} diff --git a/backend/src/main/java/com/yfd/platform/env/entity/vo/DataParam.java b/backend/src/main/java/com/yfd/platform/env/entity/vo/DataParam.java new file mode 100644 index 0000000..88b5bac --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/entity/vo/DataParam.java @@ -0,0 +1,20 @@ +package com.yfd.platform.env.entity.vo; + +import lombok.Data; + +@Data +public class DataParam { + + + private String dt; + + private String tm; + + private String month; + + private String year; + + private String drtp; + + private String id; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/entity/vo/SdAlongDetailVO.java b/backend/src/main/java/com/yfd/platform/env/entity/vo/SdAlongDetailVO.java new file mode 100644 index 0000000..59ba7f7 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/entity/vo/SdAlongDetailVO.java @@ -0,0 +1,39 @@ +package com.yfd.platform.env.entity.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.FieldNameConstants; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +@Getter +@Setter +@FieldNameConstants +@Schema(description = "沿程水温变化二级数据VO") +public class SdAlongDetailVO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date tm; + + @Schema(description = "月份") + private Integer mon; + + @Schema(description = "站码") + private String stcd; + + @Schema(description = "水温") + private BigDecimal wt; + + @Schema(description = "站名") + private String stnm; + + @Schema(description = "基地名称") + private String baseName; +} diff --git a/backend/src/main/java/com/yfd/platform/env/entity/vo/WtrvDataVo.java b/backend/src/main/java/com/yfd/platform/env/entity/vo/WtrvDataVo.java new file mode 100644 index 0000000..17a0196 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/entity/vo/WtrvDataVo.java @@ -0,0 +1,25 @@ +package com.yfd.platform.env.entity.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +@Data +@EqualsAndHashCode(callSuper = true) +@Schema(description = "出入库水温数据") +public class WtrvDataVo extends WtrvInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date tm; + + @Schema(description = "水温") + private BigDecimal wt; +} diff --git a/backend/src/main/java/com/yfd/platform/env/entity/vo/WtrvInfo.java b/backend/src/main/java/com/yfd/platform/env/entity/vo/WtrvInfo.java new file mode 100644 index 0000000..bfd6c11 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/entity/vo/WtrvInfo.java @@ -0,0 +1,66 @@ +package com.yfd.platform.env.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; + +@Data +@Schema(description = "水温站点信息") +public class WtrvInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "出入库标识:1-入库水温,2-出库水温,3-非出入库水温") + private Integer type; + + @Schema(description = "类型名称") + private String typeName; + + @Schema(description = "站码") + private String stcd; + + @Schema(description = "站名") + private String stnm; + + @Schema(description = "站点类型编码") + private String sttpCode; + + @Schema(description = "关联电站编码") + private String rstcd; + + @Schema(description = "关联电站名称") + private String ennm; + + @Schema(description = "垂向水温站站码") + private String vtStcd; + + @Schema(description = "垂向水温站站名") + private String vtStnm; + + @Schema(description = "低温水减缓设施站码") + private String dwStcd; + + @Schema(description = "低温水减缓设施站名") + private String dwStnm; + + public String getTypeName() { + if (type == null) { + return "未知类型"; + } + switch (type) { + case 1: + return "入库水温"; + case 2: + return "出库水温"; + case 3: + return "河道水温"; + default: + return "未知类型"; + } + } + + public void setTypeName(String typeName) { + this.typeName = typeName; + } +} diff --git a/backend/src/main/java/com/yfd/platform/env/mapper/AlongDetailMapper.java b/backend/src/main/java/com/yfd/platform/env/mapper/AlongDetailMapper.java new file mode 100644 index 0000000..2e997a2 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/mapper/AlongDetailMapper.java @@ -0,0 +1,143 @@ +package com.yfd.platform.env.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yfd.platform.env.entity.vo.SdAlongDetailVO; +import com.yfd.platform.env.entity.vo.WtrvInfo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 沿程水温变化二级数据接口 + * + * @author + * @since 2023-04-23 09:32:10 + */ +@Mapper +public interface AlongDetailMapper extends BaseMapper { + + WtrvInfo getWtrvInfoByStcd(@Param("stcd") String stcd); + //电站数据 + @Select("SELECT AVG(a.QI) AS qi, AVG(a.QO) AS qo, a.tm, AVG(a.RZ) AS rz, AVG(a.DZ) AS dz " + + "FROM SD_HYDROPW_R a " + + "INNER JOIN MS_STBPRP_T b ON a.STCD = b.RSTCD " + + "WHERE b.IS_DELETED = 0 AND a.IS_DELETED = 0 " + + "AND b.STCD = #{stcd} AND a.TM BETWEEN #{startTime} AND #{endTime} " + + "GROUP BY a.TM") + List> getHydropwDataList(@Param("stcd") String stcd, + @Param("startTime") Date startTime, + @Param("endTime") Date endTime); + //天然水温 + @Select("") + List> getNatureTmpDataList(@Param("rstcd") String rstcd,@Param("monnth") Integer month); + //入库水温 + @Select("") + List> getIwtrvDataList(@Param("stcd")String stcd,@Param("rstcd")String rstcd, @Param("startTime") Date startTime, @Param("endTime") Date endTime); + //出库水温 + @Select("") + List> getDwtrvDataList(@Param("stcd")String stcd,@Param("rstcd")String rstcd, @Param("startTime") Date startTime, @Param("endTime") Date endTime); + //降雨量 + @Select("SELECT a.TM, AVG(a.DRP) AS DRP " + + "FROM SD_PPTN_R a " + + "INNER JOIN MS_STBPRP_T b ON a.STCD = b.STCD " + + "WHERE b.STTP_CODE = 'MM' " + + "AND a.IS_DELETED = 0 AND b.IS_DELETED = 0 " + + "AND b.RSTCD = (SELECT RSTCD FROM MS_STBPRP_T WHERE STCD = #{stcd}) " + + "AND a.TM BETWEEN #{startTime} AND #{endTime} " + + "GROUP BY a.TM") + List> getPptnDataList(@Param("stcd")String stcd, @Param("startTime") Date startTime, @Param("endTime") Date endTime); + //气象站数据 + @Select("SELECT a.TM, AVG(a.AT) AS AT " + + "FROM SD_TMP_R a " + + "INNER JOIN MS_STBPRP_T b ON a.STCD = b.STCD " + + "WHERE b.STTP_CODE = 'MM' AND a.IS_DELETED = 0 AND b.IS_DELETED = 0 " + + "AND b.RSTCD = (SELECT RSTCD FROM MS_STBPRP_T WHERE STCD = #{stcd}) " + + "AND a.TM BETWEEN #{startTime} AND #{endTime} " + + "GROUP BY a.TM") + List> getTmpDataList(@Param("stcd")String stcd, @Param("startTime") Date startTime, @Param("endTime") Date endTime); + + @Select("SELECT * FROM (" + + "SELECT TM, WTHG, ROUND(AVG(VWT), 2) AS VWT " + + "FROM SD_WTVT_R " + + "WHERE STCD IN (" + + " SELECT STCD FROM MS_STBPRP_T " + + " WHERE RSTCD = #{rstcd} AND STTP_CODE = 'WTVT' AND IS_DELETED = 0" + + ") " + + "AND TO_CHAR(TM, 'mi') = 0 AND IS_DELETED = 0 " + + "AND TM BETWEEN #{startTime} AND #{endTime} " + + "GROUP BY TM, WTHG" + + ") ORDER BY TM ASC, VWT ASC") + List> getWtvtDataList(@Param("stcd")String stcd,@Param("rstcd")String rstcd, @Param("startTime") Date startTime, @Param("endTime") Date endTime); + + @Select("SELECT a.STCD AS rstcd, a.STNM AS ennm, " + + "REGEXP_REPLACE(LISTAGG(TO_CHAR(b.STCD), ',') WITHIN GROUP (ORDER BY b.STCD), '([^,]+)(,\\1)*(,|$)', '\\1\\3') AS stcd, " + + "REGEXP_REPLACE(LISTAGG(TO_CHAR(b.STNM), ',') WITHIN GROUP (ORDER BY b.STCD), '([^,]+)(,\\1)*(,|$)', '\\1\\3') AS stnm, " + + "REGEXP_REPLACE(LISTAGG(TO_CHAR(c.STCD), ',') WITHIN GROUP (ORDER BY c.STCD), '([^,]+)(,\\1)*(,|$)', '\\1\\3') AS vtStcd, " + + "REGEXP_REPLACE(LISTAGG(TO_CHAR(c.STNM), ',') WITHIN GROUP (ORDER BY c.STCD), '([^,]+)(,\\1)*(,|$)', '\\1\\3') AS vtStnm, " + + "REGEXP_REPLACE(LISTAGG(TO_CHAR(d.STCD), ',') WITHIN GROUP (ORDER BY d.STCD), '([^,]+)(,\\1)*(,|$)', '\\1\\3') AS dwStcd, " + + "REGEXP_REPLACE(LISTAGG(TO_CHAR(d.STNM), ',') WITHIN GROUP (ORDER BY d.STCD), '([^,]+)(,\\1)*(,|$)', '\\1\\3') AS dwStnm " + + "FROM MS_STBPRP_T a " + + "LEFT JOIN MS_STBPRP_T b ON a.STCD = b.RSTCD AND b.STTP_CODE = 'WTRV' AND b.IS_DELETED = 0 AND b.MWAY = 2 AND b.DTIN_TYPE = 0 " + + "LEFT JOIN MS_STBPRP_T c ON a.STCD = c.RSTCD AND c.STTP_CODE = 'WTVT' AND c.IS_DELETED = 0 AND c.MWAY = 2 " + + "LEFT JOIN MS_STBPRP_T d ON a.STCD = d.RSTCD AND d.STTP_CODE LIKE 'DW_%' AND d.IS_DELETED = 0 " + + "WHERE a.STTP_CODE = 'ENG' AND a.IS_DELETED = 0 " + + "AND b.STCD IS NOT NULL AND c.STCD IS NOT NULL AND d.STCD IS NOT NULL AND b.ENG_DWT_CODE IS NOT NULL " + + "AND (d.STCD = #{stcd} OR b.STCD = #{stcd} OR c.STCD = #{stcd} OR a.STCD = #{stcd}) " + + "AND a.STCD = b.ENG_DWT_CODE " + + "GROUP BY a.STCD, a.STNM") + WtrvInfo getWtrvInfoByStcd2(@Param("stcd") String stcd); + + @Select("SELECT a.STCD AS rstcd, a.STNM AS ennm, " + + "REGEXP_REPLACE(LISTAGG(TO_CHAR(b.STCD), ',') WITHIN GROUP (ORDER BY b.STCD), '([^,]+)(,\\1)*(,|$)', '\\1\\3') AS stcd, " + + "REGEXP_REPLACE(LISTAGG(TO_CHAR(b.STNM), ',') WITHIN GROUP (ORDER BY b.STCD), '([^,]+)(,\\1)*(,|$)', '\\1\\3') AS stnm, " + + "REGEXP_REPLACE(LISTAGG(TO_CHAR(c.STCD), ',') WITHIN GROUP (ORDER BY c.STCD), '([^,]+)(,\\1)*(,|$)', '\\1\\3') AS vtStcd, " + + "REGEXP_REPLACE(LISTAGG(TO_CHAR(c.STNM), ',') WITHIN GROUP (ORDER BY c.STCD), '([^,]+)(,\\1)*(,|$)', '\\1\\3') AS vtStnm " + + "FROM MS_STBPRP_T a " + + "LEFT JOIN MS_STBPRP_T b ON a.STCD = b.RSTCD AND b.STTP_CODE = 'WTRV' AND b.IS_DELETED = 0 AND b.MWAY = 2 AND b.DTIN_TYPE = 0 " + + "LEFT JOIN MS_STBPRP_T c ON a.STCD = c.RSTCD AND c.STTP_CODE = 'WTVT' AND c.IS_DELETED = 0 AND c.MWAY = 2 " + + "WHERE a.STTP_CODE = 'ENG' AND a.IS_DELETED = 0 " + + "AND b.STCD IS NOT NULL AND c.STCD IS NOT NULL AND b.ENG_DWT_CODE IS NOT NULL " + + "AND (b.STCD = #{stcd} OR c.STCD = #{stcd} OR a.STCD = #{stcd}) " + + "AND a.STCD = b.ENG_DWT_CODE " + + "GROUP BY a.STCD, a.STNM") + WtrvInfo getWtrvInfoByStcd3(@Param("stcd") String stcd); +} diff --git a/backend/src/main/java/com/yfd/platform/env/mapper/SdWtrvdrtpSMapper.java b/backend/src/main/java/com/yfd/platform/env/mapper/SdWtrvdrtpSMapper.java new file mode 100644 index 0000000..a8b50a5 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/mapper/SdWtrvdrtpSMapper.java @@ -0,0 +1,36 @@ +package com.yfd.platform.env.mapper; + +import com.yfd.platform.env.entity.vo.DataParam; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface SdWtrvdrtpSMapper { + void deleteWtrvMonthData(@Param("ids") List ids, @Param("deleteTime") String deleteTime); + + @Delete("") + void deleteWtrvRData(@Param("dataParamList") List dataParamList, @Param("deleteTime") String deleteTime, @Param("userID") String userID); + + @Update("") + void updateWtrvRData(@Param("updateData") Map updateData); + +// void updateWtvtRData(@Param("updateData") Map updateData); + +} diff --git a/backend/src/main/java/com/yfd/platform/env/service/AlongDetailService.java b/backend/src/main/java/com/yfd/platform/env/service/AlongDetailService.java new file mode 100644 index 0000000..586c352 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/service/AlongDetailService.java @@ -0,0 +1,48 @@ +package com.yfd.platform.env.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.common.GroupResult; +import com.yfd.platform.env.entity.vo.BatchDeleteAo; +import com.yfd.platform.env.entity.vo.SdAlongDetailVO; +import com.yfd.platform.env.entity.vo.WtrvInfo; + + +import java.util.Map; + +/** + * 沿程水温变化二级数据接口服务 + * + * @author + * @since 2023-04-23 09:32:10 + */ +public interface AlongDetailService extends IService { + /** + * 处理kendo列表 + * + * @param dataSourceRequest 数据源请求 + * @param filterResult 筛选结果 + * @param page 页面 + * @return {@link DataSourceResult}<{@link SdMonthListVO}> + */ + DataSourceResult processKendoList(DataSourceRequest dataSourceRequest, Map filterResult, Page page); + + DataSourceResult processDayKendoList(DataSourceRequest dataSourceRequest, Map filterResult, Page page, String groupBy); + + DataSourceResult processDrtpKendoList(DataSourceRequest dataSourceRequest, Map filterResult, Page page, String groupBy); + + DataSourceResult processQgcKendList(DataSourceResult dataSourceResult, WtrvInfo wtrvInfo); + + WtrvInfo getWtrvInfoByStcd(String stcd); + + WtrvInfo getWtrvInfoByStcd2(String stcd); + + WtrvInfo getWtrvInfoByStcd3(String stcd); + + boolean removeKendoByIds(BatchDeleteAo batchDeleteAo); + + void updateWtrvRData(Map updateData); + +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/service/impl/AlongDetailServiceImpl.java b/backend/src/main/java/com/yfd/platform/env/service/impl/AlongDetailServiceImpl.java new file mode 100644 index 0000000..3320d89 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/service/impl/AlongDetailServiceImpl.java @@ -0,0 +1,597 @@ +package com.yfd.platform.env.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.yfd.platform.common.*; +import com.yfd.platform.env.entity.vo.*; +import com.yfd.platform.env.mapper.AlongDetailMapper; +import com.yfd.platform.env.mapper.SdWtrvdrtpSMapper; +import com.yfd.platform.env.service.AlongDetailService; +import com.yfd.platform.utils.CollectionExtUtils; +import com.yfd.platform.utils.SecurityUtils; +import jakarta.annotation.Resource; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 沿程水温二级数据接口服务 + * + * @author + * @since 2023-04-23 09:32:10 + */ +@Service +public class AlongDetailServiceImpl extends ServiceImpl implements AlongDetailService { + @Resource + private DynamicSQLMapper dynamicSQLMapper; + @Resource + private AlongDetailMapper alongDetailMapper; + + @Resource + private SdWtrvdrtpSMapper sdWtrvdrtpSMapper; + + @Resource + private JdbcTemplate jdbcTemplate; + + @Override + public DataSourceResult processKendoList(DataSourceRequest dataSourceRequest, Map filterResult, Page page) { + DataSourceResult dataSourceResult = new DataSourceResult(); + StringBuilder sql = new StringBuilder("SELECT t.tm,t.mon, t.stcd, t.wt, t.stnm, t.basename,t.mway,t.rstcd\n" + + "FROM (SELECT DISTINCT r.tm,to_char(r.tm,'MM') mon, r.stcd, r.WT,r.TASK_ID,r.TASK_STATUS ,t2.stnm,t2.BASE_Id AS baseId, t2.BASE_NAME baseName,t2.MWAY AS mway, t2.rstcd\n" + + " FROM SD_WTRV_R r\n" + + //" inner join MS_ALONGDET_B b on r.stcd=b.stcd and b.is_deleted=0 inner join MS_ALONG_B a on a.ID=b.ALONG_ID and a.code='common' " + + " LEFT JOIN MS_STBPRP_T t2 ON r.STCD = t2.STCD \n" + + " WHERE r.is_deleted=0 and t2.is_deleted=0 " + + " order by r.tm DESC, r.stcd) t where 1=1 "); + + sql. append(" AND (TASK_ID IS NULL OR TASK_ID ='' OR TASK_STATUS ='Approved') "); + if (ObjectUtil.isNotEmpty(filterResult.get(CommonConstant.DEFAULT))) { + if (StrUtil.isNotBlank(filterResult.get(CommonConstant.DEFAULT).getGroupSql())) { + sql.append(" and ").append(filterResult.get(CommonConstant.DEFAULT).getGroupSql()); + } + + if (StrUtil.isNotBlank(filterResult.get(CommonConstant.DEFAULT).getOrderBySql())) { + sql.append(" ").append(filterResult.get(CommonConstant.DEFAULT).getOrderBySql()); + } + } + Map map = new HashMap(); + Iterator iterator = filterResult.keySet().iterator(); + + while (iterator.hasNext()) { + String key = (String) iterator.next(); + map.putAll(filterResult.get(key).getParamMap()); + } + List list = this.dynamicSQLMapper.pageAllListWithResultType(page, sql.toString(), map, SdAlongDetailVO.class); + dataSourceResult.setData(list); + dataSourceResult.setTotal(ObjectUtil.isNotEmpty(page) ? page.getTotal() : (long) list.size()); + return dataSourceResult; + } + + @Override + public DataSourceResult processDayKendoList(DataSourceRequest dataSourceRequest, Map filterResult, Page page, String groupBy) { + DataSourceResult dataSourceResult = new DataSourceResult(); + StringBuilder sql = new StringBuilder(); + + if(StrUtil.isNotBlank(filterResult.get("default").getSelectSql())){ + sql.append(filterResult.get("default").getSelectSql()); + sql.append(" from "); + sql.append(" SD_WTRVDAY_S a inner join MS_STBPRP_T b on a.STCD=b.STCD and b.STTP_CODE='WTRV' "); + sql.append(" where 1=1 "); + if (ObjectUtil.isNotEmpty(filterResult.get(CommonConstant.DEFAULT))) { + if (StrUtil.isNotBlank(filterResult.get(CommonConstant.DEFAULT).getGroupSql())) { + sql.append(" and ").append(filterResult.get(CommonConstant.DEFAULT).getGroupSql()); + } + + if (StrUtil.isNotBlank(filterResult.get(CommonConstant.DEFAULT).getOrderBySql())) { + sql.append(" ").append(filterResult.get(CommonConstant.DEFAULT).getOrderBySql()); + } + } + } + Map map = new HashMap(); + Iterator iterator = filterResult.keySet().iterator(); + while (iterator.hasNext()) { + String key = (String) iterator.next(); + map.putAll(filterResult.get(key).getParamMap()); + } + List< Map> resultList = this.dynamicSQLMapper.pageAllList(page, sql.toString(), map); + dataSourceResult.setData(resultList); + dataSourceResult.setTotal(ObjectUtil.isNotEmpty(page) ? page.getTotal() : (long) resultList.size()); + return dataSourceResult; + } + + @Override + public DataSourceResult processDrtpKendoList(DataSourceRequest dataSourceRequest, Map filterResult, Page page, String groupBy) { + DataSourceResult dataSourceResult = new DataSourceResult(); + StringBuilder sql = new StringBuilder(); + if(StrUtil.isNotBlank(filterResult.get(CommonConstant.DEFAULT).getSelectSql())){ + sql.append(filterResult.get(CommonConstant.DEFAULT).getSelectSql()); + sql.append(" from "); + sql.append(" SD_WTRVDRTP_S a inner join MS_STBPRP_T b on a.STCD=b.STCD and b.STTP_CODE='WTRV' "); + sql.append(" where 1=1 "); + if (ObjectUtil.isNotEmpty(filterResult.get(CommonConstant.DEFAULT))) { + if (StrUtil.isNotBlank(filterResult.get(CommonConstant.DEFAULT).getGroupSql())) { + sql.append(" and ").append(filterResult.get(CommonConstant.DEFAULT).getGroupSql()); + } + + if (StrUtil.isNotBlank(filterResult.get(CommonConstant.DEFAULT).getOrderBySql())) { + sql.append(" ").append(filterResult.get(CommonConstant.DEFAULT).getOrderBySql()); + } + } + } + Map map = new HashMap(); + Iterator iterator = filterResult.keySet().iterator(); + + while (iterator.hasNext()) { + String key = (String) iterator.next(); + map.putAll(filterResult.get(key).getParamMap()); + } + List> resultList = this.dynamicSQLMapper.pageAllList(page, sql.toString(), map); + dataSourceResult.setData(resultList); + dataSourceResult.setTotal(ObjectUtil.isNotEmpty(page) ? page.getTotal() : (long) resultList.size()); + return dataSourceResult; + } + + @Override + public DataSourceResult processQgcKendList(DataSourceResult dataSourceResult, WtrvInfo wtrvInfo) { + DataSourceResult dr = new DataSourceResult(); + List> list = (List>) dataSourceResult.getData(); + + if (list == null || list.isEmpty()) { + dr.setData(new ArrayList<>()); + dr.setTotal(0); + return dr; + } + + Date startTime = (Date) list.get(0).get("tm"); + Date endTime = (Date) list.get(list.size() - 1).get("tm"); + + if (startTime.compareTo(endTime) > 0) { + Date tmpDate = startTime; + startTime = endTime; + endTime = tmpDate; + } + + List> iwtDataVoList = new ArrayList<>(); + List> dwtDataVoList = new ArrayList<>(); + List> wtvtDataVoList = new ArrayList<>(); + List> hydropwDataVoList = new ArrayList<>(); + List> pptnDataVoList = new ArrayList<>(); + List> tmpDataVoList = new ArrayList<>(); + List> wtnpDataVoList; + + if (wtrvInfo.getType() == 1) { + dwtDataVoList.addAll(this.alongDetailMapper.getDwtrvDataList(wtrvInfo.getStcd(), null, startTime, endTime)); + } + + Map>> wtvtDataVoMap; + if (wtrvInfo.getType() == 2) { + iwtDataVoList.addAll(this.alongDetailMapper.getIwtrvDataList(wtrvInfo.getStcd(), null, startTime, endTime)); + wtvtDataVoList.addAll(this.alongDetailMapper.getWtvtDataList(null, wtrvInfo.getRstcd(), startTime, endTime)); + wtvtDataVoMap = wtvtDataVoList.stream() + .filter(it -> it.get("tm") != null) + .collect(Collectors.groupingBy(it -> (Date) it.get("tm"))); + } else { + wtvtDataVoMap = null; + } + + Map> iwtDataMap = iwtDataVoList.stream() + .collect(Collectors.toMap(it -> (Date) it.get("tm"), Function.identity())); + Map> dwtDataMap = dwtDataVoList.stream() + .collect(Collectors.toMap(it -> (Date) it.get("tm"), Function.identity())); + + hydropwDataVoList.addAll(this.alongDetailMapper.getHydropwDataList(wtrvInfo.getStcd(), startTime, endTime)); + Map> hydropwDataMap = hydropwDataVoList.stream() + .collect(Collectors.toMap(it -> (Date) it.get("tm"), Function.identity())); + + pptnDataVoList.addAll(this.alongDetailMapper.getPptnDataList(wtrvInfo.getStcd(), startTime, endTime)); + Map> pptnDataMap = pptnDataVoList.stream() + .collect(Collectors.toMap(it -> (Date) it.get("tm"), Function.identity())); + + tmpDataVoList.addAll(this.alongDetailMapper.getTmpDataList(wtrvInfo.getStcd(), startTime, endTime)); + Map> tmpDataMap = tmpDataVoList.stream() + .collect(Collectors.toMap(it -> (Date) it.get("tm"), Function.identity())); + + Map wtnpDataMap = new HashMap<>(); + if (StrUtil.isNotBlank(wtrvInfo.getRstcd())) { + wtnpDataVoList = this.alongDetailMapper.getNatureTmpDataList(wtrvInfo.getRstcd(), null); + wtnpDataMap.putAll(wtnpDataVoList.stream() + .filter(it -> it.get("mnth") != null) + .collect(Collectors.toMap( + it -> (Integer) it.get("mnth"), + it -> (BigDecimal) it.get("wt") + ))); + } + + List> qgcWtrvDataVoList = new ArrayList<>(); + list.forEach(it -> { + Map vo = new HashMap<>(); + vo.put("stcd", it.get("stcd")); + vo.put("stnm", it.get("stnm")); + vo.put("wt", it.get("wt")); + vo.put("tm", it.get("tm")); + vo.put("ennm", wtrvInfo.getEnnm()); + vo.put("rstcd", wtrvInfo.getRstcd()); + vo.put("type", wtrvInfo.getType()); + vo.put("natureTmp", wtnpDataMap.get(it.get("mon"))); + vo.put("hydropwDataVo", hydropwDataMap.get(it.get("tm"))); + vo.put("pptnDataVo", pptnDataMap.get(it.get("tm"))); + vo.put("tmpDataVo", tmpDataMap.get(it.get("tm"))); + + if (wtrvInfo.getType() == 1) { + Map iwtVo = new HashMap<>(); + iwtVo.put("tm", it.get("tm")); + iwtVo.put("wt", it.get("wt")); + vo.put("iwtDataVo", iwtVo); + vo.put("dwtDataVo", dwtDataMap.get(it.get("tm"))); + } + + if (wtrvInfo.getType() == 2) { + Map dwtVo = new HashMap<>(); + dwtVo.put("tm", it.get("tm")); + dwtVo.put("wt", it.get("wt")); + vo.put("dwtDataVo", dwtVo); + vo.put("iwtDataVo", iwtDataMap.get(it.get("tm"))); + + if (it.get("wt") != null && wtvtDataVoMap != null) { + List> vtList = wtvtDataVoMap.get(it.get("tm")); + if (vtList != null) { + Map>> vtMap = vtList.stream() + .filter(tt -> tt.get("vwt") != null) + .collect(Collectors.groupingBy(tt -> (BigDecimal) tt.get("vwt"))); + + if (vtMap.containsKey(it.get("wt"))) { + vo.put("wtvtDataVo", vtMap.get(it.get("wt")).get(0)); + qgcWtrvDataVoList.add(vo); + return; + } + + BigDecimal leftVt = null; + BigDecimal rightVt = null; + Map leftVo = null; + Map rightVo = null; + + List sortVt = new ArrayList<>(vtMap.keySet()).stream() + .sorted() + .collect(Collectors.toList()); + + BigDecimal[] lrValue = CollectionExtUtils.findNeighbors(sortVt, (BigDecimal) it.get("wt")); + if (lrValue.length == 2) { + leftVt = lrValue[0]; + rightVt = lrValue[1]; + } + + Map vo1 = new HashMap<>(); + if (leftVt != null) { + leftVo = vtMap.get(leftVt).get(0); + vo1.put("leftWtvtData", leftVo); + } + if (rightVt != null) { + rightVo = vtMap.get(rightVt).get(0); + vo1.put("rightWtvtData", rightVo); + } + + if (leftVt != null && rightVt != null) { + BigDecimal currentWt = (BigDecimal) it.get("wt"); + BigDecimal wthg = ((rightVt.subtract(currentWt)).multiply((BigDecimal) leftVo.get("wthg")) + .add((currentWt.subtract(leftVt)).multiply((BigDecimal) rightVo.get("wthg")))) + .divide((rightVt.subtract(currentWt)).add(currentWt.subtract(leftVt)), RoundingMode.HALF_UP); + vo1.put("wthg", wthg); + vo1.put("vwt", currentWt); + } + vo.put("wtvtDataVo", vo1); + } + } + } + qgcWtrvDataVoList.add(vo); + }); + + dr.setData(qgcWtrvDataVoList); + dr.setTotal(dataSourceResult.getTotal()); + return dr; + } + + + @Override + public WtrvInfo getWtrvInfoByStcd(String stcd) { + return this.alongDetailMapper.getWtrvInfoByStcd(stcd); + } + + @Override + public WtrvInfo getWtrvInfoByStcd2(String stcd) { + return this.alongDetailMapper.getWtrvInfoByStcd2(stcd); + } + + @Override + public WtrvInfo getWtrvInfoByStcd3(String stcd) { + return this.alongDetailMapper.getWtrvInfoByStcd3(stcd); + } + + @Override + public boolean removeKendoByIds(BatchDeleteAo batchDeleteAo) { + String dataType = batchDeleteAo.getDataType(); + List dataList = batchDeleteAo.getDataList(); + if(CollUtil.isEmpty(dataList)){ + return true; + } + //删除小时数据 + int batchSize = 500; + for (int i = 0; i < dataList.size(); i += batchSize) { + List subList = dataList.subList(i, Math.min(i + batchSize, dataList.size())); + //判断数据类型 + if ("MON".equals(dataType)) { + //删除月数据 + + } + if ("DATE".equals(dataType)) { + //删除日数据 + + } + if ("TIME".equals(dataType)) { + sdWtrvdrtpSMapper.deleteWtrvRData(subList, DateUtil.now(), SecurityUtils.getCurrentUsername()); + + // 删除小时数据后,需要重新统计对应的日数据和月数据 + Map dateRangeMap = new HashMap<>(); + Map monthRangeMap = new HashMap<>(); + + for (DataParam param : subList) { + if (param.getId() != null && param.getDt() != null) { + String stcd = param.getId(); + String tm = param.getDt(); + // 提取日期部分 + String dateStr = tm.substring(0, 10); + + // 收集每个测站的日期范围 + if (!dateRangeMap.containsKey(stcd)) { + dateRangeMap.put(stcd, new String[]{dateStr, dateStr}); + } else { + String[] range = dateRangeMap.get(stcd); + if (dateStr.compareTo(range[0]) < 0) { + range[0] = dateStr; + } + if (dateStr.compareTo(range[1]) > 0) { + range[1] = dateStr; + } + } + + // 收集每个测站的月份范围 + String yearMonth = tm.substring(0, 7); + String[] ym = yearMonth.split("-"); + if (ym.length == 2) { + Integer year = Integer.parseInt(ym[0]); + Integer month = Integer.parseInt(ym[1]); + String monthStart = year + "-" + String.format("%02d", month) + "-01"; + String monthEnd = getMonthEndDate(year, month); + + String monthKey = stcd + "_" + year + "_" + month; + if (!monthRangeMap.containsKey(monthKey)) { + monthRangeMap.put(monthKey, new String[]{stcd, monthStart, monthEnd}); + } + } + } + } + + // 统计日数据(从小时数据)- 按测站和日期范围批量统计 + for (Map.Entry entry : dateRangeMap.entrySet()) { + String stcd = entry.getKey(); + String[] range = entry.getValue(); + statisticsDayDataFromHour(stcd, range[0], range[1]); + } + + // 统计月数据(从日数据)- 按测站和月份范围批量统计 + Set processedMonths = new HashSet<>(); + for (String[] values : monthRangeMap.values()) { + String stcd = values[0]; + String startDate = values[1]; + String endDate = values[2]; + String monthKey = stcd + "_" + startDate; + + if (!processedMonths.contains(monthKey)) { + statisticsMonthDataFromDay(stcd, startDate, endDate); + processedMonths.add(monthKey); + } + } + + } + } + return true; + } + + /** + * 获取指定年月的最后一天 + */ + private String getMonthEndDate(Integer year, Integer month) { + Calendar calendar = Calendar.getInstance(); + calendar.set(year, month - 1, 1); + int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); + return year + "-" + String.format("%02d", month) + "-" + String.format("%02d", lastDay); + } + + /** + * 从小时水温数据统计日数据(支持日期范围) + * @param stcd 测站编码 + * @param startDate 开始日期 yyyy-MM-dd + * @param endDate 结束日期 yyyy-MM-dd + */ + private void statisticsDayDataFromHour(String stcd, String startDate, String endDate) { + // 第一步:标记没有对应小时数据的日记录为删除 + String deleteSql = "DELETE FROM SD_WTRVDAY_S T " + + "WHERE T.STCD = ? " + + "AND T.DT BETWEEN TO_DATE(?, 'YYYY-MM-DD') " + + "AND TO_DATE(?, 'YYYY-MM-DD') " + + "AND NOT EXISTS ( " + + "SELECT 1 FROM SD_WTRV_R S " + + "WHERE S.STCD = T.STCD " + + "AND TRUNC(S.TM) = T.DT " + + "AND S.TM >= TO_DATE(? || ' 00:00:00', 'YYYY-MM-DD HH24:MI:SS') " + + "AND S.TM <= TO_DATE(? || ' 23:59:59', 'YYYY-MM-DD HH24:MI:SS') " + + "AND S.IS_DELETED = 0)"; +// String deleteSql = "UPDATE SD_WTRVDAY_S T " + +// "SET T.IS_DELETED = 1, " + +// "T.DELETE_TIME = SYSDATE, " + +// "T.MODIFY_TIME = SYSDATE " + +// "WHERE T.STCD = ? " + +// "AND T.DT BETWEEN TO_DATE(?, 'YYYY-MM-DD') " + +// "AND TO_DATE(?, 'YYYY-MM-DD') " + +// "AND T.IS_DELETED = 0 " + +// "AND NOT EXISTS ( " + +// "SELECT 1 FROM SD_WTRV_R S " + +// "WHERE S.STCD = T.STCD " + +// "AND TRUNC(S.TM) = T.DT " + +// "AND S.TM >= TO_DATE(? || ' 00:00:00', 'YYYY-MM-DD HH24:MI:SS') " + +// "AND S.TM <= TO_DATE(? || ' 23:59:59', 'YYYY-MM-DD HH24:MI:SS') " + +// "AND S.IS_DELETED = 0)"; + + jdbcTemplate.update(deleteSql, stcd, startDate, endDate, startDate, endDate); + + // 第二步:从小时数据聚合统计日数据 + String mergeSql = "MERGE INTO SD_WTRVDAY_S T " + + "USING ( " + + " SELECT " + + " STCD, " + + " TRUNC(TM) AS DT, " + + " AVG(WT) AS WT " + + " FROM SD_WTRV_R " + + " WHERE STCD = ? " + + " AND TM >= TO_DATE(? || ' 00:00:00', 'YYYY-MM-DD HH24:MI:SS') " + + " AND TM <= TO_DATE(? || ' 23:59:59', 'YYYY-MM-DD HH24:MI:SS') " + + " AND IS_DELETED = 0 " + + " GROUP BY STCD, TRUNC(TM) " + + ") S " + + "ON (T.STCD = S.STCD AND T.DT = S.DT) " + + "WHEN MATCHED THEN UPDATE SET " + + " T.WT = S.WT, " + + " T.IS_DELETED = 0, " + + " T.DELETE_TIME = NULL, " + + " T.MODIFY_TIME = SYSDATE " + + "WHEN NOT MATCHED THEN INSERT ( " + + " ID, STCD, DT, WT, RECORD_TIME, IS_DELETED " + + ") VALUES ( " + + " SYS_GUID(), S.STCD, S.DT, S.WT, SYSDATE, 0 " + + ")"; + + jdbcTemplate.update(mergeSql, stcd, startDate, endDate); + } + + /** + * 从日水温数据统计月数据(支持日期范围) + * @param stcd 测站编码 + * @param startDate 开始日期 yyyy-MM-dd + * @param endDate 结束日期 yyyy-MM-dd + */ + private void statisticsMonthDataFromDay(String stcd, String startDate, String endDate) { + // 解析年月 + String startYear = startDate.substring(0, 4); + String startMonth = startDate.substring(5, 7); + String endYear = endDate.substring(0, 4); + String endMonth = endDate.substring(5, 7); + + Integer startYearInt = Integer.parseInt(startYear); + Integer startMonthInt = Integer.parseInt(startMonth); + Integer endMonthInt = Integer.parseInt(endMonth); + + // 第一步:标记没有对应日数据的月记录为删除 +// String deleteSql = "UPDATE SD_WTRVDRTP_S T " + +// "SET T.IS_DELETED = 1, " + +// "T.DELETE_TIME = SYSDATE, " + +// "T.MODIFY_TIME = SYSDATE " + +// "WHERE T.DRTP = 'MON' " + +// "AND T.STCD = ? " + +// "AND T.YEAR = ? " + +// "AND T.MONTH BETWEEN ? AND ? " + +// "AND T.IS_DELETED = 0 " + +// "AND NOT EXISTS ( " + +// " SELECT 1 FROM SD_WTRVDAY_S D " + +// " WHERE D.STCD = T.STCD " + +// " AND D.IS_DELETED = 0 " + +// " AND EXTRACT(YEAR FROM D.DT) = T.YEAR " + +// " AND EXTRACT(MONTH FROM D.DT) = T.MONTH " + +// " AND D.DT >= TO_DATE(?, 'YYYY-MM-DD') " + +// " AND D.DT < TO_DATE(?, 'YYYY-MM-DD') + 1)"; + + String deleteSql = "DELETE FROM SD_WTRVDRTP_S T " + + "WHERE T.DRTP = 'MON' " + + "AND T.STCD = ? " + + "AND T.YEAR = ? " + + "AND T.MONTH BETWEEN ? AND ? " + + "AND NOT EXISTS ( " + + " SELECT 1 FROM SD_WTRVDAY_S D " + + " WHERE D.STCD = T.STCD " + + " AND D.IS_DELETED = 0 " + + " AND EXTRACT(YEAR FROM D.DT) = T.YEAR " + + " AND EXTRACT(MONTH FROM D.DT) = T.MONTH " + + " AND D.DT >= TO_DATE(?, 'YYYY-MM-DD') " + + " AND D.DT < TO_DATE(?, 'YYYY-MM-DD') + 1)"; + + jdbcTemplate.update(deleteSql, stcd, startYearInt, startMonthInt, endMonthInt, startDate, endDate); + + // 第二步:从日数据聚合统计月数据 + String mergeSql = "MERGE INTO SD_WTRVDRTP_S T " + + "USING ( " + + " SELECT " + + " STCD, " + + " EXTRACT(YEAR FROM DT) AS YEAR, " + + " EXTRACT(MONTH FROM DT) AS MONTH, " + + " 'MON' AS DRTP, " + + " AVG(WT) AS WT " + + " FROM SD_WTRVDAY_S " + + " WHERE STCD = ? " + + " AND DT >= TO_DATE(?, 'YYYY-MM-DD') " + + " AND DT < TO_DATE(?, 'YYYY-MM-DD') + 1 " + + " AND IS_DELETED = 0 " + + " GROUP BY STCD, EXTRACT(YEAR FROM DT), EXTRACT(MONTH FROM DT) " + + ") S " + + "ON (T.STCD = S.STCD AND T.DRTP = 'MON' AND T.YEAR = S.YEAR AND T.MONTH = S.MONTH) " + + "WHEN MATCHED THEN UPDATE SET " + + " T.WT = S.WT, " + + " T.IS_DELETED = 0, " + + " T.DELETE_USER = NULL, " + + " T.DELETE_TIME = NULL, " + + " T.MODIFY_USER = USER, " + + " T.MODIFY_TIME = SYSDATE, " + + " T.TM = SYSDATE " + + "WHEN NOT MATCHED THEN INSERT ( " + + " ID, STCD, WT, DRTP, YEAR, MONTH, DR, RECORD_TIME, IS_DELETED, TM " + + ") VALUES ( " + + " SYS_GUID(), S.STCD, S.WT, 'MON', S.YEAR, S.MONTH, NULL, SYSDATE, 0, SYSDATE " + + ")"; + + jdbcTemplate.update(mergeSql, stcd, startDate, endDate); + } + + + @Override + public void updateWtrvRData(Map updateData) { + sdWtrvdrtpSMapper.updateWtrvRData(updateData); + + // 获取测站编码和时间 + String stcd = (String) updateData.get("stcd"); + String tm = (String) updateData.get("dt"); + + if (StrUtil.isNotBlank(stcd) && StrUtil.isNotBlank(tm)) { + // 提取日期部分(yyyy-MM-dd) + String dateStr = tm.substring(0, 10); + + // 从小时水温数据统计日数据 + statisticsDayDataFromHour(stcd, dateStr, dateStr); + + // 从日水温数据统计月数据(统计该日期所在月份) + String yearMonth = dateStr.substring(0, 7); + String[] ym = yearMonth.split("-"); + if (ym.length == 2) { + Integer year = Integer.parseInt(ym[0]); + Integer month = Integer.parseInt(ym[1]); + String startDate = year + "-" + String.format("%02d", month) + "-01"; + String endDate = getMonthEndDate(year, month); + statisticsMonthDataFromDay(stcd, startDate, endDate); + } + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/utils/CollectionExtUtils.java b/backend/src/main/java/com/yfd/platform/utils/CollectionExtUtils.java new file mode 100644 index 0000000..dc49148 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/utils/CollectionExtUtils.java @@ -0,0 +1,257 @@ +package com.yfd.platform.utils; + +import com.google.common.base.Objects; +import com.google.common.collect.Maps; +import org.apache.commons.lang3.StringUtils; + +import java.math.BigDecimal; +import java.util.*; + +/** + * description: + *
+ *      template
+ * 
+ * + * @author supeng + * @date 2018 -08-30 14:53 + */ +@SuppressWarnings({"WeakerAccess", "unused"}) +public class CollectionExtUtils { + + /** + * 内存分页 + * + * @param // + * @param datas // + * @param row // + * @param page // + * @return // + */ + public static List getBatch(Collection datas, Integer row, Integer page) { + List> batchCollection = getBatch(datas, row); + if (batchCollection.isEmpty()) { + return new ArrayList<>(); + } + page = (page == null || page < 1) ? 1 : page; + if (batchCollection.size() >= page) { + return (List) batchCollection.get(page - 1); + } else { + return (List) batchCollection.get(batchCollection.size() - 1); + } + } + + /** + * 对集合数据, 进行批次 + * + * @param // + * @param datas // + * @param row // + * @return // + */ + public static List> getBatch(Collection datas, Integer row) { + List> result = new ArrayList<>(); + if (datas == null || datas.isEmpty()) { + return result; + } + //批量每次最多条数, 默认:100 + row = (row == null || row < 1) ? 100 : row; + int sourListSize = datas.size(); + int subCount = (sourListSize % row == 0) ? sourListSize / row : sourListSize / row + 1; + int startIndex = 0; + int stopIndex = 0; + List collectionDataList = new ArrayList<>(datas); + for (int i = 0; i < subCount; i++) { + stopIndex = ((i == subCount - 1) && (sourListSize % row != 0)) ? stopIndex + sourListSize % row : stopIndex + row; + List es = collectionDataList.subList(startIndex, stopIndex); + result.add(es); + startIndex = stopIndex; + } + return result; + } + + /** + * List 2 iterator array iterator. + * + * @param list the list + * @return the iterator + */ + public static Iterator convertIteratorArray(List list) { + List dataToBeReturned = new ArrayList<>(); + for (Object item : list) { + dataToBeReturned.add(new Object[]{item}); + } + return dataToBeReturned.iterator(); + } + + /** + * Gets map key by value. + * + * @param findValue the find value + * @param map the map + * @return the map key by value + */ + public static Object getMapKey(Object findValue, Map map) { + if (!map.containsValue(findValue)) { + return null; + } + for (Map.Entry entry : map.entrySet()) { + if (findValue.equals(entry.getValue())) { + return entry.getKey(); + } + } + return null; + } + + public static V getMapKey(Object findValue, Map map, Class valType) { + Object mapKey = getMapKey(findValue, map); + //noinspection unchecked + return mapKey == null ? null : (V) mapKey; + } + + /** + * 移除map中空key或者value空值 + * + * @param map // + */ + public static void removeNullEntry(Map map) { + removeNullKey(map); + removeNullValue(map); + } + + /** + * 移除map的空key + * + * @param map // + * @return // + */ + public static void removeNullKey(Map map) { + Set set = map.keySet(); + for (Iterator iterator = set.iterator(); iterator.hasNext(); ) { + Object obj = (Object) iterator.next(); + remove(obj, iterator); + } + } + + /** + * 移除map中的value空值 + * + * @param map + * @return + */ + public static void removeNullValue(Map map) { + Set set = map.keySet(); + for (Iterator iterator = set.iterator(); iterator.hasNext(); ) { + Object obj = (Object) iterator.next(); + Object value = (Object) map.get(obj); + remove(value, iterator); + } + } + + /** + * 移除map中的空值 + *

+ * Iterator 是工作在一个独立的线程中, 并且拥有一个 mutex 锁. Iterator + * 被创建之后会建立一个指向原来对象的单链索引表, 当原来的对象数量发生变化时, 这个索引表的内容不会同步改变, + * 所以当索引指针往后移动的时候就找不到要迭代的对象, 所以按照 fail-fast 原则 Iterator 会马上抛出 + * java.util.ConcurrentModificationException 异常. 所以 Iterator + * 在工作的时候是不允许被迭代的对象被改变的. 但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() + * 方法会在删除当前迭代对象的同时维护索引的一致性. + * + * @param obj + * @param iterator + */ + private static void remove(Object obj, Iterator iterator) { + if (obj instanceof String) { + String str = (String) obj; + if (StringUtils.isEmpty(str)) { // 过滤掉为null和""的值 主函数输出结果map:{2=BB, 1=AA, 5=CC, 8= } +// if("".equals(str.trim())){ //过滤掉为null、""和" "的值 主函数输出结果map:{2=BB, 1=AA, 5=CC} + iterator.remove(); + } + + } else if (obj instanceof Collection) { + Collection col = (Collection) obj; + if (col == null || col.isEmpty()) { + iterator.remove(); + } + + } else if (obj instanceof Map) { + Map temp = (Map) obj; + if (temp == null || temp.isEmpty()) { + iterator.remove(); + } + + } else if (obj instanceof Object[]) { + Object[] array = (Object[]) obj; + if (array == null || array.length <= 0) { + iterator.remove(); + } + } else { + if (obj == null) { + iterator.remove(); + } + } + } + + /** + * 过滤未修改的数据 主键不过滤 + * + * @param map + * @return + */ + public static Map cleanModifyMap(Map map) { + Map mapModify = Maps.newHashMap(); + if (null == map || null == map.get("modifyKeys")) { + return null; + } + //只修改数据来源不提交 +// if(null != map.get("modifyKeys") && (Objects.equal(map.get("modifyKeys").toString(), "[vlsr]") || Objects.equal(map.get("modifyKeys").toString(), "[valuesr]"))) { +// return null; +// } + String modifyKeys = map.get("modifyKeys").toString().replace("[", "").replace("]", ""); + String[] modifyKeyStr = modifyKeys.split(","); + + for (Map.Entry mapEntry : map.entrySet()) { + //非key的字段不过滤 + if (Objects.equal(mapEntry.getKey(), "stcd") || Objects.equal(mapEntry.getKey(), "blprd") || + Objects.equal(mapEntry.getKey(), "spcd") || Objects.equal(mapEntry.getKey(), "mchgrno") || Objects.equal(mapEntry.getKey(), "vlsr")) { + mapModify.put(mapEntry.getKey(), mapEntry.getValue()); + } + for (int i = 0; i < modifyKeyStr.length; i++) { + //主键不过滤 + if (Objects.equal(modifyKeyStr[i].trim(), mapEntry.getKey())) { + mapModify.put(mapEntry.getKey(), mapEntry.getValue()); + } + } + } + return mapModify; + } + + /** + * 根据给定值,获取其前后的数值 + * @param list + * @param target + * @return + */ + public static BigDecimal[] findNeighbors(List list, BigDecimal target) { + int index = list.indexOf(target); + // 如果找到了目标数字 + if (index >= 0) { + BigDecimal before = (index > 0) ? list.get(index - 1) : null; // 前一个数字 + BigDecimal after = (index < list.size() - 1) ? list.get(index + 1) : null; // 后一个数字 + return new BigDecimal[]{before, after}; + } else { + for(int i = 0; i < list.size(); i++){ + //找到比target大的位置 + if(target.compareTo(list.get(i))<0){ + index=i; + break; + } + } + //取前后的值 + BigDecimal before = (index <= 0) ? null: list.get(index-1); // 前一个数字 + BigDecimal after = (index < 0 || index == list.size()-1)?null:(list.get(index)); // 后一个数字 + return new BigDecimal[]{before, after}; + } + } +} \ No newline at end of file diff --git a/backend/src/main/resources/application-devtw.yml b/backend/src/main/resources/application-devtw.yml index d571469..a2533b1 100644 --- a/backend/src/main/resources/application-devtw.yml +++ b/backend/src/main/resources/application-devtw.yml @@ -11,13 +11,13 @@ spring: master: driverClassName: oracle.jdbc.OracleDriver url: "${DB_MASTER_URL:jdbc:oracle:thin:@172.16.21.134:1521/SDLYZ}" - username: "${DB_MASTER_USERNAME:QGC}" - password: "${DB_MASTER_PASSWORD:ar6Yr7Vxo5}" + username: "${DB_MASTER_USERNAME:QGC_REFA}" + password: "${DB_MASTER_PASSWORD:Y4M4K1oCkL8U}" slave: driverClassName: oracle.jdbc.OracleDriver url: "${DB_SLAVE_URL:jdbc:oracle:thin:@172.16.21.134:1521/SDLYZ}" - username: "${DB_SLAVE_USERNAME:QGC}" - password: "${DB_SLAVE_PASSWORD:ar6Yr7Vxo5}" + username: "${DB_SLAVE_USERNAME:QGC_REFA}" + password: "${DB_SLAVE_PASSWORD:Y4M4K1oCkL8U}" mvc: pathmatch: