diff --git a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewThresholdManage.java b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewThresholdManage.java index b162923180..8ea51c24c0 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewThresholdManage.java +++ b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartViewThresholdManage.java @@ -1,17 +1,23 @@ package io.dataease.chart.manage; +import io.dataease.api.chart.request.ThresholdCheckRequest; +import io.dataease.api.chart.vo.ThresholdCheckVO; import io.dataease.dataset.manage.DatasetTableFieldManage; +import io.dataease.engine.constant.DeTypeConstants; import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO; +import io.dataease.extensions.view.dto.ChartViewDTO; import io.dataease.extensions.view.filter.FilterTreeItem; import io.dataease.extensions.view.filter.FilterTreeObj; import io.dataease.utils.JsonUtil; import jakarta.annotation.Resource; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; @Component("chartViewThresholdManage") @@ -20,6 +26,9 @@ public class ChartViewThresholdManage { @Resource private DatasetTableFieldManage datasetTableFieldManage; + @Resource + private ChartViewManege chartViewManege; + public String convertThresholdRules(Long tableId, String thresholdRules) { List fieldList = datasetTableFieldManage.selectByDatasetGroupId(tableId); FilterTreeObj filterTreeObj = JsonUtil.parseObject(thresholdRules, FilterTreeObj.class); @@ -60,7 +69,7 @@ public class ChartViewThresholdManage { if (StringUtils.equals(filterType, "enum")) { List enumValue = item.getEnumValue(); String enumValueText = String.join(",", enumValue); - return fieldName + " 包括 " + "( " + enumValueText + " )"; + return fieldName + " 属于 " + "( " + enumValueText + " )"; } else { return fieldName + " " + translateTerm(item.getTerm()) + " " + item.getValue(); } @@ -74,8 +83,8 @@ public class ChartViewThresholdManage { case "le" -> "小于等于"; case "gt" -> "大于"; case "ge" -> "大于等于"; - case "in" -> "包括"; - case "not in" -> "不包括"; + case "in" -> "属于"; + case "not in" -> "不属于"; case "like" -> "包含"; case "not like" -> "不包含"; case "null" -> "为空"; @@ -91,4 +100,150 @@ public class ChartViewThresholdManage { if (StringUtils.equals(logic, "and")) return " 且 "; return " 或 "; } + + + public ThresholdCheckVO checkThreshold(ThresholdCheckRequest request) throws Exception { + String thresholdTemplate = request.getThresholdTemplate(); + String thresholdRules = request.getThresholdRules(); + Long chartId = request.getChartId(); + ChartViewDTO chart = chartViewManege.getChart(chartId); + Map data = chart.getData(); + List> tableRow = (List>) data.get("tableRow"); + List fields = (List) data.get("fields"); + Map fieldMap = fields.stream().collect(Collectors.toMap(DatasetTableFieldDTO::getId, item -> item)); + FilterTreeObj filterTreeObj = JsonUtil.parseObject(thresholdRules, FilterTreeObj.class); + List> rows = filterRows(tableRow, filterTreeObj, fieldMap); + if (CollectionUtils.isEmpty(rows)) { + return new ThresholdCheckVO(false, null, null, null); + } + String regex = "]*id=\"changeText-(\\d+)(?!0$)(?!1$)\"[^>]*>.*?"; + Pattern pattern = Pattern.compile(regex, Pattern.DOTALL); + Matcher matcher = pattern.matcher(thresholdTemplate); + StringBuilder sb = new StringBuilder(); + while (matcher.find()) { + long id = Long.parseLong(matcher.group(1)); + // 根据id从map中获取替换文本 + DatasetTableFieldDTO fieldDTO = fieldMap.get(id); + String fieldDTOName = fieldDTO.getName(); + String dataeaseName = fieldDTO.getDataeaseName(); + List valueList = rows.stream().map(row -> row.get(dataeaseName).toString()).collect(Collectors.toList()); + String replacement = fieldDTOName + ": " + JsonUtil.toJSONString(valueList); + // 替换文本 + matcher.appendReplacement(sb, replacement); + } + matcher.appendTail(sb); + + // 输出替换后的HTML内容 + String result = sb.toString(); + return new ThresholdCheckVO(true, result, null, null); + } + + public List> filterRows(List> rows, FilterTreeObj conditionTree, Map fieldMap) { + List> filteredRows = new ArrayList<>(); + for (Map row : rows) { + if (matchesConditionTree(row, conditionTree, fieldMap)) { + filteredRows.add(row); + } + } + return filteredRows; + } + + private boolean matchesConditionTree(Map row, FilterTreeObj conditionTree, Map fieldMap) { + if (conditionTree == null || conditionTree.getItems().isEmpty()) { + return true; // 如果没有条件树或条件列表为空,返回所有行 + } + List items = conditionTree.getItems(); + if (conditionTree.getLogic().equals("or")) { + return matchesAnyItem(row, items, fieldMap); + } + return matchesAllItems(row, items, fieldMap); + } + + private boolean matchesAllItems(Map row, List items, Map fieldMap) { + for (FilterTreeItem item : items) { + if (!matchesConditionItem(row, item, fieldMap)) { + return false; + } + } + return true; + } + + private boolean matchesAnyItem(Map row, List items, Map fieldMap) { + for (FilterTreeItem item : items) { + if (matchesConditionItem(row, item, fieldMap)) { + return true; + } + } + return false; + } + + private boolean matchesConditionItem(Map row, FilterTreeItem item, Map fieldMap) { + if ("item".equals(item.getType())) { + DatasetTableFieldDTO fieldDTO = fieldMap.get(item.getFieldId()); + return rowMatch(row, item, fieldDTO); + } else if ("tree".equals(item.getType()) && item.getSubTree() != null) { + return matchesConditionTree(row, item.getSubTree(), fieldMap); + } + return false; // 如果类型不匹配或没有子树,不匹配 + } + + private boolean rowMatch(Map row, FilterTreeItem item, DatasetTableFieldDTO fieldDTO) { + String dataeaseName = fieldDTO.getDataeaseName(); + String filterType = item.getFilterType(); + Integer deType = fieldDTO.getDeType(); + Object valueObj = row.get(dataeaseName); + if (StringUtils.equals(filterType, "enum")) { + List enumValue = item.getEnumValue(); + return ObjectUtils.isNotEmpty(valueObj) && enumValue.contains(valueObj); + } else { + String term = item.getTerm(); + if (Objects.equals(deType, DeTypeConstants.DE_STRING)) { + if (StringUtils.equals(term, "eq")) { + return StringUtils.equals(item.getValue(), valueObj.toString()); + } else if (StringUtils.equals(term, "not_eq")) { + return !StringUtils.equals(item.getValue(), valueObj.toString()); + } else if (StringUtils.equals(term, "in")) { + return Arrays.stream(item.getValue().split(",")).toList().contains(valueObj.toString()); + } else if (StringUtils.equals(term, "not_in")) { + return !Arrays.stream(item.getValue().split(",")).toList().contains(valueObj.toString()); + } else if (StringUtils.equals(term, "like")) { + return StringUtils.contains(item.getValue(), valueObj.toString()); + } else if (StringUtils.equals(term, "not_like")) { + return !StringUtils.contains(item.getValue(), valueObj.toString()); + } else if (StringUtils.equals(term, "null")) { + return valueObj == null; + } else if (StringUtils.equals(term, "not_null")) { + return valueObj != null; + } else if (StringUtils.equals(term, "empty")) { + return StringUtils.isBlank(valueObj.toString()); + } else if (StringUtils.equals(term, "not_empty")) { + return !StringUtils.isBlank(valueObj.toString()); + } else { + return StringUtils.equals(item.getValue(), valueObj.toString()); + } + } else if (Objects.equals(deType, DeTypeConstants.DE_INT) || Objects.equals(deType, DeTypeConstants.DE_FLOAT)) { + if (StringUtils.equals(term, "eq")) { + return StringUtils.equals(item.getValue().toString(), valueObj.toString()); + } else if (StringUtils.equals(term, "not_eq")) { + return !StringUtils.equals(item.getValue().toString(), valueObj.toString()); + } else if (StringUtils.equals(term, "gt")) { + return Float.parseFloat(item.getValue().toString()) < Float.parseFloat(valueObj.toString()); + } else if (StringUtils.equals(term, "ge")) { + return Float.parseFloat(item.getValue().toString()) <= Float.parseFloat(valueObj.toString()); + } else if (StringUtils.equals(term, "lt")) { + return Float.parseFloat(item.getValue().toString()) > Float.parseFloat(valueObj.toString()); + } else if (StringUtils.equals(term, "le")) { + return Float.parseFloat(item.getValue().toString()) >= Float.parseFloat(valueObj.toString()); + } else { + return StringUtils.equals(item.getValue().toString(), valueObj.toString()); + } + } else if (Objects.equals(deType, DeTypeConstants.DE_TIME)) { + // 补充时间逻辑 + return true; + } else { + return true; + } + } + } + } diff --git a/de-xpack b/de-xpack index 7d33cdfc9c..d321778819 160000 --- a/de-xpack +++ b/de-xpack @@ -1 +1 @@ -Subproject commit 7d33cdfc9cc735685e430cc5685c21608c589218 +Subproject commit d321778819aefea132bfc13633684d4011b11f90 diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/chart/request/ThresholdCheckRequest.java b/sdk/api/api-base/src/main/java/io/dataease/api/chart/request/ThresholdCheckRequest.java new file mode 100644 index 0000000000..cbc9a4f5ac --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/chart/request/ThresholdCheckRequest.java @@ -0,0 +1,18 @@ +package io.dataease.api.chart.request; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +@Data +public class ThresholdCheckRequest implements Serializable { + @Serial + private static final long serialVersionUID = -8377694080272137660L; + + private Long chartId; + + private String thresholdRules; + + private String thresholdTemplate; +} diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/chart/vo/ThresholdCheckVO.java b/sdk/api/api-base/src/main/java/io/dataease/api/chart/vo/ThresholdCheckVO.java new file mode 100644 index 0000000000..4ebe994dd3 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/chart/vo/ThresholdCheckVO.java @@ -0,0 +1,24 @@ +package io.dataease.api.chart.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serial; +import java.io.Serializable; + +@AllArgsConstructor +@NoArgsConstructor +@Data +public class ThresholdCheckVO implements Serializable { + @Serial + private static final long serialVersionUID = 2782520137890522432L; + + private boolean valid; + + private String content; + + private String msg; + + private Long taskId; +}