feat: 电站告警描点列表

This commit is contained in:
tangwei 2026-07-09 10:08:11 +08:00
parent 04b0f8dd3a
commit 2f92eeef1a
6 changed files with 462 additions and 1 deletions

View File

@ -52,6 +52,12 @@ public class SdEngMonitorController {
return ResponseResult.successData(engInfoBHService.getEngPointKendoListCust(dataSourceRequest));
}
@PostMapping("/alarmPoint/GetKendoListCust")
@Operation(summary = "电站告警描点列表")
public ResponseResult getAlarmPointKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
return ResponseResult.successData(engInfoBHService.getAlarmPointKendoListCust(dataSourceRequest));
}
@PostMapping("/rsvrcscdb/GetKendoList")
@Operation(summary = "条件过滤数据列表")
public ResponseResult getRsvrcscdBKendoList(@RequestBody DataSourceRequest dataSourceRequest) {

View File

@ -0,0 +1,101 @@
package com.yfd.platform.qgc_base.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Data
@Schema(description = "电站告警描点")
public class EngAlarmPointVo {
@Schema(description = "站点类型")
private String sttp;
@Schema(description = "站点编码")
private String stcd;
@Schema(description = "经度")
private BigDecimal lgtd;
@Schema(description = "纬度")
private BigDecimal lttd;
@Schema(description = "高程")
private BigDecimal dtmel;
@Schema(description = "描点状态")
private String anchoPointState;
@Schema(description = "锚点类型")
private String sttpMap;
@Schema(description = "弹框站点名称")
private String titleName;
@Schema(description = "地图避让")
private Integer distance;
@Schema(description = "流域编码")
private String rvcd;
@Schema(description = "行政编码")
private String addvcd;
@Schema(description = "基地编码")
private String baseId;
@Schema(description = "关联电站编码")
private String rstcds;
@Schema(description = "设施类型")
private String sttpCode;
@Schema(description = "电站名称")
private String ennm;
@Schema(description = "流域名称")
private String rvnm;
@Schema(description = "电站装机类型")
private Integer endInstalledType;
@Schema(description = "生态流量告警数")
private Integer stqCount;
@Schema(description = "水质告警数")
private Integer wqCount;
@Schema(description = "水位告警数")
private Integer zCount;
@Schema(description = "水温告警数")
private Integer wtCount;
@Schema(description = "年份")
private String yyyy;
@Schema(description = "告警区间范围")
private String range;
@Schema(description = "装机容量")
private BigDecimal ttpwr;
@Schema(description = "基地名称")
private String baseName;
@Schema(description = "电站编码")
private String rstcd;
@Schema(description = "流域沿程")
private Integer rvcdStepSort;
@Schema(description = "电站沿程")
private Integer rstcdStepSort;
@Schema(description = "站点沿程")
private Integer siteStepSort;
@Schema(description = "电站图片")
private String logo;
}

View File

@ -7,6 +7,7 @@ import com.yfd.platform.common.DataSourceResult;
import com.yfd.platform.qgc_base.domain.SdEngInfoBH;
import com.yfd.platform.qgc_base.domain.SdEngInfoBHRequest;
import com.yfd.platform.qgc_base.domain.vo.EngBaseInfoVo;
import com.yfd.platform.qgc_base.domain.vo.EngAlarmPointVo;
import com.yfd.platform.qgc_base.domain.vo.EngEiaapprovalVo;
import com.yfd.platform.qgc_base.domain.vo.EngOperatVo;
import com.yfd.platform.qgc_base.domain.vo.EngQgcRvcdVo;
@ -93,6 +94,8 @@ public interface ISdEngInfoBHService extends IService<SdEngInfoBH> {
DataSourceResult<EngPointVo> getEngPointKendoListCust(DataSourceRequest dataSourceRequest);
DataSourceResult<EngAlarmPointVo> getAlarmPointKendoListCust(DataSourceRequest dataSourceRequest);
DataSourceResult<EngRsvrcscdBVo> getRsvrcscdBKendoList(DataSourceRequest dataSourceRequest);
DataSourceResult<EngRsvrcscdRvcdVo> getRsvrcscdBRvcdList(DataSourceRequest dataSourceRequest);

View File

@ -3,6 +3,7 @@ package com.yfd.platform.qgc_base.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
@ -25,6 +26,7 @@ import com.yfd.platform.qgc_data.mapper.SysUserDataScopeMapper;
import com.yfd.platform.qgc_base.domain.SdEngInfoBH;
import com.yfd.platform.qgc_base.domain.vo.DataScopeApplyResult;
import com.yfd.platform.qgc_base.domain.SdEngInfoBHRequest;
import com.yfd.platform.qgc_base.domain.vo.EngAlarmPointVo;
import com.yfd.platform.qgc_base.domain.vo.EngBaseInfoVo;
import com.yfd.platform.qgc_base.domain.vo.EngEiaapprovalVo;
import com.yfd.platform.qgc_base.domain.vo.EngOperatVo;
@ -2789,6 +2791,353 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
return result;
}
@Override
public DataSourceResult<EngAlarmPointVo> getAlarmPointKendoListCust(DataSourceRequest dataSourceRequest) {
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
String startTimeText = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "startTime");
String endTimeText = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "endTime");
Date startTime;
Date endTime;
String yyyy = null;
if (StrUtil.isNotBlank(startTimeText) && StrUtil.isNotBlank(endTimeText)) {
startTime = parseAlarmPointTime(startTimeText);
endTime = parseAlarmPointTime(endTimeText);
} else {
yyyy = String.valueOf(DateUtil.year(new Date()));
Map<String, Date> yearRange = buildAlarmPointYearRange(yyyy);
startTime = yearRange.get("startTime");
endTime = yearRange.get("endTime");
}
Map<String, Object> pointParamMap = new HashMap<>();
StringBuilder pointSql = new StringBuilder(buildAlarmPointBaseSql());
// DataScopeApplyResult scopeApplyResult = dataScopeFilterService.appendCurrentUserStationScope(pointSql, pointParamMap, "eng.STCD");
List<EngAlarmPointVo> points= microservicDynamicSQLMapper.getAllListWithResultType(
pointSql.toString(),
pointParamMap,
EngAlarmPointVo.class
);
// if (scopeApplyResult.isEmptyResult()) {
// points = new ArrayList<>();
// } else {
// points = microservicDynamicSQLMapper.getAllListWithResultType(
// pointSql.toString(),
// pointParamMap,
// EngAlarmPointVo.class
// );
// }
Map<String, Object> countParamMap = new HashMap<>();
countParamMap.put("alarmPointStartTime", startTime);
countParamMap.put("alarmPointEndTime", endTime);
List<Map<String, Object>> countRows = microservicDynamicSQLMapper.getAllList(buildAlarmPointCountSql(), countParamMap);
Map<String, Integer> qecCountMap = buildAlarmPointQecCountMap(countRows);
Map<String, Integer> wqCountMap = buildAlarmPointWqCountMap(countRows);
List<Map<String, Object>> expressionRows = microservicDynamicSQLMapper.getAllList(buildAlarmPointLegendSql(), new HashMap<>());
List<EngAlarmPointVo> resultList = mergeAlarmPointData(points, qecCountMap, wqCountMap, expressionRows, yyyy);
DataSourceResult<EngAlarmPointVo> result = new DataSourceResult<>();
result.setData(resultList);
result.setTotal(resultList.size());
result.setAggregates(new HashMap<>());
return result;
}
private String buildAlarmPointBaseSql() {
return "SELECT " +
"eng.STCD AS stcd, " +
"'ENG' AS sttp, " +
"eng.ENNM AS ennm, " +
"eng.ENNM AS titleName, " +
"eng.LOGO AS logo, " +
"eng.RVCD AS rvcd, " +
"eng.RVCD_NAME AS rvnm, " +
"eng.ADDVCD AS addvcd, " +
"eng.BASE_ID AS baseId, " +
"NVL(eng.BASE_NAME, hb.BASENAME) AS baseName, " +
"eng.LGTD AS lgtd, " +
"eng.LTTD AS lttd, " +
"eng.ELEV AS dtmel, " +
"eng.YRGEB AS ttpwr, " +
"'ENG' AS sttpMap, " +
"CASE WHEN eng.PRSC IN (1, 2) THEN 1 WHEN eng.PRSC = 3 THEN 2 END AS endInstalledType, " +
"CASE " +
" WHEN eng.PRSC IN (1, 2) AND NVL(eng.BLDSTT_CODE, 0) = 2 THEN 'large_eng_built' " +
" WHEN eng.PRSC IN (1, 2) AND NVL(eng.BLDSTT_CODE, 0) = 1 THEN 'large_eng_ubuilt' " +
" WHEN eng.PRSC IN (1, 2) THEN 'large_eng_nbuilt' " +
" WHEN eng.PRSC = 3 AND NVL(eng.BLDSTT_CODE, 0) = 2 THEN 'mid_eng_built' " +
" WHEN eng.PRSC = 3 AND NVL(eng.BLDSTT_CODE, 0) = 1 THEN 'mid_eng_ubuilt' " +
" WHEN eng.PRSC = 3 THEN 'mid_eng_nbuilt' " +
" ELSE NULL END AS anchoPointState, " +
"eng.STCD AS rstcd, " +
"eng.STCD AS rstcds, " +
"'ENG' AS sttpCode, " +
"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 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 " +
"WHERE NVL(eng.IS_DELETED, 0) = 0 " +
"AND NVL(eng.USFL, 0) = 1 " +
"AND eng.LGTD IS NOT NULL " +
"AND eng.LTTD IS NOT NULL ";
}
private String buildAlarmPointCountSql() {
return "SELECT wr.STCD AS stcd, wr.STCD AS rstcd, COUNT(wr.STCD) AS count, 'QEC' AS ys " +
"FROM MS_WARN_RECORD_W wr " +
"WHERE NVL(wr.IS_DELETED, 0) = 0 " +
"AND wr.TB_ID IN (SELECT tb.ID FROM ST_TB_B tb WHERE tb.TB_CODE = 'QEC_R' AND NVL(tb.IS_DELETED, 0) = 0) " +
"AND wr.YS = 'QEC' " +
"AND wr.SFGB = 'N' " +
"AND wr.BTM BETWEEN #{map.alarmPointStartTime} AND #{map.alarmPointEndTime} " +
"GROUP BY wr.STCD " +
"UNION ALL " +
"SELECT wr.STCD AS stcd, wq.RSTCD AS rstcd, COUNT(wr.STCD) AS count, 'WQ' AS ys " +
"FROM MS_WARN_RECORD_W wr " +
"LEFT JOIN SD_WQ_B_H wq ON wr.STCD = wq.STCD AND NVL(wq.IS_DELETED, 0) = 0 " +
"WHERE NVL(wr.IS_DELETED, 0) = 0 " +
"AND wr.TB_ID IN (SELECT tb.ID FROM ST_TB_B tb WHERE tb.TB_CODE = 'WQ_R' AND NVL(tb.IS_DELETED, 0) = 0) " +
"AND wr.SFGB = 'N' " +
"AND wr.BTM BETWEEN #{map.alarmPointStartTime} AND #{map.alarmPointEndTime} " +
"AND wq.RSTCD IS NOT NULL " +
"GROUP BY wr.STCD, wq.RSTCD";
}
private String buildAlarmPointLegendSql() {
return "SELECT EXPRESSION AS expression, NAME_EN AS nameEn " +
"FROM MS_MAPLEGEND_B " +
"WHERE LAYER_CODE = 'eng_alarm_point' " +
"AND IF_SHOW = 1 " +
"AND NVL(IS_DELETED, 0) = 0 " +
"AND EXPRESSION IS NOT NULL " +
"ORDER BY NVL(ORDER_INDEX, 999999), ID";
}
private Map<String, Date> buildAlarmPointYearRange(String yearText) {
Date endTime = new Date();
String currentYear = String.valueOf(DateUtil.year(endTime));
Date startTime = DateUtil.parse(currentYear + "-01-01");
if (StrUtil.isNotBlank(yearText) && !currentYear.equals(yearText)) {
startTime = DateUtil.parse(yearText + "-01-01");
endTime = DateUtil.parse(yearText + "-12-31");
}
Map<String, Date> result = new HashMap<>();
result.put("startTime", startTime);
result.put("endTime", endTime);
return result;
}
private Map<String, Integer> buildAlarmPointQecCountMap(List<Map<String, Object>> countRows) {
Map<String, Integer> result = new HashMap<>();
if (CollUtil.isEmpty(countRows)) {
return result;
}
for (Map<String, Object> row : countRows) {
if (!"QEC".equalsIgnoreCase(safeAlarmValue(firstPresentAlarmValue(row, "YS", "ys")))) {
continue;
}
String stcd = safeAlarmValue(firstPresentAlarmValue(row, "RSTCD", "rstcd", "STCD", "stcd"));
if (StrUtil.isBlank(stcd)) {
continue;
}
result.put(stcd, toAlarmIntegerValue(firstPresentAlarmValue(row, "COUNT", "count")));
}
return result;
}
private Map<String, Integer> buildAlarmPointWqCountMap(List<Map<String, Object>> countRows) {
Map<String, Integer> result = new HashMap<>();
if (CollUtil.isEmpty(countRows)) {
return result;
}
for (Map<String, Object> row : countRows) {
if (!"WQ".equalsIgnoreCase(safeAlarmValue(firstPresentAlarmValue(row, "YS", "ys")))) {
continue;
}
Integer count = toAlarmIntegerValue(firstPresentAlarmValue(row, "COUNT", "count"));
if (count == null) {
count = 0;
}
String rstcdText = safeAlarmValue(firstPresentAlarmValue(row, "RSTCD", "rstcd"));
if (StrUtil.isBlank(rstcdText)) {
continue;
}
for (String rstcd : rstcdText.split(",")) {
String trimmed = StrUtil.trim(rstcd);
if (StrUtil.isBlank(trimmed)) {
continue;
}
result.put(trimmed, result.getOrDefault(trimmed, 0) + count);
}
}
return result;
}
private List<EngAlarmPointVo> mergeAlarmPointData(List<EngAlarmPointVo> points,
Map<String, Integer> qecCountMap,
Map<String, Integer> wqCountMap,
List<Map<String, Object>> expressionRows,
String yyyy) {
List<EngAlarmPointVo> result = new ArrayList<>();
if (CollUtil.isEmpty(points)) {
return result;
}
for (EngAlarmPointVo point : points) {
if (point == null || !isAlarmPointVisible(point.getAnchoPointState())) {
continue;
}
point.setAnchoPointState(normalizeAlarmPointState(point.getAnchoPointState()) + "_ALARM");
point.setStqCount(qecCountMap.getOrDefault(point.getStcd(), 0));
point.setWqCount(wqCountMap.getOrDefault(point.getStcd(), 0));
point.setZCount(0);
point.setWtCount(0);
point.setYyyy(yyyy);
point.setSttpCode("ENG");
int total = point.getStqCount() + point.getWqCount();
applyAlarmPointRange(point, total, expressionRows);
result.add(point);
}
return result;
}
private boolean isAlarmPointVisible(String state) {
return "large_eng_built".equals(state)
|| "mid_eng_built".equals(state)
|| "large_eng_ubuilt".equals(state)
|| "mid_eng_ubuilt".equals(state);
}
private String normalizeAlarmPointState(String state) {
if ("large_eng_ubuilt".equals(state)) {
return "large_eng_built";
}
if ("mid_eng_ubuilt".equals(state)) {
return "mid_eng_built";
}
return state;
}
private void applyAlarmPointRange(EngAlarmPointVo point, int total, List<Map<String, Object>> expressionRows) {
if (point == null || CollUtil.isEmpty(expressionRows)) {
return;
}
for (Map<String, Object> row : expressionRows) {
String expression = safeAlarmValue(firstPresentAlarmValue(row, "EXPRESSION", "expression"));
if (!matchesAlarmExpression(expression, total)) {
continue;
}
String nameEn = safeAlarmValue(firstPresentAlarmValue(row, "NAMEEN", "nameEn", "NAME_EN"));
if (StrUtil.isNotBlank(nameEn)) {
point.setAnchoPointState(point.getAnchoPointState() + "_" + nameEn);
point.setRange(nameEn);
}
return;
}
}
private boolean matchesAlarmExpression(String range, int value) {
if (StrUtil.isBlank(range)) {
return false;
}
if (range.matches("x=\\d+")) {
return value == Integer.parseInt(range.substring(2));
}
if (range.matches("x>\\d+")) {
return value > Integer.parseInt(range.substring(2));
}
if (range.matches("x>=\\d+")) {
return value >= Integer.parseInt(range.substring(3));
}
if (range.matches("x<\\d+")) {
return value < Integer.parseInt(range.substring(2));
}
if (range.matches("x<=\\d+")) {
return value <= Integer.parseInt(range.substring(3));
}
if (range.matches("\\d+<x<\\d+")) {
String[] split = range.split("<x<");
return value > Integer.parseInt(split[0]) && value < Integer.parseInt(split[1]);
}
if (range.matches("\\d+<=x<=\\d+")) {
String[] split = range.split("<=x<=");
return value >= Integer.parseInt(split[0]) && value <= Integer.parseInt(split[1]);
}
if (range.matches("\\d+<x<=\\d+")) {
String[] split = range.split("<x<=");
return value > Integer.parseInt(split[0]) && value <= Integer.parseInt(split[1]);
}
if (range.matches("\\d+<=x<\\d+")) {
String[] split = range.split("<=x<");
return value >= Integer.parseInt(split[0]) && value < Integer.parseInt(split[1]);
}
return false;
}
private Date parseAlarmPointTime(String timeText) {
if (StrUtil.isBlank(timeText)) {
return null;
}
String value = timeText.trim();
if (value.length() <= 10) {
return DateUtil.parse(value, "yyyy-MM-dd");
}
return DateUtil.parse(value, "yyyy-MM-dd HH:mm:ss");
}
private Object firstPresentAlarmValue(Map<String, Object> row, String... keys) {
if (row == null || keys == null) {
return null;
}
for (String key : keys) {
if (row.containsKey(key)) {
return row.get(key);
}
}
return null;
}
private Integer toAlarmIntegerValue(Object value) {
if (value == null) {
return null;
}
if (value instanceof Number number) {
return number.intValue();
}
String text = String.valueOf(value).trim();
if (StrUtil.isBlank(text)) {
return null;
}
try {
return Integer.parseInt(text);
} catch (NumberFormatException ex) {
try {
return Double.valueOf(text).intValue();
} catch (NumberFormatException ignore) {
return null;
}
}
}
private String safeAlarmValue(Object value) {
return value == null ? "" : String.valueOf(value).trim();
}
private String buildEngPointFilterCondition(DataSourceRequest.FilterDescriptor filter,
Map<String, Object> paramMap,
int[] indexHolder) {

View File

@ -280,7 +280,7 @@ public class FpBuildServiceImpl implements FpBuildService {
" UNION " +
" SELECT STCD FROM SD_FPSS_R WHERE NVL(IS_DELETED, 0) = 0 AND STRDT >= ADD_MONTHS(SYSDATE, -12) AND NVL(ENDDT, STRDT) <= SYSDATE GROUP BY STCD) recent " +
"ON recent.STCD = fp.STCD " +
"WHERE NVL(fp.IS_DELETED, 0) = 0 ");
"WHERE NVL(fp.IS_DELETED, 0) = 0 AND fp.STTP !='FPQ'");
Map<String, Object> paramMap = new HashMap<>();
DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest();

View File

@ -2664,8 +2664,10 @@ public class WeFishServiceImpl implements WeFishService {
if (StrUtil.isBlank(field)) {
return null;
}
return switch (field) {
case "stcd" -> "section.STCD";
case "lgtd" -> "section.LGTD";
case "stnm", "titleName" -> "section.STNM";
case "ennm" -> "eng.ENNM";
case "rvcd" -> "section.RVCD";