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

【项目开发】

1.优化项目代码结构
ChenYL преди 11 месеца
родител
ревизия
5110df69b5
променени са 42 файла, в които са добавени 639 реда и са изтрити 140 реда
  1. 17 0
      data-easy/pom.xml
  2. 5 3
      data-easy/src/main/java/com/dataeasy/server/AppEncryptor.java
  3. 1 1
      data-easy/src/main/java/com/dataeasy/server/core/config/HzApiConfig.java
  4. 4 4
      data-easy/src/main/java/com/dataeasy/server/feign/FinanceFeign.java
  5. 4 4
      data-easy/src/main/java/com/dataeasy/server/feign/HzApiFeign.java
  6. 1 1
      data-easy/src/main/java/com/dataeasy/server/feign/dto/finance/BondResponse.java
  7. 1 1
      data-easy/src/main/java/com/dataeasy/server/feign/dto/finance/FinanceRequest.java
  8. 1 1
      data-easy/src/main/java/com/dataeasy/server/feign/dto/finance/StockResponse.java
  9. 1 1
      data-easy/src/main/java/com/dataeasy/server/feign/dto/hzapi/DaLeTouResponse.java
  10. 1 1
      data-easy/src/main/java/com/dataeasy/server/feign/dto/hzapi/HzApiBaseResponse.java
  11. 1 1
      data-easy/src/main/java/com/dataeasy/server/feign/dto/hzapi/HzApiRequest.java
  12. 1 1
      data-easy/src/main/java/com/dataeasy/server/feign/dto/hzapi/ShuangSeQiuResponse.java
  13. 1 1
      data-easy/src/main/java/com/dataeasy/server/service/manager/IAiChatManager.java
  14. 3 3
      data-easy/src/main/java/com/dataeasy/server/service/manager/IFinanceManager.java
  15. 3 3
      data-easy/src/main/java/com/dataeasy/server/service/manager/IHzApiManager.java
  16. 2 2
      data-easy/src/main/java/com/dataeasy/server/service/manager/impl/AiChatManagerImpl.java
  17. 6 6
      data-easy/src/main/java/com/dataeasy/server/service/manager/impl/FinanceManagerImpl.java
  18. 7 7
      data-easy/src/main/java/com/dataeasy/server/service/manager/impl/HzApiManagerImpl.java
  19. 0 0
      data-easy/src/main/resources/prompts/system-message.st
  20. 0 36
      product-hunt/pom.xml
  21. 30 0
      product-hunt/src/main/java/com/producthunt/server/common/BusinessException.java
  22. 15 0
      product-hunt/src/main/java/com/producthunt/server/common/IgnoreResponseWrapper.java
  23. 113 0
      product-hunt/src/main/java/com/producthunt/server/common/JsonResponse.java
  24. 19 0
      product-hunt/src/main/java/com/producthunt/server/common/LoginException.java
  25. 25 0
      product-hunt/src/main/java/com/producthunt/server/common/ResponseCodeEnum.java
  26. 68 0
      product-hunt/src/main/java/com/producthunt/server/core/aop/GlobalExceptionHandler.java
  27. 48 0
      product-hunt/src/main/java/com/producthunt/server/core/aop/ResponseControllerAdvice.java
  28. 53 0
      product-hunt/src/main/java/com/producthunt/server/core/aop/WebOperateLogAspect.java
  29. 32 0
      product-hunt/src/main/java/com/producthunt/server/core/config/BizConfig.java
  30. 31 0
      product-hunt/src/main/java/com/producthunt/server/core/config/EncryptorConfig.java
  31. 2 0
      product-hunt/src/main/java/com/producthunt/server/core/config/FeignConfig.java
  32. 0 22
      product-hunt/src/main/java/com/producthunt/server/core/config/GraphQLClientConfig.java
  33. 39 0
      product-hunt/src/main/java/com/producthunt/server/core/config/WebMvcConfig.java
  34. 51 0
      product-hunt/src/main/java/com/producthunt/server/core/interceptor/AuthInterceptor.java
  35. 2 2
      product-hunt/src/main/java/com/producthunt/server/feign/ProductHuntFeign.java
  36. 1 1
      product-hunt/src/main/java/com/producthunt/server/feign/dto/OauthRequest.java
  37. 1 1
      product-hunt/src/main/java/com/producthunt/server/feign/dto/OauthResponse.java
  38. 24 0
      product-hunt/src/main/java/com/producthunt/server/service/controller/HealthController.java
  39. 2 2
      product-hunt/src/main/java/com/producthunt/server/service/manager/impl/ProductHuntManagerImpl.java
  40. 6 16
      product-hunt/src/main/resources/application-dev.yaml
  41. 6 17
      product-hunt/src/main/resources/application-prod.yaml
  42. 11 2
      product-hunt/src/main/resources/application.yaml

+ 17 - 0
data-easy/pom.xml

@@ -14,8 +14,21 @@
     <properties>
         <wxjava.version>4.7.0</wxjava.version>
         <jwt.version>4.4.0</jwt.version>
+        <spring-ai.version>1.0.0-M6</spring-ai.version>
     </properties>
 
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.ai</groupId>
+                <artifactId>spring-ai-bom</artifactId>
+                <version>${spring-ai.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
     <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
@@ -30,6 +43,10 @@
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.ai</groupId>
+            <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>

+ 5 - 3
product-hunt/src/main/java/com/producthunt/server/AppEncryptor.java → data-easy/src/main/java/com/dataeasy/server/AppEncryptor.java

@@ -1,4 +1,4 @@
-package com.producthunt.server;
+package com.dataeasy.server;
 
 import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
 import org.jasypt.iv.RandomIvGenerator;
@@ -50,7 +50,9 @@ public class AppEncryptor {
 
     public static void main(String[] args) {
         AppEncryptor appEncryptor = new AppEncryptor("", "PBEWithMD5AndDES");
-        appEncryptor.encryptAndShow("id", "");
-        appEncryptor.encryptAndShow("key", "");
+        appEncryptor.encryptAndShow("dev", "");
+
+        AppEncryptor appEncryptor2 = new AppEncryptor("", "PBEWithMD5AndDES");
+        appEncryptor2.encryptAndShow("prod", "");
     }
 }

+ 1 - 1
product-hunt/src/main/java/com/producthunt/server/core/config/HzApiConfig.java → data-easy/src/main/java/com/dataeasy/server/core/config/HzApiConfig.java

@@ -1,4 +1,4 @@
-package com.producthunt.server.core.config;
+package com.dataeasy.server.core.config;
 
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.stereotype.Component;

+ 4 - 4
product-hunt/src/main/java/com/producthunt/server/feign/FinanceFeign.java → data-easy/src/main/java/com/dataeasy/server/feign/FinanceFeign.java

@@ -1,8 +1,8 @@
-package com.producthunt.server.feign;
+package com.dataeasy.server.feign;
 
-import com.producthunt.server.feign.dto.finance.BondResponse;
-import com.producthunt.server.feign.dto.finance.FinanceRequest;
-import com.producthunt.server.feign.dto.finance.StockResponse;
+import com.dataeasy.server.feign.dto.finance.BondResponse;
+import com.dataeasy.server.feign.dto.finance.FinanceRequest;
+import com.dataeasy.server.feign.dto.finance.StockResponse;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.cloud.openfeign.SpringQueryMap;
 import org.springframework.web.bind.annotation.GetMapping;

+ 4 - 4
product-hunt/src/main/java/com/producthunt/server/feign/HzApiFeign.java → data-easy/src/main/java/com/dataeasy/server/feign/HzApiFeign.java

@@ -1,8 +1,8 @@
-package com.producthunt.server.feign;
+package com.dataeasy.server.feign;
 
-import com.producthunt.server.feign.dto.hzapi.DaLeTouResponse;
-import com.producthunt.server.feign.dto.hzapi.HzApiRequest;
-import com.producthunt.server.feign.dto.hzapi.ShuangSeQiuResponse;
+import com.dataeasy.server.feign.dto.hzapi.DaLeTouResponse;
+import com.dataeasy.server.feign.dto.hzapi.HzApiRequest;
+import com.dataeasy.server.feign.dto.hzapi.ShuangSeQiuResponse;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.cloud.openfeign.SpringQueryMap;
 import org.springframework.web.bind.annotation.GetMapping;

+ 1 - 1
product-hunt/src/main/java/com/producthunt/server/feign/dto/finance/BondResponse.java → data-easy/src/main/java/com/dataeasy/server/feign/dto/finance/BondResponse.java

@@ -1,4 +1,4 @@
-package com.producthunt.server.feign.dto.finance;
+package com.dataeasy.server.feign.dto.finance;
 
 import java.io.Serial;
 import java.io.Serializable;

+ 1 - 1
product-hunt/src/main/java/com/producthunt/server/feign/dto/finance/FinanceRequest.java → data-easy/src/main/java/com/dataeasy/server/feign/dto/finance/FinanceRequest.java

@@ -1,4 +1,4 @@
-package com.producthunt.server.feign.dto.finance;
+package com.dataeasy.server.feign.dto.finance;
 
 import feign.Param;
 import lombok.Data;

+ 1 - 1
product-hunt/src/main/java/com/producthunt/server/feign/dto/finance/StockResponse.java → data-easy/src/main/java/com/dataeasy/server/feign/dto/finance/StockResponse.java

@@ -1,4 +1,4 @@
-package com.producthunt.server.feign.dto.finance;
+package com.dataeasy.server.feign.dto.finance;
 
 import java.io.Serial;
 import java.io.Serializable;

+ 1 - 1
product-hunt/src/main/java/com/producthunt/server/feign/dto/hzapi/DaLeTouResponse.java → data-easy/src/main/java/com/dataeasy/server/feign/dto/hzapi/DaLeTouResponse.java

@@ -1,4 +1,4 @@
-package com.producthunt.server.feign.dto.hzapi;
+package com.dataeasy.server.feign.dto.hzapi;
 
 import lombok.Data;
 import lombok.EqualsAndHashCode;

+ 1 - 1
product-hunt/src/main/java/com/producthunt/server/feign/dto/hzapi/HzApiBaseResponse.java → data-easy/src/main/java/com/dataeasy/server/feign/dto/hzapi/HzApiBaseResponse.java

@@ -1,4 +1,4 @@
-package com.producthunt.server.feign.dto.hzapi;
+package com.dataeasy.server.feign.dto.hzapi;
 
 import lombok.Data;
 

+ 1 - 1
product-hunt/src/main/java/com/producthunt/server/feign/dto/hzapi/HzApiRequest.java → data-easy/src/main/java/com/dataeasy/server/feign/dto/hzapi/HzApiRequest.java

@@ -1,4 +1,4 @@
-package com.producthunt.server.feign.dto.hzapi;
+package com.dataeasy.server.feign.dto.hzapi;
 
 import lombok.Data;
 

+ 1 - 1
product-hunt/src/main/java/com/producthunt/server/feign/dto/hzapi/ShuangSeQiuResponse.java → data-easy/src/main/java/com/dataeasy/server/feign/dto/hzapi/ShuangSeQiuResponse.java

@@ -1,4 +1,4 @@
-package com.producthunt.server.feign.dto.hzapi;
+package com.dataeasy.server.feign.dto.hzapi;
 
 import lombok.Data;
 import lombok.EqualsAndHashCode;

+ 1 - 1
product-hunt/src/main/java/com/producthunt/server/service/manager/IAiChatManager.java → data-easy/src/main/java/com/dataeasy/server/service/manager/IAiChatManager.java

@@ -1,4 +1,4 @@
-package com.producthunt.server.service.manager;
+package com.dataeasy.server.service.manager;
 
 /**
  * @author tyuio

+ 3 - 3
product-hunt/src/main/java/com/producthunt/server/service/manager/IFinanceManager.java → data-easy/src/main/java/com/dataeasy/server/service/manager/IFinanceManager.java

@@ -1,7 +1,7 @@
-package com.producthunt.server.service.manager;
+package com.dataeasy.server.service.manager;
 
-import com.producthunt.server.feign.dto.finance.BondResponse;
-import com.producthunt.server.feign.dto.finance.StockResponse;
+import com.dataeasy.server.feign.dto.finance.BondResponse;
+import com.dataeasy.server.feign.dto.finance.StockResponse;
 
 import java.util.List;
 

+ 3 - 3
product-hunt/src/main/java/com/producthunt/server/service/manager/IHzApiManager.java → data-easy/src/main/java/com/dataeasy/server/service/manager/IHzApiManager.java

@@ -1,7 +1,7 @@
-package com.producthunt.server.service.manager;
+package com.dataeasy.server.service.manager;
 
-import com.producthunt.server.feign.dto.hzapi.DaLeTouResponse;
-import com.producthunt.server.feign.dto.hzapi.ShuangSeQiuResponse;
+import com.dataeasy.server.feign.dto.hzapi.DaLeTouResponse;
+import com.dataeasy.server.feign.dto.hzapi.ShuangSeQiuResponse;
 
 /**
  * @author tyuio

+ 2 - 2
product-hunt/src/main/java/com/producthunt/server/service/manager/impl/AiChatManagerImpl.java → data-easy/src/main/java/com/dataeasy/server/service/manager/impl/AiChatManagerImpl.java

@@ -1,6 +1,6 @@
-package com.producthunt.server.service.manager.impl;
+package com.dataeasy.server.service.manager.impl;
 
-import com.producthunt.server.service.manager.IAiChatManager;
+import com.dataeasy.server.service.manager.IAiChatManager;
 import org.springframework.ai.chat.client.ChatClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;

+ 6 - 6
product-hunt/src/main/java/com/producthunt/server/service/manager/impl/FinanceManagerImpl.java → data-easy/src/main/java/com/dataeasy/server/service/manager/impl/FinanceManagerImpl.java

@@ -1,10 +1,10 @@
-package com.producthunt.server.service.manager.impl;
+package com.dataeasy.server.service.manager.impl;
 
-import com.producthunt.server.feign.FinanceFeign;
-import com.producthunt.server.feign.dto.finance.BondResponse;
-import com.producthunt.server.feign.dto.finance.FinanceRequest;
-import com.producthunt.server.feign.dto.finance.StockResponse;
-import com.producthunt.server.service.manager.IFinanceManager;
+import com.dataeasy.server.feign.FinanceFeign;
+import com.dataeasy.server.feign.dto.finance.BondResponse;
+import com.dataeasy.server.feign.dto.finance.FinanceRequest;
+import com.dataeasy.server.feign.dto.finance.StockResponse;
+import com.dataeasy.server.service.manager.IFinanceManager;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;

+ 7 - 7
product-hunt/src/main/java/com/producthunt/server/service/manager/impl/HzApiManagerImpl.java → data-easy/src/main/java/com/dataeasy/server/service/manager/impl/HzApiManagerImpl.java

@@ -1,11 +1,11 @@
-package com.producthunt.server.service.manager.impl;
+package com.dataeasy.server.service.manager.impl;
 
-import com.producthunt.server.core.config.HzApiConfig;
-import com.producthunt.server.feign.HzApiFeign;
-import com.producthunt.server.feign.dto.hzapi.DaLeTouResponse;
-import com.producthunt.server.feign.dto.hzapi.HzApiRequest;
-import com.producthunt.server.feign.dto.hzapi.ShuangSeQiuResponse;
-import com.producthunt.server.service.manager.IHzApiManager;
+import com.dataeasy.server.core.config.HzApiConfig;
+import com.dataeasy.server.feign.HzApiFeign;
+import com.dataeasy.server.feign.dto.hzapi.DaLeTouResponse;
+import com.dataeasy.server.feign.dto.hzapi.HzApiRequest;
+import com.dataeasy.server.feign.dto.hzapi.ShuangSeQiuResponse;
+import com.dataeasy.server.service.manager.IHzApiManager;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;

+ 0 - 0
product-hunt/src/main/resources/prompts/system-message.st → data-easy/src/main/resources/prompts/system-message.st


+ 0 - 36
product-hunt/pom.xml

@@ -11,22 +11,6 @@
 
     <artifactId>product-hunt</artifactId>
 
-    <properties>
-        <spring-ai.version>1.0.0-M6</spring-ai.version>
-    </properties>
-
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>org.springframework.ai</groupId>
-                <artifactId>spring-ai-bom</artifactId>
-                <version>${spring-ai.version}</version>
-                <type>pom</type>
-                <scope>import</scope>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
-
     <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
@@ -36,10 +20,6 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-validation</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
@@ -52,26 +32,10 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-graphql</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.springframework.ai</groupId>
-            <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-tx</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.mysql</groupId>
-            <artifactId>mysql-connector-j</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
         </dependency>
-        <dependency>
-            <groupId>tk.mybatis</groupId>
-            <artifactId>mapper-spring-boot-starter</artifactId>
-        </dependency>
         <dependency>
             <groupId>com.github.ulisesbocchio</groupId>
             <artifactId>jasypt-spring-boot-starter</artifactId>

+ 30 - 0
product-hunt/src/main/java/com/producthunt/server/common/BusinessException.java

@@ -0,0 +1,30 @@
+package com.producthunt.server.common;
+
+/**
+ * 业务异常
+ *
+ * @author tyuio
+ */
+public class BusinessException extends RuntimeException {
+
+    public BusinessException(String message) {
+        super(message);
+    }
+
+    /**
+     * 构造业务异常信息
+     * @param message
+     * @return
+     */
+    public static BusinessException fail(String message) {
+        return new BusinessException(message);
+    }
+
+    /**
+     * 抛出业务异常
+     * @param message
+     */
+    public static void throwFail(String message) {
+    	throw fail(message);
+    }
+}

+ 15 - 0
product-hunt/src/main/java/com/producthunt/server/common/IgnoreResponseWrapper.java

@@ -0,0 +1,15 @@
+package com.producthunt.server.common;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 忽略接口返回统一处理
+ */
+@Documented
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface IgnoreResponseWrapper {}

+ 113 - 0
product-hunt/src/main/java/com/producthunt/server/common/JsonResponse.java

@@ -0,0 +1,113 @@
+package com.producthunt.server.common;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * json 统一响应体
+ *
+ * @param <T>
+ */
+@Data
+@EqualsAndHashCode
+public class JsonResponse<T> implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = -5372948141725666083L;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss:SSS", timezone = "GMT+8")
+    private Date timestamp = new Date();
+
+    /**
+     * 是否成功标志位 true-成功 false-失败
+     */
+    private Boolean success;
+
+    /**
+     * 响应编码
+     */
+    private String code;
+
+    /**
+     * 错误信息
+     */
+    private String msg;
+
+    /**
+     * 返回数据
+     */
+    private T data;
+
+    public JsonResponse(Boolean success, String code, String msg) {
+        this.success = success;
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public JsonResponse(Boolean success, String code, String msg, T data) {
+        this.success = success;
+        this.code = code;
+        this.msg = msg;
+        this.data = data;
+    }
+
+    /**
+     * 返回成功响应体
+     *
+     * @param <T>
+     * @return
+     */
+    public static <T> JsonResponse<T> success() {
+        return new JsonResponse<>(true, ResponseCodeEnum.SUCCESS.getCode(), ResponseCodeEnum.SUCCESS.getMsg());
+    }
+
+    /**
+     * 返回成功响应体
+     *
+     * @param data 响应数据
+     * @param <T>
+     * @return
+     */
+    public static <T> JsonResponse<T> success(T data) {
+        return new JsonResponse<>(true, ResponseCodeEnum.SUCCESS.getCode(), ResponseCodeEnum.SUCCESS.getMsg(), data);
+    }
+
+    /**
+     * 返回错误响应体
+     *
+     * @param <T>
+     * @return
+     */
+    public static <T> JsonResponse<T> fail() {
+        return new JsonResponse<>(false, ResponseCodeEnum.FAIL.getCode(), ResponseCodeEnum.FAIL.getMsg());
+    }
+
+    /**
+     * 返回错误响应体
+     *
+     * @param msg 错误信息
+     * @param <T>
+     * @return
+     */
+    public static <T> JsonResponse<T> fail(String msg) {
+        return new JsonResponse<>(false, ResponseCodeEnum.FAIL.getCode(), msg);
+    }
+
+    /**
+     * 返回错误响应体
+     *
+     * @param code 错误编码
+     * @param msg 错误信息
+     * @param <T>
+     * @return
+     */
+    public static <T> JsonResponse<T> fail(String code, String msg) {
+        return new JsonResponse<>(false, code, msg);
+    }
+}

+ 19 - 0
product-hunt/src/main/java/com/producthunt/server/common/LoginException.java

@@ -0,0 +1,19 @@
+package com.producthunt.server.common;
+
+/**
+ * @className AuthException
+ * @description 登录校验异常
+ * @author ChenYL 
+ * @date 2023/07/29 20:27
+ * @version V1.0
+**/
+public class LoginException extends RuntimeException {
+
+    public LoginException(String message) {
+        super(message);
+    }
+
+    public static LoginException fail(String message) {
+        return new LoginException(message);
+    }
+}

+ 25 - 0
product-hunt/src/main/java/com/producthunt/server/common/ResponseCodeEnum.java

@@ -0,0 +1,25 @@
+package com.producthunt.server.common;
+
+/**
+ * 基本响应码
+ */
+public enum ResponseCodeEnum {
+
+    SUCCESS("0", "操作成功"), FAIL("999", "操作失败");
+
+    private String code;
+    private String msg;
+
+    ResponseCodeEnum(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+}

+ 68 - 0
product-hunt/src/main/java/com/producthunt/server/core/aop/GlobalExceptionHandler.java

@@ -0,0 +1,68 @@
+package com.producthunt.server.core.aop;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.producthunt.server.common.BusinessException;
+import com.producthunt.server.common.JsonResponse;
+import com.producthunt.server.common.LoginException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.ObjectError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 全局异常处理
+ */
+@Slf4j
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+
+    /**
+     * 业务异常处理
+     *
+     * @param e
+     * @return
+     */
+    @ExceptionHandler(BusinessException.class)
+    public JsonResponse businessExceptionHandler(Exception e) {
+        log.error(e.getMessage(), e);
+        return JsonResponse.fail(e.getMessage());
+    }
+
+    /**
+     * 登录异常处理
+     * @param e
+     * @return
+     */
+    @ExceptionHandler(LoginException.class)
+    public ResponseEntity<Object> loginExceptionHandler(LoginException e) {
+        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(JsonResponse.fail(e.getMessage()));
+    }
+
+    /**
+     * 方法参数校验异常处理
+     * @param e
+     * @return
+     */
+    @ExceptionHandler(MethodArgumentNotValidException.class)
+    public JsonResponse methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
+        List<ObjectError> allErrors = e.getAllErrors();
+        String errorMsg = allErrors.stream().map(error -> error.getDefaultMessage())
+                .collect(Collectors.joining(";"));
+        return JsonResponse.fail(String.format("参数错误:%s", errorMsg));
+    }
+
+    /**
+     * 全局异常处理
+     */
+    @ExceptionHandler(Exception.class)
+    public JsonResponse exceptionHandler(Exception e) {
+        log.error(e.getMessage(), e);
+        return JsonResponse.fail("系统异常,请稍后再试");
+    }
+}

+ 48 - 0
product-hunt/src/main/java/com/producthunt/server/core/aop/ResponseControllerAdvice.java

@@ -0,0 +1,48 @@
+package com.producthunt.server.core.aop;
+
+import com.producthunt.server.common.IgnoreResponseWrapper;
+import com.producthunt.server.common.JsonResponse;
+import org.springframework.core.MethodParameter;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+
+/**
+ * 接口返回统一处理
+ */
+@RestControllerAdvice(basePackages = {"com.producthunt.server.service.controller"})
+public class ResponseControllerAdvice implements ResponseBodyAdvice<Object> {
+    @Override
+    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
+        return returnType.getMethodAnnotation(IgnoreResponseWrapper.class) == null;
+    }
+
+    @Override
+    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
+        Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
+        ServerHttpResponse response) {
+        if (body instanceof JsonResponse || body instanceof ResponseEntity) {
+            return body;
+        }
+
+        Class<?> returnClass = returnType.getParameterType();
+        if (String.class.equals(returnClass)) {
+            ObjectMapper objectMapper = new ObjectMapper();
+            try {
+                return objectMapper.writeValueAsString(JsonResponse.success(body));
+            } catch (JsonProcessingException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        return JsonResponse.success(body);
+    }
+}

+ 53 - 0
product-hunt/src/main/java/com/producthunt/server/core/aop/WebOperateLogAspect.java

@@ -0,0 +1,53 @@
+package com.producthunt.server.core.aop;
+
+import java.util.Arrays;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.multipart.MultipartFile;
+
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Aspect
+@Component
+public class WebOperateLogAspect {
+
+    @Pointcut("execution(* com.producthunt.server.service.controller..*.*(..))")
+    public void pointcut() {}
+
+    @Around("pointcut()")
+    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
+        long startTime = System.currentTimeMillis();
+
+        ServletRequestAttributes requestAttributes =
+            (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = requestAttributes.getRequest();
+
+        String requestURI = request.getRequestURI();
+        Object[] args = Arrays.stream(joinPoint.getArgs()).filter(arg -> !(arg instanceof MultipartFile)).toArray();
+        Object result = null;
+        Exception exception = null;
+        try {
+            result = joinPoint.proceed();
+        } catch (Exception e) {
+            exception = e;
+        }
+        long cost = System.currentTimeMillis() - startTime;
+
+        // 耗时、URI、入参、出参
+        log.info("{}|{}|{}|{}", cost, requestURI, args, result);
+
+        if (exception != null) {
+            throw exception;
+        }
+
+        return result;
+    }
+}

+ 32 - 0
product-hunt/src/main/java/com/producthunt/server/core/config/BizConfig.java

@@ -0,0 +1,32 @@
+package com.producthunt.server.core.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 系统配置类
+ * @date 2025/3/6 16:40
+ */
+@Data
+@Component
+@ConfigurationProperties("biz")
+public class BizConfig {
+
+    /**
+     * 加密密钥
+     */
+    private String secret;
+
+    /**
+     * 加密算法
+     */
+    private String algorithm;
+
+    /**
+     * 系统自访问密钥
+     */
+    private String apiKey;
+}

+ 31 - 0
product-hunt/src/main/java/com/producthunt/server/core/config/EncryptorConfig.java

@@ -0,0 +1,31 @@
+package com.producthunt.server.core.config;
+
+import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
+import org.jasypt.iv.RandomIvGenerator;
+import org.jasypt.salt.RandomSaltGenerator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author tyuio
+ * @version 1.0.0
+ * @description 加解密配置类
+ * @date 2025/3/6 17:02
+ */
+@Configuration
+public class EncryptorConfig {
+
+    @Autowired
+    private BizConfig bizConfig;
+
+    @Bean
+    public StandardPBEStringEncryptor encryptor() {
+        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
+        encryptor.setPassword(bizConfig.getSecret());
+        encryptor.setAlgorithm(bizConfig.getAlgorithm());
+        encryptor.setSaltGenerator(new RandomSaltGenerator());
+        encryptor.setIvGenerator(new RandomIvGenerator());
+        return encryptor;
+    }
+}

+ 2 - 0
product-hunt/src/main/java/com/producthunt/server/core/config/FeignConfig.java

@@ -7,6 +7,7 @@ import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
 import org.springframework.cloud.openfeign.support.SpringDecoder;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
 import org.springframework.http.MediaType;
 import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
 
@@ -29,6 +30,7 @@ public class FeignConfig {
      * @return
      */
     @Bean
+    @Profile("dev")
     public Logger.Level devLogLevel() {
         return Logger.Level.FULL;
     }

+ 0 - 22
product-hunt/src/main/java/com/producthunt/server/core/config/GraphQLClientConfig.java

@@ -1,22 +0,0 @@
-package com.producthunt.server.core.config;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.graphql.client.GraphQlClient;
-import org.springframework.graphql.client.HttpSyncGraphQlClient;
-
-/**
- * @author tyuio
- * @version 1.0.0
- * @description GraphQL客户端配置
- * @date 2025/2/17 18:55
- */
-@Configuration
-public class GraphQLClientConfig {
-
-    @Bean
-    public GraphQlClient graphQLClient() {
-        return HttpSyncGraphQlClient.builder().url("https://api.producthunt.com/v2/api/graphql")
-                .header("Authorization", "Bearer fyE_0xkhXbkLw_81QhuyMHRXqcPnayzkGqVXEftAL2g").build();
-    }
-}

+ 39 - 0
product-hunt/src/main/java/com/producthunt/server/core/config/WebMvcConfig.java

@@ -0,0 +1,39 @@
+package com.producthunt.server.core.config;
+
+import com.producthunt.server.core.interceptor.AuthInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+    @Autowired
+    private AuthInterceptor authInterceptor;
+
+    /**
+     * 登录校验拦截
+     * @param registry
+     */
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(authInterceptor)
+                .excludePathPatterns("/health/**");
+    }
+
+    /**
+     * 跨域配置
+     * @param registry
+     */
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+        registry.addMapping("/**") // 对所有路径生效
+                .allowedOriginPatterns("*") // 允许所有来源
+                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的HTTP方法
+                .allowedHeaders("*") // 允许的头部
+                .allowCredentials(true) // 是否允许发送Cookie
+                .maxAge(3600); // 预检请求的有效期,单位为秒
+    }
+}

+ 51 - 0
product-hunt/src/main/java/com/producthunt/server/core/interceptor/AuthInterceptor.java

@@ -0,0 +1,51 @@
+package com.producthunt.server.core.interceptor;
+
+import com.producthunt.server.common.LoginException;
+import com.producthunt.server.core.config.BizConfig;
+import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author ChenYL
+ * @version V1.0
+ * @className AuthInterceptor
+ * @description 登录权限拦截
+ * @date 2023/07/29 16:22
+ **/
+@Slf4j
+@Component
+public class AuthInterceptor implements HandlerInterceptor {
+
+    @Autowired
+    private BizConfig bizConfig;
+
+    @Autowired
+    private StandardPBEStringEncryptor encryptor;
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
+            throws Exception {
+
+        // 判断请求头中是否有token
+        String apiKeyStr = request.getHeader("Authorization");
+        if (!StringUtils.hasText(apiKeyStr)) {
+            throw LoginException.fail("登录校验异常,原因:没有token凭据");
+        }
+
+        // TODO 这个加解密部分要加点变化的内容
+        String apiKey = encryptor.decrypt(apiKeyStr);
+        if (!bizConfig.getApiKey().equals(apiKey)) {
+            log.warn("登录校验失败,apiKey不符,apiKey:{}", apiKey);
+            throw LoginException.fail("登录校验失败,apiKey不符");
+        }
+
+        return true;
+    }
+}

+ 2 - 2
product-hunt/src/main/java/com/producthunt/server/feign/ProductHuntFeign.java

@@ -4,8 +4,8 @@ import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 
-import com.producthunt.server.feign.dto.producthunt.OauthRequest;
-import com.producthunt.server.feign.dto.producthunt.OauthResponse;
+import com.producthunt.server.feign.dto.OauthRequest;
+import com.producthunt.server.feign.dto.OauthResponse;
 
 /**
  * @author tyuio

+ 1 - 1
product-hunt/src/main/java/com/producthunt/server/feign/dto/producthunt/OauthRequest.java → product-hunt/src/main/java/com/producthunt/server/feign/dto/OauthRequest.java

@@ -1,4 +1,4 @@
-package com.producthunt.server.feign.dto.producthunt;
+package com.producthunt.server.feign.dto;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.Data;

+ 1 - 1
product-hunt/src/main/java/com/producthunt/server/feign/dto/producthunt/OauthResponse.java → product-hunt/src/main/java/com/producthunt/server/feign/dto/OauthResponse.java

@@ -1,4 +1,4 @@
-package com.producthunt.server.feign.dto.producthunt;
+package com.producthunt.server.feign.dto;
 
 import com.fasterxml.jackson.annotation.JsonAlias;
 import lombok.Data;

+ 24 - 0
product-hunt/src/main/java/com/producthunt/server/service/controller/HealthController.java

@@ -0,0 +1,24 @@
+package com.producthunt.server.service.controller;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 健康检查
+ * 
+ * @author ChenYL
+ * @version V1.0
+ * @className HealthController
+ * @description
+ * @date 2023/10/04 16:21
+ **/
+@RestController
+@RequestMapping("/health")
+public class HealthController {
+
+    @GetMapping("/info")
+    public String info() {
+        return "小石ProductHunt后端服务 正在运行";
+    }
+}

+ 2 - 2
product-hunt/src/main/java/com/producthunt/server/service/manager/impl/ProductHuntManagerImpl.java

@@ -4,8 +4,8 @@ import com.producthunt.server.dto.PostNode;
 import com.producthunt.server.dto.PostResponse;
 import com.producthunt.server.core.config.ProductHuntConfig;
 import com.producthunt.server.feign.ProductHuntFeign;
-import com.producthunt.server.feign.dto.producthunt.OauthRequest;
-import com.producthunt.server.feign.dto.producthunt.OauthResponse;
+import com.producthunt.server.feign.dto.OauthRequest;
+import com.producthunt.server.feign.dto.OauthResponse;
 import com.producthunt.server.service.manager.IProductHuntManager;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;

+ 6 - 16
product-hunt/src/main/resources/application-dev.yaml

@@ -1,21 +1,11 @@
-spring:
-  datasource:
-    username: root
-    url: jdbc:mysql://localhost:3306/data_easy?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
-  ai:
-    openai:
-      base-url: ENC(H4FobFSxLct+ZapdAa5GWKbBC3u32wRgWrVaksCJyHvyTPmpqz2P4gq7QfFPIARI)
-      api-key: ENC(CXar5AEVP7jIiOpZfEzkh/4TEi0CePm+sx3ObEgYcUn4ZvDfFlprjyiU3j22x3n/bVmmC5hQlm4Zs23FnGNCB66SQ0ATB2hJ)
-      chat:
-        options:
-          model: deepseek-ai/DeepSeek-V3
-
 # Product Hunt平台配置
 product-hunt:
   client-id: ENC(ANqnssfEBJfIYM2s2D4ZHw1kwndMGp1zxxz3/c1VrsoiwauH5SQq/dB9NObC1AnnI19/AodFB8/bEja1xf+zXw==)
   client-secret: ENC(RnNMBLx32FzSOlA21bzg6vcYpaVqrmGlMj5rKQtr+/LuVCBAP7fad9YjeqOt0kfrJvrYZ9z8/DR76aDv7PxiUw==)
 
-# 接口盒子平台配置
-hz-api:
-  id: ENC(2myOnTLci1DlpQfDkcqN2fGoM24y/fairiO5hH7braM=)
-  key: ENC(SK18qyEQdxOACJ2xeNLTGbUZEDi+wRkvDBs4lL/+wCc1ANFwD42P2Q7Ssl3U3uu9fVRQ3BdgV2o=)
+# 系统配置
+biz:
+  # 加密密钥
+  secret: ENC(2wscdOD7kzByW3VNDQkOZq2BdoM6PS7peINZRwJjEwVubsFN437X3g==)
+  # 系统自访问密钥
+  api-key: ENC(S3TSPw9QuJwvZScgrOv1ORm089BkXy6EJJNeFYwRVxqZnBb176rSXA==)

+ 6 - 17
product-hunt/src/main/resources/application-prod.yaml

@@ -1,22 +1,11 @@
-spring:
-  datasource:
-    username: ENC(NSemTCqIcv//3e9jGN32BW/7W5T/U41S)
-    password: ENC(JCvpZk2f9TBxI/JWILBrgj8CRGh9F6Bbx7TX42VBOsCuAwQw0kyppA==)
-    url: ENC(qquG8FQIQ1L/5VzI18bKQcpkwpNyeYQYUv0pWtdK9JjaNpIyJqcOee48ZqRFg7Kd0Hm2/tZBA6mp21zVX7lqLCL1QWWhZ1+7rldsEO1ujD3ZaAsNugFvAyyyeqAfnGwm9CWk+XwN0MfRLjF/SvD/+W9D9Y/A1EjfpB2zLWGS+W3zI1//3Lj9iZNTCGFw1XTcZg89D700vubl9VWqzmIXpOj+sJKXQ8DS)
-  ai:
-    openai:
-      base-url: ENC(aYgDpynp/i5RsEqxPYMei+leHCdZhhT+mr63Mr9ebQBwNZZMpYYsM2D3lNgrMFf/)
-      api-key: ENC(DxYwiHLqdAh0/PQGtSAIVhVVyGWSQcUjAwmm+0/PpgIUaF3Y4K1k7RBZTtop2kK+1MYEeLVYGEdnGo/YtJP3zu/mlQY5lwqi)
-      chat:
-        options:
-          model: deepseek-ai/DeepSeek-V3
-
 # Product Hunt平台配置
 product-hunt:
   client-id: ENC(uiT7ZiWWHooEYfs42QqDWMxwMgE18uEaE7PMVB2/AYURrn//Jd54BO6Q1a/J6mGFdrQwiO02X0YZeobglUXW2A==)
   client-secret: ENC(3DYuspmnbTjlJJ0H+kzpvtoiEzKZXNQD5tKDDkI8K85funxQKMj5fTaLOjsepB40BO4HzTD5SBDDy9WTfUbVSA==)
 
-# 接口盒子平台配置
-hz-api:
-  id: ENC(xOmDcVBaAxOJHC1bazlmG8m3E082uCTZ4o8jxT7Fi8Q=)
-  key: ENC(I2SZcgbv6EEyEndn4FSMihTlTxVZ3zhxaQAIeJAOdeos3ZH4Nb8QalW1L1phlIK8C/FdPmnsEw8=)
+# 系统配置
+biz:
+  # 加密密钥
+  secret: ENC(V0XvB+A9qK6Xmd1q7M9Bjls8aW4QH3m91GMcr+zpiAIhXFiLALCn+w==)
+  # 系统自访问密钥
+  api-key: ENC(z2rDV5xcbhkO3JuGB83J+0GmLREenc7ucsn0s5POe2NtMtblIgdOfQ==)

+ 11 - 2
product-hunt/src/main/resources/application.yaml

@@ -5,11 +5,20 @@ spring:
     active: prod
   application:
     name: product-hunt-server
-  datasource:
-    driver-class-name: com.mysql.cj.jdbc.Driver
 
 jasypt:
   encryptor:
     algorithm: PBEWithMD5AndDES
     salt-generator-classname: org.jasypt.salt.RandomSaltGenerator
     iv-generator-classname: org.jasypt.iv.RandomIvGenerator
+
+# Product Hunt平台配置
+product-hunt:
+  base-url: https://api.producthunt.com
+  # GraphQL 接口地址
+  graphql-url: https://api.producthunt.com/v2/api/graphql
+
+# 系统配置
+biz:
+  # 加密算法
+  algorithm: PBEWithMD5AndDES