feat: 监测设备告警情况列表

This commit is contained in:
tangwei 2026-06-24 10:19:38 +08:00
parent d2199e47b8
commit 201c36e3b6
4 changed files with 511 additions and 0 deletions

View File

@ -68,4 +68,10 @@ public class WarnDataController {
public ResponseResult getAlarmPointKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
return ResponseResult.successData(warnDataService.getAlarmPointKendoListCust(dataSourceRequest));
}
@PostMapping("/stcd/GetKendoListCust")
@Operation(summary = "监测设备告警情况列表")
public ResponseResult getWarnStcdKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
return ResponseResult.successData(warnDataService.getWarnStcdKendoListCust(dataSourceRequest));
}
}

View File

@ -0,0 +1,59 @@
package com.yfd.platform.qgc_env.warn.entity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
@Data
@Schema(description = "监测设备告警情况")
public class StcdWarnStateVo {
@Schema(description = "测站编码")
private String stcd;
@Schema(description = "测站名称")
private String stnm;
@Schema(description = "电站编码")
private String rstcd;
@Schema(description = "电站名称")
private String ennm;
@Schema(description = "监测方式")
private Integer mway;
@Schema(description = "测站类型编码")
private String sttpCode;
@Schema(description = "测站类型名称")
private String sttpName;
@Schema(description = "基地编码")
private String baseId;
@Schema(description = "基地名称")
private String baseName;
@Schema(description = "流域编码")
private String rvcd;
@Schema(description = "告警状态")
private Integer warnState;
@Schema(description = "告警状态名称")
private String warnstateName;
@Schema(description = "告警时间")
private Date warnTm;
@Schema(description = "基础排序")
private Integer baseStepSort;
@Schema(description = "电站排序")
private Integer rstcdStepSort;
@Schema(description = "数据接入类型")
private Integer dtinType;
}

View File

@ -9,6 +9,7 @@ import com.yfd.platform.qgc_env.warn.entity.vo.AiDmRunVo;
import com.yfd.platform.qgc_env.warn.entity.vo.AiComListVo;
import com.yfd.platform.qgc_env.warn.entity.vo.AiRstcdVo;
import com.yfd.platform.qgc_env.warn.entity.vo.EngWarnCountVo;
import com.yfd.platform.qgc_env.warn.entity.vo.StcdWarnStateVo;
import java.util.List;
@ -29,4 +30,6 @@ public interface WarnDataService {
List<AiRecordVo> getAiRecordKendoListCust(DataSourceRequest dataSourceRequest);
DataSourceResult<AlarmPointVo> getAlarmPointKendoListCust(DataSourceRequest dataSourceRequest);
DataSourceResult<StcdWarnStateVo> getWarnStcdKendoListCust(DataSourceRequest dataSourceRequest);
}

View File

@ -17,6 +17,7 @@ import com.yfd.platform.qgc_env.warn.entity.vo.AiProtectVo;
import com.yfd.platform.qgc_env.warn.entity.vo.AiRecordVo;
import com.yfd.platform.qgc_env.warn.entity.vo.AiRstcdVo;
import com.yfd.platform.qgc_env.warn.entity.vo.EngWarnCountVo;
import com.yfd.platform.qgc_env.warn.entity.vo.StcdWarnStateVo;
import com.yfd.platform.qgc_env.warn.service.WarnDataService;
import com.yfd.platform.utils.QgcQueryWrapperUtil;
import jakarta.annotation.Resource;
@ -297,6 +298,62 @@ public class WarnDataServiceImpl implements WarnDataService {
return result;
}
@Override
public DataSourceResult<StcdWarnStateVo> getWarnStcdKendoListCust(DataSourceRequest dataSourceRequest) {
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
String warnType = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "warnType");
String rvcd = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "rvcd");
Map<String, Object> paramMap = new HashMap<>();
String filterSql = buildWarnStcdFilterCondition(
dataSourceRequest == null ? null : dataSourceRequest.getFilter(),
paramMap,
new int[]{0}
);
StringBuilder sql = new StringBuilder();
sql.append("SELECT ")
.append("r.stcd AS stcd, ")
.append("r.stnm AS stnm, ")
.append("r.rstcd AS rstcd, ")
.append("r.ennm AS ennm, ")
.append("r.mway AS mway, ")
.append("r.sttpCode AS sttpCode, ")
.append("r.sttpName AS sttpName, ")
.append("r.baseId AS baseId, ")
.append("r.baseName AS baseName, ")
.append("r.rvcd AS rvcd, ")
.append("r.warnState AS warnState, ")
.append("r.baseStepSort AS baseStepSort, ")
.append("r.rstcdStepSort AS rstcdStepSort, ")
.append("r.dtinType AS dtinType ")
.append("FROM (")
.append(buildWarnStcdDetailSql(warnType))
.append(") r WHERE 1 = 1 ");
if (StrUtil.isNotBlank(filterSql)) {
sql.append(" AND ").append(filterSql).append(" ");
}
sql.append(buildWarnStcdOrderBySql(
dataSourceRequest == null ? null : dataSourceRequest.getSort(),
rvcd
));
Page<?> page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake());
List<StcdWarnStateVo> list = microservicDynamicSQLMapper.pageAllListWithResultType(
page,
sql.toString(),
paramMap,
StcdWarnStateVo.class
);
fillWarnStcdData(list, warnType);
DataSourceResult<StcdWarnStateVo> result = new DataSourceResult<>();
result.setData(list);
result.setTotal(page == null ? list.size() : page.getTotal());
result.setAggregates(new HashMap<>());
return result;
}
private AiDmRunVo buildAiDmRunVo(Map<String, Object> row) {
if (row == null || row.isEmpty()) {
return null;
@ -308,6 +365,371 @@ public class WarnDataServiceImpl implements WarnDataService {
return vo;
}
private String buildWarnStcdDetailSql(String warnType) {
String normalizedWarnStateExpr = "CASE " +
"WHEN eng.WARN_STATE = '0' OR eng.WARN_STATE IS NULL OR eng.WARN_STATE = '' THEN '00' " +
"ELSE eng.WARN_STATE END";
String nonEngWarnStateExpr = "CASE state.STD_SSTATE " +
"WHEN 2 THEN 0 " +
"WHEN 3 THEN 2 " +
"ELSE state.STD_SSTATE END";
List<String> parts = new ArrayList<>();
if ("QEC".equalsIgnoreCase(warnType)) {
parts.add(buildWarnStcdEngSql(normalizedWarnStateExpr, warnType));
} else {
parts.add(buildWarnStcdEngSql(normalizedWarnStateExpr, warnType));
parts.add(buildWarnStcdWqSql(nonEngWarnStateExpr));
parts.add(buildWarnStcdWtSql(nonEngWarnStateExpr));
}
return String.join(" UNION ALL ", parts);
}
private String buildWarnStcdEngSql(String normalizedWarnStateExpr, String warnType) {
String warnStateExpr;
if ("RZ".equalsIgnoreCase(warnType)) {
warnStateExpr = "TO_NUMBER(SUBSTR(" + normalizedWarnStateExpr + ", 1, 1))";
} else if ("QEC".equalsIgnoreCase(warnType)) {
warnStateExpr = "NVL(TO_NUMBER(SUBSTR(" + normalizedWarnStateExpr + ", 2, 1)), 0)";
} else {
warnStateExpr = "TO_NUMBER(NULLIF(eng.WARN_STATE, ''))";
}
StringBuilder sql = new StringBuilder();
sql.append("SELECT ")
.append("eng.STCD AS stcd, ")
.append("eng.ENNM AS stnm, ")
.append("CAST(NULL AS VARCHAR2(32)) AS rstcd, ")
.append("eng.ENNM AS ennm, ")
.append("CAST(NULL AS NUMBER) AS mway, ")
.append("'ENG' AS sttpCode, ")
.append("sttp.STTP_NAME AS sttpName, ")
.append("eng.BASE_ID AS baseId, ")
.append("NVL(hb.BASENAME, eng.BASE_NAME) AS baseName, ")
.append("eng.HBRVCD AS rvcd, ")
.append(warnStateExpr).append(" AS warnState, ")
.append("hb.ORDER_INDEX AS baseStepSort, ")
.append("eng.ORDER_INDEX AS rstcdStepSort, ")
.append("CAST(NULL AS NUMBER) AS dtinType ")
.append("FROM SD_ENGINFO_B_H eng ")
.append("LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = 'ENG' AND NVL(sttp.IS_DELETED, 0) = 0 ")
.append("LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 ")
.append("WHERE NVL(eng.IS_DELETED, 0) = 0 ");
if ("QEC".equalsIgnoreCase(warnType)) {
sql.append("AND NVL(eng.BLDSTT_CODE, -1) = 2 ")
.append("AND NVL(eng.DTIN, 0) = 1 ")
.append("AND NVL(eng.RUN_STATE, 2) = 4 ");
} else {
sql.append("AND NVL(eng.USFL, 0) = 1 ");
}
return sql.toString();
}
private String buildWarnStcdWqSql(String warnStateExpr) {
return "SELECT " +
"wq.STCD AS stcd, " +
"wq.STNM AS stnm, " +
"wq.RSTCD AS rstcd, " +
"eng.ENNM AS ennm, " +
"wq.MWAY AS mway, " +
"wq.STTP AS sttpCode, " +
"sttp.STTP_NAME AS sttpName, " +
"eng.BASE_ID AS baseId, " +
"hb.BASENAME AS baseName, " +
"eng.HBRVCD AS rvcd, " +
warnStateExpr + " AS warnState, " +
"hb.ORDER_INDEX AS baseStepSort, " +
"eng.ORDER_INDEX AS rstcdStepSort, " +
"wq.DTIN_TYPE AS dtinType " +
"FROM SD_WQ_B_H wq " +
"LEFT JOIN (" + buildWarnStcdLatestStateSql() + ") state ON state.STCD = wq.STCD AND state.STTP_CODE = wq.STTP " +
"LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = wq.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " +
"LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " +
"LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = wq.STTP AND NVL(sttp.IS_DELETED, 0) = 0 " +
"WHERE NVL(wq.IS_DELETED, 0) = 0 " +
"AND NVL(wq.USFL, 0) = 1 " +
"AND wq.STTP IN ('WQ', 'WQFB') ";
}
private String buildWarnStcdWtSql(String warnStateExpr) {
return "SELECT " +
"wt.STCD AS stcd, " +
"wt.STNM AS stnm, " +
"wt.RSTCD AS rstcd, " +
"eng.ENNM AS ennm, " +
"wt.MWAY AS mway, " +
"wt.STTP AS sttpCode, " +
"sttp.STTP_NAME AS sttpName, " +
"eng.BASE_ID AS baseId, " +
"hb.BASENAME AS baseName, " +
"eng.HBRVCD AS rvcd, " +
warnStateExpr + " AS warnState, " +
"hb.ORDER_INDEX AS baseStepSort, " +
"eng.ORDER_INDEX AS rstcdStepSort, " +
"wt.DTIN_TYPE AS dtinType " +
"FROM SD_WT_B_H wt " +
"LEFT JOIN (" + buildWarnStcdLatestStateSql() + ") state ON state.STCD = wt.STCD AND state.STTP_CODE = wt.STTP " +
"LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = wt.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " +
"LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " +
"LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = wt.STTP AND NVL(sttp.IS_DELETED, 0) = 0 " +
"WHERE NVL(wt.IS_DELETED, 0) = 0 " +
"AND NVL(wt.USFL, 0) = 1 " +
"AND wt.STTP = 'WTRV' ";
}
private String buildWarnStcdLatestStateSql() {
return "SELECT s.STCD, s.STTP_CODE, s.STD_SSTATE " +
"FROM MS_STSTATE_T s " +
"INNER JOIN (" +
"SELECT STCD, MAX(YR) AS MAX_YR " +
"FROM MS_STSTATE_T " +
"WHERE NVL(IS_DELETED, 0) = 0 " +
"GROUP BY STCD" +
") mx ON mx.STCD = s.STCD AND mx.MAX_YR = s.YR " +
"WHERE NVL(s.IS_DELETED, 0) = 0";
}
private String buildWarnStcdFilterCondition(DataSourceRequest.FilterDescriptor filter,
Map<String, Object> paramMap,
int[] indexHolder) {
if (filter == null) {
return "";
}
List<String> parts = new ArrayList<>();
if (CollUtil.isNotEmpty(filter.getFilters())) {
for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) {
String childSql = buildWarnStcdFilterCondition(child, paramMap, indexHolder);
if (StrUtil.isNotBlank(childSql)) {
parts.add(childSql);
}
}
if (parts.isEmpty()) {
return "";
}
String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND ";
return "(" + String.join(logic, parts) + ")";
}
if ("warnType".equalsIgnoreCase(filter.getField())) {
return "";
}
String column = mapWarnStcdColumn(filter.getField());
if (StrUtil.isBlank(column)) {
return "";
}
String paramKey = "warnStcdParam" + indexHolder[0]++;
String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase();
Object value = filter.getValue();
switch (operator) {
case "eq":
paramMap.put(paramKey, normalizeWarnStcdValue(filter.getField(), value));
return column + " = #{map." + paramKey + "}";
case "neq":
paramMap.put(paramKey, normalizeWarnStcdValue(filter.getField(), value));
return column + " <> #{map." + paramKey + "}";
case "contains":
paramMap.put(paramKey, "%" + safeString(value) + "%");
return column + " LIKE #{map." + paramKey + "}";
case "doesnotcontain":
paramMap.put(paramKey, "%" + safeString(value) + "%");
return column + " NOT LIKE #{map." + paramKey + "}";
case "startswith":
paramMap.put(paramKey, safeString(value) + "%");
return column + " LIKE #{map." + paramKey + "}";
case "endswith":
paramMap.put(paramKey, "%" + safeString(value));
return column + " LIKE #{map." + paramKey + "}";
case "gt":
paramMap.put(paramKey, normalizeWarnStcdValue(filter.getField(), value));
return column + " > #{map." + paramKey + "}";
case "gte":
paramMap.put(paramKey, normalizeWarnStcdValue(filter.getField(), value));
return column + " >= #{map." + paramKey + "}";
case "lt":
paramMap.put(paramKey, normalizeWarnStcdValue(filter.getField(), value));
return column + " < #{map." + paramKey + "}";
case "lte":
paramMap.put(paramKey, normalizeWarnStcdValue(filter.getField(), value));
return column + " <= #{map." + paramKey + "}";
case "isnull":
return column + " IS NULL";
case "isnotnull":
return column + " IS NOT NULL";
case "isempty":
return "(" + column + " IS NULL OR " + column + " = '')";
case "isnotempty":
return "(" + column + " IS NOT NULL AND " + column + " <> '')";
case "in":
return buildWarnStcdInSql(column, value, paramKey, paramMap);
default:
return "";
}
}
private String buildWarnStcdInSql(String column, Object value, String paramKey, Map<String, Object> paramMap) {
List<String> values = parseAiCodes(value == null ? null : String.valueOf(value));
if (CollUtil.isEmpty(values)) {
return "";
}
List<String> placeholders = new ArrayList<>();
for (int i = 0; i < values.size(); i++) {
String key = paramKey + "_" + i;
paramMap.put(key, values.get(i));
placeholders.add("#{map." + key + "}");
}
return column + " IN (" + String.join(", ", placeholders) + ")";
}
private String mapWarnStcdColumn(String field) {
if (StrUtil.isBlank(field)) {
return null;
}
return switch (field) {
case "stcd" -> "r.stcd";
case "stnm" -> "r.stnm";
case "rstcd" -> "r.rstcd";
case "ennm" -> "r.ennm";
case "mway" -> "r.mway";
case "sttpCode" -> "r.sttpCode";
case "sttpName" -> "r.sttpName";
case "baseId" -> "r.baseId";
case "baseName" -> "r.baseName";
case "rvcd" -> "r.rvcd";
case "warnState" -> "r.warnState";
case "dtinType" -> "r.dtinType";
default -> null;
};
}
private Object normalizeWarnStcdValue(String field, Object value) {
if ("warnState".equals(field) || "mway".equals(field) || "dtinType".equals(field)) {
return toIntegerValue(value);
}
return value;
}
private String buildWarnStcdOrderBySql(List<DataSourceRequest.SortDescriptor> sortList, String rvcd) {
if (CollUtil.isEmpty(sortList)) {
if (StrUtil.isNotBlank(rvcd)) {
return " ORDER BY r.rstcdStepSort ASC NULLS LAST ";
}
return "";
}
List<String> orderItems = new ArrayList<>();
for (DataSourceRequest.SortDescriptor item : sortList) {
if (item == null || StrUtil.isBlank(item.getField())) {
continue;
}
String column = mapWarnStcdColumn(item.getField());
if (StrUtil.isBlank(column)) {
continue;
}
String dir = "desc".equalsIgnoreCase(item.getDir()) ? "DESC" : "ASC";
orderItems.add(column + " " + dir);
}
if (orderItems.isEmpty()) {
if (StrUtil.isNotBlank(rvcd)) {
return " ORDER BY r.rstcdStepSort ASC NULLS LAST ";
}
return "";
}
return " ORDER BY " + String.join(", ", orderItems);
}
private void fillWarnStcdData(List<StcdWarnStateVo> list, String warnType) {
if (CollUtil.isEmpty(list)) {
return;
}
Map<String, Date> engRzWarnTmMap = new HashMap<>();
Map<String, Date> engQecWarnTmMap = new HashMap<>();
Map<String, Date> wqWarnTmMap = new HashMap<>();
Map<String, Date> wtWarnTmMap = new HashMap<>();
if ("RZ".equalsIgnoreCase(warnType)) {
engRzWarnTmMap = getWarnRecordTimeMap(collectWarnStcds(list, "ENG"), "HYDROPW_R");
} else if ("QEC".equalsIgnoreCase(warnType)) {
engQecWarnTmMap = getWarnRecordTimeMap(collectWarnStcds(list, "ENG"), "QEC_R");
}
wqWarnTmMap = getWarnRecordTimeMap(collectWarnStcds(list, "WQ", "WQFB"), "WQ_R");
wtWarnTmMap = getWarnRecordTimeMap(collectWarnStcds(list, "WTRV"), "WTRV_R");
for (StcdWarnStateVo item : list) {
if (item == null) {
continue;
}
item.setWarnstateName(resolveWarnStateName(item.getWarnState()));
if (!Integer.valueOf(2).equals(item.getWarnState())) {
continue;
}
if ("ENG".equalsIgnoreCase(item.getSttpCode()) && "RZ".equalsIgnoreCase(warnType)) {
item.setWarnTm(defaultWarnTm(engRzWarnTmMap.get(item.getStcd())));
} else if ("ENG".equalsIgnoreCase(item.getSttpCode()) && "QEC".equalsIgnoreCase(warnType)) {
item.setWarnTm(defaultWarnTm(engQecWarnTmMap.get(item.getStcd())));
} else if ("WTRV".equalsIgnoreCase(item.getSttpCode())) {
item.setWarnTm(defaultWarnTm(wtWarnTmMap.get(item.getStcd())));
} else if ("WQ".equalsIgnoreCase(item.getSttpCode()) || "WQFB".equalsIgnoreCase(item.getSttpCode())) {
item.setWarnTm(defaultWarnTm(wqWarnTmMap.get(item.getStcd())));
} else {
item.setWarnTm(new Date());
}
}
}
private List<String> collectWarnStcds(List<StcdWarnStateVo> list, String... sttpCodes) {
List<String> result = new ArrayList<>();
if (CollUtil.isEmpty(list) || sttpCodes == null || sttpCodes.length == 0) {
return result;
}
List<String> sttpCodeList = Arrays.asList(sttpCodes);
for (StcdWarnStateVo item : list) {
if (item == null || !Integer.valueOf(2).equals(item.getWarnState())) {
continue;
}
if (!sttpCodeList.contains(item.getSttpCode())) {
continue;
}
if (StrUtil.isNotBlank(item.getStcd()) && !result.contains(item.getStcd())) {
result.add(item.getStcd());
}
}
return result;
}
private Map<String, Date> getWarnRecordTimeMap(List<String> stcdList, String tbCode) {
Map<String, Date> result = new HashMap<>();
if (CollUtil.isEmpty(stcdList) || StrUtil.isBlank(tbCode)) {
return result;
}
Map<String, Object> paramMap = new HashMap<>();
List<String> placeholders = new ArrayList<>();
for (int i = 0; i < stcdList.size(); i++) {
String key = "warnRecordStcd" + i;
paramMap.put(key, stcdList.get(i));
placeholders.add("#{map." + key + "}");
}
paramMap.put("warnRecordTbCode", tbCode);
String sql = "SELECT rec.STCD AS stcd, MAX(rec.BTM) AS warnTm " +
"FROM MS_WARN_RECORD_W rec " +
"INNER JOIN ST_TB_B tb ON tb.ID = rec.TB_ID AND NVL(tb.IS_DELETED, 0) = 0 " +
"WHERE NVL(rec.IS_DELETED, 0) = 0 " +
"AND NVL(rec.SFGB, 'N') = 'N' " +
"AND tb.TB_CODE = #{map.warnRecordTbCode} " +
"AND rec.STCD IN (" + String.join(", ", placeholders) + ") " +
"GROUP BY rec.STCD";
List<Map<String, Object>> rows = microservicDynamicSQLMapper.getAllList(sql, paramMap);
for (Map<String, Object> row : rows) {
String stcd = safeString(firstPresentValue(row, "STCD", "stcd"));
Date warnTm = toDateValue(firstPresentValue(row, "WARNTM", "warnTm"));
if (StrUtil.isNotBlank(stcd) && warnTm != null) {
result.put(stcd, warnTm);
}
}
return result;
}
private Date defaultWarnTm(Date warnTm) {
return warnTm == null ? new Date() : warnTm;
}
private String buildAiRstcdListSql(String baseId,
Date startTime,
Date endTime,
@ -1364,6 +1786,27 @@ public class WarnDataServiceImpl implements WarnDataService {
}
}
private Date toDateValue(Object value) {
if (value == null) {
return null;
}
if (value instanceof Date date) {
return date;
}
if (value instanceof Number number) {
return new Date(number.longValue());
}
String text = String.valueOf(value).trim();
if (StrUtil.isBlank(text)) {
return null;
}
try {
return DateUtil.parse(text).toJdkDate();
} catch (Exception ex) {
return null;
}
}
private BigDecimal toBigDecimalValue(Object value) {
if (value == null) {
return null;