Skip to content

Commit

Permalink
Merge pull request #8 from kingschan1204/develop
Browse files Browse the repository at this point in the history
1.x稳定版本合并
  • Loading branch information
kingschan1204 authored Nov 13, 2018
2 parents a3dd88c + ad58ca0 commit 0787626
Show file tree
Hide file tree
Showing 49 changed files with 2,856 additions and 584 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
<groupId>io.github.kingschan1204</groupId>
<artifactId>istock</artifactId>
<packaging>jar</packaging>
<version>1.6.3</version>
<version>1.6.7</version>
<name>pritice Maven Webapp</name>
<url>http://maven.apache.org</url>
<!-- 继承父包 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
<version>1.5.10.RELEASE</version>
</parent>

<properties>
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

## Demo 效果

:link: [点我查看效果](http://stock.51so.info/) (demo版) :link:
:link: [点我查看效果](http://211.159.182.106/) (demo版) :link:

## :boom: 效果图 :boom:

Expand Down
10 changes: 8 additions & 2 deletions src/main/java/io.github.kingschan1204.istock/Application.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package io.github.kingschan1204.istock;

import io.github.kingschan1204.istock.module.startup.InitQuartzTaskRunner;
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;


/**
* spring boot 启动类
* @author kings.chan
*/
@Controller
@EnableCaching
@SpringBootApplication
Expand All @@ -26,6 +30,8 @@ public InitQuartzTaskRunner startupRunner() {
}

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
SpringApplication sa = new SpringApplication(Application.class);
sa.setBannerMode(Banner.Mode.OFF);
sa.run( args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package io.github.kingschan1204.istock.common.conf;

import org.apache.http.client.HttpClient;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
* restTemplate 配置
* @author chenguoxiang
* @create 2018-10-30 15:56
**/
@Configuration
public class RestClientConfig {
private static Logger log = LoggerFactory.getLogger(RestClientConfig.class);

@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(clientHttpRequestFactory());
restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
return restTemplate;
}
@Bean
public HttpComponentsClientHttpRequestFactory clientHttpRequestFactory() {
try {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
return true;
}
}).build();
httpClientBuilder.setSSLContext(sslContext);
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslConnectionSocketFactory).build();// 注册http和https请求
// 开始设置连接池
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
poolingHttpClientConnectionManager.setMaxTotal(500); // 最大连接数500
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100); // 同路由并发数100
httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)); // 重试次数
HttpClient httpClient = httpClientBuilder.build();
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); // httpClient连接配置
clientHttpRequestFactory.setConnectTimeout(20000); // 连接超时
clientHttpRequestFactory.setReadTimeout(30000); // 数据读取超时时间
clientHttpRequestFactory.setConnectionRequestTimeout(20000); // 连接不够用的等待时间
return clientHttpRequestFactory;
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
log.error("初始化HTTP连接池出错{}", e);
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ public class QuartzManager {
public void addJob(String jobName, String jobGroupName,
String triggerName, String triggerGroupName, Class jobClass, String cron) {
try {
Scheduler sched = schedulerFactoryBean.getScheduler();//schedulerFactory.getScheduler();

Scheduler sched = schedulerFactoryBean.getScheduler();
// 任务名,任务组,任务执行类
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
// 触发器
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import java.util.Date;

/**
* Created by kingschan on 2017/6/29.
* 代码定时更新任务
* @author kings.chan
* @date 2018-6-29
*/
public class StockDateUtil {

Expand Down Expand Up @@ -111,8 +113,9 @@ public static long getCurrentTimestamp() {
*/
public static long dateToUnixTime(String dateString) throws ParseException {
Date date1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.parse(dateString);// HH:mm:ss
long temp = date1.getTime();// JAVA的时间戳长度是13位
.parse(dateString);
// JAVA的时间戳长度是13位
long temp = date1.getTime();
return temp / 1000;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
**/
public interface StockSpider {

static final String REGEX_NUMBER = "^[-+]?([0]{1}(\\.[0-9]+)?|[1-9]{1}\\d*(\\.[0-9]+)?)";//"^[-+]?[0-9]+(\\.[0-9]+)?$";
static final String REGEX_NUMBER = "^[-+]?([0]{1}(\\.[0-9]+)?|[1-9]{1}\\d*(\\.[0-9]+)?)";

/**
* 将股票代码转换成新浪接口的格式http://hq.sinajs.cn/list=
Expand Down Expand Up @@ -80,9 +80,10 @@ static String findStrByRegx(String text, String regx) {
/**
* 是否工作日
* @param date
* @return
* @return true 工作日 false 非工作日
* @throws IOException
*/
static boolean isWorkDay(String date) throws IOException {
static boolean isWorkDay(Integer date) throws IOException {
String api =String.format("http://api.goseek.cn/Tools/holiday?date=%s",date);
String result = Jsoup.connect(api).timeout(3000).ignoreContentType(true).get().text();
//{"code":10001,"data":2} 工作日对应结果为 0, 休息日对应结果为 1, 节假日对应的结果为 2
Expand Down Expand Up @@ -156,9 +157,9 @@ public void checkServerTrusted(X509Certificate[] certs, String authType) {

/**
* 得到指定代码的价格
*
* @param stockCode
* @return
* @throws Exception
*/
JSONArray getStockPrice(String[] stockCode) throws Exception;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import java.io.File;
import java.math.RoundingMode;
import java.net.SocketTimeoutException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.text.NumberFormat;
import java.util.*;

Expand All @@ -38,7 +35,10 @@ public class DefaultSpiderImpl implements StockSpider {

private static Logger log = LoggerFactory.getLogger(DefaultSpiderImpl.class);
@Value("${spider.timeout}")
protected int timeout;//8s超时
/**
* 8s超时
*/
protected int timeout;
@Value("${spider.useagent}")
protected String useAgent;
@Value("${xueqiu.token}")
Expand Down Expand Up @@ -79,24 +79,33 @@ public JSONArray getStockPrice(String[] stockCode) throws Exception {
double todayMax = StockSpider.mathFormat(data[5]);
double todayMin = StockSpider.mathFormat(data[6]);
json = new JSONObject();
if (xj == 0) { //一般这种是停牌的
json.put("fluctuate", 0);//波动
//一般这种是停牌的
if (xj == 0) {
//波动
json.put("fluctuate", 0);
} else {
NumberFormat nf = NumberFormat.getNumberInstance();
// 保留两位小数
nf.setMaximumFractionDigits(2);
// 如果不需要四舍五入,可以使用RoundingMode.DOWN
nf.setRoundingMode(RoundingMode.UP);
json.put("fluctuate", StockSpider.mathFormat(nf.format(zf)));//波动
//波动
json.put("fluctuate", StockSpider.mathFormat(nf.format(zf)));
}
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
json.put("code", data[0]);//代码
//代码
json.put("code", data[0]);
json.put("type", StockSpider.formatStockCode(data[0]).replaceAll("\\d", ""));
json.put("name", data[1].replaceAll("\\s", ""));//名称
json.put("price", xj);//现价
json.put("todayMax", todayMax);//今日最高价
json.put("todayMin", todayMin);//今日最低价
json.put("yesterdayPrice", zs);//昨收
//名称
json.put("name", data[1].replaceAll("\\s", ""));
//现价
json.put("price", xj);
//今日最高价
json.put("todayMax", todayMax);
//今日最低价
json.put("todayMin", todayMin);
//昨收
json.put("yesterdayPrice", zs);
json.put("priceDate", StockDateUtil.getCurrentDateTimeNumber());
rows.add(json);
}
Expand All @@ -112,27 +121,43 @@ public JSONObject getStockInfo(String code) throws Exception {
Elements table = doc.getElementsByTag("table");
//第一个表格的第一行
Elements tds = table.get(0).select("tr").get(0).select("td");
String zyyw = tds.get(0).text().replaceAll(regex, "");//主营业务
String sshy = tds.get(1).text().replaceAll(regex, "");//所属行业
//主营业务
String zyyw = tds.get(0).text().replaceAll(regex, "");
//所属行业
String sshy = tds.get(1).text().replaceAll(regex, "");
Elements tds1 = table.get(1).select("td");
String dtsyl = tds1.get(0).text().replaceAll(regex, "");//市盈率(动态)
String sjljt = tds1.get(4).text().replaceAll(regex, "");//市盈率(静态)
String sjl = tds1.get(8).text().replaceAll(regex, "");//市净率
String zsz = tds1.get(11).text().replaceAll("\\D+", "");//总市值
double mgjzc = StockSpider.mathFormat(tds1.get(12).text().replaceAll("\\[.*|", ""));//每股净资产
//市盈率(动态)
String dtsyl = tds1.get(0).text().replaceAll(regex, "");
//市盈率(静态)
String sjljt = tds1.get(4).text().replaceAll(regex, "");
//市净率
String sjl = tds1.get(8).text().replaceAll(regex, "");
//总市值
String zsz = tds1.get(11).text().replaceAll("\\D+", "");
//每股净资产
double mgjzc = StockSpider.mathFormat(tds1.get(12).text().replaceAll("\\[.*|", ""));
String jzcsyl = "-1";
if (tds1.size() > 14) {
jzcsyl = tds1.get(14).select("span").get(1).text();//净资产收益率
//净资产收益率
jzcsyl = tds1.get(14).select("span").get(1).text();
}
JSONObject json = new JSONObject();
json.put("mainBusiness", zyyw);//主营业务
json.put("industry", sshy);//所属行业
json.put("ped", StockSpider.mathFormat(dtsyl));//市盈率(动态)
json.put("pes", StockSpider.mathFormat(sjljt));//市盈率(静态)
json.put("pb", StockSpider.mathFormat(sjl));//市净率
json.put("totalValue", StockSpider.mathFormat(zsz));//总市值
json.put("roe", StockSpider.mathFormat(jzcsyl));//净资产收益率
json.put("bvps", mgjzc);//每股净资产
//主营业务
json.put("mainBusiness", zyyw);
//所属行业
json.put("industry", sshy);
//市盈率(动态)
json.put("ped", StockSpider.mathFormat(dtsyl));
//市盈率(静态)
json.put("pes", StockSpider.mathFormat(sjljt));
//市净率
json.put("pb", StockSpider.mathFormat(sjl));
//总市值
json.put("totalValue", StockSpider.mathFormat(zsz));
//净资产收益率
json.put("roe", StockSpider.mathFormat(jzcsyl));
//每股净资产
json.put("bvps", mgjzc);
json.put("infoDate", StockDateUtil.getCurrentDateNumber());
json.put("code", stockCode);
json.put("type", StockSpider.formatStockCode(stockCode).replaceAll("\\d", ""));
Expand Down Expand Up @@ -160,16 +185,26 @@ public JSONArray getHistoryDividendRate(String code) throws Exception {
log.debug("报告期:{},A股除权除息日:{},实施日期:{},分红方案说明:{},分红率:{}", data[0], data[6], data[3], data[4], data[9]);
json = new JSONObject();
json.put("code", stockCode);
json.put("title", data[0]);//报告期
json.put("releaseDate", data[1]);//披露时间 董事会日期
json.put("plan", data[4]);//分红方案
json.put("sgbl", 0);//送股比例
json.put("zgbl", 0);//转股比例
json.put("percent", StockSpider.mathFormat(data[9]));//分红率
json.put("gqdjr", data[5]);//股权登记日
json.put("cxcqr", data[6]);//除息除权日
json.put("progress", data[7]);//方案进度
json.put("from", "ths");//来源
//报告期
json.put("title", data[0]);
//披露时间 董事会日期
json.put("releaseDate", data[1]);
//分红方案
json.put("plan", data[4]);
//送股比例
json.put("sgbl", 0);
//转股比例
json.put("zgbl", 0);
//分红率
json.put("percent", StockSpider.mathFormat(data[9]));
//股权登记日
json.put("gqdjr", data[5]);
//除息除权日
json.put("cxcqr", data[6]);
//方案进度
json.put("progress", data[7]);
//来源
json.put("from", "ths");
jsons.add(json);
}
return jsons;
Expand All @@ -180,7 +215,7 @@ public JSONArray getHistoryDividendRate(String code) throws Exception {
@Override
public JSONArray getHistoryROE(String code) throws Exception {
String url = String.format("http://basic.10jqka.com.cn/api/stock/export.php?export=main&type=year&code=%s", code);
String path = String.format("./data/%s_main_year.xls", code);
String path = String.format("./data/%s.xls", code);
String referrer=String.format("http://basic.10jqka.com.cn/%s/finance.html",code);
if (!new File(path).exists()) {
//下载
Expand All @@ -190,8 +225,11 @@ public JSONArray getHistoryROE(String code) throws Exception {
}
//读取excel数据
List<Object[]> list = ExcelOperactionTool.readExcelData(path);
//报告期 年
Object[] year = list.get(1);
//净资产收益率
Object[] roe = list.get(10);
//净资产收益率-摊薄
Object[] roeTb = list.get(11);
JSONArray jsons = new JSONArray();
JSONObject json;
Expand Down
Loading

0 comments on commit 0787626

Please sign in to comment.