diff --git a/src/main/java/com/rebuild/server/business/trigger/impl/FormulaEvaluator.java b/src/main/java/com/rebuild/server/business/trigger/impl/FormulaEvaluator.java index 4543d076d..d0c43fa74 100644 --- a/src/main/java/com/rebuild/server/business/trigger/impl/FormulaEvaluator.java +++ b/src/main/java/com/rebuild/server/business/trigger/impl/FormulaEvaluator.java @@ -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 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); } } diff --git a/src/main/java/com/rebuild/web/admin/robot/FieldAggregationControll.java b/src/main/java/com/rebuild/web/admin/robot/FieldAggregationControll.java index 77dcb9de3..9eeaabecf 100644 --- a/src/main/java/com/rebuild/web/admin/robot/FieldAggregationControll.java +++ b/src/main/java/com/rebuild/web/admin/robot/FieldAggregationControll.java @@ -76,17 +76,27 @@ public class FieldAggregationControll extends BaseControll { List sourceFields = new ArrayList<>(); List 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[] { diff --git a/src/main/webapp/assets/css/triggers.css b/src/main/webapp/assets/css/triggers.css index a959a25ce..0bf6fb5b3 100644 --- a/src/main/webapp/assets/css/triggers.css +++ b/src/main/webapp/assets/css/triggers.css @@ -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 { diff --git a/src/main/webapp/assets/js/triggers/trigger.FIELDAGGREGATION.jsx b/src/main/webapp/assets/js/triggers/trigger.FIELDAGGREGATION.jsx index 8a2dc7c00..6a92dfe97 100644 --- a/src/main/webapp/assets/js/triggers/trigger.FIELDAGGREGATION.jsx +++ b/src/main/webapp/assets/js/triggers/trigger.FIELDAGGREGATION.jsx @@ -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