diff --git a/backend/src/main/java/io/dataease/dto/chart/FilterParamTO.java b/backend/src/main/java/io/dataease/dto/chart/FilterParamTO.java new file mode 100644 index 0000000000..828e2fd445 --- /dev/null +++ b/backend/src/main/java/io/dataease/dto/chart/FilterParamTO.java @@ -0,0 +1,18 @@ +package io.dataease.dto.chart; + +import lombok.Data; + +import java.util.List; +import java.util.Map; + +@Data +public class FilterParamTO { + + private Map component; + + private List value; + + private String operator; + + private Boolean isTree = false; +} diff --git a/backend/src/main/java/io/dataease/service/chart/FilterBuildTemplate.java b/backend/src/main/java/io/dataease/service/chart/FilterBuildTemplate.java new file mode 100644 index 0000000000..a162996fb5 --- /dev/null +++ b/backend/src/main/java/io/dataease/service/chart/FilterBuildTemplate.java @@ -0,0 +1,187 @@ +package io.dataease.service.chart; + +import io.dataease.commons.utils.CommonBeanFactory; +import io.dataease.dto.chart.FilterParamTO; +import io.dataease.plugins.common.request.chart.ChartExtFilterRequest; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.*; +import java.util.stream.Collectors; + +public abstract class FilterBuildTemplate { + + protected abstract FilterParamTO buildParam(Map component); + + public Map> buildFilters(List> components) { + Map searchButton = components.stream().filter(item -> { + if (ObjectUtils.isEmpty(item.get("type"))) return false; + if (ObjectUtils.isEmpty(item.get("serviceName"))) return false; + return StringUtils.equals("custom-button", item.get("type").toString()) && StringUtils.equals("buttonSureWidget", item.get("serviceName").toString()); + }).findFirst().orElseGet(null); + + List> filters = componentsFilter(components, "custom", null, null); + + if(ObjectUtils.isNotEmpty(searchButton)) { + Map options = (Map) searchButton.get("options"); + Map attrs = (Map) options.get("attrs"); + Boolean customRange = (Boolean)attrs.get("customRange"); + Boolean autoTrigger = (Boolean) attrs.get("autoTrigger"); + List filterIds = (List) attrs.get("filterIds"); + if (!autoTrigger) { // 不是自动触发 // 需要过滤掉按钮关联的条件组件 + if (customRange) { // 自定义控制范围 //过滤掉被按钮关联的 + filters = filters.stream().filter(filter -> !filterIds.contains(filter.get("id"))).collect(Collectors.toList()); + } else { // 按钮控制所有 // 过滤掉所有条件 + filters = new ArrayList<>(); + } + } + } + + Map> emptyResult = buildEmpty(components); + + emptyResult = fillFilters(emptyResult, filters); + + return emptyResult; + } + + private Map> fillFilters(Map> emptyResult, List> filters) { + filters.forEach(element -> { + FilterParamTO filterParamTO = buildParam(element); + ChartExtFilterRequest condition = formatCondition(filterParamTO); + Boolean vValid = valueValid(condition); + String filterComponentId = condition.getComponentId(); + emptyResult.entrySet().forEach(entry -> { + String viewId = entry.getKey(); + boolean vidMatch = viewIdMatch(condition.getViewIds(), viewId); + List viewFilters = emptyResult.get(viewId); + int j = viewFilters.size(); + while (j-- > 0) { + ChartExtFilterRequest filter = viewFilters.get(j); + if (StringUtils.equals(filter.getComponentId(), filterComponentId)) { + viewFilters.remove(j); + } + } + if (vidMatch && vValid) { + viewFilters.add(condition); + } + }); + }); + + return emptyResult; + } + + private Boolean valueValid(ChartExtFilterRequest condition) { + return ObjectUtils.isNotEmpty(condition) && CollectionUtils.isNotEmpty(condition.getValue()) && StringUtils.isNotBlank(condition.getValue().get(0)); + } + + private Boolean viewIdMatch(List viewIds, String viewId) { + return CollectionUtils.isEmpty(viewIds) || viewIds.contains(viewId); + } + + private ChartExtFilterRequest formatCondition(FilterParamTO filterParamTO) { + + Boolean isTree = filterParamTO.getIsTree(); + List value = filterParamTO.getValue(); + Map component = filterParamTO.getComponent(); + Map attrs = (Map) ((Map) component.get("options")).get("attrs"); + String fieldId = attrs.get("fieldId").toString(); + List viewIds = (List)attrs.get("viewIds"); + List parameters = (List) attrs.get("parameters"); + Boolean multiple = ObjectUtils.isNotEmpty(attrs.get("multiple")) && (Boolean) attrs.get("multiple"); + if (isTree && !multiple && CollectionUtils.isNotEmpty(value)) { + // 单选树 + String val = value.get(0); + if (StringUtils.isNotBlank(val)) { + int len = val.split(",").length; + if (len > 0) { + List fieldIdList = Arrays.asList(fieldId.split(",")); + fieldId = fieldIdList.stream().limit(len).collect(Collectors.joining(",")); + } + } + } + ChartExtFilterRequest condition = new ChartExtFilterRequest(); + condition.setComponentId(component.get("id").toString()); + condition.setFieldId(fieldId); + condition.setValue(value); + condition.setOperator(filterParamTO.getOperator()); + condition.setViewIds(viewIds); + condition.setParameters(parameters); + condition.setIsTree(isTree); + return condition; + } + + private Map> buildEmpty(List> components) { + Map> result = new HashMap<>(); + components.forEach(element -> { + if (StringUtils.equals(element.get("type").toString(), "'view'")) { + String viewId = ((Map) element.get("propValue")).get("viewId").toString(); + result.put(viewId, new ArrayList<>()); + } + if (StringUtils.equals(element.get("type").toString(), "'de-tabs'")) { + List> tabs = (List>) ((Map) element.get("options")).get("tabList"); + if (CollectionUtils.isNotEmpty(tabs)) { + tabs.forEach(tab -> { + Object contentObj = null; + if ((contentObj = tab.get("content")) != null) { + Map content = (Map) contentObj; + Object propObj = null; + if ((propObj = content.get("propValue")) != null) { + Map prop = (Map) propObj; + String viewId = prop.get("viewId"); + if (StringUtils.isNotBlank(viewId)) { + result.put(viewId, new ArrayList<>()); + } + } + } + + }); + } + + + } + }); + return result; + } + + public static List> componentsFilter(List> components, String type, + String componentType, String serviceName) { + return components.stream().filter(component -> { + String ctype = Optional.ofNullable(component.get("type")).orElse("").toString(); + String cComponentType = Optional.ofNullable(component.get("component")).orElse("").toString(); + String cServiceName = Optional.ofNullable(component.get("serviceName")).orElse("").toString(); + + boolean typeMatch = true; + boolean componentTypeMatch = true; + boolean serviceNameMatch = true; + + if (StringUtils.isNotBlank(type)) { + typeMatch = StringUtils.equals(type, ctype); + } + + if (StringUtils.isNotBlank(componentType)) { + componentTypeMatch = StringUtils.equals(componentType, cComponentType); + } + + if (StringUtils.isNotBlank(serviceName)) { + serviceNameMatch = StringUtils.equals(serviceName, cServiceName); + } + + return typeMatch && componentTypeMatch && serviceNameMatch; + + }).collect(Collectors.toList()); + + } + + public static FilterBuildTemplate getInstance(String serviceName) { + Map beanMapping = new HashMap<>(); + beanMapping.put("numberRangeWidget", "numberRangeWidget"); + beanMapping.put("textSelectTreeWidget", "textSelectTreeWidget"); + beanMapping.put("textInputWidget", "textInputWidget"); + String beanName = beanMapping.get(serviceName); + if (StringUtils.isBlank(beanName) && StringUtils.contains(serviceName, "select")) { + beanName = "selectWidget"; + } + return (FilterBuildTemplate)CommonBeanFactory.getBean(beanName); + } +} diff --git a/backend/src/main/java/io/dataease/service/chart/ViewExportExcel.java b/backend/src/main/java/io/dataease/service/chart/ViewExportExcel.java index 3c8788bafe..67f830aee8 100644 --- a/backend/src/main/java/io/dataease/service/chart/ViewExportExcel.java +++ b/backend/src/main/java/io/dataease/service/chart/ViewExportExcel.java @@ -44,7 +44,7 @@ public class ViewExportExcel { PanelGroupDTO panelDto = panelGroupService.findOne(panelId); String componentsJson = panelDto.getPanelData(); List> components = gson.fromJson(componentsJson, tokenType); - ChartExtRequest chartExtRequest = buildViewRequest(componentsFilter(components, "custom", null, null)); + ChartExtRequest chartExtRequest = buildViewRequest(FilterBuildTemplate.componentsFilter(components, "custom", null, null)); List results = new ArrayList<>(); List sheets = viewIds.stream().map(viewId -> viewFiles(viewId, chartExtRequest)).collect(Collectors.toList()); File excelFile = ExcelUtils.exportExcel(sheets, panelDto.getName()); @@ -52,34 +52,7 @@ public class ViewExportExcel { return results; } - private List> componentsFilter(List> components, String type, - String componentType, String serviceName) { - return components.stream().filter(component -> { - String ctype = Optional.ofNullable(component.get("type")).orElse("").toString(); - String cComponentType = Optional.ofNullable(component.get("component")).orElse("").toString(); - String cServiceName = Optional.ofNullable(component.get("serviceName")).orElse("").toString(); - boolean typeMatch = true; - boolean componentTypeMatch = true; - boolean serviceNameMatch = true; - - if (StringUtils.isNotBlank(type)) { - typeMatch = StringUtils.equals(type, ctype); - } - - if (StringUtils.isNotBlank(componentType)) { - componentTypeMatch = StringUtils.equals(componentType, cComponentType); - } - - if (StringUtils.isNotBlank(serviceName)) { - serviceNameMatch = StringUtils.equals(serviceName, cServiceName); - } - - return typeMatch && componentTypeMatch && serviceNameMatch; - - }).collect(Collectors.toList()); - - } private ChartExtRequest buildViewRequest(List> filters) { ChartExtRequest chartExtRequest = new ChartExtRequest(); @@ -95,6 +68,11 @@ public class ViewExportExcel { return chartExtRequest; } + private List initFilters(List> components) { + + return null; + } + private ExcelSheetModel viewFiles(String viewId, ChartExtRequest request) { ExcelSheetModel result = new ExcelSheetModel(); ChartViewDTO chartViewDTO = null; diff --git a/backend/src/main/java/io/dataease/service/chart/build/NumberRangeBuild.java b/backend/src/main/java/io/dataease/service/chart/build/NumberRangeBuild.java new file mode 100644 index 0000000000..42ea023770 --- /dev/null +++ b/backend/src/main/java/io/dataease/service/chart/build/NumberRangeBuild.java @@ -0,0 +1,65 @@ +package io.dataease.service.chart.build; + +import cn.hutool.core.collection.CollectionUtil; +import io.dataease.dto.chart.FilterParamTO; +import io.dataease.service.chart.FilterBuildTemplate; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Service("numberRangeWidget") +public class NumberRangeBuild extends FilterBuildTemplate { + + @Override + protected FilterParamTO buildParam(Map component) { + FilterParamTO result = new FilterParamTO(); + result.setComponent(component); + result.setValue(null); + result.setOperator("eq"); + Object optionObj = null; + Object valueObj = null; + + Map options = null; + List values = null; + if((optionObj = component.get("options")) != null && (valueObj = (options = (Map) optionObj).get("value")) != null && CollectionUtil.isNotEmpty((values = (List) valueObj))) { + String min = values.get(0); + String max = null; + + if(values.size() > 1) { + max = values.get(1); + } + result.setOperator("between"); + result.getValue().set(0, min); + result.getValue().set(1, max); + + if (StringUtils.isNotBlank(min) && StringUtils.isNotBlank(max)) { + return result; + } + + if (StringUtils.isBlank(min) && StringUtils.isBlank(max)) { + result.setValue(null); + return result; + } + + if (StringUtils.isNotBlank(min)) { + List tempValues = new ArrayList<>(); + tempValues.add(min); + result.setValue(tempValues); + result.setOperator("ge"); + return result; + } + + if (StringUtils.isNotBlank(max)) { + List tempValues = new ArrayList<>(); + tempValues.add(max); + result.setValue(tempValues); + result.setOperator("le"); + return result; + } + } + return result; + } +} diff --git a/backend/src/main/java/io/dataease/service/chart/build/SelectBuild.java b/backend/src/main/java/io/dataease/service/chart/build/SelectBuild.java new file mode 100644 index 0000000000..5a55d50488 --- /dev/null +++ b/backend/src/main/java/io/dataease/service/chart/build/SelectBuild.java @@ -0,0 +1,57 @@ +package io.dataease.service.chart.build; + +import io.dataease.dto.chart.FilterParamTO; +import io.dataease.service.chart.FilterBuildTemplate; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service("selectWidget") +public class SelectBuild extends FilterBuildTemplate { + @Override + protected FilterParamTO buildParam(Map component) { + FilterParamTO result = new FilterParamTO(); + result.setComponent(component); + result.setValue(null); + result.setOperator("eq"); + Object valueObj = null; + + List realValues = null; + if(ObjectUtils.isEmpty(component.get("options"))) return result; + Map options = (Map)component.get("options"); + + valueObj = options.get("value"); + String defaultValue = ""; + Map attrs = (Map) options.get("attrs"); + boolean multiple = (boolean) attrs.get("multiple"); + if(!ObjectUtils.isEmpty(valueObj)) { + if(valueObj instanceof List) { + defaultValue = ""; + }else { + defaultValue = valueObj.toString(); + } + } + if(multiple) { + if (StringUtils.isBlank(defaultValue)) { + realValues = new ArrayList<>(); + }else { + realValues = Arrays.asList(defaultValue.split(",")); + } + } else { + if (StringUtils.isBlank(defaultValue)) { + realValues = new ArrayList<>(); + }else { + realValues = Arrays.asList(defaultValue.split(",")).stream().limit(1).collect(Collectors.toList()); + } + } + result.setOperator(multiple ? "in" : "eq"); + result.setValue(realValues); + return result; + } +} diff --git a/backend/src/main/java/io/dataease/service/chart/build/SelectTreeBuild.java b/backend/src/main/java/io/dataease/service/chart/build/SelectTreeBuild.java new file mode 100644 index 0000000000..c906191799 --- /dev/null +++ b/backend/src/main/java/io/dataease/service/chart/build/SelectTreeBuild.java @@ -0,0 +1,63 @@ +package io.dataease.service.chart.build; + +import io.dataease.dto.chart.FilterParamTO; +import io.dataease.service.chart.FilterBuildTemplate; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service("textSelectTreeWidget") +public class SelectTreeBuild extends FilterBuildTemplate { + @Override + protected FilterParamTO buildParam(Map component) { + FilterParamTO result = new FilterParamTO(); + result.setComponent(component); + result.setValue(null); + result.setOperator("eq"); + result.setIsTree(true); + Object valueObj = null; + + List realValues = null; + if(ObjectUtils.isEmpty(component.get("options"))) return result; + Map options = (Map)component.get("options"); + + valueObj = options.get("value"); + String defaultValue = ""; + Map attrs = (Map) options.get("attrs"); + boolean multiple = (boolean) attrs.get("multiple"); + if(!ObjectUtils.isEmpty(valueObj)) { + if(valueObj instanceof List) { + defaultValue = ""; + }else { + defaultValue = valueObj.toString(); + } + } + if(multiple) { + if (StringUtils.isBlank(defaultValue)) { + realValues = new ArrayList<>(); + }else { + realValues = Arrays.asList(defaultValue.split(",")); + } + } else { + if (StringUtils.isBlank(defaultValue)) { + realValues = new ArrayList<>(); + }else { + realValues = Arrays.asList(defaultValue.split(",")).stream().limit(1).collect(Collectors.toList()); + } + } + result.setOperator(multiple ? "in" : "eq"); + result.setValue(realValues); + + if (CollectionUtils.isNotEmpty(result.getValue())) { + result.setValue(result.getValue().stream().map(val -> val.replaceAll("-de-", ",")).collect(Collectors.toList())); + } + return result; + } +} diff --git a/backend/src/main/java/io/dataease/service/chart/build/TextInputBuild.java b/backend/src/main/java/io/dataease/service/chart/build/TextInputBuild.java new file mode 100644 index 0000000000..b8fd6d7478 --- /dev/null +++ b/backend/src/main/java/io/dataease/service/chart/build/TextInputBuild.java @@ -0,0 +1,47 @@ +package io.dataease.service.chart.build; + +import io.dataease.dto.chart.FilterParamTO; +import io.dataease.service.chart.FilterBuildTemplate; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service("textInputWidget") +public class TextInputBuild extends FilterBuildTemplate { + @Override + protected FilterParamTO buildParam(Map component) { + FilterParamTO result = new FilterParamTO(); + result.setComponent(component); + result.setValue(null); + result.setOperator("like"); + Object valueObj = null; + + List realValues = null; + if(ObjectUtils.isEmpty(component.get("options"))) return result; + Map options = (Map)component.get("options"); + + valueObj = options.get("value"); + String defaultValue = ""; + Map attrs = (Map) options.get("attrs"); + if(!ObjectUtils.isEmpty(valueObj)) { + if(valueObj instanceof List) { + defaultValue = ""; + }else { + defaultValue = valueObj.toString(); + } + } + if (StringUtils.isBlank(defaultValue)) { + realValues = new ArrayList<>(); + }else { + realValues = Arrays.asList(defaultValue.split(",")).stream().limit(1).collect(Collectors.toList()); + } + result.setValue(realValues); + return result; + } +} diff --git a/backend/src/main/java/io/dataease/service/chart/build/TimeYearBuild.java b/backend/src/main/java/io/dataease/service/chart/build/TimeYearBuild.java new file mode 100644 index 0000000000..76581fe6d1 --- /dev/null +++ b/backend/src/main/java/io/dataease/service/chart/build/TimeYearBuild.java @@ -0,0 +1,73 @@ +package io.dataease.service.chart.build; + +import io.dataease.dto.chart.FilterParamTO; +import io.dataease.service.chart.FilterBuildTemplate; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + + +public class TimeYearBuild extends FilterBuildTemplate { + @Override + protected FilterParamTO buildParam(Map component) { + List realVals = null; + Object valueObj = null; + String defaultValue = ""; + Map options = (Map) component.get("options"); + Map attrs = (Map) options.get("attrs"); + Object aDefault = attrs.get("default"); + Boolean isDynamic = (Boolean) attrs.getOrDefault("isDynamic", false); + if (ObjectUtils.isNotEmpty(aDefault) && isDynamic) { + Long aLong = dynamicDateFormNow(component); + realVals = new ArrayList<>(); + realVals.add(aLong.toString()); + }else { + if(!ObjectUtils.isEmpty(valueObj)) { + if(valueObj instanceof List) { + defaultValue = ""; + }else { + defaultValue = valueObj.toString(); + } + } + if (StringUtils.isBlank(defaultValue)) { + realVals = new ArrayList<>(); + }else { + realVals = Arrays.asList(defaultValue.split(",")).stream().limit(1).collect(Collectors.toList()); + } + } + + + + return null; + } + + + private Long dynamicDateFormNow(Map component) { + Map attrs = (Map) ((Map) component.get("options")).get("attrs"); + Object aDefault = attrs.get("default"); + Boolean isDynamic = (Boolean) attrs.getOrDefault("isDynamic", false); + if (ObjectUtils.isEmpty(aDefault) || !isDynamic) return null; + + Calendar now = Calendar.getInstance(); + int nowYear = now.get(Calendar.YEAR); + Map aDefaultMap = (Map) aDefault; + if (Integer.parseInt(aDefaultMap.get("dkey").toString()) == 0){ + now.set(nowYear, 0, 1, 0, 0, 0); + return now.getTimeInMillis(); + } + if (Integer.parseInt(aDefaultMap.get("dkey").toString()) == 1){ + now.set(nowYear - 1, 0, 1, 0, 0, 0); + return now.getTimeInMillis(); + } + if (Integer.parseInt(aDefaultMap.get("dkey").toString()) == 2){ + int dynamicPrefix = Integer.parseInt(aDefaultMap.get("dynamicPrefix").toString()); + String dynamicSuffix = aDefaultMap.get("dynamicSuffix").toString(); + now.set(StringUtils.equals("before", dynamicSuffix) ? (nowYear - dynamicPrefix) : (nowYear + dynamicPrefix), 0, 1, 0, 0, 0); + return now.getTimeInMillis(); + } + return 0L; + } +}