From fc09d69302a6d38b5fcd0309ed88111fb781417f Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 29 Jun 2026 13:47:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=94=B5=E7=AB=99=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E5=AE=9E=E6=97=B6=E7=9B=91=E6=B5=8B=E6=95=B0=E6=8D=AE=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SdEngInfoBHController.java | 8 + .../qgc_base/domain/vo/EngStbprpDataVo.java | 24 ++ .../qgc_base/service/ISdEngInfoBHService.java | 2 + .../service/impl/SdEngInfoBHServiceImpl.java | 371 +++++++++++++++++- 4 files changed, 396 insertions(+), 9 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_base/domain/vo/EngStbprpDataVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdEngInfoBHController.java b/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdEngInfoBHController.java index b5c994ee..798ab6d7 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdEngInfoBHController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/controller/SdEngInfoBHController.java @@ -93,6 +93,14 @@ public class SdEngInfoBHController { return ResponseResult.successData(engInfoBHService.getVmsstbprptKendoList(dataSourceRequest)); } + @PostMapping("/stbprpData/GetKendoListCust") + @Operation(summary = "电站通用实时监测数据查询") + public ResponseResult getStbprpDataKendoListCust(@RequestBody DataSourceRequest dataSourceRequest, + @RequestParam("tbCode") String tbCode, + @RequestParam(value = "ignorePageLimit", required = false) Boolean ignorePageLimit) { + return ResponseResult.successData(engInfoBHService.getStbprpDataKendoListCust(dataSourceRequest, tbCode, ignorePageLimit)); + } + @Log(module = "电站管理", value = "新增电站") @PostMapping("/add") @Operation(summary = "新增电站") diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/domain/vo/EngStbprpDataVo.java b/backend/src/main/java/com/yfd/platform/qgc_base/domain/vo/EngStbprpDataVo.java new file mode 100644 index 00000000..afd9546c --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_base/domain/vo/EngStbprpDataVo.java @@ -0,0 +1,24 @@ +package com.yfd.platform.qgc_base.domain.vo; + +import io.swagger.v3.oas.annotations.media.Schema; + +import java.io.Serializable; +import java.util.LinkedHashMap; +import java.util.Map; + +@Schema(description = "电站通用监测数据动态行") +public class EngStbprpDataVo extends LinkedHashMap implements Serializable { + + private static final long serialVersionUID = 1L; + + public EngStbprpDataVo() { + super(); + } + + public EngStbprpDataVo(Map source) { + super(); + if (source != null && !source.isEmpty()) { + putAll(source); + } + } +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdEngInfoBHService.java b/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdEngInfoBHService.java index e9128874..7d034512 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdEngInfoBHService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_base/service/ISdEngInfoBHService.java @@ -84,4 +84,6 @@ public interface ISdEngInfoBHService extends IService { DataSourceResult getVmsstbprptKendoList(DataSourceRequest dataSourceRequest); DataSourceResult getOperatKendoList(DataSourceRequest dataSourceRequest); + + DataSourceResult getStbprpDataKendoListCust(DataSourceRequest dataSourceRequest, String tbCode, Boolean ignorePageLimit); } 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 315005fd..e860aa8b 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 @@ -27,6 +27,7 @@ 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.EngEiaapprovalVo; import com.yfd.platform.qgc_base.domain.vo.EngOperatVo; +import com.yfd.platform.qgc_base.domain.vo.EngStbprpDataVo; import com.yfd.platform.qgc_base.domain.vo.EngStBaseInfoVo; import com.yfd.platform.qgc_base.domain.vo.EngStInfoResultVo; import com.yfd.platform.qgc_base.domain.vo.EngVmsstbprptVo; @@ -41,15 +42,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; /** @@ -709,6 +702,59 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl result = new DataSourceResult<>(); + result.setAggregates(new HashMap<>()); + if (StrUtil.isBlank(tbCode)) { + result.setData(new ArrayList<>()); + result.setTotal(0L); + return result; + } + DataSourceRequest request = dataSourceRequest == null ? new DataSourceRequest() : dataSourceRequest; + if (!Boolean.TRUE.equals(ignorePageLimit) && request.getTake() == 0) { + request.setTake(2000); + } + + DataSourceLoadOptionsBase loadOptions = request.toDevRequest(); + List tableMetaList = queryStbprpTableMeta(tbCode); + if (CollUtil.isEmpty(tableMetaList)) { + return result; + } + + String firstTableName = tableMetaList.getFirst().tableName(); + String detailSql = buildStbprpDataDetailSql(request, tableMetaList); + Map paramMap = new HashMap<>(); + String filterSql = buildStbprpDataFilterCondition(request.getFilter(), paramMap, new int[]{0}, tableMetaList); + if (StrUtil.isNotBlank(filterSql)) { + detailSql = detailSql + " AND " + filterSql; + } + + if (CollUtil.isEmpty(request.getGroup())) { + String sql = detailSql + buildStbprpDataOrderBySql(request.getSort(), tableMetaList); + Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List> rows = microservicDynamicSQLMapper.pageAllList(page, sql, paramMap); + List list = new ArrayList<>(); + for (Map row : rows) { + list.add(new EngStbprpDataVo(row)); + } + result.setData(list); + result.setTotal(page == null ? list.size() : page.getTotal()); + return result; + } + + GroupingInfo[] groupInfos = loadOptions == null ? new GroupingInfo[0] : loadOptions.getGroup(); + String groupSql = buildStbprpDataGroupSql(detailSql, request.getGroup(), tableMetaList); + List> rows = microservicDynamicSQLMapper.pageAllList(null, groupSql, paramMap); + if (Boolean.TRUE.equals(request.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.setTotal((long) rows.size()); + return result; + } + private DataSourceResult queryOperatSummaryList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { StringBuilder sql = new StringBuilder(); @@ -2303,4 +2349,311 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl null; }; } + + private List queryStbprpTableMeta(String tbCode) { + // 1. 解析参数 + List tbCodes = StrUtil.split(tbCode, ',') + .stream() + .map(StrUtil::trim) + .filter(StrUtil::isNotBlank) + .distinct() + .toList(); + + if (tbCodes.isEmpty()) { + return Collections.emptyList(); + } + + // 2. 构建 SQL 和参数 + Map paramMap = new HashMap<>(); + List placeholders = new ArrayList<>(); + for (int i = 0; i < tbCodes.size(); i++) { + String key = "tbCode" + i; + paramMap.put(key, tbCodes.get(i)); + placeholders.add("#{map." + key + "}"); + } + + String sql = "SELECT ID, TB, TB_CODE, STCD_MAPPING, TM_MAPPING " + + "FROM ST_TB_B " + + "WHERE NVL(IS_DELETED, 0) = 0 " + + "AND TB_CODE IN (" + StrUtil.join(", ", placeholders) + ") " + + "ORDER BY TB_CODE"; + + // 3. 执行查询 + List> rows = microservicDynamicSQLMapper.pageAllList(null, sql, paramMap); + + // 4. 转换结果 + List result = new ArrayList<>(); + for (Map row : rows) { + result.add(new StbprpTableMeta( + asString(row.get("ID")), + asString(row.get("TB")), + asString(row.get("TB_CODE")), + StrUtil.blankToDefault(asString(row.get("STCD_MAPPING")), "STCD"), + StrUtil.blankToDefault(asString(row.get("TM_MAPPING")), "TM") + )); + } + return result; + } + + /** + * 安全转为字符串 + */ + private String asString(Object obj) { + return obj == null ? null : obj.toString(); + } + + private String buildStbprpDataDetailSql(DataSourceRequest request, List tableMetaList) { + List selectItems = resolveStbprpSelectItems(request == null ? null : request.getSelect(), tableMetaList); + StringBuilder sql = new StringBuilder("SELECT "); + sql.append(String.join(", ", selectItems)).append(" FROM "); + for (int i = 0; i < tableMetaList.size(); i++) { + StbprpTableMeta meta = tableMetaList.get(i); + String alias = "t" + (i + 1); + if (i == 0) { + sql.append(meta.tableName()).append(" ").append(alias).append(" "); + } else { + StbprpTableMeta first = tableMetaList.getFirst(); + sql.append(" LEFT JOIN ").append(meta.tableName()).append(" ").append(alias) + .append(" ON t1.").append(first.stcdMapping()).append(" = ").append(alias).append(".").append(meta.stcdMapping()) + .append(" AND t1.").append(first.tmMapping()).append(" = ").append(alias).append(".").append(meta.tmMapping()).append(" "); + } + } + sql.append(" WHERE 1 = 1"); + return sql.toString(); + } + + private List resolveStbprpSelectItems(List selectFields, List tableMetaList) { + if (CollUtil.isEmpty(selectFields)) { + return List.of("t1.*"); + } + List items = new ArrayList<>(); + for (String field : selectFields) { + if (StrUtil.isBlank(field)) { + continue; + } + String mapped = mapStbprpField(field, tableMetaList); + if (StrUtil.isNotBlank(mapped)) { + items.add(mapped + " AS \"" + field.trim() + "\""); + } + } + if (items.isEmpty()) { + items.add("t1.*"); + } + return items; + } + + private String buildStbprpDataFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder, + List tableMetaList) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildStbprpDataLeafCondition(filter, paramMap, indexHolder, tableMetaList); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List childConditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildStbprpDataFilterCondition(child, paramMap, indexHolder, tableMetaList); + if (StrUtil.isNotBlank(childSql)) { + childConditions.add("(" + childSql + ")"); + } + } + if (childConditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return String.join(logic, childConditions); + } + + private String buildStbprpDataLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder, + List tableMetaList) { + String column = mapStbprpField(filter.getField(), tableMetaList); + if (StrUtil.isBlank(column)) { + return ""; + } + 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 ("isempty".equals(operator)) { + return "(" + column + " IS NULL OR " + column + " = '')"; + } + if ("isnotempty".equals(operator)) { + return "(" + column + " IS NOT NULL AND " + column + " <> '')"; + } + boolean dateField = isStbprpDateField(filter); + if ("in".equals(operator) || "ni".equals(operator)) { + List values = normalizeFilterValues(value); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (Object item : values) { + String key = "stbprpParam" + indexHolder[0]++; + paramMap.put(key, item); + placeholders.add(buildStbprpDataValueExpr(key, dateField, item)); + } + return column + ("ni".equals(operator) ? " NOT IN (" : " IN (") + String.join(", ", placeholders) + ")"; + } + if (value == null) { + return ""; + } + String key = "stbprpParam" + indexHolder[0]++; + String expr = buildStbprpDataValueExpr(key, dateField, value); + return switch (operator) { + case "eq" -> { + paramMap.put(key, value); + yield column + " = " + expr; + } + case "neq" -> { + paramMap.put(key, value); + yield column + " <> " + expr; + } + case "contains" -> { + paramMap.put(key, "%" + value + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "doesnotcontain" -> { + paramMap.put(key, "%" + value + "%"); + yield column + " NOT LIKE #{map." + key + "}"; + } + case "startswith" -> { + paramMap.put(key, value + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "endswith" -> { + paramMap.put(key, "%" + value); + yield column + " LIKE #{map." + key + "}"; + } + case "gt" -> { + paramMap.put(key, value); + yield column + " > " + expr; + } + case "gte" -> { + paramMap.put(key, value); + yield column + " >= " + expr; + } + case "lt" -> { + paramMap.put(key, value); + yield column + " < " + expr; + } + case "lte" -> { + paramMap.put(key, value); + yield column + " <= " + expr; + } + default -> ""; + }; + } + + private String buildStbprpDataValueExpr(String paramKey, boolean dateField, Object value) { + if (!dateField || value == null) { + return "#{map." + paramKey + "}"; + } + String text = String.valueOf(value).trim(); + if (text.length() <= 10) { + return "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"; + } + return "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"; + } + + private boolean isStbprpDateField(DataSourceRequest.FilterDescriptor filter) { + if (filter == null) { + return false; + } + if ("date".equalsIgnoreCase(filter.getDataType())) { + return true; + } + String field = StrUtil.blankToDefault(filter.getField(), "").trim().toLowerCase(); + if (field.contains(".")) { + field = field.substring(field.lastIndexOf('.') + 1); + } + return "tm".equals(field) || "dt".equals(field); + } + + private String buildStbprpDataOrderBySql(List sortList, List tableMetaList) { + if (CollUtil.isEmpty(sortList)) { + return ""; + } + List orderItems = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sortList) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapStbprpField(sort.getField(), tableMetaList); + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(sort.getDir()) || "des".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderItems.add(column + " " + dir); + } + if (orderItems.isEmpty()) { + return ""; + } + return " ORDER BY " + String.join(", ", orderItems); + } + + private String buildStbprpDataGroupSql(String detailSql, + List groups, + List tableMetaList) { + List selectItems = new ArrayList<>(); + List groupItems = new ArrayList<>(); + List orderItems = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor descriptor : groups) { + if (descriptor == null || StrUtil.isBlank(descriptor.getField())) { + continue; + } + String column = mapStbprpField(descriptor.getField(), tableMetaList); + if (StrUtil.isBlank(column)) { + continue; + } + String upperField = descriptor.getField().trim().toUpperCase(); + selectItems.add(column + " AS " + upperField); + selectItems.add("COUNT(*) AS COUNT_" + upperField); + groupItems.add(column); + String dir = "desc".equalsIgnoreCase(descriptor.getDir()) || "des".equalsIgnoreCase(descriptor.getDir()) ? "DESC" : "ASC"; + orderItems.add(column + " " + dir); + } + if (selectItems.isEmpty()) { + selectItems.add("t1.STCD AS STCD"); + selectItems.add("COUNT(*) AS COUNT_STCD"); + groupItems.add("t1.STCD"); + orderItems.add("t1.STCD ASC"); + } + return "SELECT " + String.join(", ", selectItems) + + " FROM (" + detailSql + ") t1 GROUP BY " + String.join(", ", groupItems) + + " ORDER BY " + String.join(", ", orderItems); + } + + private String mapStbprpField(String field, List tableMetaList) { + if (StrUtil.isBlank(field) || CollUtil.isEmpty(tableMetaList)) { + return null; + } + String normalized = field.trim(); + if (!normalized.contains(".")) { + return "t1." + normalized.toUpperCase(); + } + String[] parts = normalized.split("\\.", 2); + if (parts.length != 2) { + return null; + } + for (int i = 0; i < tableMetaList.size(); i++) { + if (StrUtil.equalsIgnoreCase(tableMetaList.get(i).tbCode(), parts[0])) { + return "t" + (i + 1) + "." + parts[1].toUpperCase(); + } + } + return null; + } + + private record StbprpTableMeta(String id, String tableName, String tbCode, String stcdMapping, String tmMapping) { + } }