浏览代码

标签查询增加表达式支持

zhou-hao 4 年之前
父节点
当前提交
607dc59b93

+ 52 - 18
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceTagTerm.java

@@ -3,9 +3,12 @@ package org.jetlinks.community.device.service.term;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import org.hswebframework.ezorm.core.param.Term;
 import org.hswebframework.ezorm.core.param.Term;
 import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
 import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
+import org.hswebframework.ezorm.rdb.operator.builder.fragments.AbstractTermsFragmentBuilder;
 import org.hswebframework.ezorm.rdb.operator.builder.fragments.PrepareSqlFragments;
 import org.hswebframework.ezorm.rdb.operator.builder.fragments.PrepareSqlFragments;
 import org.hswebframework.ezorm.rdb.operator.builder.fragments.SqlFragments;
 import org.hswebframework.ezorm.rdb.operator.builder.fragments.SqlFragments;
+import org.hswebframework.ezorm.rdb.operator.builder.fragments.TermFragmentBuilder;
 import org.hswebframework.ezorm.rdb.operator.builder.fragments.term.AbstractTermFragmentBuilder;
 import org.hswebframework.ezorm.rdb.operator.builder.fragments.term.AbstractTermFragmentBuilder;
+import org.hswebframework.web.api.crud.entity.TermExpressionParser;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 
 
 import java.util.HashMap;
 import java.util.HashMap;
@@ -19,21 +22,22 @@ import java.util.stream.Stream;
  */
  */
 @Component
 @Component
 public class DeviceTagTerm extends AbstractTermFragmentBuilder {
 public class DeviceTagTerm extends AbstractTermFragmentBuilder {
+
+    public static final String termType = "dev-tag";
+
     public DeviceTagTerm() {
     public DeviceTagTerm() {
-        super("dev-tag", "根据设备标签查询设备");
+        super(termType, "根据设备标签查询设备");
     }
     }
 
 
-    private void acceptTerm(PrepareSqlFragments fragments, String terms) {
-        List<Map<String, String>> tags;
-
+    private void acceptTerm(boolean and, RDBColumnMetadata column, PrepareSqlFragments fragments, String terms) {
         //json
         //json
         if (terms.startsWith("[")) {
         if (terms.startsWith("[")) {
-            tags = (List) JSON.parseArray(terms, Map.class);
+            acceptTerm(and, fragments, (List) JSON.parseArray(terms, Map.class));
         } else if (terms.startsWith("{")) {
         } else if (terms.startsWith("{")) {
-            acceptTerm(fragments, JSON.parseObject(terms));
-            return;
-        } else {
-            tags = Stream.of(terms.split("[,]"))
+            acceptTerm(and, fragments, JSON.parseObject(terms));
+        } else if (terms.contains(":") && !terms.contains(" ")) {
+            List<Map<String, String>> tags = Stream
+                .of(terms.split("[,]"))
                 .map(str -> str.split("[:]"))
                 .map(str -> str.split("[:]"))
                 .map(str -> {
                 .map(str -> {
                     Map<String, String> tag = new HashMap<>();
                     Map<String, String> tag = new HashMap<>();
@@ -42,12 +46,17 @@ public class DeviceTagTerm extends AbstractTermFragmentBuilder {
                     return tag;
                     return tag;
                 })
                 })
                 .collect(Collectors.toList());
                 .collect(Collectors.toList());
+            acceptTerm(and, fragments, tags);
+        } else {
+            //SQL表达式
+            List<Term> tagKeys = TermExpressionParser.parse(terms);
+            fragments.addSql("and (").addFragments(builder.createTermFragments(column, tagKeys)).addSql(")");
         }
         }
-        acceptTerm(fragments, tags);
+
     }
     }
 
 
-    private void acceptTerm(PrepareSqlFragments fragments, Map<?, ?> terms) {
-        acceptTerm(fragments, terms.entrySet().stream().map(e -> {
+    private void acceptTerm(boolean and, PrepareSqlFragments fragments, Map<?, ?> terms) {
+        acceptTerm(and, fragments, terms.entrySet().stream().map(e -> {
             Map<String, String> tag = new HashMap<>();
             Map<String, String> tag = new HashMap<>();
             tag.put("key", String.valueOf(e.getKey()));
             tag.put("key", String.valueOf(e.getKey()));
             tag.put("value", String.valueOf(e.getValue()));
             tag.put("value", String.valueOf(e.getValue()));
@@ -55,13 +64,13 @@ public class DeviceTagTerm extends AbstractTermFragmentBuilder {
         }).collect(Collectors.toList()));
         }).collect(Collectors.toList()));
     }
     }
 
 
-    private void acceptTerm(PrepareSqlFragments fragments, List<Map<String, String>> tags) {
+    private void acceptTerm(boolean and, PrepareSqlFragments fragments, List<Map<String, String>> tags) {
 
 
         int len = 0;
         int len = 0;
         fragments.addSql("and (");
         fragments.addSql("and (");
         for (Map<String, String> tag : tags) {
         for (Map<String, String> tag : tags) {
             if (len++ > 0) {
             if (len++ > 0) {
-                fragments.addSql("or");
+                fragments.addSql(and ? "and" : "or");
             }
             }
             fragments.addSql("(d.key = ? and d.value like ?)").addParameter(tag.get("key"), tag.get("value"));
             fragments.addSql("(d.key = ? and d.value like ?)").addParameter(tag.get("key"), tag.get("value"));
         }
         }
@@ -79,17 +88,42 @@ public class DeviceTagTerm extends AbstractTermFragmentBuilder {
 
 
         fragments.addSql("exists(select 1 from dev_device_tags d where d.device_id =", columnFullName);
         fragments.addSql("exists(select 1 from dev_device_tags d where d.device_id =", columnFullName);
         Object value = term.getValue();
         Object value = term.getValue();
-
+        boolean and = term.getOptions().contains("and");
         if (value instanceof Map) {
         if (value instanceof Map) {
-            acceptTerm(fragments, (Map<?, ?>) value);
+            acceptTerm(and, fragments, (Map<?, ?>) value);
         } else if (value instanceof List) {
         } else if (value instanceof List) {
-            acceptTerm(fragments, (List<Map<String, String>>) value);
+            acceptTerm(and, fragments, (List<Map<String, String>>) value);
         } else {
         } else {
-            acceptTerm(fragments, String.valueOf(value));
+            acceptTerm(and, column, fragments, String.valueOf(value));
         }
         }
 
 
         fragments.addSql(")");
         fragments.addSql(")");
 
 
         return fragments;
         return fragments;
     }
     }
+
+    static DeviceTagTerm.WhereBuilder builder = new DeviceTagTerm.WhereBuilder();
+
+    static class WhereBuilder extends AbstractTermsFragmentBuilder<RDBColumnMetadata> {
+
+
+        @Override
+        protected SqlFragments createTermFragments(RDBColumnMetadata parameter, Term term) {
+
+            PrepareSqlFragments sqlFragments = PrepareSqlFragments.of();
+            sqlFragments.addSql("(d.key = ?")
+                        .addParameter(term.getColumn())
+                        .addSql("and")
+                        .addFragments(parameter
+                                          .findFeatureNow(TermFragmentBuilder.createFeatureId(term.getTermType()))
+                                          .createFragments("d.value", parameter, term)
+                        ).addSql(")");
+            return sqlFragments;
+        }
+
+        @Override
+        protected SqlFragments createTermFragments(RDBColumnMetadata parameter, List<Term> terms) {
+            return super.createTermFragments(parameter, terms);
+        }
+    }
 }
 }