feat: 数据聚合跨实体

This commit is contained in:
devezhao 2020-01-16 17:38:24 +08:00
parent 8af4757881
commit 17b5d894b0
4 changed files with 30 additions and 15 deletions

View file

@ -27,6 +27,7 @@ import com.googlecode.aviator.AviatorEvaluatorInstance;
import com.googlecode.aviator.Options;
import com.googlecode.aviator.exception.ExpressionSyntaxErrorException;
import com.rebuild.server.Application;
import com.rebuild.server.metadata.EntityHelper;
import com.rebuild.server.metadata.MetadataHelper;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
@ -51,14 +52,14 @@ public class FormulaEvaluator {
private static AviatorEvaluatorInstance AVIATOR = AviatorEvaluator.newInstance();
static {
// 强制浮点数运算
// 强制使用 BigDecimal/BigInteger 运算
AVIATOR.setOption(Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL, true);
}
private Entity sourceEntity;
private JSONObject item;
private String followSourceField;
private String filterSql;
final private Entity sourceEntity;
final private JSONObject item;
final private String followSourceField;
final private String filterSql;
/**
* @param item
@ -84,16 +85,20 @@ public class FormulaEvaluator {
}
String sourceField = item.getString("sourceField");
if (!MetadataHelper.checkAndWarnField(sourceEntity, sourceField)) {
if (MetadataHelper.getLastJoinField(sourceEntity, sourceField) == null) {
return null;
}
// 直接利用 SQL 函数计算结果
String sql = String.format("select %s(%s) from %s where %s = ?",
calcMode, sourceField, sourceEntity.getName(), followSourceField);
boolean direct = calcMode.equalsIgnoreCase("DIRECT");
String funcAndField = direct ? sourceField : String.format("%s(%s)", calcMode, sourceField);
String sql = String.format("select %s from %s where %s = ?", funcAndField, sourceEntity.getName(), followSourceField);
if (filterSql != null) {
sql += " and " + filterSql;
}
// 最近一条
if (direct) {
sql += " order by " + (sourceEntity.containsField(EntityHelper.ModifiedOn) ? EntityHelper.ModifiedOn : EntityHelper.CreatedOn) + " desc";
}
Object[] o = Application.createQueryNoFilter(sql).setParameter(1, triggerRecord).unique();
return o == null || o[0] == null ? 0 : o[0];
@ -110,7 +115,7 @@ public class FormulaEvaluator {
Set<String> fields = new HashSet<>();
while (m.find()) {
String fieldName = m.group(1);
if (MetadataHelper.checkAndWarnField(sourceEntity, fieldName)) {
if (MetadataHelper.getLastJoinField(sourceEntity, fieldName) != null) {
fields.add(fieldName);
}
}

View file

@ -76,17 +76,27 @@ public class FieldAggregationControll extends BaseControll {
List<String[]> sourceFields = new ArrayList<>();
List<String[]> targetFields = new ArrayList<>();
for (Field field : MetadataSorter.sortFields(sourceEntity.getFields(), DisplayType.NUMBER, DisplayType.DECIMAL)) {
sourceFields.add(new String[] { field.getName(), EasyMeta.getLabel(field) });
}
// 关联实体
for (Field fieldRef : MetadataSorter.sortFields(sourceEntity.getFields(), DisplayType.REFERENCE)) {
for (Field field : MetadataSorter.sortFields(fieldRef.getReferenceEntity(), DisplayType.NUMBER, DisplayType.DECIMAL)) {
sourceFields.add(new String[] {
fieldRef.getName() + "." + field.getName(),
EasyMeta.getLabel(fieldRef) + "." + EasyMeta.getLabel(field) });
}
}
if (targetEntity != null) {
for (Field field : MetadataSorter.sortFields(targetEntity.getFields(), DisplayType.NUMBER, DisplayType.DECIMAL)) {
targetFields.add(new String[] { field.getName(), EasyMeta.getLabel(field) });
}
}
boolean hadApproval = RobotApprovalManager.instance.hadApproval(targetEntity, null) != null;
boolean hadApproval = targetEntity != null && RobotApprovalManager.instance.hadApproval(targetEntity, null) != null;
JSON data = JSONUtils.toJSONObject(
new String[] { "source", "target", "hadApproval" },
new Object[] {

View file

@ -131,7 +131,7 @@
.formula-calc ul li>a {
display: inline-block;
width: 100%;
padding: 5px;
padding: 6px 5px;
font-weight: bold;
text-align: center;
background-color: #eee;
@ -149,7 +149,7 @@
}
.formula-calc .fields {
max-height: 175px;
max-height: 186px;
}
.formula-calc .fields ul li {

View file

@ -1,4 +1,4 @@
const CALC_MODES = { 'SUM': '求和', 'COUNT': '计数', 'AVG': '平均值', 'MAX': '最大', 'MIN': '最小', 'FORMULA': '计算公式' }
const CALC_MODES = { 'SUM': '求和', 'COUNT': '计数', 'AVG': '平均值', 'MAX': '最大', 'MIN': '最小', 'DIRECT': '赋值', 'FORMULA': '计算公式' }
// ~~
// eslint-disable-next-line no-undef