Merge branch 'develop' into 'main'
Develop See merge request india/india_market_java!1
This commit is contained in:
@@ -25,10 +25,10 @@ build:
|
|||||||
</settings>' > $HOME/.m2/settings.xml
|
</settings>' > $HOME/.m2/settings.xml
|
||||||
|
|
||||||
artifacts:
|
artifacts:
|
||||||
name: stock-market.war
|
name: india_market_java.jar
|
||||||
expire_in: 1 day
|
expire_in: 1 day
|
||||||
paths:
|
paths:
|
||||||
- ./target/stock-market.war
|
- ./target/india_market_java.jar
|
||||||
script:
|
script:
|
||||||
- echo ">>>>>>Start Building<<<<<<"
|
- echo ">>>>>>Start Building<<<<<<"
|
||||||
- pwd
|
- pwd
|
||||||
@@ -36,22 +36,17 @@ build:
|
|||||||
- mvn -v
|
- mvn -v
|
||||||
- mvn clean install -Dmaven.test.skip=true
|
- mvn clean install -Dmaven.test.skip=true
|
||||||
- ls
|
- ls
|
||||||
#- apt-get install -y curl
|
|
||||||
#- curl --max-time 20 http://43.128.20.12:11113/api/webhook/justpull?project=api\&setenv_file=alpha.sh\&publish_env=alpha
|
|
||||||
- echo ">>>>>>Finish Building<<<<<<"
|
- echo ">>>>>>Finish Building<<<<<<"
|
||||||
webhook:
|
webhook:
|
||||||
stage: webhook
|
stage: webhook
|
||||||
#tags:
|
|
||||||
# - gz
|
|
||||||
only:
|
only:
|
||||||
- main
|
|
||||||
- develop
|
- develop
|
||||||
script:
|
script:
|
||||||
- echo ">>>>>>Start Deploy<<<<<<"
|
- echo ">>>>>>Start Deploy<<<<<<"
|
||||||
- ls
|
- ls
|
||||||
- apt-get update
|
- apt-get update
|
||||||
- apt-get install -y curl
|
- apt-get install -y curl
|
||||||
- curl --max-time 30 http://43.139.146.165:11113/api/webhook/justpull?project=market\&setenv_file=alpha.sh\&publish_env=alpha\&shell=deploy-alpha.sh
|
- curl --max-time 30 http://124.156.133.209:11113/api/webhook/justpull?project=india_market_java\&setenv_file=alpha.sh\&publish_env=alpha\&shell=india/deploy-test.sh
|
||||||
- echo ">>>>>>Start Deploy Finish<<<<<<"
|
- echo ">>>>>>Start Deploy Finish<<<<<<"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
87
pom.xml
87
pom.xml
@@ -2,7 +2,7 @@
|
|||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>war</packaging>
|
<packaging>jar</packaging>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>cn.qutaojing</groupId>
|
<groupId>cn.qutaojing</groupId>
|
||||||
<artifactId>qutaojing-micro-pom</artifactId>
|
<artifactId>qutaojing-micro-pom</artifactId>
|
||||||
@@ -20,6 +20,11 @@
|
|||||||
<name>股票行情</name>
|
<name>股票行情</name>
|
||||||
<description>股票行情</description>
|
<description>股票行情</description>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.squareup</groupId>
|
||||||
|
<artifactId>javapoet</artifactId>
|
||||||
|
<version>1.11.1</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||||
@@ -176,19 +181,60 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<finalName>stock-market</finalName>
|
<finalName>india_market_java</finalName>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<!--<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
<version>3.3.1</version>
|
<version>3.3.1</version>
|
||||||
</plugin>
|
</plugin>-->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<version>2.3.9.RELEASE</version>
|
||||||
|
<configuration>
|
||||||
|
<executable>true</executable>
|
||||||
|
<layout>JAR</layout>
|
||||||
|
<!-- <includes> <include> 排除所有Jar <groupId>nothing</groupId> <artifactId>nothing</artifactId>
|
||||||
|
</include> </includes> -->
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<attach>false</attach>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.mysema.maven</groupId>
|
||||||
|
<artifactId>apt-maven-plugin</artifactId>
|
||||||
|
<version>1.1.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>process</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>src/main/generated</outputDirectory>
|
||||||
|
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.mysema.maven</groupId>
|
<groupId>com.mysema.maven</groupId>
|
||||||
<artifactId>apt-maven-plugin</artifactId>
|
<artifactId>apt-maven-plugin</artifactId>
|
||||||
@@ -219,38 +265,5 @@
|
|||||||
<enabled>true</enabled>
|
<enabled>true</enabled>
|
||||||
</snapshots>
|
</snapshots>
|
||||||
</repository>
|
</repository>
|
||||||
<!--<repository>
|
|
||||||
<id>alimaven</id>
|
|
||||||
<name>aliyun maven</name>
|
|
||||||
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
|
|
||||||
<releases>
|
|
||||||
<enabled>true</enabled>
|
|
||||||
</releases>
|
|
||||||
<snapshots>
|
|
||||||
<enabled>false</enabled>
|
|
||||||
</snapshots>
|
|
||||||
</repository>
|
|
||||||
|
|
||||||
<repository>
|
|
||||||
<id>public</id>
|
|
||||||
<url>http://nexus.rplees.com/nexus/content/repositories/public/</url>
|
|
||||||
<releases>
|
|
||||||
<enabled>true</enabled>
|
|
||||||
</releases>
|
|
||||||
<snapshots>
|
|
||||||
<enabled>true</enabled>
|
|
||||||
<updatePolicy>always</updatePolicy>
|
|
||||||
<checksumPolicy>warn</checksumPolicy>
|
|
||||||
</snapshots>
|
|
||||||
</repository>
|
|
||||||
|
|
||||||
<repository>
|
|
||||||
<id>spring-milestones</id>
|
|
||||||
<name>Spring Milestones</name>
|
|
||||||
<url>https://repo.spring.io/libs-milestone</url>
|
|
||||||
<snapshots>
|
|
||||||
<enabled>false</enabled>
|
|
||||||
</snapshots>
|
|
||||||
</repository>-->
|
|
||||||
</repositories>
|
</repositories>
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package cn.stock.market.infrastructure.db.po;
|
||||||
|
|
||||||
|
import static com.querydsl.core.types.PathMetadataFactory.*;
|
||||||
|
|
||||||
|
import com.querydsl.core.types.dsl.*;
|
||||||
|
|
||||||
|
import com.querydsl.core.types.PathMetadata;
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
import com.querydsl.core.types.Path;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QBtodayStockPO is a Querydsl query type for BtodayStockPO
|
||||||
|
*/
|
||||||
|
@Generated("com.querydsl.codegen.EntitySerializer")
|
||||||
|
public class QBtodayStockPO extends EntityPathBase<BtodayStockPO> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1079736803L;
|
||||||
|
|
||||||
|
public static final QBtodayStockPO btodayStockPO = new QBtodayStockPO("btodayStockPO");
|
||||||
|
|
||||||
|
public final StringPath coCode = createString("coCode");
|
||||||
|
|
||||||
|
public final NumberPath<Integer> id = createNumber("id", Integer.class);
|
||||||
|
|
||||||
|
public final DateTimePath<java.util.Date> lastUpdateTime = createDateTime("lastUpdateTime", java.util.Date.class);
|
||||||
|
|
||||||
|
public final StringPath selfUrl = createString("selfUrl");
|
||||||
|
|
||||||
|
public final StringPath stockCode = createString("stockCode");
|
||||||
|
|
||||||
|
public final StringPath stockName = createString("stockName");
|
||||||
|
|
||||||
|
public final StringPath stockSpell = createString("stockSpell");
|
||||||
|
|
||||||
|
public final StringPath stockType = createString("stockType");
|
||||||
|
|
||||||
|
public final StringPath url = createString("url");
|
||||||
|
|
||||||
|
public QBtodayStockPO(String variable) {
|
||||||
|
super(BtodayStockPO.class, forVariable(variable));
|
||||||
|
}
|
||||||
|
|
||||||
|
public QBtodayStockPO(Path<? extends BtodayStockPO> path) {
|
||||||
|
super(path.getType(), path.getMetadata());
|
||||||
|
}
|
||||||
|
|
||||||
|
public QBtodayStockPO(PathMetadata metadata) {
|
||||||
|
super(BtodayStockPO.class, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package cn.stock.market.infrastructure.stockdb.po;
|
package cn.stock.market.infrastructure.db.po;
|
||||||
|
|
||||||
import static com.querydsl.core.types.PathMetadataFactory.*;
|
import static com.querydsl.core.types.PathMetadataFactory.*;
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ import com.querydsl.core.types.Path;
|
|||||||
@Generated("com.querydsl.codegen.EntitySerializer")
|
@Generated("com.querydsl.codegen.EntitySerializer")
|
||||||
public class QSiteSettingPO extends EntityPathBase<SiteSettingPO> {
|
public class QSiteSettingPO extends EntityPathBase<SiteSettingPO> {
|
||||||
|
|
||||||
private static final long serialVersionUID = -51441337L;
|
private static final long serialVersionUID = 926298165L;
|
||||||
|
|
||||||
public static final QSiteSettingPO siteSettingPO = new QSiteSettingPO("siteSettingPO");
|
public static final QSiteSettingPO siteSettingPO = new QSiteSettingPO("siteSettingPO");
|
||||||
|
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package cn.stock.market.infrastructure.db.po;
|
||||||
|
|
||||||
|
import static com.querydsl.core.types.PathMetadataFactory.*;
|
||||||
|
|
||||||
|
import com.querydsl.core.types.dsl.*;
|
||||||
|
|
||||||
|
import com.querydsl.core.types.PathMetadata;
|
||||||
|
import javax.annotation.Generated;
|
||||||
|
import com.querydsl.core.types.Path;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QStockIpoPO is a Querydsl query type for StockIpoPO
|
||||||
|
*/
|
||||||
|
@Generated("com.querydsl.codegen.EntitySerializer")
|
||||||
|
public class QStockIpoPO extends EntityPathBase<StockIpoPO> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1023664740L;
|
||||||
|
|
||||||
|
public static final QStockIpoPO stockIpoPO = new QStockIpoPO("stockIpoPO");
|
||||||
|
|
||||||
|
public final StringPath apply = createString("apply");
|
||||||
|
|
||||||
|
public final DateTimePath<java.util.Date> createDate = createDateTime("createDate", java.util.Date.class);
|
||||||
|
|
||||||
|
public final NumberPath<Integer> id = createNumber("id", Integer.class);
|
||||||
|
|
||||||
|
public final NumberPath<Integer> isList = createNumber("isList", Integer.class);
|
||||||
|
|
||||||
|
public final NumberPath<Integer> isShow = createNumber("isShow", Integer.class);
|
||||||
|
|
||||||
|
public final DateTimePath<java.util.Date> listingDate = createDateTime("listingDate", java.util.Date.class);
|
||||||
|
|
||||||
|
public final NumberPath<java.math.BigDecimal> peRatio = createNumber("peRatio", java.math.BigDecimal.class);
|
||||||
|
|
||||||
|
public final StringPath sourceType = createString("sourceType");
|
||||||
|
|
||||||
|
public final StringPath stockCode = createString("stockCode");
|
||||||
|
|
||||||
|
public final StringPath stockName = createString("stockName");
|
||||||
|
|
||||||
|
public final NumberPath<java.math.BigDecimal> stockPrice = createNumber("stockPrice", java.math.BigDecimal.class);
|
||||||
|
|
||||||
|
public final DateTimePath<java.util.Date> subscriptionDate = createDateTime("subscriptionDate", java.util.Date.class);
|
||||||
|
|
||||||
|
public final NumberPath<Integer> totalNumber = createNumber("totalNumber", Integer.class);
|
||||||
|
|
||||||
|
public final DateTimePath<java.util.Date> updateDate = createDateTime("updateDate", java.util.Date.class);
|
||||||
|
|
||||||
|
public QStockIpoPO(String variable) {
|
||||||
|
super(StockIpoPO.class, forVariable(variable));
|
||||||
|
}
|
||||||
|
|
||||||
|
public QStockIpoPO(Path<? extends StockIpoPO> path) {
|
||||||
|
super(path.getType(), path.getMetadata());
|
||||||
|
}
|
||||||
|
|
||||||
|
public QStockIpoPO(PathMetadata metadata) {
|
||||||
|
super(StockIpoPO.class, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package cn.stock.market.infrastructure.stockdb.po;
|
package cn.stock.market.infrastructure.db.po;
|
||||||
|
|
||||||
import static com.querydsl.core.types.PathMetadataFactory.*;
|
import static com.querydsl.core.types.PathMetadataFactory.*;
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ import com.querydsl.core.types.Path;
|
|||||||
@Generated("com.querydsl.codegen.EntitySerializer")
|
@Generated("com.querydsl.codegen.EntitySerializer")
|
||||||
public class QStockPO extends EntityPathBase<StockPO> {
|
public class QStockPO extends EntityPathBase<StockPO> {
|
||||||
|
|
||||||
private static final long serialVersionUID = -1246401708L;
|
private static final long serialVersionUID = 2143409346L;
|
||||||
|
|
||||||
public static final QStockPO stockPO = new QStockPO("stockPO");
|
public static final QStockPO stockPO = new QStockPO("stockPO");
|
||||||
|
|
||||||
@@ -33,6 +33,8 @@ public class QStockPO extends EntityPathBase<StockPO> {
|
|||||||
|
|
||||||
public final StringPath stockCode = createString("stockCode");
|
public final StringPath stockCode = createString("stockCode");
|
||||||
|
|
||||||
|
public final StringPath stockExchangeId = createString("stockExchangeId");
|
||||||
|
|
||||||
public final StringPath stockGid = createString("stockGid");
|
public final StringPath stockGid = createString("stockGid");
|
||||||
|
|
||||||
public final StringPath stockName = createString("stockName");
|
public final StringPath stockName = createString("stockName");
|
||||||
@@ -43,6 +45,8 @@ public class QStockPO extends EntityPathBase<StockPO> {
|
|||||||
|
|
||||||
public final NumberPath<Integer> stockState = createNumber("stockState", Integer.class);
|
public final NumberPath<Integer> stockState = createNumber("stockState", Integer.class);
|
||||||
|
|
||||||
|
public final StringPath stockSymbol = createString("stockSymbol");
|
||||||
|
|
||||||
public final StringPath stockType = createString("stockType");
|
public final StringPath stockType = createString("stockType");
|
||||||
|
|
||||||
public QStockPO(String variable) {
|
public QStockPO(String variable) {
|
||||||
@@ -47,7 +47,7 @@ public class CommonApis {
|
|||||||
public Map<String, StockVO> stockDetailMap(List<StockCode> code) {
|
public Map<String, StockVO> stockDetailMap(List<StockCode> code) {
|
||||||
Function<StockSource, List<StockCode>> func = (source) -> {
|
Function<StockSource, List<StockCode>> func = (source) -> {
|
||||||
return code.stream()
|
return code.stream()
|
||||||
.filter(val -> val != null && source == val.getSource())
|
// .filter(val -> val != null && source == val.getSource())
|
||||||
.collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(StockCode::getCode))), ArrayList::new));
|
.collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(StockCode::getCode))), ArrayList::new));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package cn.stock.market.application.assembler;
|
||||||
|
|
||||||
|
import cn.qutaojing.common.utils.Beans;
|
||||||
|
import cn.qutaojing.common.utils.SpringUtils;
|
||||||
|
import cn.stock.market.domain.basic.entity.BtodayStock;
|
||||||
|
import cn.stock.market.dto.BtodayStockDTO;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BtodayStockAssembler
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/25
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Lazy
|
||||||
|
public class BtodayStockAssembler {
|
||||||
|
public BtodayStockDTO toDTO(BtodayStock e) {
|
||||||
|
BtodayStockDTO dto = Beans.mapper(e, BtodayStockDTO.class);
|
||||||
|
if(dto == null) return dto;
|
||||||
|
fill(e, dto);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fill(BtodayStock e, BtodayStockDTO dto) {
|
||||||
|
if(dto == null) return;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BtodayStockAssembler of() {
|
||||||
|
return SpringUtils.getBean(BtodayStockAssembler.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package cn.stock.market.application.assembler;
|
||||||
|
|
||||||
|
import cn.qutaojing.common.utils.Beans;
|
||||||
|
import cn.qutaojing.common.utils.SpringUtils;
|
||||||
|
import cn.stock.market.domain.basic.entity.StockIpo;
|
||||||
|
import cn.stock.market.dto.StockIpoDTO;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StockIpoAssembler
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/28
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Lazy
|
||||||
|
public class StockIpoAssembler {
|
||||||
|
public StockIpoDTO toDTO(StockIpo e) {
|
||||||
|
StockIpoDTO dto = Beans.mapper(e, StockIpoDTO.class);
|
||||||
|
if(dto == null) return dto;
|
||||||
|
fill(e, dto);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fill(StockIpo e, StockIpoDTO dto) {
|
||||||
|
if(dto == null) return;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StockIpoAssembler of() {
|
||||||
|
return SpringUtils.getBean(StockIpoAssembler.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/main/java/cn/stock/market/constant/StockData.java
Normal file
16
src/main/java/cn/stock/market/constant/StockData.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package cn.stock.market.constant;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public class StockData {
|
||||||
|
private String upd_date;
|
||||||
|
private BigDecimal price;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package cn.stock.market.domain.basic.convert;
|
||||||
|
|
||||||
|
import cn.qutaojing.common.domain.convert.SimpleEntityPOConvert;
|
||||||
|
import cn.qutaojing.common.utils.SpringUtils;
|
||||||
|
import cn.stock.market.domain.basic.entity.BtodayStock;
|
||||||
|
import cn.stock.market.infrastructure.db.po.BtodayStockPO;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BtodayStockConvert
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/25
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Lazy
|
||||||
|
public class BtodayStockConvert extends SimpleEntityPOConvert<BtodayStock, BtodayStockPO> {
|
||||||
|
public static BtodayStockConvert of() {
|
||||||
|
return SpringUtils.getBean(BtodayStockConvert.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import org.springframework.stereotype.Component;
|
|||||||
import cn.qutaojing.common.domain.convert.SimpleEntityPOConvert;
|
import cn.qutaojing.common.domain.convert.SimpleEntityPOConvert;
|
||||||
import cn.qutaojing.common.utils.SpringUtils;
|
import cn.qutaojing.common.utils.SpringUtils;
|
||||||
import cn.stock.market.domain.basic.entity.SiteSetting;
|
import cn.stock.market.domain.basic.entity.SiteSetting;
|
||||||
import cn.stock.market.infrastructure.stockdb.po.SiteSettingPO;
|
import cn.stock.market.infrastructure.db.po.SiteSettingPO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StockConvert
|
* StockConvert
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package cn.stock.market.domain.basic.convert;
|
|||||||
import cn.qutaojing.common.domain.convert.SimpleEntityPOConvert;
|
import cn.qutaojing.common.domain.convert.SimpleEntityPOConvert;
|
||||||
import cn.qutaojing.common.utils.SpringUtils;
|
import cn.qutaojing.common.utils.SpringUtils;
|
||||||
import cn.stock.market.domain.basic.entity.Stock;
|
import cn.stock.market.domain.basic.entity.Stock;
|
||||||
import cn.stock.market.infrastructure.stockdb.po.StockPO;
|
import cn.stock.market.infrastructure.db.po.StockPO;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package cn.stock.market.domain.basic.convert;
|
||||||
|
|
||||||
|
import cn.qutaojing.common.domain.convert.SimpleEntityPOConvert;
|
||||||
|
import cn.qutaojing.common.utils.SpringUtils;
|
||||||
|
import cn.stock.market.domain.basic.entity.StockIpo;
|
||||||
|
import cn.stock.market.infrastructure.db.po.StockIpoPO;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StockIpoConvert
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/28
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Lazy
|
||||||
|
public class StockIpoConvert extends SimpleEntityPOConvert<StockIpo, StockIpoPO> {
|
||||||
|
public static StockIpoConvert of() {
|
||||||
|
return SpringUtils.getBean(StockIpoConvert.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package cn.stock.market.domain.basic.entity;
|
||||||
|
|
||||||
|
import cn.qutaojing.common.utils.Beans;
|
||||||
|
import cn.stock.market.dto.command.BtodayStockCreateCommand;
|
||||||
|
import cn.stock.market.infrastructure.db.po.BtodayStockPO;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BtodayStock
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/25
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@SuperBuilder
|
||||||
|
@EqualsAndHashCode(
|
||||||
|
callSuper = false
|
||||||
|
)
|
||||||
|
public class BtodayStock extends BtodayStockPO {
|
||||||
|
public void update(BtodayStockCreateCommand cmd) {
|
||||||
|
Beans.copyProperties(cmd, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ import com.google.common.collect.Lists;
|
|||||||
|
|
||||||
import cn.qutaojing.common.utils.Beans;
|
import cn.qutaojing.common.utils.Beans;
|
||||||
import cn.stock.market.dto.command.StockCreateCommand;
|
import cn.stock.market.dto.command.StockCreateCommand;
|
||||||
import cn.stock.market.infrastructure.stockdb.po.SiteSettingPO;
|
import cn.stock.market.infrastructure.db.po.SiteSettingPO;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package cn.stock.market.domain.basic.entity;
|
|||||||
|
|
||||||
import cn.qutaojing.common.utils.Beans;
|
import cn.qutaojing.common.utils.Beans;
|
||||||
import cn.stock.market.dto.command.StockCreateCommand;
|
import cn.stock.market.dto.command.StockCreateCommand;
|
||||||
import cn.stock.market.infrastructure.stockdb.po.StockPO;
|
import cn.stock.market.infrastructure.db.po.StockPO;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package cn.stock.market.domain.basic.entity;
|
||||||
|
|
||||||
|
import cn.qutaojing.common.utils.Beans;
|
||||||
|
import cn.stock.market.dto.command.StockIpoCreateCommand;
|
||||||
|
import cn.stock.market.infrastructure.db.po.StockIpoPO;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StockIpo
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/28
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@SuperBuilder
|
||||||
|
@EqualsAndHashCode(
|
||||||
|
callSuper = false
|
||||||
|
)
|
||||||
|
public class StockIpo extends StockIpoPO {
|
||||||
|
public void update(StockIpoCreateCommand cmd) {
|
||||||
|
Beans.copyProperties(cmd, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package cn.stock.market.domain.basic.factory;
|
||||||
|
|
||||||
|
import cn.qutaojing.common.utils.SpringUtils;
|
||||||
|
import cn.stock.market.domain.basic.entity.BtodayStock;
|
||||||
|
import cn.stock.market.dto.command.BtodayStockCreateCommand;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BtodayStockFactory
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/25
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Lazy
|
||||||
|
public class BtodayStockFactory {
|
||||||
|
public static BtodayStockFactory of() {
|
||||||
|
return SpringUtils.getBean(BtodayStockFactory.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BtodayStock from(BtodayStockCreateCommand cmd) {
|
||||||
|
BtodayStock e = BtodayStock.builder().build();
|
||||||
|
e.update(cmd);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package cn.stock.market.domain.basic.factory;
|
||||||
|
|
||||||
|
import cn.qutaojing.common.utils.SpringUtils;
|
||||||
|
import cn.stock.market.domain.basic.entity.StockIpo;
|
||||||
|
import cn.stock.market.dto.command.StockIpoCreateCommand;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StockIpoFactory
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/28
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Lazy
|
||||||
|
public class StockIpoFactory {
|
||||||
|
public static StockIpoFactory of() {
|
||||||
|
return SpringUtils.getBean(StockIpoFactory.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StockIpo from(StockIpoCreateCommand cmd) {
|
||||||
|
StockIpo e = StockIpo.builder().build();
|
||||||
|
e.update(cmd);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package cn.stock.market.domain.basic.repository;
|
||||||
|
|
||||||
|
import cn.qutaojing.common.domain.convert.IEntityPOConvert;
|
||||||
|
import cn.qutaojing.common.domain.respostory.SimplePoConvertEntityRepository;
|
||||||
|
import cn.qutaojing.common.utils.SpringUtils;
|
||||||
|
import cn.stock.market.domain.basic.convert.BtodayStockConvert;
|
||||||
|
import cn.stock.market.domain.basic.entity.BtodayStock;
|
||||||
|
import cn.stock.market.domain.basic.entity.Stock;
|
||||||
|
import cn.stock.market.infrastructure.db.po.BtodayStockPO;
|
||||||
|
import cn.stock.market.infrastructure.db.po.QBtodayStockPO;
|
||||||
|
import cn.stock.market.infrastructure.db.repo.BtodayStockRepo;
|
||||||
|
import com.rp.spring.jpa.GenericJpaRepository;
|
||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.Override;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BtodayStockRepository
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/25
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
@RequiredArgsConstructor(
|
||||||
|
onConstructor = @__(@Autowired)
|
||||||
|
)
|
||||||
|
public class BtodayStockRepository extends SimplePoConvertEntityRepository<BtodayStock, BtodayStockPO, Integer> {
|
||||||
|
final BtodayStockRepo repo;
|
||||||
|
|
||||||
|
final BtodayStockConvert convert;
|
||||||
|
|
||||||
|
final QBtodayStockPO q = QBtodayStockPO.btodayStockPO;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GenericJpaRepository<BtodayStockPO, Integer> repo() {
|
||||||
|
return repo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IEntityPOConvert<BtodayStock, BtodayStockPO> convert() {
|
||||||
|
return convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BtodayStockRepository of() {
|
||||||
|
return SpringUtils.getBean(BtodayStockRepository.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BtodayStock findBtStockByCoCode(String coCode,String stockType) {
|
||||||
|
return findOneIfMutil(q.coCode.eq(coCode),q.stockType.eq(stockType));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,8 +10,8 @@ import cn.qutaojing.common.domain.respostory.LocalCacheRepository;
|
|||||||
import cn.qutaojing.common.utils.SpringUtils;
|
import cn.qutaojing.common.utils.SpringUtils;
|
||||||
import cn.stock.market.domain.basic.convert.SiteSettingConvert;
|
import cn.stock.market.domain.basic.convert.SiteSettingConvert;
|
||||||
import cn.stock.market.domain.basic.entity.SiteSetting;
|
import cn.stock.market.domain.basic.entity.SiteSetting;
|
||||||
import cn.stock.market.infrastructure.stockdb.po.SiteSettingPO;
|
import cn.stock.market.infrastructure.db.po.SiteSettingPO;
|
||||||
import cn.stock.market.infrastructure.stockdb.repo.SiteSettingRepo;
|
import cn.stock.market.infrastructure.db.repo.SiteSettingRepo;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package cn.stock.market.domain.basic.repository;
|
||||||
|
|
||||||
|
import cn.qutaojing.common.domain.convert.IEntityPOConvert;
|
||||||
|
import cn.qutaojing.common.domain.respostory.SimplePoConvertEntityRepository;
|
||||||
|
import cn.qutaojing.common.utils.SpringUtils;
|
||||||
|
import cn.stock.market.domain.basic.convert.StockIpoConvert;
|
||||||
|
import cn.stock.market.domain.basic.entity.StockIpo;
|
||||||
|
import cn.stock.market.infrastructure.db.po.StockIpoPO;
|
||||||
|
import cn.stock.market.infrastructure.db.repo.StockIpoRepo;
|
||||||
|
import com.rp.spring.jpa.GenericJpaRepository;
|
||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.Override;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StockIpoRepository
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/28
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
@RequiredArgsConstructor(
|
||||||
|
onConstructor = @__(@Autowired)
|
||||||
|
)
|
||||||
|
public class StockIpoRepository extends SimplePoConvertEntityRepository<StockIpo, StockIpoPO, Integer> {
|
||||||
|
final StockIpoRepo repo;
|
||||||
|
|
||||||
|
final StockIpoConvert convert;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GenericJpaRepository<StockIpoPO, Integer> repo() {
|
||||||
|
return repo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IEntityPOConvert<StockIpo, StockIpoPO> convert() {
|
||||||
|
return convert;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StockIpoRepository of() {
|
||||||
|
return SpringUtils.getBean(StockIpoRepository.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import cn.stock.market.infrastructure.db.po.QStockPO;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@@ -21,9 +22,8 @@ import cn.qutaojing.common.jpa.ConditionBuilder;
|
|||||||
import cn.qutaojing.common.utils.SpringUtils;
|
import cn.qutaojing.common.utils.SpringUtils;
|
||||||
import cn.stock.market.domain.basic.convert.StockConvert;
|
import cn.stock.market.domain.basic.convert.StockConvert;
|
||||||
import cn.stock.market.domain.basic.entity.Stock;
|
import cn.stock.market.domain.basic.entity.Stock;
|
||||||
import cn.stock.market.infrastructure.stockdb.po.QStockPO;
|
import cn.stock.market.infrastructure.db.po.StockPO;
|
||||||
import cn.stock.market.infrastructure.stockdb.po.StockPO;
|
import cn.stock.market.infrastructure.db.repo.StockRepo;
|
||||||
import cn.stock.market.infrastructure.stockdb.repo.StockRepo;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package cn.stock.market.domain.basic.service;
|
||||||
|
|
||||||
|
import cn.qutaojing.common.utils.SpringUtils;
|
||||||
|
import cn.stock.market.domain.basic.entity.BtodayStock;
|
||||||
|
import cn.stock.market.domain.basic.factory.BtodayStockFactory;
|
||||||
|
import cn.stock.market.domain.basic.repository.BtodayStockRepository;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BtodayStockService
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/25
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor(
|
||||||
|
onConstructor = @__(@Autowired)
|
||||||
|
)
|
||||||
|
public class BtodayStockService {
|
||||||
|
final BtodayStockRepository repository;
|
||||||
|
|
||||||
|
final BtodayStockFactory factory;
|
||||||
|
|
||||||
|
public BtodayStockRepository repository() {
|
||||||
|
return repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BtodayStockService of() {
|
||||||
|
return SpringUtils.getBean(BtodayStockService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BtodayStock findBtStockByCoCode(String coCode,String stockType){
|
||||||
|
return repository.findBtStockByCoCode(coCode,stockType);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package cn.stock.market.domain.basic.service;
|
||||||
|
|
||||||
|
import cn.qutaojing.common.utils.SpringUtils;
|
||||||
|
import cn.stock.market.domain.basic.factory.StockIpoFactory;
|
||||||
|
import cn.stock.market.domain.basic.repository.StockIpoRepository;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StockIpoService
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/28
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor(
|
||||||
|
onConstructor = @__(@Autowired)
|
||||||
|
)
|
||||||
|
public class StockIpoService {
|
||||||
|
final StockIpoRepository repository;
|
||||||
|
|
||||||
|
final StockIpoFactory factory;
|
||||||
|
|
||||||
|
public StockIpoRepository repository() {
|
||||||
|
return repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StockIpoService of() {
|
||||||
|
return SpringUtils.getBean(StockIpoService.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,23 +1,42 @@
|
|||||||
package cn.stock.market.domain.basic.service;
|
package cn.stock.market.domain.basic.service;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Date;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
import javax.persistence.EntityExistsException;
|
import javax.persistence.EntityExistsException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.text.StrFormatter;
|
||||||
import cn.stock.market.dto.model.*;
|
import cn.stock.market.dto.model.*;
|
||||||
|
import cn.stock.market.infrastructure.api.investing.IndiaIndexVo;
|
||||||
|
import cn.stock.market.infrastructure.api.investing.IndiaStockVO;
|
||||||
|
import cn.stock.market.infrastructure.api.investing.InvestingApis;
|
||||||
|
import cn.stock.market.infrastructure.api.investing.InvestingInvokerApis;
|
||||||
import cn.stock.market.infrastructure.api.sina.vo.HotSearchVO;
|
import cn.stock.market.infrastructure.api.sina.vo.HotSearchVO;
|
||||||
|
import cn.stock.market.utils.*;
|
||||||
|
import com.ag.utils.CollectionUtils;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.google.common.base.Stopwatch;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Protocol;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Request.Builder;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import cn.stock.market.infrastructure.db.po.QStockPO;
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
import org.jsoup.nodes.Document;
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
import org.jsoup.select.Elements;
|
import org.jsoup.select.Elements;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@@ -43,7 +62,6 @@ import cn.stock.market.infrastructure.api.sina.vo.MarketVO;
|
|||||||
import cn.stock.market.infrastructure.api.sina.vo.MarketVOResult;
|
import cn.stock.market.infrastructure.api.sina.vo.MarketVOResult;
|
||||||
import cn.stock.market.infrastructure.api.sina.vo.k.MinDataVO;
|
import cn.stock.market.infrastructure.api.sina.vo.k.MinDataVO;
|
||||||
import cn.stock.market.infrastructure.api.sina.vo.k.echarts.EchartsDataVO;
|
import cn.stock.market.infrastructure.api.sina.vo.k.echarts.EchartsDataVO;
|
||||||
import cn.stock.market.infrastructure.stockdb.po.QStockPO;
|
|
||||||
import cn.stock.market.utils.GetPyByChinese;
|
import cn.stock.market.utils.GetPyByChinese;
|
||||||
import cn.stock.market.utils.HttpClientRequest;
|
import cn.stock.market.utils.HttpClientRequest;
|
||||||
import cn.stock.market.utils.PropertiesUtil;
|
import cn.stock.market.utils.PropertiesUtil;
|
||||||
@@ -238,6 +256,38 @@ public class StockService {
|
|||||||
return ServerResponse.createBySuccess(marketVO);
|
return ServerResponse.createBySuccess(marketVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getNews() {
|
||||||
|
String result = "";
|
||||||
|
try {
|
||||||
|
// 使用Jsoup连接到网页
|
||||||
|
Document doc = Jsoup.connect("https://www.business-standard.com/markets/news")
|
||||||
|
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36")
|
||||||
|
.header("Referer", "https://www.business-standard.com/")
|
||||||
|
.header("Accept-Language", "en-US,en;q=0.9")
|
||||||
|
.get();
|
||||||
|
result = doc.html().substring(doc.html().indexOf("<div class=\"short-video-img\">"),doc.html().lastIndexOf("<div class=\"short-video-img\">")+500);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return e.toString();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNewsInfo(String url) {
|
||||||
|
String result = "";
|
||||||
|
try {
|
||||||
|
// 使用Jsoup连接到网页
|
||||||
|
Document doc = Jsoup.connect(url)
|
||||||
|
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36")
|
||||||
|
.header("Referer", "https://www.business-standard.com/")
|
||||||
|
.header("Accept-Language", "en-US,en;q=0.9")
|
||||||
|
.get();
|
||||||
|
result = doc.html().substring(doc.html().indexOf("articleBody") + 15, doc.html().indexOf(",\"author\":") - 1);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return e.toString();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public ServerResponse getStock(int pageNum, int pageSize, String keyWords, String stockPlate, String stockType,
|
public ServerResponse getStock(int pageNum, int pageSize, String keyWords, String stockPlate, String stockType,
|
||||||
HttpServletRequest request) {
|
HttpServletRequest request) {
|
||||||
Page<Stock> page = repository.findStockListByKeyWords(keyWords, stockPlate, stockType, 0, PageParam.of(pageNum, pageSize));
|
Page<Stock> page = repository.findStockListByKeyWords(keyWords, stockPlate, stockType, 0, PageParam.of(pageNum, pageSize));
|
||||||
@@ -711,4 +761,215 @@ public class StockService {
|
|||||||
}
|
}
|
||||||
return ServerResponse.createByErrorMsg("请求失败");
|
return ServerResponse.createByErrorMsg("请求失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String find_overview_table_value_with_key(JSONArray overview_table_value, String key) {
|
||||||
|
for (Object obj : overview_table_value) {
|
||||||
|
JSONObject item = (JSONObject) obj;
|
||||||
|
if(StringUtils.equals(item.getString("key"), key)) {
|
||||||
|
return item.getString("val");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String numberToString(String string) {
|
||||||
|
return StringUtils.replace(string, ",", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addHeader(Builder builder,String headerLines) {
|
||||||
|
String[] headers = StringUtils.split(headerLines, "\n");
|
||||||
|
for (String header : headers) {
|
||||||
|
String[] split2 = StringUtils.split(header, ": ");
|
||||||
|
String key = split2[0];
|
||||||
|
String value = StringUtils.substring(header, key.length() + 2);
|
||||||
|
builder.header(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerResponse syncIndiaData(){
|
||||||
|
log.info("同步股票数据开始。。。。");
|
||||||
|
Map<String, Stock> stockMap = StockRepository.of().cacheCodeMap();
|
||||||
|
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||||
|
List<Stock> list = Lists.newArrayList();
|
||||||
|
int currentTotal = 0;
|
||||||
|
int pageNum =1;
|
||||||
|
int pageSize = 300;
|
||||||
|
try {
|
||||||
|
for(int i = 0;i < pageNum;i ++) {
|
||||||
|
String tmpl = "https://api.investing.com/api/financialdata/assets/equitiesByCountry/default?fields-list=id,name,symbol,high,low,last,lastPairDecimal,change,changePercent,volume,time,isOpen,url,flag,countryNameTranslated,exchangeId,performanceDay,performanceWeek,performanceMonth,performanceYtd,performanceYear,performance3Year,technicalHour,technicalDay,technicalWeek,technicalMonth,avgVolume,fundamentalMarketCap,fundamentalRevenue,fundamentalRatio,fundamentalBeta,pairType&country-id=14&page={}&page-size={}&include-major-indices=false&include-additional-indices=false&include-primary-sectors=false&include-other-indices=false&limit=0";
|
||||||
|
String url = StrFormatter.format(tmpl, pageNum - 1, pageSize);
|
||||||
|
// String str = HttpClientRequest.doGet(url);
|
||||||
|
JSONObject jsonObject = InvestingInvokerApis.of().__page(pageNum, pageSize);
|
||||||
|
// JSONObject jsonObject = JSON.parseObject(str);
|
||||||
|
int total = 0;
|
||||||
|
if(jsonObject.containsKey("total")){
|
||||||
|
total = Integer.parseInt(jsonObject.get("total").toString());
|
||||||
|
}
|
||||||
|
JSONArray dataObjArray = new JSONArray();
|
||||||
|
if(jsonObject.containsKey("data")){
|
||||||
|
dataObjArray = JSON.parseArray(jsonObject.get("data").toString());
|
||||||
|
}
|
||||||
|
for (Object obj : dataObjArray) {
|
||||||
|
JSONObject jsonObject2 = JSON.parseObject(obj.toString());
|
||||||
|
String code = jsonObject2.get("Id").toString();
|
||||||
|
String name = jsonObject2.get("Name").toString();
|
||||||
|
String stockSymbol = jsonObject2.get("Symbol").toString();
|
||||||
|
String exchangeId = jsonObject2.get("ExchangeId").toString();
|
||||||
|
if (stockMap.containsKey(code)) {
|
||||||
|
log.info("已经存在 {} 信息, 跳过", code);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(! Utils.isShOrSzOrBJ(code)) {
|
||||||
|
log.info("{} 非 sh 或者 sz 或者 bj , 跳过", code);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Stock stock = new Stock();
|
||||||
|
stock.setStockSymbol(stockSymbol);
|
||||||
|
stock.setStockExchangeId(exchangeId);
|
||||||
|
stock.setStockName(name);
|
||||||
|
stock.setStockCode(code);
|
||||||
|
stock.setIsLock(0);
|
||||||
|
stock.setIsShow(0);
|
||||||
|
stock.setAddTime(new Date());
|
||||||
|
stock.setStockState(0);
|
||||||
|
list.add(stock);
|
||||||
|
}
|
||||||
|
currentTotal += pageSize;
|
||||||
|
if((total - currentTotal) < pageSize ){
|
||||||
|
pageSize = total - currentTotal;
|
||||||
|
}
|
||||||
|
if(total <= currentTotal){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pageNum ++;
|
||||||
|
}
|
||||||
|
if(CollectionUtils.isNotEmpty(list)) {
|
||||||
|
StockRepository.of().saveAll(list);
|
||||||
|
}
|
||||||
|
int count = list.size();
|
||||||
|
log.info("syncAFutureStockList执行, 受影响数{}, 耗时:{}毫秒", count, stopwatch.elapsed(TimeUnit.MILLISECONDS));
|
||||||
|
log.info("同步股票数据结束。。。。");
|
||||||
|
return ServerResponse.createBySuccess();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("同步股票数据异常,异常信息{}。。。。",e.getMessage());
|
||||||
|
return ServerResponse.createByErrorMsg(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void syncIndiaData2(){
|
||||||
|
log.info("同步股票数据开始。。。。");
|
||||||
|
Map<String, Stock> stockMap = StockRepository.of().cacheCodeMap();
|
||||||
|
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||||
|
List<Stock> list = Lists.newArrayList();
|
||||||
|
int currentTotal = 0;
|
||||||
|
int pageNum =1;
|
||||||
|
int pageSize = 300;
|
||||||
|
try {
|
||||||
|
|
||||||
|
String str = Utils.readTxt();
|
||||||
|
JSONObject jsonObject = JSON.parseObject(str);
|
||||||
|
JSONArray dataObjArray = JSON.parseArray(jsonObject.get("data").toString());
|
||||||
|
for (Object obj : dataObjArray) {
|
||||||
|
JSONObject jsonObject2 = JSON.parseObject(obj.toString());
|
||||||
|
String code = jsonObject2.get("Id").toString();
|
||||||
|
String name = jsonObject2.get("Name").toString();
|
||||||
|
String stockSymbol = jsonObject2.get("Symbol").toString();
|
||||||
|
String exchangeId = jsonObject2.get("ExchangeId").toString();
|
||||||
|
String fundamentalMarketCap = null;
|
||||||
|
if(jsonObject2.containsKey("FundamentalMarketCap") && jsonObject2.get("FundamentalMarketCap") != null){
|
||||||
|
fundamentalMarketCap = jsonObject2.get("FundamentalMarketCap").toString();
|
||||||
|
}
|
||||||
|
if (stockMap.containsKey(code)) {
|
||||||
|
log.info("已经存在 {} 信息, 跳过", code);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(! Utils.isShOrSzOrBJ(code)) {
|
||||||
|
log.info("{} 非 sh 或者 sz 或者 bj , 跳过", code);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Stock stock = new Stock();
|
||||||
|
stock.setStockSymbol(stockSymbol);
|
||||||
|
stock.setStockExchangeId(exchangeId);
|
||||||
|
stock.setStockName(name);
|
||||||
|
stock.setStockCode(code);
|
||||||
|
stock.setIsLock(0);
|
||||||
|
stock.setIsShow(0);
|
||||||
|
stock.setAddTime(new Date());
|
||||||
|
stock.setStockState(0);
|
||||||
|
// stock.setFundamentalMarketCap(fundamentalMarketCap);
|
||||||
|
list.add(stock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(CollectionUtils.isNotEmpty(list)) {
|
||||||
|
StockRepository.of().saveAll(list);
|
||||||
|
}
|
||||||
|
int count = list.size();
|
||||||
|
log.info("syncAFutureStockList执行, 受影响数{}, 耗时:{}毫秒", count, stopwatch.elapsed(TimeUnit.MILLISECONDS));
|
||||||
|
log.info("同步股票数据结束。。。。");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("同步股票数据异常,异常信息{}。。。。",e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String jsoupByUrl(String url) {
|
||||||
|
String result = "";
|
||||||
|
try {
|
||||||
|
// 使用Jsoup连接到网页
|
||||||
|
Document doc = Jsoup.connect(url)
|
||||||
|
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36")
|
||||||
|
.header("Referer", "https://www.business-standard.com/")
|
||||||
|
.header("Accept-Language", "en-US,en;q=0.9")
|
||||||
|
.get();
|
||||||
|
result = doc.html();
|
||||||
|
} catch (Exception e) {
|
||||||
|
return e.toString();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerResponse getIndiaIndex() {
|
||||||
|
List<IndiaIndexVo> indexVoList = new ArrayList<>();
|
||||||
|
//获取BSESENSEX指数
|
||||||
|
|
||||||
|
try {
|
||||||
|
IndiaIndexVo vo1 = new IndiaIndexVo();
|
||||||
|
String stockCode = "39929";
|
||||||
|
IndiaStockVO market = InvestingApis.of().market(StockCode.of(stockCode));
|
||||||
|
market.setName("BSESENSEX指数");
|
||||||
|
vo1.setIndexVo(market);
|
||||||
|
|
||||||
|
String type = "min";
|
||||||
|
List<JSONObject> list = InvestingApis.of().kline(StockCode.of(stockCode), type);
|
||||||
|
if(list == null || list.size() == 0){
|
||||||
|
type = "day";
|
||||||
|
list = InvestingApis.of().kline(StockCode.of(stockCode), type);
|
||||||
|
}
|
||||||
|
vo1.setKLine(list);
|
||||||
|
indexVoList.add(vo1);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.info("获取BSESENSEX指数数据异常,异常信息{}。。。。",e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
IndiaIndexVo vo2 = new IndiaIndexVo();
|
||||||
|
String stockCode = "8985"; //"17940";
|
||||||
|
IndiaStockVO market = InvestingApis.of().market(StockCode.of(stockCode));
|
||||||
|
market.setName("NIFTY50指数");
|
||||||
|
vo2.setIndexVo(market);
|
||||||
|
|
||||||
|
String type = "min";
|
||||||
|
List<JSONObject> list = InvestingApis.of().kline(StockCode.of(stockCode), type);
|
||||||
|
if(list == null || list.size() == 0){
|
||||||
|
type = "day";
|
||||||
|
list = InvestingApis.of().kline(StockCode.of(stockCode), type);
|
||||||
|
}
|
||||||
|
vo2.setKLine(list);
|
||||||
|
indexVoList.add(vo2);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.info("获取NIFTY50指数数据异常,异常信息{}。。。。",e.getMessage());
|
||||||
|
}
|
||||||
|
return ServerResponse.createBySuccess(indexVoList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
23
src/main/java/cn/stock/market/dto/BtodayStockDTO.java
Normal file
23
src/main/java/cn/stock/market/dto/BtodayStockDTO.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package cn.stock.market.dto;
|
||||||
|
|
||||||
|
import cn.stock.market.infrastructure.db.po.BtodayStockPO;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BtodayStockDTO
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/25
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@SuperBuilder
|
||||||
|
@EqualsAndHashCode(
|
||||||
|
callSuper = false
|
||||||
|
)
|
||||||
|
public class BtodayStockDTO extends BtodayStockPO {
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package cn.stock.market.dto;
|
package cn.stock.market.dto;
|
||||||
|
|
||||||
import cn.stock.market.infrastructure.stockdb.po.StockPO;
|
import cn.stock.market.infrastructure.db.po.StockPO;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|||||||
23
src/main/java/cn/stock/market/dto/StockIpoDTO.java
Normal file
23
src/main/java/cn/stock/market/dto/StockIpoDTO.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package cn.stock.market.dto;
|
||||||
|
|
||||||
|
import cn.stock.market.infrastructure.db.po.StockIpoPO;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StockIpoDTO
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/28
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@SuperBuilder
|
||||||
|
@EqualsAndHashCode(
|
||||||
|
callSuper = false
|
||||||
|
)
|
||||||
|
public class StockIpoDTO extends StockIpoPO {
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package cn.stock.market.dto.command;
|
||||||
|
|
||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.String;
|
||||||
|
import java.util.Date;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BtodayStockCreateCommand
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/25
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@SuperBuilder
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class BtodayStockCreateCommand {
|
||||||
|
/**
|
||||||
|
* 主键 */
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 股票名称 */
|
||||||
|
String stockName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 股票code */
|
||||||
|
String stockCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型 */
|
||||||
|
String stockType;
|
||||||
|
|
||||||
|
String stockSpell;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* btoday的业务id */
|
||||||
|
String coCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主页的http链接 */
|
||||||
|
String selfUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* url */
|
||||||
|
String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上次更新时间 */
|
||||||
|
Date lastUpdateTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package cn.stock.market.dto.command;
|
||||||
|
|
||||||
|
import java.lang.Integer;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BtodayStockModifyCommand
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/25
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@SuperBuilder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode(
|
||||||
|
callSuper = false
|
||||||
|
)
|
||||||
|
public class BtodayStockModifyCommand extends BtodayStockCreateCommand {
|
||||||
|
Integer id;
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package cn.stock.market.dto.command;
|
||||||
|
|
||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.String;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StockIpoCreateCommand
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/28
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@SuperBuilder
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class StockIpoCreateCommand {
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 股票代码 */
|
||||||
|
String stockCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 股票名称 */
|
||||||
|
String stockName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发行价格 */
|
||||||
|
BigDecimal stockPrice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申购日期 */
|
||||||
|
Date subscriptionDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上市日期 */
|
||||||
|
Date listingDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否显示【1 显示,2 不显示】 */
|
||||||
|
Integer isShow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否上市【1 未上市,2 已上市】 */
|
||||||
|
Integer isList;
|
||||||
|
|
||||||
|
Date createDate;
|
||||||
|
|
||||||
|
Date updateDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发行总数 */
|
||||||
|
Integer totalNumber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请总额 */
|
||||||
|
String apply;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 市盈率 */
|
||||||
|
BigDecimal peRatio;
|
||||||
|
|
||||||
|
String sourceType;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package cn.stock.market.dto.command;
|
||||||
|
|
||||||
|
import java.lang.Integer;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StockIpoModifyCommand
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/28
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@SuperBuilder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode(
|
||||||
|
callSuper = false
|
||||||
|
)
|
||||||
|
public class StockIpoModifyCommand extends StockIpoCreateCommand {
|
||||||
|
Integer id;
|
||||||
|
}
|
||||||
@@ -14,17 +14,20 @@ import lombok.experimental.SuperBuilder;
|
|||||||
@ApiModel
|
@ApiModel
|
||||||
public class StockCode {
|
public class StockCode {
|
||||||
String code;
|
String code;
|
||||||
StockSource source;
|
// StockSource source;
|
||||||
|
|
||||||
public static StockCode a(String code) {
|
public static StockCode a(String code) {
|
||||||
return of(code, StockSource.A);
|
return StockCode.builder().code(code)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
public static StockCode of(String code) {
|
||||||
public static StockCode of(String code, String source) {
|
return StockCode.builder().code(code)
|
||||||
return of(code, StockSource.of(source));
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StockCode of(String code, StockSource source) {
|
public static StockCode of(String code, StockSource source) {
|
||||||
return StockCode.builder().code(code).source(source).build();
|
return StockCode.builder().code(code)
|
||||||
|
// .source(source)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,15 @@ public class StockVO {
|
|||||||
private String monthImg;
|
private String monthImg;
|
||||||
|
|
||||||
private Integer depositAmt;
|
private Integer depositAmt;
|
||||||
|
private String volume;
|
||||||
|
|
||||||
|
public String getVolume() {
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVolume(String volume) {
|
||||||
|
this.volume = volume;
|
||||||
|
}
|
||||||
|
|
||||||
public static StockVO from(StockDetail detail, Stock stock) {
|
public static StockVO from(StockDetail detail, Stock stock) {
|
||||||
StockVO vo = new StockVO();
|
StockVO vo = new StockVO();
|
||||||
|
|||||||
114
src/main/java/cn/stock/market/infrastructure/api/TodayApis.java
Normal file
114
src/main/java/cn/stock/market/infrastructure/api/TodayApis.java
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
package cn.stock.market.infrastructure.api;
|
||||||
|
|
||||||
|
import cn.stock.market.utils.HttpClientRequest;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据来源网站:https://www.businesstoday.in/stocks
|
||||||
|
*
|
||||||
|
* @auther xiaoliuhu
|
||||||
|
*/
|
||||||
|
public class TodayApis {
|
||||||
|
|
||||||
|
static String get(String url) {
|
||||||
|
return HttpClientRequest.doGet(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取Top Gainers
|
||||||
|
public static List<JSONObject> getTopGainers(String exchange){
|
||||||
|
String url = "https://marketapi.intoday.in/widget/topgainer/view?exchange=" + exchange;
|
||||||
|
//返回字符串对象格式:{"status_code":1,"success":true,"data":[{}],"message":"Successful","fromredis":true}
|
||||||
|
String str = get(url);
|
||||||
|
JSONObject object = JSON.parseObject(str);
|
||||||
|
boolean bool = false;
|
||||||
|
if(object.containsKey("success")){
|
||||||
|
bool = object.getBoolean("success");
|
||||||
|
}
|
||||||
|
if(!bool){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//进行数据转换
|
||||||
|
List<JSONObject> dataObject = new ArrayList<>();
|
||||||
|
JSONArray jsonArray = JSON.parseArray(object.getString("data"));
|
||||||
|
for (Object obj : jsonArray){
|
||||||
|
JSONObject entity = JSON.parseObject(obj.toString());
|
||||||
|
dataObject.add(entity);
|
||||||
|
}
|
||||||
|
return dataObject;
|
||||||
|
}
|
||||||
|
//获取Top Losers
|
||||||
|
public static List<JSONObject> getTopLosers(String exchange){
|
||||||
|
String url = "https://marketapi.intoday.in/widget/toploser/view?exchange=" + exchange;
|
||||||
|
//返回字符串对象格式:{"status_code":1,"success":true,"data":[{}],"message":"Successful","fromredis":true}
|
||||||
|
String str = get(url);
|
||||||
|
JSONObject object = JSON.parseObject(str);
|
||||||
|
boolean bool = false;
|
||||||
|
if(object.containsKey("success")){
|
||||||
|
bool = object.getBoolean("success");
|
||||||
|
}
|
||||||
|
if(!bool){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//进行数据转换
|
||||||
|
List<JSONObject> dataObject = new ArrayList<>();
|
||||||
|
JSONArray jsonArray = JSON.parseArray(object.getString("data"));
|
||||||
|
for (Object obj : jsonArray){
|
||||||
|
JSONObject entity = JSON.parseObject(obj.toString());
|
||||||
|
dataObject.add(entity);
|
||||||
|
}
|
||||||
|
return dataObject;
|
||||||
|
}
|
||||||
|
//获取Most Active Volume
|
||||||
|
public static List<JSONObject> getMostActiveVolume(String exchange){
|
||||||
|
String url = "https://marketapi.intoday.in/widget/mostactivetopper/view?exchange=" + exchange;
|
||||||
|
//返回字符串对象格式:{"status_code":1,"success":true,"data":[{}],"message":"Successful","fromredis":true}
|
||||||
|
String str = get(url);
|
||||||
|
JSONObject object = JSON.parseObject(str);
|
||||||
|
boolean bool = false;
|
||||||
|
if(object.containsKey("success")){
|
||||||
|
bool = object.getBoolean("success");
|
||||||
|
}
|
||||||
|
if(!bool){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//进行数据转换
|
||||||
|
List<JSONObject> dataObject = new ArrayList<>();
|
||||||
|
JSONArray jsonArray = JSON.parseArray(object.getString("data"));
|
||||||
|
for (Object obj : jsonArray){
|
||||||
|
JSONObject entity = JSON.parseObject(obj.toString());
|
||||||
|
dataObject.add(entity);
|
||||||
|
}
|
||||||
|
return dataObject;
|
||||||
|
}
|
||||||
|
//获取Most Active Value
|
||||||
|
public static List<JSONObject> getMostActiveValue(String exchange){
|
||||||
|
String url = "https://marketapi.intoday.in/widget/mostactivetopperbyvalue/view?exchange=" + exchange;
|
||||||
|
//返回字符串对象格式:{"status_code":1,"success":true,"data":[{}],"message":"Successful","fromredis":true}
|
||||||
|
String str = get(url);
|
||||||
|
JSONObject object = JSON.parseObject(str);
|
||||||
|
boolean bool = false;
|
||||||
|
if(object.containsKey("success")){
|
||||||
|
bool = object.getBoolean("success");
|
||||||
|
}
|
||||||
|
if(!bool){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//进行数据转换
|
||||||
|
List<JSONObject> dataObject = new ArrayList<>();
|
||||||
|
JSONArray jsonArray = JSON.parseArray(object.getString("data"));
|
||||||
|
for (Object obj : jsonArray){
|
||||||
|
JSONObject entity = JSON.parseObject(obj.toString());
|
||||||
|
dataObject.add(entity);
|
||||||
|
}
|
||||||
|
return dataObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println(getTopGainers("nse"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package cn.stock.market.infrastructure.api.investing;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ApiModel(value = "指数信息")
|
||||||
|
public class IndiaIndexVo {
|
||||||
|
@ApiModelProperty(value = "指数详情")
|
||||||
|
private IndiaStockVO indexVo;
|
||||||
|
@ApiModelProperty(value = "指数k线")
|
||||||
|
private List<JSONObject> kLine;
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package cn.stock.market.infrastructure.api.investing;
|
||||||
|
|
||||||
|
import cn.qutaojing.common.utils.BigDecimals;
|
||||||
|
import cn.stock.market.dto.model.StockVO;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class IndiaStockVO {
|
||||||
|
private Integer id;
|
||||||
|
/**
|
||||||
|
* 股票名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 股票中文名称
|
||||||
|
*/
|
||||||
|
private String cname;
|
||||||
|
/**
|
||||||
|
* 股票代码
|
||||||
|
*/
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
private Integer isLock;
|
||||||
|
|
||||||
|
private Integer isShow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 股票价格
|
||||||
|
*/
|
||||||
|
private String nowPrice;
|
||||||
|
|
||||||
|
private String open;
|
||||||
|
|
||||||
|
private String high;
|
||||||
|
|
||||||
|
private String low;
|
||||||
|
|
||||||
|
private String close;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 成交额(暂未获取到)
|
||||||
|
*/
|
||||||
|
private String turnover;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 成交量
|
||||||
|
*/
|
||||||
|
private String volume;
|
||||||
|
|
||||||
|
private String marketValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 股票涨跌幅
|
||||||
|
*/
|
||||||
|
private String number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 股票涨跌幅百分比
|
||||||
|
*/
|
||||||
|
private String rate;
|
||||||
|
|
||||||
|
/*是否添加自选:1、添加自选,0、未添加自选*/
|
||||||
|
private String isOption;
|
||||||
|
private String time;
|
||||||
|
private String type; //股票类型
|
||||||
|
String url;
|
||||||
|
String targetId;
|
||||||
|
|
||||||
|
public StockVO toStockVo() {
|
||||||
|
StockVO vo = new StockVO();
|
||||||
|
vo.setName(name);
|
||||||
|
vo.setCode(code);
|
||||||
|
vo.setNowPrice(nowPrice);
|
||||||
|
vo.setHcrate(BigDecimals.divide(BigDecimals.p(rate), 100));
|
||||||
|
vo.setToday_max(high);
|
||||||
|
vo.setToday_min(low);
|
||||||
|
vo.setOpen_px(open);
|
||||||
|
vo.setPreclose_px(close);
|
||||||
|
vo.setVolume(volume);
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,259 @@
|
|||||||
|
package cn.stock.market.infrastructure.api.investing;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
import com.ag.utils.CollectionUtils;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.github.pagehelper.PageInfo;
|
||||||
|
import com.google.common.base.Stopwatch;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.qutaojing.common.utils.BigDecimals;
|
||||||
|
import cn.stock.market.dto.model.StockCode;
|
||||||
|
import cn.stock.market.utils.RequestCacheUtils;
|
||||||
|
import cn.stock.market.utils.ServerResponse;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class InvestingApis {
|
||||||
|
|
||||||
|
public IndiaStockVO market(StockCode code) {
|
||||||
|
List<IndiaStockVO> list = batchMarket(Lists.newArrayList(code));
|
||||||
|
return CollectionUtils.isNotEmpty(list) ? list.get(0) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IndiaStockVO> batchMarket(List<StockCode> list) {
|
||||||
|
List<IndiaStockVO> retList = Lists.newArrayList();
|
||||||
|
for (StockCode code : list) {
|
||||||
|
ServerResponse<IndiaStockVO> response = RequestCacheUtils.cache("_INDIA_", "targetId_" + code.getCode(), (string) -> {
|
||||||
|
IndiaStockVO vo = _market(code);
|
||||||
|
return ServerResponse.createBySuccess(vo);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(response.getData() != null) {
|
||||||
|
retList.add(response.getData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IndiaStockVO _market(StockCode code) {
|
||||||
|
try {
|
||||||
|
JSONObject json = InvestingInvokerApis.of().__market(code);
|
||||||
|
JSONArray pairs_data = json
|
||||||
|
.getJSONArray("data").getJSONObject(0)
|
||||||
|
.getJSONObject("screen_data").getJSONArray("pairs_data");
|
||||||
|
IndiaStockVO vo = new IndiaStockVO();
|
||||||
|
JSONArray overview_table = pairs_data.getJSONObject(0).getJSONArray("overview_table");
|
||||||
|
JSONObject info_header = pairs_data.getJSONObject(0).getJSONObject("info_header");
|
||||||
|
String pair_name_base = info_header.getString("pair_name_base");
|
||||||
|
String pair_ID = info_header.getString("pair_ID");
|
||||||
|
|
||||||
|
vo.setName(pair_name_base);
|
||||||
|
vo.setCname(pair_name_base);
|
||||||
|
vo.setCode(pair_ID);
|
||||||
|
vo.setTargetId(pair_ID);
|
||||||
|
|
||||||
|
String 昨收 = find_overview_table_value_with_key(overview_table, "昨收");
|
||||||
|
vo.setClose(numberToString(昨收));
|
||||||
|
String 开盘 = find_overview_table_value_with_key(overview_table, "开盘");
|
||||||
|
String 成交量 = find_overview_table_value_with_key(overview_table, "成交量"); //658,477,949
|
||||||
|
vo.setVolume(numberToString(成交量));
|
||||||
|
|
||||||
|
if(StringUtils.isNotBlank(开盘)) {
|
||||||
|
vo.setOpen(numberToString(开盘));
|
||||||
|
}
|
||||||
|
String 当日幅度 = find_overview_table_value_with_key(overview_table, "当日幅度"); //6.91 - 7.89
|
||||||
|
if(StringUtils.isNotBlank(当日幅度)) {
|
||||||
|
String[] split = 当日幅度.trim().split("-");
|
||||||
|
vo.setLow(numberToString(split[0]));
|
||||||
|
vo.setHigh(numberToString(split[1]));
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
|
String last = info_header.getString("last"); //当前价
|
||||||
|
vo.setNowPrice(numberToString(last));
|
||||||
|
|
||||||
|
String percent_tooltip_value = info_header.getString("percent_tooltip_value"); //涨幅
|
||||||
|
vo.setRate(percent_tooltip_value);
|
||||||
|
String change = info_header.getString("change"); //涨幅值 ("+0.65")
|
||||||
|
if(change.startsWith("+")) {
|
||||||
|
vo.setNumber(numberToString(change.substring(1)));
|
||||||
|
} else {
|
||||||
|
vo.setNumber(numberToString(change));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(BigDecimals.loeZero(vo.getNowPrice())) {
|
||||||
|
log.warn("{} 当前价非法, 将忽略.", JSON.toJSONString(vo));
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("batchIndiaStockMarketData>>code:{}, 失败. 跳过", code, e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String numberToString(String string) {
|
||||||
|
return StringUtils.replace(string, ",", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String find_overview_table_value_with_key(JSONArray overview_table_value, String key) {
|
||||||
|
for (Object obj : overview_table_value) {
|
||||||
|
JSONObject item = (JSONObject) obj;
|
||||||
|
if(StringUtils.equals(item.getString("key"), key)) {
|
||||||
|
return item.getString("val");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "AvgVolume": 3741486,
|
||||||
|
"Chg": -9.55,
|
||||||
|
"ChgPct": -5.25,
|
||||||
|
"CountryNameTranslated": "India",
|
||||||
|
"ExchangeId": "46",
|
||||||
|
"Flag": "IN",
|
||||||
|
"FundamentalBeta": 0.916,
|
||||||
|
"FundamentalMarketCap": 448530000000,
|
||||||
|
"FundamentalRatio": 8.41,
|
||||||
|
"FundamentalRevenue": "250.56B",
|
||||||
|
"High": 183,
|
||||||
|
"Id": "7310",
|
||||||
|
"IsOpen": "0",
|
||||||
|
"Last": 172.35,
|
||||||
|
"LastPairDecimal": 2,
|
||||||
|
"Low": 171.45,
|
||||||
|
"Name": "Aditya Birla Capital",
|
||||||
|
"PairType": "Equities",
|
||||||
|
"Performance3Year": 150.69,
|
||||||
|
"PerformanceDay": -5.25,
|
||||||
|
"PerformanceMonth": -2.38,
|
||||||
|
"PerformanceWeek": -5.67,
|
||||||
|
"PerformanceYear": 48.71,
|
||||||
|
"PerformanceYtd": 14.75,
|
||||||
|
"Symbol": "ADTB",
|
||||||
|
"TechnicalDay": "strong_sell",
|
||||||
|
"TechnicalHour": "strong_sell",
|
||||||
|
"TechnicalMonth": "strong_buy",
|
||||||
|
"TechnicalWeek": "sell",
|
||||||
|
"Time": "1698055197",
|
||||||
|
"Url": "/equities/aditya-birla",
|
||||||
|
"Volume": 3693615
|
||||||
|
* @param httpClient
|
||||||
|
* @param currPage
|
||||||
|
* @param pageSize
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public PageInfo<IndiaStockVO> page(int currPage, int pageSize) throws IOException {
|
||||||
|
JSONObject json = InvestingInvokerApis.of().__page(currPage, pageSize);
|
||||||
|
|
||||||
|
int totalPages = (json.getIntValue("total") / json.getIntValue("pageSize")) + 1;
|
||||||
|
log.info("总页码数: {}", totalPages);
|
||||||
|
|
||||||
|
List<IndiaStockVO> items = json.getJSONArray("data").stream().map(val -> {
|
||||||
|
JSONObject j = (JSONObject) val;
|
||||||
|
IndiaStockVO vo = new IndiaStockVO();
|
||||||
|
vo.setName(j.getString("Name"));
|
||||||
|
vo.setCname(j.getString("Name"));
|
||||||
|
vo.setCode(j.getString("Symbol"));
|
||||||
|
vo.setIsLock(0);
|
||||||
|
vo.setIsShow(0);
|
||||||
|
vo.setNowPrice(numberToString(j.getString("Last")));
|
||||||
|
vo.setOpen("--");
|
||||||
|
vo.setClose("--");
|
||||||
|
vo.setNumber(numberToString(j.getString("Chg")));
|
||||||
|
vo.setRate(numberToString(j.getString("ChgPct")));
|
||||||
|
vo.setHigh(numberToString(j.getString("High")));
|
||||||
|
vo.setLow(numberToString(j.getString("Low")));
|
||||||
|
vo.setUrl(numberToString(j.getString("Url")));
|
||||||
|
vo.setTargetId(j.getString("Id"));
|
||||||
|
vo.setType("印度");
|
||||||
|
return vo;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
PageInfo<IndiaStockVO> page = new PageInfo<>();
|
||||||
|
page.setPageNum(currPage);
|
||||||
|
page.setPageSize(pageSize);
|
||||||
|
page.setTotal(json.getIntValue("total"));
|
||||||
|
page.setPages(totalPages);
|
||||||
|
page.setList(items);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IndiaStockVO> thirdIndiaList() throws IOException {
|
||||||
|
List<IndiaStockVO> list = Lists.newArrayList();
|
||||||
|
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||||
|
int totalPages = 0;
|
||||||
|
int currPage = 0;
|
||||||
|
do {
|
||||||
|
try {
|
||||||
|
PageInfo<IndiaStockVO> page = page(currPage, 100);
|
||||||
|
|
||||||
|
totalPages = page.getPages();
|
||||||
|
currPage ++;
|
||||||
|
list.addAll(page.getList());
|
||||||
|
} catch(Exception e) {
|
||||||
|
log.error("发送错误, 跳过", e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} while(currPage < totalPages);
|
||||||
|
|
||||||
|
log.info("获取印度股票列表执行完毕, 查询到数据 {} 条, 耗时: {} 毫秒", list.size(), stopwatch.elapsed(TimeUnit.MILLISECONDS));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param code
|
||||||
|
* @param string min/day/week/month
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public List<JSONObject> kline(StockCode code, String string) throws IOException {
|
||||||
|
if(code == null) {
|
||||||
|
throw new RuntimeException("找不到股票信息");
|
||||||
|
}
|
||||||
|
Date nowDate = new Date();
|
||||||
|
JSONObject json = InvestingInvokerApis.of().__kline(code, string);
|
||||||
|
return json
|
||||||
|
.getJSONArray("data")
|
||||||
|
.stream()
|
||||||
|
.map(val -> {
|
||||||
|
JSONArray _ar = (JSONArray) val;
|
||||||
|
JSONObject item = new JSONObject();
|
||||||
|
item.put("date", _ar.get(0));
|
||||||
|
item.put("open", _ar.get(1));
|
||||||
|
item.put("high", _ar.get(2));
|
||||||
|
item.put("low", _ar.get(3));
|
||||||
|
item.put("close", _ar.get(4));
|
||||||
|
item.put("volume", _ar.get(5));
|
||||||
|
return item;
|
||||||
|
}).filter(val -> {
|
||||||
|
if("min".equalsIgnoreCase(string)) {
|
||||||
|
return DateUtil.isSameDay(nowDate, new Date(val.getLong("date")));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InvestingApis of() {
|
||||||
|
return new InvestingApis();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
package cn.stock.market.infrastructure.api.investing;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.google.common.base.Stopwatch;
|
||||||
|
|
||||||
|
import cn.hutool.core.text.StrFormatter;
|
||||||
|
import cn.stock.market.dto.model.StockCode;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Protocol;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Request.Builder;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class InvestingInvokerApis {
|
||||||
|
public static final int COUNTRY_ID = 14; // INDIA
|
||||||
|
public static final String API_HEADER = ":method: GET\n"
|
||||||
|
+ ":scheme: https\n"
|
||||||
|
+ ":path: /get_screen.php?screen_ID=22&skinID=1&overview_table_order=1&time_utc_offset=28800&pair_ID=1156730&additionalTimeframes=Yes&lang_ID=6&include_pair_attr=true&v2=1\n"
|
||||||
|
+ ":authority: cnappapi.investing.com\n"
|
||||||
|
+ "cache-control: no-cache\n"
|
||||||
|
+ "user-agent: Investing.China/64 CFNetwork/1390 Darwin/22.0.0\n"
|
||||||
|
+ "x-os: ios\n"
|
||||||
|
+ "x-idfa-perm: 0\n"
|
||||||
|
+ "x-os-ver: 16.0\n"
|
||||||
|
+ "x-app-ver: 156\n"
|
||||||
|
+ "apf_src: no\n"
|
||||||
|
+ "x-meta-ver: 14\n"
|
||||||
|
+ "accept-language: zh-CN,zh-Hans;q=0.9\n"
|
||||||
|
+ "accept: */*\n"
|
||||||
|
+ "ccode: CN\n"
|
||||||
|
+ "";
|
||||||
|
public static final String API_HEADER_LIST = "Host: api.investing.com\n"
|
||||||
|
+ "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/119.0\n"
|
||||||
|
+ "Accept: application/json, text/plain, */*\n"
|
||||||
|
+ "Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\n"
|
||||||
|
+ "domain-id: cn\n"
|
||||||
|
+ "Origin: https://cn.investing.com\n"
|
||||||
|
+ "Connection: keep-alive\n"
|
||||||
|
+ "Referer: https://cn.investing.com/\n"
|
||||||
|
+ "Sec-Fetch-Dest: empty\n"
|
||||||
|
+ "Sec-Fetch-Mode: cors\n"
|
||||||
|
+ "Sec-Fetch-Site: same-site\n"
|
||||||
|
+ "Pragma: no-cache\n"
|
||||||
|
+ "Cache-Control: no-cache\n"
|
||||||
|
+ "TE: trailers";
|
||||||
|
|
||||||
|
static OkHttpClient httpClient;
|
||||||
|
public static OkHttpClient httpClient() {
|
||||||
|
if(httpClient == null) {
|
||||||
|
X509TrustManager manager = SSLSocketClientUtil.getX509TrustManager();
|
||||||
|
httpClient = new OkHttpClient.Builder()
|
||||||
|
.followRedirects(true) // 为了制造非200状态码,禁止302跳转
|
||||||
|
.protocols(Collections.unmodifiableList(Arrays.asList(Protocol.HTTP_1_1, Protocol.HTTP_2)))// 启用http2.0协议 //, Protocol.HTTP_2
|
||||||
|
.sslSocketFactory(SSLSocketClientUtil.getSocketFactory(manager), manager)
|
||||||
|
.hostnameVerifier(SSLSocketClientUtil.getHostnameVerifier())//忽略校验
|
||||||
|
.retryOnConnectionFailure(true)
|
||||||
|
.connectTimeout(60, TimeUnit.SECONDS)
|
||||||
|
.readTimeout(60, TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addHeader(Builder builder,String headerLines) {
|
||||||
|
String[] headers = StringUtils.split(headerLines, "\n");
|
||||||
|
for (String header : headers) {
|
||||||
|
String[] split2 = StringUtils.split(header, ": ");
|
||||||
|
String key = split2[0];
|
||||||
|
String value = StringUtils.substring(header, key.length() + 2);
|
||||||
|
builder.header(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builderGet(String url) {
|
||||||
|
return new Request.Builder().url(url).method("GET", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject __market(StockCode code) throws IOException {
|
||||||
|
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||||
|
String tmpl = "https://cnappapi.investing.com/get_screen.php?v2=1&additionalTimeframes=Yes&time_utc_offset=28800&overview_table_order=0&skinID=1&lang_ID=6&include_pair_attr=true&screen_ID=22&pair_ID={}";
|
||||||
|
String url = StrFormatter.format(tmpl, code.getCode());
|
||||||
|
log.info("url: {}", url);
|
||||||
|
Builder builder = builderGet(url);
|
||||||
|
addHeader(builder, API_HEADER);
|
||||||
|
String body = httpClient().newCall(builder.build()).execute().body().string();
|
||||||
|
log.info("india market cost: {} ms, url: {}, body: {}", stopwatch.elapsed(TimeUnit.MILLISECONDS), url, body);
|
||||||
|
return JSON.parseObject(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String numberToString(String string) {
|
||||||
|
return StringUtils.replace(string, ",", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String find_overview_table_value_with_key(JSONArray overview_table_value, String key) {
|
||||||
|
for (Object obj : overview_table_value) {
|
||||||
|
JSONObject item = (JSONObject) obj;
|
||||||
|
if(StringUtils.equals(item.getString("key"), key)) {
|
||||||
|
return item.getString("val");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject __page(int pageNum, int pageSize) throws IOException {
|
||||||
|
String tmpl = "https://api.investing.com/api/financialdata/assets/equitiesByCountry/default?fields-list=id,name,symbol,high,low,last,lastPairDecimal,change,changePercent,volume,time,isOpen,url,flag,countryNameTranslated,exchangeId,performanceDay,performanceWeek,performanceMonth,performanceYtd,performanceYear,performance3Year,technicalHour,technicalDay,technicalWeek,technicalMonth,avgVolume,fundamentalMarketCap,fundamentalRevenue,fundamentalRatio,fundamentalBeta,pairType&country-id=14&page={}&page-size={}&include-major-indices=false&include-additional-indices=false&include-primary-sectors=false&include-other-indices=false&limit=0";
|
||||||
|
String url = StrFormatter.format(tmpl, pageNum - 1, pageSize);
|
||||||
|
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||||
|
log.info("url: {}", url);
|
||||||
|
Builder builder = builderGet(url);
|
||||||
|
String body = httpClient().newCall(builder.build()).execute().body().string();
|
||||||
|
log.info("第{}页码, 耗时: {} 毫秒, 返回原始值: {}, 准备解析中.", pageNum, stopwatch.elapsed(TimeUnit.MILLISECONDS), body);
|
||||||
|
return JSON.parseObject(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与 __page 的区别
|
||||||
|
* api/financialdata/assets/equitiesByCountry/default
|
||||||
|
* api/financialdata/assets/equitiesByCountry/17943
|
||||||
|
* @param pageNum
|
||||||
|
* @param pageSize
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public JSONObject __page_nifty100(int pageNum, int pageSize) throws IOException {
|
||||||
|
String tmpl = "https://api.investing.com/api/financialdata/assets/equitiesByIndices/17943?fields-list=id%2Cname%2Csymbol%2Chigh%2Clow%2Clast%2ClastPairDecimal%2Cchange%2CchangePercent%2Cvolume%2Ctime%2CisOpen%2Curl%2Cflag%2CcountryNameTranslated%2CexchangeId%2CperformanceDay%2CperformanceWeek%2CperformanceMonth%2CperformanceYtd%2CperformanceYear%2Cperformance3Year%2CtechnicalHour%2CtechnicalDay%2CtechnicalWeek%2CtechnicalMonth%2CavgVolume%2CfundamentalMarketCap%2CfundamentalRevenue%2CfundamentalRatio%2CfundamentalBeta%2CpairType&country-id=14&page={}&page-size={}&include-major-indices=false&include-additional-indices=false&include-primary-sectors=false&include-other-indices=false&limit=0";
|
||||||
|
// String tmpl = "https://api.investing.com/api/financialdata/assets/equitiesByCountry/17943?fields-list=id,name,symbol,high,low,last,lastPairDecimal,change,changePercent,volume,time,isOpen,url,flag,countryNameTranslated,exchangeId,performanceDay,performanceWeek,performanceMonth,performanceYtd,performanceYear,performance3Year,technicalHour,technicalDay,technicalWeek,technicalMonth,avgVolume,fundamentalMarketCap,fundamentalRevenue,fundamentalRatio,fundamentalBeta,pairType&country-id=14&page={}&page-size={}&include-major-indices=false&include-additional-indices=false&include-primary-sectors=false&include-other-indices=false&limit=0";
|
||||||
|
String url = StrFormatter.format(tmpl, pageNum - 1, pageSize);
|
||||||
|
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||||
|
log.info("url: {}", url);
|
||||||
|
Builder builder = builderGet(url);
|
||||||
|
String body = httpClient().newCall(builder.build()).execute().body().string();
|
||||||
|
log.info("第{}页码, 耗时: {} 毫秒, 返回原始值: {}, 准备解析中.", pageNum, stopwatch.elapsed(TimeUnit.MILLISECONDS), body);
|
||||||
|
return JSON.parseObject(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param code
|
||||||
|
* @param string min/day/week/month
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public JSONObject __kline(StockCode code, String string) throws IOException {
|
||||||
|
if(code == null) {
|
||||||
|
throw new RuntimeException("找不到股票信息");
|
||||||
|
}
|
||||||
|
String interval = null;
|
||||||
|
String period = null;
|
||||||
|
if("min".equalsIgnoreCase(string)) {
|
||||||
|
interval = "PT5M";
|
||||||
|
} else if("day".equalsIgnoreCase(string)) {
|
||||||
|
interval = "P1D";
|
||||||
|
} else if("week".equalsIgnoreCase(string)) {
|
||||||
|
interval = "P1W";
|
||||||
|
} else if("month".equalsIgnoreCase(string)) {
|
||||||
|
interval = "P1M";
|
||||||
|
} else if("3month".equalsIgnoreCase(string)) {
|
||||||
|
interval = "P1D";
|
||||||
|
period = "P3M";
|
||||||
|
} else if("6month".equalsIgnoreCase(string)) {
|
||||||
|
interval = "P1D";
|
||||||
|
period = "P6M";
|
||||||
|
} else if("year".equalsIgnoreCase(string)) {
|
||||||
|
interval = "P1W";
|
||||||
|
period = "P1Y";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(StringUtils.isBlank(interval)) {
|
||||||
|
interval = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
String url = null;
|
||||||
|
if(StringUtils.isNotBlank(period)) {
|
||||||
|
String tmpl = "https://api.investing.com/api/financialdata/{}/historical/chart/?period={}&interval={}&pointscount=160";
|
||||||
|
url = StrFormatter.format(tmpl, code.getCode(), period, interval);
|
||||||
|
} else {
|
||||||
|
String tmpl = "https://api.investing.com/api/financialdata/{}/historical/chart/?interval={}&pointscount=160";
|
||||||
|
url = StrFormatter.format(tmpl, code.getCode(), interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder builder = builderGet(url);
|
||||||
|
|
||||||
|
String body = httpClient().newCall(builder.build()).execute().body().string();
|
||||||
|
return JSON.parseObject(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InvestingInvokerApis of() {
|
||||||
|
return new InvestingInvokerApis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
JSONObject __market = of().__page(1,100);
|
||||||
|
System.out.println(__market);
|
||||||
|
|
||||||
|
JSONObject __page = of().__page(1, 10);
|
||||||
|
JSONObject __page_nifty100 = of().__page_nifty100(1, 10);
|
||||||
|
|
||||||
|
System.out.println(__page);
|
||||||
|
System.out.println(__page_nifty100);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package cn.stock.market.infrastructure.api.investing;
|
||||||
|
|
||||||
|
import java.security.KeyManagementException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
import javax.net.ssl.HostnameVerifier;
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLSession;
|
||||||
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
|
||||||
|
public class SSLSocketClientUtil {
|
||||||
|
|
||||||
|
public static SSLSocketFactory getSocketFactory(TrustManager manager) {
|
||||||
|
SSLSocketFactory socketFactory = null;
|
||||||
|
try {
|
||||||
|
SSLContext sslContext = SSLContext.getInstance("SSL");
|
||||||
|
sslContext.init(null, new TrustManager[]{manager}, new SecureRandom());
|
||||||
|
socketFactory = sslContext.getSocketFactory();
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (KeyManagementException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return socketFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static X509TrustManager getX509TrustManager() {
|
||||||
|
return new X509TrustManager() {
|
||||||
|
@Override
|
||||||
|
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return new X509Certificate[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HostnameVerifier getHostnameVerifier() {
|
||||||
|
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
|
||||||
|
@Override
|
||||||
|
public boolean verify(String s, SSLSession sslSession) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return hostnameVerifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,14 +37,12 @@ import com.rp.spring.jpa.GenericJpaRepositoryImpl;
|
|||||||
* @created Jan 26, 2018 3:57:47 PM
|
* @created Jan 26, 2018 3:57:47 PM
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ComponentScan({ "cn.stock.**.db.po", "com.stock.**.db.repo","cn.qutaojing.**.po", "cn.qutaojing.**.repo" })
|
@ComponentScan({ "cn.stock.**.db.po", "cn.stock.**.db.repo"})
|
||||||
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory",
|
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory",
|
||||||
transactionManagerRef = "transactionManager",
|
transactionManagerRef = "transactionManager",
|
||||||
repositoryBaseClass = GenericJpaRepositoryImpl.class,
|
repositoryBaseClass = GenericJpaRepositoryImpl.class,
|
||||||
repositoryFactoryBeanClass = GenericJpaRepositoryFactoryBean.class,
|
repositoryFactoryBeanClass = GenericJpaRepositoryFactoryBean.class,
|
||||||
basePackages = {
|
basePackages = {
|
||||||
"cn.qutaojing.ipay.infrastructure.db.po", "cn.qutaojing.ipay.infrastructure.db.repo",
|
|
||||||
"cn.stock.trade.infrastructure.db.po", "cn.stock.trade.infrastructure.db.repo",
|
|
||||||
"cn.stock.market.infrastructure.db.po", "cn.stock.market.infrastructure.db.repo"})
|
"cn.stock.market.infrastructure.db.po", "cn.stock.market.infrastructure.db.repo"})
|
||||||
public class MarketDatasourceConfig {
|
public class MarketDatasourceConfig {
|
||||||
@Autowired HibernateProperties hibernateProperties;
|
@Autowired HibernateProperties hibernateProperties;
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package cn.stock.market.infrastructure.db.po;
|
||||||
|
|
||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.String;
|
||||||
|
import java.util.Date;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.Generated;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
import org.hibernate.annotations.DynamicInsert;
|
||||||
|
import org.hibernate.annotations.DynamicUpdate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BtodayStockPO
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/25
|
||||||
|
*/
|
||||||
|
@SuperBuilder
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Entity
|
||||||
|
@DynamicInsert
|
||||||
|
@DynamicUpdate
|
||||||
|
@Table(
|
||||||
|
name = "btoday_stock"
|
||||||
|
)
|
||||||
|
public class BtodayStockPO {
|
||||||
|
/**
|
||||||
|
* 主键 */
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(
|
||||||
|
strategy = GenerationType.IDENTITY
|
||||||
|
)
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 股票名称 */
|
||||||
|
String stockName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 股票code */
|
||||||
|
String stockCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型 */
|
||||||
|
String stockType;
|
||||||
|
|
||||||
|
String stockSpell;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* btoday的业务id */
|
||||||
|
String coCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主页的http链接 */
|
||||||
|
String selfUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* url */
|
||||||
|
String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上次更新时间 */
|
||||||
|
Date lastUpdateTime;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package cn.stock.market.infrastructure.stockdb.po;
|
package cn.stock.market.infrastructure.db.po;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package cn.stock.market.infrastructure.db.po;
|
||||||
|
|
||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.String;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
import org.hibernate.annotations.DynamicInsert;
|
||||||
|
import org.hibernate.annotations.DynamicUpdate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StockIpoPO
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/28
|
||||||
|
*/
|
||||||
|
@SuperBuilder
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Entity
|
||||||
|
@DynamicInsert
|
||||||
|
@DynamicUpdate
|
||||||
|
@Table(
|
||||||
|
name = "stock_ipo"
|
||||||
|
)
|
||||||
|
public class StockIpoPO {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(
|
||||||
|
strategy = javax.persistence.GenerationType.IDENTITY
|
||||||
|
)
|
||||||
|
Integer id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 股票代码 */
|
||||||
|
String stockCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 股票名称 */
|
||||||
|
String stockName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发行价格 */
|
||||||
|
BigDecimal stockPrice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申购日期 */
|
||||||
|
Date subscriptionDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上市日期 */
|
||||||
|
Date listingDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否显示【1 显示,2 不显示】 */
|
||||||
|
Integer isShow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否上市【1 未上市,2 已上市】 */
|
||||||
|
Integer isList;
|
||||||
|
|
||||||
|
Date createDate;
|
||||||
|
|
||||||
|
Date updateDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发行总数 */
|
||||||
|
Integer totalNumber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请总额 */
|
||||||
|
String apply;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 市盈率 */
|
||||||
|
BigDecimal peRatio;
|
||||||
|
|
||||||
|
String sourceType;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package cn.stock.market.infrastructure.stockdb.po;
|
package cn.stock.market.infrastructure.db.po;
|
||||||
|
|
||||||
import java.lang.Integer;
|
import java.lang.Integer;
|
||||||
import java.lang.String;
|
import java.lang.String;
|
||||||
@@ -65,4 +65,8 @@ public class StockPO {
|
|||||||
BigDecimal increaseRatio;
|
BigDecimal increaseRatio;
|
||||||
|
|
||||||
Integer stockState;
|
Integer stockState;
|
||||||
|
|
||||||
|
String stockExchangeId;
|
||||||
|
|
||||||
|
String stockSymbol;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package cn.stock.market.infrastructure.db.repo;
|
||||||
|
|
||||||
|
import cn.stock.market.infrastructure.db.po.BtodayStockPO;
|
||||||
|
import com.rp.spring.jpa.GenericJpaRepository;
|
||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BtodayStockRepo
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/25
|
||||||
|
*/
|
||||||
|
public interface BtodayStockRepo extends GenericJpaRepository<BtodayStockPO, Integer> {
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package cn.stock.market.infrastructure.stockdb.repo;
|
package cn.stock.market.infrastructure.db.repo;
|
||||||
|
|
||||||
import com.rp.spring.jpa.GenericJpaRepository;
|
import com.rp.spring.jpa.GenericJpaRepository;
|
||||||
|
|
||||||
import cn.stock.market.infrastructure.stockdb.po.SiteSettingPO;
|
import cn.stock.market.infrastructure.db.po.SiteSettingPO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StockRepo
|
* StockRepo
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package cn.stock.market.infrastructure.db.repo;
|
||||||
|
|
||||||
|
import cn.stock.market.infrastructure.db.po.StockIpoPO;
|
||||||
|
import com.rp.spring.jpa.GenericJpaRepository;
|
||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StockIpoRepo
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @created 2023/12/28
|
||||||
|
*/
|
||||||
|
public interface StockIpoRepo extends GenericJpaRepository<StockIpoPO, Integer> {
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package cn.stock.market.infrastructure.stockdb.repo;
|
package cn.stock.market.infrastructure.db.repo;
|
||||||
|
|
||||||
import com.rp.spring.jpa.GenericJpaRepository;
|
import com.rp.spring.jpa.GenericJpaRepository;
|
||||||
|
|
||||||
import cn.stock.market.infrastructure.stockdb.po.StockPO;
|
import cn.stock.market.infrastructure.db.po.StockPO;
|
||||||
|
|
||||||
import java.lang.Integer;
|
import java.lang.Integer;
|
||||||
|
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
package cn.stock.market.infrastructure.job;
|
||||||
|
|
||||||
|
import cn.stock.market.domain.basic.entity.Stock;
|
||||||
|
import cn.stock.market.domain.basic.repository.StockRepository;
|
||||||
|
import cn.stock.market.infrastructure.api.investing.InvestingInvokerApis;
|
||||||
|
import cn.stock.market.utils.Utils;
|
||||||
|
import com.ag.utils.CollectionUtils;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.google.common.base.Stopwatch;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class InvestingTask {
|
||||||
|
|
||||||
|
// @Scheduled(cron = "0 0 6 * * ?")
|
||||||
|
public void syncIndiaData(){
|
||||||
|
log.info("同步股票数据开始。。。。");
|
||||||
|
Map<String, Stock> stockMap = StockRepository.of().cacheCodeMap();
|
||||||
|
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||||
|
List<Stock> list = Lists.newArrayList();
|
||||||
|
int currentTotal = 0;
|
||||||
|
int pageNum =1;
|
||||||
|
int pageSize = 300;
|
||||||
|
try {
|
||||||
|
for(int i = 0;i < pageNum;i ++) {
|
||||||
|
JSONObject jsonObject = InvestingInvokerApis.of().__page(pageNum, pageSize);
|
||||||
|
int total = 0;
|
||||||
|
if(jsonObject.containsKey("total")){
|
||||||
|
total = Integer.parseInt(jsonObject.get("total").toString());
|
||||||
|
}
|
||||||
|
JSONArray dataObjArray = new JSONArray();
|
||||||
|
if(jsonObject.containsKey("data")){
|
||||||
|
dataObjArray = JSON.parseArray(jsonObject.get("data").toString());
|
||||||
|
}
|
||||||
|
for (Object obj : dataObjArray) {
|
||||||
|
JSONObject jsonObject2 = JSON.parseObject(obj.toString());
|
||||||
|
String code = jsonObject2.get("Id").toString();
|
||||||
|
String name = jsonObject2.get("Name").toString();
|
||||||
|
String stockSymbol = jsonObject2.get("Symbol").toString();
|
||||||
|
String exchangeId = jsonObject2.get("ExchangeId").toString();
|
||||||
|
if (stockMap.containsKey(code)) {
|
||||||
|
log.info("已经存在 {} 信息, 跳过", code);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(! Utils.isShOrSzOrBJ(code)) {
|
||||||
|
log.info("{} 非 sh 或者 sz 或者 bj , 跳过", code);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Stock stock = new Stock();
|
||||||
|
stock.setStockSymbol(stockSymbol);
|
||||||
|
stock.setStockExchangeId(exchangeId);
|
||||||
|
if("46".equals(exchangeId)){
|
||||||
|
stock.setStockType("NSE");
|
||||||
|
}
|
||||||
|
stock.setStockName(name);
|
||||||
|
stock.setStockCode(code);
|
||||||
|
stock.setStockGid(code);
|
||||||
|
stock.setIsLock(0);
|
||||||
|
stock.setIsShow(0);
|
||||||
|
stock.setAddTime(new Date());
|
||||||
|
stock.setStockState(0);
|
||||||
|
list.add(stock);
|
||||||
|
}
|
||||||
|
currentTotal += pageSize;
|
||||||
|
if((total - currentTotal) < pageSize ){
|
||||||
|
pageSize = total - currentTotal;
|
||||||
|
}
|
||||||
|
if(total <= currentTotal){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pageNum ++;
|
||||||
|
}
|
||||||
|
if(CollectionUtils.isNotEmpty(list)) {
|
||||||
|
StockRepository.of().saveAll(list);
|
||||||
|
}
|
||||||
|
int count = list.size();
|
||||||
|
log.info("syncAFutureStockList执行, 受影响数{}, 耗时:{}毫秒", count, stopwatch.elapsed(TimeUnit.MILLISECONDS));
|
||||||
|
log.info("同步股票数据结束。。。。");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("同步股票数据异常,异常信息{}。。。。",e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ import cn.stock.market.domain.basic.service.SiteNewsService;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
//@Component
|
||||||
public class JobBoot {
|
public class JobBoot {
|
||||||
/**
|
/**
|
||||||
* cronExpression表达式定义:
|
* cronExpression表达式定义:
|
||||||
|
|||||||
351
src/main/java/cn/stock/market/infrastructure/job/Scraper.java
Normal file
351
src/main/java/cn/stock/market/infrastructure/job/Scraper.java
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
package cn.stock.market.infrastructure.job;
|
||||||
|
|
||||||
|
import cn.stock.market.domain.basic.entity.BtodayStock;
|
||||||
|
import cn.stock.market.domain.basic.entity.StockIpo;
|
||||||
|
import cn.stock.market.domain.basic.repository.BtodayStockRepository;
|
||||||
|
import cn.stock.market.domain.basic.repository.StockIpoRepository;
|
||||||
|
import cn.stock.market.dto.StockIpoDTO;
|
||||||
|
import cn.stock.market.infrastructure.db.po.QStockIpoPO;
|
||||||
|
import cn.stock.market.infrastructure.db.po.StockIpoPO;
|
||||||
|
import cn.stock.market.infrastructure.db.repo.BtodayStockRepo;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.http.HttpRequest;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
public class Scraper {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BtodayStockRepository btodayStockRepo;
|
||||||
|
@Autowired
|
||||||
|
private StockIpoRepository stockIpoRepository;
|
||||||
|
|
||||||
|
private final ExecutorService executorService = Executors.newFixedThreadPool(5);
|
||||||
|
|
||||||
|
|
||||||
|
@Scheduled(cron = "0 0 1 */2 * ?")
|
||||||
|
@RequestMapping("/testScraperGetBusinessToday")
|
||||||
|
public void schedule() {
|
||||||
|
String BASE_URL = "https://akm-img-a-in.tosshub.com/businesstoday/resource/market-widgets/prod/company-master-23-01-2023.json";
|
||||||
|
String company_name = "Bhagawati Oxygen Ltd";
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 获取 JSON 数据
|
||||||
|
String json_data = scrapePage(BASE_URL);
|
||||||
|
// 解析 JSON 数据
|
||||||
|
if (json_data != null) {
|
||||||
|
List<BtodayStock> all = btodayStockRepo.findAll();
|
||||||
|
Map<String, String> sefUrlList = getSefUrl(json_data, company_name);
|
||||||
|
sefUrlList = sefUrlList.entrySet().stream()
|
||||||
|
.filter(entry -> all.stream().noneMatch(stock -> stock.getStockName().equals(entry.getKey())))
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
|
|
||||||
|
// 将 Map 中的数据分成 5 个线程处理
|
||||||
|
int batchSize = sefUrlList.size() / 5; // 假设分成 5 个线程
|
||||||
|
int threadCount = 5;
|
||||||
|
CompletableFuture<Void>[] futures = new CompletableFuture[threadCount];
|
||||||
|
for (int i = 0; i < threadCount; i++) {
|
||||||
|
int startIndex = i * batchSize;
|
||||||
|
int endIndex = (i == threadCount - 1) ? sefUrlList.size() : (i + 1) * batchSize;
|
||||||
|
|
||||||
|
Map<String, String> subMap = sefUrlList.entrySet().stream()
|
||||||
|
.skip(startIndex)
|
||||||
|
.limit(endIndex - startIndex)
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
|
|
||||||
|
futures[i] = CompletableFuture.runAsync(() -> processSubMap(subMap), executorService);
|
||||||
|
}
|
||||||
|
// 等待所有异步任务完成
|
||||||
|
CompletableFuture.allOf(futures).get();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("IOException occurred while processing the JSON data", e);
|
||||||
|
}finally {
|
||||||
|
// 关闭线程池
|
||||||
|
executorService.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Scheduled(cron = "0 0 5 * * ?")
|
||||||
|
@RequestMapping("/testScraperGetMoneyControllerNewIPO")
|
||||||
|
public void schedule2() {
|
||||||
|
// 目标 URL
|
||||||
|
String url = "https://www.moneycontrol.com/ipo/open-upcoming-ipos";
|
||||||
|
// 创建 HttpClient 实例
|
||||||
|
HttpClient client = HttpClients.createDefault();
|
||||||
|
// 创建 HttpGet 请求
|
||||||
|
HttpGet request = new HttpGet(url);
|
||||||
|
try {
|
||||||
|
// 执行请求
|
||||||
|
HttpResponse response = client.execute(request);
|
||||||
|
|
||||||
|
// 检查请求是否成功
|
||||||
|
if (response.getStatusLine().getStatusCode() == 200) {
|
||||||
|
// 获取响应体
|
||||||
|
String responseBody = EntityUtils.toString(response.getEntity());
|
||||||
|
|
||||||
|
// 使用 Jsoup 解析 HTML
|
||||||
|
Document doc = Jsoup.parse(responseBody);
|
||||||
|
|
||||||
|
// 找到包含 JSON 数据的 <script> 标签
|
||||||
|
Element scriptTag = doc.selectFirst("script#__NEXT_DATA__");
|
||||||
|
|
||||||
|
if (scriptTag != null) {
|
||||||
|
// 获取 JSON 数据
|
||||||
|
String jsonDataStr = scriptTag.html();
|
||||||
|
|
||||||
|
// 将 JSON 字符串解析为 Java JSONObject
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(jsonDataStr);
|
||||||
|
log.info(jsonObject.toJSONString());
|
||||||
|
|
||||||
|
JSONObject pageProps = jsonObject.getJSONObject("props").getJSONObject("pageProps");
|
||||||
|
JSONObject ipoTableData = pageProps.getJSONObject("ipoTableData");
|
||||||
|
|
||||||
|
// 解析 openData 和 upcomingData
|
||||||
|
JSONArray openData = ipoTableData.getJSONArray("openData");
|
||||||
|
JSONArray upcomingData = ipoTableData.getJSONArray("upcomingData");
|
||||||
|
List<StockIpo> listStockIpoList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < openData.size(); i++) {
|
||||||
|
JSONObject entry = openData.getJSONObject(i);
|
||||||
|
StockIpo stockIpo = new StockIpo();
|
||||||
|
stockIpo.setStockCode(entry.getString("sc_id"));
|
||||||
|
stockIpo.setStockName(entry.getString("company_name"));
|
||||||
|
stockIpo.setStockPrice(entry.getBigDecimal("issue_price"));
|
||||||
|
stockIpo.setSubscriptionDate(convertStringToTimestamp(entry.getString("open_date")));
|
||||||
|
stockIpo.setListingDate(convertStringToTimestamp(entry.getString("listing_date")));
|
||||||
|
stockIpo.setTotalNumber(entry.getInteger("lot_size"));
|
||||||
|
stockIpo.setApply(entry.getString("total_subs"));
|
||||||
|
stockIpo.setCreateDate(new Date());
|
||||||
|
stockIpo.setUpdateDate(new Date());
|
||||||
|
stockIpo.setSourceType("2");
|
||||||
|
listStockIpoList.add(stockIpo);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < upcomingData.size(); i++) {
|
||||||
|
JSONObject entry = upcomingData.getJSONObject(i);
|
||||||
|
StockIpo stockIpo = new StockIpo();
|
||||||
|
stockIpo.setStockCode(entry.getString("sc_id"));
|
||||||
|
stockIpo.setStockName(entry.getString("company_name"));
|
||||||
|
stockIpo.setStockPrice(entry.getBigDecimal("issue_price"));
|
||||||
|
stockIpo.setSubscriptionDate(convertStringToTimestamp(entry.getString("open_date")));
|
||||||
|
stockIpo.setListingDate(convertStringToTimestamp(entry.getString("listing_date")));
|
||||||
|
stockIpo.setTotalNumber(entry.getInteger("lot_size"));
|
||||||
|
stockIpo.setApply(entry.getString("total_subs"));
|
||||||
|
stockIpo.setCreateDate(new Date());
|
||||||
|
stockIpo.setUpdateDate(new Date());
|
||||||
|
stockIpo.setSourceType("3");
|
||||||
|
listStockIpoList.add(stockIpo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// stockIpoRepository.saveAll(listStockIpoList);
|
||||||
|
|
||||||
|
List<String> nameList = Lists.transform(listStockIpoList, StockIpo::getStockName);
|
||||||
|
List<StockIpo> existStockIpoList = stockIpoRepository.findAll(QStockIpoPO.stockIpoPO.stockName.in(nameList));
|
||||||
|
List<String> existingStockNames = existStockIpoList.stream()
|
||||||
|
.map(StockIpo::getStockName)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
listStockIpoList = listStockIpoList.stream()
|
||||||
|
.filter(stockIpos -> !existingStockNames.contains(stockIpos.getStockName()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
//保存全部的新股
|
||||||
|
stockIpoRepository.saveAll(listStockIpoList);
|
||||||
|
|
||||||
|
// 输出整个 JSON 数据
|
||||||
|
} else {
|
||||||
|
log.info("未找到包含 JSON 数据的 <script> 标签");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.info("HTTP请求失败,状态码:" + response.getStatusLine().getStatusCode());
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("获取新股接口发生异常",e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Timestamp convertStringToTimestamp(String dateString) {
|
||||||
|
// 实现将字符串转换为 Timestamp 的逻辑
|
||||||
|
// 这里假设 dateString 是合法的日期时间字符串
|
||||||
|
if(StringUtils.isNotBlank(dateString)){
|
||||||
|
return Timestamp.valueOf(dateString + " 00:00:00");
|
||||||
|
}else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void processSubMap(Map<String, String> sefUrlList) {
|
||||||
|
for (Map.Entry<String, String> entry : sefUrlList.entrySet()) {
|
||||||
|
String companyName = entry.getKey();
|
||||||
|
String url = entry.getValue();
|
||||||
|
|
||||||
|
// 获取网页 HTML
|
||||||
|
String webHtml = null;
|
||||||
|
int maxRetries = 5;
|
||||||
|
int retryCount = 0;
|
||||||
|
|
||||||
|
while (retryCount < maxRetries) {
|
||||||
|
try {
|
||||||
|
webHtml = getWebsiteHtml(url);
|
||||||
|
break; // If successful, break out of the loop
|
||||||
|
} catch (java.net.SocketTimeoutException e) {
|
||||||
|
log.warn("Socket timeout exception occurred. Retrying... (" + (retryCount + 1) + "/" + maxRetries + ")");
|
||||||
|
retryCount++;
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("IOException occurred. Retrying... (" + (retryCount + 1) + "/" + maxRetries + ")");
|
||||||
|
retryCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (webHtml != null) {
|
||||||
|
// 获取公司代码
|
||||||
|
String coCode = getCompanyCode(webHtml);
|
||||||
|
|
||||||
|
if (coCode != null) {
|
||||||
|
// 获取股票市场列表
|
||||||
|
String[] stockMarketList = getStockMarket(webHtml);
|
||||||
|
|
||||||
|
for (String stockMarket : stockMarketList) {
|
||||||
|
// 获取网页详情
|
||||||
|
String detailUrl = buildWebDetailUrl(coCode, stockMarket);
|
||||||
|
// String webInfo = getWebDetail(detailUrl);
|
||||||
|
log.info("Stock detail coCode:{}, stockMarket:{}: ,detailUrl:{}", coCode, stockMarket,detailUrl);
|
||||||
|
|
||||||
|
BtodayStock btodayStock = new BtodayStock();
|
||||||
|
btodayStock.setStockName(companyName);
|
||||||
|
btodayStock.setCoCode(coCode);
|
||||||
|
btodayStock.setStockType(stockMarket);
|
||||||
|
btodayStock.setSelfUrl(url);
|
||||||
|
btodayStock.setUrl(detailUrl);
|
||||||
|
btodayStock.setLastUpdateTime(new Date());
|
||||||
|
btodayStockRepo.save(btodayStock);
|
||||||
|
|
||||||
|
/* if (webInfo != null) {
|
||||||
|
log.info("Stock detail for {} in {}: {}", coCode, stockMarket, webInfo);
|
||||||
|
log.info(webInfo);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log.warn("Failed to retrieve web detail information.");
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("Failed to retrieve company code.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("Failed to retrieve website HTML.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String buildWebDetailUrl(String coCode, String stockMarket) {
|
||||||
|
return "https://marketapi.intoday.in/widget/stockdetail/pullview?co_code=" + coCode + "&exchange=" + stockMarket;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String scrapePage(String url) throws IOException {
|
||||||
|
log.info("Scraping " + url + "...");
|
||||||
|
return Jsoup.connect(url).ignoreContentType(true).execute().body();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, String> getSefUrl(String json_data, String companyName) {
|
||||||
|
Map<String, String> sefUrls = new HashMap<>();
|
||||||
|
|
||||||
|
// 在这里放入你的模糊匹配逻辑
|
||||||
|
JSONArray jsonArray = JSONArray.parseArray(json_data);
|
||||||
|
|
||||||
|
for (int i = 0; i < jsonArray.size(); i++) {
|
||||||
|
JSONObject item = jsonArray.getJSONObject(i);
|
||||||
|
|
||||||
|
// 在这里放入你的模糊匹配逻辑
|
||||||
|
String sef_url = item.getString("sef_url");
|
||||||
|
String company_name = item.getString("companyname");
|
||||||
|
|
||||||
|
if (company_name != null && sef_url != null/* && company_name.equals(companyName)*/) {
|
||||||
|
sefUrls.put(company_name, sef_url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sefUrls;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getWebsiteHtml(String url) throws IOException {
|
||||||
|
log.info("Getting website URL: " + url + "...");
|
||||||
|
return Jsoup.connect(url).timeout(10000).get().html();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getCompanyCode(String text) {
|
||||||
|
Document document = Jsoup.parse(text);
|
||||||
|
Element companyCodeInput = document.selectFirst("input[id=comapnyCodeId]");
|
||||||
|
|
||||||
|
if (companyCodeInput != null) {
|
||||||
|
return companyCodeInput.attr("value");
|
||||||
|
} else {
|
||||||
|
log.warn("No <input> with id=\"companyCodeId\" found on the website.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String[] getStockMarket(String text) {
|
||||||
|
Document document = Jsoup.parse(text);
|
||||||
|
Elements ulElements = document.select("ul[class*=wdg_rhs_hdr_ul]");
|
||||||
|
|
||||||
|
List<String> stockMarketList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Element ulElement : ulElements) {
|
||||||
|
Elements liElements = ulElement.select("li");
|
||||||
|
for (Element liElement : liElements) {
|
||||||
|
Element spanElement = liElement.selectFirst("span[class=wdg_rhs_hdr_lnk]");
|
||||||
|
if (spanElement != null) {
|
||||||
|
stockMarketList.add(spanElement.text());
|
||||||
|
} else {
|
||||||
|
log.warn("Invalid status code while scraping.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stockMarketList.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getWebDetail(String url) throws IOException {
|
||||||
|
log.info("Getting web detail URL: " + url + "...");
|
||||||
|
return Jsoup.connect(url).ignoreContentType(true).execute().body();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package cn.stock.market.infrastructure.job;
|
package cn.stock.market.infrastructure.job;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -10,6 +11,11 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
import cn.stock.market.domain.basic.entity.SiteNews;
|
||||||
|
import cn.stock.market.domain.basic.repository.SiteNewsRepository;
|
||||||
|
import cn.stock.market.domain.basic.service.SiteNewsService;
|
||||||
|
import cn.stock.market.domain.basic.service.StockService;
|
||||||
|
import cn.stock.market.infrastructure.db.po.QSiteNewsPO;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
@@ -37,10 +43,12 @@ import cn.stock.market.web.config.Config;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
//@Component
|
||||||
public class StockTask {
|
public class StockTask {
|
||||||
@Autowired RealtimeRepository realtimeRepository;
|
@Autowired RealtimeRepository realtimeRepository;
|
||||||
@Autowired StockRepository stockRepository;
|
@Autowired StockRepository stockRepository;
|
||||||
|
@Autowired StockService stockService;
|
||||||
|
@Autowired SiteNewsRepository newsRepository;
|
||||||
ThreadPoolExecutor pool;
|
ThreadPoolExecutor pool;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
@@ -202,7 +210,7 @@ public class StockTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*同步股票列表*/
|
/*同步股票列表*/
|
||||||
@Scheduled(cron = "0 5 6 * * ?")
|
// @Scheduled(cron = "0 5 6 * * ?")
|
||||||
public void syncBjsStockList() {
|
public void syncBjsStockList() {
|
||||||
MdcUtil.setTraceIdIfAbsent();
|
MdcUtil.setTraceIdIfAbsent();
|
||||||
boolean flag = true;
|
boolean flag = true;
|
||||||
@@ -339,4 +347,32 @@ public class StockTask {
|
|||||||
//
|
//
|
||||||
// log.info("syncAStockList执行, 受影响数{}, 耗时:{}毫秒", count, stopwatch.elapsed(TimeUnit.MILLISECONDS));
|
// log.info("syncAStockList执行, 受影响数{}, 耗时:{}毫秒", count, stopwatch.elapsed(TimeUnit.MILLISECONDS));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
/*新闻接口*/
|
||||||
|
@Scheduled(cron = "0 0 1 * * ?")
|
||||||
|
public void saveStockNews() {
|
||||||
|
String news = stockService.getNews();
|
||||||
|
List<String> newsList = Arrays.asList(news.split("<a href="));
|
||||||
|
newsList = newsList.subList(1, newsList.size());
|
||||||
|
newsList.forEach( n -> {
|
||||||
|
String contentUrl = n.substring(1, n.indexOf("class=\"img-smllnews\"") - 2);
|
||||||
|
String id = contentUrl.substring(contentUrl.lastIndexOf("-") + 1, contentUrl.lastIndexOf("_"));
|
||||||
|
String imgUrl = n.substring(n.indexOf("img src=") + 9, n.indexOf("?"));
|
||||||
|
String time = n.substring(n.indexOf("Last Updated") + 23, n.indexOf("IST") - 9);
|
||||||
|
String title = n.substring(n.indexOf("html\">") + 6, n.indexOf("<div class=\"short-video-img\">") - 47);
|
||||||
|
|
||||||
|
SiteNews siteNews = new SiteNews();
|
||||||
|
siteNews.setAddTime(new Date());
|
||||||
|
siteNews.setSourceId(id);
|
||||||
|
siteNews.setTitle(title);
|
||||||
|
siteNews.setDescription(time);
|
||||||
|
siteNews.setImgurl(imgUrl);
|
||||||
|
siteNews.setContent(stockService.getNewsInfo(contentUrl));
|
||||||
|
List<SiteNews> list = newsRepository.findAll(QSiteNewsPO.siteNewsPO.sourceId.eq(id));
|
||||||
|
if (list.size() == 0) {
|
||||||
|
newsRepository.save(siteNews);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,77 +1,77 @@
|
|||||||
package cn.stock.market.infrastructure.stockdb.config;
|
//package cn.stock.market.infrastructure.stockdb.config;
|
||||||
|
//
|
||||||
import java.util.Map;
|
//import java.util.Map;
|
||||||
|
//
|
||||||
import javax.persistence.EntityManagerFactory;
|
//import javax.persistence.EntityManagerFactory;
|
||||||
import javax.sql.DataSource;
|
//import javax.sql.DataSource;
|
||||||
|
//
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
//import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
//import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
|
//import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
|
||||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
|
//import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
|
||||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
|
//import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
//import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
|
//import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
|
||||||
import org.springframework.context.annotation.Bean;
|
//import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
//import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.Configuration;
|
//import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
//import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
//import org.springframework.orm.jpa.JpaTransactionManager;
|
||||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
//import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
//import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
//
|
||||||
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
|
//import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
|
||||||
import com.rp.spring.jpa.GenericJpaRepositoryFactoryBean;
|
//import com.rp.spring.jpa.GenericJpaRepositoryFactoryBean;
|
||||||
import com.rp.spring.jpa.GenericJpaRepositoryImpl;
|
//import com.rp.spring.jpa.GenericJpaRepositoryImpl;
|
||||||
|
//
|
||||||
/**
|
///**
|
||||||
*
|
// *
|
||||||
* title: ErpDatasourceConfig.java
|
// * title: ErpDatasourceConfig.java
|
||||||
* ERP 数据源设置
|
// * ERP 数据源设置
|
||||||
*
|
// *
|
||||||
* @author rplees
|
// * @author rplees
|
||||||
* @email rplees.i.ly@gmail.com
|
// * @email rplees.i.ly@gmail.com
|
||||||
* @version 1.0
|
// * @version 1.0
|
||||||
* @created Jan 5, 2018 11:44:49 AM
|
// * @created Jan 5, 2018 11:44:49 AM
|
||||||
*/
|
// */
|
||||||
@Configuration
|
//@Configuration
|
||||||
@ComponentScan({ "cn.stock.market.infrastructure.stockdb.po", "cn.stock.market.infrastructure.stockdb.repo"})
|
//@ComponentScan({ "cn.stock.market.infrastructure.stockdb.po", "cn.stock.market.infrastructure.stockdb.repo"})
|
||||||
@EnableJpaRepositories(
|
//@EnableJpaRepositories(
|
||||||
repositoryBaseClass = GenericJpaRepositoryImpl.class,
|
// repositoryBaseClass = GenericJpaRepositoryImpl.class,
|
||||||
repositoryFactoryBeanClass = GenericJpaRepositoryFactoryBean.class,
|
// repositoryFactoryBeanClass = GenericJpaRepositoryFactoryBean.class,
|
||||||
entityManagerFactoryRef = "stockEntityManagerFactory",
|
// entityManagerFactoryRef = "stockEntityManagerFactory",
|
||||||
transactionManagerRef = "stockTransactionManager",
|
// transactionManagerRef = "stockTransactionManager",
|
||||||
basePackages = { "cn.stock.market.infrastructure.stockdb.po", "cn.stock.market.infrastructure.stockdb.repo"})
|
// basePackages = { "cn.stock.market.infrastructure.stockdb.po", "cn.stock.market.infrastructure.stockdb.repo"})
|
||||||
public class StockDatasourceConfig {
|
//public class StockDatasourceConfig {
|
||||||
@Autowired HibernateProperties hibernateProperties;
|
// @Autowired HibernateProperties hibernateProperties;
|
||||||
@Bean(name = "stockDataSource")
|
// @Bean(name = "stockDataSource")
|
||||||
@ConfigurationProperties(prefix="spring.datasource.stock")
|
// @ConfigurationProperties(prefix="spring.datasource.stock")
|
||||||
public DataSource dataSource() {
|
// public DataSource dataSource() {
|
||||||
return DruidDataSourceBuilder.create().build();
|
// return DruidDataSourceBuilder.create().build();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Bean(name = "stockJpaProperties")
|
// @Bean(name = "stockJpaProperties")
|
||||||
@ConfigurationProperties(prefix = "spring.jpa")
|
// @ConfigurationProperties(prefix = "spring.jpa")
|
||||||
public JpaProperties jpaProperties() {
|
// public JpaProperties jpaProperties() {
|
||||||
return new JpaProperties();
|
// return new JpaProperties();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Bean(name = "stockEntityManagerFactory")
|
// @Bean(name = "stockEntityManagerFactory")
|
||||||
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
|
// public LocalContainerEntityManagerFactoryBean entityManagerFactory(
|
||||||
EntityManagerFactoryBuilder builder,
|
// EntityManagerFactoryBuilder builder,
|
||||||
@Qualifier("stockJpaProperties") JpaProperties jpaProperties,
|
// @Qualifier("stockJpaProperties") JpaProperties jpaProperties,
|
||||||
@Qualifier("stockDataSource") DataSource dataSource) {
|
// @Qualifier("stockDataSource") DataSource dataSource) {
|
||||||
Map<String, Object> properties = hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
|
// Map<String, Object> properties = hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
|
||||||
return builder
|
// return builder
|
||||||
.dataSource(dataSource)
|
// .dataSource(dataSource)
|
||||||
.properties(properties)
|
// .properties(properties)
|
||||||
.packages("cn.stock.market.infrastructure.stockdb.po")
|
// .packages("cn.stock.market.infrastructure.stockdb.po")
|
||||||
.persistenceUnit("stock")
|
// .persistenceUnit("stock")
|
||||||
.build();
|
// .build();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Bean(name = "stockTransactionManager")
|
// @Bean(name = "stockTransactionManager")
|
||||||
public PlatformTransactionManager transactionManager(@Qualifier("stockEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
|
// public PlatformTransactionManager transactionManager(@Qualifier("stockEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
|
||||||
return new JpaTransactionManager(entityManagerFactory);
|
// return new JpaTransactionManager(entityManagerFactory);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
119
src/main/java/cn/stock/market/utils/AESUtil.java
Normal file
119
src/main/java/cn/stock/market/utils/AESUtil.java
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
package cn.stock.market.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.codec.Base64;
|
||||||
|
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES工具类
|
||||||
|
* @author lxiaol
|
||||||
|
* @date 2021年12月23日 13:58
|
||||||
|
*/
|
||||||
|
public class AESUtil {
|
||||||
|
/**
|
||||||
|
* 128位的AESkey
|
||||||
|
*/
|
||||||
|
private static final byte[] AES_KEY = PropertiesUtil.getProperty("aes.key","Jy112211Kj112211").getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES解密
|
||||||
|
*
|
||||||
|
* @param data 待解密内容
|
||||||
|
* @return 字节数组
|
||||||
|
*/
|
||||||
|
public static byte[] decrypt(byte[] data) throws InvalidKeyException, NoSuchAlgorithmException,
|
||||||
|
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
|
||||||
|
Cipher cipher = getCipher(AES_KEY, Cipher.DECRYPT_MODE);
|
||||||
|
return cipher.doFinal(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES 加密操作
|
||||||
|
*
|
||||||
|
* @param data 待加密内容
|
||||||
|
* @return 字节数组
|
||||||
|
*/
|
||||||
|
public static byte[] encrypt(byte[] data) throws InvalidKeyException, NoSuchAlgorithmException,
|
||||||
|
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
|
||||||
|
Cipher cipher = getCipher(AES_KEY, Cipher.ENCRYPT_MODE);
|
||||||
|
return cipher.doFinal(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES 加密操作
|
||||||
|
*
|
||||||
|
* @param text 待加密内容
|
||||||
|
* @return Base64转码后的加密数据
|
||||||
|
*/
|
||||||
|
public static String encrypt(String text) {
|
||||||
|
byte[] byteContent = text.getBytes(StandardCharsets.UTF_8);
|
||||||
|
try {
|
||||||
|
byte[] result = encrypt(byteContent);// 加密
|
||||||
|
return Base64.encode(result);//通过Base64转码返回
|
||||||
|
} catch (Exception e) {
|
||||||
|
// log.info("Error message: {}", e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES 解密操作
|
||||||
|
*
|
||||||
|
* @param text
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String decrypt(String text) {
|
||||||
|
byte[] bytes = Base64.decode(text);
|
||||||
|
try {
|
||||||
|
byte[] result = decrypt(bytes);
|
||||||
|
return new String(result, StandardCharsets.UTF_8);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// log.info("Error message: {}", e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取加密器
|
||||||
|
* @param key
|
||||||
|
* @param model
|
||||||
|
* @return
|
||||||
|
* @throws NoSuchAlgorithmException
|
||||||
|
* @throws NoSuchPaddingException
|
||||||
|
* @throws InvalidKeyException
|
||||||
|
*/
|
||||||
|
private static Cipher getCipher(byte[] key, int model)
|
||||||
|
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
|
||||||
|
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
||||||
|
cipher.init(model, secretKeySpec);
|
||||||
|
return cipher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String s = "{\n" +
|
||||||
|
" \"mobile\": \"17570717251\",\n" +
|
||||||
|
" \"password\": \"Dd112211\",\n" +
|
||||||
|
" \"platType\": 1,\n" +
|
||||||
|
" \"loginType\": 0,\n" +
|
||||||
|
" \"sourceType\": 1,\n" +
|
||||||
|
" \"equipmentModel\": \"IPHONE\",\n" +
|
||||||
|
" \"version\":1\n" +
|
||||||
|
"}";
|
||||||
|
System.out.println(encrypt(s));
|
||||||
|
System.out.println("Dd112211Ds112211".length());
|
||||||
|
System.out.println(decrypt("Z3aCERCWi+nDUzv67h1/8PqS3CCuCgoj/YRTzkFNa0aNRvagi+wxpj9RsutL7nk2oo65ypyEYbjQXCI8fze8V4kMoVAb2rmoXqO3/DudVeTtY1J2784eXw+DS1QWZlZeHAHKiBaEwLcYe4XcsU9tpQIu6fE6cuSPGNetwN3C7qg6/78t4yUjCf49WW7u0/kErfgsSjMajGaVV/LOg74d2RlUcVBIIq6Us8JW3fFWPQA="));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.github.pagehelper.StringUtil;
|
import com.github.pagehelper.StringUtil;
|
||||||
|
import okhttp3.*;
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
import org.apache.http.client.ClientProtocolException;
|
import org.apache.http.client.ClientProtocolException;
|
||||||
@@ -73,6 +74,29 @@ public class HttpClientRequest {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
public static String http2Get(String url) throws IOException {
|
||||||
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
|
.protocols(java.util.Arrays.asList(Protocol.HTTP_2, Protocol.HTTP_1_1))
|
||||||
|
.build();
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(url) // 替换为你要请求的URL
|
||||||
|
.addHeader("Cf-Ray", "82e0bc56ccabfabe-SJC")
|
||||||
|
.addHeader("X-Correlation-Id", "a3120e84-ab22-4a03-81bc-270bbb373c1f")
|
||||||
|
.addHeader("Server", "cloudflare")
|
||||||
|
.addHeader("Cf-Cache-Status", "DYNAMIC")
|
||||||
|
.addHeader("Alt-Svc", "h3=\":443\"; ma=86400")
|
||||||
|
.addHeader("Date", "Thu, 30 Nov 2023 05:36:57 GMT")
|
||||||
|
.addHeader("Content-Encoding", "br")
|
||||||
|
.addHeader("Content-Type", "application/json")
|
||||||
|
.addHeader("X-Envoy-Upstream-Service", "434")
|
||||||
|
.addHeader("Via", "1.1 google")
|
||||||
|
.addHeader("X-App-Version", "1.45.3")
|
||||||
|
.addHeader("Cf-Cache-Status", "DYNAMIC")
|
||||||
|
.build();
|
||||||
|
Call call = client.newCall(request);
|
||||||
|
Response response = call.execute();
|
||||||
|
return response.body().string();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 获取cooike
|
* 获取cooike
|
||||||
* @param url
|
* @param url
|
||||||
@@ -187,4 +211,10 @@ public class HttpClientRequest {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
String url = "https://marketapi.intoday.in/widget/topgainer/view?exchange=nse";
|
||||||
|
String str = doGet(url);
|
||||||
|
System.out.println(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
60
src/main/java/cn/stock/market/utils/SSLSocketClientUtil.java
Normal file
60
src/main/java/cn/stock/market/utils/SSLSocketClientUtil.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package cn.stock.market.utils;
|
||||||
|
|
||||||
|
import java.security.KeyManagementException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
import javax.net.ssl.HostnameVerifier;
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLSession;
|
||||||
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
|
||||||
|
public class SSLSocketClientUtil {
|
||||||
|
|
||||||
|
public static SSLSocketFactory getSocketFactory(TrustManager manager) {
|
||||||
|
SSLSocketFactory socketFactory = null;
|
||||||
|
try {
|
||||||
|
SSLContext sslContext = SSLContext.getInstance("SSL");
|
||||||
|
sslContext.init(null, new TrustManager[]{manager}, new SecureRandom());
|
||||||
|
socketFactory = sslContext.getSocketFactory();
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (KeyManagementException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return socketFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static X509TrustManager getX509TrustManager() {
|
||||||
|
return new X509TrustManager() {
|
||||||
|
@Override
|
||||||
|
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return new X509Certificate[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HostnameVerifier getHostnameVerifier() {
|
||||||
|
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
|
||||||
|
@Override
|
||||||
|
public boolean verify(String s, SSLSession sslSession) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return hostnameVerifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
53
src/main/java/cn/stock/market/utils/StreamUtil.java
Normal file
53
src/main/java/cn/stock/market/utils/StreamUtil.java
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package cn.stock.market.utils;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流工具类
|
||||||
|
* @author zhouyl
|
||||||
|
* @date 2023年12月09日 15:11
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class StreamUtil {
|
||||||
|
private static final Integer BUFFER_SIZE = 128;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将requestBody的数据转成字符串
|
||||||
|
*
|
||||||
|
* @param inputStream
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getBodyString(InputStream inputStream) {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
BufferedReader bufferedReader = null;
|
||||||
|
try {
|
||||||
|
if (Objects.nonNull(inputStream)) {
|
||||||
|
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||||
|
int bytesRead;
|
||||||
|
char[] charBuffer = new char[BUFFER_SIZE];
|
||||||
|
while ((bytesRead = bufferedReader.read(charBuffer)) != -1) {
|
||||||
|
stringBuilder.append(charBuffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("get body fail,{}", e.getMessage());
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
if (bufferedReader != null) {
|
||||||
|
try {
|
||||||
|
bufferedReader.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,18 @@
|
|||||||
package cn.stock.market.utils;
|
package cn.stock.market.utils;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.time.DayOfWeek;
|
import java.time.DayOfWeek;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
|
|
||||||
@@ -394,13 +396,55 @@ public final class Utils {
|
|||||||
return returnStr;
|
return returnStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//读取txt文本内容
|
||||||
|
public static String readTxt() {
|
||||||
|
FileReader fr = null;
|
||||||
|
BufferedReader br = null;
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
try {
|
||||||
|
String file = Objects.requireNonNull(Utils.class.getResource("/2036.txt")).getPath();
|
||||||
|
fr = new FileReader(file);
|
||||||
|
br = new BufferedReader(fr);
|
||||||
|
|
||||||
|
String line = "";
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
buffer.append(line);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
if (br != null) {
|
||||||
|
try {
|
||||||
|
br.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fr != null) {
|
||||||
|
try {
|
||||||
|
fr.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.println(getFirstLetter("0L神鼎ds飞#@#丹砂"));
|
// System.out.println(getFirstLetter("0L神鼎ds飞#@#丹砂"));
|
||||||
System.out.println(getFirstLetter("0L神鼎ds飞#@#丹砂"));
|
// System.out.println(getFirstLetter("0L神鼎ds飞#@#丹砂"));
|
||||||
System.out.println(highVersion("1.0.8", "1.0.9"));
|
// System.out.println(highVersion("1.0.8", "1.0.9"));
|
||||||
System.out.println(highVersion("1.0.9", "1.0.10"));
|
// System.out.println(highVersion("1.0.9", "1.0.10"));
|
||||||
System.out.println(highVersion("1.0.10", "1.0.11"));
|
// System.out.println(highVersion("1.0.10", "1.0.11"));
|
||||||
System.out.println(highVersion("1.0.10", "1.0.9"));
|
// System.out.println(highVersion("1.0.10", "1.0.9"));
|
||||||
|
String str = readTxt();
|
||||||
|
JSONArray jsonArray = JSON.parseArray(str);
|
||||||
|
System.out.println(Arrays.toString(jsonArray.toArray()));
|
||||||
|
// for (Object object : jsonArray){
|
||||||
|
// object.
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
175
src/main/java/cn/stock/market/web/BTodayStockController.java
Normal file
175
src/main/java/cn/stock/market/web/BTodayStockController.java
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
package cn.stock.market.web;
|
||||||
|
|
||||||
|
import cn.stock.market.domain.basic.entity.BtodayStock;
|
||||||
|
import cn.stock.market.domain.basic.service.BtodayStockService;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
|
import io.swagger.annotations.ApiImplicitParams;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import io.swagger.annotations.ApiResponse;
|
||||||
|
import io.swagger.annotations.ApiResponses;
|
||||||
|
//import net.sf.json.JSONArray;
|
||||||
|
//import net.sf.json.JSONObject;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@Api(tags="bToday获取详情接口")
|
||||||
|
public class BTodayStockController {
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
@Autowired
|
||||||
|
private BtodayStockService btodayStockService;
|
||||||
|
|
||||||
|
@GetMapping("/api/bToday/kLine")
|
||||||
|
@ApiOperation(value = "股票详情K线图",httpMethod = "GET")
|
||||||
|
@ApiImplicitParams({
|
||||||
|
@ApiImplicitParam(name="exchange",value = "BSE或者NSE"),
|
||||||
|
@ApiImplicitParam(name="co_code",value = "BToday的coCode值"),
|
||||||
|
@ApiImplicitParam(name="format",value = "S(1D的时候传S),H(5D的时候传H),H(3M的时候传H),H(1Y的时候传H),H(5Y的时候传H),H(10Y的时候传H)"),
|
||||||
|
@ApiImplicitParam(name="durationtype",value = "D(1D的时候传D),D(5D的时候传D),M(3M的时候传M),Y(1Y的时候传Y),Y(5Y的时候传Y),Y(10Y的时候传Y)"),
|
||||||
|
@ApiImplicitParam(name="duration",value = "1(1D的时候传1),5(5D的时候传5),3(3M的时候传3),1(1Y的时候传1),5(5Y的时候传5),10(10Y的时候传10)"),
|
||||||
|
})
|
||||||
|
public JSONArray getPriceChartCompanyPullView(
|
||||||
|
@RequestParam(value = "exchange") String exchange,
|
||||||
|
@RequestParam(value = "co_code") String coCode,
|
||||||
|
@RequestParam(value = "format") String format,
|
||||||
|
@RequestParam(value = "durationtype") String durationType,
|
||||||
|
@RequestParam(value = "duration") String duration) {
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(exchange) || StringUtils.isBlank(coCode) || StringUtils.isBlank(format) || StringUtils.isBlank(durationType) || StringUtils.isBlank(duration)) {
|
||||||
|
return new JSONArray();
|
||||||
|
}
|
||||||
|
// 构建请求URL
|
||||||
|
String apiUrl = buildApiUrl(exchange, coCode, format, durationType, duration);
|
||||||
|
|
||||||
|
// 发起REST请求并获取响应数据
|
||||||
|
Map<String, Object> response = restTemplate.getForObject(apiUrl, Map.class);
|
||||||
|
List<Map<String, Object>> data = (List<Map<String, Object>>) response.get("data");
|
||||||
|
|
||||||
|
// 转换为StockData列表
|
||||||
|
JSONArray jsonArray = new JSONArray();
|
||||||
|
data.forEach(item -> {
|
||||||
|
String updateDate = (String) item.get("upd_date");
|
||||||
|
BigDecimal price = new BigDecimal(String.valueOf(item.get("price")));
|
||||||
|
|
||||||
|
// 创建JSONObject并放入数据
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("updateDate", updateDate);
|
||||||
|
jsonObject.put("price", price);
|
||||||
|
|
||||||
|
jsonArray.add(jsonObject);
|
||||||
|
});
|
||||||
|
return jsonArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ApiOperation(value = "股票详情信息",httpMethod = "GET")
|
||||||
|
@ApiImplicitParams({
|
||||||
|
@ApiImplicitParam(name="exchange",value = "BSE或者NSE"),
|
||||||
|
@ApiImplicitParam(name="co_code",value = "coCode值"),
|
||||||
|
})
|
||||||
|
@ApiResponses(value = {
|
||||||
|
@ApiResponse(code = 200, message = "这个接口返回的 JSON 字段说明如下:\n" +
|
||||||
|
"status_code: 操作状态码,1 表示成功。\n" +
|
||||||
|
"success: 操作是否成功,true 表示成功。\n" +
|
||||||
|
"data: 包含具体数据的部分,是一个数组,包含了以下关于公司 \"Gujarat Fluorochemicals Ltd\" 的信息:\n" +
|
||||||
|
"exchange: 交易所,这里是 NSE(国家股票交易所)。\n" +
|
||||||
|
"sc_code: 股票代码。\n" +
|
||||||
|
"symbol: 股票符号。\n" +
|
||||||
|
"companyname: 公司全名,英文。\n" +
|
||||||
|
"companyshortname: 公司简称,英文。\n" +
|
||||||
|
"companyname_hi: 公司全名,印地文。\n" +
|
||||||
|
"companyshortname_hi: 公司简称,印地文。\n" +
|
||||||
|
"co_code: 公司代码。\n" +
|
||||||
|
"mcap_val: 市值。\n" +
|
||||||
|
"mcaptype: 市值类型,这里是 Mid Cap(中型市值)。\n" +
|
||||||
|
"co_image: 公司图标的 URL。\n" +
|
||||||
|
"sef_url: 公司的链接。\n" +
|
||||||
|
"ros_sef_url: 公司 ROS 链接。\n" +
|
||||||
|
"sectorname: 公司所属行业。\n" +
|
||||||
|
"sc_group: 股票组别。\n" +
|
||||||
|
"upd_time: 最后更新时间。\n" +
|
||||||
|
"cmot_upd_time: CMOT 最后更新时间。\n" +
|
||||||
|
"open_price: 开盘价。\n" +
|
||||||
|
"high_price: 最高价。\n" +
|
||||||
|
"cmot_high_price: CMOT 最高价。\n" +
|
||||||
|
"price: 最新交易价。\n" +
|
||||||
|
"cmot_price: CMOT 最新交易价。\n" +
|
||||||
|
"low_price: 最低价。\n" +
|
||||||
|
"cmot_low_price: CMOT 最低价。\n" +
|
||||||
|
"bbuy_qty: 买入数量。\n" +
|
||||||
|
"bbuy_price: 买入价格。\n" +
|
||||||
|
"bsell_qty: 卖出数量。\n" +
|
||||||
|
"bsell_price: 卖出价格。\n" +
|
||||||
|
"perchg: 当前涨跌幅。\n" +
|
||||||
|
"cmot_perchg: CMOT 涨跌幅。\n" +
|
||||||
|
"pricediff: 当前价格变动。\n" +
|
||||||
|
"cmot_pricediff: CMOT 价格变动。\n" +
|
||||||
|
"vol_traded: 成交量。\n" +
|
||||||
|
"cmot_vol_traded: CMOT 成交量。\n" +
|
||||||
|
"val_traded: 成交额。\n" +
|
||||||
|
"52weekhigh: 52周最高价。\n" +
|
||||||
|
"52weeklow: 52周最低价。\n" +
|
||||||
|
"value: 市值。\n" +
|
||||||
|
"list_Info: 是否已上市。\n" +
|
||||||
|
"h52date: 52周最高价日期。\n" +
|
||||||
|
"l52date: 52周最低价日期。\n" +
|
||||||
|
"b52high_adj: 调整后的 52周最高价。\n" +
|
||||||
|
"b52low_adj: 调整后的 52周最低价。\n" +
|
||||||
|
"isin: ISIN 编号。\n" +
|
||||||
|
"prev_close: 前一交易日收盘价。\n" +
|
||||||
|
"offerqty: 报价数量。\n" +
|
||||||
|
"message: 返回信息,\"Successful\" 表示成功。\n" +
|
||||||
|
"fromredis: 标志是否来自 Redis 缓存,false 表示不是", response = JSONObject.class),
|
||||||
|
|
||||||
|
})
|
||||||
|
@GetMapping("/api/bToday/stockDetail")
|
||||||
|
public com.alibaba.fastjson.JSONObject getPriceChartCompanyPullView(
|
||||||
|
@RequestParam(value = "exchange") String exchange,
|
||||||
|
@RequestParam(value = "co_code") String coCode
|
||||||
|
) {
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(exchange) || StringUtils.isBlank(coCode) ) {
|
||||||
|
return new com.alibaba.fastjson.JSONObject();
|
||||||
|
}
|
||||||
|
BtodayStock btodayStock = btodayStockService.findBtStockByCoCode(coCode,exchange);
|
||||||
|
if(btodayStock == null){
|
||||||
|
return new com.alibaba.fastjson.JSONObject();
|
||||||
|
}
|
||||||
|
// 构建请求URL
|
||||||
|
String apiUrl = buildDetailApiUrl(exchange, coCode);
|
||||||
|
|
||||||
|
String forObject = restTemplate.getForObject(apiUrl, String.class);
|
||||||
|
JSONObject jsonObject = JSON.parseObject(forObject);
|
||||||
|
jsonObject.put("id",btodayStock.getId());
|
||||||
|
return jsonObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildDetailApiUrl(String exchange, String coCode) {
|
||||||
|
String url = String.format("https://marketapi.intoday.in/widget/stockdetail/pullview?co_code=%s&exchange=%s",coCode,exchange);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String buildApiUrl(String exchange, String coCode, String format, String durationType, String duration) {
|
||||||
|
// 构建请求URL的逻辑,根据你的实际情况来
|
||||||
|
// 示例:return "https://your-api-endpoint/bToday/kLine?exchange=" + exchange + "&co_code=" + coCode + "&format=" + format + "&durationtype=" + durationType + "&duration=" + duration;
|
||||||
|
String url = String.format("https://marketapi.intoday.in/widget/pricechart_company/pullview?exchange=%s&co_code=%s&format=%s&durationtype=%s&duration=%s",
|
||||||
|
exchange, coCode, format, durationType, duration);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,17 @@
|
|||||||
package cn.stock.market.web;
|
package cn.stock.market.web;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.io.IOException;
|
||||||
import java.util.Comparator;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import cn.qutaojing.common.PageParam;
|
||||||
|
import cn.stock.market.domain.basic.entity.SiteNews;
|
||||||
|
import cn.stock.market.domain.basic.repository.SiteNewsRepository;
|
||||||
|
import cn.stock.market.infrastructure.db.po.QSiteNewsPO;
|
||||||
|
import cn.stock.market.web.annotations.EncryptFilter;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
import io.swagger.annotations.ApiImplicitParams;
|
import io.swagger.annotations.ApiImplicitParams;
|
||||||
@@ -24,6 +27,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
|
|
||||||
import com.ag.utils.DateUtils;
|
import com.ag.utils.DateUtils;
|
||||||
import com.ag.utils.Jsons;
|
import com.ag.utils.Jsons;
|
||||||
|
import com.ag.utils.param.ParamUtils;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.cache.Cache;
|
import com.google.common.cache.Cache;
|
||||||
@@ -40,6 +44,9 @@ import cn.stock.market.domain.basic.service.StockService;
|
|||||||
import cn.stock.market.dto.model.StockCode;
|
import cn.stock.market.dto.model.StockCode;
|
||||||
import cn.stock.market.dto.model.StockVO;
|
import cn.stock.market.dto.model.StockVO;
|
||||||
import cn.stock.market.infrastructure.api.EastmoneyApi;
|
import cn.stock.market.infrastructure.api.EastmoneyApi;
|
||||||
|
import cn.stock.market.infrastructure.api.investing.IndiaStockVO;
|
||||||
|
import cn.stock.market.infrastructure.api.investing.InvestingApis;
|
||||||
|
import cn.stock.market.infrastructure.api.investing.InvestingInvokerApis;
|
||||||
import cn.stock.market.infrastructure.api.qq.QqStockApi;
|
import cn.stock.market.infrastructure.api.qq.QqStockApi;
|
||||||
import cn.stock.market.infrastructure.api.sina.SinaStockApi;
|
import cn.stock.market.infrastructure.api.sina.SinaStockApi;
|
||||||
import cn.stock.market.utils.RequestCacheUtils;
|
import cn.stock.market.utils.RequestCacheUtils;
|
||||||
@@ -59,6 +66,8 @@ public class StockApiController {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
StockService stockService;
|
StockService stockService;
|
||||||
|
@Autowired
|
||||||
|
SiteNewsRepository newsRepository;
|
||||||
|
|
||||||
@RequestMapping({"getRawSinaStock.do"})
|
@RequestMapping({"getRawSinaStock.do"})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@@ -119,39 +128,80 @@ public class StockApiController {
|
|||||||
@ApiOperation(value = "印度股票个股详情", httpMethod = "GET")
|
@ApiOperation(value = "印度股票个股详情", httpMethod = "GET")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ServerResponse getINDStockInfo(@RequestParam("stockCode") String stockCode) {
|
public ServerResponse getINDStockInfo(@RequestParam("stockCode") String stockCode) {
|
||||||
return this.stockService.getStockInfo(stockCode);
|
ParamUtils.verify("股票代码", stockCode, ParamUtils.STRING_NOT_EMPTY_VERIFY_AND_CONVERT_VALUE);
|
||||||
|
IndiaStockVO market = InvestingApis.of().market(StockCode.of(stockCode));
|
||||||
|
return ServerResponse.createBySuccess(market.toStockVo());
|
||||||
|
}
|
||||||
|
|
||||||
|
//印度股票个股详情
|
||||||
|
@RequestMapping({"getIndiaIndexInfo.do"})
|
||||||
|
@ApiOperation(value = "印度--获取指数详情", httpMethod = "GET")
|
||||||
|
@ResponseBody
|
||||||
|
public ServerResponse getIndiaIndexInfo(@RequestParam("stockCode") String stockCode) {
|
||||||
|
ParamUtils.verify("指数代码", stockCode, ParamUtils.STRING_NOT_EMPTY_VERIFY_AND_CONVERT_VALUE);
|
||||||
|
IndiaStockVO market = InvestingApis.of().market(StockCode.of(stockCode));
|
||||||
|
return ServerResponse.createBySuccess(market.toStockVo());
|
||||||
|
}
|
||||||
|
|
||||||
|
//印度股票列表 英情
|
||||||
|
@RequestMapping({"getINDStockList.do"})
|
||||||
|
@ApiOperation(value = "印度股票列表", httpMethod = "GET")
|
||||||
|
@ResponseBody
|
||||||
|
@EncryptFilter(decryptRequest = false)
|
||||||
|
public ServerResponse getINDStockList(@RequestParam("pageSize") Integer pageSize, @RequestParam("pageNum") Integer pageNum) throws IOException {
|
||||||
|
return ServerResponse.createBySuccess(InvestingInvokerApis.of().__page(pageNum, pageSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping({"getTopINDStockList.do"})
|
||||||
|
@ApiOperation(value = "印度热门股票列表", httpMethod = "GET")
|
||||||
|
@ResponseBody
|
||||||
|
public ServerResponse getTopINDStockList(@RequestParam("pageSize") Integer pageSize, @RequestParam("pageNum") Integer pageNum) throws IOException {
|
||||||
|
return ServerResponse.createBySuccess(InvestingInvokerApis.of().__page_nifty100(pageNum, pageSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping({"getINDNews.do"})
|
||||||
|
@ApiOperation(value = "印度新闻列表", httpMethod = "GET")
|
||||||
|
@ResponseBody
|
||||||
|
public ServerResponse getINDNews(@RequestParam("pageSize") Integer pageSize, @RequestParam("pageNum") Integer pageNum) {
|
||||||
|
return ServerResponse.createBySuccess(newsRepository.findAll(PageParam.of(pageNum, pageSize)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//印度股票时线-K线
|
//印度股票时线-K线
|
||||||
@RequestMapping({"getINDTimeK.do"})
|
@RequestMapping({"getINDTimeK.do"})
|
||||||
@ApiOperation(value = "印度股票时线-K线", httpMethod = "GET")
|
@ApiOperation(value = "印度股票K线", httpMethod = "GET")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ServerResponse getINDTimeK(@RequestParam("stockCode") String stockCode) {
|
@ApiImplicitParams({
|
||||||
return this.stockService.getTimeK(stockCode);
|
@ApiImplicitParam(name = "stockCode",value = "股票对应代码",dataType ="String", paramType = "query", required = true),
|
||||||
|
@ApiImplicitParam(name = "type",value = "min-时分线 day-日线 week-周线 month-月线, 3month-季度, 6month-半年, year-年",dataType ="String", paramType = "query", required = true),
|
||||||
|
})
|
||||||
|
public ServerResponse getINDTimeK(@RequestParam("stockCode") String stockCode, @RequestParam("type") String type) throws IOException {
|
||||||
|
ParamUtils.verify("股票代码", stockCode, ParamUtils.STRING_NOT_EMPTY_VERIFY_AND_CONVERT_VALUE);
|
||||||
|
ParamUtils.verify("K线类型", stockCode, ParamUtils.STRING_NOT_EMPTY_VERIFY_AND_CONVERT_VALUE);
|
||||||
|
|
||||||
|
List<JSONObject> list = InvestingApis.of().kline(StockCode.of(stockCode), type);
|
||||||
|
return ServerResponse.createBySuccess(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
//印度股票日线-K线
|
//印度指数-K线
|
||||||
@RequestMapping({"getINDDayK.do"})
|
@RequestMapping({"getIndiaIndexTimeK.do"})
|
||||||
@ApiOperation(value = "印度股票日线-K线", httpMethod = "GET")
|
@ApiOperation(value = "印度--获取指数K线", httpMethod = "GET")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ServerResponse getINDDayK(@RequestParam("stockCode") String stockCode) {
|
@ApiImplicitParams({
|
||||||
return this.stockService.getDayK(stockCode);
|
@ApiImplicitParam(name = "stockCode",value = "指数代码",dataType ="String", paramType = "query", required = true),
|
||||||
}
|
@ApiImplicitParam(name = "type",value = "min-时分线 day-日线 week-周线 month-月线, 3month-季度, 6month-半年, year-年",dataType ="String", paramType = "query", required = true),
|
||||||
|
})
|
||||||
|
public ServerResponse getIndiaIndexTimeK(@RequestParam("stockCode") String stockCode, @RequestParam("type") String type) throws IOException {
|
||||||
|
ParamUtils.verify("指数代码", stockCode, ParamUtils.STRING_NOT_EMPTY_VERIFY_AND_CONVERT_VALUE);
|
||||||
|
ParamUtils.verify("K线类型", stockCode, ParamUtils.STRING_NOT_EMPTY_VERIFY_AND_CONVERT_VALUE);
|
||||||
|
|
||||||
//印度股票周线-K线
|
List<JSONObject> list = InvestingApis.of().kline(StockCode.of(stockCode), type);
|
||||||
@RequestMapping({"getINDWeekK.do"})
|
return ServerResponse.createBySuccess(list);
|
||||||
@ApiOperation(value = "印度股票周线-K线", httpMethod = "GET")
|
|
||||||
@ResponseBody
|
|
||||||
public ServerResponse getINDWeekK(@RequestParam("stockCode") String stockCode) {
|
|
||||||
return this.stockService.getWeekK(stockCode);
|
|
||||||
}
|
}
|
||||||
|
@RequestMapping({"getIndiaIndex.do"})
|
||||||
//印度股票月线-K线
|
@ApiOperation(value = "印度--获取指定指数信息", httpMethod = "GET")
|
||||||
@RequestMapping({"getINDMonthK.do"})
|
|
||||||
@ApiOperation(value = "印度股票月线-K线", httpMethod = "GET")
|
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ServerResponse getINDMonthK(@RequestParam("stockCode") String stockCode) {
|
public ServerResponse getIndiaIndex() {
|
||||||
return this.stockService.getMonthK(stockCode);
|
return this.stockService.getIndiaIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
//根据股票id查询 股票指数、大盘指数信息
|
//根据股票id查询 股票指数、大盘指数信息
|
||||||
@@ -634,9 +684,16 @@ public class StockApiController {
|
|||||||
@ApiOperation(value = "新股待上市接口",httpMethod = "GET", response = ServerResponse.class)
|
@ApiOperation(value = "新股待上市接口",httpMethod = "GET", response = ServerResponse.class)
|
||||||
@RequestMapping({"getNewStockList.do"})
|
@RequestMapping({"getNewStockList.do"})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public
|
public ServerResponse getNewStockList() {
|
||||||
ServerResponse getNewStockList() {
|
|
||||||
|
|
||||||
return this.stockService.getNewStockList();
|
return this.stockService.getNewStockList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "印度股票入库",httpMethod = "GET", response = ServerResponse.class)
|
||||||
|
@RequestMapping({"syncIndiaData.do"})
|
||||||
|
@ResponseBody
|
||||||
|
public ServerResponse syncIndiaData() {
|
||||||
|
|
||||||
|
return stockService.syncIndiaData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
44
src/main/java/cn/stock/market/web/TodayApiController.java
Normal file
44
src/main/java/cn/stock/market/web/TodayApiController.java
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package cn.stock.market.web;
|
||||||
|
|
||||||
|
import cn.stock.market.infrastructure.api.TodayApis;
|
||||||
|
import cn.stock.market.utils.ServerResponse;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@Api(value = "/TodayApiController", tags = "today股票行情")
|
||||||
|
@RequestMapping({"/api/market/today/"})
|
||||||
|
public class TodayApiController {
|
||||||
|
|
||||||
|
@RequestMapping({"getTopGainers.do"})
|
||||||
|
@ApiOperation(value = "获取Top Gainers",notes = "exchange传nse或者bse", httpMethod = "GET")
|
||||||
|
@ResponseBody
|
||||||
|
public ServerResponse getTopGainers(@RequestParam("exchange") String exchange) {
|
||||||
|
return ServerResponse.createBySuccess(TodayApis.getTopGainers(exchange));
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping({"getTopLosers.do"})
|
||||||
|
@ApiOperation(value = "获取 Top Losers",notes = "exchange传nse或者bse", httpMethod = "GET")
|
||||||
|
@ResponseBody
|
||||||
|
public ServerResponse getTopLosers(@RequestParam("exchange") String exchange) {
|
||||||
|
return ServerResponse.createBySuccess(TodayApis.getTopLosers(exchange));
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping({"getMostActiveVolume.do"})
|
||||||
|
@ApiOperation(value = "获取 Most Active Volume",notes = "exchange传nse或者bse", httpMethod = "GET")
|
||||||
|
@ResponseBody
|
||||||
|
public ServerResponse getMostActiveVolume(@RequestParam("exchange") String exchange) {
|
||||||
|
return ServerResponse.createBySuccess(TodayApis.getMostActiveVolume(exchange));
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping({"getMostActiveValue.do"})
|
||||||
|
@ApiOperation(value = "获取 Most Active Value",notes = "exchange传nse或者bse",httpMethod = "GET")
|
||||||
|
@ResponseBody
|
||||||
|
public ServerResponse getMostActiveValue(@RequestParam("exchange") String exchange) {
|
||||||
|
return ServerResponse.createBySuccess(TodayApis.getMostActiveValue(exchange));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package cn.stock.market.web.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||||
|
public @interface EncryptFilter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对入参是否解密
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean decryptRequest() default true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对出参是否加密
|
||||||
|
*/
|
||||||
|
boolean encryptResponse() default true;
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
|||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableScheduling
|
@EnableScheduling
|
||||||
@ConditionalOnProperty(prefix = "enable", name = "scheduled", havingValue = "true")
|
@ConditionalOnProperty(prefix = "enable", name = "scheduled", havingValue = "true", matchIfMissing = true)
|
||||||
public class ControlSchedulingConfiguration {
|
public class ControlSchedulingConfiguration {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ public class Swagger2Config {
|
|||||||
|
|
||||||
public ApiInfoBuilder commonApiInfoBuilder() {
|
public ApiInfoBuilder commonApiInfoBuilder() {
|
||||||
return new ApiInfoBuilder()
|
return new ApiInfoBuilder()
|
||||||
.description("鑫宝 接口文档")
|
.description("英文股票接口文档")
|
||||||
.termsOfServiceUrl("http://www.xxxx.cn/")
|
.termsOfServiceUrl("http://www.xxxx.cn/")
|
||||||
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0").version("v1.0");
|
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0").version("v1.0");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package cn.stock.market.web.handler;
|
||||||
|
|
||||||
|
import cn.stock.market.utils.AESUtil;
|
||||||
|
import cn.stock.market.utils.StreamUtil;
|
||||||
|
import cn.stock.market.web.annotations.EncryptFilter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.core.MethodParameter;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpInputMessage;
|
||||||
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局请求入参(RequestBody)处理器
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@ControllerAdvice
|
||||||
|
@Slf4j
|
||||||
|
public class GlobalRequestBodyHandler extends RequestBodyAdviceAdapter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 该方法用于判断当前请求,是否要执行beforeBodyRead方法
|
||||||
|
*
|
||||||
|
* @param methodParameter handler方法的参数对象
|
||||||
|
* @param targetType handler方法的参数类型
|
||||||
|
* @param converterType 将会使用到的Http消息转换器类类型
|
||||||
|
* @return 返回true则会执行beforeBodyRead
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean supports(MethodParameter methodParameter, Type targetType,
|
||||||
|
Class<? extends HttpMessageConverter<?>> converterType) {
|
||||||
|
Method method = methodParameter.getMethod();
|
||||||
|
if (Objects.nonNull(method)) {
|
||||||
|
EncryptFilter encryptFilter = method.getAnnotation(EncryptFilter.class);
|
||||||
|
if (Objects.nonNull(encryptFilter)) {
|
||||||
|
return encryptFilter.decryptRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在Http消息转换器执转换,之前执行
|
||||||
|
*
|
||||||
|
* @param inputMessage 客户端的请求数据
|
||||||
|
* @param methodParameter handler方法的参数对象
|
||||||
|
* @param targetType handler方法的参数类型
|
||||||
|
* @param converterType 将会使用到的Http消息转换器类类型
|
||||||
|
* @return 返回 一个自定义的HttpInputMessage
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter methodParameter, Type targetType,
|
||||||
|
Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
|
||||||
|
|
||||||
|
// 读取加密的请求体
|
||||||
|
InputStream body = inputMessage.getBody();
|
||||||
|
HttpHeaders headers = inputMessage.getHeaders();
|
||||||
|
headers.remove("Content-Length");
|
||||||
|
String s = StreamUtil.getBodyString(body);
|
||||||
|
log.info("解密前请求body:" + s);
|
||||||
|
if (StringUtils.isEmpty(s)){
|
||||||
|
return inputMessage;
|
||||||
|
}
|
||||||
|
Method method = methodParameter.getMethod();
|
||||||
|
if (Objects.isNull(method)) {
|
||||||
|
return inputMessage;
|
||||||
|
}
|
||||||
|
// 解密请求
|
||||||
|
EncryptFilter encryptFilter = method.getAnnotation(EncryptFilter.class);
|
||||||
|
if (Objects.nonNull(encryptFilter) && encryptFilter.decryptRequest()) {
|
||||||
|
// 使用AES解密
|
||||||
|
String bodyDec = AESUtil.decrypt(s);
|
||||||
|
log.info("解密后请求body:" + bodyDec);
|
||||||
|
if (!StringUtils.isEmpty(bodyDec)) {
|
||||||
|
// 使用解密后的数据,构造新的读取流
|
||||||
|
InputStream inputStream = new ByteArrayInputStream(bodyDec.getBytes(StandardCharsets.UTF_8));
|
||||||
|
return new HttpInputMessage() {
|
||||||
|
@Override
|
||||||
|
public HttpHeaders getHeaders() {
|
||||||
|
return inputMessage.getHeaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getBody() {
|
||||||
|
return inputStream;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inputMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package cn.stock.market.web.handler;
|
||||||
|
|
||||||
|
import cn.stock.market.utils.AESUtil;
|
||||||
|
import cn.stock.market.utils.PropertiesUtil;
|
||||||
|
import cn.stock.market.web.annotations.EncryptFilter;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.core.MethodParameter;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.server.ServerHttpRequest;
|
||||||
|
import org.springframework.http.server.ServerHttpResponse;
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局响应结果(ResponseBody)处理器
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@ControllerAdvice
|
||||||
|
@Slf4j
|
||||||
|
public class GlobalResponseBodyHandler implements ResponseBodyAdvice {
|
||||||
|
|
||||||
|
private ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
public GlobalResponseBodyHandler(){
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("NullableProblems") // 避免 IDEA 警告
|
||||||
|
public boolean supports(MethodParameter returnType, Class converterType) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("NullableProblems") // 避免 IDEA 警告
|
||||||
|
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType,
|
||||||
|
ServerHttpRequest request, ServerHttpResponse response) {
|
||||||
|
Method method = returnType.getMethod();
|
||||||
|
if (Objects.isNull(body) || Objects.isNull(method)) {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
log.info("处理请求地址:{} 的返回值", request.getURI());
|
||||||
|
//获取请求数据
|
||||||
|
String srcData = null;
|
||||||
|
try {
|
||||||
|
srcData = objectMapper.writeValueAsString(body);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
log.info("加密前响应body={}", srcData);
|
||||||
|
EncryptFilter encryptFilter = method.getAnnotation(EncryptFilter.class);
|
||||||
|
if (Objects.nonNull(encryptFilter) && encryptFilter.encryptResponse()) {
|
||||||
|
//加密
|
||||||
|
String returnStr = AESUtil.encrypt(srcData);
|
||||||
|
log.info("加密后响应body:" + returnStr);
|
||||||
|
//添加 encrypt 告诉前端数据已加密
|
||||||
|
return returnStr;
|
||||||
|
}
|
||||||
|
return body;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ spring:
|
|||||||
show-sql: true
|
show-sql: true
|
||||||
# Redis配置
|
# Redis配置
|
||||||
redis:
|
redis:
|
||||||
host: 43.128.20.124
|
host: 43.132.212.180
|
||||||
password: ruTZ9J3gaDhknJ
|
password: ruTZ9J3gaDhknJ
|
||||||
port: 36379
|
port: 36379
|
||||||
database: 1
|
database: 1
|
||||||
@@ -17,7 +17,7 @@ spring:
|
|||||||
datasource:
|
datasource:
|
||||||
stock-market:
|
stock-market:
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
url: jdbc:mysql://124.156.133.209:33306/stock-market?useUnicode=true&characterEncoding=utf-8
|
url: jdbc:mysql://43.132.212.180:33306/india_stock?useUnicode=true&characterEncoding=utf-8
|
||||||
username: root
|
username: root
|
||||||
password: 33BsUUcnXRYgwt
|
password: 33BsUUcnXRYgwt
|
||||||
maxActive: 500
|
maxActive: 500
|
||||||
|
|||||||
16
src/main/resources/rebel.xml
Normal file
16
src/main/resources/rebel.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
|
||||||
|
Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
|
||||||
|
-->
|
||||||
|
<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
|
||||||
|
|
||||||
|
<id>market</id>
|
||||||
|
|
||||||
|
<classpath>
|
||||||
|
<dir name="/Users/gs/Downloads/works/india_market_java/target/classes">
|
||||||
|
</dir>
|
||||||
|
</classpath>
|
||||||
|
|
||||||
|
</application>
|
||||||
@@ -113,3 +113,4 @@ website.domain.url=http://www.huijuwang888.com
|
|||||||
website.token=0DC8F78384C7AAFF3192A9C60A473FEE7F89C62888689616B98A06910E86B510
|
website.token=0DC8F78384C7AAFF3192A9C60A473FEE7F89C62888689616B98A06910E86B510
|
||||||
|
|
||||||
news.main.url=http://eminfo.eastmoney.com
|
news.main.url=http://eminfo.eastmoney.com
|
||||||
|
aes.key=Jy112211Kj112211
|
||||||
|
|||||||
57
src/test/java/rp/lee/jpa/JpaDDDGen.java
Normal file
57
src/test/java/rp/lee/jpa/JpaDDDGen.java
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package rp.lee.jpa;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import com.mysql.cj.jdbc.MysqlDataSource;
|
||||||
|
|
||||||
|
import rp.lee.jpa.ddd.Cons;
|
||||||
|
import rp.lee.jpa.ddd.ToolDDD;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* title: JpaDDDGen.java
|
||||||
|
* DDD 脚手架
|
||||||
|
*
|
||||||
|
* @author rplees
|
||||||
|
* @email rplees.i.ly@gmail.com
|
||||||
|
* @version 1.0
|
||||||
|
* @created 2023年8月9日 下午5:41:52
|
||||||
|
*/
|
||||||
|
public class JpaDDDGen {
|
||||||
|
@Resource DataSource dataSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据库连接
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static DataSource getMySQLDataSource() {
|
||||||
|
MysqlDataSource mysqlDS = new MysqlDataSource();
|
||||||
|
mysqlDS.setURL("jdbc:mysql://43.132.212.180:33306/india_stock?useUnicode=true&characterEncoding=utf-8");
|
||||||
|
mysqlDS.setUser("root");
|
||||||
|
mysqlDS.setPassword("33BsUUcnXRYgwt");
|
||||||
|
return mysqlDS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws SQLException, Exception {
|
||||||
|
Cons.BASE_PACKAGE = "cn.stock.%s";
|
||||||
|
Cons.module = "market";
|
||||||
|
/**
|
||||||
|
* 请修改实际上本机的项目路径
|
||||||
|
*/
|
||||||
|
String path = "src/main/java";
|
||||||
|
Cons.CLIENT_FOLDER_PATH = path;
|
||||||
|
Cons.SERVER_FOLDER_PATH = path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cs_statistic - 要生成的数据库表
|
||||||
|
*/
|
||||||
|
Cons.tableNameToEntiyMapping.put("stock_ipo", null);
|
||||||
|
|
||||||
|
ToolDDD.g(getMySQLDataSource().getConnection());
|
||||||
|
}
|
||||||
|
}
|
||||||
51
src/test/java/rp/lee/jpa/ddd/ApiFeignGen.java
Normal file
51
src/test/java/rp/lee/jpa/ddd/ApiFeignGen.java
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
public class ApiFeignGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
|
||||||
|
Builder builder = TypeSpec.interfaceBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
.addSuperinterface(ddd.api.toClassName())
|
||||||
|
.addAnnotation(AnnotationSpec
|
||||||
|
.builder(ClassName.get("org.springframework.cloud.openfeign", "FeignClient"))
|
||||||
|
.addMember("name", "\"" + ddd.module + "\"")
|
||||||
|
.addMember("contextId", "\"" + StringUtils.uncapitalize(ddd.entityPrefix) + "\"")
|
||||||
|
.addMember("configuration", "{ $T.class }", ClassName.get("cn.qutaojing.common.feign", "FeignConfiguration"))
|
||||||
|
|
||||||
|
.build())
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return "IFeign" + ddd.entityPrefix + "Client";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.CLIENT_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.API_FEIGN_PACKAGE, ddd.module);
|
||||||
|
}
|
||||||
|
}
|
||||||
137
src/test/java/rp/lee/jpa/ddd/ApiGen.java
Normal file
137
src/test/java/rp/lee/jpa/ddd/ApiGen.java
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.ParameterSpec;
|
||||||
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
public class ApiGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
ClassName springQueryMapClass = ClassName.get("org.springframework.cloud.openfeign", "SpringQueryMap");
|
||||||
|
|
||||||
|
Builder builder = TypeSpec.interfaceBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/" + StringUtils.lowerCase(ddd.entityPrefix) + "\"").build())
|
||||||
|
|
||||||
|
// 分页构造
|
||||||
|
.addMethod(MethodSpec.methodBuilder("page").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||||
|
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/page" + "\"").build())
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.query.toClassName(), "query")
|
||||||
|
.addAnnotation(springQueryMapClass)
|
||||||
|
.build())
|
||||||
|
.addParameter(ParameterSpec.builder(ClassName.get("cn.qutaojing.common", "PageParam"), "p").build())
|
||||||
|
.returns(ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common", "PageInfo"), ddd.dto.toClassName()))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
// 列表构造
|
||||||
|
.addMethod(MethodSpec.methodBuilder("list").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/list\"").build())
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.query.toClassName(), "query")
|
||||||
|
.addAnnotation(springQueryMapClass)
|
||||||
|
.build())
|
||||||
|
.returns(ParameterizedTypeName.get(ClassName.get(List.class), ddd.dto.toClassName()))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
//create
|
||||||
|
.addMethod(MethodSpec.methodBuilder("create").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"create\"").build())
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.put.toClassName(), "request").addAnnotation(Valid.class)
|
||||||
|
.addAnnotation(springQueryMapClass)
|
||||||
|
.build())
|
||||||
|
.addParameter(ParameterSpec.builder(BindingResult.class, "bindingResult")
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RequestParam.class)
|
||||||
|
.addMember("required", "false")
|
||||||
|
.addMember("value", "\"bindingResult\"")
|
||||||
|
.build()).build())
|
||||||
|
.returns(ddd.dto.toClassName())
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
//update
|
||||||
|
.addMethod(MethodSpec.methodBuilder("update").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/{id}/update\"").build())
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.poPK, "id").addAnnotation(AnnotationSpec.builder(PathVariable.class).addMember("value", "\"id\"").build()).build())
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.put.toClassName(), "request")
|
||||||
|
.addAnnotation(springQueryMapClass)
|
||||||
|
.build())
|
||||||
|
.returns(ddd.dto.toClassName())
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
//根据ID获取
|
||||||
|
.addMethod(MethodSpec.methodBuilder("get").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/{id}/get\"").build())
|
||||||
|
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.poPK, "id").addAnnotation(AnnotationSpec.builder(PathVariable.class).addMember("value", "\"id\"").build()).build())
|
||||||
|
.returns(ddd.dto.toClassName())
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
//启用
|
||||||
|
.addMethod(MethodSpec.methodBuilder("enable").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/{id}/enable\"").build())
|
||||||
|
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.poPK, "id").addAnnotation(AnnotationSpec.builder(PathVariable.class).addMember("value", "\"id\"").build()).build())
|
||||||
|
.returns(void.class)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
//禁用
|
||||||
|
.addMethod(MethodSpec.methodBuilder("disable").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/{id}/disable\"").build())
|
||||||
|
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.poPK, "id").addAnnotation(AnnotationSpec.builder(PathVariable.class).addMember("value", "\"id\"").build()).build())
|
||||||
|
.returns(void.class)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
//删除
|
||||||
|
.addMethod(MethodSpec.methodBuilder("remove").addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RequestMapping.class).addMember("path", "\"/{id}/remove\"").build())
|
||||||
|
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.poPK, "id").addAnnotation(AnnotationSpec.builder(PathVariable.class).addMember("value", "\"id\"").build()).build())
|
||||||
|
.returns(void.class)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return "I" + ddd.entityPrefix + "Client";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.CLIENT_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.API_PACKAGE, ddd.module);
|
||||||
|
}
|
||||||
|
}
|
||||||
163
src/test/java/rp/lee/jpa/ddd/ApiImplGen.java
Normal file
163
src/test/java/rp/lee/jpa/ddd/ApiImplGen.java
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.FieldSpec;
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.ParameterSpec;
|
||||||
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
public class ApiImplGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
|
||||||
|
Builder builder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
.addSuperinterface(ddd.api.toClassName())
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RestController.class).build())
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RequiredArgsConstructor.class).addMember("onConstructor", "@__(@$T)", ClassName.get(Autowired.class)).build())
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Slf4j.class).build())
|
||||||
|
.addField(FieldSpec.builder(ddd.service.toClassName(), "service").addModifiers(Modifier.FINAL).build())
|
||||||
|
.addField(FieldSpec.builder(ddd.assembler.toClassName(), "assembler").addModifiers(Modifier.FINAL).build())
|
||||||
|
.addField(FieldSpec.builder(ddd.factory.toClassName(), "factory").addModifiers(Modifier.FINAL).build())
|
||||||
|
|
||||||
|
// 分页构造
|
||||||
|
.addMethod(MethodSpec.methodBuilder("page")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Override.class).build())
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.query.toClassName(), "query").build())
|
||||||
|
.addParameter(ParameterSpec.builder(ClassName.get("cn.qutaojing.common", "PageParam"), "p").build())
|
||||||
|
.returns(ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common", "PageInfo"), ddd.dto.toClassName()))
|
||||||
|
.addStatement("$T<$T> page = service.repository().findAll($T.spec(query), PageParam.of(p))\n"
|
||||||
|
+ " .map(entity -> assembler.toDTO(entity))",
|
||||||
|
ClassName.get("org.springframework.data.domain", "Page"),
|
||||||
|
ddd.dto.toClassName(),ClassName.get("cn.qutaojing.common.jpa", "QueryHelp"))
|
||||||
|
|
||||||
|
.addStatement("return PageInfo.with(page)")
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
// // 列表构造
|
||||||
|
.addMethod(MethodSpec.methodBuilder("list")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Override.class).build())
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.query.toClassName(), "query").build())
|
||||||
|
.returns(ParameterizedTypeName.get(ClassName.get(List.class), ddd.dto.toClassName()))
|
||||||
|
.addStatement("List<$T> list = service.repository().findAll($T.spec(query))", ddd.entity.toClassName(), ClassName.get("cn.qutaojing.common.jpa", "QueryHelp"))
|
||||||
|
|
||||||
|
.addStatement("return $T.transform(list, entity -> assembler.toDTO(entity))", ClassName.get("com.google.common.collect", "Lists"))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
// //create
|
||||||
|
.addMethod(MethodSpec.methodBuilder("create")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Override.class).build())
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.put.toClassName(), "request").build())
|
||||||
|
.addParameter(ParameterSpec.builder(BindingResult.class, "bindingResult").build())
|
||||||
|
.returns(ddd.dto.toClassName())
|
||||||
|
|
||||||
|
.addStatement("$T.validBindResult(bindingResult)", ClassName.get("com.ag.utils", "AgAssert"))
|
||||||
|
.addStatement("$T createEntity = factory.entity(request)", ddd.entity.toClassName())
|
||||||
|
.addStatement("$T entity = service.repository().save(createEntity)", ddd.entity.toClassName())
|
||||||
|
.addStatement("return assembler.toDTO(entity)")
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
//
|
||||||
|
// //update
|
||||||
|
.addMethod(MethodSpec.methodBuilder("update")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Override.class).build())
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.poPK, "id").build())
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.put.toClassName(), "request").build())
|
||||||
|
.returns(ddd.dto.toClassName())
|
||||||
|
|
||||||
|
.addStatement("$T updateEntity = factory.entity(request)", ddd.entity.toClassName())
|
||||||
|
.addStatement("$T entity = service.update(id, updateEntity)", ddd.entity.toClassName())
|
||||||
|
.addStatement("return assembler.toDTO(entity)")
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
//
|
||||||
|
// //根据ID获取
|
||||||
|
.addMethod(MethodSpec.methodBuilder("get")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Override.class).build())
|
||||||
|
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.poPK, "id").build())
|
||||||
|
.returns(ddd.dto.toClassName())
|
||||||
|
|
||||||
|
.addStatement("$T entity = service.repository().findById(id).orElseThrow($T::new)", ddd.entity.toClassName(), ClassName.get("com.ag.exception", "EntityNotFoundException"))
|
||||||
|
.addStatement("return assembler.toDTO(entity)")
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
//
|
||||||
|
// //启用
|
||||||
|
.addMethod(MethodSpec.methodBuilder("enable")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Override.class).build())
|
||||||
|
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.poPK, "id").build())
|
||||||
|
.returns(void.class)
|
||||||
|
.addStatement("service.repository().setStatusEnable(id)")
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
//
|
||||||
|
// //禁用
|
||||||
|
.addMethod(MethodSpec.methodBuilder("disable")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Override.class).build())
|
||||||
|
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.poPK, "id").build())
|
||||||
|
.returns(void.class)
|
||||||
|
.addStatement("service.repository().setStatusDisable(id)")
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
//
|
||||||
|
// //删除
|
||||||
|
.addMethod(MethodSpec.methodBuilder("remove")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Override.class).build())
|
||||||
|
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.poPK, "id").build())
|
||||||
|
.returns(void.class)
|
||||||
|
.addStatement("log.warn(\"删除{}实体\", id)")
|
||||||
|
.addStatement("service.repository().deleteById(id)")
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "ClientImpl";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.SERVER_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.API_IMPL_PACKAGE, ddd.module);
|
||||||
|
}
|
||||||
|
}
|
||||||
73
src/test/java/rp/lee/jpa/ddd/AssemblerGen.java
Normal file
73
src/test/java/rp/lee/jpa/ddd/AssemblerGen.java
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
public class AssemblerGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
ClassName slef = ClassName.get(packagePath(ddd), className(ddd));
|
||||||
|
|
||||||
|
Builder builder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(Component.class)
|
||||||
|
.addAnnotation(Lazy.class)
|
||||||
|
|
||||||
|
.addMethod(MethodSpec.methodBuilder("toDTO")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addParameter(ddd.entity.toClassName(), "e")
|
||||||
|
.returns(ddd.dto.toClassName())
|
||||||
|
.addStatement("$T dto = $T.mapper(e, $T.class)", ddd.dto.toClassName(), ClassName.get("cn.qutaojing.common.utils", "Beans"), ddd.dto.toClassName())
|
||||||
|
.addStatement("if(dto == null) return dto")
|
||||||
|
.addStatement("fill(e, dto)")
|
||||||
|
.addStatement("return dto")
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
.addMethod(MethodSpec.methodBuilder("fill")
|
||||||
|
.addModifiers(Modifier.PROTECTED)
|
||||||
|
.addParameter(ddd.entity.toClassName(), "e")
|
||||||
|
.addParameter(ddd.dto.toClassName(), "dto")
|
||||||
|
.addStatement("if(dto == null) return")
|
||||||
|
.addStatement("return")
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
.addMethod(MethodSpec.methodBuilder("of")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addModifiers(Modifier.STATIC)
|
||||||
|
.returns(slef)
|
||||||
|
.addStatement("return $T.getBean($T.class)", ClassName.get("cn.qutaojing.common.utils", "SpringUtils"), slef)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)));
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "Assembler";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.SERVER_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.ASSEMBLER_PACKAGE, ddd.module, ddd.module);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/test/java/rp/lee/jpa/ddd/ClassVO.java
Normal file
19
src/test/java/rp/lee/jpa/ddd/ClassVO.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@lombok.Builder
|
||||||
|
public class ClassVO {
|
||||||
|
|
||||||
|
String folderPath;
|
||||||
|
String packagePath;
|
||||||
|
String className;
|
||||||
|
Builder builder;
|
||||||
|
|
||||||
|
ClassName toClassName() {
|
||||||
|
return ClassName.get(packagePath, className);
|
||||||
|
}
|
||||||
|
}
|
||||||
58
src/test/java/rp/lee/jpa/ddd/Cons.java
Normal file
58
src/test/java/rp/lee/jpa/ddd/Cons.java
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
public class Cons {
|
||||||
|
public static final boolean SIMPLE = true;
|
||||||
|
public static final boolean C = true;
|
||||||
|
/**
|
||||||
|
* 模块
|
||||||
|
*/
|
||||||
|
public static String module = "cs";//项目
|
||||||
|
public static String entity = "basic"; //领域
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 客户端项目的git路径
|
||||||
|
*/
|
||||||
|
public static String CLIENT_FOLDER_PATH = "/Users/rplees/work/git/stock-company/cs_java/src/main/java";
|
||||||
|
/**
|
||||||
|
* Server项目的git路径
|
||||||
|
*/
|
||||||
|
public static String SERVER_FOLDER_PATH = "/Users/rplees/work/git/stock-company/cs_java/src/main/java";
|
||||||
|
|
||||||
|
public static Map<String, String> tableNameToEntiyMapping = Maps.newHashMap();
|
||||||
|
static {
|
||||||
|
/**
|
||||||
|
* 需要导出的数据库表名 -> 导出的 实体命名(不需要加后缀 PO/DTO/Entity)
|
||||||
|
*/
|
||||||
|
// tableNameToEntiyMapping.put("cs_statistic", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String BASE_PACKAGE = "cn.stock.%s";
|
||||||
|
public static String PO_PACKAGE = BASE_PACKAGE + ".infrastructure.db.po";
|
||||||
|
public static String PO_MONGO_PACKAGE = BASE_PACKAGE + ".infrastructure.mongodb.po";
|
||||||
|
public static String REPO_PACKAGE = BASE_PACKAGE + ".infrastructure.db.repo";
|
||||||
|
public static String REPO_MONGO_PACKAGE = BASE_PACKAGE + ".infrastructure.mongodb.repo";
|
||||||
|
|
||||||
|
public static String ENTITY_PACKAGE = BASE_PACKAGE + ".domain.%s.entity";
|
||||||
|
public static String SERVICE_PACKAGE = BASE_PACKAGE + ".domain.%s.service";
|
||||||
|
public static String REPOSITORY_PACKAGE = BASE_PACKAGE + ".domain.%s.repository";
|
||||||
|
public static String FACTORY_PACKAGE = BASE_PACKAGE + ".domain.%s.factory";
|
||||||
|
public static String CONVERT_PACKAGE = BASE_PACKAGE + ".domain.%s.convert";
|
||||||
|
|
||||||
|
public static String ASSEMBLER_PACKAGE = BASE_PACKAGE + ".application.assembler";
|
||||||
|
|
||||||
|
//client
|
||||||
|
public static String API_PACKAGE = BASE_PACKAGE + ".client";
|
||||||
|
public static String API_FEIGN_PACKAGE = BASE_PACKAGE + ".client.impl";
|
||||||
|
public static String API_IMPL_PACKAGE = BASE_PACKAGE + ".application";
|
||||||
|
|
||||||
|
|
||||||
|
public static String DTO_PACKAGE = BASE_PACKAGE + ".dto";
|
||||||
|
public static String QUERY_PACKAGE = BASE_PACKAGE + ".vo";
|
||||||
|
public static String PUT_PACKAGE = BASE_PACKAGE + ".vo";
|
||||||
|
public static String CREATE_PACKAGE = DTO_PACKAGE + ".command";
|
||||||
|
public static String MODIFY_PACKAGE = CREATE_PACKAGE;
|
||||||
|
}
|
||||||
92
src/test/java/rp/lee/jpa/ddd/ConvertGen.java
Normal file
92
src/test/java/rp/lee/jpa/ddd/ConvertGen.java
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
public class ConvertGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
ClassName slef = ClassName.get(packagePath(ddd), className(ddd));
|
||||||
|
|
||||||
|
// Builder builder = TypeSpec.interfaceBuilder(className(ddd))
|
||||||
|
// .addModifiers(Modifier.PUBLIC)
|
||||||
|
// .addAnnotation(Component.class)
|
||||||
|
// .addAnnotation(Lazy.class)
|
||||||
|
// .addAnnotation(AnnotationSpec.builder(ClassName.get("org.mapstruct.Mapper", "Mapper"))
|
||||||
|
// .addMember("componentModel", "spring")
|
||||||
|
// .addMember("unmappedTargetPolicy", "ReportingPolicy.IGNORE)")
|
||||||
|
// .build())
|
||||||
|
// .addSuperinterface(ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common.domain.convert", "IEntityPOConvert"),
|
||||||
|
// ddd.entity.toClassName(),
|
||||||
|
// ddd.po.toClassName()))
|
||||||
|
//
|
||||||
|
// .addJavadoc(String.format("%s \n", className(ddd)));
|
||||||
|
|
||||||
|
Builder builder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(Component.class)
|
||||||
|
.addAnnotation(Lazy.class)
|
||||||
|
.superclass(ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common.domain.convert", "SimpleEntityPOConvert"),
|
||||||
|
ddd.entity.toClassName(),
|
||||||
|
ddd.po.toClassName()))
|
||||||
|
// .addSuperinterface(ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common.domain.convert", "IEntityPOConvert"),
|
||||||
|
// ddd.entity.toClassName(),
|
||||||
|
// ddd.po.toClassName()))
|
||||||
|
//
|
||||||
|
// .addMethod(MethodSpec.methodBuilder("toEntity")
|
||||||
|
// .addModifiers(Modifier.PUBLIC)
|
||||||
|
// .addAnnotation(Override.class)
|
||||||
|
// .addParameter(ddd.po.toClassName(), "po")
|
||||||
|
// .returns(ddd.entity.toClassName())
|
||||||
|
// .addStatement("return $T.mapper(po, $T.class)", ClassName.get("cn.qutaojing.common.utils", "Beans"), ddd.entity.toClassName())
|
||||||
|
// .build()
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// .addMethod(MethodSpec.methodBuilder("toPo")
|
||||||
|
// .addModifiers(Modifier.PUBLIC)
|
||||||
|
// .addAnnotation(Override.class)
|
||||||
|
// .addParameter(ddd.entity.toClassName(), "entity")
|
||||||
|
// .returns(ddd.po.toClassName())
|
||||||
|
// .addStatement("return $T.mapper(entity, $T.class)", ClassName.get("cn.qutaojing.common.utils", "Beans"), ddd.po.toClassName())
|
||||||
|
// .build()
|
||||||
|
// )
|
||||||
|
|
||||||
|
.addMethod(MethodSpec.methodBuilder("of")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addModifiers(Modifier.STATIC)
|
||||||
|
.returns(slef)
|
||||||
|
.addStatement("return $T.getBean($T.class)", ClassName.get("cn.qutaojing.common.utils", "SpringUtils"), slef)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)));
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "Convert";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.SERVER_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.CONVERT_PACKAGE, ddd.module, ddd.e);
|
||||||
|
}
|
||||||
|
}
|
||||||
87
src/test/java/rp/lee/jpa/ddd/CreateGen.java
Normal file
87
src/test/java/rp/lee/jpa/ddd/CreateGen.java
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.FieldSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import rp.lee.jpa.entity.ColumnStyle;
|
||||||
|
import rp.lee.jpa.entity.Utils;
|
||||||
|
|
||||||
|
public class CreateGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
String tableName = rs.getString("TABLE_NAME");
|
||||||
|
Builder classBuilder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
.addJavadoc(rs.getString("REMARKS"))
|
||||||
|
.addJavadoc("")
|
||||||
|
.addAnnotation(Data.class)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(ClassName.get("lombok.experimental", "SuperBuilder")).build())
|
||||||
|
.addAnnotation(NoArgsConstructor.class)
|
||||||
|
;
|
||||||
|
|
||||||
|
buildFields(ddd, conn, tableName, classBuilder);
|
||||||
|
return classBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void buildFields(DDD ddd, Connection conn, String tableName, Builder classBuilder) throws SQLException {
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
DatabaseMetaData metaData = conn.getMetaData();
|
||||||
|
rs = metaData.getColumns(null, "%", tableName, "%");
|
||||||
|
while (rs.next()) {
|
||||||
|
String columnName = rs.getString("COLUMN_NAME");
|
||||||
|
int dataType = rs.getInt("DATA_TYPE");
|
||||||
|
String remarks = rs.getString("REMARKS");
|
||||||
|
String fieldName = Utils.columnNameToFieldName(columnName, ColumnStyle.defaultColumnStyle);
|
||||||
|
if("createTime".equals(fieldName) || "updateTime".equals(fieldName)) {//忽略
|
||||||
|
|
||||||
|
} else {
|
||||||
|
com.squareup.javapoet.FieldSpec.Builder fieldBuilder = FieldSpec
|
||||||
|
.builder(Utils.dataTypeToFieldType(columnName, dataType),
|
||||||
|
fieldName)
|
||||||
|
.addJavadoc(remarks);
|
||||||
|
|
||||||
|
classBuilder.addField(fieldBuilder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (rs != null) {
|
||||||
|
try {
|
||||||
|
rs.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "CreateCommand";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.CLIENT_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.CREATE_PACKAGE, ddd.module);
|
||||||
|
}
|
||||||
|
}
|
||||||
54
src/test/java/rp/lee/jpa/ddd/DDD.java
Normal file
54
src/test/java/rp/lee/jpa/ddd/DDD.java
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import java.util.List;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
public class DDD {
|
||||||
|
public DDD(String m, String e) {
|
||||||
|
this.module = m;
|
||||||
|
this.e = e;
|
||||||
|
}
|
||||||
|
String module;
|
||||||
|
String e;
|
||||||
|
|
||||||
|
Type poPK;
|
||||||
|
String poPKKey;
|
||||||
|
|
||||||
|
String entityPrefix;
|
||||||
|
|
||||||
|
ClassVO po; //ok
|
||||||
|
ClassVO entity; //ok
|
||||||
|
ClassVO dto;//ok
|
||||||
|
|
||||||
|
ClassVO assembler;//ok
|
||||||
|
ClassVO convert;//ok
|
||||||
|
ClassVO factory;//ok
|
||||||
|
ClassVO repository;//ok
|
||||||
|
ClassVO service;//ok
|
||||||
|
|
||||||
|
ClassVO repo;//ok
|
||||||
|
ClassVO query;//ok
|
||||||
|
ClassVO put;//ok
|
||||||
|
|
||||||
|
ClassVO create;//ok
|
||||||
|
ClassVO modify;//ok
|
||||||
|
|
||||||
|
ClassVO api;//ok
|
||||||
|
ClassVO apiFeign;//ok
|
||||||
|
ClassVO apiImplGen;//ok
|
||||||
|
|
||||||
|
public List<ClassVO> list() {
|
||||||
|
if(Cons.SIMPLE) {
|
||||||
|
return Lists.newArrayList(po, entity, dto,create,modify, convert, factory,assembler, repository, service, repo, query, put);
|
||||||
|
}
|
||||||
|
if(Cons.C) {
|
||||||
|
return Lists.newArrayList(po, entity, dto, create,modify, convert, factory,assembler, repository, service, repo, query, put, api, apiFeign, apiImplGen);
|
||||||
|
}
|
||||||
|
return Lists.newArrayList(po, entity, dto, convert, factory,assembler, repository, service, repo, query, put, api, apiFeign, apiImplGen);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ClassVO> mongoList() {
|
||||||
|
return Lists.newArrayList(entity, dto,create,modify, convert, factory,assembler, repository, service, repo, query, put, api, apiFeign, apiImplGen);
|
||||||
|
}
|
||||||
|
}
|
||||||
60
src/test/java/rp/lee/jpa/ddd/DTOGen.java
Normal file
60
src/test/java/rp/lee/jpa/ddd/DTOGen.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
public class DTOGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
// String tableName = rs.getString("TABLE_NAME");
|
||||||
|
// Builder classBuilder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
// .addModifiers(Modifier.PUBLIC)
|
||||||
|
// .addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
// .addJavadoc(rs.getString("REMARKS"))
|
||||||
|
// .addJavadoc("")
|
||||||
|
// .addAnnotation(Data.class)
|
||||||
|
// .addAnnotation(lombok.Builder.class)
|
||||||
|
// .addAnnotation(NoArgsConstructor.class)
|
||||||
|
// .addAnnotation(AllArgsConstructor.class)
|
||||||
|
// ;
|
||||||
|
//
|
||||||
|
// buildFields(ddd, conn, tableName, classBuilder);
|
||||||
|
// return classBuilder;
|
||||||
|
|
||||||
|
Builder builder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(lombok.Data.class)
|
||||||
|
.addAnnotation(lombok.NoArgsConstructor.class)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(ClassName.get("lombok.experimental", "SuperBuilder")).build())
|
||||||
|
.superclass(ddd.po.toClassName())
|
||||||
|
.addAnnotation(AnnotationSpec.builder(ClassName.get("lombok", "EqualsAndHashCode"))
|
||||||
|
.addMember("callSuper", "false")
|
||||||
|
.build())
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
;
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "DTO";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.CLIENT_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.DTO_PACKAGE, ddd.module);
|
||||||
|
}
|
||||||
|
}
|
||||||
62
src/test/java/rp/lee/jpa/ddd/EntityGen.java
Normal file
62
src/test/java/rp/lee/jpa/ddd/EntityGen.java
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.ParameterSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
public class EntityGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
Builder builder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(lombok.Data.class)
|
||||||
|
.addAnnotation(lombok.NoArgsConstructor.class)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(ClassName.get("lombok.experimental", "SuperBuilder")).build())
|
||||||
|
.superclass(ddd.po.toClassName())
|
||||||
|
.addAnnotation(AnnotationSpec.builder(ClassName.get("lombok", "EqualsAndHashCode"))
|
||||||
|
.addMember("callSuper", "false")
|
||||||
|
.build())
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
//public <E extends FrontClassifyCreateCommand> void update(E cmd) {
|
||||||
|
// Beans.copyPropertiesIgnoreNull(cmd, this);
|
||||||
|
// }
|
||||||
|
;
|
||||||
|
|
||||||
|
if(Cons.C) {
|
||||||
|
builder.addMethod(MethodSpec.methodBuilder("update")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.returns(void.class)
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.create.toClassName(), "cmd").build())
|
||||||
|
// .addStatement("$T.copyPropertiesIgnoreNull(cmd, this)", ClassName.get("cn.qutaojing.common.utils", "Beans"))
|
||||||
|
.addStatement("$T.copyProperties(cmd, this)", ClassName.get("cn.qutaojing.common.utils", "Beans"))
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix; // + "Entity";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.SERVER_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.ENTITY_PACKAGE, ddd.module, ddd.e);
|
||||||
|
}
|
||||||
|
}
|
||||||
74
src/test/java/rp/lee/jpa/ddd/FactoryGen.java
Normal file
74
src/test/java/rp/lee/jpa/ddd/FactoryGen.java
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.ParameterSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
public class FactoryGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
ClassName slef = ClassName.get(packagePath(ddd), className(ddd));
|
||||||
|
|
||||||
|
Builder builder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(Component.class)
|
||||||
|
.addAnnotation(Lazy.class)
|
||||||
|
|
||||||
|
.addMethod(MethodSpec.methodBuilder("of")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addModifiers(Modifier.STATIC)
|
||||||
|
.returns(slef)
|
||||||
|
.addStatement("return $T.getBean($T.class)", ClassName.get("cn.qutaojing.common.utils", "SpringUtils"), slef)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
// .addMethod(MethodSpec.methodBuilder("entity")
|
||||||
|
// .addModifiers(Modifier.PUBLIC)
|
||||||
|
// .addParameter(ddd.put.toClassName(), "request")
|
||||||
|
// .returns(ddd.entity.toClassName())
|
||||||
|
// .addStatement("return $T.mapper(request, $T.class)", ClassName.get("cn.qutaojing.common.utils", "Beans"), ddd.entity.toClassName())
|
||||||
|
// .build()
|
||||||
|
// )
|
||||||
|
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)));
|
||||||
|
if(Cons.C) {
|
||||||
|
builder.addMethod(MethodSpec.methodBuilder("from")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.returns(ddd.entity.toClassName())
|
||||||
|
.addParameter(ParameterSpec.builder(ddd.create.toClassName(), "cmd").build())
|
||||||
|
.addStatement("$T e = $T.builder().build()", ddd.entity.toClassName(), ddd.entity.toClassName())
|
||||||
|
.addStatement("e.update(cmd)")
|
||||||
|
.addStatement("return e")
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "Factory";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.SERVER_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.FACTORY_PACKAGE, ddd.module, ddd.e);
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/test/java/rp/lee/jpa/ddd/IClassGenerate.java
Normal file
21
src/test/java/rp/lee/jpa/ddd/IClassGenerate.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import com.ag.utils.DateUtils;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
public interface IClassGenerate {
|
||||||
|
Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception;
|
||||||
|
String className(DDD ddd);
|
||||||
|
String folerPath(DDD ddd);
|
||||||
|
String packagePath(DDD ddd);
|
||||||
|
|
||||||
|
default void addAuthor(Builder builder) {
|
||||||
|
builder
|
||||||
|
.addJavadoc("\n")
|
||||||
|
.addJavadoc(String.format("@author %s \n", "rplees"))
|
||||||
|
.addJavadoc(String.format("@email %s \n", "rplees.i.ly@gmail.com"))
|
||||||
|
.addJavadoc(String.format("@created %s \n", DateUtils.nowDate("yyyy/MM/dd")));
|
||||||
|
}
|
||||||
|
}
|
||||||
56
src/test/java/rp/lee/jpa/ddd/ModifyGen.java
Normal file
56
src/test/java/rp/lee/jpa/ddd/ModifyGen.java
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.FieldSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
public class ModifyGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
Builder classBuilder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
.addJavadoc(rs.getString("REMARKS"))
|
||||||
|
.addJavadoc("")
|
||||||
|
.addAnnotation(Data.class)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(ClassName.get("lombok.experimental", "SuperBuilder")).build())
|
||||||
|
.addAnnotation(NoArgsConstructor.class)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(ClassName.get("lombok", "EqualsAndHashCode"))
|
||||||
|
.addMember("callSuper", "false")
|
||||||
|
.build())
|
||||||
|
.superclass(ddd.create.toClassName())
|
||||||
|
;
|
||||||
|
|
||||||
|
com.squareup.javapoet.FieldSpec.Builder fieldBuilder = FieldSpec
|
||||||
|
.builder(Integer.class,
|
||||||
|
"id");
|
||||||
|
classBuilder.addField(fieldBuilder.build());
|
||||||
|
|
||||||
|
return classBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "ModifyCommand";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.CLIENT_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.MODIFY_PACKAGE, ddd.module);
|
||||||
|
}
|
||||||
|
}
|
||||||
158
src/test/java/rp/lee/jpa/ddd/POGen.java
Normal file
158
src/test/java/rp/lee/jpa/ddd/POGen.java
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.hibernate.annotations.CreationTimestamp;
|
||||||
|
import org.hibernate.annotations.DynamicInsert;
|
||||||
|
import org.hibernate.annotations.DynamicUpdate;
|
||||||
|
import org.hibernate.annotations.UpdateTimestamp;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.FieldSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import rp.lee.jpa.entity.ColumnStyle;
|
||||||
|
import rp.lee.jpa.entity.Utils;
|
||||||
|
|
||||||
|
public class POGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
String primaryKey = ""; //TODO:目前之支持一个主键
|
||||||
|
String tableName = "";
|
||||||
|
|
||||||
|
Builder classBuilder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
// .addJavadoc(rs.getString("REMARKS"))
|
||||||
|
.addJavadoc("")
|
||||||
|
.addAnnotation(AnnotationSpec.builder(ClassName.get("lombok.experimental", "SuperBuilder")).build())
|
||||||
|
.addAnnotation(Data.class)
|
||||||
|
.addAnnotation(NoArgsConstructor.class)
|
||||||
|
.addAnnotation(AllArgsConstructor.class);
|
||||||
|
if(conn != null) {
|
||||||
|
tableName = rs.getString("TABLE_NAME");
|
||||||
|
DatabaseMetaData metaData = conn.getMetaData();
|
||||||
|
ResultSet primaryKeyResultSet = metaData.getPrimaryKeys(conn.getCatalog(),null, tableName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
while(primaryKeyResultSet.next()){
|
||||||
|
primaryKey = primaryKeyResultSet.getString("COLUMN_NAME");
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
primaryKeyResultSet.close();
|
||||||
|
} catch(Exception e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(StringUtils.isBlank(primaryKey)) {//没有主键的不生成
|
||||||
|
System.err.println(String.format("表[%s]没有主键, 将跳过", tableName));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
classBuilder.addJavadoc(rs.getString("REMARKS"))
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Entity.class).build())
|
||||||
|
.addAnnotation(AnnotationSpec.builder(DynamicInsert.class).build())
|
||||||
|
.addAnnotation(AnnotationSpec.builder(DynamicUpdate.class).build())
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Table.class)
|
||||||
|
.addMember("name", "\"" + tableName + "\"").build());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
primaryKey = "id";
|
||||||
|
}
|
||||||
|
|
||||||
|
buildFields(ddd, conn, tableName, primaryKey, classBuilder);
|
||||||
|
return classBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void buildFields(DDD ddd, Connection conn, String tableName, String primaryKey, Builder classBuilder) throws SQLException {
|
||||||
|
if(conn == null) {
|
||||||
|
ddd.poPK = Long.class;
|
||||||
|
ddd.poPKKey = primaryKey;
|
||||||
|
} else {
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
DatabaseMetaData metaData = conn.getMetaData();
|
||||||
|
rs = metaData.getColumns(null, "%", tableName, "%");
|
||||||
|
while (rs.next()) {
|
||||||
|
String columnName = rs.getString("COLUMN_NAME");
|
||||||
|
String filedName = Utils.columnNameToFieldName(columnName, ColumnStyle.defaultColumnStyle);
|
||||||
|
|
||||||
|
int dataType = rs.getInt("DATA_TYPE");
|
||||||
|
String remarks = rs.getString("REMARKS");
|
||||||
|
String IS_AUTOINCREMENT = rs.getString("IS_AUTOINCREMENT");
|
||||||
|
|
||||||
|
com.squareup.javapoet.FieldSpec.Builder fieldBuilder = FieldSpec
|
||||||
|
.builder(Utils.dataTypeToFieldType(columnName, dataType), filedName)
|
||||||
|
.addJavadoc(remarks);
|
||||||
|
|
||||||
|
if(StringUtils.equals(primaryKey, columnName)) {
|
||||||
|
fieldBuilder.addAnnotation(Id.class);
|
||||||
|
//主键类型
|
||||||
|
ddd.poPK = Utils.dataTypeToFieldType(filedName, dataType);
|
||||||
|
ddd.poPKKey = filedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if("create_time".equalsIgnoreCase(columnName) || "create_at".equalsIgnoreCase(columnName)) {
|
||||||
|
fieldBuilder.addAnnotation(CreationTimestamp.class);
|
||||||
|
fieldBuilder.addAnnotation(AnnotationSpec.builder(Column.class).addMember("updatable", "false").build());
|
||||||
|
}
|
||||||
|
|
||||||
|
if("update_time".equalsIgnoreCase(columnName) || "update_at".equalsIgnoreCase(columnName)) {
|
||||||
|
fieldBuilder.addAnnotation(UpdateTimestamp.class);
|
||||||
|
}
|
||||||
|
if("YES".equals(IS_AUTOINCREMENT)) {
|
||||||
|
AnnotationSpec generatedValue = AnnotationSpec.builder(ClassName.get("javax.persistence", "GeneratedValue"))
|
||||||
|
.addMember("strategy", "javax.persistence.GenerationType.IDENTITY")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
fieldBuilder.addAnnotation(generatedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
classBuilder.addField(fieldBuilder.build());
|
||||||
|
/**
|
||||||
|
* 参考资料 https://www.cnblogs.com/lbangel/p/3487796.html
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (rs != null) {
|
||||||
|
try {
|
||||||
|
rs.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "PO";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.SERVER_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.PO_PACKAGE, ddd.module);
|
||||||
|
}
|
||||||
|
}
|
||||||
60
src/test/java/rp/lee/jpa/ddd/POMongoGen.java
Normal file
60
src/test/java/rp/lee/jpa/ddd/POMongoGen.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
public class POMongoGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
String primaryKey = ""; //TODO:目前之支持一个主键
|
||||||
|
String tableName = "";
|
||||||
|
|
||||||
|
Builder classBuilder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
// .addJavadoc(rs.getString("REMARKS"))
|
||||||
|
.addJavadoc("")
|
||||||
|
.addAnnotation(AnnotationSpec.builder(ClassName.get("lombok.experimental", "SuperBuilder")).build())
|
||||||
|
.addAnnotation(Data.class)
|
||||||
|
.addAnnotation(NoArgsConstructor.class)
|
||||||
|
.addAnnotation(AllArgsConstructor.class);
|
||||||
|
primaryKey = "id";
|
||||||
|
|
||||||
|
buildFields(ddd, conn, tableName, primaryKey, classBuilder);
|
||||||
|
return classBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void buildFields(DDD ddd, Connection conn, String tableName, String primaryKey, Builder classBuilder) throws SQLException {
|
||||||
|
ddd.poPK = Long.class;
|
||||||
|
ddd.poPKKey = primaryKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "PO";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.SERVER_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.PO_MONGO_PACKAGE, ddd.module);
|
||||||
|
}
|
||||||
|
}
|
||||||
87
src/test/java/rp/lee/jpa/ddd/PutGen.java
Normal file
87
src/test/java/rp/lee/jpa/ddd/PutGen.java
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.FieldSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import rp.lee.jpa.entity.ColumnStyle;
|
||||||
|
import rp.lee.jpa.entity.Utils;
|
||||||
|
|
||||||
|
public class PutGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
String tableName = rs.getString("TABLE_NAME");
|
||||||
|
Builder classBuilder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
.addJavadoc(rs.getString("REMARKS"))
|
||||||
|
.addJavadoc("")
|
||||||
|
.addAnnotation(Data.class)
|
||||||
|
.addAnnotation(lombok.Builder.class)
|
||||||
|
.addAnnotation(NoArgsConstructor.class)
|
||||||
|
.addAnnotation(AllArgsConstructor.class)
|
||||||
|
;
|
||||||
|
|
||||||
|
buildFields(ddd, conn, tableName, classBuilder);
|
||||||
|
return classBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void buildFields(DDD ddd, Connection conn, String tableName, Builder classBuilder) throws SQLException {
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
DatabaseMetaData metaData = conn.getMetaData();
|
||||||
|
rs = metaData.getColumns(null, "%", tableName, "%");
|
||||||
|
while (rs.next()) {
|
||||||
|
String columnName = rs.getString("COLUMN_NAME");
|
||||||
|
int dataType = rs.getInt("DATA_TYPE");
|
||||||
|
String remarks = rs.getString("REMARKS");
|
||||||
|
String fieldName = Utils.columnNameToFieldName(columnName, ColumnStyle.defaultColumnStyle);
|
||||||
|
if("createTime".equals(fieldName) || "updateTime".equals(fieldName)) {//忽略
|
||||||
|
|
||||||
|
} else {
|
||||||
|
com.squareup.javapoet.FieldSpec.Builder fieldBuilder = FieldSpec
|
||||||
|
.builder(Utils.dataTypeToFieldType(columnName, dataType),
|
||||||
|
fieldName)
|
||||||
|
.addJavadoc(remarks);
|
||||||
|
|
||||||
|
classBuilder.addField(fieldBuilder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (rs != null) {
|
||||||
|
try {
|
||||||
|
rs.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "PutRequest";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.CLIENT_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.PUT_PACKAGE, ddd.module);
|
||||||
|
}
|
||||||
|
}
|
||||||
110
src/test/java/rp/lee/jpa/ddd/QueryGen.java
Normal file
110
src/test/java/rp/lee/jpa/ddd/QueryGen.java
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.FieldSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import rp.lee.jpa.entity.ColumnStyle;
|
||||||
|
import rp.lee.jpa.entity.Utils;
|
||||||
|
|
||||||
|
public class QueryGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
String tableName = rs.getString("TABLE_NAME");
|
||||||
|
Builder classBuilder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
.addJavadoc(rs.getString("REMARKS"))
|
||||||
|
.addJavadoc("")
|
||||||
|
.addAnnotation(Data.class)
|
||||||
|
.addAnnotation(lombok.Builder.class)
|
||||||
|
.addAnnotation(NoArgsConstructor.class)
|
||||||
|
.addAnnotation(AllArgsConstructor.class)
|
||||||
|
;
|
||||||
|
|
||||||
|
buildFields(ddd, conn, tableName, classBuilder);
|
||||||
|
return classBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void buildFields(DDD ddd, Connection conn, String tableName, Builder classBuilder) throws SQLException {
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
DatabaseMetaData metaData = conn.getMetaData();
|
||||||
|
rs = metaData.getColumns(null, "%", tableName, "%");
|
||||||
|
while (rs.next()) {
|
||||||
|
String columnName = rs.getString("COLUMN_NAME");
|
||||||
|
int dataType = rs.getInt("DATA_TYPE");
|
||||||
|
String remarks = rs.getString("REMARKS");
|
||||||
|
String fieldName = Utils.columnNameToFieldName(columnName, ColumnStyle.defaultColumnStyle);
|
||||||
|
|
||||||
|
if("createTime".equals(fieldName)) {
|
||||||
|
com.squareup.javapoet.FieldSpec.Builder fieldBuilder = FieldSpec
|
||||||
|
.builder(Utils.dataTypeToFieldType(columnName, dataType), "start" + StringUtils.capitalize(fieldName))
|
||||||
|
.addJavadoc(remarks);
|
||||||
|
fieldBuilder.addAnnotation(AnnotationSpec.builder(ClassName.get("cn.qutaojing.common.jpa", "QueryCriteria"))
|
||||||
|
.addMember("type", "$T.GREATER_THAN", ClassName.get("cn.qutaojing.common.jpa.QueryCriteria", "Type"))
|
||||||
|
.addMember("propName", "\"" + fieldName + "\"")
|
||||||
|
.build());
|
||||||
|
|
||||||
|
com.squareup.javapoet.FieldSpec.Builder fieldBuilder2 = FieldSpec
|
||||||
|
.builder(Utils.dataTypeToFieldType(columnName, dataType), "end" + StringUtils.capitalize(fieldName))
|
||||||
|
.addJavadoc(remarks);
|
||||||
|
fieldBuilder2.addAnnotation(AnnotationSpec.builder(ClassName.get("cn.qutaojing.common.jpa", "QueryCriteria"))
|
||||||
|
.addMember("type", "$T.LESS_THAN", ClassName.get("cn.qutaojing.common.jpa.QueryCriteria", "Type"))
|
||||||
|
.addMember("propName", "\"" + fieldName + "\"")
|
||||||
|
.build());
|
||||||
|
|
||||||
|
classBuilder.addField(fieldBuilder.build());
|
||||||
|
classBuilder.addField(fieldBuilder2.build());
|
||||||
|
} else if("updateTime".equals(fieldName)) {//忽略
|
||||||
|
|
||||||
|
} else {
|
||||||
|
com.squareup.javapoet.FieldSpec.Builder fieldBuilder = FieldSpec
|
||||||
|
.builder(Utils.dataTypeToFieldType(columnName, dataType), fieldName)
|
||||||
|
.addJavadoc(remarks);
|
||||||
|
fieldBuilder.addAnnotation(AnnotationSpec.builder(ClassName.get("cn.qutaojing.common.jpa", "QueryCriteria"))
|
||||||
|
.addMember("type", "$T.EQUAL", ClassName.get("cn.qutaojing.common.jpa.QueryCriteria", "Type")).build());
|
||||||
|
classBuilder.addField(fieldBuilder.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (rs != null) {
|
||||||
|
try {
|
||||||
|
rs.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "Query";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.CLIENT_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.QUERY_PACKAGE, ddd.module);
|
||||||
|
}
|
||||||
|
}
|
||||||
47
src/test/java/rp/lee/jpa/ddd/RepoGen.java
Normal file
47
src/test/java/rp/lee/jpa/ddd/RepoGen.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import com.rp.spring.jpa.GenericJpaRepository;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
|
import com.squareup.javapoet.TypeName;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
public class RepoGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
//生成DAO
|
||||||
|
Builder daoClassBuilder = TypeSpec.interfaceBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addSuperinterface(ParameterizedTypeName.get(ClassName.get(GenericJpaRepository.class),
|
||||||
|
ddd.po.toClassName(),
|
||||||
|
TypeName.get(ddd.poPK)))
|
||||||
|
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
;
|
||||||
|
|
||||||
|
return daoClassBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "Repo";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.SERVER_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.REPO_PACKAGE, ddd.module);
|
||||||
|
}
|
||||||
|
}
|
||||||
46
src/test/java/rp/lee/jpa/ddd/RepoMongoGen.java
Normal file
46
src/test/java/rp/lee/jpa/ddd/RepoMongoGen.java
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
|
import com.squareup.javapoet.TypeName;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
public class RepoMongoGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
ClassName className = ClassName.get("cn.qutaojing.data.analyse.infrastructure.mongodb.core", "GenericMongoRepository");
|
||||||
|
//生成DAO
|
||||||
|
Builder daoClassBuilder = TypeSpec.interfaceBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addSuperinterface(ParameterizedTypeName.get(className,
|
||||||
|
ddd.po.toClassName(),
|
||||||
|
TypeName.get(ddd.poPK)))
|
||||||
|
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
;
|
||||||
|
|
||||||
|
return daoClassBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "Repo";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.SERVER_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.REPO_MONGO_PACKAGE, ddd.module);
|
||||||
|
}
|
||||||
|
}
|
||||||
104
src/test/java/rp/lee/jpa/ddd/RepositoryGen.java
Normal file
104
src/test/java/rp/lee/jpa/ddd/RepositoryGen.java
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import com.rp.spring.jpa.GenericJpaRepository;
|
||||||
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.FieldSpec;
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
|
import com.squareup.javapoet.TypeName;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
import com.squareup.javapoet.TypeVariableName;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
public class RepositoryGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
ClassName slef = ClassName.get(packagePath(ddd), className(ddd));
|
||||||
|
|
||||||
|
Builder builder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(org.springframework.stereotype.Repository.class)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RequiredArgsConstructor.class).addMember("onConstructor", "@__(@$T)", ClassName.get(Autowired.class)).build())
|
||||||
|
.superclass(ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common.domain.respostory", "SimplePoConvertEntityRepository"),
|
||||||
|
ddd.entity.toClassName(),
|
||||||
|
ddd.po.toClassName(),
|
||||||
|
TypeName.get(ddd.poPK)))
|
||||||
|
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)));
|
||||||
|
|
||||||
|
if(StringUtils.isNotBlank(ddd.poPKKey)) { //有主键
|
||||||
|
// builder.addMethod(MethodSpec.methodBuilder("save")
|
||||||
|
// .addModifiers(Modifier.PUBLIC)
|
||||||
|
// .addAnnotation(AnnotationSpec.builder(Override.class).build())
|
||||||
|
// .addParameter(ParameterSpec.builder(ddd.entity.toClassName(), "entity").build())
|
||||||
|
// .returns(void.class)
|
||||||
|
//
|
||||||
|
// .addStatement("$T po = repo().save(convert().toPo(entity));", ddd.po.toClassName())
|
||||||
|
// .addStatement(String.format("entity.set%s(po.get%s())", StringUtils.capitalize(ddd.poPKKey), StringUtils.capitalize(ddd.poPKKey)))
|
||||||
|
// .build()
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
builder.addField(FieldSpec.builder(ddd.repo.toClassName(), "repo").addModifiers(Modifier.FINAL).build())
|
||||||
|
.addMethod(MethodSpec.methodBuilder("repo")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Override.class).build())
|
||||||
|
.returns(ParameterizedTypeName.get(ClassName.get(GenericJpaRepository.class),
|
||||||
|
ddd.po.toClassName(),
|
||||||
|
TypeName.get(ddd.poPK)))
|
||||||
|
.addStatement("return $T", TypeVariableName.get("repo"))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
.addField(FieldSpec.builder(ddd.convert.toClassName(), "convert").addModifiers(Modifier.FINAL).build())
|
||||||
|
.addMethod(MethodSpec.methodBuilder("convert")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Override.class).build())
|
||||||
|
.returns(
|
||||||
|
ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common.domain.convert", "IEntityPOConvert"),
|
||||||
|
ddd.entity.toClassName(), ddd.po.toClassName()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.addStatement("return $T", TypeVariableName.get("convert"))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
.addMethod(MethodSpec.methodBuilder("of")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addModifiers(Modifier.STATIC)
|
||||||
|
.returns(slef)
|
||||||
|
.addStatement("return $T.getBean($T.class)", ClassName.get("cn.qutaojing.common.utils", "SpringUtils"), slef)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "Repository";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.SERVER_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.REPOSITORY_PACKAGE, ddd.module, ddd.e);
|
||||||
|
}
|
||||||
|
}
|
||||||
97
src/test/java/rp/lee/jpa/ddd/RepositoryMongoGen.java
Normal file
97
src/test/java/rp/lee/jpa/ddd/RepositoryMongoGen.java
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import com.rp.spring.jpa.GenericJpaRepository;
|
||||||
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.FieldSpec;
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
|
import com.squareup.javapoet.TypeName;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
import com.squareup.javapoet.TypeVariableName;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
public class RepositoryMongoGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
ClassName className = ClassName.get("cn.qutaojing.data.analyse.infrastructure.mongodb.core", "GenericMongoRepository");
|
||||||
|
|
||||||
|
Builder builder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(org.springframework.stereotype.Repository.class)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RequiredArgsConstructor.class).addMember("onConstructor", "@__(@$T)", ClassName.get(Autowired.class)).build())
|
||||||
|
.superclass(ParameterizedTypeName.get(ClassName.get("cn.qutaojing.dataanalyse.infrastructure.mongodb.core", "SimplePoConvertEntityMongoRepository"),
|
||||||
|
ddd.entity.toClassName(),
|
||||||
|
ddd.po.toClassName(),
|
||||||
|
TypeName.get(ddd.poPK)))
|
||||||
|
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)));
|
||||||
|
|
||||||
|
if(StringUtils.isNotBlank(ddd.poPKKey)) { //有主键
|
||||||
|
// builder.addMethod(MethodSpec.methodBuilder("save")
|
||||||
|
// .addModifiers(Modifier.PUBLIC)
|
||||||
|
// .addAnnotation(AnnotationSpec.builder(Override.class).build())
|
||||||
|
// .addParameter(ParameterSpec.builder(ddd.entity.toClassName(), "entity").build())
|
||||||
|
// .returns(void.class)
|
||||||
|
//
|
||||||
|
// .addStatement("$T po = repo().save(convert().toPo(entity));", ddd.po.toClassName())
|
||||||
|
// .addStatement(String.format("entity.set%s(po.get%s())", StringUtils.capitalize(ddd.poPKKey), StringUtils.capitalize(ddd.poPKKey)))
|
||||||
|
// .build()
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
builder.addField(FieldSpec.builder(ddd.repo.toClassName(), "repo").addModifiers(Modifier.FINAL).build())
|
||||||
|
.addMethod(MethodSpec.methodBuilder("repo")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Override.class).build())
|
||||||
|
.returns(ParameterizedTypeName.get(className,
|
||||||
|
ddd.po.toClassName(),
|
||||||
|
TypeName.get(ddd.poPK)))
|
||||||
|
.addStatement("return $T", TypeVariableName.get("repo"))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
.addField(FieldSpec.builder(ddd.convert.toClassName(), "convert").addModifiers(Modifier.FINAL).build())
|
||||||
|
.addMethod(MethodSpec.methodBuilder("convert")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(Override.class).build())
|
||||||
|
.returns(
|
||||||
|
ParameterizedTypeName.get(ClassName.get("cn.qutaojing.common.domain.convert", "IEntityPOConvert"),
|
||||||
|
ddd.entity.toClassName(), ddd.po.toClassName()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.addStatement("return $T", TypeVariableName.get("convert"))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "Repository";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.SERVER_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.REPOSITORY_PACKAGE, ddd.module, ddd.e);
|
||||||
|
}
|
||||||
|
}
|
||||||
82
src/test/java/rp/lee/jpa/ddd/ServiceGen.java
Normal file
82
src/test/java/rp/lee/jpa/ddd/ServiceGen.java
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.AnnotationSpec;
|
||||||
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.FieldSpec;
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
import com.squareup.javapoet.TypeVariableName;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
public class ServiceGen implements IClassGenerate {
|
||||||
|
@Override
|
||||||
|
public Builder builder(DDD ddd, Connection conn, ResultSet rs) throws Exception {
|
||||||
|
ClassName slef = ClassName.get(packagePath(ddd), className(ddd));
|
||||||
|
|
||||||
|
Builder serviceClassBuilder = TypeSpec.classBuilder(className(ddd))
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(org.springframework.stereotype.Service.class)
|
||||||
|
.addAnnotation(AnnotationSpec.builder(RequiredArgsConstructor.class).addMember("onConstructor", "@__(@$T)", ClassName.get(Autowired.class)).build())
|
||||||
|
// .addAnnotation(Transactional.class)
|
||||||
|
.addJavadoc(String.format("%s \n", className(ddd)))
|
||||||
|
|
||||||
|
.addField(FieldSpec.builder(ddd.repository.toClassName(), "repository").addModifiers(Modifier.FINAL).build())
|
||||||
|
.addField(FieldSpec.builder(ddd.factory.toClassName(), "factory").addModifiers(Modifier.FINAL).build())
|
||||||
|
|
||||||
|
.addMethod(MethodSpec.methodBuilder("repository")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.returns(ddd.repository.toClassName())
|
||||||
|
.addStatement("return $T", TypeVariableName.get("repository"))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
.addMethod(MethodSpec.methodBuilder("of")
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addModifiers(Modifier.STATIC)
|
||||||
|
.returns(slef)
|
||||||
|
.addStatement("return $T.getBean($T.class)", ClassName.get("cn.qutaojing.common.utils", "SpringUtils"), slef)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
|
// .addMethod(MethodSpec.methodBuilder("update")
|
||||||
|
// .addModifiers(Modifier.PUBLIC)
|
||||||
|
// .addParameter(ParameterSpec.builder(ddd.poPK, "id").build())
|
||||||
|
// .addParameter(ParameterSpec.builder(ddd.entity.toClassName(), "updateEntity").build())
|
||||||
|
// .returns(ddd.entity.toClassName())
|
||||||
|
// .addStatement("$T entity = repository().findById(id).orElseThrow($T::new)", ddd.entity.toClassName(), ClassName.get("com.ag.exception", "EntityNotFoundException"))
|
||||||
|
// .addStatement("$T.copyPropertiesIgnoreNull(updateEntity, entity)", ClassName.get("cn.qutaojing.common.utils", "Beans"))
|
||||||
|
// .addStatement("return repository().save(entity)")
|
||||||
|
//
|
||||||
|
// .build()
|
||||||
|
// )
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
return serviceClassBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String className(DDD ddd) {
|
||||||
|
return ddd.entityPrefix + "Service";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String folerPath(DDD ddd) {
|
||||||
|
return Cons.SERVER_FOLDER_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String packagePath(DDD ddd) {
|
||||||
|
return String.format(Cons.SERVICE_PACKAGE, ddd.module, ddd.e);
|
||||||
|
}
|
||||||
|
}
|
||||||
98
src/test/java/rp/lee/jpa/ddd/ToolDDD.java
Normal file
98
src/test/java/rp/lee/jpa/ddd/ToolDDD.java
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.JavaFile;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
import rp.lee.jpa.entity.Utils;
|
||||||
|
|
||||||
|
public class ToolDDD {
|
||||||
|
|
||||||
|
public static void g(Connection conn) throws Exception {
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String catalog = conn.getCatalog();
|
||||||
|
DatabaseMetaData metaData = conn.getMetaData();
|
||||||
|
rs = metaData.getTables(catalog, null, null, new String[] { "TABLE" });
|
||||||
|
while (rs.next()) {
|
||||||
|
String tableName = rs.getString("TABLE_NAME");
|
||||||
|
boolean pass = Cons.tableNameToEntiyMapping.keySet().contains(tableName);
|
||||||
|
if(pass) {
|
||||||
|
buildDDD(conn, rs, Cons.module, Cons.entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (rs != null) {
|
||||||
|
try {
|
||||||
|
rs.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildDDD(Connection conn, ResultSet rs, String module, String e) throws Exception {
|
||||||
|
DDD ddd = new DDD(module, e);
|
||||||
|
String tableName = rs.getString("TABLE_NAME");
|
||||||
|
|
||||||
|
String entity = Cons.tableNameToEntiyMapping.get(tableName);
|
||||||
|
if(StringUtils.isBlank(entity)) {
|
||||||
|
entity = Utils.tableNameToEntityName(tableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
ddd.entityPrefix = entity;
|
||||||
|
|
||||||
|
make(conn, rs, ddd, new POGen(), vo -> ddd.po = vo );
|
||||||
|
make(conn, rs, ddd, new CreateGen(), vo -> ddd.create = vo );
|
||||||
|
make(conn, rs, ddd, new ModifyGen(), vo -> ddd.modify = vo );
|
||||||
|
make(conn, rs, ddd, new EntityGen(), vo -> ddd.entity = vo );
|
||||||
|
make(conn, rs, ddd, new DTOGen(), vo -> ddd.dto = vo);
|
||||||
|
|
||||||
|
make(conn, rs, ddd, new ConvertGen(), vo -> ddd.convert = vo);
|
||||||
|
make(conn, rs, ddd, new AssemblerGen(), vo -> ddd.assembler = vo);
|
||||||
|
make(conn, rs, ddd, new FactoryGen(), vo -> ddd.factory = vo);
|
||||||
|
|
||||||
|
make(conn, rs, ddd, new RepoGen(), vo -> ddd.repo = vo);
|
||||||
|
make(conn, rs, ddd, new RepositoryGen(), vo -> ddd.repository = vo);
|
||||||
|
make(conn, rs, ddd, new ServiceGen(), vo -> ddd.service = vo);
|
||||||
|
|
||||||
|
// make(conn, rs, ddd, new ApiGen(), vo -> ddd.api = vo);
|
||||||
|
// make(conn, rs, ddd, new ApiFeignGen(), vo -> ddd.apiFeign = vo);
|
||||||
|
// make(conn, rs, ddd, new ApiImplGen(), vo -> ddd.apiImplGen = vo);
|
||||||
|
// make(conn, rs, ddd, new PutGen(), vo -> ddd.put = vo);
|
||||||
|
// make(conn, rs, ddd, new QueryGen(), vo -> ddd.query = vo);
|
||||||
|
|
||||||
|
List<ClassVO> list = ddd.list();
|
||||||
|
for (ClassVO classVO : list) {
|
||||||
|
if(classVO == null) continue;
|
||||||
|
JavaFile javaFile = JavaFile.builder(classVO.packagePath, classVO.builder.build())
|
||||||
|
.build();
|
||||||
|
javaFile.writeTo(System.out);
|
||||||
|
javaFile.writeTo(Paths.get(classVO.folderPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ClassVO make(Connection conn, ResultSet rs, DDD ddd, IClassGenerate ig, Consumer<ClassVO> c) throws Exception {
|
||||||
|
Builder builder = ig.builder(ddd, conn, rs);
|
||||||
|
ig.addAuthor(builder);
|
||||||
|
|
||||||
|
ClassVO vo = ClassVO.builder()
|
||||||
|
.builder(builder)
|
||||||
|
.className(ig.className(ddd))
|
||||||
|
.folderPath(ig.folerPath(ddd))
|
||||||
|
.packagePath(ig.packagePath(ddd))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
c.accept(vo);
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
}
|
||||||
73
src/test/java/rp/lee/jpa/ddd/ToolDDDMongo.java
Normal file
73
src/test/java/rp/lee/jpa/ddd/ToolDDDMongo.java
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package rp.lee.jpa.ddd;
|
||||||
|
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.JavaFile;
|
||||||
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
|
||||||
|
import rp.lee.jpa.entity.Utils;
|
||||||
|
|
||||||
|
public class ToolDDDMongo {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void g() throws Exception {
|
||||||
|
for(Map.Entry<String, String> entry : Cons.tableNameToEntiyMapping.entrySet()) {
|
||||||
|
String entity = entry.getValue();
|
||||||
|
if(StringUtils.isBlank(entity)) {
|
||||||
|
entity = Utils.tableNameToEntityName(entry.getKey());
|
||||||
|
}
|
||||||
|
buildDDD(entity,Cons.module, Cons.entity);
|
||||||
|
}
|
||||||
|
Cons.tableNameToEntiyMapping.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void buildDDD(String entity, String module, String e) throws Exception {
|
||||||
|
DDD ddd = new DDD(module, e);
|
||||||
|
ddd.entityPrefix = entity;
|
||||||
|
|
||||||
|
make(ddd, new POMongoGen(), vo -> ddd.po = vo );
|
||||||
|
make(ddd, new EntityGen(), vo -> ddd.entity = vo );
|
||||||
|
make(ddd, new DTOGen(), vo -> ddd.dto = vo);
|
||||||
|
|
||||||
|
make(ddd, new ConvertGen(), vo -> ddd.convert = vo);
|
||||||
|
make(ddd, new AssemblerGen(), vo -> ddd.assembler = vo);
|
||||||
|
make(ddd, new FactoryGen(), vo -> ddd.factory = vo);
|
||||||
|
|
||||||
|
make(ddd, new RepoMongoGen(), vo -> ddd.repo = vo);
|
||||||
|
make(ddd, new RepositoryMongoGen(), vo -> ddd.repository = vo);
|
||||||
|
make(ddd, new ServiceGen(), vo -> ddd.service = vo);
|
||||||
|
|
||||||
|
List<ClassVO> list = ddd.mongoList();
|
||||||
|
for (ClassVO classVO : list) {
|
||||||
|
if(classVO == null) continue;
|
||||||
|
JavaFile javaFile = JavaFile.builder(classVO.packagePath, classVO.builder.build())
|
||||||
|
.build();
|
||||||
|
System.out.println("路径:::" + Paths.get(classVO.folderPath) + "/" + classVO.packagePath);
|
||||||
|
javaFile.writeTo(System.out);
|
||||||
|
javaFile.writeTo(Paths.get(classVO.folderPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ClassVO make(DDD ddd, IClassGenerate ig, Consumer<ClassVO> c) throws Exception {
|
||||||
|
Builder builder = ig.builder(ddd, null, null);
|
||||||
|
ig.addAuthor(builder);
|
||||||
|
|
||||||
|
ClassVO vo = ClassVO.builder()
|
||||||
|
.builder(builder)
|
||||||
|
.className(ig.className(ddd))
|
||||||
|
.folderPath(ig.folerPath(ddd))
|
||||||
|
.packagePath(ig.packagePath(ddd))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
c.accept(vo);
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/test/java/rp/lee/jpa/entity/ColumnStyle.java
Normal file
10
src/test/java/rp/lee/jpa/entity/ColumnStyle.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package rp.lee.jpa.entity;
|
||||||
|
|
||||||
|
public enum ColumnStyle {
|
||||||
|
/**原值*/
|
||||||
|
normal,
|
||||||
|
/**下划线转驼峰*/
|
||||||
|
lowercaseTocamelhump;
|
||||||
|
|
||||||
|
public static ColumnStyle defaultColumnStyle = lowercaseTocamelhump;
|
||||||
|
}
|
||||||
60
src/test/java/rp/lee/jpa/entity/Utils.java
Normal file
60
src/test/java/rp/lee/jpa/entity/Utils.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package rp.lee.jpa.entity;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.ArrayUtils;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
public class Utils {
|
||||||
|
public static String tableNameToEntityName(String tableName) {
|
||||||
|
String[] split = StringUtils.split(tableName, '_');
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
for (String string : split) {
|
||||||
|
buffer.append(StringUtils.capitalize(string));
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String columnNameToFieldName(String columnName, ColumnStyle columnStyle) {
|
||||||
|
if(ColumnStyle.normal == columnStyle) {
|
||||||
|
return columnName;
|
||||||
|
} else if(ColumnStyle.lowercaseTocamelhump == columnStyle) {
|
||||||
|
columnName = StringUtils.lowerCase(columnName);
|
||||||
|
//user_id_string ==> userIdString
|
||||||
|
String[] split = StringUtils.split(columnName, '_');
|
||||||
|
if(split.length <= 1) return columnName;
|
||||||
|
|
||||||
|
StringBuffer buffer = new StringBuffer(split[0]);
|
||||||
|
for (int i = 1; i < split.length; i++) {
|
||||||
|
buffer.append(StringUtils.capitalize(split[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
//other
|
||||||
|
return columnName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type dataTypeToFieldType(String columnName, int dataType) {
|
||||||
|
if (ArrayUtils.contains(new int[] { Types.TINYINT, Types.SMALLINT, Types.INTEGER }, dataType)) {// int.class
|
||||||
|
return Integer.class;
|
||||||
|
} else if (ArrayUtils.contains(new int[] { Types.FLOAT, Types.DOUBLE, Types.NUMERIC, },
|
||||||
|
dataType)) {// double.class
|
||||||
|
return Double.class;
|
||||||
|
} else if (ArrayUtils.contains(new int[] {Types.DECIMAL },
|
||||||
|
dataType)) {// double.class
|
||||||
|
return BigDecimal.class;
|
||||||
|
} else if (ArrayUtils.contains(new int[] { Types.BIGINT }, dataType)) {
|
||||||
|
return Long.class;
|
||||||
|
} else if (ArrayUtils.contains(new int[] { Types.DATE, Types.TIME, Types.TIMESTAMP }, dataType)) {
|
||||||
|
return Date.class;
|
||||||
|
} else {
|
||||||
|
return String.class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user