Build safe chart aggregation query models
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
package com.ruoyi.generator.domain.front.dto.block;
|
||||
|
||||
public class ChartQueryParameter
|
||||
{
|
||||
private String name;
|
||||
private Object value;
|
||||
|
||||
public ChartQueryParameter()
|
||||
{
|
||||
}
|
||||
|
||||
public ChartQueryParameter(String name, Object value)
|
||||
{
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Object getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Object value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.ruoyi.generator.domain.front.dto.block;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ChartQueryRenderModel
|
||||
{
|
||||
private String tableName;
|
||||
private String dimensionSql;
|
||||
private String metricSelectSql;
|
||||
private String whereSql;
|
||||
private String groupBySql;
|
||||
private String orderBySql;
|
||||
private Integer limit;
|
||||
private List<ChartQueryParameter> parameters;
|
||||
private List<ChartMetricConfig> metrics;
|
||||
private ChartDateRangeConfig dateRange;
|
||||
private boolean metricOnly;
|
||||
|
||||
public String getTableName() { return tableName; }
|
||||
public void setTableName(String tableName) { this.tableName = tableName; }
|
||||
public String getDimensionSql() { return dimensionSql; }
|
||||
public void setDimensionSql(String dimensionSql) { this.dimensionSql = dimensionSql; }
|
||||
public String getMetricSelectSql() { return metricSelectSql; }
|
||||
public void setMetricSelectSql(String metricSelectSql) { this.metricSelectSql = metricSelectSql; }
|
||||
public String getWhereSql() { return whereSql; }
|
||||
public void setWhereSql(String whereSql) { this.whereSql = whereSql; }
|
||||
public String getGroupBySql() { return groupBySql; }
|
||||
public void setGroupBySql(String groupBySql) { this.groupBySql = groupBySql; }
|
||||
public String getOrderBySql() { return orderBySql; }
|
||||
public void setOrderBySql(String orderBySql) { this.orderBySql = orderBySql; }
|
||||
public Integer getLimit() { return limit; }
|
||||
public void setLimit(Integer limit) { this.limit = limit; }
|
||||
public List<ChartQueryParameter> getParameters() { return parameters; }
|
||||
public void setParameters(List<ChartQueryParameter> parameters) { this.parameters = parameters; }
|
||||
public List<ChartMetricConfig> getMetrics() { return metrics; }
|
||||
public void setMetrics(List<ChartMetricConfig> metrics) { this.metrics = metrics; }
|
||||
public ChartDateRangeConfig getDateRange() { return dateRange; }
|
||||
public void setDateRange(ChartDateRangeConfig dateRange) { this.dateRange = dateRange; }
|
||||
public boolean isMetricOnly() { return metricOnly; }
|
||||
public void setMetricOnly(boolean metricOnly) { this.metricOnly = metricOnly; }
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
package com.ruoyi.generator.util;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.generator.domain.GenTable;
|
||||
import com.ruoyi.generator.domain.GenTableColumn;
|
||||
import com.ruoyi.generator.domain.front.dto.block.BusinessBlockDefinition;
|
||||
import com.ruoyi.generator.domain.front.dto.block.BusinessBlockInstance;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartDatasetConfig;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartDateRangeConfig;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartDimensionConfig;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartFilterConfig;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartMetricConfig;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartQueryParameter;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartQueryRenderModel;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartSortConfig;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ChartBlockRenderSupport
|
||||
{
|
||||
public ChartQueryRenderModel build(GenTable table, BusinessBlockDefinition definition,
|
||||
BusinessBlockInstance instance)
|
||||
{
|
||||
if (table == null || definition == null || instance == null || instance.getDataset() == null)
|
||||
{
|
||||
throw new ServiceException("图表查询配置不完整");
|
||||
}
|
||||
|
||||
ChartDatasetConfig dataset = instance.getDataset();
|
||||
boolean metricOnly = "metric".equalsIgnoreCase(StringUtils.defaultString(definition.getChartType()));
|
||||
List<ChartMetricConfig> metrics = dataset.getMetrics() == null
|
||||
? Collections.<ChartMetricConfig>emptyList() : dataset.getMetrics();
|
||||
List<ChartQueryParameter> parameters = new ArrayList<ChartQueryParameter>();
|
||||
|
||||
String dimensionSql = metricOnly ? "" : dimensionSql(table, dataset.getDimension());
|
||||
ChartQueryRenderModel model = new ChartQueryRenderModel();
|
||||
model.setTableName(table.getTableName());
|
||||
model.setDimensionSql(dimensionSql);
|
||||
model.setMetricSelectSql(metricSelectSql(table, metrics));
|
||||
model.setWhereSql(whereSql(table, dataset, parameters));
|
||||
model.setGroupBySql(metricOnly ? "" : dimensionSql);
|
||||
model.setOrderBySql(orderBySql(dataset.getSort(), metricOnly));
|
||||
model.setLimit(dataset.getLimit());
|
||||
model.setParameters(parameters);
|
||||
model.setMetrics(metrics);
|
||||
model.setDateRange(dataset.getDateRange());
|
||||
model.setMetricOnly(metricOnly);
|
||||
return model;
|
||||
}
|
||||
|
||||
private String dimensionSql(GenTable table, ChartDimensionConfig dimension)
|
||||
{
|
||||
if (dimension == null)
|
||||
{
|
||||
throw new ServiceException("图表维度配置不存在");
|
||||
}
|
||||
String column = requireColumn(table, dimension.getField()).getColumnName();
|
||||
String timeUnit = StringUtils.defaultString(dimension.getTimeUnit()).toLowerCase();
|
||||
if ("day".equals(timeUnit))
|
||||
{
|
||||
return "DATE_FORMAT(t." + column + ", '%Y-%m-%d')";
|
||||
}
|
||||
if ("week".equals(timeUnit))
|
||||
{
|
||||
return "DATE_FORMAT(t." + column + ", '%x-W%v')";
|
||||
}
|
||||
if ("month".equals(timeUnit))
|
||||
{
|
||||
return "DATE_FORMAT(t." + column + ", '%Y-%m')";
|
||||
}
|
||||
return "t." + column;
|
||||
}
|
||||
|
||||
private String metricSelectSql(GenTable table, List<ChartMetricConfig> metrics)
|
||||
{
|
||||
List<String> selections = new ArrayList<String>();
|
||||
for (ChartMetricConfig metric : metrics)
|
||||
{
|
||||
String aggregate = StringUtils.defaultString(metric.getAggregate()).toLowerCase();
|
||||
String column = StringUtils.isEmpty(metric.getField())
|
||||
? "" : requireColumn(table, metric.getField()).getColumnName();
|
||||
selections.add(metricSql(column, aggregate, metric.getAlias()));
|
||||
}
|
||||
return join(selections, ", ");
|
||||
}
|
||||
|
||||
private String metricSql(String column, String aggregate, String alias)
|
||||
{
|
||||
if ("count".equals(aggregate))
|
||||
{
|
||||
return StringUtils.isEmpty(column)
|
||||
? "COUNT(*) AS " + alias
|
||||
: "COUNT(t." + column + ") AS " + alias;
|
||||
}
|
||||
if ("avg".equals(aggregate))
|
||||
{
|
||||
return "AVG(t." + column + ") AS " + alias;
|
||||
}
|
||||
return "SUM(t." + column + ") AS " + alias;
|
||||
}
|
||||
|
||||
private String whereSql(GenTable table, ChartDatasetConfig dataset, List<ChartQueryParameter> parameters)
|
||||
{
|
||||
List<String> conditions = new ArrayList<String>();
|
||||
List<ChartFilterConfig> filters = dataset.getFilters() == null
|
||||
? Collections.<ChartFilterConfig>emptyList() : dataset.getFilters();
|
||||
for (ChartFilterConfig filter : filters)
|
||||
{
|
||||
String column = requireColumn(table, filter.getField()).getColumnName();
|
||||
String operator = StringUtils.defaultString(filter.getOperator()).toLowerCase();
|
||||
addFilterCondition(conditions, parameters, column, operator, filter.getValue());
|
||||
}
|
||||
|
||||
ChartDateRangeConfig dateRange = dataset.getDateRange();
|
||||
if (dateRange != null)
|
||||
{
|
||||
String column = requireColumn(table, dateRange.getField()).getColumnName();
|
||||
conditions.add("t." + column + " >= #{dateStart}");
|
||||
conditions.add("t." + column + " < #{dateEnd}");
|
||||
}
|
||||
return join(conditions, " AND ");
|
||||
}
|
||||
|
||||
private void addFilterCondition(List<String> conditions, List<ChartQueryParameter> parameters,
|
||||
String column, String operator, Object value)
|
||||
{
|
||||
String columnSql = "t." + column;
|
||||
if ("is_null".equals(operator))
|
||||
{
|
||||
conditions.add(columnSql + " IS NULL");
|
||||
return;
|
||||
}
|
||||
if ("is_not_null".equals(operator))
|
||||
{
|
||||
conditions.add(columnSql + " IS NOT NULL");
|
||||
return;
|
||||
}
|
||||
if ("between".equals(operator))
|
||||
{
|
||||
List<Object> values = values(value);
|
||||
String first = addParameter(parameters, values.get(0));
|
||||
String second = addParameter(parameters, values.get(1));
|
||||
conditions.add(columnSql + " BETWEEN " + first + " AND " + second);
|
||||
return;
|
||||
}
|
||||
if ("in".equals(operator))
|
||||
{
|
||||
List<String> placeholders = new ArrayList<String>();
|
||||
for (Object item : values(value))
|
||||
{
|
||||
placeholders.add(addParameter(parameters, item));
|
||||
}
|
||||
conditions.add(columnSql + " IN (" + join(placeholders, ", ") + ")");
|
||||
return;
|
||||
}
|
||||
|
||||
String sqlOperator = operatorSql(operator);
|
||||
conditions.add(columnSql + " " + sqlOperator + " " + addParameter(parameters, value));
|
||||
}
|
||||
|
||||
private String operatorSql(String operator)
|
||||
{
|
||||
if ("ne".equals(operator)) return "<>";
|
||||
if ("gt".equals(operator)) return ">";
|
||||
if ("gte".equals(operator)) return ">=";
|
||||
if ("lt".equals(operator)) return "<";
|
||||
if ("lte".equals(operator)) return "<=";
|
||||
return "=";
|
||||
}
|
||||
|
||||
private String addParameter(List<ChartQueryParameter> parameters, Object value)
|
||||
{
|
||||
String name = "filter" + parameters.size();
|
||||
parameters.add(new ChartQueryParameter(name, value));
|
||||
return "#{" + name + "}";
|
||||
}
|
||||
|
||||
private List<Object> values(Object value)
|
||||
{
|
||||
List<Object> values = new ArrayList<Object>();
|
||||
if (value instanceof Collection)
|
||||
{
|
||||
values.addAll((Collection<?>) value);
|
||||
return values;
|
||||
}
|
||||
if (value != null && value.getClass().isArray())
|
||||
{
|
||||
for (int index = 0; index < Array.getLength(value); index++)
|
||||
{
|
||||
values.add(Array.get(value, index));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
values.add(value);
|
||||
return values;
|
||||
}
|
||||
|
||||
private String orderBySql(ChartSortConfig sort, boolean metricOnly)
|
||||
{
|
||||
if (sort == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
String by = "dimension".equals(sort.getBy()) && !metricOnly ? "dimensionKey" : sort.getBy();
|
||||
return by + " " + StringUtils.defaultString(sort.getOrder()).toUpperCase();
|
||||
}
|
||||
|
||||
private GenTableColumn requireColumn(GenTable table, String field)
|
||||
{
|
||||
List<GenTableColumn> columns = table.getColumns() == null
|
||||
? Collections.<GenTableColumn>emptyList() : table.getColumns();
|
||||
for (GenTableColumn column : columns)
|
||||
{
|
||||
if (column != null && (StringUtils.equals(field, column.getColumnName())
|
||||
|| StringUtils.equals(field, column.getJavaField())))
|
||||
{
|
||||
return column;
|
||||
}
|
||||
}
|
||||
throw new ServiceException("图表字段不存在:" + table.getTableName() + "."
|
||||
+ StringUtils.defaultString(field));
|
||||
}
|
||||
|
||||
private String join(List<String> values, String delimiter)
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (String value : values)
|
||||
{
|
||||
if (result.length() > 0)
|
||||
{
|
||||
result.append(delimiter);
|
||||
}
|
||||
result.append(value);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
package com.ruoyi.generator.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import org.junit.Test;
|
||||
import com.ruoyi.generator.domain.GenTable;
|
||||
import com.ruoyi.generator.domain.GenTableColumn;
|
||||
import com.ruoyi.generator.domain.front.dto.block.BusinessBlockDefinition;
|
||||
import com.ruoyi.generator.domain.front.dto.block.BusinessBlockInstance;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartDatasetConfig;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartDateRangeConfig;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartDimensionConfig;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartFilterConfig;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartMetricConfig;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartQueryRenderModel;
|
||||
import com.ruoyi.generator.domain.front.dto.block.ChartSortConfig;
|
||||
|
||||
public class ChartBlockRenderSupportTest
|
||||
{
|
||||
private final ChartBlockRenderSupport support = new ChartBlockRenderSupport();
|
||||
|
||||
@Test
|
||||
public void rendersBoundSingleTableAggregation()
|
||||
{
|
||||
ChartQueryRenderModel model = support.build(orderTable(), definition("line"), lineInstance());
|
||||
|
||||
assertEquals("shop_order", model.getTableName());
|
||||
assertEquals("DATE_FORMAT(t.create_time, '%Y-%m-%d')", model.getDimensionSql());
|
||||
assertEquals("DATE_FORMAT(t.create_time, '%Y-%m-%d')", model.getGroupBySql());
|
||||
assertTrue(model.getMetricSelectSql().contains("SUM(t.amount) AS salesAmount"));
|
||||
assertTrue(model.getWhereSql().contains("t.status = #{filter0}"));
|
||||
assertEquals("filter0", model.getParameters().get(0).getName());
|
||||
assertEquals("PAID", model.getParameters().get(0).getValue());
|
||||
assertEquals("dimensionKey ASC", model.getOrderBySql());
|
||||
assertEquals(Integer.valueOf(100), model.getLimit());
|
||||
assertFalse(model.isMetricOnly());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void neverCopiesFilterValuesIntoSql()
|
||||
{
|
||||
BusinessBlockInstance instance = lineInstance();
|
||||
instance.getDataset().getFilters().get(0).setValue("PAID' OR 1=1 --");
|
||||
|
||||
ChartQueryRenderModel model = support.build(orderTable(), definition("line"), instance);
|
||||
|
||||
assertTrue(model.getWhereSql().contains("#{filter0}"));
|
||||
assertFalse(model.getWhereSql().contains("OR 1=1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void formatsDayWeekAndMonthDimensionsFromResolvedColumns()
|
||||
{
|
||||
assertDimension("day", "DATE_FORMAT(t.create_time, '%Y-%m-%d')");
|
||||
assertDimension("week", "DATE_FORMAT(t.create_time, '%x-W%v')");
|
||||
assertDimension("month", "DATE_FORMAT(t.create_time, '%Y-%m')");
|
||||
assertDimension(null, "t.create_time");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rendersCountSumAndAverageMetrics()
|
||||
{
|
||||
BusinessBlockInstance instance = lineInstance();
|
||||
instance.getDataset().setMetrics(Arrays.asList(
|
||||
metric(null, "count", "orderCount"),
|
||||
metric("amount", "sum", "salesAmount"),
|
||||
metric("amount", "avg", "averageAmount")));
|
||||
|
||||
ChartQueryRenderModel model = support.build(orderTable(), definition("line"), instance);
|
||||
|
||||
assertEquals("COUNT(*) AS orderCount, SUM(t.amount) AS salesAmount, AVG(t.amount) AS averageAmount",
|
||||
model.getMetricSelectSql());
|
||||
assertEquals(3, model.getMetrics().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rendersBetweenInNullAndDateRangeConditionsAsBoundParameters()
|
||||
{
|
||||
BusinessBlockInstance instance = lineInstance();
|
||||
ChartDateRangeConfig dateRange = new ChartDateRangeConfig();
|
||||
dateRange.setField("createTime");
|
||||
dateRange.setPreset("last_30_days");
|
||||
instance.getDataset().setDateRange(dateRange);
|
||||
instance.getDataset().setFilters(Arrays.asList(
|
||||
filter("amount", "between", Arrays.asList(10, 20)),
|
||||
filter("status", "in", new String[] { "PAID", "SHIPPED" }),
|
||||
filter("createTime", "is_not_null", null),
|
||||
filter("id", "is_null", null)));
|
||||
|
||||
ChartQueryRenderModel model = support.build(orderTable(), definition("line"), instance);
|
||||
|
||||
assertTrue(model.getWhereSql().contains("t.amount BETWEEN #{filter0} AND #{filter1}"));
|
||||
assertTrue(model.getWhereSql().contains("t.status IN (#{filter2}, #{filter3})"));
|
||||
assertTrue(model.getWhereSql().contains("t.create_time IS NOT NULL"));
|
||||
assertTrue(model.getWhereSql().contains("t.id IS NULL"));
|
||||
assertTrue(model.getWhereSql().contains("t.create_time >= #{dateStart}"));
|
||||
assertTrue(model.getWhereSql().contains("t.create_time < #{dateEnd}"));
|
||||
assertEquals(Arrays.asList(10, 20, "PAID", "SHIPPED"), Arrays.asList(
|
||||
model.getParameters().get(0).getValue(),
|
||||
model.getParameters().get(1).getValue(),
|
||||
model.getParameters().get(2).getValue(),
|
||||
model.getParameters().get(3).getValue()));
|
||||
assertSame(dateRange, model.getDateRange());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rendersMetricOnlyQueryWithoutDimensionOrGrouping()
|
||||
{
|
||||
BusinessBlockInstance instance = lineInstance();
|
||||
instance.getDataset().setDimension(null);
|
||||
instance.getDataset().setMetrics(Collections.singletonList(metric("id", "count", "orderCount")));
|
||||
instance.getDataset().setSort(null);
|
||||
instance.getDataset().setLimit(Integer.valueOf(1));
|
||||
|
||||
ChartQueryRenderModel model = support.build(orderTable(), definition("metric"), instance);
|
||||
|
||||
assertTrue(model.isMetricOnly());
|
||||
assertEquals("", model.getDimensionSql());
|
||||
assertEquals("", model.getGroupBySql());
|
||||
assertEquals("", model.getOrderBySql());
|
||||
assertEquals("COUNT(t.id) AS orderCount", model.getMetricSelectSql());
|
||||
assertEquals(Integer.valueOf(1), model.getLimit());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rendersMetricAliasSortAndConfiguredChartLimits()
|
||||
{
|
||||
BusinessBlockInstance instance = lineInstance();
|
||||
instance.getDataset().getSort().setBy("salesAmount");
|
||||
instance.getDataset().getSort().setOrder("desc");
|
||||
instance.getDataset().setLimit(Integer.valueOf(20));
|
||||
|
||||
ChartQueryRenderModel model = support.build(orderTable(), definition("bar"), instance);
|
||||
|
||||
assertEquals("salesAmount DESC", model.getOrderBySql());
|
||||
assertEquals(Integer.valueOf(20), model.getLimit());
|
||||
|
||||
instance.getDataset().setLimit(Integer.valueOf(10));
|
||||
assertEquals(Integer.valueOf(10),
|
||||
support.build(orderTable(), definition("pie"), instance).getLimit());
|
||||
}
|
||||
|
||||
private void assertDimension(String timeUnit, String expected)
|
||||
{
|
||||
BusinessBlockInstance instance = lineInstance();
|
||||
instance.getDataset().getDimension().setField("createTime");
|
||||
instance.getDataset().getDimension().setTimeUnit(timeUnit);
|
||||
assertEquals(expected, support.build(orderTable(), definition("line"), instance).getDimensionSql());
|
||||
}
|
||||
|
||||
private BusinessBlockDefinition definition(String chartType)
|
||||
{
|
||||
BusinessBlockDefinition definition = new BusinessBlockDefinition();
|
||||
definition.setKind("chart");
|
||||
definition.setChartType(chartType);
|
||||
return definition;
|
||||
}
|
||||
|
||||
private BusinessBlockInstance lineInstance()
|
||||
{
|
||||
ChartDimensionConfig dimension = new ChartDimensionConfig();
|
||||
dimension.setField("create_time");
|
||||
dimension.setTimeUnit("day");
|
||||
|
||||
ChartSortConfig sort = new ChartSortConfig();
|
||||
sort.setBy("dimension");
|
||||
sort.setOrder("asc");
|
||||
|
||||
ChartDatasetConfig dataset = new ChartDatasetConfig();
|
||||
dataset.setTable("shop_order");
|
||||
dataset.setDimension(dimension);
|
||||
dataset.setMetrics(Collections.singletonList(metric("amount", "sum", "salesAmount")));
|
||||
dataset.setFilters(Collections.singletonList(filter("status", "eq", "PAID")));
|
||||
dataset.setSort(sort);
|
||||
dataset.setLimit(Integer.valueOf(100));
|
||||
|
||||
BusinessBlockInstance instance = new BusinessBlockInstance();
|
||||
instance.setId("admin_line_chart_001");
|
||||
instance.setDataset(dataset);
|
||||
return instance;
|
||||
}
|
||||
|
||||
private ChartMetricConfig metric(String field, String aggregate, String alias)
|
||||
{
|
||||
ChartMetricConfig metric = new ChartMetricConfig();
|
||||
metric.setField(field);
|
||||
metric.setAggregate(aggregate);
|
||||
metric.setAlias(alias);
|
||||
metric.setLabel(alias);
|
||||
return metric;
|
||||
}
|
||||
|
||||
private ChartFilterConfig filter(String field, String operator, Object value)
|
||||
{
|
||||
ChartFilterConfig filter = new ChartFilterConfig();
|
||||
filter.setField(field);
|
||||
filter.setOperator(operator);
|
||||
filter.setValue(value);
|
||||
return filter;
|
||||
}
|
||||
|
||||
private GenTable orderTable()
|
||||
{
|
||||
GenTable table = new GenTable();
|
||||
table.setTableName("shop_order");
|
||||
table.setColumns(Arrays.asList(
|
||||
column("id", "id"),
|
||||
column("amount", "amount"),
|
||||
column("status", "status"),
|
||||
column("create_time", "createTime")));
|
||||
return table;
|
||||
}
|
||||
|
||||
private GenTableColumn column(String columnName, String javaField)
|
||||
{
|
||||
GenTableColumn column = new GenTableColumn();
|
||||
column.setColumnName(columnName);
|
||||
column.setJavaField(javaField);
|
||||
return column;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user