feat(图表): 过滤器支持动态时间

This commit is contained in:
junjun 2024-08-07 10:35:54 +08:00
parent aeaf6290be
commit 1a0c1ac2b5
7 changed files with 240 additions and 9 deletions

View File

@ -2,15 +2,16 @@ package io.dataease.chart.manage;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import io.dataease.chart.dao.auto.entity.CoreChartView;
import io.dataease.chart.dao.auto.mapper.CoreChartViewMapper;
import io.dataease.extensions.view.dto.ChartCustomFilterItemDTO; import io.dataease.extensions.view.dto.ChartCustomFilterItemDTO;
import io.dataease.extensions.view.dto.ChartFieldCustomFilterDTO; import io.dataease.extensions.view.dto.ChartFieldCustomFilterDTO;
import io.dataease.extensions.view.filter.FilterTreeItem; import io.dataease.extensions.view.filter.FilterTreeItem;
import io.dataease.extensions.view.filter.FilterTreeObj; import io.dataease.extensions.view.filter.FilterTreeObj;
import io.dataease.chart.dao.auto.entity.CoreChartView;
import io.dataease.chart.dao.auto.mapper.CoreChartViewMapper;
import io.dataease.utils.JsonUtil; import io.dataease.utils.JsonUtil;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -147,4 +148,58 @@ public class ChartViewOldDataMergeService {
} }
return tree; return tree;
} }
/**
* 视图过滤器动态时间兼容老数据
*/
public void refreshFilter() {
// 获取所有视图数据
// 在filter中增加filterTypeTime = dateValue
List<CoreChartView> chartViewWithBLOBs = coreChartViewMapper.selectList(new QueryWrapper<>());
if (CollectionUtils.isEmpty(chartViewWithBLOBs)) {
return;
}
for (CoreChartView view : chartViewWithBLOBs) {
FilterTreeObj filterTreeObj;
try {
filterTreeObj = JsonUtil.parseObject(view.getCustomFilter(), FilterTreeObj.class);
} catch (Exception e) {
continue;
}
if (ObjectUtils.isNotEmpty(filterTreeObj)) {
if (ObjectUtils.isEmpty(filterTreeObj.getItems())) {
continue;
}
FilterTreeObj tree = fixFilter(filterTreeObj);
view.setCustomFilter((String) JsonUtil.toJSONString(tree));
}
try {
coreChartViewMapper.updateById(view);
} catch (Exception e) {
// do nothing,to continue
e.printStackTrace();
}
}
}
public FilterTreeObj fixFilter(FilterTreeObj filterTreeObj) {
doFix(filterTreeObj.getItems());
return filterTreeObj;
}
public void doFix(List<FilterTreeItem> items) {
if (ObjectUtils.isEmpty(items)) {
return;
}
for (FilterTreeItem item : items) {
if (StringUtils.equalsIgnoreCase(item.getType(), "item")) {
item.setFilterTypeTime("dateValue");
} else {
doFix(item.getSubTree().getItems());
}
}
}
} }

View File

@ -1,22 +1,20 @@
package io.dataease.engine.trans; package io.dataease.engine.trans;
import io.dataease.engine.constant.SQLConstants;
import io.dataease.engine.utils.Utils;
import io.dataease.extensions.datasource.constant.SqlPlaceholderConstants; import io.dataease.extensions.datasource.constant.SqlPlaceholderConstants;
import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO;
import io.dataease.extensions.datasource.dto.DatasourceSchemaDTO; import io.dataease.extensions.datasource.dto.DatasourceSchemaDTO;
import io.dataease.extensions.datasource.model.SQLMeta; import io.dataease.extensions.datasource.model.SQLMeta;
import io.dataease.extensions.datasource.model.SQLObj; import io.dataease.extensions.datasource.model.SQLObj;
import io.dataease.extensions.view.filter.DynamicTimeSetting;
import io.dataease.extensions.view.filter.FilterTreeItem; import io.dataease.extensions.view.filter.FilterTreeItem;
import io.dataease.extensions.view.filter.FilterTreeObj; import io.dataease.extensions.view.filter.FilterTreeObj;
import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO;
import io.dataease.engine.constant.SQLConstants;
import io.dataease.engine.utils.Utils;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* @Author Junjun * @Author Junjun
@ -153,6 +151,8 @@ public class CustomWhere2Str {
} else { } else {
// 如果是时间字段过滤当条件是等于和不等于的时候转换成between和not between // 如果是时间字段过滤当条件是等于和不等于的时候转换成between和not between
if (field.getDeType() == 1) { if (field.getDeType() == 1) {
// 如果是动态时间计算具体值
value = fixValue(item);
if (StringUtils.equalsIgnoreCase(whereTerm, " = ")) { if (StringUtils.equalsIgnoreCase(whereTerm, " = ")) {
whereTerm = " BETWEEN "; whereTerm = " BETWEEN ";
// 把value类似过滤组件处理获得start time和end time // 把value类似过滤组件处理获得start time和end time
@ -178,4 +178,109 @@ public class CustomWhere2Str {
} }
return res; return res;
} }
private static String fixValue(FilterTreeItem item) {
if (StringUtils.isNotEmpty(item.getFilterTypeTime()) && StringUtils.equalsIgnoreCase(item.getFilterTypeTime(), "dynamicDate")) {
DynamicTimeSetting dynamicTimeSetting = item.getDynamicTimeSetting();
Calendar instance = Calendar.getInstance();
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getTimeGranularity(), "year")) {
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "thisYear")) {
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "lastYear")) {
instance.add(Calendar.YEAR, -1);
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "custom")) {
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getAround(), "f")) {
instance.add(Calendar.YEAR, -dynamicTimeSetting.getTimeNum());
} else {
instance.add(Calendar.YEAR, dynamicTimeSetting.getTimeNum());
}
}
return "" + instance.get(Calendar.YEAR);
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getTimeGranularity(), "month")) {
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "thisMonth")) {
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "lastMonth")) {
instance.add(Calendar.MONTH, -1);
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "custom")) {
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrentType(), "year")) {
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getAround(), "f")) {
instance.add(Calendar.YEAR, -dynamicTimeSetting.getTimeNum());
} else {
instance.add(Calendar.YEAR, dynamicTimeSetting.getTimeNum());
}
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrentType(), "month")) {
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getAround(), "f")) {
instance.add(Calendar.MONTH, -dynamicTimeSetting.getTimeNum());
} else {
instance.add(Calendar.MONTH, dynamicTimeSetting.getTimeNum());
}
}
}
return instance.get(Calendar.YEAR) + "-" + (instance.get(Calendar.MONTH) + 1 < 10 ? "0" : "") + (instance.get(Calendar.MONTH) + 1);
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getTimeGranularity(), "date")) {
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "today")) {
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "yesterday")) {
instance.add(Calendar.DAY_OF_MONTH, -1);
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "monthBeginning")) {
instance.set(Calendar.DAY_OF_MONTH, 1);
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "yearBeginning")) {
instance.set(Calendar.MONTH, 0);
instance.set(Calendar.DAY_OF_MONTH, 1);
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "custom")) {
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrentType(), "year")) {
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getAround(), "f")) {
instance.add(Calendar.YEAR, -dynamicTimeSetting.getTimeNum());
} else {
instance.add(Calendar.YEAR, dynamicTimeSetting.getTimeNum());
}
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrentType(), "month")) {
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getAround(), "f")) {
instance.add(Calendar.MONTH, -dynamicTimeSetting.getTimeNum());
} else {
instance.add(Calendar.MONTH, dynamicTimeSetting.getTimeNum());
}
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrentType(), "date")) {
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getAround(), "f")) {
instance.add(Calendar.DAY_OF_MONTH, -dynamicTimeSetting.getTimeNum());
} else {
instance.add(Calendar.DAY_OF_MONTH, dynamicTimeSetting.getTimeNum());
}
}
}
return instance.get(Calendar.YEAR) + "-" + (instance.get(Calendar.MONTH) + 1 < 10 ? "0" : "") + (instance.get(Calendar.MONTH) + 1) + "-" + (instance.get(Calendar.DAY_OF_MONTH) < 10 ? "0" : "") + instance.get(Calendar.DAY_OF_MONTH);
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getTimeGranularity(), "datetime")) {
String time = " 00:00:00";
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "today")) {
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "yesterday")) {
instance.add(Calendar.DAY_OF_MONTH, -1);
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "monthBeginning")) {
instance.set(Calendar.DAY_OF_MONTH, 1);
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "yearBeginning")) {
instance.set(Calendar.MONTH, 0);
instance.set(Calendar.DAY_OF_MONTH, 1);
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrent(), "custom")) {
time = " " + dynamicTimeSetting.getArbitraryTime().substring(11, 19);
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrentType(), "year")) {
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getAround(), "f")) {
instance.add(Calendar.YEAR, -dynamicTimeSetting.getTimeNum());
} else {
instance.add(Calendar.YEAR, dynamicTimeSetting.getTimeNum());
}
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrentType(), "month")) {
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getAround(), "f")) {
instance.add(Calendar.MONTH, -dynamicTimeSetting.getTimeNum());
} else {
instance.add(Calendar.MONTH, dynamicTimeSetting.getTimeNum());
}
} else if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getRelativeToCurrentType(), "date")) {
if (StringUtils.equalsIgnoreCase(dynamicTimeSetting.getAround(), "f")) {
instance.add(Calendar.DAY_OF_MONTH, -dynamicTimeSetting.getTimeNum());
} else {
instance.add(Calendar.DAY_OF_MONTH, dynamicTimeSetting.getTimeNum());
}
}
}
return instance.get(Calendar.YEAR) + "-" + (instance.get(Calendar.MONTH) + 1 < 10 ? "0" : "") + (instance.get(Calendar.MONTH) + 1) + "-" + (instance.get(Calendar.DAY_OF_MONTH) < 10 ? "0" : "") + instance.get(Calendar.DAY_OF_MONTH) + time;
}
}
return item.getValue();
}
} }

View File

@ -0,0 +1,45 @@
package io.dataease.listener;
import io.dataease.chart.manage.ChartViewOldDataMergeService;
import io.dataease.startup.dao.auto.entity.CoreSysStartupJob;
import io.dataease.startup.dao.auto.mapper.CoreSysStartupJobMapper;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* @Author Junjun
*/
@Component
@Order(value = 9)
public class ChartFilterDynamicListener implements ApplicationListener<ApplicationReadyEvent> {
private final Logger logger = LoggerFactory.getLogger(ChartFilterDynamicListener.class);
public static final String JOB_ID = "chartFilterDynamic";
@Resource
private CoreSysStartupJobMapper coreSysStartupJobMapper;
@Resource
private ChartViewOldDataMergeService chartViewOldDataMergeService;
@Override
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
logger.info("====chart filter dynamic [start]====");
CoreSysStartupJob sysStartupJob = coreSysStartupJobMapper.selectById(JOB_ID);
if (ObjectUtils.isNotEmpty(sysStartupJob) && StringUtils.equalsIgnoreCase(sysStartupJob.getStatus(), "ready")) {
logger.info("====chart filter dynamic [doing]====");
chartViewOldDataMergeService.refreshFilter();
sysStartupJob.setStatus("done");
coreSysStartupJobMapper.updateById(sysStartupJob);
}
logger.info("====chart filter dynamic [end]====");
}
}

View File

@ -0,0 +1,3 @@
BEGIN;
INSERT INTO `core_sys_startup_job` VALUES ('chartFilterDynamic', 'chartFilterDynamic', 'ready');
COMMIT;

View File

@ -0,0 +1,3 @@
BEGIN;
INSERT INTO `core_sys_startup_job` VALUES ('chartFilterDynamic', 'chartFilterDynamic', 'ready');
COMMIT;

View File

@ -0,0 +1,18 @@
package io.dataease.extensions.view.filter;
import lombok.Data;
import java.io.Serializable;
/**
* @Author Junjun
*/
@Data
public class DynamicTimeSetting implements Serializable {
private String relativeToCurrent;//相对当前 thisYear lastYear thisMonth lastMonth today yesterday monthBeginning yearBeginning
private String timeGranularity;//时间粒度 year month date datetime
private Integer timeNum;// 数值
private String relativeToCurrentType;// year month date
private String around;// f b
private String arbitraryTime;//timeGranularity = datetime时 取时分秒
}

View File

@ -22,6 +22,8 @@ public class FilterTreeItem implements Serializable {
private String term;//'eq','not_eq','lt','le','gt','ge','in','not in','like','not like','null','not_null','empty','not_empty','between' private String term;//'eq','not_eq','lt','le','gt','ge','in','not in','like','not like','null','not_null','empty','not_empty','between'
private String value;// 'a' private String value;// 'a'
private List<String> enumValue;// ['a','b'] private List<String> enumValue;// ['a','b']
private String filterTypeTime;// dateValue | dynamicDate
private DynamicTimeSetting dynamicTimeSetting;
// tree // tree
private FilterTreeObj subTree; private FilterTreeObj subTree;
} }