diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java index 64fa1084..da85cba8 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/impl/SdEngInfoBHServiceImpl.java @@ -402,12 +402,13 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl page = null; - if (dataSourceRequest.getTake() > 0) { - page = new Page<>(dataSourceRequest.getSkip() / dataSourceRequest.getTake() + 1, - dataSourceRequest.getTake()); - } - +// Page page = null; +// if (dataSourceRequest.getTake() > 0) { +// page = new Page<>(dataSourceRequest.getSkip() / dataSourceRequest.getTake() + 1, +// dataSourceRequest.getTake()); +// } + DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); + Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); Map paramMap = new HashMap<>(); StringBuilder sql = new StringBuilder(buildEiaapprovalBaseSql()); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fh/service/impl/FhHabitatServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/fh/service/impl/FhHabitatServiceImpl.java index 1f7a1337..cef364cf 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fh/service/impl/FhHabitatServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fh/service/impl/FhHabitatServiceImpl.java @@ -96,10 +96,14 @@ public class FhHabitatServiceImpl implements FhHabitatService { } sql.append(buildOrderBySql(dataSourceRequest.getSort())); - Page page = null; - if (QgcQueryWrapperUtil.getPageInfo(loadOptions).getHasPageInfo()) { - page = QgcQueryWrapperUtil.getPageInfo(loadOptions).getPage(); - } +// Page page = null; +// if (QgcQueryWrapperUtil.getPageInfo(loadOptions).getHasPageInfo()) { +// page = QgcQueryWrapperUtil.getPageInfo(loadOptions).getPage(); +// } + +// DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); + Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType(page, sql.toString(), paramMap, HabitatVo.class); DataSourceResult result = new DataSourceResult<>(); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/warn/controller/WarnDataController.java b/backend/src/main/java/com/yfd/platform/qgc_env/warn/controller/WarnDataController.java index bb9adeb2..493d28d1 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/warn/controller/WarnDataController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/warn/controller/WarnDataController.java @@ -32,4 +32,10 @@ public class WarnDataController { public ResponseResult getAiDmRunCount(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(warnDataService.getAiDmRunCount(dataSourceRequest)); } + + @PostMapping("/ai/com/GetKendoListCust") + @Operation(summary = "AI常规业务列表") + public ResponseResult getAiComKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(warnDataService.getAiComKendoListCust(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/warn/entity/vo/AiComListVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/warn/entity/vo/AiComListVo.java new file mode 100644 index 00000000..5b7445e1 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/warn/entity/vo/AiComListVo.java @@ -0,0 +1,71 @@ +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 = "AI常规业务列表") +public class AiComListVo { + + @Schema(description = "主键") + private String id; + + @Schema(description = "类型编码") + private String type; + + @Schema(description = "类型名称") + private String typeName; + + @Schema(description = "AI测站编码") + private String stcd; + + @Schema(description = "AI测站名称") + private String stnm; + + @Schema(description = "所属电站编码") + private String rstcd; + + @Schema(description = "所属电站名称") + private String ennm; + + @Schema(description = "所属基地编码") + private String baseId; + + @Schema(description = "所属基地流域编码") + private String hbrvcd; + + @Schema(description = "所属流域编码") + private String rvcd; + + @Schema(description = "数据时间") + private Date tm; + + @Schema(description = "结束时间") + private Date endTm; + + @Schema(description = "AI识别值") + private String aiVal; + + @Schema(description = "附件ID") + private String fid; + + @Schema(description = "是否填报") + private Integer isFsf; + + @Schema(description = "是否大面积漂浮物") + private Integer isBigDebrisArea; + + @Schema(description = "是否已清漂") + private Integer isClearDrift; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "创建时间") + private Date recordTime; + + @Schema(description = "更新时间") + private Date modifyTime; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/WarnDataService.java b/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/WarnDataService.java index 3c1a3a10..f371d4bb 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/WarnDataService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/WarnDataService.java @@ -3,6 +3,7 @@ package com.yfd.platform.qgc_env.warn.service; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; 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.EngWarnCountVo; public interface WarnDataService { @@ -10,4 +11,6 @@ public interface WarnDataService { DataSourceResult getEngWarnCount(DataSourceRequest dataSourceRequest); AiDmRunVo getAiDmRunCount(DataSourceRequest dataSourceRequest); + + DataSourceResult getAiComKendoListCust(DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/impl/WarnDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/impl/WarnDataServiceImpl.java index 30227e9d..7616b699 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/impl/WarnDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/warn/service/impl/WarnDataServiceImpl.java @@ -7,7 +7,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.common.DataSourceLoadOptionsBase; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.common.GroupHelper; +import com.yfd.platform.common.GroupingInfo; 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.AiDmRunVo; import com.yfd.platform.qgc_env.warn.entity.vo.EngWarnCountVo; import com.yfd.platform.qgc_env.warn.service.WarnDataService; @@ -16,6 +19,7 @@ import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -91,6 +95,70 @@ public class WarnDataServiceImpl implements WarnDataService { return vo; } + @Override + public DataSourceResult getAiComKendoListCust(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + GroupingInfo[] groupInfos = loadOptions == null ? null : loadOptions.getGroup(); + Map paramMap = new HashMap<>(); + + StringBuilder detailSql = new StringBuilder(); + detailSql.append("SELECT ") + .append("rec.ID AS id, ") + .append("rec.TYPE AS type, ") + .append(buildAiTypeNameExpr("rec.TYPE")).append(" AS typeName, ") + .append("rec.STCD AS stcd, ") + .append("ai.STNM AS stnm, ") + .append("ai.RSTCD AS rstcd, ") + .append("eng.ENNM AS ennm, ") + .append("ai.BASE_ID AS baseId, ") + .append("ai.HBRVCD AS hbrvcd, ") + .append("ai.RVCD AS rvcd, ") + .append("rec.TM AS tm, ") + .append("rec.END_TM AS endTm, ") + .append("rec.AI_VAL AS aiVal, ") + .append("rec.FID AS fid, ") + .append("rec.IS_FSF AS isFsf, ") + .append("rec.IS_BIG_DEBRIS_AREA AS isBigDebrisArea, ") + .append("rec.IS_CLEAR_DRIFT AS isClearDrift, ") + .append("rec.REMARK AS remark, ") + .append("rec.RECORD_TIME AS recordTime, ") + .append("rec.MODIFY_TIME AS modifyTime ") + .append("FROM SD_AICOM_R rec ") + .append("LEFT JOIN SD_AIMONITOR_B_H ai ON ai.STCD = rec.STCD AND NVL(ai.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = ai.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("WHERE NVL(rec.IS_DELETED, 0) = 0 "); + + String filterSql = buildAiComFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + detailSql.append(" AND ").append(filterSql).append(" "); + } + + DataSourceResult result = new DataSourceResult<>(); + if (CollUtil.isNotEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + String groupedSql = buildAiComGroupSql(detailSql.toString(), groupInfos); + List> rows = microservicDynamicSQLMapper.getAllList(groupedSql, paramMap); + result.setTotal(rows.size()); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos))); + } else { + result.setData((List) (List) new GroupHelper().group(rows, Arrays.asList(groupInfos))); + } + result.setAggregates(new HashMap<>()); + return result; + } + + StringBuilder finalSql = new StringBuilder(); + finalSql.append("SELECT r.* FROM (").append(detailSql).append(") r "); + finalSql.append(buildAiComOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + + Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType(page, finalSql.toString(), paramMap, AiComListVo.class); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + private AiDmRunVo buildAiDmRunVo(Map row) { if (row == null || row.isEmpty()) { return null; @@ -182,6 +250,213 @@ public class WarnDataServiceImpl implements WarnDataService { return sql.toString(); } + private String buildAiComGroupSql(String detailSql, GroupingInfo[] groupInfos) { + if (groupInfos == null || groupInfos.length == 0) { + return detailSql; + } + List selectColumns = new ArrayList<>(); + List groupColumns = new ArrayList<>(); + for (GroupingInfo item : groupInfos) { + String column = mapAiComResultColumn("t", item.getSelector()); + if (StrUtil.isBlank(column)) { + continue; + } + String alias = item.getSelector(); + selectColumns.add(column + " AS " + alias); + selectColumns.add("COUNT(1) AS count_" + alias); + groupColumns.add(column); + } + if (selectColumns.isEmpty()) { + return detailSql; + } + return "SELECT " + String.join(", ", selectColumns) + + " FROM (" + detailSql + ") t GROUP BY " + String.join(", ", groupColumns); + } + + private String buildAiComOrderBySql(List sorts) { + if (CollUtil.isEmpty(sorts)) { + return " ORDER BY r.tm DESC, r.recordTime DESC "; + } + List orderItems = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor item : sorts) { + if (item == null || StrUtil.isBlank(item.getField())) { + continue; + } + String column = mapAiComResultColumn("r", item.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(item.getDir()) ? "DESC" : "ASC"; + orderItems.add(column + " " + dir); + } + if (orderItems.isEmpty()) { + return " ORDER BY r.tm DESC, r.recordTime DESC "; + } + return " ORDER BY " + String.join(", ", orderItems); + } + + private String buildAiComFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + List parts = new ArrayList<>(); + if (CollUtil.isNotEmpty(filter.getFilters())) { + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildAiComFilterCondition(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) + ")"; + } + String column = mapAiComBaseColumn(filter.getField()); + if (StrUtil.isBlank(column)) { + return ""; + } + String paramKey = "aiComParam" + indexHolder[0]++; + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + Object value = filter.getValue(); + switch (operator) { + case "eq": + paramMap.put(paramKey, value); + return column + " = #{map." + paramKey + "}"; + case "neq": + paramMap.put(paramKey, 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, normalizeAiValue(filter.getField(), value)); + return column + " > #{map." + paramKey + "}"; + case "gte": + paramMap.put(paramKey, normalizeAiValue(filter.getField(), value)); + return column + " >= #{map." + paramKey + "}"; + case "lt": + paramMap.put(paramKey, normalizeAiValue(filter.getField(), value)); + return column + " < #{map." + paramKey + "}"; + case "lte": + paramMap.put(paramKey, normalizeAiValue(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 buildAiComInSql(column, value, paramKey, paramMap); + default: + return ""; + } + } + + private String buildAiComInSql(String column, Object value, String paramKey, Map paramMap) { + List values = parseAiCodes(value == null ? null : String.valueOf(value)); + if (CollUtil.isEmpty(values)) { + return ""; + } + List 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 mapAiComBaseColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "id" -> "rec.ID"; + case "type" -> "rec.TYPE"; + case "typeName" -> buildAiTypeNameExpr("rec.TYPE"); + case "stcd" -> "rec.STCD"; + case "stnm" -> "ai.STNM"; + case "rstcd" -> "ai.RSTCD"; + case "ennm", "stnmEng" -> "eng.ENNM"; + case "baseId" -> "ai.BASE_ID"; + case "hbrvcd" -> "ai.HBRVCD"; + case "rvcd" -> "ai.RVCD"; + case "tm" -> "rec.TM"; + case "endTm" -> "rec.END_TM"; + case "aiVal" -> "rec.AI_VAL"; + case "fid" -> "rec.FID"; + case "isFsf" -> "rec.IS_FSF"; + case "isBigDebrisArea" -> "rec.IS_BIG_DEBRIS_AREA"; + case "isClearDrift" -> "rec.IS_CLEAR_DRIFT"; + case "remark" -> "rec.REMARK"; + case "recordTime" -> "rec.RECORD_TIME"; + case "modifyTime" -> "rec.MODIFY_TIME"; + default -> null; + }; + } + + private String mapAiComResultColumn(String alias, String field) { + if (StrUtil.isBlank(alias) || StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "id" -> alias + ".id"; + case "type" -> alias + ".type"; + case "typeName" -> alias + ".typeName"; + case "stcd" -> alias + ".stcd"; + case "stnm" -> alias + ".stnm"; + case "rstcd" -> alias + ".rstcd"; + case "ennm", "stnmEng" -> alias + ".ennm"; + case "baseId" -> alias + ".baseId"; + case "hbrvcd" -> alias + ".hbrvcd"; + case "rvcd" -> alias + ".rvcd"; + case "tm" -> alias + ".tm"; + case "endTm" -> alias + ".endTm"; + case "aiVal" -> alias + ".aiVal"; + case "fid" -> alias + ".fid"; + case "isFsf" -> alias + ".isFsf"; + case "isBigDebrisArea" -> alias + ".isBigDebrisArea"; + case "isClearDrift" -> alias + ".isClearDrift"; + case "remark" -> alias + ".remark"; + case "recordTime" -> alias + ".recordTime"; + case "modifyTime" -> alias + ".modifyTime"; + default -> null; + }; + } + + private String buildAiTypeNameExpr(String typeColumn) { + return "CASE " + typeColumn + + " WHEN 'AI_5001' THEN '漂浮物' " + + " WHEN 'AI_5002' THEN '运鱼车运行' " + + " WHEN 'AI_5003' THEN '运鱼船出港' " + + " WHEN 'AI_5004' THEN '集鱼船集鱼' " + + " WHEN 'AI_5005' THEN '叠梁门运行' " + + " WHEN 'AI_5006' THEN '赶鱼栅运行' " + + " WHEN 'AI_5007' THEN '升鱼机运行' " + + " WHEN 'AI_5008' THEN 'AGV小车' " + + " WHEN 'AI_5009' THEN '鱼类暂养' " + + " WHEN 'AI_5010' THEN '坝上升鱼机' " + + " WHEN 'AI_5011' THEN '漂浮物清理' " + + " WHEN 'AI_5012' THEN '鱼道放流' " + + " ELSE " + typeColumn + " END"; + } + private void fillWarnNames(List list) { if (CollUtil.isEmpty(list)) { return; @@ -283,6 +558,20 @@ public class WarnDataServiceImpl implements WarnDataService { } } + private Object normalizeAiValue(String field, Object value) { + if (value == null) { + return null; + } + if ("tm".equals(field) || "endTm".equals(field) || "recordTime".equals(field) || "modifyTime".equals(field)) { + return parseAiTime(String.valueOf(value)); + } + return value; + } + + private String safeString(Object value) { + return value == null ? "" : String.valueOf(value).trim(); + } + private String buildSourceFilterCondition(DataSourceRequest.FilterDescriptor filter, Map paramMap, int[] indexHolder) {