From b12493e1a149ac18aa0bb4139f0263fece0a1aab Mon Sep 17 00:00:00 2001 From: tancong <130981800+tancongsir@users.noreply.github.com> Date: Tue, 8 Aug 2023 11:36:13 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E5=9C=BA=E6=99=AF=E8=81=94=E5=8A=A8):=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=8C=87=E6=A0=87=E5=9C=BA=E6=99=AF=E5=91=8A?= =?UTF-8?q?=E8=AD=A6=E4=B8=8D=E8=A7=A6=E5=8F=91=E9=97=AE=E9=A2=98=20(#400)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rule/engine/scene/SceneUtils.java | 31 +++++- .../internal/triggers/DeviceTrigger.java | 102 ++++++------------ 2 files changed, 59 insertions(+), 74 deletions(-) diff --git a/jetlinks-manager/rule-engine-manager/src/main/java/org/jetlinks/community/rule/engine/scene/SceneUtils.java b/jetlinks-manager/rule-engine-manager/src/main/java/org/jetlinks/community/rule/engine/scene/SceneUtils.java index 24593757..73aa012a 100644 --- a/jetlinks-manager/rule-engine-manager/src/main/java/org/jetlinks/community/rule/engine/scene/SceneUtils.java +++ b/jetlinks-manager/rule-engine-manager/src/main/java/org/jetlinks/community/rule/engine/scene/SceneUtils.java @@ -7,14 +7,37 @@ import org.jetlinks.community.rule.engine.scene.term.TermColumn; import org.jetlinks.community.rule.engine.scene.value.TermValue; import org.springframework.util.StringUtils; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.Function; public class SceneUtils { + public static String createColumnAlias(String prefix,String column, boolean wrapColumn) { + if (!column.contains(".")) { + return wrapColumn ? wrapColumnName(column) : column; + } + String[] arr = column.split("[.]"); + String alias; + //prefix.temp.current + if (prefix.equals(arr[0])) { + String property = arr[1]; + alias = property + "_" + arr[arr.length - 1]; + } else { + if (arr.length > 1) { + alias = String.join("_", Arrays.copyOfRange(arr, 1, arr.length)); + } else { + alias = column.replace(".", "_"); + } + } + return wrapColumn ? wrapColumnName(alias) : alias; + } + + public static String wrapColumnName(String column) { + if (column.startsWith("\"") && column.endsWith("\"")) { + return column; + } + return "\"" + (column.replace("\"", "\\\"")) + "\""; + } /** * 根据条件和可选的条件列解析出将要输出的变量信息 diff --git a/jetlinks-manager/rule-engine-manager/src/main/java/org/jetlinks/community/rule/engine/scene/internal/triggers/DeviceTrigger.java b/jetlinks-manager/rule-engine-manager/src/main/java/org/jetlinks/community/rule/engine/scene/internal/triggers/DeviceTrigger.java index 6be0476d..8dee22f1 100644 --- a/jetlinks-manager/rule-engine-manager/src/main/java/org/jetlinks/community/rule/engine/scene/internal/triggers/DeviceTrigger.java +++ b/jetlinks-manager/rule-engine-manager/src/main/java/org/jetlinks/community/rule/engine/scene/internal/triggers/DeviceTrigger.java @@ -9,6 +9,7 @@ import org.hswebframework.ezorm.rdb.executor.PrepareSqlRequest; import org.hswebframework.ezorm.rdb.executor.SqlRequest; import org.hswebframework.ezorm.rdb.operator.builder.fragments.AbstractTermsFragmentBuilder; import org.hswebframework.ezorm.rdb.operator.builder.fragments.EmptySqlFragments; +import org.hswebframework.ezorm.rdb.operator.builder.fragments.NativeSql; import org.hswebframework.ezorm.rdb.operator.builder.fragments.SqlFragments; import org.hswebframework.web.bean.FastBeanCopier; import org.hswebframework.web.i18n.LocaleUtils; @@ -48,6 +49,8 @@ import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; +import static org.jetlinks.community.rule.engine.scene.SceneRule.DEFAULT_FILTER_TABLE; + @Getter @Setter public class DeviceTrigger extends DeviceSelectorSpec implements SceneTriggerProvider.TriggerConfig, Serializable { @@ -175,37 +178,6 @@ public class DeviceTrigger extends DeviceSelectorSpec implements SceneTriggerPro return CollectionUtils.isEmpty(terms) ? EmptySqlFragments.INSTANCE : termBuilder.createTermFragments(this, terms); } - Function, Mono> createFilter(List terms) { - SqlFragments fragments = CollectionUtils.isEmpty(terms) ? EmptySqlFragments.INSTANCE : termBuilder.createTermFragments(this, terms); - if (!fragments.isEmpty()) { - SqlRequest request = fragments.toRequest(); - String sql = "select 1 from t where " + request.getSql(); - ReactorQL ql = ReactorQL - .builder() - .sql(sql) - .build(); - List args = Arrays.asList(request.getParameters()); - String sqlString = request.toNativeSql(); - return new Function, Mono>() { - @Override - public Mono apply(Map map) { - ReactorQLContext context = new DefaultReactorQLContext((t) -> Flux.just(map), args); - return ql - .start(context) - .hasElements(); - } - - @Override - public String toString() { - return sqlString; - } - }; - } - - return ignore -> Reactors.ALWAYS_TRUE; - - } - private String createFromTable() { String topic = null; @@ -230,12 +202,13 @@ public class DeviceTrigger extends DeviceSelectorSpec implements SceneTriggerPro if (!StringUtils.hasText(selector)) { selector = "all"; } + String scope; switch (selector) { case "all": topic = String.format(topic, "*"); break; case "fixed": - String scope = getSelectorValues() + scope = getSelectorValues() .stream() .map(SelectorValue::getValue) .map(String::valueOf) @@ -273,7 +246,7 @@ public class DeviceTrigger extends DeviceSelectorSpec implements SceneTriggerPro .lookupSupport(termType) .orElseThrow(() -> new UnsupportedOperationException("unsupported termType " + termType)); - Term copy = refactorTermValue("t", term.clone()); + Term copy = refactorTermValue(DEFAULT_FILTER_TABLE, term.clone()); return support.createSql(copy.getColumn(), copy.getValue(), term); } @@ -330,30 +303,42 @@ public class DeviceTrigger extends DeviceSelectorSpec implements SceneTriggerPro .collect(Collectors.toList()); } - if (!term.getOptions().contains(TermType.OPTIONS_NATIVE_SQL)) { - String column; - // properties.xxx.last的场景 - if (arr.length > 3 && arr[0].equals("properties")) { - column = tableName + "['" + createColumnAlias(term.getColumn(), false) + "." + String.join(".", Arrays.copyOfRange(arr, 2, arr.length - 1)) + "']"; - } else if (!isBranchTerm(arr[0])) { - column = tableName + "['" + createColumnAlias(term.getColumn(), false) + "']"; - } else { - column = term.getColumn(); - } - term.setColumn(column); + String column; + // properties.xxx.last的场景 + if (arr.length > 3 && arr[0].equals("properties")) { + column = tableName + "['" + createColumnAlias(term.getColumn(), false) + "." + String.join(".", Arrays.copyOfRange(arr, 2, arr.length - 1)) + "']"; + } else if (!isDirectTerm(arr[0])) { + column = tableName + "['" + createColumnAlias(term.getColumn(), false) + "']"; + } else { + column = term.getColumn(); } + if (term.getOptions().contains(TermType.OPTIONS_NATIVE_SQL)) { + val = NativeSql.of(String.valueOf(val)); + } + + term.setColumn(column); + term.setValue(val); return term; } + private static boolean isDirectTerm(String column) { + //直接term,构建Condition输出条件时使用 + return isBranchTerm(column) || isSceneTerm(column); + } + private static boolean isBranchTerm(String column) { return column.startsWith("branch_") && column.contains("_group_") && column.contains("_action_"); } + private static boolean isSceneTerm(String column) { + return column.startsWith("scene"); + } + static String parseProperty(String column) { String[] arr = column.split("[.]"); @@ -377,9 +362,9 @@ public class DeviceTrigger extends DeviceSelectorSpec implements SceneTriggerPro case current: return "this['properties." + property + "']"; case recent: - return "coalesce(this['properties." + property + "']" + ",device.property.recent(deviceId,'" + property + "',timestamp))"; + return "coalesce(this['properties." + property + "']" + ",device.property.recent(deviceId,'" + property + "',timestamp - 1))"; case last: - return "device.property.recent(deviceId,'" + property + "',timestamp)"; + return "device.property.recent(deviceId,'" + property + "',timestamp - 1)"; } } catch (IllegalArgumentException ignore) { @@ -389,35 +374,13 @@ public class DeviceTrigger extends DeviceSelectorSpec implements SceneTriggerPro } static String createColumnAlias(String column, boolean wrapColumn) { - if (!column.contains(".")) { - return wrapColumn ? wrapColumnName(column) : column; - } - String[] arr = column.split("[.]"); - String alias; - //properties.temp.current - if ("properties".equals(arr[0])) { - String property = arr[1]; - alias = property + "_" + arr[arr.length - 1]; - } else { - if (arr.length > 1) { - alias = String.join("_", Arrays.copyOfRange(arr, 1, arr.length)); - } else { - alias = column.replace(".", "_"); - } - } - return wrapColumn ? wrapColumnName(alias) : alias; + return SceneUtils.createColumnAlias("properties", column, wrapColumn); } static String createColumnAlias(String column) { return createColumnAlias(column, true); } - static String wrapColumnName(String column) { - if (column.startsWith("\"") && column.endsWith("\"")) { - return column; - } - return "\"" + (column.replace("\"", "\\\"")) + "\""; - } public List createDefaultVariable() { return Arrays.asList( @@ -518,5 +481,4 @@ public class DeviceTrigger extends DeviceSelectorSpec implements SceneTriggerPro operation.validate(); } - }