feat: 全过程AI识别监测日历表(漂浮物+清漂合并)

This commit is contained in:
tangwei 2026-06-23 18:01:36 +08:00
parent 2fbdb0cdef
commit 158f331777
4 changed files with 194 additions and 1 deletions

View File

@ -50,4 +50,10 @@ public class WarnDataController {
public ResponseResult getAiRstcdListKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { public ResponseResult getAiRstcdListKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
return ResponseResult.successData(warnDataService.getAiRstcdListKendoListCust(dataSourceRequest)); return ResponseResult.successData(warnDataService.getAiRstcdListKendoListCust(dataSourceRequest));
} }
@PostMapping("/ai/com/qgc/aiPfwRecord/GetKendoListCust")
@Operation(summary = "全过程AI识别监测日历表(漂浮物+清漂合并)")
public ResponseResult getAiPfwRecordKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
return ResponseResult.successData(warnDataService.getAiPfwRecordKendoListCust(dataSourceRequest));
}
} }

View File

@ -0,0 +1,44 @@
package com.yfd.platform.qgc_env.warn.entity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
@Schema(description = "全过程AI识别监测日历记录")
public class AiRecordVo {
@Schema(description = "AI类型")
private String type;
@Schema(description = "日期")
private String dt;
@Schema(description = "是否大面积漂浮物")
private Integer isBigDebrisArea;
@Schema(description = "AI数据数")
private Integer aiCnt;
@Schema(description = "统计数")
private Integer cnt;
@Schema(description = "是否已清漂")
private Integer isClearDrift;
@Schema(description = "漂浮物状态")
private Integer status;
@Schema(description = "漂浮物状态名称")
private String statusName;
@Schema(description = "清漂状态")
private Integer qpStatus;
@Schema(description = "清漂状态名称")
private String qpStatusName;
@Schema(description = "附件ID")
private String fid;
}

View File

@ -2,12 +2,15 @@ package com.yfd.platform.qgc_env.warn.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_env.warn.entity.vo.AiRecordVo;
import com.yfd.platform.qgc_env.warn.entity.vo.AiProtectVo; import com.yfd.platform.qgc_env.warn.entity.vo.AiProtectVo;
import com.yfd.platform.qgc_env.warn.entity.vo.AiDmRunVo; 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.AiComListVo;
import com.yfd.platform.qgc_env.warn.entity.vo.AiRstcdVo; 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.EngWarnCountVo;
import java.util.List;
public interface WarnDataService { public interface WarnDataService {
DataSourceResult<EngWarnCountVo> getEngWarnCount(DataSourceRequest dataSourceRequest); DataSourceResult<EngWarnCountVo> getEngWarnCount(DataSourceRequest dataSourceRequest);
@ -19,4 +22,6 @@ public interface WarnDataService {
DataSourceResult<AiComListVo> getAiComKendoListCust(DataSourceRequest dataSourceRequest); DataSourceResult<AiComListVo> getAiComKendoListCust(DataSourceRequest dataSourceRequest);
DataSourceResult<AiRstcdVo> getAiRstcdListKendoListCust(DataSourceRequest dataSourceRequest); DataSourceResult<AiRstcdVo> getAiRstcdListKendoListCust(DataSourceRequest dataSourceRequest);
List<AiRecordVo> getAiPfwRecordKendoListCust(DataSourceRequest dataSourceRequest);
} }

View File

@ -13,7 +13,7 @@ import com.yfd.platform.common.MicroservicDynamicSQLMapper;
import com.yfd.platform.qgc_env.warn.entity.vo.AiComListVo; import com.yfd.platform.qgc_env.warn.entity.vo.AiComListVo;
import com.yfd.platform.qgc_env.warn.entity.vo.AiDmRunVo; import com.yfd.platform.qgc_env.warn.entity.vo.AiDmRunVo;
import com.yfd.platform.qgc_env.warn.entity.vo.AiProtectVo; import com.yfd.platform.qgc_env.warn.entity.vo.AiProtectVo;
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.AiRstcdVo;
import com.yfd.platform.qgc_env.warn.entity.vo.EngWarnCountVo; import com.yfd.platform.qgc_env.warn.entity.vo.EngWarnCountVo;
import com.yfd.platform.qgc_env.warn.service.WarnDataService; import com.yfd.platform.qgc_env.warn.service.WarnDataService;
@ -221,6 +221,21 @@ public class WarnDataServiceImpl implements WarnDataService {
return result; return result;
} }
@Override
public List<AiRecordVo> getAiPfwRecordKendoListCust(DataSourceRequest dataSourceRequest) {
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
String baseId = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "baseId");
String startTime = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "startTime");
String endTime = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "endTime");
String rstcd = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "rstcd");
Map<String, Object> paramMap = new HashMap<>();
String sql = buildAiPfwRecordSql(baseId, parseAiTime(startTime), parseAiTime(endTime), parseAiCodes(rstcd), paramMap);
List<AiRecordVo> list = microservicDynamicSQLMapper.getAllListWithResultType(sql, paramMap, AiRecordVo.class);
fillAiPfwStatus(list);
return list;
}
private AiDmRunVo buildAiDmRunVo(Map<String, Object> row) { private AiDmRunVo buildAiDmRunVo(Map<String, Object> row) {
if (row == null || row.isEmpty()) { if (row == null || row.isEmpty()) {
return null; return null;
@ -264,6 +279,53 @@ public class WarnDataServiceImpl implements WarnDataService {
return sql.toString(); return sql.toString();
} }
private String buildAiPfwRecordSql(String baseId,
Date startTime,
Date endTime,
List<String> rstcdList,
Map<String, Object> paramMap) {
StringBuilder sql = new StringBuilder();
sql.append("SELECT a.dt AS dt, b.isClearDrift AS isClearDrift, b.isBigDebrisArea AS isBigDebrisArea, b.fid AS fid ")
.append("FROM (")
.append("SELECT TO_CHAR(hb.TM, 'yyyy-MM-dd') AS dt ")
.append("FROM SD_AIHEARTBEAT_R hb ")
.append("INNER JOIN SD_AIMONITOR_B_H ai ON ai.STCD = hb.STCD ")
.append("WHERE NVL(hb.IS_DELETED, 0) = 0 ")
.append("AND NVL(ai.IS_DELETED, 0) = 0 ")
.append("AND ai.STTP = 'AI_5001' ");
appendAiPfwFacilityFilterSql(sql, "aiPfwHeartbeat", "ai", "hb", baseId, startTime, endTime, rstcdList, paramMap);
sql.append("GROUP BY TO_CHAR(hb.TM, 'yyyy-MM-dd') ")
.append("UNION ")
.append("SELECT TO_CHAR(rec.TM, 'yyyy-MM-dd') AS dt ")
.append("FROM SD_AICOM_R rec ")
.append("INNER JOIN SD_AIMONITOR_B_H ai ON ai.STCD = rec.STCD ")
.append("WHERE NVL(rec.IS_DELETED, 0) = 0 ")
.append("AND NVL(ai.IS_DELETED, 0) = 0 ")
.append("AND ai.STTP = 'AI_5001' ");
appendAiPfwFacilityFilterSql(sql, "aiPfwAicom", "ai", "rec", baseId, startTime, endTime, rstcdList, paramMap);
sql.append("GROUP BY TO_CHAR(rec.TM, 'yyyy-MM-dd') ")
.append(") a ")
.append("LEFT JOIN (")
.append("SELECT TO_CHAR(rec.TM, 'yyyy-MM-dd') AS dt, ")
.append("MAX(CASE ")
.append("WHEN rec.TYPE = 'AI_5001' AND rec.IS_BIG_DEBRIS_AREA IS NULL THEN 0 ")
.append("WHEN rec.TYPE = 'AI_5001' AND rec.IS_BIG_DEBRIS_AREA IS NOT NULL THEN rec.IS_BIG_DEBRIS_AREA ")
.append("END) AS isBigDebrisArea, ")
.append("MAX(CASE WHEN rec.TYPE = 'AI_5011' THEN 1 END) AS isClearDrift, ")
.append("LISTAGG(rec.FID, ',') WITHIN GROUP (ORDER BY rec.FID) AS fid ")
.append("FROM SD_AICOM_R rec ")
.append("INNER JOIN SD_AIMONITOR_B_H ai ON ai.STCD = rec.STCD ")
.append("WHERE NVL(rec.IS_DELETED, 0) = 0 ")
.append("AND NVL(ai.IS_DELETED, 0) = 0 ")
.append("AND ai.STTP = 'AI_5001' ")
.append("AND rec.TYPE IN ('AI_5001', 'AI_5011') ");
appendAiPfwFacilityFilterSql(sql, "aiPfwStatus", "ai", "rec", baseId, startTime, endTime, rstcdList, paramMap);
sql.append("GROUP BY TO_CHAR(rec.TM, 'yyyy-MM-dd') ")
.append(") b ON a.dt = b.dt ")
.append("ORDER BY a.dt");
return sql.toString();
}
private void appendAiRstcdCommonFilterSql(StringBuilder sql, private void appendAiRstcdCommonFilterSql(StringBuilder sql,
String keyPrefix, String keyPrefix,
String aiAlias, String aiAlias,
@ -313,6 +375,82 @@ public class WarnDataServiceImpl implements WarnDataService {
sql.append("AND ai.STTP = #{map.aiRstcdHeartbeatType} "); sql.append("AND ai.STTP = #{map.aiRstcdHeartbeatType} ");
} }
private void appendAiPfwFacilityFilterSql(StringBuilder sql,
String keyPrefix,
String aiAlias,
String recordAlias,
String baseId,
Date startTime,
Date endTime,
List<String> rstcdList,
Map<String, Object> paramMap) {
if (StrUtil.isNotBlank(baseId)) {
paramMap.put(keyPrefix + "BaseId", baseId.trim());
sql.append("AND ").append(aiAlias).append(".BASE_ID = #{map.").append(keyPrefix).append("BaseId} ");
}
if (CollUtil.isNotEmpty(rstcdList)) {
List<String> placeholders = new ArrayList<>();
for (int i = 0; i < rstcdList.size(); i++) {
String key = keyPrefix + "Rstcd" + i;
paramMap.put(key, rstcdList.get(i));
placeholders.add("#{map." + key + "}");
}
sql.append("AND ").append(aiAlias).append(".RSTCD IN (").append(String.join(", ", placeholders)).append(") ");
}
if (startTime != null) {
paramMap.put(keyPrefix + "StartTime", startTime);
sql.append("AND ").append(recordAlias).append(".TM >= #{map.").append(keyPrefix).append("StartTime} ");
}
if (endTime != null) {
paramMap.put(keyPrefix + "EndTime", endTime);
sql.append("AND ").append(recordAlias).append(".TM <= #{map.").append(keyPrefix).append("EndTime} ");
}
}
private void fillAiPfwStatus(List<AiRecordVo> list) {
if (CollUtil.isEmpty(list)) {
return;
}
for (AiRecordVo item : list) {
if (item == null) {
continue;
}
if (item.getIsBigDebrisArea() != null) {
if (item.getIsBigDebrisArea() == 0) {
item.setStatus(1);
} else {
item.setStatus(2);
}
} else {
item.setStatus(0);
}
item.setStatusName(resolveAiStatusName(item.getStatus()));
if (item.getIsClearDrift() != null) {
item.setQpStatus(5);
} else {
item.setQpStatus(6);
}
item.setQpStatusName(resolveAiStatusName(item.getQpStatus()));
}
}
private String resolveAiStatusName(Integer status) {
if (status == null) {
return null;
}
return switch (status) {
case -1 -> "未监测";
case 0 -> "无漂浮物";
case 1 -> "小面积漂浮物";
case 2 -> "大面积漂浮物";
case 3 -> "运行";
case 4 -> "未运行";
case 5 -> "清漂";
case 6 -> "未清漂";
default -> null;
};
}
private AiProtectVo buildAiProtectVo(Map<String, Object> row) { private AiProtectVo buildAiProtectVo(Map<String, Object> row) {
if (row == null || row.isEmpty()) { if (row == null || row.isEmpty()) {
return null; return null;