anderx 1 год назад
Сommit
fd7c69ce1f
100 измененных файлов с 4341 добавлено и 0 удалено
  1. 141 0
      pom.xml
  2. 22 0
      src/main/java/com/sciradar/annotation/RegexEmail.java
  3. 29 0
      src/main/java/com/sciradar/annotation/RegexImage.java
  4. 23 0
      src/main/java/com/sciradar/annotation/SciradarBootApplication.java
  5. 27 0
      src/main/java/com/sciradar/aspect/LogAspect.java
  6. 30 0
      src/main/java/com/sciradar/cache/CachedUser.java
  7. 33 0
      src/main/java/com/sciradar/cache/UserCache.java
  8. 148 0
      src/main/java/com/sciradar/cache/impl/UserCacheImpl.java
  9. 56 0
      src/main/java/com/sciradar/component/DefaultMessageSource.java
  10. 51 0
      src/main/java/com/sciradar/config/FieldProperty.java
  11. 27 0
      src/main/java/com/sciradar/config/GlobalConfiguration.java
  12. 34 0
      src/main/java/com/sciradar/config/RedisClientConfig.java
  13. 17 0
      src/main/java/com/sciradar/config/RestClientConfig.java
  14. 184 0
      src/main/java/com/sciradar/constant/Constants.java
  15. 37 0
      src/main/java/com/sciradar/constant/PaymentType.java
  16. 5 0
      src/main/java/com/sciradar/data_model/DataSource.java
  17. 12 0
      src/main/java/com/sciradar/data_model/PageData.java
  18. 28 0
      src/main/java/com/sciradar/data_model/analytics/AbstractResponse.java
  19. 26 0
      src/main/java/com/sciradar/data_model/document/Author.java
  20. 29 0
      src/main/java/com/sciradar/data_model/document/FavoriteDocument.java
  21. 10 0
      src/main/java/com/sciradar/data_model/document/OrgAuthor.java
  22. 10 0
      src/main/java/com/sciradar/data_model/document/Organization.java
  23. 12 0
      src/main/java/com/sciradar/data_model/document/Reference.java
  24. 13 0
      src/main/java/com/sciradar/data_model/document/request/DocumentsByReferenceIdsRequest.java
  25. 13 0
      src/main/java/com/sciradar/data_model/document/request/DocumentsRequest.java
  26. 13 0
      src/main/java/com/sciradar/data_model/document/request/FavoriteDocumentRequest.java
  27. 14 0
      src/main/java/com/sciradar/data_model/document/request/TranslateRequest.java
  28. 151 0
      src/main/java/com/sciradar/data_model/document/response/Document.java
  29. 13 0
      src/main/java/com/sciradar/data_model/document/response/DocumentReferenceResponse.java
  30. 153 0
      src/main/java/com/sciradar/data_model/es/Document.java
  31. 22 0
      src/main/java/com/sciradar/data_model/es/Reference.java
  32. 4 0
      src/main/java/com/sciradar/data_model/payment/PayOrderResponse.java
  33. 13 0
      src/main/java/com/sciradar/data_model/payment/request/HFiveRequest.java
  34. 36 0
      src/main/java/com/sciradar/data_model/payment/request/JsapiRequest.java
  35. 13 0
      src/main/java/com/sciradar/data_model/payment/request/NativeRequest.java
  36. 40 0
      src/main/java/com/sciradar/data_model/payment/request/WeChatRequest.java
  37. 17 0
      src/main/java/com/sciradar/data_model/payment/response/HFivePaymentResponse.java
  38. 70 0
      src/main/java/com/sciradar/data_model/payment/response/OrderRecordResponse.java
  39. 13 0
      src/main/java/com/sciradar/data_model/payment/response/PCWechatPaymentResponse.java
  40. 16 0
      src/main/java/com/sciradar/data_model/payment/response/WechatPayOrderResponse.java
  41. 14 0
      src/main/java/com/sciradar/data_model/search/aggregation/AggBucket.java
  42. 4 0
      src/main/java/com/sciradar/data_model/search/aggregation/AggResult.java
  43. 39 0
      src/main/java/com/sciradar/data_model/search/aggregation/AggResultDeserializer.java
  44. 45 0
      src/main/java/com/sciradar/data_model/search/aggregation/AggType.java
  45. 15 0
      src/main/java/com/sciradar/data_model/search/aggregation/ListAggResult.java
  46. 12 0
      src/main/java/com/sciradar/data_model/search/aggregation/SingleAggResult.java
  47. 22 0
      src/main/java/com/sciradar/data_model/search/aggregation/SubjectItem.java
  48. 52 0
      src/main/java/com/sciradar/data_model/search/request/AggRequest.java
  49. 14 0
      src/main/java/com/sciradar/data_model/search/request/DocumentsByDoiesRequest.java
  50. 12 0
      src/main/java/com/sciradar/data_model/search/request/Request.java
  51. 56 0
      src/main/java/com/sciradar/data_model/search/request/SearchRequest.java
  52. 37 0
      src/main/java/com/sciradar/data_model/search/response/SearchResultResponse.java
  53. 30 0
      src/main/java/com/sciradar/data_model/user/UpUserOrder.java
  54. 54 0
      src/main/java/com/sciradar/data_model/user/UserOrder.java
  55. 21 0
      src/main/java/com/sciradar/data_model/user/UserSearch.java
  56. 23 0
      src/main/java/com/sciradar/data_model/user/UserVerify.java
  57. 61 0
      src/main/java/com/sciradar/exception/GlobalExceptionHandler.java
  58. 92 0
      src/main/java/com/sciradar/exception/HandlerICException.java
  59. 38 0
      src/main/java/com/sciradar/exception/ICException.java
  60. 14 0
      src/main/java/com/sciradar/exception/InternalException.java
  61. 10 0
      src/main/java/com/sciradar/exception/NotFoundException.java
  62. 11 0
      src/main/java/com/sciradar/exception/SavedDataException.java
  63. 9 0
      src/main/java/com/sciradar/exception/UndefinedException.java
  64. 14 0
      src/main/java/com/sciradar/service/DocumentServiceClient.java
  65. 13 0
      src/main/java/com/sciradar/service/RecommendSearchService.java
  66. 177 0
      src/main/java/com/sciradar/service/RedisService.java
  67. 14 0
      src/main/java/com/sciradar/service/SearchServiceClient.java
  68. 12 0
      src/main/java/com/sciradar/service/TranslationServiceClient.java
  69. 14 0
      src/main/java/com/sciradar/service/UserOrderServiceClient.java
  70. 10 0
      src/main/java/com/sciradar/service/UserPermissionServiceClient.java
  71. 9 0
      src/main/java/com/sciradar/service/analytics/AbstractService.java
  72. 62 0
      src/main/java/com/sciradar/service/analytics/impl/AbstractServiceImpl.java
  73. 76 0
      src/main/java/com/sciradar/service/impl/DocumentServiceClientImpl.java
  74. 51 0
      src/main/java/com/sciradar/service/impl/RecommendSearchServiceClientImpl.java
  75. 200 0
      src/main/java/com/sciradar/service/impl/RedisServiceImpl.java
  76. 90 0
      src/main/java/com/sciradar/service/impl/SearchServiceClientImpl.java
  77. 53 0
      src/main/java/com/sciradar/service/impl/TranslationServiceClientImpl.java
  78. 52 0
      src/main/java/com/sciradar/service/impl/UserOrderServiceClientImpl.java
  79. 55 0
      src/main/java/com/sciradar/service/impl/UserPermissionServiceClientImpl.java
  80. 15 0
      src/main/java/com/sciradar/service/pay/PaymentServiceClient.java
  81. 15 0
      src/main/java/com/sciradar/service/pay/WechatCommonServiceClient.java
  82. 52 0
      src/main/java/com/sciradar/service/pay/impl/HFivePaymentServiceClientImpl.java
  83. 52 0
      src/main/java/com/sciradar/service/pay/impl/PCWechatPaymentServiceClientImpl.java
  84. 79 0
      src/main/java/com/sciradar/service/pay/impl/WechatCommonServiceClientImpl.java
  85. 49 0
      src/main/java/com/sciradar/service/pay/impl/WechatPaymentServiceClientImpl.java
  86. 51 0
      src/main/java/com/sciradar/support/BaseCondition.java
  87. 127 0
      src/main/java/com/sciradar/support/Log.java
  88. 93 0
      src/main/java/com/sciradar/support/R.java
  89. 93 0
      src/main/java/com/sciradar/support/entity/UserVO.java
  90. 54 0
      src/main/java/com/sciradar/util/AgentUserKit.java
  91. 19 0
      src/main/java/com/sciradar/util/DocumentUtils.java
  92. 31 0
      src/main/java/com/sciradar/util/EmailValidator.java
  93. 29 0
      src/main/java/com/sciradar/util/HttpHeaderUtils.java
  94. 30 0
      src/main/java/com/sciradar/util/ImageValidator.java
  95. 103 0
      src/main/java/com/sciradar/util/IpAddrUtil.java
  96. 13 0
      src/main/java/com/sciradar/util/JacksonUtils.java
  97. 91 0
      src/main/java/com/sciradar/util/JsonUtil.java
  98. 81 0
      src/main/java/com/sciradar/util/LogUtils.java
  99. 72 0
      src/main/java/com/sciradar/util/Md5Utils.java
  100. 0 0
      src/main/java/com/sciradar/util/PaymentUtil.java

+ 141 - 0
pom.xml

@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>com.jishutao.brain</groupId>
+        <artifactId>core-parent</artifactId>
+        <version>1.0.1</version>
+    </parent>
+
+    <artifactId>common-library</artifactId>
+    <version>1.0.1</version>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <!--api-->
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+
+        <!-- 接口管理 -->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>${swagger.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>io.swagger</groupId>
+                    <artifactId>swagger-models</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-models</artifactId>
+            <version>${swagger-models.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>swagger-bootstrap-ui</artifactId>
+            <version>${swagger-bootstrap-ui.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-crypto</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>${fastjson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <!-- jwt -->
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>${jjwt.version}</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <!-- redis -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+            <version>20220320</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 22 - 0
src/main/java/com/sciradar/annotation/RegexEmail.java

@@ -0,0 +1,22 @@
+package com.sciradar.annotation;
+
+import com.sciradar.util.EmailValidator;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = EmailValidator.class)
+public @interface RegexEmail {
+
+    String message() default "邮箱格式错误";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

+ 29 - 0
src/main/java/com/sciradar/annotation/RegexImage.java

@@ -0,0 +1,29 @@
+package com.sciradar.annotation;
+
+import com.sciradar.util.ImageValidator;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/**
+ * @deseription 图片校验注解
+ * @author: tq
+ * @date: 2021/12/25 12:28
+ * @version 1.0
+ **/
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = ImageValidator.class)
+public @interface RegexImage {
+
+    String message() default "图片格式错误";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

+ 23 - 0
src/main/java/com/sciradar/annotation/SciradarBootApplication.java

@@ -0,0 +1,23 @@
+package com.sciradar.annotation;
+
+import com.sciradar.aspect.LogAspect;
+import com.sciradar.config.RestClientConfig;
+import com.sciradar.exception.HandlerICException;
+import com.sciradar.util.RedisCacheUtils;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.context.annotation.Import;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.lang.annotation.*;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@EnableAspectJAutoProxy
+@SpringBootApplication
+@EnableSwagger2
+@Import({LogAspect.class, HandlerICException.class, RedisCacheUtils.class, RestClientConfig.class})
+public @interface SciradarBootApplication {
+}

+ 27 - 0
src/main/java/com/sciradar/aspect/LogAspect.java

@@ -0,0 +1,27 @@
+package com.sciradar.aspect;
+
+import com.sciradar.util.LogUtils;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+
+@Aspect
+@Component
+public class LogAspect {
+
+    @Pointcut("execution(* com.sciradar.*.controller.*.*(..))")
+    public void controllerExpress(){
+
+    }
+
+    @AfterReturning(value = "controllerExpress()")
+    public void afterReturning(JoinPoint joinPoint){
+        Class<?> clz = joinPoint.getTarget().getClass();
+        System.out.println("==============================================================================================================================");
+        LogUtils.info(clz, joinPoint.getSignature().getName(), "AfterReturning log recorded");
+        System.out.println("==============================================================================================================================");
+
+    }
+}

+ 30 - 0
src/main/java/com/sciradar/cache/CachedUser.java

@@ -0,0 +1,30 @@
+package com.sciradar.cache;
+
+import lombok.Data;
+
+@Data
+public class CachedUser {
+    /**
+     * 用户ID
+     */
+    private Integer id;
+
+    /**
+     * hash后的token值
+     */
+    private String token;
+
+    /**
+     * jwt值
+     */
+    private String jwt;
+
+    private int expire;
+
+    public CachedUser(Integer id, String token, String jwt, int expire) {
+        this.id = id;
+        this.token = token;
+        this.jwt = jwt;
+        this.expire = expire;
+    }
+}

+ 33 - 0
src/main/java/com/sciradar/cache/UserCache.java

@@ -0,0 +1,33 @@
+package com.sciradar.cache;
+
+import java.util.Set;
+
+public interface UserCache {
+    void setUserTokens(Integer userId, Set<String> tokens);
+
+    void addUserToken(Integer userId, String token);
+
+    void deleteUserToken(Integer userId, String token);
+
+    Set<String> getUserTokens(Integer userId);
+
+    /**
+     * 刷新用户和token列表
+     * @param userId 用户ID
+     */
+    void refresh(Integer userId);
+
+    boolean userTokenExists(String token);
+
+    void save(CachedUser cachedUser, long time);
+
+    CachedUser get(String token);
+
+    Boolean deleteUser(String token);
+
+    /**
+     * 删除最快到期的用户
+     * @param userId 用户ID
+     */
+    void deleteAlmostExpired(Integer userId);
+}

+ 148 - 0
src/main/java/com/sciradar/cache/impl/UserCacheImpl.java

@@ -0,0 +1,148 @@
+package com.sciradar.cache.impl;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.sciradar.cache.CachedUser;
+import com.sciradar.cache.UserCache;
+import com.sciradar.service.RedisService;
+import com.sciradar.service.impl.RedisServiceImpl;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@Service
+public class UserCacheImpl implements UserCache {
+    private final RedisService redisService;
+    private final ObjectMapper objectMapper;
+
+    public UserCacheImpl(RedisServiceImpl redisService, ObjectMapper objectMapper) {
+        this.redisService = redisService;
+        this.objectMapper = objectMapper;
+    }
+
+    private String getTokensKey(Integer userId) {
+        return String.format("user_tokens:%d", userId);
+    }
+
+    /**
+     * 根据token获取用户缓存的key值
+     * @param token Token
+     * @return 用户缓存的key值
+     */
+    private String getUserKey(String token) {
+        return String.format("user:%s", token);
+    }
+
+    @Override
+    public void setUserTokens(Integer userId, Set<String> tokens) {
+        String key = getTokensKey(userId);
+        redisService.del(key);
+        for (String token : tokens) {
+            redisService.sAdd(key, token);
+        }
+    }
+
+    @Override
+    public void addUserToken(Integer userId, String token) {
+        redisService.sAdd(getTokensKey(userId), token);
+    }
+
+    @Override
+    public void deleteUserToken(Integer userId, String token) {
+        redisService.sRemove(getTokensKey(userId), token);
+    }
+
+    /**
+     * 根据用户ID获取所有在线的用户的token
+     * @param userId 用户ID
+     * @return 所有在线用户的token列表
+     */
+    @Override
+    public Set<String> getUserTokens(Integer userId) {
+        String tokensKey = getTokensKey(userId);
+
+        if (!redisService.hasKey(tokensKey)) {
+            return Collections.emptySet();
+        }
+
+        Set<Object> members = redisService.sMembers(tokensKey);
+        if (members.size() == 0) {
+            return Collections.emptySet();
+        }
+
+        return members.stream().map(x -> (String) x).collect(Collectors.toSet());
+    }
+
+    @Override
+    public void refresh(Integer userId) {
+        Set<String> userTokens = getUserTokens(userId);
+        Object[] notExistsUserTokens = userTokens.stream().filter(token -> !userTokenExists(token)).toArray(String[]::new);
+        if (notExistsUserTokens.length > 0) {
+            redisService.sRemove(getTokensKey(userId), notExistsUserTokens);
+        }
+    }
+
+    @Override
+    public boolean userTokenExists(String token) {
+        return redisService.hasKey(getUserKey(token));
+    }
+
+    @Override
+    public void save(CachedUser cachedUser, long time) {
+        String userStr = null;
+        try {
+            userStr = objectMapper.writeValueAsString(cachedUser);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        redisService.set(getUserKey(cachedUser.getToken()), userStr, time);
+    }
+
+    /**
+     * 根据token获取用户缓存的信息
+     * @param token Token
+     * @return 用户缓存信息
+     */
+    @Override
+    public CachedUser get(String token) {
+        String userStr = (String) redisService.get(getUserKey(token));
+
+        if (userStr == null) {
+            return null;
+        }
+
+        try {
+            return objectMapper.readValue(userStr, CachedUser.class);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    @Override
+    public Boolean deleteUser(String token) {
+        CachedUser user = get(token);
+        deleteUserToken(user.getId(), token);
+        return redisService.del(getUserKey(token));
+    }
+
+    @Override
+    public void deleteAlmostExpired(Integer userId) {
+        Set<String> tokens = getUserTokens(userId);
+        Long minExpire = Long.MAX_VALUE;
+        String matchedToken = null;
+        for (String token : tokens) {
+            Long expire = redisService.getExpire(getUserKey(token));
+            if (expire < minExpire) {
+                minExpire = expire;
+                matchedToken = token;
+            }
+        }
+        if (matchedToken != null) {
+            deleteUserToken(userId, matchedToken);
+            deleteUser(matchedToken);
+        }
+    }
+}

+ 56 - 0
src/main/java/com/sciradar/component/DefaultMessageSource.java

@@ -0,0 +1,56 @@
+package com.sciradar.component;
+
+import com.sciradar.constant.Constants;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.context.support.ResourceBundleMessageSource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.nio.charset.StandardCharsets;
+import java.util.Locale;
+
+@Component
+public class DefaultMessageSource extends ResourceBundleMessageSource {
+    public DefaultMessageSource() {
+        setDefaultEncoding(StandardCharsets.UTF_8.name());
+        setBasename("default");
+        addBasenames("messages");
+    }
+
+    public String getMessage(String code, String... args) {
+        return getMessage(code, args, getLocale());
+    }
+
+    public String getMessage(Integer code, String... args) {
+        return getMessage(code+"", args);
+    }
+
+    private Locale getLocale() {
+        Locale locale = Locale.SIMPLIFIED_CHINESE;
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        if (attributes == null) {
+            return locale;
+        }
+
+        HttpServletRequest request = attributes.getRequest();
+        String headerLang = request.getHeader(HttpHeaders.ACCEPT_LANGUAGE);
+
+        String language = StringUtils.isEmpty(headerLang) ? request.getParameter(Constants.DEFAULT_LANG) : headerLang;
+        if (language == null) {
+            return locale;
+        }
+
+        String[] langs = language.split(",");
+        if (langs.length > 0) {
+            String[] s = langs[0].split("[-_]");
+            if (s.length == 2) {
+                locale = new Locale(s[0], s[1]);
+            }
+        }
+
+        return locale;
+    }
+}

+ 51 - 0
src/main/java/com/sciradar/config/FieldProperty.java

@@ -0,0 +1,51 @@
+package com.sciradar.config;
+
+
+import lombok.Data;
+
+@Data
+public class FieldProperty {
+    private String abvName;
+    private String fullName;
+    private String[] abvNames;
+    private String aggName = null;
+    private String exact = null;
+    private boolean canHighlight = false;
+    private boolean nested = false;
+    private String parent;
+
+    /**
+     * 返回是否为一个多字段的类型
+     * @return boolean
+     */
+    public boolean isMultiField() {
+        return abvNames != null && abvNames.length > 0;
+    }
+
+    /**
+     * 字段是否为nested字段
+     * @return boolean
+     */
+    public boolean isNested() {
+        return nested;
+    }
+
+    /**
+     * 精确匹配字段
+     * @return String
+     */
+    public String getExact() {
+        if (exact != null) {
+            return exact;
+        }
+
+        return fullName;
+    }
+
+    public String getAggNameOrFullName() {
+        if (aggName == null || aggName.isEmpty()) {
+            return fullName;
+        }
+        return aggName;
+    }
+}

+ 27 - 0
src/main/java/com/sciradar/config/GlobalConfiguration.java

@@ -0,0 +1,27 @@
+package com.sciradar.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "global-config")
+public class GlobalConfiguration {
+    private Service service;
+
+    @Data
+    public static class Service {
+        private Endpoint endpoint;
+
+        @Data
+        public static class Endpoint {
+            private String search = "http://search-service:8080/v1";
+            private String user = "http://user-service:8080";
+            private String document = "http://document-service:8080/v1";
+            private String analytics = "http://analytics-service:8080";
+            private String payment = "http://payment-service:8080/v1";
+        }
+    }
+
+}

+ 34 - 0
src/main/java/com/sciradar/config/RedisClientConfig.java

@@ -0,0 +1,34 @@
+package com.sciradar.config;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+
+@Configuration
+public class RedisClientConfig {
+
+    @Bean
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
+    {
+        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
+        ObjectMapper om = new ObjectMapper();
+        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+//        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
+        jackson2JsonRedisSerializer.setObjectMapper(om);
+
+        RedisTemplate<String, Object> template = new RedisTemplate<>();
+        template.setConnectionFactory(redisConnectionFactory);
+        template.setKeySerializer(jackson2JsonRedisSerializer);
+        template.setValueSerializer(jackson2JsonRedisSerializer);
+        template.setHashKeySerializer(jackson2JsonRedisSerializer);
+        template.setHashValueSerializer(jackson2JsonRedisSerializer);
+        template.afterPropertiesSet();
+
+        return template;
+    }
+}

+ 17 - 0
src/main/java/com/sciradar/config/RestClientConfig.java

@@ -0,0 +1,17 @@
+package com.sciradar.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * Rest template请求配置
+ */
+@Configuration
+public class RestClientConfig {
+
+    @Bean
+    public RestTemplate restTemplate() {
+        return new RestTemplate();
+    }
+}

+ 184 - 0
src/main/java/com/sciradar/constant/Constants.java

@@ -0,0 +1,184 @@
+package com.sciradar.constant;
+
+
+public final class Constants {
+
+    /**
+     * 默认成功状态码
+     */
+    public static final Integer DEFAULT_SUCCESS_STATUS = 1000;
+
+    /**
+     * 默认失败状态码
+     */
+    public static final Integer DEFAULT_ERROR_STATUS = 1001;
+
+    public static final Integer DEFAULT_NOTFOUND = 1004;
+
+    public static final Integer DEFAULT_NOT_ALLOWED = 1005;
+
+    public static final Integer DEFAULT_SERVER_ERROR = 1010;
+
+
+    /**
+     * token 过期
+     */
+    public static final Integer TOKEN_OVERDUE = 200004;
+
+    /**
+     * tonekn 不匹配
+     */
+    public static final Integer TOKEN_MISMATCHING = 200005;
+
+    /**
+     * token 构建错误
+     */
+    public static final Integer TOKEN_BUILD_ERROR = 200006;
+
+    /**
+     * token 验证签名失败
+     */
+    public static final Integer TOKEN_SIGNATURE_FAILED = 200007;
+
+    /**
+     * token 非法
+     */
+    public static final Integer TOKEN_ILLEGALITY = 200008;
+
+
+    /**
+     * 默认成功消息
+     */
+    public static final String DEFAULT_SUCCESS_MSG = "操作成功";
+
+    /**
+     * 服务异常
+     */
+    public static final String DEFAULT_FAIL_MSG = "服务异常";
+
+    /**
+     * api版本
+     */
+    public static final String API_VERSION = "v1";
+
+
+    /**
+     * 通用字符集编码
+     */
+    public static final String CHARSET_UTF8 = "UTF-8";
+
+    /**
+     * 中文字符集编码
+     */
+    public static final String CHARSET_CHINESE = "GBK";
+
+    /**
+     * 英文字符集编码
+     */
+    public static final String CHARSET_LATIN = "ISO-8859-1";
+
+    /**
+     * NULL字符串
+     */
+    public static final String NULL = "null";
+
+    /**
+     * 日期格式
+     */
+    public static final String FORMAT_DATE = "yyyy-MM-dd";
+
+    /**
+     * 简单日期时间格式
+     */
+    public static final String FORMAT_DATETIME_SIMPLE = "yyyyMMddHHmmss";
+
+    /**
+     * 日期时间格式
+     */
+    public static final String FORMAT_DATETIME = "yyyy-MM-dd HH:mm:ss";
+
+    /**
+     * 时间戳格式
+     */
+    public static final String FORMAT_TIMESTAMP = "yyyy-MM-dd HH:mm:ss.SSS";
+
+    /**
+     * 当前登录用户的默认属性
+     */
+    public static final String CURRENT_USER = "currentUser";
+
+    /**
+     * 限制属性
+     */
+    public static final String SECRET_KEY = "secretKey";
+
+    /**
+     * 过期时间
+     */
+    public static final long EXPIRATION = 300;
+    public static final long USER_LOCK = 900;
+    public static final long TWO_HOURS = 2;
+
+    /**
+     * 过期前1分钟
+     */
+    public static final long LASTTIME = 60;
+
+    /**
+     * 状态数值0
+     */
+    public static final Integer ZEOR = 0;
+
+    /**
+     * 状态数值1
+     */
+    public static final Integer SINGLE = 1;
+
+    /**
+     * 状态数值2
+     */
+    public static final Integer TWIN = 2;
+
+    /**
+     * jwt 配置
+     */
+    public static final String JWTHEADER = "Authorization";
+    public static final String JWTISSUER = "com.zx";
+    public static final String JWTSECTET = "mySecret";
+    public static final Integer JWTEXPIRATION = 3600;
+    public static final String JWTPREFIX = "ZxStoreUser";
+
+    /**
+     * jwt 配置
+     */
+    public static final Integer REDIS_CACHE_TIME = 24;
+
+    public static final String DEFAULT_LANG = "lang";
+    /**
+     * 密码ENCORDER
+     */
+    public static int PW_ENCORDER_SALT = 12;
+
+    /**
+     * 发送短信通道
+     */
+    public static final String SMS_MESSAGE = "st_smsMessage";
+
+    public static final String SEARCH_HISTORY = "search_history";
+
+    public static final String HW_SMS_MESSAGE = "st_hwSMSMessage";
+
+    public static final String HTTP_HEADER_USER_ID = "Sr-User-Id";
+
+    public static final String HTTP_HEADER_FROM = "Sr-From";
+
+    /**
+     * API V3密钥
+     */
+    public static final String API_V3_KEY = "3dd0b280ea506adae1eacc3bc5301e56";
+
+    public static final Integer VIP_USER_MONEY = 36000;
+
+    public static final Integer MAIOR_USER_MONEY = 180000;
+
+}

+ 37 - 0
src/main/java/com/sciradar/constant/PaymentType.java

@@ -0,0 +1,37 @@
+package com.sciradar.constant;
+
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+/**
+ * @author lbw
+ * @create 2022/9/22
+ */
+public enum PaymentType {
+    HFIVE("HFIVE"),
+    NATIVE("NATIVE"),
+    JSAPI("JSAPI"),
+    UNKONOWN("UNKONOWN");
+
+    PaymentType(String paymentType){
+        this.paymentType = paymentType;
+    }
+    private String paymentType;
+
+    @JsonCreator
+    public static PaymentType getPaymentType(String paymentType){
+        switch (paymentType) {
+            case "HFIVE":
+                return HFIVE;
+
+            case "NATIVE":
+                return NATIVE;
+
+            case "JSAPI":
+                return JSAPI;
+
+            default:
+                return UNKONOWN;
+        }
+    }
+}

+ 5 - 0
src/main/java/com/sciradar/data_model/DataSource.java

@@ -0,0 +1,5 @@
+package com.sciradar.data_model;
+
+public enum DataSource {
+    EN, CN
+}

+ 12 - 0
src/main/java/com/sciradar/data_model/PageData.java

@@ -0,0 +1,12 @@
+package com.sciradar.data_model;
+
+import lombok.Data;
+
+import java.util.Collection;
+
+@Data
+public class PageData<T> {
+    private Long total;
+
+    private Collection<T> data;
+}

+ 28 - 0
src/main/java/com/sciradar/data_model/analytics/AbstractResponse.java

@@ -0,0 +1,28 @@
+package com.sciradar.data_model.analytics;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+/**
+ * @author lbw
+ * @create 2022/10/19
+ */
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class AbstractResponse {
+    public AbstractResponse() {
+    }
+
+    public AbstractResponse(Integer code, String data) {
+        this.code = code;
+        this.data = data;
+    }
+
+    public AbstractResponse( String data) {
+        this.data = data;
+    }
+
+    private Integer code;
+
+    private String data;
+}

+ 26 - 0
src/main/java/com/sciradar/data_model/document/Author.java

@@ -0,0 +1,26 @@
+package com.sciradar.data_model.document;
+
+import lombok.Data;
+
+@Data
+public class Author {
+    /**
+     * 名字全称
+     */
+    private String name;
+
+    /**
+     * 名字简称
+     */
+    private String shortName;
+
+    /**
+     * 省
+     */
+    private String province;
+
+    /**
+     * 市
+     */
+    private String city;
+}

+ 29 - 0
src/main/java/com/sciradar/data_model/document/FavoriteDocument.java

@@ -0,0 +1,29 @@
+package com.sciradar.data_model.document;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class FavoriteDocument {
+    /**
+     * 论文ID
+     */
+    private Long id;
+
+    /**
+     * 论文标题
+     */
+    private String title;
+
+    /**
+     * 作者
+     */
+    private List<String> authors;
+
+    /**
+     * 年份
+     */
+    private String year;
+
+}

+ 10 - 0
src/main/java/com/sciradar/data_model/document/OrgAuthor.java

@@ -0,0 +1,10 @@
+package com.sciradar.data_model.document;
+
+import lombok.Data;
+
+@Data
+public class OrgAuthor {
+    private Organization org;
+
+    private Author author;
+}

+ 10 - 0
src/main/java/com/sciradar/data_model/document/Organization.java

@@ -0,0 +1,10 @@
+package com.sciradar.data_model.document;
+
+import lombok.Data;
+
+@Data
+public class Organization {
+    private String name;
+
+    private String country;
+}

+ 12 - 0
src/main/java/com/sciradar/data_model/document/Reference.java

@@ -0,0 +1,12 @@
+package com.sciradar.data_model.document;
+
+import lombok.Data;
+
+@Data
+public class Reference {
+    private String referenceId;
+    private String doi;
+    private String year;
+    private String description;
+    private String authors;
+}

+ 13 - 0
src/main/java/com/sciradar/data_model/document/request/DocumentsByReferenceIdsRequest.java

@@ -0,0 +1,13 @@
+package com.sciradar.data_model.document.request;
+
+import com.sciradar.data_model.DataSource;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class DocumentsByReferenceIdsRequest {
+    private DataSource dataSource;
+
+    private List<String> referenceIds;
+}

+ 13 - 0
src/main/java/com/sciradar/data_model/document/request/DocumentsRequest.java

@@ -0,0 +1,13 @@
+package com.sciradar.data_model.document.request;
+
+import com.sciradar.data_model.DataSource;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class DocumentsRequest {
+    private DataSource dataSource;
+
+    private List<Long> ids;
+}

+ 13 - 0
src/main/java/com/sciradar/data_model/document/request/FavoriteDocumentRequest.java

@@ -0,0 +1,13 @@
+package com.sciradar.data_model.document.request;
+
+import com.sciradar.data_model.DataSource;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class FavoriteDocumentRequest {
+    private DataSource dataSource;
+
+    private List<Long> ids;
+}

+ 14 - 0
src/main/java/com/sciradar/data_model/document/request/TranslateRequest.java

@@ -0,0 +1,14 @@
+package com.sciradar.data_model.document.request;
+
+import lombok.Data;
+
+/**
+ * @author lbw
+ * @create 2022/7/14
+ */
+@Data
+public class TranslateRequest {
+    private String from = "cn";
+    private String to = "en";
+    private String text;
+}

+ 151 - 0
src/main/java/com/sciradar/data_model/document/response/Document.java

@@ -0,0 +1,151 @@
+package com.sciradar.data_model.document.response;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.sciradar.data_model.document.Reference;
+import lombok.Data;
+
+import java.util.Arrays;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Document {
+    /**
+     * 文档数字ID
+     */
+    private Long id;
+
+    /**
+     * 文档标题
+     */
+    private String title;
+
+    /**
+     * 文档被引次数
+     */
+    private Integer cited;
+
+    /**
+     * 文档提要
+     */
+    @JsonProperty("abstract")
+    private String summary;
+
+    /**
+     * DOI
+     */
+    private String doi;
+
+    /**
+     * 文档语言
+     */
+    private String language;
+
+    /**
+     * 作者和机构
+     */
+    private OrgAuthor[] orgAuthors;
+
+    /**
+     * 作者列表
+     */
+    private String[] authors;
+
+    /**
+     * 文献类型
+     */
+    private String type;
+
+    /**
+     * 研究领域
+     */
+    private String[] researches;
+
+    /**
+     * 会议名称
+     */
+    private String conference;
+
+    /**
+     * 收录库
+     */
+    private String sourceDatabase;
+
+    /**
+     * 通讯地址
+     */
+    private String correspondenceAddress;
+
+    /**
+     * 关键词列表
+     */
+    private String[] keywords;
+
+    /**
+     * 期刊
+     */
+    private Journal journal;
+
+    /**
+     * 参考文献
+     */
+    private Reference[] references;
+
+    /**
+     * 年份
+     */
+    private String year;
+
+    @Data
+    public static class OrgAuthor {
+        /**
+         * 机构名称
+         */
+        private String organization;
+
+        /**
+         * 作者名字
+         */
+        private String author;
+    }
+
+    @Data
+    public static class Journal {
+        /**
+         * 期刊名称
+         */
+        private String name;
+
+        /**
+         * 期刊发布时间
+         */
+        private String date;
+
+        /**
+         * 卷标
+         */
+        private String volume;
+
+        /**
+         * 页码
+         */
+        private String page;
+    }
+
+    /**
+     * 学科
+     */
+    private String subject;
+
+    /**
+     * 阅读次数
+     */
+    private Long readings;
+
+    private static String[] getKeywords(String keywords) {
+        return Arrays.stream(keywords.split("[,;]"))
+                .filter(k -> !k.trim().isEmpty())
+                .toArray(String[]::new);
+    }
+
+}

+ 13 - 0
src/main/java/com/sciradar/data_model/document/response/DocumentReferenceResponse.java

@@ -0,0 +1,13 @@
+package com.sciradar.data_model.document.response;
+
+import com.sciradar.data_model.es.Reference;
+import lombok.Data;
+
+@Data
+public class DocumentReferenceResponse {
+    private boolean exists = false;
+
+    private Document document;
+
+    private Reference reference;
+}

+ 153 - 0
src/main/java/com/sciradar/data_model/es/Document.java

@@ -0,0 +1,153 @@
+package com.sciradar.data_model.es;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.sciradar.util.DocumentUtils;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class Document {
+    private String _id;
+
+    private Long id;
+
+    private float score;
+
+    @JsonProperty("resource_type_name")
+    private String[] resourceTypeName;
+
+    private String year;
+
+    private Integer cited;
+
+    private String source;
+
+    private String title;
+
+    @JsonProperty("ext_id")
+    private String extId;
+
+    @JsonProperty("tidy_time")
+    private Date tidyTime;
+
+    @JsonProperty("user_srh_keywords")
+    private String[] userSrhKeywords;
+
+    private String issue;
+
+    @JsonProperty("resource_type")
+    private Integer resourceType;
+
+    @JsonProperty("journal_name")
+    private String journalName;
+
+    @JsonProperty("abstract")
+    private String summary;
+
+    public String getSummary() {
+        if (summary == null) {
+            summary = "";
+        }
+        return DocumentUtils.stripSummary(summary);
+    }
+
+    private String issn;
+
+    private String[] authors;
+
+    private String page;
+
+    @JsonProperty("unit_scholar")
+    private List<UnitScholar> unitScholar;
+
+    public List<UnitScholar> getUnitScholar() {
+        List<UnitScholar> unitScholars = new ArrayList<>();
+        if (unitScholar == null) {
+            return unitScholars;
+        }
+
+        for (UnitScholar scholar : unitScholar) {
+            if (!scholar.isEmpty()) {
+                unitScholars.add(scholar);
+            }
+        }
+        return unitScholars;
+    }
+
+    private List<String> keywords;
+
+    private Map<String, List<String>> highlight;
+
+    @Data
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    public static class UnitScholar {
+        @JsonProperty("unit_name")
+        private String unitName;
+
+        @JsonProperty("unit_scholar_name")
+        private String unitScholarName;
+
+        private String province;
+
+        private String city;
+
+        private String scholar_name;
+
+        private String country;
+
+        public boolean isEmpty() {
+            return unitName == null && unitScholarName == null && province == null && city == null && scholar_name == null;
+        }
+    }
+
+    @Data
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    @JsonInclude(JsonInclude.Include.NON_NULL)
+    public static class Keyword {
+        @JsonProperty("keyword_name")
+        private String keywordName;
+    }
+
+    private String[] subject;
+
+    /**
+     * 研究领域
+     */
+    @JsonProperty("researchs")
+    private String[] researches;
+
+    private String doi;
+
+    public String getDoi() {
+        if (doi == null) {
+            return "";
+        }
+
+        return doi.trim();
+    }
+
+    /**
+     * 语言
+     */
+    private String language;
+
+    /**
+     * 文献类型
+     */
+    @JsonProperty("publication_type")
+    private String publicationType;
+
+    /**
+     * 参考文献
+     */
+    private List<Reference> references;
+}

+ 22 - 0
src/main/java/com/sciradar/data_model/es/Reference.java

@@ -0,0 +1,22 @@
+package com.sciradar.data_model.es;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class Reference {
+    @JsonProperty("reference_id")
+    private String referenceId;
+
+    private String doi;
+
+    private String description;
+
+    private String authors;
+
+    private String year;
+}

+ 4 - 0
src/main/java/com/sciradar/data_model/payment/PayOrderResponse.java

@@ -0,0 +1,4 @@
+package com.sciradar.data_model.payment;
+
+public interface PayOrderResponse {
+}

+ 13 - 0
src/main/java/com/sciradar/data_model/payment/request/HFiveRequest.java

@@ -0,0 +1,13 @@
+package com.sciradar.data_model.payment.request;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * @author lbw
+ * @create 2022/9/16
+ */
+@Data
+@Accessors(chain = true)
+public class HFiveRequest extends WeChatRequest {
+}

+ 36 - 0
src/main/java/com/sciradar/data_model/payment/request/JsapiRequest.java

@@ -0,0 +1,36 @@
+package com.sciradar.data_model.payment.request;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+public class JsapiRequest extends WeChatRequest {
+
+    /**
+     * 创建订单成功的回调地址
+     */
+    @JsonProperty("notify_url")
+    private String notifyUrl;
+
+
+    private Payer payer;
+
+    /**
+     * 支付者信息
+     */
+    @Data
+    public static class Payer {
+        /**
+         * 支付都的ID
+         */
+        private String openid;
+
+        public Payer() {}
+
+        public Payer(String openid) {
+            this.openid = openid;
+        }
+    }
+}

+ 13 - 0
src/main/java/com/sciradar/data_model/payment/request/NativeRequest.java

@@ -0,0 +1,13 @@
+package com.sciradar.data_model.payment.request;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * @author lbw
+ * @create 2022/9/16
+ */
+@Data
+@Accessors(chain = true)
+public class NativeRequest extends WeChatRequest {
+}

+ 40 - 0
src/main/java/com/sciradar/data_model/payment/request/WeChatRequest.java

@@ -0,0 +1,40 @@
+package com.sciradar.data_model.payment.request;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * @author lbw
+ * @create 2022/9/18
+ */
+@Data
+@Accessors(chain = true)
+public class WeChatRequest {
+
+    private String outTradeNo;
+
+    private Amount amount;
+
+    private String description;
+
+    private Integer userId;
+
+    /**
+     * 支付金额信息
+     */
+    @Data
+    public static class Amount {
+        /**
+         * 订单金额,以分为单位
+         */
+        private Integer total;
+
+        public Amount() {}
+
+        public Amount(Integer total) {
+            this.total = total;
+        }
+    }
+
+    private String type;
+}

+ 17 - 0
src/main/java/com/sciradar/data_model/payment/response/HFivePaymentResponse.java

@@ -0,0 +1,17 @@
+package com.sciradar.data_model.payment.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.sciradar.data_model.payment.PayOrderResponse;
+import lombok.Data;
+
+/**
+ * @author lbw
+ * @create 2022/9/16
+ */
+@Data
+public class HFivePaymentResponse implements PayOrderResponse {
+    @JsonProperty("h5_url")
+    private String h5Url;
+
+    private String outTradeNo;
+}

+ 70 - 0
src/main/java/com/sciradar/data_model/payment/response/OrderRecordResponse.java

@@ -0,0 +1,70 @@
+package com.sciradar.data_model.payment.response;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @author lbw
+ * @create 2022/8/25
+ */
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class OrderRecordResponse {
+
+    private String appid;
+
+    private String mchid;
+
+    @JsonProperty("out_trade_no")
+    private String outTradeNo;
+
+    @JsonProperty("transaction_id")
+    private String transactionId;
+
+    @JsonProperty("trade_type")
+    private String tradeType;
+
+    @JsonProperty("trade_state")
+    private String tradeState;
+
+    @JsonProperty("trade_state_desc")
+    private String tradeStateDesc;
+
+    @JsonProperty("bank_type")
+    private String bankType;
+
+    private String attach;
+
+    @JsonProperty("success_time")
+    private String successTime;
+
+    private Payer payer;
+
+    private Amount amount;
+
+    @Data
+    public static class Payer {
+        private String openid;
+
+    }
+
+    @Data
+    public static class Amount {
+        /**
+         * 总金额
+         */
+        private String total;
+
+        /**
+         * 用户支付金额
+         */
+        private String payer_total;
+
+        private String currency;
+
+        private String payer_currency;
+
+    }
+
+}

+ 13 - 0
src/main/java/com/sciradar/data_model/payment/response/PCWechatPaymentResponse.java

@@ -0,0 +1,13 @@
+package com.sciradar.data_model.payment.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.sciradar.data_model.payment.PayOrderResponse;
+import lombok.Data;
+
+@Data
+public class PCWechatPaymentResponse implements PayOrderResponse {
+    @JsonProperty("code_url")
+    private String codeUrl;
+
+    private String outTradeNo;
+}

+ 16 - 0
src/main/java/com/sciradar/data_model/payment/response/WechatPayOrderResponse.java

@@ -0,0 +1,16 @@
+package com.sciradar.data_model.payment.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.sciradar.data_model.payment.PayOrderResponse;
+import lombok.Data;
+
+/**
+ * 微信支付创建订单的响应
+ */
+@Data
+public class WechatPayOrderResponse implements PayOrderResponse {
+    @JsonProperty("prepay_id")
+    private String prepayId;
+
+    private String outTradeNo;
+}

+ 14 - 0
src/main/java/com/sciradar/data_model/search/aggregation/AggBucket.java

@@ -0,0 +1,14 @@
+package com.sciradar.data_model.search.aggregation;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.Map;
+
+@Data
+@AllArgsConstructor
+public class AggBucket {
+    Object key;
+    Number count;
+    Map<String, AggResult> children;
+}

+ 4 - 0
src/main/java/com/sciradar/data_model/search/aggregation/AggResult.java

@@ -0,0 +1,4 @@
+package com.sciradar.data_model.search.aggregation;
+
+public interface AggResult {
+}

+ 39 - 0
src/main/java/com/sciradar/data_model/search/aggregation/AggResultDeserializer.java

@@ -0,0 +1,39 @@
+package com.sciradar.data_model.search.aggregation;
+
+import com.fasterxml.jackson.core.JacksonException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.ObjectCodec;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+import java.io.IOException;
+
+public class AggResultDeserializer extends StdDeserializer<AggResult> {
+    private ObjectMapper objectMapper = new ObjectMapper();
+
+    public AggResultDeserializer() {
+        this(null);
+    }
+
+    public AggResultDeserializer(Class<?> vc) {
+        super(vc);
+    }
+
+    @Override
+    public AggResult deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
+        ObjectCodec codec = p.getCodec();
+        JsonNode node = codec.readTree(p);
+        if (node.isArray()) {
+            ListAggResult coll = new ListAggResult();
+            for (JsonNode jsonNode : node) {
+                coll.add(objectMapper.treeToValue(jsonNode, AggBucket.class));
+            }
+
+            return coll;
+        }
+
+        return new SingleAggResult(objectMapper.treeToValue(node, Object.class));
+    }
+}

+ 45 - 0
src/main/java/com/sciradar/data_model/search/aggregation/AggType.java

@@ -0,0 +1,45 @@
+package com.sciradar.data_model.search.aggregation;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import com.sciradar.exception.UndefinedException;
+
+public enum AggType {
+    TERMS("terms"),
+    CARDINALITY("cardinality"),
+    MIN("min"),
+    MAX("max"),
+    TERMS_NESTED("terms_nested"),
+    TERMS_REVERSE("terms_reverse");
+
+    private final String name;
+
+    AggType(String name) {
+        this.name = name;
+    }
+
+    @JsonValue
+    public String getName() {
+        return name;
+    }
+
+    public static AggType fromStr(String name) throws UndefinedException {
+        switch (name.toLowerCase()) {
+            case "terms":
+                return TERMS;
+
+            case "cardinality":
+                return CARDINALITY;
+
+            case "min":
+                return MIN;
+
+            case "max":
+                return MAX;
+
+            case "terms_reverse":
+                return TERMS_REVERSE;
+        }
+
+        throw new UndefinedException("聚合类型: " + name + "没有定义");
+    }
+}

+ 15 - 0
src/main/java/com/sciradar/data_model/search/aggregation/ListAggResult.java

@@ -0,0 +1,15 @@
+package com.sciradar.data_model.search.aggregation;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class ListAggResult extends ArrayList<AggBucket> implements AggResult {
+    public static ListAggResult fromList(List<AggBucket> aggBuckets) {
+        ListAggResult aggResult = new ListAggResult();
+        aggResult.addAll(aggBuckets);
+        return aggResult;
+    }
+}

+ 12 - 0
src/main/java/com/sciradar/data_model/search/aggregation/SingleAggResult.java

@@ -0,0 +1,12 @@
+package com.sciradar.data_model.search.aggregation;
+
+import lombok.Data;
+
+@Data
+public class SingleAggResult implements AggResult {
+    private Object value;
+
+    public SingleAggResult(Object value) {
+        this.value = value;
+    }
+}

+ 22 - 0
src/main/java/com/sciradar/data_model/search/aggregation/SubjectItem.java

@@ -0,0 +1,22 @@
+package com.sciradar.data_model.search.aggregation;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+
+/**
+ * @author lbw
+ * @create 2022/6/27
+ */
+@Data
+@Accessors(chain = true)
+public class SubjectItem {
+
+    private String name;
+
+    private long count;
+
+    private List<SubjectItem> children;
+
+}

+ 52 - 0
src/main/java/com/sciradar/data_model/search/request/AggRequest.java

@@ -0,0 +1,52 @@
+package com.sciradar.data_model.search.request;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.sciradar.config.FieldProperty;
+import com.sciradar.data_model.search.aggregation.AggType;
+import lombok.Data;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 聚合查询请求
+ */
+@Data
+public class AggRequest {
+    @JsonIgnore
+    private String name;
+
+    @JsonIgnore
+    private FieldProperty fieldProperty;
+
+    /**
+     * 聚合的字段
+     */
+    private String field;
+
+    /**
+     * 聚合类型,默认为terms
+     */
+    private AggType type = AggType.TERMS;
+
+    /**
+     * 聚合值的数量
+     */
+    private int size = 10;
+
+    /**
+     * 排序方式,以/分割,前面指定是以key还是count排序,后面指定按asc还是desc排序
+     */
+    private String sort = "key/desc";
+
+    /**
+     * 需要包含的聚合值
+     */
+    private String[] include;
+
+    /**
+     * 子聚合
+     */
+    private Map<String, AggRequest> subAggs = new HashMap<>();
+
+}

+ 14 - 0
src/main/java/com/sciradar/data_model/search/request/DocumentsByDoiesRequest.java

@@ -0,0 +1,14 @@
+package com.sciradar.data_model.search.request;
+
+
+import com.sciradar.data_model.DataSource;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class DocumentsByDoiesRequest {
+    private DataSource dataSource;
+
+    private List<String> doies;
+}

+ 12 - 0
src/main/java/com/sciradar/data_model/search/request/Request.java

@@ -0,0 +1,12 @@
+package com.sciradar.data_model.search.request;
+
+import lombok.Data;
+
+@Data
+public class Request {
+    /**
+     * 搜索的数据源
+     */
+    protected String[] dataSources = {"CN"};
+
+}

+ 56 - 0
src/main/java/com/sciradar/data_model/search/request/SearchRequest.java

@@ -0,0 +1,56 @@
+package com.sciradar.data_model.search.request;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 简单搜索请求
+ */
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SearchRequest extends Request {
+    /**
+     * 查询式
+     */
+    private String query;
+
+    /**
+     * 开始位置
+     */
+    private int from = 0;
+
+    /**
+     * 查询数量
+     */
+    private int size = 10;
+
+    /**
+     * 需要查询的字段
+     */
+    private List<String> fields = new ArrayList<>();
+
+    /**
+     * 过滤条件
+     */
+    private String filter;
+
+    /**
+     * 排序
+     */
+    private Map<String, String> sort = new HashMap<>();
+
+    /**
+     * 需要做统计的字段
+     */
+    private Map<String, AggRequest> aggs = new HashMap<>();
+
+    /**
+     * 需要判断为空的字段,使用简称或者全称
+     */
+    private String[] notEmptyFields = new String[0];
+}

+ 37 - 0
src/main/java/com/sciradar/data_model/search/response/SearchResultResponse.java

@@ -0,0 +1,37 @@
+package com.sciradar.data_model.search.response;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.sciradar.data_model.es.Document;
+import com.sciradar.data_model.search.aggregation.AggResult;
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 返回给前端使用的搜索结果的数据结构
+ */
+@Data
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class SearchResultResponse {
+    /**
+     * 搜索结果总数
+     */
+    private long total;
+
+    /**
+     * 最大分值,默认是BM25的计算结果
+     */
+    private float maxScore;
+
+    /**
+     * 文档列表
+     */
+    private List<Document> docs;
+
+    /**
+     * 统计结果
+     */
+    private  Map<String, Object> aggs;
+
+}

+ 30 - 0
src/main/java/com/sciradar/data_model/user/UpUserOrder.java

@@ -0,0 +1,30 @@
+package com.sciradar.data_model.user;
+
+import io.swagger.models.auth.In;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * @author lbw
+ * @create 2022/8/29
+ */
+@Data
+@Accessors(chain = true)
+public class UpUserOrder {
+
+    private String orderNo;
+
+    private String wxOpenid;
+
+    private String transactionId;
+
+    private Integer isPay;
+
+    private String orderJson;
+
+    private Integer orderStatus;
+
+    private Date utime;
+}

+ 54 - 0
src/main/java/com/sciradar/data_model/user/UserOrder.java

@@ -0,0 +1,54 @@
+package com.sciradar.data_model.user;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * @author lbw
+ * @create 2022/8/29
+ */
+@Data
+@Accessors(chain = true)
+public class UserOrder {
+    private Integer id;
+
+    private Integer userId;
+
+    private String orderNo;
+
+    private String transactionId;
+
+    private String wxOpenid;
+
+    private String wxUnionid;
+
+    private String orderDesc;
+
+    private String orderContent;
+
+    private String orderJson;
+
+    private Integer orderType;
+
+    private Integer isPay;
+
+    private Integer payType;
+
+    private Date ctime;
+
+    private Date utime;
+
+    private Integer isDelete;
+
+    private Double amount;
+
+    private Integer orderStatus;
+
+    private Integer year;
+
+    private Integer memberType;
+
+    private Integer peopleNumber;
+}

+ 21 - 0
src/main/java/com/sciradar/data_model/user/UserSearch.java

@@ -0,0 +1,21 @@
+package com.sciradar.data_model.user;
+
+import lombok.Data;
+
+/**
+ * @author lbw
+ * @create 2022/8/15
+ */
+@Data
+public class UserSearch {
+
+    private Integer id;
+
+    private String keywords;
+
+    private Integer addTime;
+
+    private Integer userId;
+
+    private String searchData;
+}

+ 23 - 0
src/main/java/com/sciradar/data_model/user/UserVerify.java

@@ -0,0 +1,23 @@
+package com.sciradar.data_model.user;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * @author lbw
+ * @create 2022/8/31
+ */
+@Data
+@Accessors(chain = true)
+public class UserVerify {
+
+    private String body;
+
+    private String nonce;
+
+    private String serial;
+
+    private String timestamp;
+
+    private String signature;
+}

+ 61 - 0
src/main/java/com/sciradar/exception/GlobalExceptionHandler.java

@@ -0,0 +1,61 @@
+package com.sciradar.exception;
+
+import com.sciradar.component.DefaultMessageSource;
+import com.sciradar.support.R;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+@Slf4j
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+    private final DefaultMessageSource messageSource = new DefaultMessageSource();
+
+    @ExceptionHandler(NotFoundException.class)
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    public R<Object> handleNotFoundException(NotFoundException e) {
+        int code = 1404;
+        return R.fail(code, messageSource.getMessage(code+""));
+    }
+
+    @ExceptionHandler(HttpMessageNotReadableException.class)
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    public R<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException e) {
+        int code = 1001;
+        return R.fail(code, messageSource.getMessage(code+""));
+    }
+
+    @ExceptionHandler(SavedDataException.class)
+    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+    public R<Object> handleSavedDataException(SavedDataException e) {
+        log.error("internal saved data error: {}", e.getMessage());
+        Integer code = 1200;
+        return R.fail(code, messageSource.getMessage(code));
+    }
+
+    @ExceptionHandler(ICException.class)
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    public R<Object> handleICException(ICException e) {
+        Integer code = e.getStatus();
+        return R.fail(code, messageSource.getMessage(code, e.getArgs()));
+    }
+
+    @ExceptionHandler(InternalException.class)
+    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+    public R<Object> handleInternalException(InternalException e) {
+        log.error("内部错误", e);
+        return R.fail(1013, messageSource.getMessage(1013));
+    }
+
+    @ExceptionHandler(Exception.class)
+    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
+    public R<Object> handleException(Exception e) {
+        log.error("Unknown Exception", e);
+        int code = 1999;
+        return R.fail(code, messageSource.getMessage(code+""));
+    }
+
+}

+ 92 - 0
src/main/java/com/sciradar/exception/HandlerICException.java

@@ -0,0 +1,92 @@
+package com.sciradar.exception;
+
+import com.sciradar.component.DefaultMessageSource;
+import com.sciradar.constant.Constants;
+import com.sciradar.support.R;
+import com.sciradar.util.LogUtils;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.MalformedJwtException;
+import io.jsonwebtoken.SignatureException;
+import io.jsonwebtoken.UnsupportedJwtException;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.BindException;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.FieldError;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.NoHandlerFoundException;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import java.util.Set;
+
+/**
+ * @deseription
+ * @author: tq
+ * @date: 2021/12/7 21:46
+ * @version 1.0
+ **/
+@RestControllerAdvice
+public class HandlerICException {
+
+    private DefaultMessageSource messageSource = new DefaultMessageSource();
+
+    private R<Object> i18nConverter(Integer code, String... args) {
+        String message = messageSource.getMessage(code, args);
+        return R.fail(code, message);
+    }
+
+    /**
+     * 捕获全局异常,处理所有不可知的异常
+     * @author tq
+     * @date 2021/12/7 21:45
+     * @param e 全局异常
+     * @return 错误返回信息
+     */
+    @ExceptionHandler(Exception.class)
+    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    public Object handleException(Exception e) {
+        e.printStackTrace();
+        R<Object> result = i18nConverter(Constants.DEFAULT_SERVER_ERROR);
+        if (e instanceof ICException) {
+            result = i18nConverter(((ICException) e).getStatus(), ((ICException) e).getArgs());
+        } else if (e instanceof MethodArgumentNotValidException) {
+            BindingResult bindingResult = ((MethodArgumentNotValidException) e).getBindingResult();
+            if (bindingResult.hasErrors() && bindingResult.hasFieldErrors()) {
+                FieldError fieldError = bindingResult.getFieldError();
+                result = i18nConverter(Integer.parseInt(fieldError.getDefaultMessage()));
+            }
+        } else if (e instanceof BindException) {
+            BindingResult bindingResult = ((BindException) e).getBindingResult();
+            if (bindingResult.hasErrors() && bindingResult.hasFieldErrors()) {
+                FieldError fieldError = bindingResult.getFieldError();
+                result = i18nConverter(Integer.parseInt(fieldError.getDefaultMessage()));
+            }
+        } else if (e instanceof ConstraintViolationException) {
+            Set<ConstraintViolation<?>> constraintViolations = ((ConstraintViolationException) e).getConstraintViolations();
+            ConstraintViolation<?> constraintViolation = constraintViolations.stream().findFirst().orElse(null);
+            if (constraintViolation != null) {
+                result = i18nConverter(Integer.parseInt(constraintViolation.getMessage()));
+            }
+        } else if (e instanceof HttpRequestMethodNotSupportedException) {
+            result = i18nConverter(Constants.DEFAULT_NOT_ALLOWED);
+        } else if (e instanceof NoHandlerFoundException) {
+            result = i18nConverter(Constants.DEFAULT_NOTFOUND);
+        } else if (e instanceof ExpiredJwtException) {
+            result = i18nConverter(Constants.TOKEN_OVERDUE);
+        } else if (e instanceof UnsupportedJwtException) {
+            result = i18nConverter(Constants.TOKEN_MISMATCHING);
+        } else if (e instanceof MalformedJwtException) {
+            result = i18nConverter(Constants.TOKEN_BUILD_ERROR);
+        } else if (e instanceof SignatureException) {
+            result = i18nConverter(Constants.TOKEN_SIGNATURE_FAILED);
+        } else if (e instanceof IllegalArgumentException) {
+            result = i18nConverter(Constants.TOKEN_ILLEGALITY);
+        }
+        LogUtils.error(getClass(), e, result.getMsg());
+        return result;
+    }
+}

+ 38 - 0
src/main/java/com/sciradar/exception/ICException.java

@@ -0,0 +1,38 @@
+package com.sciradar.exception;
+
+public class ICException extends RuntimeException {
+    private static final long serialVersionUID = 7654789857987795972L;
+
+    private Integer status = 1999;
+
+    private String[] args;
+
+    public ICException(Integer status, String... args) {
+        this.status = status;
+        this.args = args;
+    }
+
+    public ICException(Integer status) {
+        this.status = status;
+    }
+
+    public ICException(String... args) {
+        this.args = args;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public String[] getArgs() {
+        return args;
+    }
+
+    public void setArgs(String[] args) {
+        this.args = args;
+    }
+}

+ 14 - 0
src/main/java/com/sciradar/exception/InternalException.java

@@ -0,0 +1,14 @@
+package com.sciradar.exception;
+
+public class InternalException extends RuntimeException {
+
+    private final Integer status;
+
+    private final String[] args;
+
+    public InternalException(Integer status, String... args) {
+        this.status = status;
+        this.args = args;
+    }
+
+}

+ 10 - 0
src/main/java/com/sciradar/exception/NotFoundException.java

@@ -0,0 +1,10 @@
+package com.sciradar.exception;
+
+public class NotFoundException extends RuntimeException {
+    public NotFoundException() {
+    }
+
+    public NotFoundException(String msg) {
+        super(msg);
+    }
+}

+ 11 - 0
src/main/java/com/sciradar/exception/SavedDataException.java

@@ -0,0 +1,11 @@
+package com.sciradar.exception;
+
+public class SavedDataException extends RuntimeException {
+    public SavedDataException() {
+        super();
+    }
+
+    public SavedDataException(String message) {
+        super(message);
+    }
+}

+ 9 - 0
src/main/java/com/sciradar/exception/UndefinedException.java

@@ -0,0 +1,9 @@
+package com.sciradar.exception;
+
+public class UndefinedException extends Exception {
+    private final String msg;
+
+    public UndefinedException(String msg) {
+        this.msg = msg;
+    }
+}

+ 14 - 0
src/main/java/com/sciradar/service/DocumentServiceClient.java

@@ -0,0 +1,14 @@
+package com.sciradar.service;
+
+import com.sciradar.data_model.document.FavoriteDocument;
+import com.sciradar.data_model.document.request.DocumentsRequest;
+import com.sciradar.data_model.document.request.FavoriteDocumentRequest;
+import com.sciradar.data_model.document.response.Document;
+
+import java.util.List;
+
+public interface DocumentServiceClient {
+    List<FavoriteDocument> getFavoriteByIds(FavoriteDocumentRequest request);
+
+    List<Document> getDocumentsByIds(DocumentsRequest request);
+}

+ 13 - 0
src/main/java/com/sciradar/service/RecommendSearchService.java

@@ -0,0 +1,13 @@
+package com.sciradar.service;
+
+import com.sciradar.data_model.search.request.SearchRequest;
+import com.sciradar.data_model.search.response.SearchResultResponse;
+
+/**
+ * @author lbw
+ * @create 2022/8/15
+ */
+public interface RecommendSearchService {
+
+    SearchResultResponse search(SearchRequest searchRequest);
+}

+ 177 - 0
src/main/java/com/sciradar/service/RedisService.java

@@ -0,0 +1,177 @@
+package com.sciradar.service;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public interface RedisService {
+    /**
+     * 保存属性
+     */
+    void set(String key, Object value, long time);
+
+    /**
+     * 保存属性
+     */
+    void set(String key, Object value);
+
+    /**
+     * 获取属性
+     */
+    Object get(String key);
+
+    /**
+     * 删除属性
+     */
+    Boolean del(String key);
+
+    /**
+     * 批量删除属性
+     */
+    Long del(List<String> keys);
+
+    /**
+     * 设置过期时间
+     */
+    Boolean expire(String key, long time);
+
+    /**
+     * 获取过期时间
+     */
+    Long getExpire(String key);
+
+    /**
+     * 判断是否有该属性
+     */
+    Boolean hasKey(String key);
+
+    /**
+     * 按delta递增
+     */
+    Long incr(String key, long delta);
+
+    /**
+     * 按delta递减
+     */
+    Long decr(String key, long delta);
+
+    /**
+     * 获取Hash结构中的属性
+     */
+    Object hGet(String key, String hashKey);
+
+    /**
+     * 向Hash结构中放入一个属性
+     */
+    Boolean hSet(String key, String hashKey, Object value, long time);
+
+    /**
+     * 向Hash结构中放入一个属性
+     */
+    void hSet(String key, String hashKey, Object value);
+
+    /**
+     * 直接获取整个Hash结构
+     */
+    Map<Object, Object> hGetAll(String key);
+
+    /**
+     * 直接设置整个Hash结构
+     */
+    Boolean hSetAll(String key, Map<String, Object> map, long time);
+
+    /**
+     * 直接设置整个Hash结构
+     */
+    void hSetAll(String key, Map<String, Object> map);
+
+    /**
+     * 删除Hash结构中的属性
+     */
+    void hDel(String key, Object... hashKey);
+
+    /**
+     * 判断Hash结构中是否有该属性
+     */
+    Boolean hHasKey(String key, String hashKey);
+
+    /**
+     * Hash结构中属性递增
+     */
+    Long hIncr(String key, String hashKey, Long delta);
+
+    /**
+     * Hash结构中属性递减
+     */
+    Long hDecr(String key, String hashKey, Long delta);
+
+    /**
+     * 获取Set结构
+     */
+    Set<Object> sMembers(String key);
+
+    /**
+     * 向Set结构中添加属性
+     */
+    Long sAdd(String key, Object... values);
+
+    /**
+     * 向Set结构中添加属性
+     */
+    Long sAdd(String key, long time, Object... values);
+
+    /**
+     * 是否为Set中的属性
+     */
+    Boolean sIsMember(String key, Object value);
+
+    /**
+     * 获取Set结构的长度
+     */
+    Long sSize(String key);
+
+    /**
+     * 删除Set结构中的属性
+     */
+    Long sRemove(String key, Object... values);
+
+    /**
+     * 获取List结构中的属性
+     */
+    List<Object> lRange(String key, long start, long end);
+
+    /**
+     * 获取List结构的长度
+     */
+    Long lSize(String key);
+
+    /**
+     * 根据索引获取List中的属性
+     */
+    Object lIndex(String key, long index);
+
+    /**
+     * 向List结构中添加属性
+     */
+    Long lPush(String key, Object value);
+
+    /**
+     * 向List结构中添加属性
+     */
+    Long lPush(String key, Object value, long time);
+
+    /**
+     * 向List结构中批量添加属性
+     */
+    Long lPushAll(String key, Object... values);
+
+    /**
+     * 向List结构中批量添加属性
+     */
+    Long lPushAll(String key, Long time, Object... values);
+
+    /**
+     * 从List结构中移除属性
+     */
+    Long lRemove(String key, long count, Object value);
+}

+ 14 - 0
src/main/java/com/sciradar/service/SearchServiceClient.java

@@ -0,0 +1,14 @@
+package com.sciradar.service;
+
+import com.sciradar.data_model.DataSource;
+import com.sciradar.data_model.es.Document;
+import com.sciradar.data_model.search.request.SearchRequest;
+import com.sciradar.data_model.search.response.SearchResultResponse;
+
+import java.util.List;
+
+public interface SearchServiceClient {
+    SearchResultResponse search(SearchRequest searchRequest);
+
+    List<Document> getDocumentsByDoies(DataSource dataSource, List<String> doies);
+}

+ 12 - 0
src/main/java/com/sciradar/service/TranslationServiceClient.java

@@ -0,0 +1,12 @@
+package com.sciradar.service;
+
+import com.sciradar.data_model.document.request.TranslateRequest;
+
+/**
+ * @author lbw
+ * @create 2022/7/14
+ */
+public interface TranslationServiceClient {
+
+    String translate(TranslateRequest request);
+}

+ 14 - 0
src/main/java/com/sciradar/service/UserOrderServiceClient.java

@@ -0,0 +1,14 @@
+package com.sciradar.service;
+
+import com.sciradar.data_model.user.UpUserOrder;
+import com.sciradar.data_model.user.UserOrder;
+
+/**
+ * @author lbw
+ * @create 2022/8/29
+ */
+public interface UserOrderServiceClient {
+
+    void addUserOrder(UserOrder userOrder);
+
+}

+ 10 - 0
src/main/java/com/sciradar/service/UserPermissionServiceClient.java

@@ -0,0 +1,10 @@
+package com.sciradar.service;
+
+/**
+ * @author lbw
+ * @create 2022/8/30
+ */
+public interface UserPermissionServiceClient {
+
+    Boolean hasPermission(Integer userId, String uri);
+}

+ 9 - 0
src/main/java/com/sciradar/service/analytics/AbstractService.java

@@ -0,0 +1,9 @@
+package com.sciradar.service.analytics;
+
+/**
+ * @author lbw
+ * @create 2022/10/19
+ */
+public interface AbstractService {
+    String setAbstract(String abstr);
+}

+ 62 - 0
src/main/java/com/sciradar/service/analytics/impl/AbstractServiceImpl.java

@@ -0,0 +1,62 @@
+package com.sciradar.service.analytics.impl;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.sciradar.config.GlobalConfiguration;
+import com.sciradar.data_model.analytics.AbstractResponse;
+import com.sciradar.data_model.payment.request.WeChatRequest;
+import com.sciradar.data_model.payment.response.HFivePaymentResponse;
+import com.sciradar.exception.InternalException;
+import com.sciradar.service.analytics.AbstractService;
+import com.sciradar.support.R;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * @author lbw
+ * @create 2022/10/19
+ */
+@Service
+public class AbstractServiceImpl implements AbstractService {
+    private final RestTemplate restTemplate;
+    private final GlobalConfiguration configuration;
+
+    public AbstractServiceImpl(RestTemplate restTemplate, GlobalConfiguration configuration) {
+        this.restTemplate = restTemplate;
+        this.configuration = configuration;
+    }
+
+    @Override
+    public String setAbstract(String abstr)  {
+        ObjectMapper objectMapper = new ObjectMapper();
+        try {
+            abstr = objectMapper.writeValueAsString(abstr);
+        } catch (JsonProcessingException e) {}
+
+        String json = "{\n" +
+                        "\"abstract\": "+abstr+""+
+                        "}" ;
+        String analytics = configuration.getService().getEndpoint().getAnalytics();
+        String url = String.format("%s/api/getformatab/", analytics);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<String> param = new HttpEntity<>(json, headers);
+
+        ParameterizedTypeReference<R<AbstractResponse>> type = new ParameterizedTypeReference<R<AbstractResponse>>() {};
+        ResponseEntity<R<AbstractResponse>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, param, type);
+
+        HttpStatus statusCode = responseEntity.getStatusCode();
+        if (statusCode.is2xxSuccessful()) {
+            R<AbstractResponse> body = responseEntity.getBody();
+            if (body == null) {
+                return null;
+            }
+            return body.getData().getData();
+        }
+
+        throw new InternalException(1107);
+    }
+}

+ 76 - 0
src/main/java/com/sciradar/service/impl/DocumentServiceClientImpl.java

@@ -0,0 +1,76 @@
+package com.sciradar.service.impl;
+
+import com.sciradar.config.GlobalConfiguration;
+import com.sciradar.data_model.document.FavoriteDocument;
+import com.sciradar.data_model.document.request.DocumentsRequest;
+import com.sciradar.data_model.document.request.FavoriteDocumentRequest;
+import com.sciradar.data_model.document.response.Document;
+import com.sciradar.exception.InternalException;
+import com.sciradar.service.DocumentServiceClient;
+import com.sciradar.support.R;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.List;
+
+@Service
+public class DocumentServiceClientImpl implements DocumentServiceClient {
+    private final RestTemplate restTemplate;
+    private final GlobalConfiguration configuration;
+
+    public DocumentServiceClientImpl(RestTemplate restTemplate, GlobalConfiguration configuration) {
+        this.restTemplate = restTemplate;
+        this.configuration = configuration;
+    }
+
+    @Override
+    public List<FavoriteDocument> getFavoriteByIds(FavoriteDocumentRequest request) {
+        String searchEndpoint = configuration.getService().getEndpoint().getDocument();
+        String url = String.format("%s/favorite", searchEndpoint);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<FavoriteDocumentRequest> param = new HttpEntity<>(request, headers);
+
+        ParameterizedTypeReference<R<List<FavoriteDocument>>> type = new ParameterizedTypeReference<R<List<FavoriteDocument>>>() {};
+        ResponseEntity<R<List<FavoriteDocument>>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, param, type);
+
+        HttpStatus statusCode = responseEntity.getStatusCode();
+        if (statusCode.is2xxSuccessful()) {
+            R<List<FavoriteDocument>> body = responseEntity.getBody();
+            if (body == null) {
+                return null;
+            }
+            return body.getData();
+        }
+
+        throw new InternalException(1103);
+    }
+
+    @Override
+    public List<Document> getDocumentsByIds(DocumentsRequest request) {
+        String documentEndpoint = configuration.getService().getEndpoint().getDocument();
+        String url = String.format("%s/document", documentEndpoint);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<DocumentsRequest> param = new HttpEntity<>(request, headers);
+
+        ParameterizedTypeReference<R<List<Document>>> type = new ParameterizedTypeReference<R<List<Document>>>() {};
+        ResponseEntity<R<List<Document>>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, param, type);
+
+        HttpStatus statusCode = responseEntity.getStatusCode();
+        if (statusCode.is2xxSuccessful()) {
+            R<List<Document>> body = responseEntity.getBody();
+            if (body == null) {
+                return null;
+            }
+            return body.getData();
+        }
+
+        throw new InternalException(1103);
+    }
+
+}

+ 51 - 0
src/main/java/com/sciradar/service/impl/RecommendSearchServiceClientImpl.java

@@ -0,0 +1,51 @@
+package com.sciradar.service.impl;
+
+import com.sciradar.config.GlobalConfiguration;
+import com.sciradar.data_model.search.request.SearchRequest;
+import com.sciradar.data_model.search.response.SearchResultResponse;
+import com.sciradar.exception.InternalException;
+import com.sciradar.service.RecommendSearchService;
+import com.sciradar.support.R;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * @author lbw
+ * @create 2022/8/15
+ */
+@Service
+public class RecommendSearchServiceClientImpl implements RecommendSearchService {
+    private final RestTemplate restTemplate;
+    private final GlobalConfiguration configuration;
+
+    public RecommendSearchServiceClientImpl(RestTemplate restTemplate, GlobalConfiguration configuration) {
+        this.restTemplate = restTemplate;
+        this.configuration = configuration;
+    }
+
+    @Override
+    public SearchResultResponse search(SearchRequest searchRequest) {
+        String search = configuration.getService().getEndpoint().getSearch();
+        String url = String.format("%s/Recommendsearch", search);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<SearchRequest> param = new HttpEntity<>(searchRequest, headers);
+
+        ParameterizedTypeReference<R<SearchResultResponse>> type = new ParameterizedTypeReference<R<SearchResultResponse>>() {};
+        ResponseEntity<R<SearchResultResponse>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, param, type);
+
+        HttpStatus statusCode = responseEntity.getStatusCode();
+        if (statusCode.is2xxSuccessful()) {
+            R<SearchResultResponse> body = responseEntity.getBody();
+            if (body == null) {
+                return null;
+            }
+            return body.getData();
+        }
+
+        throw new InternalException(1104);
+    }
+}

+ 200 - 0
src/main/java/com/sciradar/service/impl/RedisServiceImpl.java

@@ -0,0 +1,200 @@
+package com.sciradar.service.impl;
+
+import com.sciradar.service.RedisService;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+@Service
+public class RedisServiceImpl implements RedisService {
+
+    private final RedisTemplate<String, Object> redisTemplate;
+
+    public RedisServiceImpl(RedisTemplate<String, Object> redisTemplate) {
+//        redisTemplate = new RedisTemplate<>();
+        this.redisTemplate = redisTemplate;
+    }
+
+    @Override
+    public void set(String key, Object value, long time) {
+        redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
+    }
+
+    @Override
+    public void set(String key, Object value) {
+        redisTemplate.opsForValue().set(key, value);
+    }
+
+    @Override
+    public Object get(String key) {
+        return redisTemplate.opsForValue().get(key);
+    }
+
+    @Override
+    public Boolean del(String key) {
+        return redisTemplate.delete(key);
+    }
+
+    @Override
+    public Long del(List<String> keys) {
+        return redisTemplate.delete(keys);
+    }
+
+    @Override
+    public Boolean expire(String key, long time) {
+        return redisTemplate.expire(key, time, TimeUnit.SECONDS);
+    }
+
+    @Override
+    public Long getExpire(String key) {
+        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+    }
+
+    @Override
+    public Boolean hasKey(String key) {
+        return redisTemplate.hasKey(key);
+    }
+
+    @Override
+    public Long incr(String key, long delta) {
+        return redisTemplate.opsForValue().increment(key, delta);
+    }
+
+    @Override
+    public Long decr(String key, long delta) {
+        return redisTemplate.opsForValue().increment(key, -delta);
+    }
+
+    @Override
+    public Object hGet(String key, String hashKey) {
+        return redisTemplate.opsForHash().get(key, hashKey);
+    }
+
+    @Override
+    public Boolean hSet(String key, String hashKey, Object value, long time) {
+        redisTemplate.opsForHash().put(key, hashKey, value);
+        return expire(key, time);
+    }
+
+    @Override
+    public void hSet(String key, String hashKey, Object value) {
+        redisTemplate.opsForHash().put(key, hashKey, value);
+    }
+
+    @Override
+    public Map<Object, Object> hGetAll(String key) {
+        return redisTemplate.opsForHash().entries(key);
+    }
+
+    @Override
+    public Boolean hSetAll(String key, Map<String, Object> map, long time) {
+        redisTemplate.opsForHash().putAll(key, map);
+        return expire(key, time);
+    }
+
+    @Override
+    public void hSetAll(String key, Map<String, Object> map) {
+        redisTemplate.opsForHash().putAll(key, map);
+    }
+
+    @Override
+    public void hDel(String key, Object... hashKey) {
+        redisTemplate.opsForHash().delete(key, hashKey);
+    }
+
+    @Override
+    public Boolean hHasKey(String key, String hashKey) {
+        return redisTemplate.opsForHash().hasKey(key, hashKey);
+    }
+
+    @Override
+    public Long hIncr(String key, String hashKey, Long delta) {
+        return redisTemplate.opsForHash().increment(key, hashKey, delta);
+    }
+
+    @Override
+    public Long hDecr(String key, String hashKey, Long delta) {
+        return redisTemplate.opsForHash().increment(key, hashKey, -delta);
+    }
+
+    @Override
+    public Set<Object> sMembers(String key) {
+        return redisTemplate.opsForSet().members(key);
+    }
+
+    @Override
+    public Long sAdd(String key, Object... values) {
+        return redisTemplate.opsForSet().add(key, values);
+    }
+
+    @Override
+    public Long sAdd(String key, long time, Object... values) {
+        Long count = redisTemplate.opsForSet().add(key, values);
+        expire(key, time);
+        return count;
+    }
+
+    @Override
+    public Boolean sIsMember(String key, Object value) {
+        return redisTemplate.opsForSet().isMember(key, value);
+    }
+
+    @Override
+    public Long sSize(String key) {
+        return redisTemplate.opsForSet().size(key);
+    }
+
+    @Override
+    public Long sRemove(String key, Object... values) {
+        return redisTemplate.opsForSet().remove(key, values);
+    }
+
+    @Override
+    public List<Object> lRange(String key, long start, long end) {
+        return redisTemplate.opsForList().range(key, start, end);
+    }
+
+    @Override
+    public Long lSize(String key) {
+        return redisTemplate.opsForList().size(key);
+    }
+
+    @Override
+    public Object lIndex(String key, long index) {
+        return redisTemplate.opsForList().index(key, index);
+    }
+
+    @Override
+    public Long lPush(String key, Object value) {
+        return redisTemplate.opsForList().rightPush(key, value);
+    }
+
+    @Override
+    public Long lPush(String key, Object value, long time) {
+        Long index = redisTemplate.opsForList().rightPush(key, value);
+        expire(key, time);
+        return index;
+    }
+
+    @Override
+    public Long lPushAll(String key, Object... values) {
+        return redisTemplate.opsForList().rightPushAll(key, values);
+    }
+
+    @Override
+    public Long lPushAll(String key, Long time, Object... values) {
+        Long count = redisTemplate.opsForList().rightPushAll(key, values);
+        expire(key, time);
+        return count;
+    }
+
+    @Override
+    public Long lRemove(String key, long count, Object value) {
+        return redisTemplate.opsForList().remove(key, count, value);
+    }
+
+}

+ 90 - 0
src/main/java/com/sciradar/service/impl/SearchServiceClientImpl.java

@@ -0,0 +1,90 @@
+package com.sciradar.service.impl;
+
+import com.sciradar.config.GlobalConfiguration;
+import com.sciradar.constant.Constants;
+import com.sciradar.data_model.DataSource;
+import com.sciradar.data_model.es.Document;
+import com.sciradar.data_model.search.request.DocumentsByDoiesRequest;
+import com.sciradar.data_model.search.request.SearchRequest;
+import com.sciradar.data_model.search.response.SearchResultResponse;
+import com.sciradar.service.SearchServiceClient;
+import com.sciradar.support.R;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class SearchServiceClientImpl implements SearchServiceClient {
+    private final RestTemplate restTemplate;
+    private final GlobalConfiguration configuration;
+
+    public SearchServiceClientImpl(RestTemplate restTemplate, GlobalConfiguration configuration) {
+        this.restTemplate = restTemplate;
+        this.configuration = configuration;
+    }
+
+    @Override
+    public SearchResultResponse search(SearchRequest searchRequest) {
+        String searchEndpoint = configuration.getService().getEndpoint().getSearch();
+        String url = String.format("%s/search", searchEndpoint);
+
+        HttpHeaders headers = new HttpHeaders();
+
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<SearchRequest> param = new HttpEntity<>(searchRequest, headers);
+
+        ParameterizedTypeReference<R<SearchResultResponse>> type = new ParameterizedTypeReference<R<SearchResultResponse>>() {};
+        ResponseEntity<R<SearchResultResponse>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, param, type);
+
+        HttpStatus statusCode = responseEntity.getStatusCode();
+        if (statusCode.is2xxSuccessful()) {
+            R<SearchResultResponse> body = responseEntity.getBody();
+            if (body == null) {
+                return null;
+            }
+            return body.getData();
+        }
+
+        return null;
+    }
+
+    @Override
+    public List<Document> getDocumentsByDoies(DataSource dataSource, List<String> doies) {
+        String searchUrl = configuration.getService().getEndpoint().getSearch();
+        String url = String.format("%s/document/doies", StringUtils.stripEnd(searchUrl, "/"));
+
+        DocumentsByDoiesRequest request = new DocumentsByDoiesRequest();
+        request.setDataSource(dataSource);
+        request.setDoies(doies);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<DocumentsByDoiesRequest> param = new HttpEntity<>(request, headers);
+
+        ParameterizedTypeReference<R<List<Document>>> typeReference = new ParameterizedTypeReference<R<List<Document>>>() {};
+        ResponseEntity<R<List<Document>>> exchange = restTemplate.exchange(url, HttpMethod.POST, param, typeReference);
+
+        List<Document> documents = new ArrayList<>();
+
+        HttpStatus statusCode = exchange.getStatusCode();
+        if (statusCode.is2xxSuccessful()) {
+            R<List<Document>> exchangeBody = exchange.getBody();
+            if (exchangeBody == null) {
+                return documents;
+            }
+            List<Document> respDocuments = exchangeBody.getData();
+            if (respDocuments == null || respDocuments.isEmpty()) {
+                return documents;
+            }
+
+            documents = respDocuments;
+        }
+
+        return documents;
+    }
+}

+ 53 - 0
src/main/java/com/sciradar/service/impl/TranslationServiceClientImpl.java

@@ -0,0 +1,53 @@
+package com.sciradar.service.impl;
+
+import com.sciradar.config.GlobalConfiguration;
+import com.sciradar.data_model.document.FavoriteDocument;
+import com.sciradar.data_model.document.request.FavoriteDocumentRequest;
+import com.sciradar.data_model.document.request.TranslateRequest;
+import com.sciradar.data_model.search.response.SearchResultResponse;
+import com.sciradar.exception.InternalException;
+import com.sciradar.service.TranslationServiceClient;
+import com.sciradar.support.R;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * @author lbw
+ * @create 2022/7/14
+ */
+@Service
+public class TranslationServiceClientImpl implements TranslationServiceClient {
+    private final RestTemplate restTemplate;
+    private final GlobalConfiguration configuration;
+
+    public TranslationServiceClientImpl(RestTemplate restTemplate, GlobalConfiguration configuration) {
+        this.restTemplate = restTemplate;
+        this.configuration = configuration;
+    }
+
+    @Override
+    public String translate(TranslateRequest request) {
+        String translate = configuration.getService().getEndpoint().getDocument();
+        String url = String.format("%s/translate", translate);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<TranslateRequest> param = new HttpEntity<>(request, headers);
+
+        ParameterizedTypeReference<R<String>> type = new ParameterizedTypeReference<R<String>>() {};
+        ResponseEntity<R<String>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, param, type);
+
+        HttpStatus statusCode = responseEntity.getStatusCode();
+        if (statusCode.is2xxSuccessful()) {
+            R<String> body = responseEntity.getBody();
+            if (body == null) {
+                return null;
+            }
+            return body.getData();
+        }
+
+        throw new InternalException(1103);
+    }
+}

+ 52 - 0
src/main/java/com/sciradar/service/impl/UserOrderServiceClientImpl.java

@@ -0,0 +1,52 @@
+package com.sciradar.service.impl;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.sciradar.config.GlobalConfiguration;
+import com.sciradar.data_model.search.response.SearchResultResponse;
+import com.sciradar.data_model.user.UpUserOrder;
+import com.sciradar.data_model.user.UserOrder;
+import com.sciradar.exception.InternalException;
+import com.sciradar.service.UserOrderServiceClient;
+import com.sciradar.support.R;
+import com.sciradar.util.JacksonUtils;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+
+/**
+ * @author lbw
+ * @create 2022/8/29
+ */
+@Service
+public class UserOrderServiceClientImpl implements UserOrderServiceClient {
+    private final RestTemplate restTemplate;
+    private final GlobalConfiguration configuration;
+
+    public UserOrderServiceClientImpl(RestTemplate restTemplate, GlobalConfiguration configuration) {
+        this.restTemplate = restTemplate;
+        this.configuration = configuration;
+    }
+
+    @Override
+    public void addUserOrder(UserOrder userOrder) {
+        String user = configuration.getService().getEndpoint().getUser();
+        String url = String.format("%s/order", user);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<UserOrder> param = new HttpEntity<>(userOrder, headers);
+
+        ParameterizedTypeReference<R<Void>> type = new ParameterizedTypeReference<R<Void>>() {};
+        ResponseEntity<R<Void>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, param, type);
+
+        HttpStatus statusCode = responseEntity.getStatusCode();
+        if (! statusCode.is2xxSuccessful()) {
+            throw new InternalException(1105);
+        }
+    }
+
+}

+ 55 - 0
src/main/java/com/sciradar/service/impl/UserPermissionServiceClientImpl.java

@@ -0,0 +1,55 @@
+package com.sciradar.service.impl;
+
+import com.sciradar.config.GlobalConfiguration;
+import com.sciradar.data_model.user.UserOrder;
+import com.sciradar.exception.InternalException;
+import com.sciradar.service.UserPermissionServiceClient;
+import com.sciradar.support.R;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+/**
+ * @author lbw
+ * @create 2022/8/30
+ */
+@Service
+public class UserPermissionServiceClientImpl implements UserPermissionServiceClient {
+    private final RestTemplate restTemplate;
+    private final GlobalConfiguration configuration;
+
+    public UserPermissionServiceClientImpl(RestTemplate restTemplate, GlobalConfiguration configuration) {
+        this.restTemplate = restTemplate;
+        this.configuration = configuration;
+    }
+
+
+    @Override
+    public Boolean hasPermission(Integer userId, String uri) {
+        String user = configuration.getService().getEndpoint().getUser();
+        String url = String.format("%s/permission/hasPermission", user);
+
+        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
+                .queryParam("userId", userId)
+                .queryParam("uri", uri);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<String> param = new HttpEntity(null, headers);
+
+        ParameterizedTypeReference<R<Boolean>> type = new ParameterizedTypeReference<R<Boolean>>() {};
+        ResponseEntity<R<Boolean>> responseEntity = restTemplate.exchange(builder.build().encode().toUri(), HttpMethod.GET, param, type);
+
+        HttpStatus statusCode = responseEntity.getStatusCode();
+        if (statusCode.is2xxSuccessful()) {
+            R<Boolean> body = responseEntity.getBody();
+            if (body == null) {
+                return null;
+            }
+            return body.getData();
+        }
+        throw new InternalException(1105);
+    }
+}

+ 15 - 0
src/main/java/com/sciradar/service/pay/PaymentServiceClient.java

@@ -0,0 +1,15 @@
+package com.sciradar.service.pay;
+
+
+import com.sciradar.data_model.payment.PayOrderResponse;
+import com.sciradar.data_model.payment.request.WeChatRequest;
+
+/**
+ * @author lbw
+ * @create 2022/9/16
+ */
+public interface PaymentServiceClient {
+
+    PayOrderResponse createOrder(WeChatRequest request);
+
+}

+ 15 - 0
src/main/java/com/sciradar/service/pay/WechatCommonServiceClient.java

@@ -0,0 +1,15 @@
+package com.sciradar.service.pay;
+
+import com.sciradar.data_model.user.UserVerify;
+import com.sciradar.data_model.payment.response.OrderRecordResponse;
+
+/**
+ * @author lbw
+ * @create 2022/9/18
+ */
+public interface WechatCommonServiceClient {
+
+    Boolean verifySignature(UserVerify userVerify) throws Exception;
+
+    OrderRecordResponse transactionsByOrderNo(String orderNo);
+}

+ 52 - 0
src/main/java/com/sciradar/service/pay/impl/HFivePaymentServiceClientImpl.java

@@ -0,0 +1,52 @@
+package com.sciradar.service.pay.impl;
+
+import com.sciradar.config.GlobalConfiguration;
+import com.sciradar.data_model.payment.PayOrderResponse;
+import com.sciradar.data_model.payment.request.WeChatRequest;
+import com.sciradar.data_model.payment.response.HFivePaymentResponse;
+import com.sciradar.exception.InternalException;
+import com.sciradar.service.pay.PaymentServiceClient;
+import com.sciradar.support.R;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * @author lbw
+ * @create 2022/9/16
+ */
+@Service
+public class HFivePaymentServiceClientImpl implements PaymentServiceClient {
+    private final RestTemplate restTemplate;
+    private final GlobalConfiguration configuration;
+
+    public HFivePaymentServiceClientImpl(RestTemplate restTemplate, GlobalConfiguration configuration) {
+        this.restTemplate = restTemplate;
+        this.configuration = configuration;
+    }
+
+    @Override
+    public PayOrderResponse createOrder(WeChatRequest request) {
+        String payment = configuration.getService().getEndpoint().getPayment();
+        String url = String.format("%s/mobilePayment/createOrder", payment);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<WeChatRequest> param = new HttpEntity<>(request, headers);
+
+        ParameterizedTypeReference<R<HFivePaymentResponse>> type = new ParameterizedTypeReference<R<HFivePaymentResponse>>() {};
+        ResponseEntity<R<HFivePaymentResponse>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, param, type);
+
+        HttpStatus statusCode = responseEntity.getStatusCode();
+        if (statusCode.is2xxSuccessful()) {
+            R<HFivePaymentResponse> body = responseEntity.getBody();
+            if (body == null) {
+                return null;
+            }
+            return body.getData();
+        }
+
+        throw new InternalException(1107);
+    }
+}

+ 52 - 0
src/main/java/com/sciradar/service/pay/impl/PCWechatPaymentServiceClientImpl.java

@@ -0,0 +1,52 @@
+package com.sciradar.service.pay.impl;
+
+import com.sciradar.config.GlobalConfiguration;
+import com.sciradar.data_model.payment.PayOrderResponse;
+import com.sciradar.data_model.payment.request.WeChatRequest;
+import com.sciradar.data_model.payment.response.PCWechatPaymentResponse;
+import com.sciradar.exception.InternalException;
+import com.sciradar.service.pay.PaymentServiceClient;
+import com.sciradar.support.R;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * @author lbw
+ * @create 2022/8/31
+ */
+@Service
+public class PCWechatPaymentServiceClientImpl implements PaymentServiceClient {
+    private final RestTemplate restTemplate;
+    private final GlobalConfiguration configuration;
+
+    public PCWechatPaymentServiceClientImpl(RestTemplate restTemplate, GlobalConfiguration configuration) {
+        this.restTemplate = restTemplate;
+        this.configuration = configuration;
+    }
+
+    @Override
+    public PayOrderResponse createOrder(WeChatRequest request) {
+        String payment = configuration.getService().getEndpoint().getPayment();
+        String url = String.format("%s/pcpayment/createOrder", payment);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<WeChatRequest> param = new HttpEntity<>(request, headers);
+
+        ParameterizedTypeReference<R<PCWechatPaymentResponse>> type = new ParameterizedTypeReference<R<PCWechatPaymentResponse>>() {};
+        ResponseEntity<R<PCWechatPaymentResponse>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, param, type);
+
+        HttpStatus statusCode = responseEntity.getStatusCode();
+        if (statusCode.is2xxSuccessful()) {
+            R<PCWechatPaymentResponse> body = responseEntity.getBody();
+            if (body == null) {
+                return null;
+            }
+            return body.getData();
+        }
+
+        throw new InternalException(1107);
+    }
+}

+ 79 - 0
src/main/java/com/sciradar/service/pay/impl/WechatCommonServiceClientImpl.java

@@ -0,0 +1,79 @@
+package com.sciradar.service.pay.impl;
+
+import com.sciradar.config.GlobalConfiguration;
+import com.sciradar.data_model.user.UserVerify;
+import com.sciradar.data_model.payment.response.OrderRecordResponse;
+import com.sciradar.exception.InternalException;
+import com.sciradar.service.pay.WechatCommonServiceClient;
+import com.sciradar.support.R;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+/**
+ * @author lbw
+ * @create 2022/9/18
+ */
+@Service
+public class WechatCommonServiceClientImpl implements WechatCommonServiceClient {
+    private final RestTemplate restTemplate;
+    private final GlobalConfiguration configuration;
+
+    public WechatCommonServiceClientImpl(RestTemplate restTemplate, GlobalConfiguration configuration) {
+        this.restTemplate = restTemplate;
+        this.configuration = configuration;
+    }
+
+    @Override
+    public Boolean verifySignature(UserVerify userVerify) {
+        String payment = configuration.getService().getEndpoint().getPayment();
+        String url = String.format("%s/common/verifySignature", payment);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<UserVerify> param = new HttpEntity<>(userVerify, headers);
+
+        ParameterizedTypeReference<R<Boolean>> type = new ParameterizedTypeReference<R<Boolean>>() {};
+        ResponseEntity<R<Boolean>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, param, type);
+
+        HttpStatus statusCode = responseEntity.getStatusCode();
+        if (statusCode.is2xxSuccessful()) {
+            R<Boolean> body = responseEntity.getBody();
+            if (body == null) {
+                return null;
+            }
+            return body.getData();
+        }
+
+        throw new InternalException(1107);
+    }
+
+    @Override
+    public OrderRecordResponse transactionsByOrderNo(String orderNo) {
+        String payment = configuration.getService().getEndpoint().getPayment();
+        String url = String.format("%s/common/getOrderStatus", payment);
+
+        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
+                .queryParam("orderNo", orderNo);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<String> param = new HttpEntity<>(null, headers);
+
+        ParameterizedTypeReference<R<OrderRecordResponse>> type = new ParameterizedTypeReference<R<OrderRecordResponse>>() {};
+        ResponseEntity<R<OrderRecordResponse>> responseEntity = restTemplate.exchange(builder.build().encode().toUri(), HttpMethod.GET, param, type);
+
+        HttpStatus statusCode = responseEntity.getStatusCode();
+        if (statusCode.is2xxSuccessful()) {
+            R<OrderRecordResponse> body = responseEntity.getBody();
+            if (body == null) {
+                return null;
+            }
+            return body.getData();
+        }
+
+        throw new InternalException(1107);
+    }
+}

+ 49 - 0
src/main/java/com/sciradar/service/pay/impl/WechatPaymentServiceClientImpl.java

@@ -0,0 +1,49 @@
+package com.sciradar.service.pay.impl;
+
+import com.sciradar.config.GlobalConfiguration;
+import com.sciradar.data_model.payment.PayOrderResponse;
+import com.sciradar.data_model.payment.request.WeChatRequest;
+import com.sciradar.data_model.payment.response.HFivePaymentResponse;
+import com.sciradar.data_model.payment.response.WechatPayOrderResponse;
+import com.sciradar.exception.InternalException;
+import com.sciradar.service.pay.PaymentServiceClient;
+import com.sciradar.support.R;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+@Service
+public class WechatPaymentServiceClientImpl implements PaymentServiceClient {
+    private final RestTemplate restTemplate;
+    private final GlobalConfiguration configuration;
+
+    public WechatPaymentServiceClientImpl(RestTemplate restTemplate, GlobalConfiguration configuration) {
+        this.restTemplate = restTemplate;
+        this.configuration = configuration;
+    }
+
+    @Override
+    public PayOrderResponse createOrder(WeChatRequest request) {
+        String payment = configuration.getService().getEndpoint().getPayment();
+        String url = String.format("%s/payment/createOrder", payment);
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        HttpEntity<WeChatRequest> param = new HttpEntity<>(request, headers);
+
+        ParameterizedTypeReference<R<WechatPayOrderResponse>> type = new ParameterizedTypeReference<R<WechatPayOrderResponse>>() {};
+        ResponseEntity<R<WechatPayOrderResponse>> responseEntity = restTemplate.exchange(url, HttpMethod.POST, param, type);
+
+        HttpStatus statusCode = responseEntity.getStatusCode();
+        if (statusCode.is2xxSuccessful()) {
+            R<WechatPayOrderResponse> body = responseEntity.getBody();
+            if (body == null) {
+                return null;
+            }
+            return body.getData();
+        }
+
+        throw new InternalException(1107);
+    }
+}

+ 51 - 0
src/main/java/com/sciradar/support/BaseCondition.java

@@ -0,0 +1,51 @@
+package com.sciradar.support;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * @deseription
+ * @author: tq
+ * @date: 2021/12/4 17:06
+ * @version 1.0
+ **/
+@ApiModel
+public class BaseCondition implements Serializable {
+
+    private static final long serialVersionUID = 5473640580608250742L;
+
+    @ApiModelProperty(value = "每页条数, 默认10条")
+    private Integer pageSize = 10;
+
+    @ApiModelProperty(value = "当前页码,默认第一页")
+    private Integer currentSize = 1;
+
+    @ApiModelProperty(value = "是否分页, 默认分页")
+    private Boolean pageable = true;
+
+    public Integer getPageSize() {
+        return pageSize;
+    }
+
+    public void setPageSize(Integer pageSize) {
+        this.pageSize = pageSize;
+    }
+
+    public Integer getCurrentSize() {
+        return currentSize;
+    }
+
+    public void setCurrentSize(Integer currentSize) {
+        this.currentSize = currentSize;
+    }
+
+    public Boolean getPageable() {
+        return pageable;
+    }
+
+    public void setPageable(Boolean pageable) {
+        this.pageable = pageable;
+    }
+}

+ 127 - 0
src/main/java/com/sciradar/support/Log.java

@@ -0,0 +1,127 @@
+package com.sciradar.support;
+
+import java.io.Serializable;
+
+/**
+ * @deseription
+ * @author: tq
+ * @date: 2021/12/3 23:43
+ * @version 1.0
+**/
+public class Log implements Serializable {
+    private String type;
+    private String uri;
+    private String args;
+    private String clazz;
+    private String method;
+    private Integer line;
+    private String message;
+    private String notes;
+    private String level;
+    private String userId;
+    private String userName;
+    private Long time;
+
+    public Log() {
+    }
+
+    public Log(String level) {
+        this.level = level;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getUri() {
+        return uri;
+    }
+
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
+
+    public String getArgs() {
+        return args;
+    }
+
+    public void setArgs(String args) {
+        this.args = args;
+    }
+
+    public String getClazz() {
+        return clazz;
+    }
+
+    public void setClazz(String clazz) {
+        this.clazz = clazz;
+    }
+
+    public String getMethod() {
+        return method;
+    }
+
+    public void setMethod(String method) {
+        this.method = method;
+    }
+
+    public Integer getLine() {
+        return line;
+    }
+
+    public void setLine(Integer line) {
+        this.line = line;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getNotes() {
+        return notes;
+    }
+
+    public void setNotes(String notes) {
+        this.notes = notes;
+    }
+
+    public String getLevel() {
+        return level;
+    }
+
+    public void setLevel(String level) {
+        this.level = level;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public Long getTime() {
+        return time;
+    }
+
+    public void setTime(Long time) {
+        this.time = time;
+    }
+}

+ 93 - 0
src/main/java/com/sciradar/support/R.java

@@ -0,0 +1,93 @@
+package com.sciradar.support;
+
+import com.sciradar.constant.Constants;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+@ApiModel
+public class R<T> {
+
+    @ApiModelProperty(value = "状态码,1000为成功状态")
+    private Integer status;
+
+    @ApiModelProperty(value = "数据内容")
+    private T data;
+
+    @ApiModelProperty(value = "消息")
+    private String msg;
+
+    @ApiModelProperty(value = "时间戳")
+    private Long timestamp;
+
+    public R() {
+        super();
+    }
+
+    public R(Integer status, String msg) {
+        super();
+        this.status = status;
+        this.msg = msg;
+        this.timestamp = System.currentTimeMillis();
+    }
+
+    public R(Integer status, String msg, T data) {
+        super();
+        this.status = status;
+        this.msg = msg;
+        this.data = data;
+        this.timestamp = System.currentTimeMillis();
+    }
+
+
+    public static <T> R<T> ok() {
+        return new R<T>(Constants.DEFAULT_SUCCESS_STATUS, Constants.DEFAULT_SUCCESS_MSG);
+    }
+
+    public static <T> R<T> ok(T data) {
+        return new R<T>(Constants.DEFAULT_SUCCESS_STATUS, Constants.DEFAULT_SUCCESS_MSG, data);
+    }
+
+    public static <T> R<T> ok(T data, String msg) {
+        return new R<T>(Constants.DEFAULT_SUCCESS_STATUS, msg, data);
+    }
+
+    public static <T> R<T> fail(String msg) {
+        return new R<T>(Constants.DEFAULT_ERROR_STATUS, msg, null);
+    }
+
+    public static <T> R<T> fail(Integer status, String msg) {
+        return new R<T>(status, msg);
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public Long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Long timestamp) {
+        this.timestamp = timestamp;
+    }
+}

+ 93 - 0
src/main/java/com/sciradar/support/entity/UserVO.java

@@ -0,0 +1,93 @@
+package com.sciradar.support.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class UserVO {
+
+    /**
+     * 唯一标识
+     */
+    private Integer id;
+
+    private String nickname;
+
+    private String headPic;
+
+    private String avatarUrl;
+
+    private String wxUnionid;
+
+    private String wxOpenid;
+
+    private String xcxOpenid;
+
+    private String sessionKey;
+
+    private String username;
+
+    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
+    private String password;
+
+    private String truename;
+
+    private Integer level;
+
+    private Integer userType;
+
+    private Integer unitId;
+
+    private String email;
+
+    private Integer sex;
+
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
+    private Date birthday;
+
+    private String organization;
+
+    private String position;
+
+    private String mobile;
+
+    private String language;
+
+    private String city;
+
+    private String province;
+
+    private String country;
+
+    private Date regTime;
+
+    private Date expirationTime;
+
+    private Date lastLoginTime;
+
+    private String getUserapiJson;
+
+    private Integer adminLevel;
+
+    private Integer freeTimes;
+
+    private Integer useTimes;
+
+    private Date utime;
+
+    /**
+     * token
+     */
+    private String token;
+
+    private String isIpUser;
+
+    private Integer onlineNumber;
+}

+ 54 - 0
src/main/java/com/sciradar/util/AgentUserKit.java

@@ -0,0 +1,54 @@
+package com.sciradar.util;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @deseription
+ * @author: tq
+ * @date: 2021/12/11 17:35
+ * @version 1.0
+ **/
+@Component
+public class AgentUserKit {
+
+    private static String pattern = "^Mozilla/\\d\\.\\d\\s+\\(+.+?\\)";
+    private static String pattern2 = "\\(+.+?\\)";
+    private static Pattern r = Pattern.compile(pattern);
+    private static Pattern r2 = Pattern.compile(pattern2);
+
+    public static String getDeviceInfo(HttpServletRequest request) {
+        String userAgent = request.getHeader("User-Agent");
+        return getDeviceInfo(userAgent);
+    }
+
+    private static String getDeviceInfo(String userAgent) {
+        Matcher m = r.matcher(userAgent);
+        String result = null;
+        if (m.find()) {
+            result = m.group(0);
+        }
+
+        Matcher m2 = r2.matcher(result);
+        if (m2.find()) {
+            result = m2.group(0);
+        }
+        result = result.replace("(", "");
+        result = result.replace(")", "");
+        return filterDeviceInfo(result);
+    }
+
+    public static String filterDeviceInfo(String result) {
+        if (StringUtils.isBlank(result)) {
+            return "";
+        }
+        result = result.replace(" U;", "");
+        result = result.replace(" zh-cn;", "");
+        return result;
+    }
+
+}

+ 19 - 0
src/main/java/com/sciradar/util/DocumentUtils.java

@@ -0,0 +1,19 @@
+package com.sciradar.util;
+
+import org.apache.commons.lang3.StringUtils;
+
+public class DocumentUtils {
+    /**
+     * 清理摘要内容
+     * @param summary 摘要内容
+     * @return 清理后的摘要内容
+     */
+    public static String stripSummary(String summary) {
+        if (summary == null) {
+            return "";
+        }
+
+        String replaced = summary.replace("\\\"", "\"").replace("\\'", "'");
+        return StringUtils.strip(replaced, "'");
+    }
+}

+ 31 - 0
src/main/java/com/sciradar/util/EmailValidator.java

@@ -0,0 +1,31 @@
+package com.sciradar.util;
+
+import com.sciradar.annotation.RegexEmail;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class EmailValidator implements ConstraintValidator<RegexEmail, String> {
+
+    @Override
+    public void initialize(RegexEmail constraintAnnotation) {
+
+    }
+
+    @Override
+    public boolean isValid(String value, ConstraintValidatorContext context) {
+        if (null==value || "".equals(value)){
+            return false;
+        }
+        String regEx1 = "^([a-z0-9A-Z]+[_-|\\.]?)+[a-z0-9A-Z_]@([a-z0-9A-Z]+(-[a-z0-9A-Z_]+)?\\.)+[a-zA-Z0-9_]{2,}$";
+        Pattern p = Pattern.compile(regEx1);
+        Matcher m = p.matcher(value);
+        if(m.matches()){
+            return true;
+        }else{
+            return false;
+        }
+    }
+}

+ 29 - 0
src/main/java/com/sciradar/util/HttpHeaderUtils.java

@@ -0,0 +1,29 @@
+package com.sciradar.util;
+
+import com.sciradar.constant.Constants;
+import com.sciradar.exception.NotFoundException;
+import org.springframework.http.HttpHeaders;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+public class HttpHeaderUtils {
+    public static int getUserId(HttpHeaders httpHeaders) {
+        List<String> values = httpHeaders.getOrEmpty(Constants.HTTP_HEADER_USER_ID);
+        if (values.isEmpty()) {
+            throw new NotFoundException();
+        }
+
+        String value = values.get(0);
+
+        int userId;
+        try {
+            userId = Integer.parseInt(value);
+        } catch (NumberFormatException e) {
+            throw new NotFoundException();
+        }
+
+        return userId;
+    }
+}

+ 30 - 0
src/main/java/com/sciradar/util/ImageValidator.java

@@ -0,0 +1,30 @@
+package com.sciradar.util;
+
+import com.sciradar.annotation.RegexImage;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * @deseription 图片校验处理
+ * @author: tq
+ * @date: 2021/12/25 12:28
+ * @version 1.0
+ **/
+public class ImageValidator implements ConstraintValidator<RegexImage, String> {
+    @Override
+    public void initialize(RegexImage constraintAnnotation) {
+
+    }
+
+    @Override
+    public boolean isValid(String image, ConstraintValidatorContext context) {
+        if (!(image.startsWith("http") || image.startsWith("https"))) {
+            return false;
+        }
+        if (!(image.endsWith("png") || image.endsWith("jpg") || image.endsWith("gif"))) {
+            return false;
+        }
+        return true;
+    }
+}

+ 103 - 0
src/main/java/com/sciradar/util/IpAddrUtil.java

@@ -0,0 +1,103 @@
+package com.sciradar.util;
+
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.util.Enumeration;
+
+
+/**
+ * @deseription 获取ip工具类
+ * @author: tq
+ * @date: 2021/12/4 18:17
+ * @version 1.0
+ **/
+@Component
+public class IpAddrUtil {
+    private static final String[] HEADERS = {
+            "X-Forwarded-For",
+            "Proxy-Client-IP",
+            "WL-Proxy-Client-IP",
+            "HTTP_X_FORWARDED_FOR",
+            "HTTP_X_FORWARDED",
+            "HTTP_X_CLUSTER_CLIENT_IP",
+            "HTTP_CLIENT_IP",
+            "HTTP_FORWARDED_FOR",
+            "HTTP_FORWARDED",
+            "HTTP_VIA",
+            "REMOTE_ADDR",
+            "X-Real-IP"
+    };
+
+
+    /**
+     * @Description 获取客户端ip地址(可以穿透代理)
+     * @Author tq
+     * @Date 2020/5/11 16:46
+     * @param request
+     * @Return ip
+     */
+    public static String getIpAddress(HttpServletRequest request) {
+        String ip = "";
+        for (String header : HEADERS) {
+            ip = request.getHeader(header);
+            if (StringUtil.isNotEmpty(ip)) {
+                break;
+            }
+        }
+        if (StringUtil.isEmpty(ip)) {
+            ip = request.getRemoteAddr();
+        }
+        if (StringUtil.isNotEmpty(ip) && ip.contains(",")) {
+            ip = ip.split(",")[0];
+        }
+        if ("0:0:0:0:0:0:0:1".equals(ip)) {
+            ip = "127.0.0.1";
+        }
+        return ip;
+    }
+
+    /**
+     * @Description 获取本机的局域网ip地址,兼容Linux
+     * @Author tq
+     * @Date 2020/5/11 16:42
+     * @Return ip
+     */
+    public static String getLocalHostIP() throws Exception {
+        Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
+        String localHostAddress = "";
+        while (allNetInterfaces.hasMoreElements()) {
+            NetworkInterface networkInterface = allNetInterfaces.nextElement();
+            Enumeration<InetAddress> address = networkInterface.getInetAddresses();
+            while (address.hasMoreElements()) {
+                InetAddress inetAddress = address.nextElement();
+                if (inetAddress != null && inetAddress instanceof Inet4Address) {
+                    localHostAddress = inetAddress.getHostAddress();
+                }
+            }
+        }
+        return localHostAddress;
+    }
+
+    //获取IP
+    public static String getIpAddr(HttpServletRequest request) {
+        String ip = request.getHeader("X-Forwarded-For");
+        if (StringUtil.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
+            //多次反向代理后会有多个ip值,第一个ip才是真实ip
+            int index = ip.indexOf(",");
+            if (index != -1) {
+                return ip.substring(0, index);
+            } else {
+                return ip;
+            }
+        }
+        ip = request.getHeader("X-Real-IP");
+        if (StringUtil.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
+            return ip;
+        }
+        return request.getRemoteAddr();
+    }
+}

+ 13 - 0
src/main/java/com/sciradar/util/JacksonUtils.java

@@ -0,0 +1,13 @@
+package com.sciradar.util;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+
+public class JacksonUtils {
+
+    public static <T> String formatJson(T obj) {
+        return JSONObject.toJSONString(obj, SerializerFeature.PrettyFormat, SerializerFeature.WriteDateUseDateFormat);
+
+    }
+}

+ 91 - 0
src/main/java/com/sciradar/util/JsonUtil.java

@@ -0,0 +1,91 @@
+package com.sciradar.util;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+
+
+/**
+ * @deseription json工具类
+ * @author: tq
+ * @date: 2021/12/10 23:39
+ * @version 1.0
+**/
+@Component
+public class JsonUtil {
+	
+	private static ObjectMapper objectMapper = new ObjectMapper();
+	
+	  /**
+     * 将对象序列化
+     * 
+     * @param obj
+     * @return
+     */
+    public static String getJsonFromObject(Object obj) {
+        try {
+            String str = objectMapper.writeValueAsString(obj);
+            return new String(str.getBytes("UTF-8"));
+        } catch (Exception e) {
+            return null;
+        }
+    }
+    
+    public static JsonNode getJsonNodeFromString(String content) {
+    	try {
+			return objectMapper.readTree(content);
+		} catch (IOException e) {
+            return null;
+		}
+    }
+    
+    /**
+     * 反序列化对象字符串
+     * 
+     * @param json
+     * @param clazz
+     * @return
+     */
+    public static <T> T getObjectFromJson(String json, Class<T> clazz) {
+        try {
+            return objectMapper.readValue(json, clazz);
+        }catch (IOException e) {
+            return null;
+        }
+    }
+
+    /**
+     * 反序列化字符串成为对象
+     * @param json
+     * @param valueTypeRef
+     * @return
+     */
+    public static <T> T getObjectFromJson(String json, TypeReference<T> valueTypeRef) {
+        try {
+            return objectMapper.readValue(json, valueTypeRef);
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+
+    /**
+     * 返回未转换的字符串
+     * @param objectId
+     * @param objectType
+     * @param objectName
+     * @param objectImg
+     * @param orderId
+     * @param orderType
+     * @param storeId
+     * @param storeType
+     * @return
+     */
+    public static String returnStr(String objectId, Integer objectType, String objectName, String objectImg, Long orderId, Integer orderType, Long storeId, Integer storeType){
+        //String str = "[{objectId:"+objectId+",objectType:"+objectType+",objectName:"+objectName+",objectImg:"+objectImg+"},{objectId:"+orderId+",objectType:"+orderType+"},{objectId:"+storeId+",objectType:"+storeType+"}]";
+        return "[{\"objectId\":"+objectId+",\"objectType\":"+objectType+",\"objectName\":\""+objectName+"\",\"objectImg\":"+objectImg+"},{\"objectId\":"+orderId+",\"objectType\":"+orderType+"},{\"objectId\":"+storeId+",\"objectType\":"+storeType+"}]";
+    }
+}

+ 81 - 0
src/main/java/com/sciradar/util/LogUtils.java

@@ -0,0 +1,81 @@
+package com.sciradar.util;
+
+import com.sciradar.support.Log;
+import org.apache.commons.lang3.ArrayUtils;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.logging.LogLevel;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Optional;
+
+public class LogUtils {
+    public static Log info(Class<?> clz, String method, String msg) {
+        return LogUtils.info(clz, method, msg, true);
+    }
+
+
+    public static Log error(Class<?> clz, Exception e, String msg) {
+        return LogUtils.error(clz, e, msg, true);
+    }
+
+    public static Log error(Class<?> clz, String method, String msg) {
+        return LogUtils.error(clz, method, msg, true);
+    }
+    public static Log info(Class<?> clz, String method, String msg, boolean print) {
+        Log log = buildLog(LogLevel.INFO.name());
+        log.setClazz(clz.getName());
+        log.setMethod(method);
+        log.setMessage(msg);
+        if (print) {
+            LoggerFactory.getLogger(clz).info(JacksonUtils.formatJson(log));
+        }
+        return log;
+    }
+
+    public static Log error(Class<?> clz, String method, String msg, boolean print) {
+        Log log = buildLog(LogLevel.ERROR.name());
+        log.setClazz(clz.getName());
+        log.setMethod(method);
+        log.setMessage(msg);
+
+
+
+        if (print) {
+            LoggerFactory.getLogger(clz).error(JacksonUtils.formatJson(log));
+        }
+        return log;
+    }
+
+    public static Log error(Class<?> clz, Exception e, String msg, boolean print) {
+        Log log = buildLog(LogLevel.ERROR.name());
+        log.setNotes(e.getMessage());
+        log.setMessage(msg);
+
+        StackTraceElement[] stackTrace = e.getStackTrace();
+        if (ArrayUtils.isNotEmpty(stackTrace)) {
+            log.setMethod(stackTrace[0].getMethodName());
+            log.setClazz(stackTrace[0].getClassName());
+            log.setLine(stackTrace[0].getLineNumber());
+        }
+        if (print) {
+            LoggerFactory.getLogger(log.getClazz()).error(JacksonUtils.formatJson(log));
+        }
+        return log;
+    }
+
+    private static Log buildLog(String level) {
+        Log log = new Log(level);
+        log.setTime(System.currentTimeMillis());
+        Optional<RequestAttributes> requestAttributes = Optional.ofNullable(RequestContextHolder.getRequestAttributes());
+        requestAttributes.ifPresent(r -> {
+            HttpServletRequest request = ((ServletRequestAttributes) r).getRequest();
+            log.setUri(request.getRequestURI().toString());
+            log.setType(request.getMethod());
+            log.setArgs(request.getQueryString());
+        });
+        return log;
+    }
+}

+ 72 - 0
src/main/java/com/sciradar/util/Md5Utils.java

@@ -0,0 +1,72 @@
+package com.sciradar.util;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class Md5Utils {
+
+    public static String stringToMD5(String plainText) {
+        byte[] secretBytes = null;
+        try {
+            secretBytes = MessageDigest.getInstance("md5").digest(
+                    plainText.getBytes());
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("没有这个md5算法!");
+        }
+        String md5code = new BigInteger(1, secretBytes).toString(16);
+        for (int i = 0; i < 32 - md5code.length(); i++) {
+            md5code = "0" + md5code;
+        }
+        return md5code;
+    }
+
+    public static String MD5Encode(String origin, String charsetname) {
+        String resultString = null;
+        try {
+            resultString = new String(origin);
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            if (charsetname == null || "".equals(charsetname))
+                resultString = byteArrayToHexString(md.digest(resultString
+                        .getBytes()));
+            else
+                resultString = byteArrayToHexString(md.digest(resultString
+                        .getBytes(charsetname)));
+        } catch (Exception exception) {
+        }
+        return resultString;
+    }
+
+    private static String byteArrayToHexString(byte b[]) {
+        StringBuffer resultSb = new StringBuffer();
+        for (int i = 0; i < b.length; i++)
+            resultSb.append(byteToHexString(b[i]));
+
+        return resultSb.toString();
+    }
+
+    private static String byteToHexString(byte b) {
+        int n = b;
+        if (n < 0)
+            n += 256;
+        int d1 = n / 16;
+        int d2 = n % 16;
+        return hexDigits[d1] + hexDigits[d2];
+    }
+
+    /**
+     *  校验MD5码
+     *
+     * @param text
+     *      	要校验的字符串
+     * @param md5
+     *            md5值
+     * @return 校验结果
+     */
+    public static boolean valid(String text, String md5) {
+        return md5.equals(stringToMD5(text)) || md5.equals(stringToMD5(text).toUpperCase());
+    }
+
+    private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
+            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
+}

+ 0 - 0
src/main/java/com/sciradar/util/PaymentUtil.java


Некоторые файлы не были показаны из-за большого количества измененных файлов