From b7dffda0bc50dad03ecb5cf265b1c6b970b86dd8 Mon Sep 17 00:00:00 2001 From: bestfeng1020 <31398465+bestfeng1020@users.noreply.github.com> Date: Fri, 7 Apr 2023 17:34:26 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=9F=A5=E8=AF=A2=E6=9D=A1=E4=BB=B6):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AE=BE=E5=A4=87=E6=9F=A5=E8=AF=A2=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E6=9E=84=E9=80=A0=E5=99=A8=20(#260)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/term/DeviceCategoryTerm.java | 65 ++++++++++++ .../service/term/DeviceInstanceTerm.java | 99 +++++++++++++++++++ .../term/DeviceProductInfoTermBuilder.java | 85 ++++++++++++++++ .../service/term/DeviceProtocolTerm.java | 34 +++++++ .../device/service/term/DeviceTypeTerm.java | 37 +++++++ 5 files changed, 320 insertions(+) create mode 100755 jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceCategoryTerm.java create mode 100644 jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceInstanceTerm.java create mode 100755 jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceProductInfoTermBuilder.java create mode 100755 jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceProtocolTerm.java create mode 100755 jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceTypeTerm.java diff --git a/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceCategoryTerm.java b/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceCategoryTerm.java new file mode 100755 index 00000000..b9f5e551 --- /dev/null +++ b/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceCategoryTerm.java @@ -0,0 +1,65 @@ +package org.jetlinks.community.device.service.term; + +import org.hswebframework.ezorm.core.param.Term; +import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata; +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.term.AbstractTermFragmentBuilder; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 根据产品分类查询与产品关联的数据,如: 查询某个分类下的产品列表. + *

+ * + * 注意: 查询时指定列名是和产品ID关联的列或者实体类属性名. + * 如: 查询设备列表时则使用productId. + * 此条件仅支持关系型数据库中的查询. + * + *

+ * 在通用查询接口中可以使用动态查询参数中的term.termType来使用此功能. + * 查看动态查询参数说明 + *

+ * 在内部通用条件中,可以使用DSL方式创建条件,例如: + *

+ *     createQuery()
+ *     .where()
+ *     .and("productId","dev-prod-cat",cateId)
+ *     .fetch()
+ * 
+ * + * @author zhouhao + * @since 1.3 + */ +@Component +public class DeviceCategoryTerm extends AbstractTermFragmentBuilder { + + public DeviceCategoryTerm() { + super("dev-prod-cat", "按产品品类查询"); + } + + @Override + public SqlFragments createFragments(String columnFullName, RDBColumnMetadata column, Term term) { + + PrepareSqlFragments sqlFragments = PrepareSqlFragments.of(); + + List idList = convertList(column, term); + + sqlFragments.addSql("exists(select 1 from dev_product prod where prod.id =", columnFullName); + + sqlFragments.addSql("and exists(select 1 from dev_product_category g where g.id = prod.classified_id and "); + sqlFragments.addSql( + idList + .stream() + .map(r -> "path like (select concat(path,'%') from dev_product_category g2 where g2.id = ?)") + .collect(Collectors.joining(" or ", "(", ")")) + , ")") + .addParameter(idList); + + sqlFragments.addSql(")"); + + return sqlFragments; + } +} diff --git a/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceInstanceTerm.java b/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceInstanceTerm.java new file mode 100644 index 00000000..bee5e6d7 --- /dev/null +++ b/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceInstanceTerm.java @@ -0,0 +1,99 @@ +package org.jetlinks.community.device.service.term; + +import org.hswebframework.ezorm.core.param.Term; +import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata; +import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata; +import org.hswebframework.ezorm.rdb.metadata.TableOrViewMetadata; +import org.hswebframework.ezorm.rdb.operator.builder.fragments.*; +import org.hswebframework.ezorm.rdb.operator.builder.fragments.term.AbstractTermFragmentBuilder; +import org.jetlinks.community.utils.ConverterUtils; +import org.springframework.stereotype.Component; + +import java.util.List; + + +/** + * 根据设备查询. + *

+ * 将设备信息的条件嵌套到此条件中 + *

+ *

+ * "terms": [
+ *      {
+ *          "column": "device_id$dev-instance",
+ *          "value": [
+ *              {
+ *                  "column": "product_id",
+ *                  "termType": "eq",
+ *                  "value": "1"
+ *              }
+ *          ]
+ *      }
+ * ],
+ * 
+ * + * @author zhouhao + * @since 1.6 + */ +@Component +public class DeviceInstanceTerm extends AbstractTermFragmentBuilder { + + public static final String termType = "dev-instance"; + + public DeviceInstanceTerm() { + super(termType, "根据设备信息查询"); + } + + @Override + public SqlFragments createFragments(String columnFullName, + RDBColumnMetadata column, + Term term) { + List terms = ConverterUtils.convertTerms(term.getValue()); + PrepareSqlFragments sqlFragments = PrepareSqlFragments.of(); + if (term.getOptions().contains("not")) { + sqlFragments.addSql("not"); + } + sqlFragments.addSql("exists(select 1 from ", getTableName("dev_device_instance", column), " _dev where _dev.id = ", columnFullName); + + RDBTableMetadata metadata = column + .getOwner() + .getSchema() + .getTable("dev_device_instance") + .orElseThrow(() -> new UnsupportedOperationException("unsupported dev_device_instance")); + + SqlFragments where = builder.createTermFragments(metadata, terms); + if (!where.isEmpty()) { + sqlFragments.addSql("and") + .addFragments(where); + } + sqlFragments.addSql(")"); + return sqlFragments; + } + + + static DeviceTermsBuilder builder = new DeviceTermsBuilder(); + + static class DeviceTermsBuilder extends AbstractTermsFragmentBuilder { + + @Override + protected SqlFragments createTermFragments(TableOrViewMetadata parameter, + List terms) { + return super.createTermFragments(parameter, terms); + } + + @Override + protected SqlFragments createTermFragments(TableOrViewMetadata table, + Term term) { + if (term.getValue() instanceof NativeSql) { + NativeSql sql = ((NativeSql) term.getValue()); + return PrepareSqlFragments.of(sql.getSql(), sql.getParameters()); + } + return table + .getColumn(term.getColumn()) + .flatMap(column -> table + .findFeature(TermFragmentBuilder.createFeatureId(term.getTermType())) + .map(termFragment -> termFragment.createFragments(column.getFullName("_dev"), column, term))) + .orElse(EmptySqlFragments.INSTANCE); + } + } +} diff --git a/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceProductInfoTermBuilder.java b/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceProductInfoTermBuilder.java new file mode 100755 index 00000000..37179c71 --- /dev/null +++ b/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceProductInfoTermBuilder.java @@ -0,0 +1,85 @@ +package org.jetlinks.community.device.service.term; + +import org.hswebframework.ezorm.core.param.Term; +import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata; +import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata; +import org.hswebframework.ezorm.rdb.metadata.TableOrViewMetadata; +import org.hswebframework.ezorm.rdb.operator.builder.fragments.*; +import org.hswebframework.ezorm.rdb.operator.builder.fragments.term.AbstractTermFragmentBuilder; +import org.jetlinks.community.utils.ConverterUtils; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 根据设备产品信息查询设备数据 + * + * @author bestfeng + * @since 2.0 + */ +@Component +public class DeviceProductInfoTermBuilder extends AbstractTermFragmentBuilder { + + public static final String termType = "product-info"; + + public DeviceProductInfoTermBuilder() { + super(termType, "根据产品信息查询设备数据"); + } + + + @SuppressWarnings("all") + public static List convertTerms(Object value) { + return ConverterUtils.convertTerms(value); + } + + + @Override + public SqlFragments createFragments(String columnFullName, RDBColumnMetadata column, Term term) { + List terms = convertTerms(term.getValue()); + PrepareSqlFragments sqlFragments = PrepareSqlFragments.of(); + if(term.getOptions().contains("not")){ + sqlFragments.addSql("not"); + } + sqlFragments + .addSql("exists(select 1 from ",getTableName("dev_product",column)," _product where _product.id = ", columnFullName); + + RDBTableMetadata metadata = column + .getOwner() + .getSchema() + .getTable("dev_product") + .orElseThrow(() -> new UnsupportedOperationException("unsupported dev_product")); + + SqlFragments where = builder.createTermFragments(metadata, terms); + if (!where.isEmpty()) { + sqlFragments.addSql("and") + .addFragments(where); + } + sqlFragments.addSql(")"); + return sqlFragments; + } + + + static ProductTermBuilder builder = new ProductTermBuilder(); + + static class ProductTermBuilder extends AbstractTermsFragmentBuilder { + + @Override + protected SqlFragments createTermFragments(TableOrViewMetadata parameter, List terms) { + return super.createTermFragments(parameter, terms); + } + + @Override + protected SqlFragments createTermFragments(TableOrViewMetadata table, Term term) { + if (term.getValue() instanceof NativeSql) { + NativeSql sql = ((NativeSql) term.getValue()); + return PrepareSqlFragments.of(sql.getSql(), sql.getParameters()); + } + return table + .getColumn(term.getColumn()) + .flatMap(column -> table + .findFeature(TermFragmentBuilder.createFeatureId(term.getTermType())) + .map(termFragment -> termFragment.createFragments(column.getFullName("_product"), column, term))) + .orElse(EmptySqlFragments.INSTANCE); + } + } +} diff --git a/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceProtocolTerm.java b/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceProtocolTerm.java new file mode 100755 index 00000000..b4e86ae4 --- /dev/null +++ b/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceProtocolTerm.java @@ -0,0 +1,34 @@ +package org.jetlinks.community.device.service.term; + +import org.hswebframework.ezorm.core.param.Term; +import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata; +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.term.AbstractTermFragmentBuilder; +import org.springframework.stereotype.Component; + +import java.util.List; + + +@Component +public class DeviceProtocolTerm extends AbstractTermFragmentBuilder { + public DeviceProtocolTerm() { + super("dev-protocol", "按协议查询设备"); + } + + @Override + public SqlFragments createFragments(String columnFullName, RDBColumnMetadata column, Term term) { + PrepareSqlFragments sqlFragments = PrepareSqlFragments.of(); + List idList = convertList(column, term); + if (term.getOptions().contains("not")) { + sqlFragments.addSql("not"); + } + sqlFragments + .addSql("exists(select 1 from ",getTableName("dev_product",column)," _product where _product.id = " + columnFullName); + sqlFragments + .addSql(" and _product.message_protocol = ?"); + sqlFragments.addSql(")").addParameter(idList); + + return sqlFragments; + } +} diff --git a/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceTypeTerm.java b/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceTypeTerm.java new file mode 100755 index 00000000..2b42a7e0 --- /dev/null +++ b/jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/term/DeviceTypeTerm.java @@ -0,0 +1,37 @@ +package org.jetlinks.community.device.service.term; + +import org.hswebframework.ezorm.core.param.Term; +import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata; +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.term.AbstractTermFragmentBuilder; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Collectors; + + +@Component +public class DeviceTypeTerm extends AbstractTermFragmentBuilder { + public DeviceTypeTerm() { + super("dev-device-type", "按设备类型查询设备"); + } + + @Override + public SqlFragments createFragments(String columnFullName, RDBColumnMetadata column, Term term) { + PrepareSqlFragments sqlFragments = PrepareSqlFragments.of(); + List idList = convertList(column, term); + if (term.getOptions().contains("not")) { + sqlFragments.addSql("not"); + } + sqlFragments + .addSql("exists(select 1 from ",getTableName("dev_product",column)," _product where _product.id = " + columnFullName); + sqlFragments + .addSql(" and _product.device_type in("); + sqlFragments.addSql(idList.stream().map(str -> "?").collect(Collectors.joining(","))) + .addParameter(idList) + .addSql("))"); + + return sqlFragments; + } +}