Jelajahi Sumber

产品分类支持

ayan 2 tahun lalu
induk
melakukan
d5d3c0dd9d

+ 0 - 30
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/entity/DeviceCategory.java

@@ -1,30 +0,0 @@
-package org.jetlinks.community.device.entity;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Getter;
-import lombok.Setter;
-import org.hswebframework.web.api.crud.entity.GenericTreeSortSupportEntity;
-
-import java.util.List;
-
-@Getter
-@Setter
-public class DeviceCategory extends GenericTreeSortSupportEntity<String> {
-
-    @Schema(description = "ID")
-    private String id;
-
-    @Schema(description = "标识")
-    private String key;
-
-    @Schema(description = "名称")
-    private String name;
-
-    @Schema(description = "父节点标识")
-    private String parentId;
-
-    @Schema(description = "子节点")
-    private List<DeviceCategory> children;
-
-
-}

+ 79 - 0
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/entity/DeviceCategoryEntity.java

@@ -0,0 +1,79 @@
+package org.jetlinks.community.device.entity;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+import org.hswebframework.ezorm.rdb.mapping.annotation.ColumnType;
+import org.hswebframework.ezorm.rdb.mapping.annotation.Comment;
+import org.hswebframework.ezorm.rdb.mapping.annotation.DefaultValue;
+import org.hswebframework.web.api.crud.entity.GenericTreeSortSupportEntity;
+import org.hswebframework.web.api.crud.entity.RecordCreationEntity;
+import org.hswebframework.web.crud.annotation.EnableEntityEvent;
+import org.hswebframework.web.crud.generator.Generators;
+import org.hswebframework.web.validator.CreateGroup;
+
+import javax.persistence.Column;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Pattern;
+import java.sql.JDBCType;
+import java.util.List;
+
+@Getter
+@Setter
+@Table(name = "dev_product_category")
+@Comment("产品分类信息表")
+@EnableEntityEvent
+public class DeviceCategoryEntity extends GenericTreeSortSupportEntity<String> implements RecordCreationEntity {
+
+    @Override
+    @Id
+    @Column(length = 64, updatable = false)
+    @GeneratedValue(generator = Generators.SNOW_FLAKE)
+    @NotBlank(message = "ID不能为空", groups = CreateGroup.class)
+    @Pattern(regexp = "^[0-9a-zA-Z_\\-|]+$", message = "ID只能由数字,字母,下划线和中划线组成", groups = CreateGroup.class)
+    public String getId() {
+        return super.getId();
+    }
+
+    @Schema(description = "标识")
+    @Column(nullable = false,length = 64)
+    @NotBlank(message = "标识不能为空", groups = CreateGroup.class)
+    @GeneratedValue(generator = Generators.SNOW_FLAKE)
+    @Pattern(regexp = "^[0-9a-zA-Z_\\-]+$", message = "分类标识只能由数字,字母,下划线和中划线组成")
+    private String key;
+
+    @Schema(description = "名称")
+    @Column(nullable = false)
+    @NotBlank
+    private String name;
+
+    @Schema(description = "说明")
+    @Column
+    private String description;
+
+    @Schema(description = "子节点")
+    private List<DeviceCategoryEntity> children;
+
+    @Schema(description = "物模型")
+    @Column
+    @ColumnType(javaType = String.class, jdbcType = JDBCType.CLOB)
+    private String metadata;
+
+    @Column(updatable = false)
+    @Schema(
+        description = "创建者ID(只读)"
+        , accessMode = Schema.AccessMode.READ_ONLY
+    )
+    private String creatorId;
+
+    @Column(updatable = false)
+    @DefaultValue(generator = Generators.CURRENT_TIME)
+    @Schema(
+        description = "创建时间(只读)"
+        , accessMode = Schema.AccessMode.READ_ONLY
+    )
+    private Long createTime;
+}

+ 80 - 0
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/service/DeviceCategoryService.java

@@ -0,0 +1,80 @@
+package org.jetlinks.community.device.service;
+
+import com.alibaba.fastjson.JSON;
+import org.hswebframework.web.api.crud.entity.TreeSupportEntity;
+import org.hswebframework.web.crud.service.GenericReactiveTreeSupportCrudService;
+import org.hswebframework.web.id.IDGenerator;
+import org.jetlinks.community.device.entity.DeviceCategoryEntity;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StreamUtils;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+@Service
+public class DeviceCategoryService extends GenericReactiveTreeSupportCrudService<DeviceCategoryEntity, String> implements CommandLineRunner {
+
+    @Override
+    public IDGenerator<String> getIDGenerator() {
+        return IDGenerator.MD5;
+    }
+
+    private static final String category_splitter = "-";
+    @Override
+    public void setChildren(DeviceCategoryEntity entity, List<DeviceCategoryEntity> children) {
+        entity.setChildren(children);
+    }
+
+    @Override
+    public void run(String... args) {
+        this
+            .createQuery()
+            .fetchOne()
+            .switchIfEmpty(initDefaultData().then(Mono.empty()))
+            .subscribe();
+    }
+
+
+    static void rebuild(String parentId, List<DeviceCategoryEntity> children) {
+        if (children == null) {
+            return;
+        }
+        for (DeviceCategoryEntity child : children) {
+            String id = child.getId();
+            child.setId(parentId + category_splitter + id +category_splitter);
+            child.setParentId(parentId +category_splitter);
+            rebuild(parentId + category_splitter + id, child.getChildren());
+        }
+    }
+
+    private Mono<Void> initDefaultData() {
+        return Mono
+            .fromCallable(() -> {
+                ClassPathResource resource = new ClassPathResource("device-category.json");
+
+                try (InputStream stream = resource.getInputStream()) {
+                    String json = StreamUtils.copyToString(stream, StandardCharsets.UTF_8);
+
+                    List<DeviceCategoryEntity> all = JSON.parseArray(json, DeviceCategoryEntity.class);
+
+                    List<DeviceCategoryEntity> root = TreeSupportEntity.list2tree(all, DeviceCategoryEntity::setChildren);
+
+                    for (DeviceCategoryEntity category : root) {
+                        String id = category.getId();
+                        category.setId(category_splitter + id + category_splitter);
+                        category.setParentId(category_splitter + category.getParentId() + category_splitter);
+                        rebuild(category_splitter + id, category.getChildren());
+                    }
+                    return root;
+                }
+
+            })
+            .flatMap(all -> save(Flux.fromIterable(all)))
+            .then();
+    }
+}

+ 50 - 63
jetlinks-manager/device-manager/src/main/java/org/jetlinks/community/device/web/DeviceCategoryController.java

@@ -1,85 +1,72 @@
 package org.jetlinks.community.device.web;
 
-import com.alibaba.fastjson.JSON;
-import io.swagger.v3.oas.annotations.Operation;
+
+import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.hswebframework.web.api.crud.entity.QueryNoPagingOperation;
+import org.hswebframework.web.api.crud.entity.QueryParamEntity;
 import org.hswebframework.web.api.crud.entity.TreeSupportEntity;
-import org.jetlinks.community.device.entity.DeviceCategory;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.util.StreamUtils;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.authorization.annotation.Resource;
+import org.hswebframework.web.crud.service.ReactiveCrudService;
+import org.hswebframework.web.crud.web.reactive.ReactiveServiceCrudController;
+import org.jetlinks.community.device.entity.DeviceCategoryEntity;
+import org.jetlinks.community.device.service.DeviceCategoryService;
+import org.springframework.web.bind.annotation.*;
 import reactor.core.publisher.Flux;
-
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
+import reactor.core.publisher.Mono;
 
 @RestController
 @RequestMapping("/device/category")
 @Slf4j
-@Tag(name = "设备分类目录")
-public class DeviceCategoryController {
+@Tag(name = "产品分类管理")
+@AllArgsConstructor
+@Resource(id="device-category",name = "产品分类")
+public class DeviceCategoryController implements ReactiveServiceCrudController<DeviceCategoryEntity,String> {
 
 
-    static List<DeviceCategory> statics;
+    private final DeviceCategoryService categoryService;
 
-
-    static void rebuild(String parentId, List<DeviceCategory> children) {
-        if (children == null) {
-            return;
-        }
-        for (DeviceCategory child : children) {
-            String id = child.getId();
-            child.setId(parentId + "|" + id + "|");
-            child.setParentId(parentId + "|");
-            rebuild(parentId + "|" + id, child.getChildren());
-        }
+    @GetMapping
+    @QueryNoPagingOperation(summary = "获取全部分类")
+    @Authorize(merge = false)
+    public Flux<DeviceCategoryEntity> getAllCategory(@Parameter(hidden = true) QueryParamEntity query) {
+        return this
+            .categoryService
+            .createQuery()
+            .setParam(query)
+            .fetch();
     }
 
-    static {
-        try {
-            ClassPathResource resource = new ClassPathResource("device-category.json");
-            String json = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);
-
-            List<DeviceCategory> all = JSON.parseArray(json, DeviceCategory.class);
-
-            List<DeviceCategory> root = TreeSupportEntity.list2tree(all, DeviceCategory::setChildren);
-
-            for (DeviceCategory category : root) {
-                String id = category.getId();
-
-                category.setId("|" + id + "|");
-                category.setParentId("|" + category.getParentId() + "|");
-                rebuild("|" + id, category.getChildren());
-            }
-
-            statics = all;
-
-        } catch (Exception e) {
-            statics = new ArrayList<>();
-            DeviceCategoryController.log.error(e.getMessage(), e);
-        }
+    @GetMapping("/_tree")
+    @QueryNoPagingOperation(summary = "获取全部分类(树结构)")
+    @Authorize(merge = false)
+    public Flux<DeviceCategoryEntity> getAllCategoryTree(@Parameter(hidden = true) QueryParamEntity query) {
+        return this
+            .categoryService
+            .createQuery()
+            .setParam(query)
+            .fetch()
+            .collectList()
+            .flatMapMany(all-> Flux.fromIterable(TreeSupportEntity.list2tree(all, DeviceCategoryEntity::setChildren)));
     }
 
-    @GetMapping
-    @Operation(summary = "获取全部分类目录")
-    public Flux<DeviceCategory> getAllCategory() {
-        return Flux.fromIterable(statics);
-    }
 
-    @GetMapping("/_query/no-paging")
-    @Operation(summary = "获取全部分类目录")
-    public Flux<DeviceCategory> getAllCategory2() {
-        return Flux.fromIterable(statics);
+    @PostMapping("/_tree")
+    @QueryNoPagingOperation(summary = "获取全部分类(树结构)")
+    @Authorize(merge = false)
+    public Flux<DeviceCategoryEntity> getAllCategoryTreeByQueryParam(@RequestBody Mono<QueryParamEntity> query) {
+        return this
+            .categoryService
+            .query(query)
+            .collectList()
+            .flatMapMany(all-> Flux.fromIterable(TreeSupportEntity.list2tree(all, DeviceCategoryEntity::setChildren)));
     }
 
-
-    @GetMapping("/_tree")
-    @Operation(summary = "获取全部分类目录(树结构)")
-    public Flux<DeviceCategory> getAllCategoryTree() {
-        return Flux.fromIterable(TreeSupportEntity.list2tree(statics, DeviceCategory::setChildren));
+    @Override
+    public ReactiveCrudService<DeviceCategoryEntity, String> getService() {
+        return categoryService;
     }
 }