Selaa lähdekoodia

Merge remote-tracking branch 'origin/master'

zhouhao 2 vuotta sitten
vanhempi
commit
a2cd2688cb

+ 2 - 1
README.md

@@ -6,7 +6,8 @@
 ![Version](https://img.shields.io/badge/version-1.20--RELEASE-brightgreen)
 ![Version](https://img.shields.io/badge/version-1.20--RELEASE-brightgreen)
 [![Codacy Badge](https://api.codacy.com/project/badge/Grade/e8d527d692c24633aba4f869c1c5d6ad)](https://app.codacy.com/gh/jetlinks/jetlinks-community?utm_source=github.com&utm_medium=referral&utm_content=jetlinks/jetlinks-community&utm_campaign=Badge_Grade_Settings)
 [![Codacy Badge](https://api.codacy.com/project/badge/Grade/e8d527d692c24633aba4f869c1c5d6ad)](https://app.codacy.com/gh/jetlinks/jetlinks-community?utm_source=github.com&utm_medium=referral&utm_content=jetlinks/jetlinks-community&utm_campaign=Badge_Grade_Settings)
 [![OSCS Status](https://www.oscs1024.com/platform/badge/jetlinks/jetlinks-community.svg?size=small)](https://www.oscs1024.com/project/jetlinks/jetlinks-community?ref=badge_small)
 [![OSCS Status](https://www.oscs1024.com/platform/badge/jetlinks/jetlinks-community.svg?size=small)](https://www.oscs1024.com/project/jetlinks/jetlinks-community?ref=badge_small)
-![jetlinks](https://visitor-badge.glitch.me/badge?page_id=jetlinks)
+[![star](https://img.shields.io/github/stars/jetlinks/jetlinks-community?style=social)](https://github.com/jetlinks/jetlinks-community)
+[![star](https://gitee.com/jetlinks/jetlinks-community/badge/star.svg?theme=gvp)](https://gitee.com/jetlinks/jetlinks-community/stargazers)
 
 
 [![QQ①群2021514](https://img.shields.io/badge/QQ①群-2021514-brightgreen)](https://qm.qq.com/cgi-bin/qm/qr?k=LGf0OPQqvLGdJIZST3VTcypdVWhdfAOG&jump_from=webapi)
 [![QQ①群2021514](https://img.shields.io/badge/QQ①群-2021514-brightgreen)](https://qm.qq.com/cgi-bin/qm/qr?k=LGf0OPQqvLGdJIZST3VTcypdVWhdfAOG&jump_from=webapi)
 [![QQ②群324606263](https://img.shields.io/badge/QQ②群-324606263-brightgreen)](https://qm.qq.com/cgi-bin/qm/qr?k=IMas2cH-TNsYxUcY8lRbsXqPnA2sGHYQ&jump_from=webapi)
 [![QQ②群324606263](https://img.shields.io/badge/QQ②群-324606263-brightgreen)](https://qm.qq.com/cgi-bin/qm/qr?k=IMas2cH-TNsYxUcY8lRbsXqPnA2sGHYQ&jump_from=webapi)

+ 2 - 2
docker/run-all/docker-compose.yml

@@ -48,7 +48,7 @@ services:
       POSTGRES_DB: jetlinks
       POSTGRES_DB: jetlinks
       TZ: Asia/Shanghai
       TZ: Asia/Shanghai
   ui:
   ui:
-    image: registry.cn-shenzhen.aliyuncs.com/jetlinks/jetlinks-ui-pro:2.0.0
+    image: registry.cn-shenzhen.aliyuncs.com/jetlinks/jetlinks-ui-vue:2.1.0-SNAPSHOT
     container_name: jetlinks-ce-ui
     container_name: jetlinks-ce-ui
     ports:
     ports:
       - 9000:80
       - 9000:80
@@ -59,7 +59,7 @@ services:
     links:
     links:
       - jetlinks:jetlinks
       - jetlinks:jetlinks
   jetlinks:
   jetlinks:
-    image: registry.cn-shenzhen.aliyuncs.com/jetlinks/jetlinks-standalone:2.0.0-SNAPSHOT
+    image: registry.cn-shenzhen.aliyuncs.com/jetlinks/jetlinks-standalone:2.1.0-SNAPSHOT
     container_name: jetlinks-ce
     container_name: jetlinks-ce
 
 
     ports:
     ports:

+ 5 - 1
jetlinks-components/notify-component/notify-sms/src/main/java/org/jetlinks/community/notify/sms/aliyun/AliyunSmsTemplate.java

@@ -1,6 +1,7 @@
 package org.jetlinks.community.notify.sms.aliyun;
 package org.jetlinks.community.notify.sms.aliyun;
 
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
+import com.google.common.collect.Maps;
 import lombok.Getter;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.Setter;
 import org.jetlinks.core.metadata.types.StringType;
 import org.jetlinks.core.metadata.types.StringType;
@@ -64,7 +65,10 @@ public class AliyunSmsTemplate extends AbstractTemplate<AliyunSmsTemplate> {
     }
     }
 
 
     public String createTtsParam(Map<String, Object> ctx) {
     public String createTtsParam(Map<String, Object> ctx) {
-        return JSON.toJSONString(ctx);
+        Map<String, VariableDefinition> variables = getVariables();
+        return JSON.toJSONString(Maps.filterEntries(
+            renderMap(ctx),
+            e -> variables.containsKey(e.getKey())));
     }
     }
 
 
     @Override
     @Override

+ 35 - 0
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/response/ResetDeviceConfigurationResult.java

@@ -0,0 +1,35 @@
+package org.jetlinks.community.device.response;
+
+import lombok.*;
+import org.hswebframework.ezorm.rdb.mapping.defaults.SaveResult;
+
+/**
+ * @see ImportDeviceInstanceResult 结构一致方便前端处理
+ */
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+public class ResetDeviceConfigurationResult {
+
+    private SaveResult result;
+
+    private boolean success;
+
+    private String message;
+
+    @Generated
+    public static ResetDeviceConfigurationResult success(SaveResult result) {
+        return new ResetDeviceConfigurationResult(result, true, null);
+    }
+
+    @Generated
+    public static ResetDeviceConfigurationResult error(String message) {
+        return new ResetDeviceConfigurationResult(null, false, message);
+    }
+
+    @Generated
+    public static ResetDeviceConfigurationResult error(Throwable message) {
+        return error(message.getMessage());
+    }
+}

+ 13 - 0
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/DefaultDeviceConfigMetadataManager.java

@@ -7,11 +7,15 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.CollectionUtils;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
 
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nonnull;
 import java.util.Comparator;
 import java.util.Comparator;
+import java.util.HashSet;
 import java.util.List;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.stream.Collectors;
 
 
 @Component
 @Component
 @Slf4j
 @Slf4j
@@ -81,6 +85,15 @@ public class DefaultDeviceConfigMetadataManager implements DeviceConfigMetadataM
     }
     }
 
 
     @Override
     @Override
+    public Mono<Set<String>> getProductConfigMetadataProperties(String productId) {
+        return this
+            .getProductConfigMetadata(productId)
+            .flatMapIterable(ConfigMetadata::getProperties)
+            .map(ConfigPropertyMetadata::getProperty)
+            .collect(Collectors.toSet());
+    }
+
+    @Override
     public Object postProcessAfterInitialization(@Nonnull Object bean, @Nonnull String beanName) {
     public Object postProcessAfterInitialization(@Nonnull Object bean, @Nonnull String beanName) {
         if (bean instanceof DeviceConfigMetadataSupplier) {
         if (bean instanceof DeviceConfigMetadataSupplier) {
             register(((DeviceConfigMetadataSupplier) bean));
             register(((DeviceConfigMetadataSupplier) bean));

+ 10 - 0
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/DeviceConfigMetadataManager.java

@@ -6,6 +6,9 @@ import org.jetlinks.community.device.spi.DeviceConfigMetadataSupplier;
 import org.jetlinks.core.message.codec.Transport;
 import org.jetlinks.core.message.codec.Transport;
 import org.jetlinks.core.metadata.*;
 import org.jetlinks.core.metadata.*;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.util.Set;
 
 
 
 
 /**
 /**
@@ -75,6 +78,13 @@ public interface DeviceConfigMetadataManager {
                                                   String typeId,
                                                   String typeId,
                                                   ConfigScope... scopes);
                                                   ConfigScope... scopes);
 
 
+    /**
+     * 根据产品ID获取产品所需配置信息
+     *
+     * @param productId 产品ID
+     * @return 配置property集合
+     */
+    Mono<Set<String>> getProductConfigMetadataProperties(String productId);
 
 
     /**
     /**
      * 根据产品ID和网关ID获取配置信息
      * 根据产品ID和网关ID获取配置信息

+ 81 - 38
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/LocalDeviceInstanceService.java

@@ -17,7 +17,17 @@ import org.hswebframework.web.exception.I18nSupportException;
 import org.hswebframework.web.exception.TraceSourceException;
 import org.hswebframework.web.exception.TraceSourceException;
 import org.hswebframework.web.i18n.LocaleUtils;
 import org.hswebframework.web.i18n.LocaleUtils;
 import org.hswebframework.web.id.IDGenerator;
 import org.hswebframework.web.id.IDGenerator;
+import org.jetlinks.community.device.entity.*;
+import org.jetlinks.community.device.enums.DeviceState;
+import org.jetlinks.community.device.events.DeviceDeployedEvent;
+import org.jetlinks.community.device.events.DeviceUnregisterEvent;
+import org.jetlinks.community.device.response.DeviceDeployResult;
 import org.jetlinks.community.device.response.DeviceDetail;
 import org.jetlinks.community.device.response.DeviceDetail;
+import org.jetlinks.community.device.response.ResetDeviceConfigurationResult;
+import org.jetlinks.community.relation.RelationObjectProvider;
+import org.jetlinks.community.relation.service.RelationService;
+import org.jetlinks.community.relation.service.response.RelatedInfo;
+import org.jetlinks.community.utils.ErrorUtils;
 import org.jetlinks.core.device.DeviceConfigKey;
 import org.jetlinks.core.device.DeviceConfigKey;
 import org.jetlinks.core.device.DeviceOperator;
 import org.jetlinks.core.device.DeviceOperator;
 import org.jetlinks.core.device.DeviceProductOperator;
 import org.jetlinks.core.device.DeviceProductOperator;
@@ -36,15 +46,6 @@ import org.jetlinks.core.metadata.ConfigMetadata;
 import org.jetlinks.core.metadata.DeviceMetadata;
 import org.jetlinks.core.metadata.DeviceMetadata;
 import org.jetlinks.core.metadata.MergeOption;
 import org.jetlinks.core.metadata.MergeOption;
 import org.jetlinks.core.utils.CyclicDependencyChecker;
 import org.jetlinks.core.utils.CyclicDependencyChecker;
-import org.jetlinks.community.device.entity.*;
-import org.jetlinks.community.device.enums.DeviceState;
-import org.jetlinks.community.device.events.DeviceDeployedEvent;
-import org.jetlinks.community.device.events.DeviceUnregisterEvent;
-import org.jetlinks.community.device.response.DeviceDeployResult;
-import org.jetlinks.community.relation.RelationObjectProvider;
-import org.jetlinks.community.relation.service.RelationService;
-import org.jetlinks.community.relation.service.response.RelatedInfo;
-import org.jetlinks.community.utils.ErrorUtils;
 import org.jetlinks.reactor.ql.utils.CastUtils;
 import org.jetlinks.reactor.ql.utils.CastUtils;
 import org.jetlinks.supports.official.JetLinksDeviceMetadataCodec;
 import org.jetlinks.supports.official.JetLinksDeviceMetadataCodec;
 import org.reactivestreams.Publisher;
 import org.reactivestreams.Publisher;
@@ -121,6 +122,47 @@ public class LocalDeviceInstanceService extends GenericReactiveCrudService<Devic
             .as(super::save);
             .as(super::save);
     }
     }
 
 
+    private Flux<DeviceInstanceEntity> findByProductId(String productId) {
+        return createQuery()
+            .and(DeviceInstanceEntity::getProductId, productId)
+            .fetch();
+    }
+
+    private Set<String> getProductConfigurationProperties(DeviceProductEntity product) {
+        if (MapUtils.isNotEmpty(product.getConfiguration())) {
+            return product.getConfiguration()
+                          .keySet();
+        }
+        return new HashSet<>();
+    }
+
+    private Mono<Map<String, Object>> resetConfiguration(DeviceProductEntity product, DeviceInstanceEntity device) {
+        return metadataManager
+            .getProductConfigMetadataProperties(product.getId())
+            .defaultIfEmpty(getProductConfigurationProperties(product))
+            .flatMap(set -> {
+                if (set.size() > 0) {
+                    if (MapUtils.isNotEmpty(device.getConfiguration())) {
+                        set.forEach(device.getConfiguration()::remove);
+                    }
+                    //重置注册中心里的配置
+                    return registry
+                        .getDevice(device.getId())
+                        .flatMap(opts -> opts.removeConfigs(set))
+                        .then();
+                }
+                return Mono.empty();
+            })
+            .then(
+                //更新数据库
+                createUpdate()
+                    .set(device::getConfiguration)
+                    .where(device::getId)
+                    .execute()
+            )
+            .then(Mono.fromSupplier(device::getConfiguration));
+    }
+
     /**
     /**
      * 重置设备配置
      * 重置设备配置
      *
      *
@@ -135,36 +177,37 @@ public class LocalDeviceInstanceService extends GenericReactiveCrudService<Devic
             .flatMap(tp2 -> {
             .flatMap(tp2 -> {
                 DeviceProductEntity product = tp2.getT2();
                 DeviceProductEntity product = tp2.getT2();
                 DeviceInstanceEntity device = tp2.getT1();
                 DeviceInstanceEntity device = tp2.getT1();
-                return Mono
-                    .defer(() -> {
-                        if (MapUtils.isNotEmpty(product.getConfiguration())) {
-                            if (MapUtils.isNotEmpty(device.getConfiguration())) {
-                                product.getConfiguration()
-                                       .keySet()
-                                       .forEach(device.getConfiguration()::remove);
-                            }
-                            //重置注册中心里的配置
-                            return registry
-                                .getDevice(deviceId)
-                                .flatMap(opts -> opts.removeConfigs(product.getConfiguration().keySet()))
-                                .then();
-                        }
-                        return Mono.empty();
-                    })
-                    .then(
-                        Mono.defer(() -> {
-                            //更新数据库
-                            return createUpdate()
-                                .when(device.getConfiguration() != null, update -> update.set(device::getConfiguration))
-                                .when(device.getConfiguration() == null, update -> update.setNull(DeviceInstanceEntity::getConfiguration))
-                                .where(device::getId)
-                                .execute();
-                        })
-                    )
-                    .then(Mono.fromSupplier(device::getConfiguration));
+                return resetConfiguration(product, device);
             })
             })
-            .defaultIfEmpty(Collections.emptyMap())
-            ;
+            .defaultIfEmpty(Collections.emptyMap());
+    }
+
+    public Mono<Long> resetConfiguration(Flux<String> payload) {
+        return payload
+            .flatMap(deviceId -> resetConfiguration(deviceId)).count();
+    }
+
+    /**
+     * 重置设备配置信息(根据产品批量重置,性能欠佳,慎用)
+     *
+     * @param productId 产品ID
+     * @return 数量
+     */
+    public Flux<ResetDeviceConfigurationResult> resetConfigurationByProductId(String productId) {
+        return deviceProductService
+            .findById(productId)
+            .flatMapMany(product -> this
+                .findByProductId(productId)
+                .flatMap(device -> {
+                    return resetConfiguration(product, device)
+                        .thenReturn(ResetDeviceConfigurationResult
+                            .success(SaveResult.of(0, 1)))
+                        .onErrorResume(throwable -> {
+                            String message = device.getId() + ":" + throwable.getMessage();
+                            return Mono.just(ResetDeviceConfigurationResult.error(message));
+                        });
+                })
+            );
     }
     }
 
 
     /**
     /**

+ 18 - 0
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/web/DeviceInstanceController.java

@@ -31,6 +31,7 @@ import org.jetlinks.community.device.enums.DeviceState;
 import org.jetlinks.community.device.response.DeviceDeployResult;
 import org.jetlinks.community.device.response.DeviceDeployResult;
 import org.jetlinks.community.device.response.DeviceDetail;
 import org.jetlinks.community.device.response.DeviceDetail;
 import org.jetlinks.community.device.response.ImportDeviceInstanceResult;
 import org.jetlinks.community.device.response.ImportDeviceInstanceResult;
+import org.jetlinks.community.device.response.ResetDeviceConfigurationResult;
 import org.jetlinks.community.device.service.DeviceConfigMetadataManager;
 import org.jetlinks.community.device.service.DeviceConfigMetadataManager;
 import org.jetlinks.community.device.service.LocalDeviceInstanceService;
 import org.jetlinks.community.device.service.LocalDeviceInstanceService;
 import org.jetlinks.community.device.service.LocalDeviceProductService;
 import org.jetlinks.community.device.service.LocalDeviceProductService;
@@ -205,6 +206,23 @@ public class DeviceInstanceController implements
         return service.resetConfiguration(deviceId);
         return service.resetConfiguration(deviceId);
     }
     }
 
 
+    @PutMapping("/configuration/_reset/ids")
+    @SaveAction
+    @Operation(summary = "重置设备配置信息(根据设备ID批量重置,性能欠佳,慎用)")
+    public Mono<Long> resetConfigurationBatch(@RequestBody Flux<String> payload) {
+        return service.resetConfiguration(payload);
+    }
+
+    @GetMapping(value = "/configuration/_reset/{productId:.+}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
+    @ResourceAction(
+        id = "batchResetConf",
+        name = "批量重置设备配置信息"
+    )
+    @Operation(summary = "重置设备配置信息(根据产品批量重置,性能欠佳,慎用)")
+    public Flux<ResetDeviceConfigurationResult> resetConfigurationBatch(@PathVariable @Parameter(description = "产品ID") String productId) {
+        return service.resetConfigurationByProductId(productId);
+    }
+
     //批量激活设备
     //批量激活设备
     @GetMapping(value = "/deploy", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
     @GetMapping(value = "/deploy", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
     @SaveAction
     @SaveAction