diff --git a/jetlinks-components/notify-component/notify-sms/src/main/java/org/jetlinks/community/notify/sms/aliyun/AliyunSmsNotifier.java b/jetlinks-components/notify-component/notify-sms/src/main/java/org/jetlinks/community/notify/sms/aliyun/AliyunSmsNotifier.java index 31703361f5cd249b20c709b68b59137b7d808cb1..89ba7e9d028d7a939381e8ad73be4d1dc3b851e1 100755 --- a/jetlinks-components/notify-component/notify-sms/src/main/java/org/jetlinks/community/notify/sms/aliyun/AliyunSmsNotifier.java +++ b/jetlinks-components/notify-component/notify-sms/src/main/java/org/jetlinks/community/notify/sms/aliyun/AliyunSmsNotifier.java @@ -32,7 +32,10 @@ import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; import javax.annotation.Nonnull; +import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; import java.util.stream.Collectors; @Slf4j @@ -164,24 +167,49 @@ public class AliyunSmsNotifier extends AbstractNotifier { * @return 短信签名集合 */ public Flux getSmsSigns() { - return Mono - .fromCallable(() -> client.getAcsResponse(new QuerySmsSignListRequest())) - .flatMapIterable(QuerySmsSignListResponse::getSmsSignList) + return doQuerySmsSigns(new AtomicInteger(0), 50) + .flatMapIterable(Function.identity()) .map(SmsSign::of) .as(FluxTracer.create("/aliyun/sms/sign")) .onErrorResume(err -> Mono.empty()); } - /** - * @return 短信模板集合 - */ + + public Flux getSmsTemplates() { - return Mono - .fromCallable(() -> client.getAcsResponse(new QuerySmsTemplateListRequest())) - .flatMapIterable(QuerySmsTemplateListResponse::getSmsTemplateList) + return doQuerySmsTemplates(new AtomicInteger(0), 50) + .flatMapIterable(Function.identity()) .map(SmsTemplate::of) .as(FluxTracer.create("/aliyun/sms/template")) .onErrorResume(err -> Mono.empty()); + } + + public Flux> doQuerySmsSigns(AtomicInteger pageIndex, int pageSize) { + QuerySmsSignListRequest request = new QuerySmsSignListRequest(); + request.setPageSize(pageSize); + request.setPageIndex(pageIndex.incrementAndGet()); + return Mono + .fromCallable(() -> client.getAcsResponse(request).getSmsSignList()) + .expand(dtos -> { + if (dtos.size() == pageSize){ + return doQuerySmsSigns(pageIndex, pageSize); + } + return Flux.empty(); + }); + } + + public Flux> doQuerySmsTemplates(AtomicInteger pageIndex, int pageSize) { + QuerySmsTemplateListRequest request = new QuerySmsTemplateListRequest(); + request.setPageSize(pageSize); + request.setPageIndex(pageIndex.incrementAndGet()); + return Mono + .fromCallable(() -> client.getAcsResponse(request).getSmsTemplateList()) + .expand(dtos -> { + if (dtos.size() == pageSize){ + return doQuerySmsTemplates(pageIndex, pageSize); + } + return Flux.empty(); + }); } } 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 0000000000000000000000000000000000000000..b9f5e5510e14482e93b15e57011681dee28bf2ac --- /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 0000000000000000000000000000000000000000..bee5e6d7d79073d9e0127ae78d148590c94ed908 --- /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 0000000000000000000000000000000000000000..37179c71b493fe44298dfea75ba35a16d513b9af --- /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 0000000000000000000000000000000000000000..b4e86ae4dac3a0e16dfc4446af23a905111f7a8d --- /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 0000000000000000000000000000000000000000..2b42a7e0c30763e6a4fe1a65f0be260039374adc --- /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; + } +}