Преглед на файлове

version 1.1: id string and relation; hibernate relation

huodongdong преди 7 години
родител
ревизия
d69395e6a7
променени са 82 файла, в които са добавени 2880 реда и са изтрити 491 реда
  1. 6 0
      pom.xml
  2. 11 0
      rankin-common-utils/pom.xml
  3. 1 1
      rankin-common-utils/src/main/java/cn/rankin/common/utils/entity/Cache.java
  4. 1 1
      rankin-common-utils/src/main/java/cn/rankin/common/utils/entity/api/APICode.java
  5. 15 1
      rankin-common-utils/src/main/java/cn/rankin/common/utils/entity/api/APICodeManager.java
  6. 1 1
      rankin-common-utils/src/main/java/cn/rankin/common/utils/entity/api/APIResult.java
  7. 1 2
      rankin-common-utils/src/main/java/cn/rankin/common/utils/entity/page/Page.java
  8. 1 1
      rankin-common-utils/src/main/java/cn/rankin/common/utils/entity/page/Pageable.java
  9. 41 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/CourseDTO.java
  10. 33 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/ItemDTO.java
  11. 26 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/ItemPriceDTO.java
  12. 23 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/LessonDTO.java
  13. 14 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/SubRelationDTO.java
  14. 30 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/SupportDTO.java
  15. 25 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/TagDTO.java
  16. 31 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/WareDTO.java
  17. 26 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/search/ItemSearchDTO.java
  18. 25 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/search/SearchDTO.java
  19. 6 3
      rankin-common-utils/src/main/java/cn/rankin/common/utils/entity/dto/ResourceSearchDTO.java
  20. 1 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/enums/BaseOrderEnum.java
  21. 20 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/enums/CourseSubTypeEnum.java
  22. 20 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/enums/ItemStatusEnum.java
  23. 21 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/enums/PriceTypeEnum.java
  24. 19 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/enums/TagTypeEnum.java
  25. 31 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/enums/WareTypeEnum.java
  26. 145 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/jpa/BasicJpaRepository.java
  27. 365 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/jpa/SimpleJpaRepository.java
  28. 49 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/util/ListToMapUtil.java
  29. 1 1
      rankin-common-utils/src/main/java/cn/rankin/common/utils/util/LocalCache.java
  30. 5 2
      rankin-common-utils/src/main/java/cn/rankin/common/utils/util/SecurityUtil.java
  31. 12 12
      rankin-product-service/pom.xml
  32. 3 0
      rankin-product-service/src/main/java/cn/rankin/productservice/ProductServiceApplication.java
  33. 84 0
      rankin-product-service/src/main/java/cn/rankin/productservice/controller/CourseController.java
  34. 73 0
      rankin-product-service/src/main/java/cn/rankin/productservice/controller/ItemController.java
  35. 73 0
      rankin-product-service/src/main/java/cn/rankin/productservice/controller/LessonController.java
  36. 74 0
      rankin-product-service/src/main/java/cn/rankin/productservice/controller/SupportController.java
  37. 72 0
      rankin-product-service/src/main/java/cn/rankin/productservice/controller/TagController.java
  38. 0 21
      rankin-product-service/src/main/java/cn/rankin/productservice/controller/TestController.java
  39. 79 0
      rankin-product-service/src/main/java/cn/rankin/productservice/controller/WareController.java
  40. 0 52
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/Combo.java
  41. 27 8
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/Course.java
  42. 15 12
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/CourseSubRelation.java
  43. 0 34
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/CourseSupportRelation.java
  44. 0 34
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/CourseTagRelation.java
  45. 33 14
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/Item.java
  46. 19 15
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/ItemPrice.java
  47. 16 10
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/Lesson.java
  48. 11 11
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/LessonWareRelation.java
  49. 53 0
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/Package.java
  50. 16 12
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/Support.java
  51. 9 11
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/SupportCircleRelation.java
  52. 16 13
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/Tag.java
  53. 0 46
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/Unit.java
  54. 0 34
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/UnitLessonRelation.java
  55. 17 10
      rankin-product-service/src/main/java/cn/rankin/productservice/entity/Ware.java
  56. 0 11
      rankin-product-service/src/main/java/cn/rankin/productservice/repository/BasicRepository.java
  57. 21 0
      rankin-product-service/src/main/java/cn/rankin/productservice/repository/CourseRepository.java
  58. 16 0
      rankin-product-service/src/main/java/cn/rankin/productservice/repository/CourseSubRelationRepository.java
  59. 14 0
      rankin-product-service/src/main/java/cn/rankin/productservice/repository/ItemPriceRepository.java
  60. 18 0
      rankin-product-service/src/main/java/cn/rankin/productservice/repository/ItemRepository.java
  61. 15 0
      rankin-product-service/src/main/java/cn/rankin/productservice/repository/LessonRepository.java
  62. 23 0
      rankin-product-service/src/main/java/cn/rankin/productservice/repository/SupportRepository.java
  63. 16 0
      rankin-product-service/src/main/java/cn/rankin/productservice/repository/SupportSelfRelationRepository.java
  64. 24 0
      rankin-product-service/src/main/java/cn/rankin/productservice/repository/TagRepository.java
  65. 8 1
      rankin-product-service/src/main/java/cn/rankin/productservice/repository/WareRepository.java
  66. 192 0
      rankin-product-service/src/main/java/cn/rankin/productservice/service/CourseService.java
  67. 105 0
      rankin-product-service/src/main/java/cn/rankin/productservice/service/ItemPriceService.java
  68. 106 0
      rankin-product-service/src/main/java/cn/rankin/productservice/service/ItemService.java
  69. 137 0
      rankin-product-service/src/main/java/cn/rankin/productservice/service/LessonService.java
  70. 165 0
      rankin-product-service/src/main/java/cn/rankin/productservice/service/SupportService.java
  71. 84 0
      rankin-product-service/src/main/java/cn/rankin/productservice/service/TagService.java
  72. 78 0
      rankin-product-service/src/main/java/cn/rankin/productservice/service/WareService.java
  73. 79 0
      rankin-product-service/src/main/java/cn/rankin/productservice/utils/DTOConverter.java
  74. 41 0
      rankin-product-service/src/main/java/cn/rankin/productservice/vo/CourseSubItemVo.java
  75. 3 0
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/ResourceServiceApplication.java
  76. 5 9
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/controller/AliOSSController.java
  77. 18 9
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/controller/ResourceController.java
  78. 2 2
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/proxy/RemoteResourceProxy.java
  79. 0 12
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/repository/BasicRepository.java
  80. 2 3
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/repository/ResourceRepository.java
  81. 0 60
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/repository/ResourceRepositoryImpl.java
  82. 12 22
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/service/ResourceService.java

+ 6 - 0
pom.xml

@@ -57,6 +57,12 @@
         </dependency>
 
         <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.7</version>
+        </dependency>
+
+        <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
             <version>1.16.16</version>

+ 11 - 0
rankin-common-utils/pom.xml

@@ -11,6 +11,13 @@
 	<name>${project.artifactId}</name>
 	<description>Common Utils for Spring Boot</description>
 
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>1.5.8.RELEASE</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+
 	<properties>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
@@ -18,6 +25,10 @@
 	</properties>
 
     <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
 
         <dependency>
             <groupId>com.alibaba</groupId>

+ 1 - 1
rankin-common-utils/src/main/java/cn/rankin/common/utils/entity/Cache.java

@@ -1,4 +1,4 @@
-package cn.rankin.common.utils.entity;
+package cn.rankin.common.utils.api;
 
 public class Cache {
 

+ 1 - 1
rankin-common-utils/src/main/java/cn/rankin/common/utils/entity/api/APICode.java

@@ -1,4 +1,4 @@
-package cn.rankin.common.utils.entity.api;
+package cn.rankin.common.utils.api.model;
 
 import com.alibaba.fastjson.JSON;
 

+ 15 - 1
rankin-common-utils/src/main/java/cn/rankin/common/utils/entity/api/APICodeManager.java

@@ -1,4 +1,4 @@
-package cn.rankin.common.utils.entity.api;
+package cn.rankin.common.utils.api.model;
 
 public class APICodeManager {
 
@@ -23,4 +23,18 @@ public class APICodeManager {
     public final static int _C_ALREADY_EXISTS = 700;
     public final static APICode ALREADY_EXISTS = new APICode(_C_ALREADY_EXISTS, "数据已存在");
 
+    public final static int _C_NOT_EXISTS = 800;
+    public final static APICode NOT_EXISTS = new APICode(_C_NOT_EXISTS, "数据不存在 ");
+
+    public final static int _C_OPERATE_ERROR = 1001;
+    public final static APICode OPERATE_ERROR = new APICode(_C_OPERATE_ERROR, "操作失败");
+
+    public static APICode ok(String message) {
+        return new APICode(_C_OK, message);
+    }
+
+    public static APICode error(String message) {
+        return new APICode(_C_PARAMETER_ERROR, message);
+    }
+
 }

+ 1 - 1
rankin-common-utils/src/main/java/cn/rankin/common/utils/entity/api/APIResult.java

@@ -1,4 +1,4 @@
-package cn.rankin.common.utils.entity.api;
+package cn.rankin.common.utils.api.model;
 
 import java.util.HashMap;
 import java.util.Map;

+ 1 - 2
rankin-common-utils/src/main/java/cn/rankin/common/utils/entity/page/Page.java

@@ -1,6 +1,5 @@
-package cn.rankin.common.utils.entity.page;
+package cn.rankin.common.utils.api.page;
 
-import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.annotation.JSONField;
 
 import java.io.Serializable;

+ 1 - 1
rankin-common-utils/src/main/java/cn/rankin/common/utils/entity/page/Pageable.java

@@ -1,4 +1,4 @@
-package cn.rankin.common.utils.entity.page;
+package cn.rankin.common.utils.api.page;
 
 public interface Pageable<E> {
 	

+ 41 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/CourseDTO.java

@@ -0,0 +1,41 @@
+package cn.rankin.common.utils.dto.product;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import lombok.Data;
+
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import java.io.Serializable;
+import java.util.*;
+
+@Data
+public class CourseDTO implements Serializable {
+
+    private String id;
+
+    private String code;
+
+    private String name;
+
+    private String title;
+
+    private String digest;
+
+    private String detail;
+
+    private String keyword;
+
+    private String cvImgIds;
+
+    private String bgImgIds;
+
+    @Enumerated(EnumType.ORDINAL)
+    private BaseStatusEnum status;
+
+    // 有序
+    private List<SubRelationDTO> subList;
+
+    private List<SupportDTO> supportList;
+
+}
+

+ 33 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/ItemDTO.java

@@ -0,0 +1,33 @@
+package cn.rankin.common.utils.dto.product;
+
+import cn.rankin.common.utils.enums.ItemStatusEnum;
+import cn.rankin.common.utils.enums.ItemTypeEnum;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Set;
+
+@Data
+public class ItemDTO implements Serializable {
+
+    private String id;
+
+    private String courseId;
+
+    private String code;
+
+    private String name;
+
+    private ItemTypeEnum type;
+
+    private String merchantId;
+
+    private Integer sort;
+
+    private ItemStatusEnum status;
+
+    private List<ItemPriceDTO> priceList;
+
+    private Set<String> tagList;
+}

+ 26 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/ItemPriceDTO.java

@@ -0,0 +1,26 @@
+package cn.rankin.common.utils.dto.product;
+
+import cn.rankin.common.utils.enums.PriceTypeEnum;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ItemPriceDTO implements Serializable {
+
+    private String id;
+
+    private String name;
+
+    private String itemId;
+
+    private PriceTypeEnum type;
+
+    private Integer duration;
+
+    private Double cpPrice;
+
+    private Double merchantPrice;
+
+    private Double terminalPrice;
+}

+ 23 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/LessonDTO.java

@@ -0,0 +1,23 @@
+package cn.rankin.common.utils.dto.product;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class LessonDTO implements Serializable {
+
+    private String id;
+
+    private String code;
+
+    private String name;
+
+    private String digest;
+
+    private Integer sort;
+
+    private List<WareDTO> wareList;
+
+}

+ 14 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/SubRelationDTO.java

@@ -0,0 +1,14 @@
+package cn.rankin.common.utils.dto.product;
+
+import cn.rankin.common.utils.enums.CourseSubTypeEnum;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class SubRelationDTO implements Serializable {
+
+    private String id;
+
+    private CourseSubTypeEnum type;
+}

+ 30 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/SupportDTO.java

@@ -0,0 +1,30 @@
+package cn.rankin.common.utils.dto.product;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Set;
+
+@Data
+public class SupportDTO implements Serializable {
+
+    private String id;
+
+    private String code;
+
+    private String name;
+
+    private String title;
+
+    private String digest;
+
+    private String detail;
+
+    private String imgIds;
+
+    private BaseStatusEnum status;
+
+    private Set<String> supportList;
+
+}

+ 25 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/TagDTO.java

@@ -0,0 +1,25 @@
+package cn.rankin.common.utils.dto.product;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.enums.TagTypeEnum;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class TagDTO implements Serializable {
+
+    private String id;
+
+    private String code;
+
+    private String name;
+
+    private TagTypeEnum type;
+
+    private String merchantId;
+
+    private Integer sort;
+
+    private BaseStatusEnum status;
+}

+ 31 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/product/WareDTO.java

@@ -0,0 +1,31 @@
+package cn.rankin.common.utils.dto.product;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.enums.WareTypeEnum;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class WareDTO implements Serializable {
+
+    private String id;
+
+    private String code;
+
+    private String name;
+
+    private String digest;
+
+    private WareTypeEnum type;
+
+    private String playUrl;
+
+    private String imgIds;
+
+    private String cpId;
+
+    private Integer sort;
+
+    private BaseStatusEnum status;
+}

+ 26 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/search/ItemSearchDTO.java

@@ -0,0 +1,26 @@
+package cn.rankin.common.utils.dto.search;
+
+import cn.rankin.common.utils.enums.ItemStatusEnum;
+import cn.rankin.common.utils.enums.ItemTypeEnum;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ItemSearchDTO implements Serializable {
+
+    private String code;
+
+    private String name;
+
+    private ItemTypeEnum type;
+
+    private ItemStatusEnum status;
+
+    private String merchantId;
+
+    private Integer pageNo = 1;
+
+    private Integer pageSize = 10;
+
+}

+ 25 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/dto/search/SearchDTO.java

@@ -0,0 +1,25 @@
+package cn.rankin.common.utils.dto.search;
+
+import cn.rankin.common.utils.enums.WareTypeEnum;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class SearchDTO implements Serializable {
+
+    private String code;
+
+    private String name;
+
+    private WareTypeEnum type;
+
+    private String sort;
+
+    private Integer by;
+
+    private Integer pageNo = 1;
+
+    private Integer pageSize = 10;
+
+}

+ 6 - 3
rankin-common-utils/src/main/java/cn/rankin/common/utils/entity/dto/ResourceSearchDTO.java

@@ -1,15 +1,17 @@
-package cn.rankin.common.utils.entity.dto;
+package cn.rankin.common.utils.dto.search;
 
 import lombok.Data;
 
+import java.io.Serializable;
+
 @Data
-public class ResourceSearchDTO {
+public class TagSearchDTO implements Serializable {
 
     private String code;
 
     private String name;
 
-    private Integer type;
+    private String merchantId;
 
     private String sort;
 
@@ -18,4 +20,5 @@ public class ResourceSearchDTO {
     private Integer pageNo = 1;
 
     private Integer pageSize = 10;
+
 }

+ 1 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/enums/BaseOrderEnum.java

@@ -13,6 +13,7 @@ public enum BaseOrderEnum {
     public String getName() {  
         return name;  
     }
+
     @Override
     public String toString() {
         return this.name;

+ 20 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/enums/CourseSubTypeEnum.java

@@ -0,0 +1,20 @@
+package cn.rankin.common.utils.enums;
+
+public enum CourseSubTypeEnum {
+    UNIT("单元"), LESSON("课");
+
+    String name;
+
+    CourseSubTypeEnum(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
+}

+ 20 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/enums/ItemStatusEnum.java

@@ -0,0 +1,20 @@
+package cn.rankin.common.utils.enums;
+
+public enum ItemStatusEnum {
+    SALE("出售中"), OFF("下架"), PRESELL("预售"), DEL("删除");
+
+    String name;
+
+    ItemStatusEnum(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
+}

+ 21 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/enums/PriceTypeEnum.java

@@ -0,0 +1,21 @@
+package cn.rankin.common.utils.enums;
+
+public enum PriceTypeEnum {
+    NORMAL("普通"), PACKAGE("课程包");
+
+    String name;
+
+    PriceTypeEnum(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
+}
+

+ 19 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/enums/TagTypeEnum.java

@@ -0,0 +1,19 @@
+package cn.rankin.common.utils.enums;
+
+public enum TagTypeEnum {
+    COURSE("课程"), SUPPORT("周边"), TRAINING("师训");
+
+    String name;
+    TagTypeEnum(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
+}

+ 31 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/enums/WareTypeEnum.java

@@ -0,0 +1,31 @@
+package cn.rankin.common.utils.enums;
+
+public enum WareTypeEnum {
+
+    SINGLE("单图"), MULTI("多图"), VIDEO("视频");
+
+    public static boolean contains(WareTypeEnum type) {
+        for (WareTypeEnum typeEnum : values()) {
+            if (typeEnum.equals(type)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    String name;
+
+    WareTypeEnum(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return this.name;
+    }
+
+}

+ 145 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/jpa/BasicJpaRepository.java

@@ -0,0 +1,145 @@
+package cn.rankin.common.utils.jpa;
+
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 类名:AfwJpaRepository  <br />
+ *
+ * 功能:
+ *
+ * @author xtwin <br />
+ * 创建时间:2016年7月26日 下午3:20:36  <br />
+ * @version 2016年7月26日
+ */
+public interface BasicJpaRepository<E, ID extends Serializable> extends JpaRepository<E, ID> {
+
+	/**
+	 * 功能:统计符合样板的数据条数 <br/>
+	 *
+	 * @author xtwin <br/>
+	 * @version 2016年3月31日 下午4:56:01 <br/>
+	 */
+	long count(E sample);
+	
+	/**
+	 * 功能:检查是否存在 <br/>
+	 *
+	 * @author xtwin <br/>
+	 * @version 2016年8月17日 下午12:04:48 <br/>
+	 */
+	boolean exists(E sample);
+
+	/**
+	 * 功能:根据id查询 <br/>
+	 *
+	 * @author xtwin <br/>
+	 * @version 2016年3月30日 下午6:28:23 <br/>
+	 */
+	E find(ID id);
+	/**
+	 * 功能:根据ids查询 <br/>
+	 *
+	 * @author xtwin <br/>
+	 * @version 2016年3月30日 下午6:28:23 <br/>
+	 */
+	List<E> findByIds(List<ID> id);
+	
+	/**
+	 * 功能:查询符合条件的第一条 <br/>
+	 *
+	 * @author xtwin <br/>
+	 * @version 2016年8月2日 上午11:55:36 <br/>
+	 */
+	E findFirst(E sample);
+	
+	/**
+	 * 功能:查询符合条件的第一条 <br/>
+	 *
+	 * @author xtwin <br/>
+	 * @version 2016年8月2日 上午11:58:10 <br/>
+	 */
+	E findFirst(E sample, Sort sort);
+
+	/**
+	 * 功能:分页查询所有数据,使用id降序排序 <br/>
+	 *
+	 * @author xtwin <br/>
+	 * @version 2016年3月31日 下午4:52:30 <br/>
+	 */
+	List<E> find(Long start, Integer offset);
+	
+	/**
+	 * 功能:分页查询,使用sort规则排序 <br/>
+	 *
+	 * @author xtwin <br/>
+	 * @version 2016年7月29日 上午10:19:05 <br/>
+	 */
+	List<E> find(Long start, Integer offset, Sort sort);
+	
+	/**
+	 * 功能:根据样板查询数据,使用id降序排序 <br/>
+	 *
+	 * @author xtwin <br/>
+	 * @version 2016年3月30日 下午6:51:00 <br/>
+	 */
+	List<E> find(E sample);
+	
+	/**
+	 * 功能:根据样板查询数据,使用sort规则排序 <br/>
+	 *
+	 * @author xtwin <br/>
+	 * @version 2016年7月29日 上午10:19:51 <br/>
+	 */
+	List<E> find(E sample, Sort sort);
+	
+	/**
+	 * 功能:分页查询,按id降序排序 <br/>
+	 *
+	 * @author xtwin <br/>
+	 * @version 2016年3月31日 上午11:58:31 <br/>
+	 */
+	List<E> find(E sample, Long start, Integer offset);
+	
+	/**
+	 * 功能:分页查询,且排序 <br/>
+	 *
+	 * @author xtwin <br/>
+	 * @version 2016年7月29日 上午9:44:26 <br/>
+	 */
+	List<E> find(E sample, Long start, Integer offset, Sort sort);
+	
+	/**
+	 * 功能:更新操作,不更新为null的字段 <br/>
+	 *
+	 * @author xtwin <br/>
+	 * @version 2016年8月1日 上午9:35:47 <br/>
+	 */
+	E update(E entity);
+	/**
+	 * 功能:基于原生merge方法的 批量更新操作
+	 *
+	 * @author  tomas <br/>
+	 * @version 2017年8月1日 上午9:35:47 <br/>
+	 */
+	<S extends E> List<S> update(Iterable<S> entities);
+
+	/**
+	 * 功能:基于原生merge方法的 批量save操作
+	 *
+	 * @author  tomas <br/>
+	 * @version 2017年8月1日 上午9:35:47 <br/>
+	 */
+	<S extends E> List<S> save(Iterable<S> entities);
+	
+	/**
+	 * 功能:更新操作,可以选择是否要忽略更新为null的字段 <br/>
+	 *
+	 * @author xtwin <br/>
+	 * @version 2016年8月1日 上午9:36:20 <br/>
+	 */
+	E update(E entity, boolean ignoreNull);
+}

+ 365 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/jpa/SimpleJpaRepository.java

@@ -0,0 +1,365 @@
+package cn.rankin.common.utils.jpa;
+
+import cn.rankin.common.utils.util.SnowflakeIdUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.Sort.Direction;
+import org.springframework.data.domain.Sort.Order;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.data.jpa.repository.support.JpaEntityInformation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.ReflectionUtils;
+import org.springframework.util.StringUtils;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.Attribute.PersistentAttributeType;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.UUID;
+
+
+public class SimpleJpaRepository<E, ID extends Serializable> extends org.springframework.data.jpa.repository.support.SimpleJpaRepository<E, ID> implements BasicJpaRepository<E, ID> {
+
+    // 日志记录器
+    private static final Logger logger = LoggerFactory.getLogger(SimpleJpaRepository.class);
+
+    // jpa管理器对象
+    @PersistenceContext
+    private EntityManager entityManager;
+
+    // 实体信息
+    private JpaEntityInformation<E, ID> entityInformation;
+
+    public SimpleJpaRepository(JpaEntityInformation<E, ID> entityInformation, EntityManager entityManager) {
+        super(entityInformation, entityManager);
+
+        this.entityInformation = entityInformation;
+        this.entityManager = entityManager;
+    }
+
+    @Override
+    public long count(E sample) {
+        return count(getSpecification(sample));
+    }
+
+    @Override
+    public boolean exists(E sample) {
+        return count(sample) > 0L;
+    }
+
+    @Override
+    public E find(ID id) {
+        return findOne(id);
+    }
+
+    public List<E> findByIds(List<ID> ids) {
+        return findAll(ids);
+    }
+
+
+    @Override
+    public List<E> find(Long start, Integer offset) {
+        return find(start, offset, null);
+    }
+
+    @Override
+    public List<E> find(Long start, Integer offset, Sort sort) {
+        return find(null, start, offset, sort);
+    }
+
+    @Override
+    public E findFirst(E sample) {
+        return findFirst(sample, null);
+    }
+
+    @Override
+    public E findFirst(E sample, Sort sort) {
+        List<E> list = find(sample, 0L, 1, sort);
+
+        return null == list || list.isEmpty() ? null : list.get(0);
+    }
+
+    @Override
+    public List<E> find(E sample) {
+        return find(sample, null);
+    }
+
+    @Override
+    public List<E> find(E sample, Sort sort) {
+        return find(sample, null, null, sort);
+    }
+
+    @Override
+    public List<E> find(E sample, Long start, Integer offset) {
+        return find(sample, start, offset, null);
+    }
+
+    @Override
+    public List<E> find(E sample, Long start, Integer offset, Sort sort) {
+        // 创建qbe
+        Specification<E> spec = getSpecification(sample);
+
+        if (null == sort) {
+            // 默认按id降序排序
+            sort = new Sort(new Order(Direction.DESC, entityInformation.getIdAttribute().getName()));
+        }
+
+        // 取得查询对象
+        TypedQuery<E> query = getQuery(spec, sort);
+
+        // 起始条数,从零开始
+        if (null != start) {
+            // TODO 此处只接受整形值
+            query.setFirstResult(start.intValue());
+        }
+
+        // 查询条数
+        if (null != offset) {
+            query.setMaxResults(offset);
+        }
+
+        // 执行查询
+        return query.getResultList();
+    }
+
+
+    @Transactional
+    public E update(E entity) {
+        return update(entity, true);
+    }
+
+    @Override
+    @Transactional
+    public <S extends E> List<S> save(Iterable<S> entities) {
+        return insertOrUpdateBatch(entities);
+    }
+
+    @Transactional
+    public <S extends E> S save(S entity) {
+
+        if (entityInformation.isNew(entity)) {
+            setSnowflakeIdId(entity);
+            entityManager.persist(entity);
+            return entity;
+        } else {
+            return entityManager.merge(entity);
+        }
+    }
+
+    @Transactional
+    public E update(E entity, boolean ignoreNull) {
+        // 取得当前实体的id
+        ID id = entityInformation.getId(entity);
+
+        // 检查id是否为空Ø
+        if (null == id) {
+            throw new RuntimeException("The update domain id must be not empty !");
+        }
+
+        // 查询库中当前对象的信息
+        E persist = find(id);
+
+        // 检查该id对应的数据是否存在
+        if (null == persist) {
+            throw new RuntimeException("The update domain id is not exist : " + id);
+        }
+
+        // 标识是否发生了变化
+        boolean isChanged = false;
+
+        // 取得所有属性
+        for (Attribute<? super E, ?> attr : entityManager.getMetamodel().entity(getDomainClass()).getAttributes()) {
+
+            Member member = attr.getJavaMember();
+
+            Field field = null;
+            if (member instanceof Field) {
+                field = (Field) member;
+            } else {
+                field = ReflectionUtils.findField(getDomainClass(), attr.getName());
+            }
+
+            // 取得字段值
+            Object value = ReflectionUtils.getField(field, entity);
+            if (null != value || !ignoreNull) {
+                // 旧值
+                Object oldValue = ReflectionUtils.getField(field, persist);
+
+                if ((null == value && null != oldValue)
+                        || (null != value && !value.equals(oldValue))) {
+
+                    // 将新值更新到持久化对象中
+                    ReflectionUtils.setField(field, persist, value);
+
+                    // 标记为发生了更新
+                    isChanged = true;
+                }
+            }
+        }
+
+        if (isChanged) {
+            persist = save(persist);
+        } else {
+            // 没有发生变更,忽略更新
+            logger.info("not changed : {}", id);
+        }
+
+        // 执行保存并返回
+        return persist;
+    }
+
+    @Transactional
+    public <S extends E> List<S> update(Iterable<S> entities) {
+        return insertOrUpdateBatch(entities);
+    }
+
+    private <S extends E> List<S> insertOrUpdateBatch(Iterable<S> entities) {
+        List<S> result = new ArrayList<>();
+        if (entities == null) {
+            return result;
+        }
+        Iterator<S> iterator = entities.iterator();
+        int i = 0;
+        int count = 0;
+        //遍历循环 每20个 insert 批量插入/更新 一次库
+        while (iterator.hasNext()) {
+            S entity = iterator.next();
+            if (entityInformation.isNew(entity)) {
+                setSnowflakeIdId(entity);
+                entityManager.persist(entity);
+            } else {
+                update(entity);
+            }
+            result.add(entity);
+            i++;
+            if (i % 20 == 0) {
+                entityManager.flush();
+                entityManager.clear();
+
+                count = 0;
+            } else {
+                count++;
+            }
+        }
+        //判断 是否有剩余未flush的 最后flush
+        if (count > 0) {
+            entityManager.flush();
+            entityManager.clear();
+        }
+        return result;
+    }
+
+    protected Specification<E> getSpecification(E sample) {
+        return null == sample ? null : new Specification<E>() {
+            @Override
+            public Predicate toPredicate(Root<E> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
+                try {
+                    // 获取qbe
+                    return SimpleJpaRepository.this.toPredicate(sample, root, query, cb);
+                } catch (Exception e) {
+                    throw new RuntimeException("toPredicate fail with error : " + String.valueOf(e), e);
+                }
+            }
+        };
+    }
+
+    /**
+     * 功能:转为查询样板,可以由子类重写 <br/>
+     *
+     * @throws IllegalAccessException
+     * @throws IllegalArgumentException
+     * @author xtwin <br/>
+     * @version 2016年7月29日 上午10:15:27 <br/>
+     */
+    protected Predicate toPredicate(E sample, Root<E> root, CriteriaQuery<?> query, CriteriaBuilder cb) throws Exception {
+        // 存放查询条件
+        List<Predicate> list = new ArrayList<Predicate>();
+
+        // 处理实体中的所有字段
+        for (Attribute<? super E, ?> attr : entityManager.getMetamodel().entity(getDomainClass()).getAttributes()) {
+            // 依次处理每个字段
+            PersistentAttributeType patype = attr.getPersistentAttributeType();
+
+            // 打印日志
+            logger.debug("the attr type is : {}", patype);
+
+            if (PersistentAttributeType.MANY_TO_ONE.equals(patype)
+                    || PersistentAttributeType.ONE_TO_MANY.equals(patype)) {
+
+                // 忽略
+                continue;
+            }
+
+            Object value = null;
+
+            Member member = attr.getJavaMember();
+            if (member instanceof Method) {
+                value = ReflectionUtils.invokeMethod((Method) member, sample);
+            } else if (member instanceof Field) {
+                //((Field) member).setAccessible(true);
+                // 确保可以访问
+                ReflectionUtils.makeAccessible((Field) member);
+
+                // 取得字段的值
+                value = ((Field) member).get(sample);
+            }
+
+            if (null != value) {
+                Predicate tmp = null;
+                //like 查询放在最前面
+                List<Predicate> likePredicate = new ArrayList<Predicate>();
+                if (String.class.isAssignableFrom(attr.getJavaType())) {
+                    if (!StringUtils.isEmpty(value)) {
+                        StringBuilder stringBuilder = new StringBuilder(((String) value).trim());
+                        //如果以 % 开头和结尾 表示 like 查询
+                        if ("%".equals(stringBuilder.substring(0, 1)) || stringBuilder.toString().endsWith("%")) {
+                            tmp = cb.like(root.get(attr.getName()), (String) value);
+                            likePredicate.add(tmp);
+                        } else {
+                            tmp = cb.equal(root.get(attr.getName()), value);
+                            list.add(tmp);
+                        }
+                    }
+                } else {
+                    tmp = cb.equal(root.get(attr.getName()), value);
+                    list.add(tmp);
+                }
+                if (likePredicate.size() > 0) {
+                    list.addAll(0, likePredicate);
+                }
+            }
+        }
+
+        // where条件
+        return list.isEmpty() ? null : cb.and(list.toArray(new Predicate[list.size()]));
+    }
+
+
+    protected void setSnowflakeIdId(E entity) {
+        try {
+            Field field = ReflectionUtils.findField(entity.getClass(), entityInformation.getIdAttribute().getName());
+            if (entityInformation.getIdAttribute().getType().getJavaType().getName().equals("java.lang.Long")) {
+                ReflectionUtils.makeAccessible(field);
+                ReflectionUtils.setField(field, entity, SnowflakeIdUtil.getSnowflakeIdUtil().nextId());
+            } else if (entityInformation.getIdAttribute().getType().getJavaType().getName().equals("java.lang.String")) {
+                ReflectionUtils.makeAccessible(field);
+                ReflectionUtils.setField(field, entity, UUID.randomUUID().toString().replace("-", ""));
+            }
+        } catch (Exception e) {
+            logger.error("Reflect set id error: {}", e.getMessage(), e);
+        }
+    }
+}

+ 49 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/util/ListToMapUtil.java

@@ -0,0 +1,49 @@
+package cn.rankin.common.utils.util;
+
+import cn.rankin.common.utils.dto.product.LessonDTO;
+import com.alibaba.fastjson.JSON;
+import lombok.Data;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class ListToMapUtil<K, V> {
+
+    private List<V> list = new ArrayList<>();
+
+    public ListToMapUtil(List<V> list) {
+        this.list = list;
+    }
+
+    public Map<K, V> parse(String key) {
+        Map<K, V> map = new HashMap<>();
+        list.forEach(v -> {
+            K k = null;
+            try {
+                Field field = v.getClass().getDeclaredField(key);
+                field.setAccessible(true);
+                k = (K) field.get(v);
+            }catch (Exception e) {
+                throw new RuntimeException(e.getCause());
+            }
+            map.put((K) k, v);
+        });
+        return map;
+    }
+
+    public static void main(String[] args) {
+        List<LessonDTO> list = new ArrayList<>();
+        for (int i = 0; i < 10; i++) {
+            LessonDTO tmp = new LessonDTO();
+            tmp.setCode(String.valueOf(i));
+            list.add(tmp);
+        }
+
+        ListToMapUtil<String, LessonDTO> mapUtil = new ListToMapUtil(list);
+        System.out.println(JSON.toJSONString(mapUtil.parse("code")));
+    }
+}

+ 1 - 1
rankin-common-utils/src/main/java/cn/rankin/common/utils/util/LocalCache.java

@@ -2,7 +2,7 @@ package cn.rankin.common.utils.util;
 
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
-import cn.rankin.common.utils.entity.Cache;
+import cn.rankin.common.utils.api.Cache;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

+ 5 - 2
rankin-common-utils/src/main/java/cn/rankin/common/utils/util/SecurityUtil.java

@@ -1,6 +1,9 @@
 package cn.rankin.common.utils.util;
 
+import com.alibaba.fastjson.JSON;
+
 import java.security.MessageDigest;
+import java.util.List;
 
 public class SecurityUtil {
 
@@ -43,7 +46,7 @@ public class SecurityUtil {
         StringBuilder out = new StringBuilder();
         System.out.println(out.toString());
         System.out.println(SecurityUtil.MD5("123456", null).equals("e10adc3949ba59abbe56e057f20f883e"));
-        System.out.println(SecurityUtil.MD5("bcd"));
-        System.out.println(SecurityUtil.MD5("123456"));
+        System.out.println(SecurityUtil.MD5("555"));
+        System.out.println(SecurityUtil.MD5("666"));
     }
 }

+ 12 - 12
rankin-product-service/pom.xml

@@ -11,12 +11,12 @@
 	<name>rankin-product-service</name>
 	<description>Product Service For Spring Cloud</description>
 
-	<parent>
-		<groupId>org.springframework.boot</groupId>
-		<artifactId>spring-boot-starter-parent</artifactId>
-		<version>1.5.8.RELEASE</version>
-		<relativePath/> <!-- lookup parent from repository -->
-	</parent>
+    <parent>
+        <groupId>cn.rankin</groupId>
+        <artifactId>rankin</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
 
 	<properties>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -43,17 +43,17 @@
             <artifactId>mysql-connector-java</artifactId>
         </dependency>
 
-        <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-            <version>1.16.16</version>
-        </dependency>
-
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-test</artifactId>
 			<scope>test</scope>
 		</dependency>
+
+        <dependency>
+            <groupId>cn.rankin</groupId>
+            <artifactId>rankin-common-utils</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
 	</dependencies>
 
 	<dependencyManagement>

+ 3 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/ProductServiceApplication.java

@@ -1,12 +1,15 @@
 package cn.rankin.productservice;
 
+import cn.rankin.common.utils.jpa.SimpleJpaRepository;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 
 
 @EnableDiscoveryClient
 @SpringBootApplication
+@EnableJpaRepositories(repositoryBaseClass = SimpleJpaRepository.class)
 public class ProductServiceApplication {
 
 	public static void main(String[] args) {

+ 84 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/controller/CourseController.java

@@ -0,0 +1,84 @@
+package cn.rankin.productservice.controller;
+
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.dto.product.CourseDTO;
+import cn.rankin.common.utils.dto.search.SearchDTO;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.productservice.entity.Course;
+import cn.rankin.productservice.service.CourseService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@Slf4j
+@RestController
+@RequestMapping(value = "course")
+public class CourseController {
+
+    @Autowired
+    private CourseService courseService;
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<Page<Course>> getWareList(SearchDTO searchDTO) {
+        Course course = new Course();
+
+        String code = searchDTO.getCode();
+        if (!StringUtils.isEmpty(code)) {
+            course.setCode("%" + code + "%");
+        }
+
+        String name = searchDTO.getName();
+        if (!StringUtils.isEmpty(name)) {
+            course.setName("%" + name + "%");
+        }
+
+        return courseService.search(course, searchDTO.getPageNo(), searchDTO.getPageSize());
+    }
+
+    // 创建资源
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<Course> create(@RequestBody CourseDTO courseDTO) {
+        String code = courseDTO.getCode();
+        if (StringUtils.isEmpty(code)) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        if (courseService.exists(code)) {
+            return APIResult.error(APICodeManager.ALREADY_EXISTS);
+        }
+
+        return courseService.create(courseDTO);
+    }
+
+    // 修改资源
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<Course> update(@RequestBody CourseDTO courseDTO) {
+        if (courseDTO.getId() == null) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return courseService.update(courseDTO);
+    }
+
+    // 删除
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public APIResult<Boolean> delete(@PathVariable("id") String id) {
+        if (StringUtils.isEmpty(id)) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return courseService.delete(id);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public APIResult<Course> getCourse(@PathVariable("id") String id) {
+        if (StringUtils.isEmpty(id)) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return courseService.findById(id);
+    }
+
+}

+ 73 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/controller/ItemController.java

@@ -0,0 +1,73 @@
+package cn.rankin.productservice.controller;
+
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.dto.product.ItemDTO;
+import cn.rankin.common.utils.dto.search.ItemSearchDTO;
+import cn.rankin.productservice.entity.Item;
+import cn.rankin.productservice.service.ItemService;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.transaction.Transactional;
+
+@RestController
+@RequestMapping(value = "item")
+public class ItemController {
+
+    @Autowired
+    private ItemService itemService;
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<Page<Item>> search(ItemSearchDTO searchDTO) {
+        Item item = new Item();
+
+        String code = searchDTO.getCode();
+        if (!StringUtils.isEmpty(code)) {
+            item.setCode("%" + code + "%");
+        }
+
+        String name = searchDTO.getName();
+        if (!StringUtils.isEmpty(name)) {
+            item.setName("%" + name + "%");
+        }
+
+        // others
+        item.setStatus(searchDTO.getStatus());
+        item.setType(searchDTO.getType());
+        item.setMerchantId(searchDTO.getMerchantId());
+
+        return itemService.search(item, searchDTO.getPageNo(), searchDTO.getPageSize());
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<Item> create(@RequestBody ItemDTO itemDTO) {
+        String code = itemDTO.getCode();
+        if (StringUtils.isEmpty(code) || itemDTO.getMerchantId() == null) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+        // 保存商品信息
+        return itemService.create(itemDTO);
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<Item> update(@RequestBody ItemDTO itemDTO) {
+        if (itemDTO.getId() == null) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return itemService.update(itemDTO);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public APIResult<Boolean> delete(@PathVariable("id") String itemId) {
+        if (itemId == null) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return itemService.delete(itemId);
+    }
+
+}

+ 73 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/controller/LessonController.java

@@ -0,0 +1,73 @@
+package cn.rankin.productservice.controller;
+
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.dto.search.SearchDTO;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.dto.product.LessonDTO;
+import cn.rankin.productservice.entity.Lesson;
+import cn.rankin.productservice.service.LessonService;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping(value = "lesson")
+public class LessonController {
+
+    @Autowired
+    private LessonService lessonService;
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<Page<Lesson>> getLessonList(SearchDTO searchDTO) {
+        Lesson lesson = new Lesson();
+
+        String code = searchDTO.getCode();
+        if (!StringUtils.isEmpty(code)) {
+            lesson.setCode("%" + code + "%");
+        }
+
+        String name = searchDTO.getName();
+        if (!StringUtils.isEmpty(name)) {
+            lesson.setName(name);
+        }
+
+        return lessonService.search(lesson, searchDTO.getPageNo(), searchDTO.getPageSize());
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public APIResult<Lesson> getLesson(@PathVariable String id) {
+        if (StringUtils.isEmpty(id)) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return lessonService.findById(id);
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<Lesson> create(@RequestBody LessonDTO lessonDTO) {
+        String code = lessonDTO.getCode();
+        if (lessonDTO.getId() != null || StringUtils.isEmpty(code)) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return lessonService.create(lessonDTO);
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<Lesson> update(@RequestBody Lesson lesson) {
+        if (lesson.getId() == null) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return lessonService.update(lesson);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public APIResult<Boolean> delete(@PathVariable("id") String id) {
+        if (StringUtils.isEmpty(id)) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+        return lessonService.delete(id);
+    }
+}

+ 74 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/controller/SupportController.java

@@ -0,0 +1,74 @@
+package cn.rankin.productservice.controller;
+
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.dto.search.SearchDTO;
+import cn.rankin.common.utils.dto.product.SupportDTO;
+import cn.rankin.productservice.entity.Support;
+import cn.rankin.productservice.service.SupportService;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping(value = "support")
+public class SupportController {
+
+    @Autowired
+    private SupportService supportService;
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<Page<Support>> search(SearchDTO searchDTO) {
+        Support support = new Support();
+
+        String code = searchDTO.getCode();
+        if (!StringUtils.isEmpty(code)) {
+            support.setCode("%" + code + "%");
+        }
+
+        String name = searchDTO.getName();
+        if (!StringUtils.isEmpty(name)) {
+            support.setName("%" + name + "%");
+        }
+
+        return supportService.search(support, searchDTO.getPageNo(), searchDTO.getPageSize());
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public APIResult<Support> getSupport(@PathVariable String id) {
+        if (StringUtils.isEmpty(id)) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return supportService.findById(id);
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<Support> create(@RequestBody SupportDTO supportDTO) {
+        String code = supportDTO.getCode();
+        if (StringUtils.isEmpty(code)) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return supportService.create(supportDTO);
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<Support> update(@RequestBody SupportDTO supportDTO) {
+        if (supportDTO.getId() == null) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return supportService.update(supportDTO);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public APIResult<Boolean> delete(@PathVariable("id") String id) {
+        if (StringUtils.isEmpty(id)) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return supportService.delete(id);
+    }
+}

+ 72 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/controller/TagController.java

@@ -0,0 +1,72 @@
+package cn.rankin.productservice.controller;
+
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.dto.product.TagDTO;
+import cn.rankin.common.utils.dto.search.TagSearchDTO;
+import cn.rankin.productservice.entity.Tag;
+import cn.rankin.productservice.service.TagService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@Slf4j
+@RestController
+@RequestMapping(value = "tag")
+public class TagController {
+
+    @Autowired
+    private TagService tagService;
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<Page<Tag>> search(TagSearchDTO searchDTO) {
+        Tag tag = new Tag();
+
+        String code = searchDTO.getCode();
+        if (!StringUtils.isEmpty(code)) {
+            tag.setCode("%" + code + "%");
+        }
+
+        String name = searchDTO.getName();
+        if (!StringUtils.isEmpty(name)) {
+            tag.setName("%" + name + "%");
+        }
+
+        String merchantId = searchDTO.getMerchantId();
+        if (merchantId != null) {
+            tag.setMerchantId(merchantId);
+        }
+
+        return tagService.search(tag, searchDTO.getPageNo(), searchDTO.getPageSize());
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<Tag> create(@RequestBody TagDTO tagDTO) {
+        String code = tagDTO.getCode();
+        if (StringUtils.isEmpty(code)) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return tagService.create(tagDTO);
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<Tag> update(@RequestBody TagDTO tagDTO) {
+        if (tagDTO.getId() == null) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return tagService.update(tagDTO);
+    }
+
+    @RequestMapping(value = "/{code}", method = RequestMethod.DELETE)
+    public APIResult<Boolean> delete(@PathVariable String code) {
+        if (StringUtils.isEmpty(code)) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return tagService.delete(code);
+    }
+}

+ 0 - 21
rankin-product-service/src/main/java/cn/rankin/productservice/controller/TestController.java

@@ -1,21 +0,0 @@
-package cn.rankin.productservice.controller;
-
-import cn.rankin.productservice.entity.Ware;
-import cn.rankin.productservice.repository.WareRepository;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-public class TestController {
-
-    @Autowired
-    private WareRepository testRepository;
-
-    @RequestMapping(value = "/hello", method = RequestMethod.GET)
-    public String sayHello() {
-        Ware ware = new Ware();
-        return "hello!";
-    }
-}

+ 79 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/controller/WareController.java

@@ -0,0 +1,79 @@
+package cn.rankin.productservice.controller;
+
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.dto.search.SearchDTO;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.dto.product.WareDTO;
+import cn.rankin.productservice.entity.Ware;
+import cn.rankin.common.utils.enums.WareTypeEnum;
+import cn.rankin.productservice.service.WareService;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping(value = "ware")
+public class WareController {
+
+    @Autowired
+    private WareService wareService;
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<Page<Ware>> getWareList(SearchDTO searchDTO) {
+        Ware ware = new Ware();
+
+        WareTypeEnum type = searchDTO.getType();
+        if (type == null) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+        ware.setType(type);
+
+        String code = searchDTO.getCode();
+        if (!StringUtils.isEmpty(code)) {
+            ware.setCode("%" + code + "%");
+        }
+
+        String name = searchDTO.getName();
+        if (!StringUtils.isEmpty(name)) {
+            ware.setName("%" + name + "%");
+        }
+
+        return wareService.search(ware, searchDTO.getPageNo(), searchDTO.getPageSize());
+    }
+
+    // 创建资源
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<Ware> create(@RequestBody WareDTO wareDTO) {
+        String code = wareDTO.getCode();
+        WareTypeEnum type = wareDTO.getType();
+        if (StringUtils.isEmpty(code) || type == null) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return wareService.create(wareDTO);
+    }
+
+    // 修改资源
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<Ware> update(@RequestBody WareDTO wareDTO) {
+        if (wareDTO.getId() == null) {
+            return APIResult.error(APICodeManager.PARAMETER_ERROR);
+        }
+
+        return wareService.update(wareDTO);
+    }
+
+    // 删除资源
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public APIResult<Boolean> delete(@PathVariable("id") String id) {
+        return wareService.delete(id);
+    }
+
+    // 取一个
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public APIResult<Ware> getWare(@PathVariable("id") String id) {
+        return wareService.findById(id);
+    }
+
+}

+ 0 - 52
rankin-product-service/src/main/java/cn/rankin/productservice/entity/Combo.java

@@ -1,52 +0,0 @@
-package cn.rankin.productservice.entity;
-
-import lombok.Data;
-import lombok.ToString;
-import org.hibernate.annotations.DynamicInsert;
-import org.hibernate.annotations.DynamicUpdate;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import java.io.Serializable;
-import java.sql.Timestamp;
-
-@Data
-@ToString
-@Entity
-@Table(name = "lj_combo")
-@DynamicInsert
-@DynamicUpdate
-public class Combo implements Serializable {
-
-    @Id
-    private Long id;
-
-    @Column(name = "merchant_id")
-    private Long merchantId;
-
-    @Column
-    private String name;
-
-    @Column
-    private String digest;
-
-    @Column(name = "cv_img_ids")
-    private String cvImgIds;
-
-    @Column(name = "dis_price")
-    private Double disPrice;
-
-    @Column
-    private Integer sort;
-
-    @Column
-    private Integer status;
-
-    @Column(name = "gmt_created")
-    private Timestamp gmtCreated;
-
-    @Column(name = "gmt_modified")
-    private Timestamp gmtModified;
-}

+ 27 - 8
rankin-product-service/src/main/java/cn/rankin/productservice/entity/Course.java

@@ -1,17 +1,18 @@
 package cn.rankin.productservice.entity;
 
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.productservice.vo.CourseSubItemVo;
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import lombok.Data;
 import lombok.ToString;
+import org.apache.commons.lang.StringUtils;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
-import org.hibernate.validator.constraints.Range;
 
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
+import javax.persistence.*;
 import java.io.Serializable;
 import java.util.Date;
+import java.util.List;
 
 @Data
 @ToString
@@ -22,9 +23,9 @@ import java.util.Date;
 public class Course implements Serializable{
 
     @Id
-    private Long id;
+    private String id;
 
-    @Column(nullable = false, unique = true)
+    @Column(unique = true)
     private String code;
 
     @Column
@@ -49,12 +50,30 @@ public class Course implements Serializable{
     private String bgImgIds;
 
     @Column
-    private Integer status;
+    @Enumerated(EnumType.ORDINAL)
+    private BaseStatusEnum status;
 
     @Column(name = "gmt_created", updatable = false, insertable = false)
+    @Temporal(TemporalType.TIMESTAMP)
     private Date gmtCreated;
 
     @Column(name = "gmt_modified")
+    @Temporal(TemporalType.TIMESTAMP)
     private Date gmtModified;
 
+    @JsonIgnore
+    public boolean isRight() {
+        if (StringUtils.isEmpty(code)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Transient
+    private List<CourseSubItemVo> subItemList;
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(name = "lj_course_support_relation", joinColumns = {@JoinColumn(name = "course_id", referencedColumnName = "id")},
+            inverseJoinColumns = {@JoinColumn(name = "support_id", referencedColumnName = "id")})
+    private List<Support> supportList;
 }

+ 15 - 12
rankin-product-service/src/main/java/cn/rankin/productservice/entity/CourseSubRelation.java

@@ -1,16 +1,14 @@
 package cn.rankin.productservice.entity;
 
+import cn.rankin.common.utils.enums.CourseSubTypeEnum;
 import lombok.Data;
 import lombok.ToString;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
 
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
+import javax.persistence.*;
 import java.io.Serializable;
-import java.sql.Timestamp;
+import java.util.Date;
 
 @Data
 @ToString
@@ -21,17 +19,22 @@ import java.sql.Timestamp;
 public class CourseSubRelation implements Serializable {
 
     @Id
-    private Long id;
+    private String id;
 
-    @Column(name = "course_code")
-    private String courseCode;
+    @Column(name = "course_id")
+    private String courseId;
 
-    @Column(name = "sub_code")
-    private String subCode;
+    @Column(name = "sub_id")
+    private String subId;
 
     @Column
-    private Integer type;
+    @Enumerated(EnumType.ORDINAL)
+    private CourseSubTypeEnum type;
+
+    @Column
+    private Integer sort;
 
     @Column(name = "gmt_created", updatable = false, insertable = false)
-    private Timestamp gmtCreated;
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtCreated;
 }

+ 0 - 34
rankin-product-service/src/main/java/cn/rankin/productservice/entity/CourseSupportRelation.java

@@ -1,34 +0,0 @@
-package cn.rankin.productservice.entity;
-
-import lombok.Data;
-import lombok.ToString;
-import org.hibernate.annotations.DynamicInsert;
-import org.hibernate.annotations.DynamicUpdate;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import java.io.Serializable;
-import java.sql.Timestamp;
-
-@Data
-@ToString
-@Entity
-@Table(name = "lj_course_support_relation")
-@DynamicInsert
-@DynamicUpdate
-public class CourseSupportRelation implements Serializable {
-
-    @Id
-    private Long id;
-
-    @Column(name = "course_code")
-    private String courseCode;
-
-    @Column(name = "support_code")
-    private String supportCode;
-
-    @Column(name = "gmt_created", insertable = false, updatable = false)
-    private Timestamp gmtCreated;
-}

+ 0 - 34
rankin-product-service/src/main/java/cn/rankin/productservice/entity/CourseTagRelation.java

@@ -1,34 +0,0 @@
-package cn.rankin.productservice.entity;
-
-import lombok.Data;
-import lombok.ToString;
-import org.hibernate.annotations.DynamicInsert;
-import org.hibernate.annotations.DynamicUpdate;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import java.io.Serializable;
-import java.sql.Timestamp;
-
-@Data
-@ToString
-@Entity
-@Table(name = "lj_course_tag_relation")
-@DynamicInsert
-@DynamicUpdate
-public class CourseTagRelation implements Serializable {
-
-    @Id
-    private Long id;
-
-    @Column(name = "tag_code")
-    private String tagCode;
-
-    @Column(name = "course_code")
-    private String courseCode;
-
-    @Column(name = "gmt_created", insertable = false, updatable = false)
-    private Timestamp gmtCreated;
-}

+ 33 - 14
rankin-product-service/src/main/java/cn/rankin/productservice/entity/Item.java

@@ -1,16 +1,17 @@
 package cn.rankin.productservice.entity;
 
+import cn.rankin.common.utils.enums.ItemStatusEnum;
+import cn.rankin.common.utils.enums.ItemTypeEnum;
 import lombok.Data;
 import lombok.ToString;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
 
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
+import javax.persistence.*;
 import java.io.Serializable;
-import java.sql.Timestamp;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
 
 @Data
 @ToString
@@ -21,26 +22,44 @@ import java.sql.Timestamp;
 public class Item implements Serializable {
 
     @Id
-    private Long id;
+    private String id;
+
+    @Column(name = "course_id")
+    private String CourseId;
 
     @Column
     private String code;
 
     @Column
-    private Integer type;
+    private String name;
+
+    @Column
+    @Enumerated(EnumType.ORDINAL)
+    private ItemTypeEnum type;
 
     @Column(name = "merchant_id")
-    private Long merchantId;
+    private String merchantId;
 
     @Column
     private Integer sort;
 
-    @Column
-    private Integer status;
+    @Enumerated(EnumType.ORDINAL)
+    private ItemStatusEnum status;
+
+    @Column(name = "gmt_created", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtCreated;
+
+    @Column(name = "gmt_modified", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtModified;
 
-    @Column(name = "gmt_created", updatable = false, insertable = false)
-    private Timestamp gmtCreated;
+    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "itemId")
+    @OrderBy("duration asc")
+    private Set<ItemPrice> priceList;
 
-    @Column(name = "gmt_modified")
-    private Timestamp gmtModified;
+    @ManyToMany(fetch = FetchType.LAZY)
+    @JoinTable(name = "lj_item_tag_relation", joinColumns = {@JoinColumn(name="item_id", referencedColumnName="id")},
+            inverseJoinColumns = {@JoinColumn(name = "tag_id", referencedColumnName = "id", unique = false)})
+    private Set<Tag> tagList;
 }

+ 19 - 15
rankin-product-service/src/main/java/cn/rankin/productservice/entity/ItemPrice.java

@@ -1,36 +1,38 @@
 package cn.rankin.productservice.entity;
 
+import cn.rankin.common.utils.enums.PriceTypeEnum;
 import lombok.Data;
 import lombok.ToString;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
+import org.hibernate.annotations.GenericGenerator;
 
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
+import javax.persistence.*;
 import java.io.Serializable;
-import java.sql.Timestamp;
+import java.util.Date;
 
 @Data
 @ToString
 @Entity
-@Table(name = "lj_item_price")
+@Table(name = "lj_item_price",  uniqueConstraints = {@UniqueConstraint(columnNames = {"item_id", "type", "duration"})})
 @DynamicInsert
 @DynamicUpdate
 public class ItemPrice implements Serializable {
 
     @Id
-    private Long id;
+    @GeneratedValue(generator = "uuid")
+    @GenericGenerator(name = "uuid", strategy = "uuid")
+    private String id;
 
     @Column
     private String name;
 
     @Column(name = "item_id")
-    private Long itemId;
+    private String itemId;
 
     @Column
-    private Integer type;
+    @Enumerated(EnumType.ORDINAL)
+    private PriceTypeEnum type;
 
     @Column
     private Integer duration;
@@ -38,18 +40,20 @@ public class ItemPrice implements Serializable {
     @Column(name = "cp_price")
     private Double cpPrice;
 
-    @Column(name = "mr_price")
-    private Double mrPrice;
+    @Column(name = "merchant_price")
+    private Double merchantPrice;
 
-    @Column(name = "tr_price")
-    private Double trPrice;
+    @Column(name = "terminal_price")
+    private Double terminalPrice;
 
     @Column
     private Integer status;
 
     @Column(name = "gmt_created", updatable = false, insertable = false)
-    private Timestamp gmtCreated;
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtCreated;
 
     @Column(name = "gmt_modified")
-    private Timestamp gmtModified;
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtModified;
 }

+ 16 - 10
rankin-product-service/src/main/java/cn/rankin/productservice/entity/Lesson.java

@@ -1,14 +1,15 @@
 package cn.rankin.productservice.entity;
 
+import cn.rankin.common.utils.enums.BaseStatusEnum;
 import lombok.Data;
 import lombok.ToString;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
-import org.hibernate.validator.constraints.Range;
 
 import javax.persistence.*;
 import java.io.Serializable;
-import java.sql.Timestamp;
+import java.util.Date;
+import java.util.List;
 
 @Data
 @ToString
@@ -17,8 +18,9 @@ import java.sql.Timestamp;
 @DynamicInsert
 @DynamicUpdate
 public class Lesson implements Serializable {
+
     @Id
-    private Long id;
+    private String id;
 
     @Column(nullable = false, unique = true)
     private String code;
@@ -30,18 +32,22 @@ public class Lesson implements Serializable {
     private String digest;
 
     @Column
-    @Range(min = 0, max = 100)
-    private Integer type;
-
-    @Column
     private Integer sort;
 
     @Column
-    private Integer status;
+    @Enumerated(EnumType.ORDINAL)
+    private BaseStatusEnum status;
 
     @Column(name = "gmt_created", updatable = false, insertable = false)
-    private Timestamp gmtCreated;
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtCreated;
 
     @Column(name = "gmt_modified")
-    private Timestamp gmtModified;
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtModified;
+
+    @OneToMany(fetch = FetchType.LAZY)
+    @JoinTable(name = "lj_lesson_ware_relation", joinColumns = {@JoinColumn(name = "lesson_id", referencedColumnName = "id")},
+            inverseJoinColumns = {@JoinColumn(name = "ware_id", referencedColumnName = "id")})
+    private List<Ware> wareList;
 }

+ 11 - 11
rankin-product-service/src/main/java/cn/rankin/productservice/entity/LessonWareRelation.java

@@ -5,12 +5,9 @@ import lombok.ToString;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
 
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
+import javax.persistence.*;
 import java.io.Serializable;
-import java.sql.Timestamp;
+import java.util.Date;
 
 @Data
 @ToString
@@ -21,14 +18,17 @@ import java.sql.Timestamp;
 public class LessonWareRelation implements Serializable{
 
     @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
 
-    @Column(name = "lesson_code")
-    private String lessonCode;
+    @Column(name = "lesson_id")
+    private String lessonId;
 
-    @Column(name = "ware_code")
-    private String wareCode;
+    @Column(name = "ware_id")
+    private String wareId;
+
+    @Column(name = "gmt_created", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtCreated;
 
-    @Column(name = "gmt_created", updatable = false, insertable = false)
-    private Timestamp gmtCreated;
 }

+ 53 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/entity/Package.java

@@ -0,0 +1,53 @@
+package cn.rankin.productservice.entity;
+
+import cn.rankin.common.utils.enums.ItemStatusEnum;
+import lombok.Data;
+import lombok.ToString;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@ToString
+@Entity
+@Table(name = "lj_package")
+@DynamicInsert
+@DynamicUpdate
+public class Package implements Serializable {
+
+    @Id
+    private String id;
+
+    @Column(name = "merchant_id")
+    private String merchantId;
+
+    @Column
+    private String name;
+
+    @Column
+    private String digest;
+
+    @Column(name = "cv_img_ids")
+    private String cvImgIds;
+
+    @Column(name = "dis_price")
+    private Double disPrice;
+
+    @Column
+    private Integer sort;
+
+    @Column
+    @Enumerated(EnumType.ORDINAL)
+    private ItemStatusEnum status;
+
+    @Column(name = "gmt_created", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtCreated;
+
+    @Column(name = "gmt_modified", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtModified;
+}

+ 16 - 12
rankin-product-service/src/main/java/cn/rankin/productservice/entity/Support.java

@@ -1,16 +1,15 @@
 package cn.rankin.productservice.entity;
 
+import cn.rankin.common.utils.enums.BaseStatusEnum;
 import lombok.Data;
 import lombok.ToString;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
 
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
+import javax.persistence.*;
 import java.io.Serializable;
-import java.sql.Timestamp;
+import java.util.Date;
+import java.util.Set;
 
 @Data
 @ToString
@@ -21,7 +20,7 @@ import java.sql.Timestamp;
 public class Support implements Serializable {
 
     @Id
-    private Long id;
+    private String id;
 
     @Column
     private String code;
@@ -33,9 +32,6 @@ public class Support implements Serializable {
     private String title;
 
     @Column
-    private Integer type;
-
-    @Column
     private String digest;
 
     @Column
@@ -45,11 +41,19 @@ public class Support implements Serializable {
     private String imgIds;
 
     @Column
-    private Integer status;
+    @Enumerated(EnumType.ORDINAL)
+    private BaseStatusEnum status;
 
     @Column(name = "gmt_created", insertable = false, updatable = false)
-    private Timestamp gmtCreated;
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtCreated;
 
     @Column(name = "gmt_modified")
-    private Timestamp gmtModified;
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtModified;
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(name = "lj_support_reference", joinColumns = {@JoinColumn(name = "fid", referencedColumnName = "id")},
+            inverseJoinColumns = {@JoinColumn(name = "tid", referencedColumnName = "id")})
+    private Set<Support> supportList;
 }

+ 9 - 11
rankin-product-service/src/main/java/cn/rankin/productservice/entity/SupportCircleRelation.java

@@ -5,30 +5,28 @@ import lombok.ToString;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
 
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
+import javax.persistence.*;
 import java.io.Serializable;
-import java.sql.Timestamp;
+import java.util.Date;
 
 @Data
 @ToString
 @Entity
-@Table(name = "lj_circle_relation")
+@Table(name = "lj_support_self_relation")
 @DynamicInsert
 @DynamicUpdate
-public class SupportCircleRelation implements Serializable {
+public class SupportSelfRelation implements Serializable {
 
     @Id
-    private Long id;
+    private String id;
 
     @Column
-    private String fcode;
+    private String fid;
 
     @Column
-    private String tcode;
+    private String tid;
 
     @Column(name = "gmt_created", insertable = false, updatable = false)
-    private Timestamp gmtCreated;
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtCreated;
 }

+ 16 - 13
rankin-product-service/src/main/java/cn/rankin/productservice/entity/Tag.java

@@ -1,16 +1,15 @@
 package cn.rankin.productservice.entity;
 
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.enums.TagTypeEnum;
 import lombok.Data;
 import lombok.ToString;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
 
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
+import javax.persistence.*;
 import java.io.Serializable;
-import java.sql.Timestamp;
+import java.util.Date;
 
 @Data
 @ToString
@@ -21,7 +20,7 @@ import java.sql.Timestamp;
 public class Tag implements Serializable {
 
     @Id
-    private Long id;
+    private String id;
 
     @Column
     private String code;
@@ -30,20 +29,24 @@ public class Tag implements Serializable {
     private String name;
 
     @Column
-    private Integer type;
+    @Enumerated(EnumType.ORDINAL)
+    private TagTypeEnum type;
 
     @Column(name = "merchant_id")
-    private Long merchantId;
+    private String merchantId;
 
     @Column
     private Integer sort;
 
     @Column
-    private Integer status;
+    @Enumerated(EnumType.ORDINAL)
+    private BaseStatusEnum status;
 
-    @Column(name = "gmt_created", updatable = false, insertable = false)
-    private Timestamp gmtCreated;
+    @Column(name = "gmt_created", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtCreated;
 
-    @Column(name = "gmt_modified")
-    private Timestamp gmtModified;
+    @Column(name = "gmt_modified", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtModified;
 }

+ 0 - 46
rankin-product-service/src/main/java/cn/rankin/productservice/entity/Unit.java

@@ -1,46 +0,0 @@
-package cn.rankin.productservice.entity;
-
-import lombok.Data;
-import lombok.ToString;
-import org.hibernate.annotations.DynamicInsert;
-import org.hibernate.annotations.DynamicUpdate;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import java.io.Serializable;
-import java.sql.Timestamp;
-
-@Data
-@ToString
-@Entity
-@Table(name = "lj_unit")
-@DynamicInsert
-@DynamicUpdate
-public class Unit implements Serializable{
-
-    @Id
-    private Long id;
-
-    @Column
-    private String code;
-
-    @Column
-    private  String name;
-
-    @Column
-    private String digest;
-
-    @Column
-    private Integer sort;
-
-    @Column
-    private Integer status;
-
-    @Column(name = "gmt_created", updatable = false, insertable = false)
-    private Timestamp gmtCreated;
-
-    @Column(name = "gmt_modified")
-    private Timestamp gmtModified;
-}

+ 0 - 34
rankin-product-service/src/main/java/cn/rankin/productservice/entity/UnitLessonRelation.java

@@ -1,34 +0,0 @@
-package cn.rankin.productservice.entity;
-
-import lombok.Data;
-import lombok.ToString;
-import org.hibernate.annotations.DynamicInsert;
-import org.hibernate.annotations.DynamicUpdate;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import java.io.Serializable;
-import java.sql.Timestamp;
-
-@Data
-@ToString
-@Entity
-@Table(name = "lj_unit_lesson_relation")
-@DynamicInsert
-@DynamicUpdate
-public class UnitLessonRelation implements Serializable{
-
-    @Id
-    private Long id;
-
-    @Column(name = "unit_code")
-    private String unitCode;
-
-    @Column(name = "lesson_code")
-    private String lessonCode;
-
-    @Column(name = "gmt_created", updatable = false, insertable = false)
-    private Timestamp gmtCreated;
-}

+ 17 - 10
rankin-product-service/src/main/java/cn/rankin/productservice/entity/Ware.java

@@ -1,14 +1,15 @@
 package cn.rankin.productservice.entity;
 
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.enums.WareTypeEnum;
 import lombok.Data;
 import lombok.ToString;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
-import org.hibernate.validator.constraints.Range;
 
 import javax.persistence.*;
 import java.io.Serializable;
-import java.sql.Timestamp;
+import java.util.Date;
 
 @Data
 @ToString
@@ -19,7 +20,7 @@ import java.sql.Timestamp;
 public class Ware implements Serializable{
 
     @Id
-    private Long id;
+    private String id;
 
     @Column(nullable = false, unique = true)
     private String code;
@@ -31,8 +32,8 @@ public class Ware implements Serializable{
     private String digest;
 
     @Column
-    @Range(min = 0, max = 100)
-    private Integer type;
+    @Enumerated(EnumType.ORDINAL)
+    private WareTypeEnum type;
 
     @Column(name = "play_url")
     private String playUrl;
@@ -40,16 +41,22 @@ public class Ware implements Serializable{
     @Column(name = "img_ids")
     private String imgIds;
 
+    @Column(name = "cp_id")
+    private String cpId;
+
     @Column
     private Integer sort;
 
     @Column
-    private Integer status;
+    @Enumerated(EnumType.ORDINAL)
+    private BaseStatusEnum status;
 
-    @Column(name = "gmt_created", updatable = false, insertable = false)
-    private Timestamp gmtCreated;
+    @Column(name = "gmt_created", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtCreated;
 
-    @Column(name = "gmt_modified")
-    private Timestamp gmtModified;
+    @Column(name = "gmt_modified", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtModified;
 
 }

+ 0 - 11
rankin-product-service/src/main/java/cn/rankin/productservice/repository/BasicRepository.java

@@ -1,11 +0,0 @@
-package cn.rankin.productservice.repository;
-
-import java.io.Serializable;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.repository.NoRepositoryBean;
-
-@NoRepositoryBean
-public interface BasicRepository <E, ID extends Serializable> extends JpaRepository<E, ID> {
-
-}
-

+ 21 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/repository/CourseRepository.java

@@ -0,0 +1,21 @@
+package cn.rankin.productservice.repository;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.productservice.entity.Course;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.transaction.annotation.Transactional;
+
+public interface CourseRepository extends BasicJpaRepository<Course, String> {
+
+    Long countByCode(String code);
+
+    Course findById(String id);
+
+    @Transactional
+    @Modifying(clearAutomatically = true)
+    @Query(value = "update Course c set c.status = :status where c.id = :id")
+    Integer updateStatusById(@Param("id") String id, @Param("status") BaseStatusEnum status);
+}

+ 16 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/repository/CourseSubRelationRepository.java

@@ -0,0 +1,16 @@
+package cn.rankin.productservice.repository;
+
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.productservice.entity.CourseSubRelation;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+public interface CourseSubRelationRepository extends BasicJpaRepository<CourseSubRelation, String> {
+
+    Long deleteByCourseId(String courseId);
+
+    @Query(value = "select r from CourseSubRelation r where r.courseId = :courseId order by r.sort")
+    List<CourseSubRelation> findByCourseId(@Param("courseId") String courseId);
+}

+ 14 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/repository/ItemPriceRepository.java

@@ -0,0 +1,14 @@
+package cn.rankin.productservice.repository;
+
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.productservice.entity.ItemPrice;
+
+import java.util.List;
+
+public interface ItemPriceRepository extends BasicJpaRepository<ItemPrice, String> {
+
+
+    List<ItemPrice> findByItemId(Long itemId);
+
+    Long countById(String id);
+}

+ 18 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/repository/ItemRepository.java

@@ -0,0 +1,18 @@
+package cn.rankin.productservice.repository;
+
+import cn.rankin.common.utils.enums.ItemStatusEnum;
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.productservice.entity.Item;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import javax.transaction.Transactional;
+
+public interface ItemRepository extends BasicJpaRepository<Item, String> {
+
+    @Transactional
+    @Modifying(clearAutomatically = true)
+    @Query(value = "update Item i set i.status = :status where i.id = :itemId")
+    Integer updateStatusById(@Param("itemId") String itemId, @Param("status") ItemStatusEnum status);
+}

+ 15 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/repository/LessonRepository.java

@@ -0,0 +1,15 @@
+package cn.rankin.productservice.repository;
+
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.productservice.entity.Lesson;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface LessonRepository extends BasicJpaRepository<Lesson, String> {
+
+    Long countByCode(String code);
+
+    Long countByIdIn(List<String> ids);
+}

+ 23 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/repository/SupportRepository.java

@@ -0,0 +1,23 @@
+package cn.rankin.productservice.repository;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.productservice.entity.Support;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+public interface SupportRepository extends BasicJpaRepository<Support, String> {
+
+    Long countByCode(String code);
+
+    Long countByIdIn(List<String> ids);
+
+    @Transactional
+    @Modifying(clearAutomatically = true)
+    @Query(value = "update Support s set s.status = :status where s.id = :id")
+    Integer updateStatusById(@Param("id") String id, @Param("status") BaseStatusEnum status);
+}

+ 16 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/repository/SupportSelfRelationRepository.java

@@ -0,0 +1,16 @@
+package cn.rankin.productservice.repository;
+
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.productservice.entity.SupportSelfRelation;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+public interface SupportSelfRelationRepository extends BasicJpaRepository<SupportSelfRelation, String> {
+
+   Long deleteAllByFid(String fid);
+
+   @Query(value = "select distinct s.tid from SupportSelfRelation s where s.fid = :fid")
+   List<String> findRefByFid(@Param("fid") String fid);
+}

+ 24 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/repository/TagRepository.java

@@ -0,0 +1,24 @@
+package cn.rankin.productservice.repository;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.productservice.entity.Tag;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+
+public interface TagRepository extends BasicJpaRepository<Tag, String> {
+
+    Long countByIdIn(List<String> ids);
+
+    Long countByCode(String code);
+
+    @Transactional
+    @Modifying(clearAutomatically = true)
+    @Query(value = "update Tag t set t.status = :status where t.id = :id")
+    Integer updateStatusById(@Param("id") String id, @Param("status") BaseStatusEnum status);
+}

+ 8 - 1
rankin-product-service/src/main/java/cn/rankin/productservice/repository/WareRepository.java

@@ -1,9 +1,16 @@
 package cn.rankin.productservice.repository;
 
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
 import cn.rankin.productservice.entity.Ware;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
+
 @Repository
-public interface WareRepository extends BasicRepository<Ware, Long> {
+public interface WareRepository extends BasicJpaRepository<Ware, String> {
+
+    Long countByCode(String code);
+
+    Long countByIdIn(List<String> Ids);
 
 }

+ 192 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/service/CourseService.java

@@ -0,0 +1,192 @@
+package cn.rankin.productservice.service;
+
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.dto.product.CourseDTO;
+import cn.rankin.common.utils.dto.product.SubRelationDTO;
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.enums.CourseSubTypeEnum;
+import cn.rankin.common.utils.util.ListToMapUtil;
+import cn.rankin.productservice.entity.*;
+import cn.rankin.productservice.repository.*;
+import cn.rankin.productservice.utils.DTOConverter;
+import cn.rankin.productservice.vo.CourseSubItemVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class CourseService {
+
+    @Autowired
+    private CourseRepository courseRepository;
+
+    @Autowired
+    private LessonRepository lessonRepository;
+
+    @Autowired
+    private CourseSubRelationRepository subRelationRepository;
+
+    public boolean exists(String code) {
+        Long count = courseRepository.countByCode(code);
+        return count > 0L;
+    }
+
+    public boolean checkSubItemIds(List<SubRelationDTO> subRelationDTOList) {
+        // TODO: 目前只包含课
+        if (subRelationDTOList == null || subRelationDTOList.size() == 0) {
+            return true;
+        }
+
+        List<String> lessonIdList = new ArrayList<>();
+        subRelationDTOList.forEach( r -> {
+            String subId = r.getId();
+            CourseSubTypeEnum type = r.getType();
+            if (type.equals(CourseSubTypeEnum.LESSON)) {
+                lessonIdList.add(subId);
+            }
+        });
+        Long count = lessonRepository.countByIdIn(lessonIdList);
+        if (count < lessonIdList.size()) {
+            return false;
+        }
+        return true;
+    }
+
+    @Transactional
+    public List<CourseSubRelation> updateSubRelation(String courseId, List<SubRelationDTO> subRelationDTOList) {
+        // TODO: 暂时不考虑单元
+        if (subRelationDTOList == null) {
+            return null;
+        }
+
+        Long count = subRelationRepository.deleteByCourseId(courseId);
+        log.info("delete course sub item, code={}, num={}", courseId, String.valueOf(count));
+
+        List<CourseSubRelation> subRelationList = new ArrayList<>();
+        for (int i = 0; i < subRelationDTOList.size(); i++) {
+            SubRelationDTO relationDTO = subRelationDTOList.get(i);
+            CourseSubRelation relation = new CourseSubRelation();
+            relation.setCourseId(courseId);
+            relation.setSubId(relationDTO.getId());
+            relation.setType(relationDTO.getType());
+            relation.setSort(i);
+            subRelationList.add(relation);
+        }
+
+        List<CourseSubRelation> result = subRelationRepository.save(subRelationList);
+        return result;
+    }
+
+    public APIResult<Page<Course>> search(Course course, Integer pageNo, Integer pageSize) {
+        Long count = courseRepository.count(course);
+        Page<Course> page = new Page(count, pageNo, pageSize);
+
+        if (count == 0) {
+            return APIResult.ok(page);
+        }
+
+        List<Course> wareList = courseRepository.find(course, page.getStart(), pageSize);
+        page.setList(wareList);
+
+        return APIResult.ok(page);
+    }
+
+    @Transactional
+    public APIResult<Course> create(CourseDTO courseDTO) {
+        String code = courseDTO.getCode();
+        if (exists(code)) {
+            return APIResult.error(APICodeManager.ALREADY_EXISTS);
+        }
+
+        // sub item check
+        List<SubRelationDTO> subRelationDTOList = courseDTO.getSubList();
+        if (!checkSubItemIds(subRelationDTOList)) {
+            return APIResult.error(APICodeManager.error("包含错误课编码"));
+        }
+
+
+        Course course = DTOConverter.convert(courseDTO);
+        Course result = courseRepository.save(course);
+
+        String courseId = result.getId();
+        updateSubRelation(courseId, subRelationDTOList);
+
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<Course> update(CourseDTO courseDTO) {
+        List<SubRelationDTO> subRelationDTOList = courseDTO.getSubList();
+        if (!checkSubItemIds(subRelationDTOList)) {
+            return APIResult.error(APICodeManager.error("包含错误课编码"));
+        }
+
+        Course course = DTOConverter.convert(courseDTO);
+        Course result = courseRepository.save(course);
+
+        String courseId = result.getId();
+        updateSubRelation(courseId, subRelationDTOList);
+
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<Boolean> delete(String id) {
+        Integer count = courseRepository.updateStatusById(id, BaseStatusEnum.DEL);
+        if (count > 0) {
+            return APIResult.ok(true);
+        }
+        return APIResult.error(APICodeManager.NOT_EXISTS);
+    }
+
+    public APIResult<Course> findById(String id) {
+        //TODO: 目前只加载课, 不加载单元
+        Course course = courseRepository.findById(id);
+        if (course == null) {
+            return APIResult.error(APICodeManager.NOT_EXISTS);
+        }
+
+        // 你瞅瞅, 加上单元难不难?
+        List<CourseSubRelation> subRelationList = subRelationRepository.findByCourseId(id);
+        if (subRelationList == null || subRelationList.size() == 0) {
+            return APIResult.ok(course);
+        }
+
+        List<CourseSubItemVo> subItemVoList = new ArrayList<>();
+
+        List<String> lessonIdList = new ArrayList<>();
+        subRelationList.forEach( rel -> {
+            CourseSubTypeEnum type = rel.getType();
+            String subId = rel.getSubId();
+            if (type.equals(CourseSubTypeEnum.LESSON)) {
+                lessonIdList.add(subId);
+            }
+        });
+
+        List<Lesson> lessonList = lessonRepository.findByIds(lessonIdList);
+        Map<String, Lesson> lessonMap = new ListToMapUtil<String, Lesson>(lessonList).parse("id");
+
+        for(CourseSubRelation rel: subRelationList) {
+            String subCode = rel.getSubId();
+            CourseSubTypeEnum type = rel.getType();
+            if (type.equals(CourseSubTypeEnum.LESSON)) {
+                Lesson lesson = lessonMap.get(subCode);
+                CourseSubItemVo vo = CourseSubItemVo.parseToVo(lesson);
+                subItemVoList.add(vo);
+            }
+        }
+
+        course.setSubItemList(subItemVoList);
+
+        return APIResult.ok(course);
+    }
+
+}

+ 105 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/service/ItemPriceService.java

@@ -0,0 +1,105 @@
+package cn.rankin.productservice.service;
+
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.dto.product.ItemPriceDTO;
+import cn.rankin.productservice.entity.ItemPrice;
+import cn.rankin.productservice.repository.ItemPriceRepository;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.transaction.Transactional;
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+@Service
+public class ItemPriceService {
+
+    @Autowired
+    private ItemPriceRepository priceRepository;
+
+    public List<ItemPrice> findByItemId(Long itemId) {
+        return priceRepository.findByItemId(itemId);
+    }
+
+    public ItemPrice findById(String priceId) {
+        return priceRepository.find(priceId);
+    }
+
+    public boolean exists(ItemPriceDTO priceDTO) {
+        ItemPrice price = new ItemPrice();
+        price.setItemId(priceDTO.getItemId());
+        price.setType(priceDTO.getType());
+        price.setDuration(priceDTO.getDuration());
+
+        Long count = priceRepository.count(price);
+
+        return count > 0L;
+    }
+
+    @Transactional
+    public APIResult<ItemPrice> create(ItemPriceDTO priceDTO) {
+        if (exists(priceDTO)) {
+            return APIResult.error(APICodeManager.ALREADY_EXISTS);
+        }
+
+        ItemPrice price = new ItemPrice();
+        BeanUtils.copyProperties(priceDTO, price);
+
+        ItemPrice result = priceRepository.save(price);
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<ItemPrice> update(ItemPriceDTO priceDTO) {
+        if (!exists(priceDTO)) {
+            return APIResult.error(APICodeManager.NOT_EXISTS);
+        }
+
+        ItemPrice price = new ItemPrice();
+        BeanUtils.copyProperties(priceDTO, price);
+        ItemPrice result = priceRepository.update(price);
+
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<List<ItemPrice>> createMulti(List<ItemPriceDTO> priceDTOList) {
+        List<ItemPrice> priceList = new ArrayList<>();
+        priceDTOList.forEach( dto -> {
+            ItemPrice price = new ItemPrice();
+            BeanUtils.copyProperties(dto, price);
+            priceList.add(price);
+        });
+
+        List<ItemPrice> result = priceRepository.save(priceList);
+
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<List<ItemPrice>> updateMulti(List<ItemPriceDTO> priceDTOList) {
+        List<ItemPrice> priceList = new ArrayList<>();
+        priceDTOList.forEach( dto -> {
+            ItemPrice price = new ItemPrice();
+            BeanUtils.copyProperties(dto, price);
+            priceList.add(price);
+        });
+
+        List<ItemPrice> result = priceRepository.update(priceList);
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<Boolean> deleteById(String priceId) {
+        Long count = priceRepository.countById(priceId);
+        if (count == 0) {
+            return APIResult.error(APICodeManager.NOT_EXISTS);
+        }
+        priceRepository.delete(priceId);
+        return APIResult.ok(true);
+    }
+}

+ 106 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/service/ItemService.java

@@ -0,0 +1,106 @@
+package cn.rankin.productservice.service;
+
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.dto.product.ItemDTO;
+import cn.rankin.common.utils.enums.ItemStatusEnum;
+import cn.rankin.productservice.entity.Item;
+import cn.rankin.productservice.repository.*;
+import cn.rankin.productservice.utils.DTOConverter;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.transaction.Transactional;
+import java.util.*;
+
+@Slf4j
+@Service
+public class ItemService {
+
+    @Autowired
+    private ItemRepository itemRepository;
+
+    @Autowired
+    private CourseRepository courseRepository;
+
+    public boolean checkCourseCode(String code) {
+        Long count = courseRepository.countByCode(code);
+        return count > 0L;
+    }
+
+    public boolean exists(Item item) {
+        Long count = itemRepository.count(item);
+        return count > 0L;
+    }
+
+    public APIResult<Page<Item>> search(Item item, Integer pageNo, Integer pageSize) {
+        Long count = itemRepository.count(item);
+        Page<Item> page = new Page(count, pageNo, pageSize);
+
+        if (count == 0) {
+            return APIResult.ok(page);
+        }
+
+        List<Item> itemList = itemRepository.find(item, page.getStart(), pageSize);
+        page.setList(itemList);
+
+        return APIResult.ok(page);
+    }
+
+    @Transactional
+    public APIResult<Item> create(ItemDTO itemDTO) {
+        // 检查course是否存在
+        String code = itemDTO.getCode();
+        if (!checkCourseCode(code)) {
+            return APIResult.error(APICodeManager.error("课程不存在"));
+        }
+
+        // 检查course与merchantId的唯一性
+        Item sample = new Item();
+        sample.setCourseId(itemDTO.getCourseId());
+        sample.setMerchantId(itemDTO.getMerchantId());
+        if (exists(sample)) {
+            return APIResult.error(APICodeManager.ALREADY_EXISTS);
+        }
+
+        // 保存item数据
+        Item item = DTOConverter.convert(itemDTO);
+        Item result = itemRepository.save(item);
+
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<Boolean> delete(String itemId) {
+        Integer count = itemRepository.updateStatusById(itemId, ItemStatusEnum.DEL);
+        if (count > 0) {
+            return APIResult.ok(true);
+        }
+        return APIResult.error(APICodeManager.NOT_EXISTS);
+    }
+
+    @Transactional
+    public APIResult<Item> update(ItemDTO itemDTO) {
+        // 检查course是否存在
+        String code = itemDTO.getCode();
+        if (!checkCourseCode(code)) {
+            return APIResult.error(APICodeManager.error("课程不存在"));
+        }
+
+        // 检查course与merchantId是否存在
+        Item sample = new Item();
+        sample.setCourseId(itemDTO.getCourseId());
+        sample.setMerchantId(itemDTO.getMerchantId());
+        if (!exists(sample)) {
+            return APIResult.error(APICodeManager.ALREADY_EXISTS);
+        }
+
+        // 保存item数据
+        Item item = DTOConverter.convert(itemDTO);
+        Item result = itemRepository.update(item);
+
+        return APIResult.ok(result);
+    }
+}

+ 137 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/service/LessonService.java

@@ -0,0 +1,137 @@
+package cn.rankin.productservice.service;
+
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.dto.product.LessonDTO;
+import cn.rankin.productservice.entity.Lesson;
+import cn.rankin.productservice.repository.LessonRepository;
+import cn.rankin.productservice.repository.WareRepository;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+@Slf4j
+@Service
+public class LessonService {
+
+    @Autowired
+    private LessonRepository lessonRepository;
+
+    @Autowired
+    private WareRepository wareRepository;
+
+    public APIResult<Page<Lesson>> search(Lesson lesson, Integer pageNo, Integer pageSize) {
+        Long count = lessonRepository.count(lesson);
+        Page<Lesson> page = new Page(count, pageNo, pageSize);
+
+        if (count == 0) {
+            return APIResult.ok(page);
+        }
+
+        List<Lesson> wareList = lessonRepository.find(lesson, page.getStart(), pageSize);
+        page.setList(wareList);
+
+        return APIResult.ok(page);
+    }
+
+    public static Lesson convert(LessonDTO lessonDTO) {
+        Lesson lesson = new Lesson();
+        BeanUtils.copyProperties(lessonDTO, lesson);
+
+//        List<WareDTO> wareDTOList = lessonDTO.getWareList();
+//        if (CollectionUtils.isEmpty(wareDTOList)) {
+//            return lesson;
+//        }
+//
+//        List<Ware> wareList = new ArrayList<>();
+//        wareDTOList.forEach( dto -> {
+//            Ware ware = new Ware();
+//            BeanUtils.copyProperties(dto, ware);
+//            wareList.add(ware);
+//        });
+//
+//        lesson.setWareList(wareList);
+        return lesson;
+    }
+
+    public APIResult<Lesson> findById(String id) {
+        Lesson lesson = lessonRepository.find(id);
+        if (lesson == null) {
+            return APIResult.error(APICodeManager.NOT_EXISTS);
+        }
+
+        return APIResult.ok(lesson);
+    }
+
+    public boolean exists(String code) {
+        Long count = lessonRepository.countByCode(code);
+        return count > 0L;
+    }
+
+    public boolean checkWareIds(Set<String> wareIdSet) {
+        if (wareIdSet == null || wareIdSet.size() == 0) {
+            return true;
+        }
+
+        List<String> wareIdList = new ArrayList<>();
+        wareIdList.addAll(wareIdSet);
+
+        Long count = wareRepository.countByIdIn(wareIdList);
+        if (count < wareIdSet.size()) {
+            return false;
+        }
+        return true;
+    }
+
+    @Transactional
+    public APIResult<Lesson> create(LessonDTO lessonDTO) {
+        String code = lessonDTO.getCode();
+        if (exists(code)) {
+            return APIResult.error(APICodeManager.ALREADY_EXISTS);
+        }
+
+//        Set<String> wareIdSet = lessonDTO.getWareList();
+//        if (!checkWareIds(wareIdSet)) {
+//            log.error("lesson: {} contains error ware code: {}", code, JSON.toJSONString(wareIdSet));
+//            return APIResult.error(APICodeManager.error("包含错误的课件"));
+//        }
+
+        Lesson lesson = convert(lessonDTO);
+        Lesson result = lessonRepository.save(lesson);
+
+//        String lessonId = result.getId();
+//        updateWareRelation(lessonId, wareIdSet);
+
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<Lesson> update(Lesson lessonDTO) {
+//        Set<String> wareIdSet = lessonDTO.getWareList();
+//        if (!checkWareIds(wareIdSet)) {
+//            return APIResult.error(APICodeManager.error("包含错误的课件"));
+//        }
+
+//        Lesson lesson = convert(lessonDTO);
+        Lesson result = lessonRepository.update(lessonDTO);
+
+//        String lessonId = result.getId();
+//        updateWareRelation(lessonId, wareIdSet);
+
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<Boolean> delete(String id) {
+        lessonRepository.delete(id);
+        return APIResult.ok(true);
+    }
+
+}

+ 165 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/service/SupportService.java

@@ -0,0 +1,165 @@
+package cn.rankin.productservice.service;
+
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.dto.product.SupportDTO;
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.productservice.entity.Support;
+import cn.rankin.productservice.entity.SupportSelfRelation;
+import cn.rankin.productservice.repository.SupportRepository;
+import cn.rankin.productservice.repository.SupportSelfRelationRepository;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@Slf4j
+@Service
+public class SupportService {
+
+    @Autowired
+    private SupportRepository supportRepository;
+
+    @Autowired
+    private SupportSelfRelationRepository selfRelationRepository;
+
+    public static Support convert(SupportDTO supportDTO) {
+        Support support = new Support();
+        BeanUtils.copyProperties(supportDTO, support);
+        Set<String> supportIdSet = supportDTO.getSupportList();
+        if (supportIdSet != null && supportIdSet.size() > 0) {
+            Set<Support> supportSet = new HashSet<>();
+            supportIdSet.forEach( e -> {
+                Support s = new Support();
+                s.setId(e);
+                supportSet.add(s);
+            });
+            support.setSupportList(supportSet);
+        }
+        return support;
+    }
+
+    public APIResult<Page<Support>> search(Support support, Integer pageNo, Integer pageSize) {
+        Long count = supportRepository.count(support);
+        Page<Support> page = new Page(count, pageNo, pageSize);
+
+        if (count == 0) {
+            return APIResult.ok(page);
+        }
+
+        List<Support> supportList = supportRepository.find(support, page.getStart(), pageSize);
+        page.setList(supportList);
+
+        return APIResult.ok(page);
+    }
+
+    public boolean exists(String code) {
+        Long count = supportRepository.countByCode(code);
+        return count > 0;
+    }
+
+    public boolean checkSupportIds(Set<String> supportSet) {
+        if (supportSet == null || supportSet.size() == 0) {
+            return true;
+        }
+
+        List<String> supportIdList = new ArrayList<>();
+        supportIdList.addAll(supportSet);
+        Long count = supportRepository.countByIdIn(supportIdList);
+        if (count < supportSet.size()) {
+            return false;
+        }
+        return true;
+    }
+
+    @Transactional
+    public List<SupportSelfRelation> updateSupportList(String supportId, Set<String> supportIdSet) {
+        if (supportIdSet == null) {
+            return null;
+        }
+
+        selfRelationRepository.deleteAllByFid(supportId);
+
+        List<SupportSelfRelation> supportSelfRelationList = new ArrayList<>();
+        for (String s : supportIdSet) {
+            SupportSelfRelation relation = new SupportSelfRelation();
+            relation.setFid(supportId);
+            relation.setTid(s);
+            supportSelfRelationList.add(relation);
+        }
+
+        return selfRelationRepository.save(supportSelfRelationList);
+    }
+
+    @Transactional
+    public APIResult<Support> create(SupportDTO supportDTO) {
+        String code = supportDTO.getCode();
+        if (exists(code)) {
+            return APIResult.error(APICodeManager.ALREADY_EXISTS);
+        }
+
+        Set<String> supportIdSet = supportDTO.getSupportList();
+        if (!checkSupportIds(supportIdSet)) {
+            return APIResult.error(APICodeManager.error("包含错误的id"));
+        }
+
+        Support support = convert(supportDTO);
+        Support result = supportRepository.save(support);
+
+        String supportId = result.getId();
+        updateSupportList(supportId, supportIdSet);
+
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<Support> update(SupportDTO supportDTO) {
+        Set<String> supportIdSet = supportDTO.getSupportList();
+        if (!checkSupportIds(supportIdSet)) {
+            return APIResult.error(APICodeManager.error("存在错误的周边编号"));
+        }
+
+        Support support = convert(supportDTO);
+        Support result = supportRepository.save(support);
+        
+        String supportId = result.getId();
+        updateSupportList(supportId, supportIdSet);
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<Boolean> delete(String id) {
+        Integer count = supportRepository.updateStatusById(id, BaseStatusEnum.DEL);
+        if (count > 0) {
+            return APIResult.ok(true);
+        }
+
+        return APIResult.error(APICodeManager.NOT_EXISTS);
+    }
+
+    public APIResult<Support> findById(String id) {
+//        SupportVo supportVo = new SupportVo();
+        Support support = supportRepository.find(id);
+        if (support == null) {
+            return APIResult.error(APICodeManager.NOT_EXISTS);
+        }
+//        }else {
+//            BeanUtils.copyProperties(support, supportVo);
+//        }
+
+//        List<String> supportIdList = selfRelationRepository.findRefByFid(id);
+//        List<Support> supportList = supportRepository.findByIds(supportIdList);
+//
+//        supportVo.setSupportList(supportList);
+
+        return APIResult.ok(support);
+    }
+
+}

+ 84 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/service/TagService.java

@@ -0,0 +1,84 @@
+package cn.rankin.productservice.service;
+
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.dto.product.TagDTO;
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.productservice.entity.Tag;
+import cn.rankin.productservice.repository.TagRepository;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Slf4j
+@Service
+public class TagService {
+
+    @Autowired
+    private TagRepository tagRepository;
+
+    public APIResult<Page<Tag>> search(Tag tag, Integer pageNo, Integer pageSize) {
+        Long count = tagRepository.count(tag);
+        Page<Tag> page = new Page(count, pageNo, pageSize);
+
+        if (count == 0) {
+            return APIResult.ok(page);
+        }
+
+        List<Tag> tagList = tagRepository.find(tag, page.getStart(), pageSize);
+        page.setList(tagList);
+
+        return APIResult.ok(page);
+    }
+
+    public boolean exists(String code) {
+        Long count = tagRepository.countByCode(code);
+        return count > 0L;
+    }
+
+    public static Tag convert(TagDTO tagDTO) {
+        Tag tag = new Tag();
+        BeanUtils.copyProperties(tagDTO, tag);
+        return tag;
+    }
+
+    @Transactional
+    public APIResult<Tag> create(TagDTO tagDTO) {
+        String code = tagDTO.getCode();
+        if (exists(code)) {
+            return APIResult.error(APICodeManager.ALREADY_EXISTS);
+        }
+
+        Tag tag = convert(tagDTO);
+        Tag result = tagRepository.save(tag);
+
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<Tag> update(TagDTO tagDTO) {
+        String code = tagDTO.getCode();
+        if (!exists(code)) {
+            return APIResult.error(APICodeManager.NOT_EXISTS);
+        }
+
+        Tag tag = convert(tagDTO);
+        Tag result = tagRepository.update(tag);
+
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<Boolean> delete(String id) {
+        Integer count = tagRepository.updateStatusById(id, BaseStatusEnum.DEL);
+        if (count > 0) {
+            return APIResult.ok(true);
+        }
+        return APIResult.error(APICodeManager.NOT_EXISTS);
+    }
+}

+ 78 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/service/WareService.java

@@ -0,0 +1,78 @@
+package cn.rankin.productservice.service;
+
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.dto.product.WareDTO;
+import cn.rankin.productservice.entity.Ware;
+import cn.rankin.productservice.repository.WareRepository;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Slf4j
+@Service
+public class WareService {
+
+    @Autowired
+    private WareRepository wareRepository;
+
+    public APIResult<Page<Ware>> search(Ware ware, Integer pageNo, Integer pageSize) {
+        Long count = wareRepository.count(ware);
+        Page<Ware> page = new Page(count, pageNo, pageSize);
+
+        if (count == 0) {
+            return APIResult.ok(page);
+        }
+
+        List<Ware> wareList = wareRepository.find(ware, page.getStart(), pageSize);
+        page.setList(wareList);
+
+        return APIResult.ok(page);
+    }
+
+    public boolean exists(String code) {
+        Long count = wareRepository.countByCode(code);
+        return count > 0L;
+    }
+
+    public static Ware convert(WareDTO wareDTO) {
+        Ware ware = new Ware();
+        BeanUtils.copyProperties(wareDTO, ware);
+        return ware;
+    }
+
+    @Transactional
+    public APIResult<Ware> create(WareDTO wareDTO) {
+        Ware ware = convert(wareDTO);
+        Ware result = wareRepository.save(ware);
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<Ware> update(WareDTO wareDTO) {
+        Ware ware = convert(wareDTO);
+        Ware result = wareRepository.update(ware);
+
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<Boolean> delete(String id) {
+        wareRepository.delete(id);
+        return APIResult.ok(true);
+    }
+
+    public APIResult<Ware> findById(String id) {
+        Ware ware = wareRepository.find(id);
+        if (ware == null) {
+            return APIResult.error(APICodeManager.NOT_EXISTS);
+        }
+        return APIResult.ok(ware);
+    }
+
+}

+ 79 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/utils/DTOConverter.java

@@ -0,0 +1,79 @@
+package cn.rankin.productservice.utils;
+
+import cn.rankin.common.utils.dto.product.*;
+import cn.rankin.productservice.entity.*;
+import org.springframework.beans.BeanUtils;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class DTOConverter {
+
+    // ItemDTO to Item
+    public static Item convert(ItemDTO itemDTO) {
+        Item item = new Item();
+        BeanUtils.copyProperties(itemDTO, item);
+
+        List<ItemPriceDTO> priceDTOList = itemDTO.getPriceList();
+        if (priceDTOList == null || priceDTOList.size() == 0) {
+            return item;
+        }
+
+        Set<ItemPrice> priceList = new HashSet<>();
+        priceDTOList.forEach(dto -> priceList.add(convert(dto)));
+        item.setPriceList(priceList);
+
+        Set<String> tagDTOList = itemDTO.getTagList();
+        if (tagDTOList == null || tagDTOList.size() == 0) {
+            return item;
+        }
+        Set<Tag> tagSet = new HashSet<>();
+        tagDTOList.forEach( tagId -> {
+            Tag tag = new Tag();
+            tag.setId(tagId);
+            tagSet.add(tag);
+        });
+        item.setTagList(tagSet);
+
+        return item;
+    }
+
+    // CourseDTO to Course
+    public static Course convert(CourseDTO courseDTO) {
+        Course course = new Course();
+        BeanUtils.copyProperties(courseDTO, course);
+
+        List<SupportDTO> supportDTOList = courseDTO.getSupportList();
+        if (supportDTOList == null || supportDTOList.size() == 0) {
+            return course;
+        }
+
+        List<Support> supportList = new ArrayList<>();
+        supportDTOList.forEach( dto -> supportList.add(convert(dto)));
+        course.setSupportList(supportList);
+        return course;
+    }
+
+    // WareDTO to Ware
+    public static Ware convert(WareDTO wareDTO) {
+        Ware ware = new Ware();
+        BeanUtils.copyProperties(wareDTO, ware);
+        return ware;
+    }
+
+    // SupportDTO to Support
+    public static Support convert(SupportDTO supportDTO) {
+        Support support = new Support();
+        BeanUtils.copyProperties(supportDTO, support);
+        return support;
+    }
+
+    // PriceDTO to Price
+    public static ItemPrice convert(ItemPriceDTO itemPriceDTO) {
+        ItemPrice itemPrice = new ItemPrice();
+        BeanUtils.copyProperties(itemPriceDTO, itemPrice);
+        return itemPrice;
+    }
+}

+ 41 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/vo/CourseSubItemVo.java

@@ -0,0 +1,41 @@
+package cn.rankin.productservice.vo;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.enums.CourseSubTypeEnum;
+import cn.rankin.productservice.entity.Lesson;
+import lombok.Data;
+import org.springframework.beans.BeanUtils;
+
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class CourseSubItemVo implements Serializable{
+
+    private String id;
+
+    private String code;
+
+    private String name;
+
+    private String digest;
+
+    private CourseSubTypeEnum type;
+
+    private BaseStatusEnum status;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtCreated;
+
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtModified;
+
+    public static CourseSubItemVo parseToVo(Lesson lesson) {
+        CourseSubItemVo vo = new CourseSubItemVo();
+        BeanUtils.copyProperties(lesson, vo);
+        vo.setType(CourseSubTypeEnum.LESSON);
+        return vo;
+    }
+}

+ 3 - 0
rankin-resource-service/src/main/java/cn/rankin/resourceservice/ResourceServiceApplication.java

@@ -1,11 +1,14 @@
 package cn.rankin.resourceservice;
 
+import cn.rankin.common.utils.jpa.SimpleJpaRepository;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.netflix.feign.EnableFeignClients;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 
 @EnableFeignClients
 @SpringBootApplication
+@EnableJpaRepositories(repositoryBaseClass = SimpleJpaRepository.class)
 public class ResourceServiceApplication {
 
 	public static void main(String[] args) {

+ 5 - 9
rankin-resource-service/src/main/java/cn/rankin/resourceservice/controller/AliOSSController.java

@@ -1,7 +1,7 @@
 package cn.rankin.resourceservice.controller;
 
-import cn.rankin.common.utils.entity.api.APICodeManager;
-import cn.rankin.common.utils.entity.api.APIResult;
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
 import cn.rankin.resourceservice.vo.OSSSignature;
 import com.aliyun.oss.OSSClient;
 import com.aliyun.oss.common.utils.BinaryUtil;
@@ -43,13 +43,9 @@ public class AliOSSController {
 
     @RequestMapping(value = "signature", method = RequestMethod.GET)
     public APIResult<OSSSignature> getSignature (String fileName) {
-        String path = getPath(fileName);
-        if (path == null || path.length() == 0) {
-            return APIResult.error(APICodeManager.PARAMETER_ERROR);
-        }
 
         OSSSignature signature = new OSSSignature(accessId, dir);
-        signature.setPath(path);
+        signature.setPath(getPath(fileName));
         signature.setHost(getHost());
 
         try {
@@ -73,7 +69,7 @@ public class AliOSSController {
 
         }catch (Exception e) {
             log.error("OSS Signature error: {}", e);
-            return APIResult.error(APICodeManager.SERVER_ERROR);
+            return APIResult.error(APICodeManager.OPERATE_ERROR);
         }
 
         return APIResult.ok(signature);
@@ -85,7 +81,7 @@ public class AliOSSController {
             return null;
         }
 
-        if (fileName.indexOf("-") != -1) {
+        if (fileName.contains("-")) {
             path = fileName.replaceAll("-","/");
         }else {
             path = fileName;

+ 18 - 9
rankin-resource-service/src/main/java/cn/rankin/resourceservice/controller/ResourceController.java

@@ -1,15 +1,15 @@
 package cn.rankin.resourceservice.controller;
 
-import cn.rankin.common.utils.entity.api.APICodeManager;
-import cn.rankin.common.utils.entity.api.APIResult;
-import cn.rankin.common.utils.entity.page.Page;
-import cn.rankin.common.utils.entity.dto.ResourceSearchDTO;
-import cn.rankin.common.utils.util.UUIDUtil;
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.dto.product.SearchDTO;
 import cn.rankin.resourceservice.entity.Resource;
 import cn.rankin.resourceservice.entity.ResourceType;
 import cn.rankin.resourceservice.service.ResourceService;
 import com.alibaba.fastjson.JSON;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -25,7 +25,7 @@ public class ResourceController {
     private ResourceService resourceService;
 
     @RequestMapping(value = "/list")
-    public APIResult<Page<Resource>> search(ResourceSearchDTO searchDTO) {
+    public APIResult<Page<Resource>> search(SearchDTO searchDTO) {
         log.info(JSON.toJSONString(searchDTO));
 
         // 参数错误返回
@@ -36,13 +36,23 @@ public class ResourceController {
         Integer type = searchDTO.getType();
         if (type.intValue() == ResourceType.IMG) {
             // 图片本地取
-            return resourceService.search(searchDTO.getCode(), searchDTO.getName(), searchDTO.getSort(), searchDTO.getPageNo(), searchDTO.getPageSize());
+            Resource resource = new Resource();
+
+            String code = searchDTO.getCode();
+            if (!StringUtils.isEmpty(code)) {
+                resource.setCode("%" + code.trim() + "%");
+            }
+
+            String name = searchDTO.getName();
+            if (!StringUtils.isEmpty(name)) {
+                resource.setCode("%" + name.trim() + "%");
+            }
+            return resourceService.search(resource, searchDTO.getPageNo(), searchDTO.getPageSize());
         }else {
             // 其他去云平台
             if (searchDTO.getCode() != null) {
                 return resourceService.findRemoteByCode(searchDTO.getCode());
             }else {
-                resourceService.testAPI();
                 return resourceService.findRemotePage(searchDTO);
             }
         }
@@ -58,7 +68,6 @@ public class ResourceController {
             return APIResult.error(APICodeManager.ALREADY_EXISTS);
         }
 
-        resource.setId(UUIDUtil.getUUID());
         Resource result = resourceService.save(resource);
 
         return APIResult.ok(result);

+ 2 - 2
rankin-resource-service/src/main/java/cn/rankin/resourceservice/proxy/RemoteResourceProxy.java

@@ -1,7 +1,7 @@
 package cn.rankin.resourceservice.proxy;
 
-import cn.rankin.common.utils.entity.api.APIResult;
-import cn.rankin.common.utils.entity.page.Page;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
 import cn.rankin.resourceservice.dto.ResourceRemote;
 import org.springframework.cloud.netflix.feign.FeignClient;
 import org.springframework.web.bind.annotation.PathVariable;

+ 0 - 12
rankin-resource-service/src/main/java/cn/rankin/resourceservice/repository/BasicRepository.java

@@ -1,12 +0,0 @@
-package cn.rankin.resourceservice.repository;
-
-import cn.rankin.resourceservice.entity.Resource;
-import java.util.List;
-
-public interface BasicRepository {
-
-    Long count(String code, String name);
-
-    List<Resource> search(String code, String name, String sort, Long start, Integer pageSize);
-
-}

+ 2 - 3
rankin-resource-service/src/main/java/cn/rankin/resourceservice/repository/ResourceRepository.java

@@ -1,12 +1,11 @@
 package cn.rankin.resourceservice.repository;
 
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
 import cn.rankin.resourceservice.entity.Resource;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;
 
 @Repository
-public interface ResourceRepository extends JpaRepository<Resource, Long>, BasicRepository {
+public interface ResourceRepository extends BasicJpaRepository<Resource, String> {
 
     Long countByCode(String code);
 

+ 0 - 60
rankin-resource-service/src/main/java/cn/rankin/resourceservice/repository/ResourceRepositoryImpl.java

@@ -1,60 +0,0 @@
-package cn.rankin.resourceservice.repository;
-
-import cn.rankin.common.utils.entity.page.Page;
-import cn.rankin.resourceservice.entity.Resource;
-
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-import javax.persistence.Query;
-import java.math.BigInteger;
-import java.util.List;
-
-public class ResourceRepositoryImpl implements BasicRepository{
-
-    private static final String TABLE = "lj_resource";
-
-    @PersistenceContext
-    private EntityManager em;
-
-    public List<Resource> search(String code, String name, String sort, Long start, Integer pageSize) {
-
-        StringBuilder buf = new StringBuilder(String.format("SELECT * FROM %s WHERE 1=1", TABLE));
-
-        if (code != null && code.length() > 0) {
-            buf.append(String.format(" AND code LIKE '%%%s%%'", code));
-        }
-
-        if (name != null && name.length() > 0) {
-            buf.append(String.format(" AND name LIKE '%%%s%%'", name));
-        }
-
-        if (sort != null && sort.length() > 0) {
-            buf.append(String.format(" ORDER BY %s", sort));
-        }
-
-        buf.append(String.format(" LIMIT %d OFFSET %d", pageSize, start));
-
-
-        List<Resource> result = em.createNativeQuery(buf.toString(), Resource.class).getResultList();
-
-        return result;
-    }
-
-    public Long count(String code, String name) {
-
-        StringBuilder buf = new StringBuilder(String.format("SELECT COUNT(*) FROM %s WHERE 1=1", TABLE));
-
-        if (code != null && code.length() > 0) {
-            buf.append(String.format(" AND code LIKE '%%%s%%'", code));
-        }
-
-        if (name != null && name.length() > 0) {
-            buf.append(String.format(" AND name LIKE '%%%s%%'", name));
-        }
-
-        Query query = em.createNativeQuery(buf.toString());
-        BigInteger totalSize = (BigInteger) query.getSingleResult();
-
-        return totalSize.longValue();
-    }
-}

+ 12 - 22
rankin-resource-service/src/main/java/cn/rankin/resourceservice/service/ResourceService.java

@@ -1,14 +1,13 @@
 package cn.rankin.resourceservice.service;
 
-import cn.rankin.common.utils.entity.api.APICodeManager;
-import cn.rankin.common.utils.entity.api.APIResult;
-import cn.rankin.common.utils.entity.page.Page;
-import cn.rankin.common.utils.entity.dto.ResourceSearchDTO;
+import cn.rankin.common.utils.api.model.APICodeManager;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.dto.search.SearchDTO;
 import cn.rankin.resourceservice.dto.ResourceRemote;
 import cn.rankin.resourceservice.entity.Resource;
 import cn.rankin.resourceservice.proxy.RemoteResourceProxy;
 import cn.rankin.resourceservice.repository.ResourceRepository;
-import com.alibaba.fastjson.JSON;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -40,11 +39,15 @@ public class ResourceService {
         return resourceRepository.save(resource);
     }
 
-    public APIResult<Page<Resource>> search(String code, String name, String sort, Integer pageNo, Integer pageSize) {
-        Long count = resourceRepository.count(code, name);
+    public APIResult<Page<Resource>> search(Resource resource, Integer pageNo, Integer pageSize) {
+        Long count = resourceRepository.count(resource);
         Page<Resource> page = new Page(count, pageNo, pageSize);
 
-        List<Resource> resourceList = resourceRepository.search(code, name, sort, page.getStart(), pageSize);
+        if (count == 0) {
+            return APIResult.ok(page);
+        }
+
+        List<Resource> resourceList = resourceRepository.find(resource, page.getStart(), pageSize, null);
         resourceList.forEach(r -> {
             initResourceUrl(r);
         });
@@ -54,19 +57,7 @@ public class ResourceService {
         return APIResult.ok(page);
     }
 
-    public void testAPI() {
-        Long timeBegin = System.currentTimeMillis();
-        resourceProxy.findPageTest(new HashMap<String, Object>() {
-            {
-                this.put("title", "1");
-                this.put("type", 0);
-            }
-        });
-        log.info("not load: {}", System.currentTimeMillis() - timeBegin);
-    }
-
-    public APIResult<Page<Resource>> findRemotePage(ResourceSearchDTO searchDTO) {
-        Long timeBegin = System.currentTimeMillis();
+    public APIResult<Page<Resource>> findRemotePage(SearchDTO searchDTO) {
         APIResult<Page<ResourceRemote>> result = resourceProxy.findPage(new HashMap<String, Object>(){
             {
                 this.put("title", searchDTO.getName());
@@ -75,7 +66,6 @@ public class ResourceService {
                 this.put("type", searchDTO.getType());
             }
         });
-        log.info(JSON.toJSONString(System.currentTimeMillis() - timeBegin));
 
         if (!result.getSuccess()) {
             log.error("Remote Server Error: code={}, message={}", result.getCode(), result.getMessage());