feat: 生态流量达标情况

This commit is contained in:
tangwei 2026-06-03 10:06:44 +08:00
parent d2432c77e9
commit a2e81f5f42
4 changed files with 781 additions and 0 deletions

View File

@ -3,6 +3,7 @@ package com.yfd.platform.qgc_eng.eq.controller;
import com.yfd.platform.common.DataSourceLoadOptionsBase; import com.yfd.platform.common.DataSourceLoadOptionsBase;
import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceRequest;
import com.yfd.platform.config.ResponseResult; import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqIntervalVo;
import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqVmsstbprptVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqVmsstbprptVo;
import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRateCountVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRateCountVo;
import com.yfd.platform.qgc_eng.eq.service.EngEqDataService; import com.yfd.platform.qgc_eng.eq.service.EngEqDataService;
@ -32,6 +33,12 @@ public class EngEqDataController {
return ResponseResult.successData(engEqDataService.getKendoListCust(dataSourceRequest)); return ResponseResult.successData(engEqDataService.getKendoListCust(dataSourceRequest));
} }
@PostMapping("/interval/GetKendoListCust")
@Operation(summary = "生态流量达标情况")
public ResponseResult getIntervalKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
return ResponseResult.successData(engEqDataService.getIntervalKendoListCust(dataSourceRequest));
}
@PostMapping("/interval/qgc/getQgcStaticData") @PostMapping("/interval/qgc/getQgcStaticData")
@Operation(summary = "生态流量达标率区间范围统计(一级页面)") @Operation(summary = "生态流量达标率区间范围统计(一级页面)")
public ResponseResult getQgcStaticData(@RequestBody DataSourceRequest dataSourceRequest) { public ResponseResult getQgcStaticData(@RequestBody DataSourceRequest dataSourceRequest) {

View File

@ -0,0 +1,125 @@
package com.yfd.platform.qgc_eng.eq.entity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Data
@Schema(description = "生态流量达标情况")
public class EngEqIntervalVo {
@Schema(description = "电站编码")
private String stcd;
@Schema(description = "电站名称")
private String stnm;
@Schema(description = "工程名称")
private String ennm;
@Schema(description = "站类")
private String sttp;
@Schema(description = "站类编码")
private String sttpCode;
@Schema(description = "基地编码")
private String baseId;
@Schema(description = "基地名称")
private String baseName;
@Schema(description = "基地流域编码")
private String hbrvcd;
@Schema(description = "基地流域名称")
private String hbrvcdName;
@Schema(description = "行政区名称")
private String addvcdName;
@Schema(description = "经度")
private BigDecimal lgtd;
@Schema(description = "纬度")
private BigDecimal lttd;
@Schema(description = "高程")
private BigDecimal dtmel;
@Schema(description = "是否接入")
private Integer dtin;
@Schema(description = "环保数据接入状态")
private Integer dtinEnv;
@Schema(description = "工程规模")
private Integer prsc;
@Schema(description = "建设状态分类")
private Integer bldsttCcode;
@Schema(description = "入库流量")
private BigDecimal qi;
@Schema(description = "出库流量")
private BigDecimal qo;
@Schema(description = "生态流量限值")
private BigDecimal qecLimit;
@Schema(description = "生态流量")
private BigDecimal qec;
@Schema(description = "坝上水位")
private BigDecimal rz;
@Schema(description = "坝下水位")
private BigDecimal dz;
@Schema(description = "生态流量达标率")
private BigDecimal qecRate;
@Schema(description = "去年同期生态流量达标率")
private BigDecimal beforeQecRate;
@Schema(description = "生态流量达标率区间")
private String qecInterval;
@Schema(description = "锚点状态")
private String anchoPointState;
@Schema(description = "环保部达标数")
private Integer qecSfdbHy;
@Schema(description = "环保部不达标数")
private Integer qecSfdbHn;
@Schema(description = "环保部统计数")
private Integer qecSfdbCount;
@Schema(description = "环保部异常数")
private Integer qecSfdbHo;
@Schema(description = "入库流量合计")
private BigDecimal qiSum;
@Schema(description = "出库流量合计")
private BigDecimal qoSum;
@Schema(description = "补水总量")
private BigDecimal fillWater;
@Schema(description = "基地排序")
private Integer baseStepSort;
@Schema(description = "流域排序")
private Integer rvcdStepSort;
@Schema(description = "电站排序")
private Integer rstcdStepSort;
@Schema(description = "站点排序")
private Integer siteStepSort;
}

View File

@ -2,6 +2,7 @@ package com.yfd.platform.qgc_eng.eq.service;
import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceRequest;
import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.common.DataSourceResult;
import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqIntervalVo;
import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRateCountVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRateCountVo;
import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqVmsstbprptVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqVmsstbprptVo;
import com.yfd.platform.qgc_eng.eq.entity.vo.QgcQecStaticVo; import com.yfd.platform.qgc_eng.eq.entity.vo.QgcQecStaticVo;
@ -12,6 +13,8 @@ public interface EngEqDataService {
DataSourceResult getKendoListCust(DataSourceRequest dataSourceRequest); DataSourceResult getKendoListCust(DataSourceRequest dataSourceRequest);
DataSourceResult<EngEqIntervalVo> getIntervalKendoListCust(DataSourceRequest dataSourceRequest);
QgcQecStaticVo getQgcStaticData(DataSourceRequest dataSourceRequest, String type); QgcQecStaticVo getQgcStaticData(DataSourceRequest dataSourceRequest, String type);
DataSourceResult<WbsbVo> getWbsbList(DataSourceRequest dataSourceRequest); DataSourceResult<WbsbVo> getWbsbList(DataSourceRequest dataSourceRequest);

View File

@ -12,6 +12,7 @@ import com.yfd.platform.common.MicroservicDynamicSQLMapper;
import com.yfd.platform.common.enums.QecIntervalEnum; import com.yfd.platform.common.enums.QecIntervalEnum;
import com.yfd.platform.common.enums.ShowEnum; import com.yfd.platform.common.enums.ShowEnum;
import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDataVo;
import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqIntervalVo;
import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRateCountVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRateCountVo;
import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqStaticIntervalVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqStaticIntervalVo;
import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqVmsstbprptVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqVmsstbprptVo;
@ -32,6 +33,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
@ -50,6 +52,15 @@ public class EngEqDataServiceImpl implements EngEqDataService {
return queryGroupList(dataSourceRequest, loadOptions); return queryGroupList(dataSourceRequest, loadOptions);
} }
@Override
public DataSourceResult<EngEqIntervalVo> getIntervalKendoListCust(DataSourceRequest dataSourceRequest) {
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
if (CollUtil.isEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) {
return queryIntervalDetailList(dataSourceRequest, loadOptions);
}
return queryIntervalGroupList(dataSourceRequest, loadOptions);
}
@Override @Override
public QgcQecStaticVo getQgcStaticData(DataSourceRequest dataSourceRequest, String type) { public QgcQecStaticVo getQgcStaticData(DataSourceRequest dataSourceRequest, String type) {
List<EngEqStaticIntervalVo> intervalList = queryStaticIntervals(dataSourceRequest, type); List<EngEqStaticIntervalVo> intervalList = queryStaticIntervals(dataSourceRequest, type);
@ -263,6 +274,486 @@ public class EngEqDataServiceImpl implements EngEqDataService {
return result; return result;
} }
private DataSourceResult<EngEqIntervalVo> queryIntervalDetailList(DataSourceRequest dataSourceRequest,
DataSourceLoadOptionsBase loadOptions) {
Map<String, Object> paramMap = new HashMap<>();
int[] indexHolder = new int[]{0};
String viewSql = buildIntervalViewSql(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, indexHolder);
StringBuilder sql = new StringBuilder();
sql.append("SELECT ")
.append(buildIntervalDetailSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect()))
.append(" FROM (")
.append(viewSql)
.append(") t WHERE 1 = 1 ");
String filterSql = buildIntervalFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, indexHolder);
if (StrUtil.isNotBlank(filterSql)) {
sql.append(" AND ").append(filterSql).append(" ");
}
if (CollUtil.isNotEmpty(dataSourceRequest == null ? null : dataSourceRequest.getAggregate())
&& "average".equalsIgnoreCase(dataSourceRequest.getAggregate().get(0).getAggregate())) {
return buildIntervalAggregateResult(dataSourceRequest, sql.toString(), paramMap);
}
sql.append(buildIntervalDetailOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort()));
Page<?> page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake());
List<EngEqIntervalVo> list = microservicDynamicSQLMapper.pageAllListWithResultType(page, sql.toString(), paramMap, EngEqIntervalVo.class);
postProcessIntervalList(list);
DataSourceResult<EngEqIntervalVo> result = new DataSourceResult<>();
result.setData(list);
result.setTotal(page != null ? page.getTotal() : list.size());
result.setAggregates(new HashMap<>());
return result;
}
private DataSourceResult<EngEqIntervalVo> queryIntervalGroupList(DataSourceRequest dataSourceRequest,
DataSourceLoadOptionsBase loadOptions) {
List<DataSourceRequest.GroupDescriptor> groups = dataSourceRequest.getGroup();
GroupingInfo[] groupInfos = loadOptions == null ? new GroupingInfo[0] : loadOptions.getGroup();
Map<String, Object> paramMap = new HashMap<>();
int[] indexHolder = new int[]{0};
String viewSql = buildIntervalViewSql(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, indexHolder);
List<String> selectItems = new ArrayList<>();
for (DataSourceRequest.GroupDescriptor descriptor : groups) {
if (descriptor == null || StrUtil.isBlank(descriptor.getField())) {
continue;
}
String column = mapIntervalColumn(descriptor.getField());
if (StrUtil.isBlank(column)) {
continue;
}
selectItems.add(column + " AS " + descriptor.getField().toUpperCase());
selectItems.add("COUNT(*) AS COUNT_" + descriptor.getField().toUpperCase());
if (CollUtil.isNotEmpty(descriptor.getAggregates())) {
for (DataSourceRequest.AggregateDescriptor aggregate : descriptor.getAggregates()) {
String aggregateColumn = mapIntervalColumn(aggregate.getField());
if (StrUtil.isBlank(aggregateColumn) || StrUtil.isBlank(aggregate.getAggregate())) {
continue;
}
selectItems.add(buildAggregateSql(aggregate.getAggregate(), aggregateColumn, aggregate.getField()));
}
}
}
if (selectItems.isEmpty()) {
selectItems.add("t.STCD AS STCD");
selectItems.add("COUNT(*) AS COUNT_STCD");
}
StringBuilder sql = new StringBuilder();
sql.append("SELECT ")
.append(String.join(", ", selectItems))
.append(" FROM (")
.append(viewSql)
.append(") t WHERE 1 = 1 ");
String filterSql = buildIntervalFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, indexHolder);
if (StrUtil.isNotBlank(filterSql)) {
sql.append(" AND ").append(filterSql).append(" ");
}
List<String> groupByColumns = new ArrayList<>();
for (DataSourceRequest.GroupDescriptor descriptor : groups) {
if (descriptor == null || StrUtil.isBlank(descriptor.getField())) {
continue;
}
String column = mapIntervalColumn(descriptor.getField());
if (StrUtil.isNotBlank(column)) {
groupByColumns.add(column);
}
}
if (!groupByColumns.isEmpty()) {
sql.append(" GROUP BY ").append(String.join(", ", groupByColumns)).append(" ");
}
sql.append(buildIntervalGroupOrderBySql(groups));
List<Map<String, Object>> rows = microservicDynamicSQLMapper.pageAllList(null, sql.toString(), paramMap);
DataSourceResult<EngEqIntervalVo> result = new DataSourceResult<>();
if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) {
result.setData((List<EngEqIntervalVo>) (List<?>) new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos)));
} else {
result.setData((List<EngEqIntervalVo>) (List<?>) new GroupHelper().group(rows, Arrays.asList(groupInfos)));
}
result.setTotal(0L);
result.setAggregates(new HashMap<>());
return result;
}
private DataSourceResult<EngEqIntervalVo> buildIntervalAggregateResult(DataSourceRequest dataSourceRequest,
String sourceSql,
Map<String, Object> paramMap) {
List<String> aggregateItems = new ArrayList<>();
for (DataSourceRequest.AggregateDescriptor item : dataSourceRequest.getAggregate()) {
if (item == null || !"average".equalsIgnoreCase(item.getAggregate())) {
continue;
}
String column = mapIntervalColumn(item.getField());
if (StrUtil.isBlank(column)) {
continue;
}
aggregateItems.add("AVG(" + column + ") AS " + item.getField());
}
if (aggregateItems.isEmpty()) {
DataSourceResult<EngEqIntervalVo> emptyResult = new DataSourceResult<>();
emptyResult.setData(new ArrayList<>());
emptyResult.setTotal(0L);
emptyResult.setAggregates(new HashMap<>());
return emptyResult;
}
String sql = "SELECT " + String.join(", ", aggregateItems) + " FROM (" + sourceSql + ")";
List<Map<String, Object>> list = microservicDynamicSQLMapper.pageAllList(null, sql, paramMap);
DataSourceResult<EngEqIntervalVo> result = new DataSourceResult<>();
result.setData((List<EngEqIntervalVo>) (List<?>) list);
result.setTotal(0L);
result.setAggregates(new HashMap<>());
return result;
}
private void postProcessIntervalList(List<EngEqIntervalVo> list) {
if (CollUtil.isEmpty(list)) {
return;
}
for (EngEqIntervalVo item : list) {
if (item == null || item.getQiSum() == null || item.getQoSum() == null) {
continue;
}
item.setFillWater(item.getQoSum().subtract(item.getQiSum()));
}
}
private String buildIntervalViewSql(DataSourceRequest.FilterDescriptor filter,
Map<String, Object> paramMap,
int[] indexHolder) {
boolean hasTmFilter = hasIntervalTmFilter(filter);
String beforeMetricSql = hasTmFilter
? buildIntervalMetricSourceSql(filter, paramMap, indexHolder, -1)
: "SELECT CAST(NULL AS VARCHAR2(36)) AS STCD, CAST(NULL AS NUMBER(18,6)) AS QEC_RATE FROM DUAL";
return "SELECT " +
"eng.STCD AS stcd, " +
"eng.ENNM AS stnm, " +
"eng.ENNM AS ennm, " +
"'ENG' AS sttp, " +
"'ENG' AS sttpCode, " +
"eng.BASE_ID AS baseId, " +
"hb.BASENAME AS baseName, " +
"eng.HBRVCD AS hbrvcd, " +
"hbrv.HBRVNM AS hbrvcdName, " +
"addv.ADDVNM AS addvcdName, " +
"eng.LGTD AS lgtd, " +
"eng.LTTD AS lttd, " +
"eng.ELEV AS dtmel, " +
"eng.DTIN AS dtin, " +
"eng.DTIN_ENV AS dtinEnv, " +
"eng.PRSC AS prsc, " +
"eng.BLDSTT_CODE AS bldsttCcode, " +
"met.QI AS qi, " +
"met.QO AS qo, " +
"met.QEC_LIMIT AS qecLimit, " +
"met.QEC AS qec, " +
"met.RZ AS rz, " +
"met.DZ AS dz, " +
buildIntervalRateDisplaySql("met.QEC_RATE") + " AS qecRate, " +
buildIntervalRateDisplaySql("beforeMet.QEC_RATE") + " AS beforeQecRate, " +
buildIntervalQecIntervalSql() + " AS qecInterval, " +
buildIntervalAnchorPointStateSql() + " AS anchoPointState, " +
"met.QEC_SFDB_HY AS qecSfdbHy, " +
"met.QEC_SFDB_HN AS qecSfdbHn, " +
"met.QEC_SFDB_COUNT AS qecSfdbCount, " +
"met.QEC_SFDB_HO AS qecSfdbHo, " +
"met.QI_SUM AS qiSum, " +
"met.QO_SUM AS qoSum, " +
"CAST(NULL AS NUMBER(18,6)) AS fillWater, " +
"NVL(hb.ORDER_INDEX, 999999) AS baseStepSort, " +
"NVL(along.ORDER_INDEX, 999999) AS rvcdStepSort, " +
"NVL(rstSort.SORT, 999999) AS rstcdStepSort, " +
"NVL(siteSort.SORT, 999999) AS siteStepSort " +
"FROM SD_ENGINFO_B_H eng " +
"LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " +
"LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eng.HBRVCD AND hbrv.BASEID = eng.BASE_ID " +
" AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1 " +
"LEFT JOIN SD_ADDVCD_DIC addv ON addv.ADDVCD = eng.ADDVCD " +
"LEFT JOIN MS_ALONG_B along ON along.RVCD = eng.HBRVCD AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 " +
"LEFT JOIN ( " +
" SELECT det.SORT, cfg.RVCD, det.STCD " +
" FROM MS_ALONGDET_B det " +
" INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID " +
" WHERE NVL(det.IS_DELETED, 0) = 0 AND NVL(cfg.IS_DELETED, 0) = 0 AND cfg.CODE = 'common' " +
") rstSort ON rstSort.RVCD = eng.HBRVCD AND rstSort.STCD = eng.STCD " +
"LEFT JOIN ( " +
" SELECT det.SORT, cfg.RVCD, det.STCD " +
" FROM MS_ALONGDET_B det " +
" INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID " +
" WHERE NVL(det.IS_DELETED, 0) = 0 AND NVL(cfg.IS_DELETED, 0) = 0 AND cfg.CODE = 'common' " +
") siteSort ON siteSort.RVCD = eng.HBRVCD AND siteSort.STCD = eng.STCD " +
"LEFT JOIN (" + buildIntervalMetricSourceSql(filter, paramMap, indexHolder, 0) + ") met ON met.STCD = eng.STCD " +
"LEFT JOIN (" + beforeMetricSql + ") beforeMet ON beforeMet.STCD = eng.STCD " +
"LEFT JOIN (" + buildIntervalNoRuleSql() + ") qecNoRule ON qecNoRule.STCD = eng.STCD " +
"WHERE NVL(eng.IS_DELETED, 0) = 0 AND NVL(eng.BLDSTT_CODE, 0) = 2";
}
private String buildIntervalMetricSourceSql(DataSourceRequest.FilterDescriptor filter,
Map<String, Object> paramMap,
int[] indexHolder,
int yearOffset) {
String qecTimeFilter = buildIntervalTmFilterCondition(filter, "qec.DT", paramMap, indexHolder, yearOffset);
String runTimeFilter = buildIntervalTmFilterCondition(filter, "run.TM", paramMap, indexHolder, yearOffset);
return "SELECT qec.STCD, " +
"AVG(runAgg.QI) AS QI, " +
"AVG(runAgg.QO) AS QO, " +
"AVG(qec.QEC_LIMIT) AS QEC_LIMIT, " +
"AVG(qec.QEC) AS QEC, " +
"AVG(runAgg.RZ) AS RZ, " +
"AVG(runAgg.DZ) AS DZ, " +
buildIntervalQecRateSql("qec") + " AS QEC_RATE, " +
buildIntervalQrSql("qec") + " AS QR, " +
"SUM(CASE WHEN qec.SFDB = 1 THEN 1 ELSE 0 END) AS QEC_SFDB_HY, " +
"SUM(CASE WHEN qec.SFDB = 0 THEN 1 ELSE 0 END) AS QEC_SFDB_HN, " +
"SUM(CASE WHEN qec.SFDB IN (0, 1) THEN 1 ELSE 0 END) AS QEC_SFDB_COUNT, " +
"SUM(CASE WHEN qec.SFDB NOT IN (0, 1) OR qec.SFDB IS NULL THEN 1 ELSE 0 END) AS QEC_SFDB_HO, " +
"SUM(NVL(runAgg.QI_SUM_DAY, 0)) AS QI_SUM, " +
"SUM(NVL(runAgg.QO_SUM_DAY, 0)) AS QO_SUM " +
"FROM SD_QECDAY_S qec " +
"LEFT JOIN (SELECT run.STCD, TRUNC(run.TM) AS DT, AVG(run.QI) AS QI, AVG(run.QO) AS QO, AVG(run.RZ) AS RZ, AVG(run.DZ) AS DZ, " +
"SUM(run.QI) AS QI_SUM_DAY, SUM(run.QO) AS QO_SUM_DAY " +
"FROM SD_HYDROPW_R run WHERE NVL(run.IS_DELETED, 0) = 0 " +
(StrUtil.isNotBlank(runTimeFilter) ? " AND " + runTimeFilter : "") +
" GROUP BY run.STCD, TRUNC(run.TM)) runAgg ON runAgg.STCD = qec.STCD AND runAgg.DT = qec.DT " +
"WHERE NVL(qec.IS_DELETED, 0) = 0 " +
(StrUtil.isNotBlank(qecTimeFilter) ? " AND " + qecTimeFilter : "") +
" GROUP BY qec.STCD";
}
private String buildIntervalQecRateSql(String alias) {
return "CASE " +
"WHEN COUNT(*) = 0 THEN NULL " +
"WHEN SUM(CASE WHEN " + alias + ".QEC_LIMIT IS NULL AND " + alias + ".MWR_LIMIT IS NULL AND " + alias + ".AVQ_LIMIT IS NULL THEN 0 ELSE 1 END) = 0 THEN -1 " +
"WHEN SUM(CASE WHEN (" + alias + ".QEC_LIMIT IS NOT NULL OR " + alias + ".MWR_LIMIT IS NOT NULL OR " + alias + ".AVQ_LIMIT IS NOT NULL) AND " + alias + ".QEC IS NULL THEN 0 ELSE 1 END) = 0 THEN -2 " +
"WHEN SUM(CASE " +
"WHEN " + alias + ".SFDB IN (0, 1) THEN 1 " +
"WHEN " + alias + ".SFDB = 2 AND " + alias + ".MWR_SFDB IN (0, 1) THEN 1 " +
"WHEN " + alias + ".MWR_SFDB = 2 AND " + alias + ".AVQ_SFDB IN (0, 1) THEN 1 " +
"ELSE 0 END) = 0 THEN NULL " +
"ELSE ((SUM(CASE " +
"WHEN " + alias + ".SFDB = 1 THEN 1 " +
"WHEN " + alias + ".SFDB = 0 THEN 0 " +
"WHEN " + alias + ".SFDB = 2 AND " + alias + ".MWR_SFDB = 1 THEN 1 " +
"WHEN " + alias + ".SFDB = 2 AND " + alias + ".MWR_SFDB = 0 THEN 0 " +
"WHEN " + alias + ".MWR_SFDB = 2 AND " + alias + ".AVQ_SFDB = 1 THEN 1 " +
"WHEN " + alias + ".MWR_SFDB = 2 AND " + alias + ".AVQ_SFDB = 0 THEN 0 " +
"ELSE 0 END) / NULLIF(SUM(CASE " +
"WHEN " + alias + ".SFDB IN (0, 1) THEN 1 " +
"WHEN " + alias + ".SFDB = 2 AND " + alias + ".MWR_SFDB IN (0, 1) THEN 1 " +
"WHEN " + alias + ".MWR_SFDB = 2 AND " + alias + ".AVQ_SFDB IN (0, 1) THEN 1 " +
"ELSE 0 END), 0)) * 100) END";
}
private String buildIntervalQrSql(String alias) {
return "CASE " +
"WHEN COUNT(*) = SUM(CASE WHEN " + alias + ".SFDB = 2 THEN 1 ELSE 0 END) THEN -1 " +
"WHEN COUNT(*) = SUM(CASE WHEN " + alias + ".SFDB = 3 THEN 1 ELSE 0 END) THEN -2 " +
"WHEN SUM(CASE WHEN " + alias + ".SFDB = 2 THEN 1 ELSE 0 END) > 0 " +
" AND COUNT(*) = SUM(CASE WHEN " + alias + ".SFDB = 2 THEN 1 ELSE 0 END) " +
" + SUM(CASE WHEN " + alias + ".SFDB = 3 THEN 1 ELSE 0 END) " +
" + SUM(CASE WHEN " + alias + ".SFDB IS NULL THEN 1 ELSE 0 END) THEN -1 " +
"WHEN SUM(CASE WHEN " + alias + ".SFDB = 2 THEN 1 ELSE 0 END) = 0 " +
" AND COUNT(*) = SUM(CASE WHEN " + alias + ".SFDB = 2 THEN 1 ELSE 0 END) " +
" + SUM(CASE WHEN " + alias + ".SFDB = 3 THEN 1 ELSE 0 END) " +
" + SUM(CASE WHEN " + alias + ".SFDB IS NULL THEN 1 ELSE 0 END) THEN -2 " +
"END";
}
private String buildIntervalAnchorPointStateSql() {
return "CASE " +
"WHEN (met.QEC_RATE IS NULL OR met.QEC_RATE IN (-1, -2)) AND eng.PRSC = 1 THEN 'eef_1_none' " +
"WHEN met.QEC_RATE >= 95 AND eng.PRSC = 1 THEN 'eef_1_1' " +
"WHEN met.QEC_RATE >= 90 AND met.QEC_RATE < 95 AND eng.PRSC = 1 THEN 'eef_1_2' " +
"WHEN met.QEC_RATE >= 80 AND met.QEC_RATE < 90 AND eng.PRSC = 1 THEN 'eef_1_3' " +
"WHEN met.QEC_RATE < 80 AND eng.PRSC = 1 THEN 'eef_1_4' " +
"WHEN (met.QEC_RATE IS NULL OR met.QEC_RATE IN (-1, -2)) AND eng.PRSC IN (2, 3) THEN 'eef_2_none' " +
"WHEN met.QEC_RATE >= 95 AND eng.PRSC IN (2, 3) THEN 'eef_2_1' " +
"WHEN met.QEC_RATE >= 90 AND met.QEC_RATE < 95 AND eng.PRSC IN (2, 3) THEN 'eef_2_2' " +
"WHEN met.QEC_RATE >= 80 AND met.QEC_RATE < 90 AND eng.PRSC IN (2, 3) THEN 'eef_2_3' " +
"WHEN met.QEC_RATE < 80 AND eng.PRSC IN (2, 3) THEN 'eef_2_4' " +
"END";
}
private String buildIntervalRateDisplaySql(String column) {
return "CASE WHEN " + column + " IN (-1, -2) THEN NULL ELSE " + column + " END";
}
private String buildIntervalQecIntervalSql() {
return "CASE " +
"WHEN qecNoRule.STCD IS NOT NULL THEN '" + QecIntervalEnum.QEC_STLL_6_NOEQMN.getCode() + "' " +
"WHEN met.QEC_RATE = -1 THEN '" + QecIntervalEnum.QEC_STLL_6_NOEQMN.getCode() + "' " +
"WHEN met.QEC_RATE IS NULL OR met.QEC_RATE = -2 THEN '" + QecIntervalEnum.QEC_STLL_5_EMPTY.getCode() + "' " +
"WHEN met.QEC_RATE >= 95 THEN '" + QecIntervalEnum.QEC_STLL_1_DY95.getCode() + "' " +
"WHEN met.QEC_RATE >= 90 AND met.QEC_RATE < 95 THEN '" + QecIntervalEnum.QEC_STLL_2_90AND95.getCode() + "' " +
"WHEN met.QEC_RATE >= 80 AND met.QEC_RATE < 90 THEN '" + QecIntervalEnum.QEC_STLL_3_80AND90.getCode() + "' " +
"WHEN met.QEC_RATE < 80 THEN '" + QecIntervalEnum.QEC_STLL_4_XY80.getCode() + "' " +
"END";
}
private String buildIntervalNoRuleSql() {
return "SELECT engRule.STCD " +
"FROM SD_ENGINFO_B_H engRule " +
"WHERE NVL(engRule.IS_DELETED, 0) = 0 " +
" AND engRule.AVQ IS NULL " +
" AND NOT EXISTS ( " +
" SELECT 1 FROM MS_WARN_RULE_B rule " +
" INNER JOIN MS_WARN_RULE_DETAIL_B detail ON detail.RULE_ID = rule.ID AND NVL(detail.IS_DELETED, 0) = 0 " +
" WHERE NVL(rule.IS_DELETED, 0) = 0 " +
" AND rule.RULE_TYPE IN ('EQMN', 'EQMNMWR') " +
" AND rule.STCD = engRule.STCD " +
" )";
}
private String buildIntervalDetailSelectSql(List<String> selectFields) {
Map<String, String> columns = intervalFieldColumns();
List<String> selected = new ArrayList<>();
if (CollUtil.isEmpty(selectFields)) {
selected.addAll(columns.values());
} else {
for (String field : selectFields) {
String column = columns.get(field);
if (StrUtil.isNotBlank(column)) {
selected.add(column);
}
}
if (selected.isEmpty()) {
selected.addAll(columns.values());
}
}
return String.join(", ", selected);
}
private Map<String, String> intervalFieldColumns() {
Map<String, String> columns = new LinkedHashMap<>();
columns.put("stcd", "t.stcd AS stcd");
columns.put("stnm", "t.stnm AS stnm");
columns.put("ennm", "t.ennm AS ennm");
columns.put("sttp", "t.sttp AS sttp");
columns.put("sttpCode", "t.sttpCode AS sttpCode");
columns.put("baseId", "t.baseId AS baseId");
columns.put("baseName", "t.baseName AS baseName");
columns.put("hbrvcd", "t.hbrvcd AS hbrvcd");
columns.put("hbrvcdName", "t.hbrvcdName AS hbrvcdName");
columns.put("addvcdName", "t.addvcdName AS addvcdName");
columns.put("lgtd", "t.lgtd AS lgtd");
columns.put("lttd", "t.lttd AS lttd");
columns.put("dtmel", "t.dtmel AS dtmel");
columns.put("dtin", "t.dtin AS dtin");
columns.put("dtinEnv", "t.dtinEnv AS dtinEnv");
columns.put("prsc", "t.prsc AS prsc");
columns.put("bldsttCcode", "t.bldsttCcode AS bldsttCcode");
columns.put("qi", "t.qi AS qi");
columns.put("qo", "t.qo AS qo");
columns.put("qecLimit", "t.qecLimit AS qecLimit");
columns.put("qec", "t.qec AS qec");
columns.put("rz", "t.rz AS rz");
columns.put("dz", "t.dz AS dz");
columns.put("qecRate", "t.qecRate AS qecRate");
columns.put("beforeQecRate", "t.beforeQecRate AS beforeQecRate");
columns.put("qecInterval", "t.qecInterval AS qecInterval");
columns.put("anchoPointState", "t.anchoPointState AS anchoPointState");
columns.put("qecSfdbHy", "t.qecSfdbHy AS qecSfdbHy");
columns.put("qecSfdbHn", "t.qecSfdbHn AS qecSfdbHn");
columns.put("qecSfdbCount", "t.qecSfdbCount AS qecSfdbCount");
columns.put("qecSfdbHo", "t.qecSfdbHo AS qecSfdbHo");
columns.put("qiSum", "t.qiSum AS qiSum");
columns.put("qoSum", "t.qoSum AS qoSum");
columns.put("fillWater", "t.fillWater AS fillWater");
columns.put("baseStepSort", "t.baseStepSort AS baseStepSort");
columns.put("rvcdStepSort", "t.rvcdStepSort AS rvcdStepSort");
columns.put("rstcdStepSort", "t.rstcdStepSort AS rstcdStepSort");
columns.put("siteStepSort", "t.siteStepSort AS siteStepSort");
return columns;
}
private String buildIntervalFilterCondition(DataSourceRequest.FilterDescriptor filter,
Map<String, Object> paramMap,
int[] indexHolder) {
if (filter == null) {
return "";
}
if (StrUtil.isNotBlank(filter.getField())) {
if ("tm".equalsIgnoreCase(filter.getField())) {
return "";
}
return buildIntervalLeafCondition(filter, paramMap, indexHolder);
}
if (CollUtil.isEmpty(filter.getFilters())) {
return "";
}
List<String> conditions = new ArrayList<>();
for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) {
String childSql = buildIntervalFilterCondition(child, paramMap, indexHolder);
if (StrUtil.isNotBlank(childSql)) {
conditions.add("(" + childSql + ")");
}
}
if (conditions.isEmpty()) {
return "";
}
String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND ";
return String.join(logic, conditions);
}
private String buildIntervalLeafCondition(DataSourceRequest.FilterDescriptor filter,
Map<String, Object> paramMap,
int[] indexHolder) {
String column = mapIntervalColumn(filter.getField());
if (StrUtil.isBlank(column)) {
return "";
}
return buildGenericCondition(column, filter, paramMap, indexHolder, false);
}
private String buildIntervalDetailOrderBySql(List<DataSourceRequest.SortDescriptor> sortList) {
if (CollUtil.isEmpty(sortList)) {
return " ORDER BY baseStepSort ASC, rvcdStepSort ASC, rstcdStepSort ASC, siteStepSort ASC, stcd ASC";
}
List<String> orders = new ArrayList<>();
for (DataSourceRequest.SortDescriptor sort : sortList) {
if (sort == null || StrUtil.isBlank(sort.getField())) {
continue;
}
String column = mapIntervalColumn(sort.getField());
if (StrUtil.isBlank(column)) {
continue;
}
String dir = "desc".equalsIgnoreCase(sort.getDir()) || "des".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC";
orders.add(column + " " + dir);
}
if (orders.isEmpty()) {
return " ORDER BY baseStepSort ASC, rvcdStepSort ASC, rstcdStepSort ASC, siteStepSort ASC, stcd ASC";
}
return " ORDER BY " + String.join(", ", orders);
}
private String buildIntervalGroupOrderBySql(List<DataSourceRequest.GroupDescriptor> groups) {
if (CollUtil.isEmpty(groups)) {
return "";
}
List<String> orders = new ArrayList<>();
for (DataSourceRequest.GroupDescriptor descriptor : groups) {
if (descriptor == null || StrUtil.isBlank(descriptor.getField())) {
continue;
}
String column = mapIntervalColumn(descriptor.getField());
if (StrUtil.isBlank(column)) {
continue;
}
String dir = "desc".equalsIgnoreCase(descriptor.getDir()) || "des".equalsIgnoreCase(descriptor.getDir()) ? "DESC" : "ASC";
orders.add(column + " " + dir);
}
return orders.isEmpty() ? "" : " ORDER BY " + String.join(", ", orders);
}
private DataSourceResult<EngEqVmsstbprptVo> queryVmsstbprptDetailList(DataSourceRequest dataSourceRequest, private DataSourceResult<EngEqVmsstbprptVo> queryVmsstbprptDetailList(DataSourceRequest dataSourceRequest,
DataSourceLoadOptionsBase loadOptions) { DataSourceLoadOptionsBase loadOptions) {
StringBuilder sql = new StringBuilder(); StringBuilder sql = new StringBuilder();
@ -1658,6 +2149,161 @@ public class EngEqDataServiceImpl implements EngEqDataService {
}; };
} }
private boolean hasIntervalTmFilter(DataSourceRequest.FilterDescriptor filter) {
if (filter == null) {
return false;
}
if ("tm".equalsIgnoreCase(filter.getField())) {
return true;
}
if (CollUtil.isEmpty(filter.getFilters())) {
return false;
}
for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) {
if (hasIntervalTmFilter(child)) {
return true;
}
}
return false;
}
private String buildIntervalTmFilterCondition(DataSourceRequest.FilterDescriptor filter,
String column,
Map<String, Object> paramMap,
int[] indexHolder,
int yearOffset) {
if (filter == null) {
return "";
}
if (StrUtil.isNotBlank(filter.getField())) {
if (!"tm".equalsIgnoreCase(filter.getField())) {
return "";
}
return buildIntervalTmLeafCondition(filter, column, paramMap, indexHolder, yearOffset);
}
if (CollUtil.isEmpty(filter.getFilters())) {
return "";
}
List<String> conditions = new ArrayList<>();
for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) {
String childSql = buildIntervalTmFilterCondition(child, column, paramMap, indexHolder, yearOffset);
if (StrUtil.isNotBlank(childSql)) {
conditions.add("(" + childSql + ")");
}
}
if (conditions.isEmpty()) {
return "";
}
String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND ";
return String.join(logic, conditions);
}
private String buildIntervalTmLeafCondition(DataSourceRequest.FilterDescriptor filter,
String column,
Map<String, Object> paramMap,
int[] indexHolder,
int yearOffset) {
String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase();
Object value = filter.getValue();
if ("isnull".equals(operator)) {
return column + " IS NULL";
}
if ("isnotnull".equals(operator)) {
return column + " IS NOT NULL";
}
if ("in".equals(operator)) {
List<Object> values = normalizeValues(value);
if (values.isEmpty()) {
return "";
}
List<String> placeholders = new ArrayList<>();
for (Object item : values) {
Object shifted = shiftTemporalValue(item, yearOffset);
String key = "intervalTmParam" + indexHolder[0]++;
paramMap.put(key, shifted);
placeholders.add(buildEqValueExpr(key, true, shifted));
}
return column + " IN (" + String.join(", ", placeholders) + ")";
}
if (value == null) {
return "";
}
Object shiftedValue = shiftTemporalValue(value, yearOffset);
String key = "intervalTmParam" + indexHolder[0]++;
paramMap.put(key, shiftedValue);
String valueExpr = buildEqValueExpr(key, true, shiftedValue);
return switch (operator) {
case "eq" -> column + " = " + valueExpr;
case "neq" -> column + " <> " + valueExpr;
case "gt" -> column + " > " + valueExpr;
case "gte" -> column + " >= " + valueExpr;
case "lt" -> column + " < " + valueExpr;
case "lte" -> column + " <= " + valueExpr;
default -> "";
};
}
private Object shiftTemporalValue(Object value, int yearOffset) {
if (value == null || yearOffset == 0) {
return value;
}
String text = String.valueOf(value).trim();
if (StrUtil.isBlank(text)) {
return value;
}
if (text.length() <= 10) {
LocalDate date = LocalDate.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
return date.plusYears(yearOffset).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
}
LocalDateTime dateTime = LocalDateTime.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
return dateTime.plusYears(yearOffset).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
private String mapIntervalColumn(String field) {
if (StrUtil.isBlank(field)) {
return null;
}
return switch (field) {
case "stcd" -> "t.stcd";
case "stnm", "ennm" -> "t.ennm";
case "sttp", "sttpCode" -> "t.sttpCode";
case "baseId" -> "t.baseId";
case "baseName" -> "t.baseName";
case "hbrvcd" -> "t.hbrvcd";
case "hbrvcdName" -> "t.hbrvcdName";
case "addvcdName" -> "t.addvcdName";
case "lgtd" -> "t.lgtd";
case "lttd" -> "t.lttd";
case "dtmel" -> "t.dtmel";
case "dtin" -> "t.dtin";
case "dtinEnv" -> "t.dtinEnv";
case "prsc" -> "t.prsc";
case "bldsttCcode", "bldstt" -> "t.bldsttCcode";
case "qi" -> "t.qi";
case "qo" -> "t.qo";
case "qecLimit" -> "t.qecLimit";
case "qec" -> "t.qec";
case "rz" -> "t.rz";
case "dz", "ddz" -> "t.dz";
case "qecRate" -> "t.qecRate";
case "beforeQecRate" -> "t.beforeQecRate";
case "qecInterval" -> "t.qecInterval";
case "anchoPointState" -> "t.anchoPointState";
case "qecSfdbHy" -> "t.qecSfdbHy";
case "qecSfdbHn" -> "t.qecSfdbHn";
case "qecSfdbCount" -> "t.qecSfdbCount";
case "qecSfdbHo" -> "t.qecSfdbHo";
case "qiSum" -> "t.qiSum";
case "qoSum" -> "t.qoSum";
case "fillWater" -> "(t.qoSum - t.qiSum)";
case "baseStepSort" -> "NVL(t.baseStepSort, 999999)";
case "rvcdStepSort" -> "NVL(t.rvcdStepSort, 999999)";
case "rstcdStepSort" -> "NVL(t.rstcdStepSort, 999999)";
case "siteStepSort" -> "NVL(t.siteStepSort, 999999)";
default -> null;
};
}
private String mapVmsstbprptColumn(String field) { private String mapVmsstbprptColumn(String field) {
if (StrUtil.isBlank(field)) { if (StrUtil.isBlank(field)) {
return null; return null;