This commit is contained in:
2025-12-29 23:26:06 +08:00
parent 76d498b9a3
commit e323aa38ac
10 changed files with 150 additions and 35 deletions

41
pom.xml
View File

@@ -21,6 +21,17 @@
<maven.compiler.source>22</maven.compiler.source>
<maven.compiler.target>22</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2023.0.5</version> <!-- 或最新的 2023.0.x -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -66,6 +77,13 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<!-- 排除 org.skyscreamer 以规避 Feign 自动装配 fake jackson 的问题 -->
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -90,6 +108,11 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
<dependency>
<groupId>org.redisson</groupId>
@@ -103,11 +126,6 @@
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.26.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
@@ -302,6 +320,19 @@
<artifactId>jsoup</artifactId>
<version>1.20.1</version>
</dependency>
<!-- 排除 org.skyscreamer 以规避 Feign 自动装配 fake jackson 的问题 -->
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>

View File

@@ -3,11 +3,13 @@ package quant.rich.emoney;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableAsync
@EnableScheduling
@EnableFeignClients
@SpringBootApplication
@EnableCaching(proxyTargetClass=true)
public class EmoneyAutoApplication {

View File

@@ -23,6 +23,7 @@ import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@@ -50,7 +51,8 @@ public class EmoneyAutoPlatformExceptionHandler {
@ExceptionHandler({
BindException.class,
ConstraintViolationException.class,
MethodArgumentNotValidException.class })
MethodArgumentNotValidException.class,
MissingServletRequestParameterException.class})
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public <Ex extends BindException> R<?> handleBindException(Ex ex) {

View File

@@ -8,7 +8,6 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import quant.rich.emoney.interceptor.BaseInterceptor;
import quant.rich.emoney.interceptor.EnumOptionsInterceptor;
import quant.rich.emoney.service.ConfigService;
@@ -22,9 +21,6 @@ import quant.rich.emoney.service.ConfigService;
@Configuration
@Import(ConfigAutoRegistrar.class)
public class EmoneyAutoConfig implements WebMvcConfigurer {
@Autowired
BaseInterceptor baseInterceptor;
@Autowired
EnumOptionsInterceptor enumOptionsInterceptor;
@@ -39,7 +35,6 @@ public class EmoneyAutoConfig implements WebMvcConfigurer {
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(baseInterceptor).addPathPatterns("/**");
registry.addInterceptor(enumOptionsInterceptor).addPathPatterns("/**");
}
}

View File

@@ -1,22 +0,0 @@
package quant.rich.emoney.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
/**
* 后台系统身份验证拦截器 Modify by Doghole 2025/3/11
*/
@Component
@Slf4j
public class BaseInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
return true;
}
}

View File

@@ -3,8 +3,6 @@ package quant.rich.emoney.interceptor;
import org.reflections.Reflections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AliasFor;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

View File

@@ -0,0 +1,28 @@
package quant.rich.emoney.tushare;
import java.time.LocalDateTime;
public interface ITsStockInfo {
/**
* 获取 Tushare 代码
* @return
*/
String getTsCode();
/**
* 获取名称
* @return
*/
String getName();
/**
* 获取上市(成立)日期
* @return
*/
LocalDateTime getListDate();
/**
* 获取退市(终止)日期
* @return
*/
default LocalDateTime getDelistDate() {
return null;
}
}

View File

@@ -0,0 +1,26 @@
package quant.rich.emoney.tushare;
import java.time.LocalDateTime;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain=true)
public class StockInfo implements ITsStockInfo {
private String tsCode;
private String name;
private LocalDateTime listDate;
private LocalDateTime delistDate;
public Integer getGoodsId() {
if (tsCode.endsWith("SH")) {
return Integer.valueOf(tsCode.substring(0, 6));
}
if (tsCode.endsWith("SZ") || tsCode.endsWith("BJ")) {
return Integer.valueOf("1" + tsCode.substring(0, 6));
}
throw new RuntimeException("无法将指定的 tsCode " + tsCode + " 转换成 goodsId");
}
}

View File

@@ -0,0 +1,22 @@
package quant.rich.emoney.tushare;
import java.util.List;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 对接 TushareDataService 的 Feign 客户端
*/
@FeignClient(name="tushare-data-service-client", url="http://localhost:9999")
public interface TushareDataServiceClient {
@GetMapping("/api/v1/common/stockInfo/list")
public List<StockInfo> list(
@RequestParam(name="listStatus", required=false) String listStatus,
@RequestParam(name="stockMarket", required=false) String[] stockMarket,
@RequestParam(name="ths", required=false, defaultValue="false") Boolean ths
);
}

View File

@@ -0,0 +1,33 @@
package quant.rich.emoney;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import lombok.extern.slf4j.Slf4j;
import quant.rich.emoney.tushare.StockInfo;
import quant.rich.emoney.tushare.TushareDataServiceClient;
@SpringBootTest
@ContextConfiguration(classes = EmoneyAutoApplication.class)
@RunWith(SpringJUnit4ClassRunner.class)
@Slf4j
public class TushareDataServiceClientTest {
@Autowired
TushareDataServiceClient tushareDataServiceClient;
@Test
void test() {
List<StockInfo> stockInfos = tushareDataServiceClient.list("LIST", new String[] {"SZ", "SH"}, null);
for(StockInfo stockInfo : stockInfos) {
log.info("{} {}", stockInfo.getGoodsId(), stockInfo);
}
}
}