diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index bc54e635..35996aa1 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -1627,7 +1627,6 @@ public class WeFishServiceImpl implements WeFishService { @Override public DataSourceResult getWeFvR(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); - GroupingInfo[] groupInfos = loadOptions == null ? null : loadOptions.getGroup(); Map paramMap = new HashMap<>(); StringBuilder sql = new StringBuilder(); @@ -1636,46 +1635,28 @@ public class WeFishServiceImpl implements WeFishService { .append("INNER JOIN SD_WEFV_R t1 ON t.ID = t1.WER_ID ") .append("WHERE NVL(t.IS_DELETED, 0) = 0 AND NVL(t1.IS_DELETED, 0) = 0 "); - String filterSql = buildWeFvFilterCondition( + String filterSql = QgcQueryWrapperUtil.buildFilterCondition( dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, - new int[]{0} + new int[]{0}, + this::mapWeFvColumn ); if (StrUtil.isNotBlank(filterSql)) { sql.append("AND ").append(filterSql).append(" "); } DataSourceResult result = new DataSourceResult<>(); - if (CollUtil.isNotEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { - String groupBy = KendoUtil.getGroupBy(dataSourceRequest); - if (StrUtil.isNotBlank(groupBy)) { - List groupFields = new ArrayList<>(); - for (GroupingInfo item : groupInfos) { - if (item != null && StrUtil.isNotBlank(item.getSelector())) { - groupFields.add(item.getSelector()); - } - } - StringBuilder temp = new StringBuilder(); - temp.append("SELECT ").append(String.join(",", groupFields)).append(", count(*) as "); - if (groupInfos.length > 1) { - temp.append("count"); - } else { - temp.append("count_").append(String.join("_", groupFields)); - } - String groupedSql = temp.append(" FROM ( ").append(sql).append(" ) ").append(groupBy).toString(); - List> rows = microservicDynamicSQLMapper.getAllList(groupedSql, paramMap); - 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.setTotal((long) rows.size()); - result.setAggregates(new HashMap<>()); - return result; - } + String groupSql = QgcQueryWrapperUtil.buildGroupSql(dataSourceRequest, sql); + if (StrUtil.isNotBlank(groupSql)) { + List> rows = microservicDynamicSQLMapper.getAllList(groupSql, paramMap); + return QgcQueryWrapperUtil.buildGroupResult(dataSourceRequest, rows); } - sql.append(buildWeFvOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + sql.append(QgcQueryWrapperUtil.buildOrderBySql( + dataSourceRequest == null ? null : dataSourceRequest.getSort(), + this::mapWeFvColumn, + "t1.TM DESC NULLS LAST, t.STCD ASC" + )); Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); @@ -1687,113 +1668,6 @@ public class WeFishServiceImpl implements WeFishService { return result; } - private String buildWeFvFilterCondition(DataSourceRequest.FilterDescriptor filter, - Map paramMap, - int[] indexHolder) { - if (filter == null) { - return ""; - } - List conditions = new ArrayList<>(); - List filters = filter.getFilters(); - if (CollUtil.isNotEmpty(filters)) { - for (DataSourceRequest.FilterDescriptor child : filters) { - String condition = buildWeFvFilterCondition(child, paramMap, indexHolder); - if (StrUtil.isNotBlank(condition)) { - conditions.add(condition); - } - } - } else { - String leafCondition = buildWeFvLeafCondition(filter, paramMap, indexHolder); - if (StrUtil.isNotBlank(leafCondition)) { - conditions.add(leafCondition); - } - } - if (conditions.isEmpty()) { - return ""; - } - String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; - return "(" + String.join(logic, conditions) + ")"; - } - - private String buildWeFvLeafCondition(DataSourceRequest.FilterDescriptor filter, - Map paramMap, - int[] indexHolder) { - String column = mapWeFvColumn(filter.getField()); - if (StrUtil.isBlank(column)) { - return ""; - } - String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); - 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 + " <> '')"; - } - if ("in".equals(operator) || "ni".equals(operator)) { - List values = normalizeWeFishQgcValues(filter.getValue()); - if (values.isEmpty()) { - return ""; - } - List placeholders = new ArrayList<>(); - boolean isDateField = "t1.tm".equals(column); - for (Object value : values) { - String paramKey = "weFvParam" + indexHolder[0]++; - paramMap.put(paramKey, value); - if (isDateField) { - String text = String.valueOf(value).trim(); - if (text.length() <= 10) { - placeholders.add("TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"); - } else { - placeholders.add("TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"); - } - } else { - placeholders.add("#{map." + paramKey + "}"); - } - } - String prefix = "ni".equals(operator) ? "NOT " : ""; - return column + " " + prefix + "IN (" + String.join(", ", placeholders) + ")"; - } - String paramKey = "weFvParam" + indexHolder[0]++; - paramMap.put(paramKey, filter.getValue()); - boolean isDateField = "t1.tm".equals(column); - String valueExpr; - if (isDateField) { - String text = String.valueOf(filter.getValue()).trim(); - if (text.length() <= 10) { - valueExpr = "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"; - } else { - valueExpr = "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"; - } - } else { - valueExpr = "#{map." + paramKey + "}"; - } - return switch (operator) { - case "lt", "lessthan" -> column + " < " + valueExpr; - case "lte", "lessthanorequals" -> column + " <= " + valueExpr; - case "gt", "greaterthan" -> column + " > " + valueExpr; - case "gte", "greaterthanorequals" -> column + " >= " + valueExpr; - case "ne", "notequals" -> column + " <> " + valueExpr; - case "contains", "doesnotcontain", "startswith", "endswith" -> { - String pattern = switch (operator) { - case "contains" -> "%#{map." + paramKey + "}%"; - case "doesnotcontain" -> "%#{map." + paramKey + "}%"; - case "startswith" -> "#{map." + paramKey + "}%"; - case "endswith" -> "%#{map." + paramKey + "}"; - default -> "%#{map." + paramKey + "}%"; - }; - String likePrefix = "doesnotcontain".equals(operator) ? "NOT " : ""; - yield column + " " + likePrefix + "LIKE " + pattern; - } - default -> column + " = " + valueExpr; - }; - } - private String mapWeFvColumn(String field) { if (StrUtil.isBlank(field)) { return null; @@ -1808,28 +1682,6 @@ public class WeFishServiceImpl implements WeFishService { }; } - private String buildWeFvOrderBySql(List sorts) { - if (CollUtil.isEmpty(sorts)) { - return " ORDER BY t1.tm DESC NULLS LAST, t.stcd ASC"; - } - List orderByParts = new ArrayList<>(); - for (DataSourceRequest.SortDescriptor sort : sorts) { - if (sort == null || StrUtil.isBlank(sort.getField())) { - continue; - } - String column = mapWeFvColumn(sort.getField()); - if (StrUtil.isBlank(column)) { - continue; - } - String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; - orderByParts.add(column + " " + direction + " NULLS LAST"); - } - if (orderByParts.isEmpty()) { - return " ORDER BY t1.tm DESC NULLS LAST, t.stcd ASC"; - } - return " ORDER BY " + String.join(", ", orderByParts); - } - private String buildWeFishQgcGroupSql(String baseSql, GroupingInfo[] groupInfos) { if (groupInfos == null || groupInfos.length == 0) { return baseSql; diff --git a/backend/src/main/java/com/yfd/platform/utils/QgcQueryWrapperUtil.java b/backend/src/main/java/com/yfd/platform/utils/QgcQueryWrapperUtil.java index 3554573d..62a60bab 100644 --- a/backend/src/main/java/com/yfd/platform/utils/QgcQueryWrapperUtil.java +++ b/backend/src/main/java/com/yfd/platform/utils/QgcQueryWrapperUtil.java @@ -37,6 +37,11 @@ public class QgcQueryWrapperUtil { return FIELDNULL.contains(columName) ? "00000000-0000-0000-0000-000000000000" : null; } + @FunctionalInterface + public interface ColumnMapper { + String apply(String field); + } + public static String getFilterFieldValue(DataSourceLoadOptionsBase loadOptions, String fieldName) { try { JsonElement jsonElement = (new JsonParser()).parse(JSONUtil.toJsonStr(loadOptions.getFilter())); @@ -702,6 +707,239 @@ public class QgcQueryWrapperUtil { } + + + public static String buildFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder, + ColumnMapper columnMapper) { + if (filter == null) { + return ""; + } + List conditions = new ArrayList<>(); + List filters = filter.getFilters(); + if (CollectionUtil.isNotEmpty(filters)) { + for (DataSourceRequest.FilterDescriptor child : filters) { + String condition = buildFilterCondition(child, paramMap, indexHolder, columnMapper); + if (StrUtil.isNotBlank(condition)) { + conditions.add(condition); + } + } + } else { + String leafCondition = buildLeafCondition(filter, paramMap, indexHolder, columnMapper); + if (StrUtil.isNotBlank(leafCondition)) { + conditions.add(leafCondition); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return "(" + String.join(logic, conditions) + ")"; + } + + private static String buildLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder, + ColumnMapper columnMapper) { + String column = columnMapper.apply(filter.getField()); + if (StrUtil.isBlank(column)) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + 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 + " <> '')"; + } + if ("in".equals(operator) || "ni".equals(operator)) { + List values = normalizeValues(filter.getValue()); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + boolean isDateField = isDateColumn(column); + for (Object value : values) { + String paramKey = "param" + indexHolder[0]++; + paramMap.put(paramKey, value); + if (isDateField) { + String text = String.valueOf(value).trim(); + if (text.length() <= 10) { + placeholders.add("TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"); + } else { + placeholders.add("TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"); + } + } else { + placeholders.add("#{map." + paramKey + "}"); + } + } + String prefix = "ni".equals(operator) ? "NOT " : ""; + return column + " " + prefix + "IN (" + String.join(", ", placeholders) + ")"; + } + String paramKey = "param" + indexHolder[0]++; + paramMap.put(paramKey, filter.getValue()); + boolean isDateField = isDateColumn(column); + String valueExpr; + if (isDateField) { + String text = String.valueOf(filter.getValue()).trim(); + if (text.length() <= 10) { + valueExpr = "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"; + } else { + valueExpr = "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"; + } + } else { + valueExpr = "#{map." + paramKey + "}"; + } + return switch (operator) { + case "lt", "lessthan" -> column + " < " + valueExpr; + case "lte", "lessthanorequals" -> column + " <= " + valueExpr; + case "gt", "greaterthan" -> column + " > " + valueExpr; + case "gte", "greaterthanorequals" -> column + " >= " + valueExpr; + case "ne", "notequals" -> column + " <> " + valueExpr; + case "contains", "doesnotcontain", "startswith", "endswith" -> { + String pattern = switch (operator) { + case "contains" -> "%#{map." + paramKey + "}%"; + case "doesnotcontain" -> "%#{map." + paramKey + "}%"; + case "startswith" -> "#{map." + paramKey + "}%"; + case "endswith" -> "%#{map." + paramKey + "}"; + default -> "%#{map." + paramKey + "}%"; + }; + String likePrefix = "doesnotcontain".equals(operator) ? "NOT " : ""; + yield column + " " + likePrefix + "LIKE " + pattern; + } + default -> column + " = " + valueExpr; + }; + } + + private static List normalizeValues(Object value) { + List result = new ArrayList<>(); + if (value == null) { + return result; + } + if (value instanceof List) { + for (Object item : (List) value) { + if (item != null && StrUtil.isNotBlank(item.toString())) { + result.add(item); + } + } + } else if (StrUtil.isNotBlank(value.toString())) { + result.add(value); + } + return result; + } + + private static boolean isDateColumn(String column) { + if (StrUtil.isBlank(column)) { + return false; + } + String lowerColumn = column.toLowerCase(); + return lowerColumn.contains(".tm") || lowerColumn.contains(".time") || lowerColumn.contains(".date"); + } + + public static String buildOrderBySql(List sorts, + ColumnMapper columnMapper, + String defaultOrderBy) { + if (CollectionUtil.isEmpty(sorts)) { + return StrUtil.isNotBlank(defaultOrderBy) ? " ORDER BY " + defaultOrderBy : ""; + } + List orderByParts = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = columnMapper.apply(sort.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderByParts.add(column + " " + direction + " NULLS LAST"); + } + if (orderByParts.isEmpty()) { + return StrUtil.isNotBlank(defaultOrderBy) ? " ORDER BY " + defaultOrderBy : ""; + } + return " ORDER BY " + String.join(", ", orderByParts); + } + + public static String buildGroupSql(DataSourceRequest dataSourceRequest, StringBuilder sql) { + if (CollectionUtil.isEmpty(dataSourceRequest.getGroup())) { + return null; + } + String groupBy = KendoUtil.getGroupBy(dataSourceRequest); + if (StrUtil.isBlank(groupBy)) { + return null; + } + List groupFields = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor item : dataSourceRequest.getGroup()) { + if (item != null && StrUtil.isNotBlank(item.getField())) { + groupFields.add(item.getField()); + } + } + StringBuilder temp = new StringBuilder(); + temp.append("SELECT ").append(String.join(",", groupFields)).append(", count(*) as "); + if (groupFields.size() > 1) { + temp.append("count"); + } else { + temp.append("count_").append(String.join("_", groupFields)); + } + return temp.append(" FROM ( ").append(sql).append(" ) ").append(groupBy).toString(); + } + + public static DataSourceResult buildGroupResult(DataSourceRequest dataSourceRequest, + List> rows) { + DataSourceResult result = new DataSourceResult<>(); + List groupingInfos = convertToGroupingInfo(dataSourceRequest.getGroup()); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(rows, groupingInfos)); + } else { + result.setData((List) (List) new GroupHelper().group(rows, groupingInfos)); + } + result.setTotal((long) rows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private static List convertToGroupingInfo(List groupDescriptors) { + List groupingInfos = new ArrayList<>(); + if (CollectionUtil.isEmpty(groupDescriptors)) { + return groupingInfos; + } + for (DataSourceRequest.GroupDescriptor groupDescriptor : groupDescriptors) { + GroupingInfo groupingInfo = new GroupingInfo(); + groupingInfo.setSelector(groupDescriptor.getField()); + String dir = groupDescriptor.getDir(); + String normalizedDir = StrUtil.isBlank(dir) ? "" : dir.toLowerCase(); + if ("des".equals(normalizedDir)) { + normalizedDir = "desc"; + } + if (StrUtil.isBlank(normalizedDir)) { + groupingInfo.setDesc(false); + } else if (normalizedDir.equals("asc")) { + groupingInfo.setDesc(false); + } else if (normalizedDir.equals("desc")) { + groupingInfo.setDesc(true); + } + groupingInfo.setNeedSortFlag(groupDescriptor.getNeedSortFlag()); + List aggregateDescriptors = groupDescriptor.getAggregates(); + if (CollectionUtil.isNotEmpty(aggregateDescriptors)) { + for (DataSourceRequest.AggregateDescriptor aggregateDescriptor : aggregateDescriptors) { + SummaryInfo summaryInfo = new SummaryInfo(); + summaryInfo.setSelector(aggregateDescriptor.getField()); + summaryInfo.setSummaryType(aggregateDescriptor.getAggregate()); + groupingInfo.getSummaryInfos().add(summaryInfo); + } + } + groupingInfos.add(groupingInfo); + } + return groupingInfos; + } + static { FIELDNULL.add("parentId"); }