forked from github/dataease
feat(图表): 过滤器支持动态时间
This commit is contained in:
parent
aeaf6290be
commit
1a0c1ac2b5
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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]====");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
BEGIN;
|
||||||
|
INSERT INTO `core_sys_startup_job` VALUES ('chartFilterDynamic', 'chartFilterDynamic', 'ready');
|
||||||
|
COMMIT;
|
@ -0,0 +1,3 @@
|
|||||||
|
BEGIN;
|
||||||
|
INSERT INTO `core_sys_startup_job` VALUES ('chartFilterDynamic', 'chartFilterDynamic', 'ready');
|
||||||
|
COMMIT;
|
@ -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时 取时分秒
|
||||||
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user