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
|
||||
|
||||
artifacts:
|
||||
name: stock-market.war
|
||||
name: india_market_java.jar
|
||||
expire_in: 1 day
|
||||
paths:
|
||||
- ./target/stock-market.war
|
||||
- ./target/india_market_java.jar
|
||||
script:
|
||||
- echo ">>>>>>Start Building<<<<<<"
|
||||
- pwd
|
||||
@@ -36,22 +36,17 @@ build:
|
||||
- mvn -v
|
||||
- mvn clean install -Dmaven.test.skip=true
|
||||
- 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<<<<<<"
|
||||
webhook:
|
||||
stage: webhook
|
||||
#tags:
|
||||
# - gz
|
||||
only:
|
||||
- main
|
||||
- develop
|
||||
script:
|
||||
- echo ">>>>>>Start Deploy<<<<<<"
|
||||
- ls
|
||||
- apt-get update
|
||||
- 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<<<<<<"
|
||||
|
||||
|
||||
|
||||
87
pom.xml
87
pom.xml
@@ -2,7 +2,7 @@
|
||||
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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>war</packaging>
|
||||
<packaging>jar</packaging>
|
||||
<parent>
|
||||
<groupId>cn.qutaojing</groupId>
|
||||
<artifactId>qutaojing-micro-pom</artifactId>
|
||||
@@ -20,6 +20,11 @@
|
||||
<name>股票行情</name>
|
||||
<description>股票行情</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.squareup</groupId>
|
||||
<artifactId>javapoet</artifactId>
|
||||
<version>1.11.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
@@ -176,18 +181,59 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>stock-market</finalName>
|
||||
<finalName>india_market_java</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!--<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>3.3.1</version>
|
||||
</plugin>
|
||||
</plugin>-->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
</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>
|
||||
<groupId>com.mysema.maven</groupId>
|
||||
@@ -219,38 +265,5 @@
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</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>
|
||||
</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.*;
|
||||
|
||||
@@ -15,7 +15,7 @@ import com.querydsl.core.types.Path;
|
||||
@Generated("com.querydsl.codegen.EntitySerializer")
|
||||
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");
|
||||
|
||||
@@ -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.*;
|
||||
|
||||
@@ -15,7 +15,7 @@ import com.querydsl.core.types.Path;
|
||||
@Generated("com.querydsl.codegen.EntitySerializer")
|
||||
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");
|
||||
|
||||
@@ -33,6 +33,8 @@ public class QStockPO extends EntityPathBase<StockPO> {
|
||||
|
||||
public final StringPath stockCode = createString("stockCode");
|
||||
|
||||
public final StringPath stockExchangeId = createString("stockExchangeId");
|
||||
|
||||
public final StringPath stockGid = createString("stockGid");
|
||||
|
||||
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 StringPath stockSymbol = createString("stockSymbol");
|
||||
|
||||
public final StringPath stockType = createString("stockType");
|
||||
|
||||
public QStockPO(String variable) {
|
||||
@@ -47,7 +47,7 @@ public class CommonApis {
|
||||
public Map<String, StockVO> stockDetailMap(List<StockCode> code) {
|
||||
Function<StockSource, List<StockCode>> func = (source) -> {
|
||||
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));
|
||||
};
|
||||
|
||||
|
||||
@@ -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.utils.SpringUtils;
|
||||
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
|
||||
|
||||
@@ -3,7 +3,7 @@ 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.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.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.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.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@@ -2,7 +2,7 @@ package cn.stock.market.domain.basic.entity;
|
||||
|
||||
import cn.qutaojing.common.utils.Beans;
|
||||
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.EqualsAndHashCode;
|
||||
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.stock.market.domain.basic.convert.SiteSettingConvert;
|
||||
import cn.stock.market.domain.basic.entity.SiteSetting;
|
||||
import cn.stock.market.infrastructure.stockdb.po.SiteSettingPO;
|
||||
import cn.stock.market.infrastructure.stockdb.repo.SiteSettingRepo;
|
||||
import cn.stock.market.infrastructure.db.po.SiteSettingPO;
|
||||
import cn.stock.market.infrastructure.db.repo.SiteSettingRepo;
|
||||
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.stream.Collectors;
|
||||
|
||||
import cn.stock.market.infrastructure.db.po.QStockPO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -21,9 +22,8 @@ import cn.qutaojing.common.jpa.ConditionBuilder;
|
||||
import cn.qutaojing.common.utils.SpringUtils;
|
||||
import cn.stock.market.domain.basic.convert.StockConvert;
|
||||
import cn.stock.market.domain.basic.entity.Stock;
|
||||
import cn.stock.market.infrastructure.stockdb.po.QStockPO;
|
||||
import cn.stock.market.infrastructure.stockdb.po.StockPO;
|
||||
import cn.stock.market.infrastructure.stockdb.repo.StockRepo;
|
||||
import cn.stock.market.infrastructure.db.po.StockPO;
|
||||
import cn.stock.market.infrastructure.db.repo.StockRepo;
|
||||
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;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import javax.persistence.EntityExistsException;
|
||||
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.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.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 okhttp3.OkHttpClient;
|
||||
import okhttp3.Protocol;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Request.Builder;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import cn.stock.market.infrastructure.db.po.QStockPO;
|
||||
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.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.k.MinDataVO;
|
||||
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.HttpClientRequest;
|
||||
import cn.stock.market.utils.PropertiesUtil;
|
||||
@@ -238,6 +256,38 @@ public class StockService {
|
||||
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,
|
||||
HttpServletRequest request) {
|
||||
Page<Stock> page = repository.findStockListByKeyWords(keyWords, stockPlate, stockType, 0, PageParam.of(pageNum, pageSize));
|
||||
@@ -711,4 +761,215 @@ public class StockService {
|
||||
}
|
||||
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;
|
||||
|
||||
import cn.stock.market.infrastructure.stockdb.po.StockPO;
|
||||
import cn.stock.market.infrastructure.db.po.StockPO;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
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
|
||||
public class StockCode {
|
||||
String code;
|
||||
StockSource source;
|
||||
// StockSource source;
|
||||
|
||||
public static StockCode a(String code) {
|
||||
return of(code, StockSource.A);
|
||||
return StockCode.builder().code(code)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static StockCode of(String code, String source) {
|
||||
return of(code, StockSource.of(source));
|
||||
public static StockCode of(String code) {
|
||||
return StockCode.builder().code(code)
|
||||
.build();
|
||||
}
|
||||
|
||||
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,7 +61,16 @@ public class StockVO {
|
||||
private String monthImg;
|
||||
|
||||
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) {
|
||||
StockVO vo = new StockVO();
|
||||
if(stock != null) {
|
||||
|
||||
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
|
||||
*/
|
||||
@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",
|
||||
transactionManagerRef = "transactionManager",
|
||||
repositoryBaseClass = GenericJpaRepositoryImpl.class,
|
||||
repositoryFactoryBeanClass = GenericJpaRepositoryFactoryBean.class,
|
||||
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"})
|
||||
public class MarketDatasourceConfig {
|
||||
@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.GeneratedValue;
|
||||
@@ -33,6 +33,6 @@ public class SiteSettingPO {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
Integer id;
|
||||
|
||||
|
||||
String marketServerList;
|
||||
}
|
||||
@@ -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.String;
|
||||
@@ -63,6 +63,10 @@ public class StockPO {
|
||||
* 涨幅比例
|
||||
*/
|
||||
BigDecimal increaseRatio;
|
||||
|
||||
|
||||
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 cn.stock.market.infrastructure.stockdb.po.SiteSettingPO;
|
||||
import cn.stock.market.infrastructure.db.po.SiteSettingPO;
|
||||
|
||||
/**
|
||||
* 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 cn.stock.market.infrastructure.stockdb.po.StockPO;
|
||||
import cn.stock.market.infrastructure.db.po.StockPO;
|
||||
|
||||
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;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
//@Component
|
||||
public class JobBoot {
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -10,6 +11,11 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
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.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
@@ -37,10 +43,12 @@ import cn.stock.market.web.config.Config;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
//@Component
|
||||
public class StockTask {
|
||||
@Autowired RealtimeRepository realtimeRepository;
|
||||
@Autowired StockRepository stockRepository;
|
||||
@Autowired StockService stockService;
|
||||
@Autowired SiteNewsRepository newsRepository;
|
||||
ThreadPoolExecutor pool;
|
||||
|
||||
@PostConstruct
|
||||
@@ -202,7 +210,7 @@ public class StockTask {
|
||||
}
|
||||
|
||||
/*同步股票列表*/
|
||||
@Scheduled(cron = "0 5 6 * * ?")
|
||||
// @Scheduled(cron = "0 5 6 * * ?")
|
||||
public void syncBjsStockList() {
|
||||
MdcUtil.setTraceIdIfAbsent();
|
||||
boolean flag = true;
|
||||
@@ -339,4 +347,32 @@ public class StockTask {
|
||||
//
|
||||
// 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;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
|
||||
import com.rp.spring.jpa.GenericJpaRepositoryFactoryBean;
|
||||
import com.rp.spring.jpa.GenericJpaRepositoryImpl;
|
||||
|
||||
/**
|
||||
*
|
||||
* title: ErpDatasourceConfig.java
|
||||
* ERP 数据源设置
|
||||
*
|
||||
* @author rplees
|
||||
* @email rplees.i.ly@gmail.com
|
||||
* @version 1.0
|
||||
* @created Jan 5, 2018 11:44:49 AM
|
||||
*/
|
||||
@Configuration
|
||||
@ComponentScan({ "cn.stock.market.infrastructure.stockdb.po", "cn.stock.market.infrastructure.stockdb.repo"})
|
||||
@EnableJpaRepositories(
|
||||
repositoryBaseClass = GenericJpaRepositoryImpl.class,
|
||||
repositoryFactoryBeanClass = GenericJpaRepositoryFactoryBean.class,
|
||||
entityManagerFactoryRef = "stockEntityManagerFactory",
|
||||
transactionManagerRef = "stockTransactionManager",
|
||||
basePackages = { "cn.stock.market.infrastructure.stockdb.po", "cn.stock.market.infrastructure.stockdb.repo"})
|
||||
public class StockDatasourceConfig {
|
||||
@Autowired HibernateProperties hibernateProperties;
|
||||
@Bean(name = "stockDataSource")
|
||||
@ConfigurationProperties(prefix="spring.datasource.stock")
|
||||
public DataSource dataSource() {
|
||||
return DruidDataSourceBuilder.create().build();
|
||||
}
|
||||
|
||||
@Bean(name = "stockJpaProperties")
|
||||
@ConfigurationProperties(prefix = "spring.jpa")
|
||||
public JpaProperties jpaProperties() {
|
||||
return new JpaProperties();
|
||||
}
|
||||
|
||||
@Bean(name = "stockEntityManagerFactory")
|
||||
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
|
||||
EntityManagerFactoryBuilder builder,
|
||||
@Qualifier("stockJpaProperties") JpaProperties jpaProperties,
|
||||
@Qualifier("stockDataSource") DataSource dataSource) {
|
||||
Map<String, Object> properties = hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
|
||||
return builder
|
||||
.dataSource(dataSource)
|
||||
.properties(properties)
|
||||
.packages("cn.stock.market.infrastructure.stockdb.po")
|
||||
.persistenceUnit("stock")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean(name = "stockTransactionManager")
|
||||
public PlatformTransactionManager transactionManager(@Qualifier("stockEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
|
||||
return new JpaTransactionManager(entityManagerFactory);
|
||||
}
|
||||
}
|
||||
//package cn.stock.market.infrastructure.stockdb.config;
|
||||
//
|
||||
//import java.util.Map;
|
||||
//
|
||||
//import javax.persistence.EntityManagerFactory;
|
||||
//import javax.sql.DataSource;
|
||||
//
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.beans.factory.annotation.Qualifier;
|
||||
//import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
|
||||
//import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
|
||||
//import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
|
||||
//import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
//import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
|
||||
//import org.springframework.context.annotation.Bean;
|
||||
//import org.springframework.context.annotation.ComponentScan;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
//import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
//import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
//import org.springframework.transaction.PlatformTransactionManager;
|
||||
//
|
||||
//import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
|
||||
//import com.rp.spring.jpa.GenericJpaRepositoryFactoryBean;
|
||||
//import com.rp.spring.jpa.GenericJpaRepositoryImpl;
|
||||
//
|
||||
///**
|
||||
// *
|
||||
// * title: ErpDatasourceConfig.java
|
||||
// * ERP 数据源设置
|
||||
// *
|
||||
// * @author rplees
|
||||
// * @email rplees.i.ly@gmail.com
|
||||
// * @version 1.0
|
||||
// * @created Jan 5, 2018 11:44:49 AM
|
||||
// */
|
||||
//@Configuration
|
||||
//@ComponentScan({ "cn.stock.market.infrastructure.stockdb.po", "cn.stock.market.infrastructure.stockdb.repo"})
|
||||
//@EnableJpaRepositories(
|
||||
// repositoryBaseClass = GenericJpaRepositoryImpl.class,
|
||||
// repositoryFactoryBeanClass = GenericJpaRepositoryFactoryBean.class,
|
||||
// entityManagerFactoryRef = "stockEntityManagerFactory",
|
||||
// transactionManagerRef = "stockTransactionManager",
|
||||
// basePackages = { "cn.stock.market.infrastructure.stockdb.po", "cn.stock.market.infrastructure.stockdb.repo"})
|
||||
//public class StockDatasourceConfig {
|
||||
// @Autowired HibernateProperties hibernateProperties;
|
||||
// @Bean(name = "stockDataSource")
|
||||
// @ConfigurationProperties(prefix="spring.datasource.stock")
|
||||
// public DataSource dataSource() {
|
||||
// return DruidDataSourceBuilder.create().build();
|
||||
// }
|
||||
//
|
||||
// @Bean(name = "stockJpaProperties")
|
||||
// @ConfigurationProperties(prefix = "spring.jpa")
|
||||
// public JpaProperties jpaProperties() {
|
||||
// return new JpaProperties();
|
||||
// }
|
||||
//
|
||||
// @Bean(name = "stockEntityManagerFactory")
|
||||
// public LocalContainerEntityManagerFactoryBean entityManagerFactory(
|
||||
// EntityManagerFactoryBuilder builder,
|
||||
// @Qualifier("stockJpaProperties") JpaProperties jpaProperties,
|
||||
// @Qualifier("stockDataSource") DataSource dataSource) {
|
||||
// Map<String, Object> properties = hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
|
||||
// return builder
|
||||
// .dataSource(dataSource)
|
||||
// .properties(properties)
|
||||
// .packages("cn.stock.market.infrastructure.stockdb.po")
|
||||
// .persistenceUnit("stock")
|
||||
// .build();
|
||||
// }
|
||||
//
|
||||
// @Bean(name = "stockTransactionManager")
|
||||
// public PlatformTransactionManager transactionManager(@Qualifier("stockEntityManagerFactory") EntityManagerFactory 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 com.github.pagehelper.StringUtil;
|
||||
import okhttp3.*;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
@@ -73,6 +74,29 @@ public class HttpClientRequest {
|
||||
}
|
||||
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
|
||||
* @param url
|
||||
@@ -187,4 +211,10 @@ public class HttpClientRequest {
|
||||
}
|
||||
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;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
@@ -394,13 +396,55 @@ public final class Utils {
|
||||
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) {
|
||||
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.9", "1.0.10"));
|
||||
System.out.println(highVersion("1.0.10", "1.0.11"));
|
||||
System.out.println(highVersion("1.0.10", "1.0.9"));
|
||||
// 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.9", "1.0.10"));
|
||||
// System.out.println(highVersion("1.0.10", "1.0.11"));
|
||||
// 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.ApiImplicitParam;
|
||||
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.Jsons;
|
||||
import com.ag.utils.param.ParamUtils;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.common.base.Joiner;
|
||||
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.StockVO;
|
||||
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.sina.SinaStockApi;
|
||||
import cn.stock.market.utils.RequestCacheUtils;
|
||||
@@ -59,6 +66,8 @@ public class StockApiController {
|
||||
|
||||
@Autowired
|
||||
StockService stockService;
|
||||
@Autowired
|
||||
SiteNewsRepository newsRepository;
|
||||
|
||||
@RequestMapping({"getRawSinaStock.do"})
|
||||
@ResponseBody
|
||||
@@ -119,39 +128,80 @@ public class StockApiController {
|
||||
@ApiOperation(value = "印度股票个股详情", httpMethod = "GET")
|
||||
@ResponseBody
|
||||
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线
|
||||
@RequestMapping({"getINDTimeK.do"})
|
||||
@ApiOperation(value = "印度股票时线-K线", httpMethod = "GET")
|
||||
@ApiOperation(value = "印度股票K线", httpMethod = "GET")
|
||||
@ResponseBody
|
||||
public ServerResponse getINDTimeK(@RequestParam("stockCode") String stockCode) {
|
||||
return this.stockService.getTimeK(stockCode);
|
||||
@ApiImplicitParams({
|
||||
@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线
|
||||
@RequestMapping({"getINDDayK.do"})
|
||||
@ApiOperation(value = "印度股票日线-K线", httpMethod = "GET")
|
||||
//印度指数-K线
|
||||
@RequestMapping({"getIndiaIndexTimeK.do"})
|
||||
@ApiOperation(value = "印度--获取指数K线", httpMethod = "GET")
|
||||
@ResponseBody
|
||||
public ServerResponse getINDDayK(@RequestParam("stockCode") String stockCode) {
|
||||
return this.stockService.getDayK(stockCode);
|
||||
}
|
||||
@ApiImplicitParams({
|
||||
@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线
|
||||
@RequestMapping({"getINDWeekK.do"})
|
||||
@ApiOperation(value = "印度股票周线-K线", httpMethod = "GET")
|
||||
@ResponseBody
|
||||
public ServerResponse getINDWeekK(@RequestParam("stockCode") String stockCode) {
|
||||
return this.stockService.getWeekK(stockCode);
|
||||
List<JSONObject> list = InvestingApis.of().kline(StockCode.of(stockCode), type);
|
||||
return ServerResponse.createBySuccess(list);
|
||||
}
|
||||
|
||||
//印度股票月线-K线
|
||||
@RequestMapping({"getINDMonthK.do"})
|
||||
@ApiOperation(value = "印度股票月线-K线", httpMethod = "GET")
|
||||
@RequestMapping({"getIndiaIndex.do"})
|
||||
@ApiOperation(value = "印度--获取指定指数信息", httpMethod = "GET")
|
||||
@ResponseBody
|
||||
public ServerResponse getINDMonthK(@RequestParam("stockCode") String stockCode) {
|
||||
return this.stockService.getMonthK(stockCode);
|
||||
public ServerResponse getIndiaIndex() {
|
||||
return this.stockService.getIndiaIndex();
|
||||
}
|
||||
|
||||
//根据股票id查询 股票指数、大盘指数信息
|
||||
@@ -196,7 +246,7 @@ public class StockApiController {
|
||||
return RequestCacheUtils.cache("getMinK.do", key, (string) -> {
|
||||
return this.stockService.getMinK(code, time, ma, size);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
@RequestMapping({"getKLine.do"})
|
||||
@@ -223,7 +273,7 @@ public class StockApiController {
|
||||
return this.stockService.getDayK_Echarts(code);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*查询股票周线*/
|
||||
@RequestMapping({"getWeekK.do"})
|
||||
@ApiOperation(value = "查询股票周线", httpMethod = "GET")
|
||||
@@ -236,7 +286,7 @@ public class StockApiController {
|
||||
return this.stockService.getWeekK_Echarts(code);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/*查询股票月线*/
|
||||
@RequestMapping({"getMonthK.do"})
|
||||
@ApiOperation(value = "查询股票月线", httpMethod = "GET")
|
||||
@@ -634,9 +684,16 @@ public class StockApiController {
|
||||
@ApiOperation(value = "新股待上市接口",httpMethod = "GET", response = ServerResponse.class)
|
||||
@RequestMapping({"getNewStockList.do"})
|
||||
@ResponseBody
|
||||
public
|
||||
ServerResponse getNewStockList() {
|
||||
public ServerResponse 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
|
||||
@EnableScheduling
|
||||
@ConditionalOnProperty(prefix = "enable", name = "scheduled", havingValue = "true")
|
||||
@ConditionalOnProperty(prefix = "enable", name = "scheduled", havingValue = "true", matchIfMissing = true)
|
||||
public class ControlSchedulingConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ public class Swagger2Config {
|
||||
|
||||
public ApiInfoBuilder commonApiInfoBuilder() {
|
||||
return new ApiInfoBuilder()
|
||||
.description("鑫宝 接口文档")
|
||||
.description("英文股票接口文档")
|
||||
.termsOfServiceUrl("http://www.xxxx.cn/")
|
||||
.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
|
||||
# Redis配置
|
||||
redis:
|
||||
host: 43.128.20.124
|
||||
host: 43.132.212.180
|
||||
password: ruTZ9J3gaDhknJ
|
||||
port: 36379
|
||||
database: 1
|
||||
@@ -17,7 +17,7 @@ spring:
|
||||
datasource:
|
||||
stock-market:
|
||||
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
|
||||
password: 33BsUUcnXRYgwt
|
||||
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
|
||||
|
||||
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