Compare commits

20 Commits

Author SHA1 Message Date
dengli
ef392a7fe7 新闻定时任务 2024-01-11 18:04:32 +08:00
rplees
e98b6d0463 Merge branch 'develop' into 'main'
Develop

See merge request india/india_market_java!4
2024-01-09 12:35:18 +00:00
Achilles
175bc87824 接口代码优化调整 2024-01-09 20:18:06 +08:00
Achilles
c24f3a86fb 接口代码优化调整 2024-01-09 16:51:01 +08:00
Achilles
53b4223370 接口代码优化调整 2024-01-09 15:01:39 +08:00
Achilles
65656ef10b 接口调整 2024-01-09 13:42:24 +08:00
Achilles
32e65dc2c2 接口调整 2024-01-09 13:40:09 +08:00
Achilles
88baedb546 actives 接口调整 2024-01-09 11:57:47 +08:00
Achilles
c9f0d8f4cf actives 接口调整 2024-01-09 11:20:41 +08:00
Achilles
163c92970d actives 接口调整 2024-01-09 11:12:11 +08:00
Achilles
bc852cbf7c k line接口调整 2024-01-08 21:04:59 +08:00
Achilles
90c5eb9644 调整结构 2024-01-08 18:54:24 +08:00
Achilles
9264f08c77 调整结构 2024-01-08 17:09:20 +08:00
Achilles
28f33672e5 调整结构 2024-01-08 16:27:41 +08:00
Achilles
2601d5cf77 调整结构 2024-01-08 16:25:04 +08:00
Achilles
a0bd21b645 调整结构 2024-01-08 16:24:35 +08:00
Achilles
95468dba5c 调整结构 2024-01-08 16:18:44 +08:00
rplees
0a0c969e28 Merge branch 'develop' into 'main'
Develop

See merge request india/india_market_java!3
2024-01-04 07:45:15 +00:00
rplees
2087d8914b Merge branch 'develop' into 'main'
Develop

See merge request india/india_market_java!2
2024-01-03 12:00:31 +00:00
rplees
42a40b9ff8 Merge branch 'develop' into 'main'
Develop

See merge request india/india_market_java!1
2023-12-31 11:13:55 +00:00
4 changed files with 209 additions and 95 deletions

View File

@@ -272,8 +272,9 @@ public class StockService {
return result; return result;
} }
public String getNewsInfo(String url) { public List<String> getNewsInfo(String url) {
String result = ""; String result = "";
List<String> list = new ArrayList<>();
try { try {
// 使用Jsoup连接到网页 // 使用Jsoup连接到网页
Document doc = Jsoup.connect(url) Document doc = Jsoup.connect(url)
@@ -281,11 +282,14 @@ public class StockService {
.header("Referer", "https://www.business-standard.com/") .header("Referer", "https://www.business-standard.com/")
.header("Accept-Language", "en-US,en;q=0.9") .header("Accept-Language", "en-US,en;q=0.9")
.get(); .get();
result = doc.html().substring(doc.html().indexOf("articleBody") + 15, doc.html().indexOf(",\"author\":") - 1); result = doc.html().substring(doc.html().indexOf("articleBody") + 14, doc.html().indexOf(",\"author\":") - 1);
list.add(result);
list.add(doc.html().substring(doc.html().indexOf("og:title") + 19, doc.html().indexOf("<meta property=\"og:url") - 5));
} catch (Exception e) { } catch (Exception e) {
return e.toString(); list.add(e.toString());
return list;
} }
return result; return list;
} }
public ServerResponse getStock(int pageNum, int pageSize, String keyWords, String stockPlate, String stockType, public ServerResponse getStock(int pageNum, int pageSize, String keyWords, String stockPlate, String stockType,

View File

@@ -117,15 +117,15 @@ public class InvestingTask {
String id = contentUrl.substring(contentUrl.lastIndexOf("-") + 1, contentUrl.lastIndexOf("_")); String id = contentUrl.substring(contentUrl.lastIndexOf("-") + 1, contentUrl.lastIndexOf("_"));
String imgUrl = n.substring(n.indexOf("img src=") + 9, n.indexOf("?")); 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 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 siteNews = new SiteNews();
siteNews.setAddTime(new Date()); siteNews.setAddTime(new Date());
siteNews.setSourceId(id); siteNews.setSourceId(id);
siteNews.setTitle(title);
siteNews.setDescription(time); siteNews.setDescription(time);
siteNews.setImgurl(imgUrl); siteNews.setImgurl(imgUrl);
siteNews.setContent(stockService.getNewsInfo(contentUrl)); List<String> newsInfo = stockService.getNewsInfo(contentUrl);
siteNews.setContent(newsInfo.get(0));
siteNews.setTitle(newsInfo.get(1));
List<SiteNews> list = newsRepository.findAll(QSiteNewsPO.siteNewsPO.sourceId.eq(id)); List<SiteNews> list = newsRepository.findAll(QSiteNewsPO.siteNewsPO.sourceId.eq(id));
if (list.size() == 0) { if (list.size() == 0) {
newsRepository.save(siteNews); newsRepository.save(siteNews);

View File

@@ -16,6 +16,7 @@ import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; 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.bind.annotation.RestController;
import java.io.BufferedReader; import java.io.BufferedReader;
@@ -93,9 +94,8 @@ public class MoneyScraper {
} }
@GetMapping("testScraperGetMoneyControlStockNoScId") @GetMapping("testScraperGetMoneyControlStockNoScId")
public String testScraperGetMoneyControlStockNoScId() { public String testScraperGetMoneyControlStockNoScId(@RequestParam("url") String url) {
String url = "http://www.moneycontrol.com/india/stockpricequote/foodprocessing/nestleindia/NI"; Document soup2 = fetchCompanyDetails(url);
/* Document soup2 = fetchCompanyDetails(url);
if (soup2 != null) { if (soup2 != null) {
Element comIdInput = soup2.selectFirst("input[id=ap_sc_id]"); Element comIdInput = soup2.selectFirst("input[id=ap_sc_id]");
@@ -109,19 +109,19 @@ public class MoneyScraper {
if (soup2 != null) { if (soup2 != null) {
Element ulElement = soup2.selectFirst("ul[id=nseBseTab]"); Element ulElement = soup2.selectFirst("ul[id=nseBseTab]");
String name = soup2.selectFirst("#stockName > h1").text();
if (ulElement != null) { if (ulElement != null) {
for (Element aElement : ulElement.select("a")) { for (Element aElement : ulElement.select("a")) {
String exchangeValue = aElement.text().trim(); String exchangeValue = aElement.text().trim();
if ("BSE".equals(exchangeValue) || "NSE".equals(exchangeValue)) { if ("BSE".equals(exchangeValue) || "NSE".equals(exchangeValue)) {
log.info(Thread.currentThread().getName() + ",the stock url: " + url + log.info(Thread.currentThread().getName() + ",the stock url: " + url +
", the exchange Value: " + exchangeValue); ", the exchange Value: " + exchangeValue);
MoneyStock build = MoneyStock.builder().stockName("sss").stockType(exchangeValue.toLowerCase(Locale.ROOT)) MoneyStock build = MoneyStock.builder().stockName(name).stockType(exchangeValue.toLowerCase(Locale.ROOT))
.detailUrl(String.format("https://priceapi.moneycontrol.com/pricefeed/%s/equitycash/%s", exchangeValue.toLowerCase(), companyCodeId)) .detailUrl(String.format("https://priceapi.moneycontrol.com/pricefeed/%s/equitycash/%s", exchangeValue.toLowerCase(), companyCodeId))
.selfUrl(url) .selfUrl(url)
.selfDispId(extractDispId(url)) .selfDispId(extractDispId(url))
.moneyScId(companyCodeId).saveTime(new Date()).build(); .moneyScId(companyCodeId).saveTime(new Date()).build();
List<MoneyStock> all = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.stockName.eq("Nestle"), QMoneyStockPO.moneyStockPO.stockType.eq(exchangeValue.toLowerCase(Locale.ROOT))); List<MoneyStock> all = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.stockName.eq(name), QMoneyStockPO.moneyStockPO.stockType.eq(exchangeValue.toLowerCase(Locale.ROOT)));
if (CollectionUtil.isEmpty(all)) { if (CollectionUtil.isEmpty(all)) {
moneyStockRepository.save(build); moneyStockRepository.save(build);
} }
@@ -129,7 +129,7 @@ public class MoneyScraper {
} }
} }
} }
}*/ }
return "ok"; return "ok";
} }

View File

@@ -6,8 +6,11 @@ import cn.stock.market.domain.basic.repository.MoneyStockRepository;
import cn.stock.market.dto.StockHistoryRequest; import cn.stock.market.dto.StockHistoryRequest;
import cn.stock.market.dto.StockHistoryResponse; import cn.stock.market.dto.StockHistoryResponse;
import cn.stock.market.infrastructure.db.po.QMoneyStockPO; import cn.stock.market.infrastructure.db.po.QMoneyStockPO;
import cn.stock.market.utils.RequestCacheUtils;
import cn.stock.market.utils.ServerResponse; import cn.stock.market.utils.ServerResponse;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParam;
@@ -23,17 +26,20 @@ import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@@ -60,6 +66,7 @@ public class MoneyApiController {
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(name="stockType",value = "BSE或者NSE"), @ApiImplicitParam(name="stockType",value = "BSE或者NSE"),
@ApiImplicitParam(name="symbol",value = "scId值"), @ApiImplicitParam(name="symbol",value = "scId值"),
@ApiImplicitParam(name="id",value = "id值"),
}) })
@ApiResponses(value = { @ApiResponses(value = {
@ApiResponse(code = 200, message = "" + @ApiResponse(code = 200, message = "" +
@@ -160,16 +167,41 @@ public class MoneyApiController {
}) })
@GetMapping("/api/market/money/getStockDetail") @GetMapping("/api/market/money/getStockDetail")
@ResponseBody @ResponseBody
public ServerResponse getStockDetail(@RequestParam String stockType, @RequestParam String symbol) { public ServerResponse getStockDetail(@RequestParam String stockType, @RequestParam String symbol ) {
String url = String.format("https://priceapi.moneycontrol.com/pricefeed/%s/equitycash/%s",stockType,symbol); String url = String.format("https://priceapi.moneycontrol.com/pricefeed/%s/equitycash/%s",stockType,symbol);
MoneyStock moneyStock = moneyStockRepository.findOne(QMoneyStockPO.moneyStockPO.stockType.eq(stockType).and(QMoneyStockPO.moneyStockPO.moneyScId.eq(symbol))).orElse(null);
/* if(moneyStock==null){
return ServerResponse.createByErrorMsg("没有找到该股票");
}*/
// 设置重试次数 // 设置重试次数
int maxRetries = 3; int maxRetries = 3;
for (int retry = 1; retry <= maxRetries; retry++) { for (int retry = 1; retry <= maxRetries; retry++) {
try { try {
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, String.class); ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
JSONObject json1 = new JSONObject();
if (responseEntity.getStatusCode().value() == 200 && responseEntity.getBody() != null ) { if (responseEntity.getStatusCode().value() == 200 && responseEntity.getBody() != null ) {
return ServerResponse.createBySuccess(JSONObject.parseObject(responseEntity.getBody()).getJSONObject("data")); JSONObject data = JSONObject.parseObject(responseEntity.getBody()).getJSONObject("data");
if(data!=null){
json1.put("company",data.getString("company"));
json1.put("pricepercentchange",data.getString("pricepercentchange"));
json1.put("stockType",stockType);
json1.put("pricechange",data.getString("pricechange"));
json1.put("pricecurrent",data.getString("pricecurrent"));
json1.put("priceprevclose",data.getString("priceprevclose"));
json1.put("PREVDATE",data.getString("PREVDATE"));
json1.put("VOL",data.getString("VOL"));
json1.put("dataSourceType","3");
json1.put("symbol",data.getString("symbol"));
json1.put("BSEID",data.getString("BSEID"));
json1.put("NSEID",data.getString("NSEID"));
json1.put("LTH",data.getString("HP"));
json1.put("LTL",data.getString("LP"));
json1.put("OPN",data.getString("OPN"));
if(null!=moneyStock){
json1.put("id",moneyStock.getId());
}
}
return ServerResponse.createBySuccess(json1);
} }
} catch (Exception e) { } catch (Exception e) {
@@ -214,10 +246,8 @@ public class MoneyApiController {
String lastPrice = getTextOrEmpty(doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td:nth-child(4)").first()); String lastPrice = getTextOrEmpty(doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td:nth-child(4)").first());
dto.setLastPrice(lastPrice); dto.setLastPrice(lastPrice);
String change = getTextOrEmpty(doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td:nth-child(5)").first()); String changePercent = getTextOrEmpty(doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td:nth-child(5)").first());
dto.setChange(change);
String changePercent = getTextOrEmpty(doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td:nth-child(6)").first());
dto.setChangePercent(changePercent); dto.setChangePercent(changePercent);
dto.setStockType("nse"); dto.setStockType("nse");
@@ -262,10 +292,7 @@ public class MoneyApiController {
String prevClosePrice = getTextOrEmpty(doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td:nth-child(5)").first()); String prevClosePrice = getTextOrEmpty(doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td:nth-child(5)").first());
dto.setPrevClosePrice(prevClosePrice); dto.setPrevClosePrice(prevClosePrice);
String change = getTextOrEmpty(doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td:nth-child(6)").first()); String changePercent = getTextOrEmpty(doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td:nth-child(6)").first());
dto.setChange(change);
String changePercent = getTextOrEmpty(doc.select("#mc_content > section > section > div.clearfix.stat_container > div.columnst.FR.wbg.brdwht > div > div > div.bsr_table.hist_tbl_hm > table > tbody > tr:nth-child(" + i + ") > td:nth-child(7)").first());
dto.setChangePercent(changePercent); dto.setChangePercent(changePercent);
dto.setStockType("bse"); dto.setStockType("bse");
@@ -476,20 +503,30 @@ public class MoneyApiController {
@ResponseBody @ResponseBody
public List<MoneyStockSuggestDTO> getTopGainer(@RequestParam String stockType) { public List<MoneyStockSuggestDTO> getTopGainer(@RequestParam String stockType) {
List<MoneyStockSuggestDTO> moneyStockSuggestDTOS = null; List<MoneyStockSuggestDTO> moneyStockSuggestDTOS = null;
if(StringUtils.equals(stockType,"nse")){ // 尝试从缓存中获取结果
moneyStockSuggestDTOS = nseGainer(); moneyStockSuggestDTOS = gainerStockSuggestCache.getIfPresent(stockType);
}else if(StringUtils.equals(stockType,"bse")){
moneyStockSuggestDTOS = bseGainer(); if (moneyStockSuggestDTOS == null) {
} // 缓存未命中,执行业务查询
if(CollectionUtils.isNotEmpty(moneyStockSuggestDTOS)){ if (StringUtils.equals(stockType, "nse")) {
List<String> selfUlrList = moneyStockSuggestDTOS.stream().map(MoneyStockSuggestDTO::getStockName).collect(Collectors.toList()); moneyStockSuggestDTOS = nseGainer();
if(CollectionUtils.isNotEmpty(selfUlrList)){ } else if (StringUtils.equals(stockType, "bse")) {
List<MoneyStock> all = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.stockName.in(selfUlrList)); moneyStockSuggestDTOS = bseGainer();
if(CollectionUtils.isNotEmpty(all)){
moneyStockSuggestDTOS.stream().filter(f->all.stream().anyMatch(s->s.getStockName().equals(f.getStockName())))
.forEach(f->f.setScId(all.stream().filter(s->s.getStockName().equals(f.getStockName())).findFirst().orElse(null).getMoneyScId()));
}
} }
moneyStockSuggestDTOS = moneyStockSuggestDTOS.stream().filter(f->StringUtils.isNotBlank(f.getStockName())).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(moneyStockSuggestDTOS)){
List<String> selfUlrList = moneyStockSuggestDTOS.stream().map(MoneyStockSuggestDTO::getStockName).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(selfUlrList)){
List<MoneyStock> all = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.stockName.in(selfUlrList));
if(CollectionUtils.isNotEmpty(all)){
moneyStockSuggestDTOS.stream().filter(f->all.stream().anyMatch(s->s.getStockName().equals(f.getStockName())))
.forEach(f->f.setScId(all.stream().filter(s->s.getStockName().equals(f.getStockName())).findFirst().orElse(null).getMoneyScId()));
}
}
gainerStockSuggestCache.put(stockType, moneyStockSuggestDTOS);
}
// 将结果放入缓存
} }
return moneyStockSuggestDTOS; return moneyStockSuggestDTOS;
} }
@@ -507,32 +544,36 @@ public class MoneyApiController {
@ResponseBody @ResponseBody
public List<MoneyStockSuggestDTO> getTopLoser(@RequestParam String stockType) { public List<MoneyStockSuggestDTO> getTopLoser(@RequestParam String stockType) {
List<MoneyStockSuggestDTO> moneyStockSuggestDTOS = null; List<MoneyStockSuggestDTO> moneyStockSuggestDTOS = null;
if(StringUtils.equals(stockType,"nse")){ moneyStockSuggestDTOS = loserStockSuggestCache.getIfPresent(stockType);
moneyStockSuggestDTOS = nseTopLoser(); if(null==moneyStockSuggestDTOS){
}else if(StringUtils.equals(stockType,"bse")){ if(StringUtils.equals(stockType,"nse")){
moneyStockSuggestDTOS = bseTopLoser(); moneyStockSuggestDTOS = nseTopLoser();
} }else if(StringUtils.equals(stockType,"bse")){
if(CollectionUtils.isNotEmpty(moneyStockSuggestDTOS)){ moneyStockSuggestDTOS = bseTopLoser();
moneyStockSuggestDTOS.stream().forEach(f->f.setDispId(extractLastSegment(f.getStockUrl()))); }
List<String> selfUlrList = moneyStockSuggestDTOS.stream().map(MoneyStockSuggestDTO::getStockName).collect(Collectors.toList()); moneyStockSuggestDTOS = moneyStockSuggestDTOS.stream().filter(f->StringUtils.isNotBlank(f.getStockName())).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(selfUlrList)){ if(CollectionUtils.isNotEmpty(moneyStockSuggestDTOS)){
List<MoneyStock> all = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.stockName.in(selfUlrList)); moneyStockSuggestDTOS.stream().forEach(f->f.setDispId(extractLastSegment(f.getStockUrl())));
if(CollectionUtils.isNotEmpty(all)){ List<String> selfUlrList = moneyStockSuggestDTOS.stream().map(MoneyStockSuggestDTO::getStockName).collect(Collectors.toList());
moneyStockSuggestDTOS.stream().filter(f->all.stream().anyMatch(s->s.getStockName().equals(f.getStockName()))) if(CollectionUtils.isNotEmpty(selfUlrList)){
.forEach(f->f.setScId(all.stream().filter(s->s.getStockName().equals(f.getStockName())).findFirst().orElse(null).getMoneyScId())); List<MoneyStock> all = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.stockName.in(selfUlrList));
} if(CollectionUtils.isNotEmpty(all)){
List<MoneyStockSuggestDTO> noScIdList = moneyStockSuggestDTOS.stream().filter(f->StringUtils.isBlank(f.getScId())).collect(Collectors.toList()); moneyStockSuggestDTOS.stream().filter(f->all.stream().anyMatch(s->s.getStockName().equals(f.getStockName())))
if(CollectionUtils.isNotEmpty(noScIdList)){ .forEach(f->f.setScId(all.stream().filter(s->s.getStockName().equals(f.getStockName())).findFirst().orElse(null).getMoneyScId()));
List<String> dispIdList = noScIdList.stream().map(MoneyStockSuggestDTO::getDispId).collect(Collectors.toList()); }
List<MoneyStock> all1 = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.selfDispId.in(dispIdList)); List<MoneyStockSuggestDTO> noScIdList = moneyStockSuggestDTOS.stream().filter(f->StringUtils.isBlank(f.getScId())).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(all1)){ if(CollectionUtils.isNotEmpty(noScIdList)){
moneyStockSuggestDTOS.stream().filter(f->all1.stream().anyMatch(s->s.getSelfDispId().equals(f.getDispId()))) List<String> dispIdList = noScIdList.stream().map(MoneyStockSuggestDTO::getDispId).collect(Collectors.toList());
.forEach(f->f.setScId(all.stream().filter(s->s.getSelfDispId().equals(f.getDispId())).findFirst().orElse(null).getMoneyScId())); List<MoneyStock> all1 = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.selfDispId.in(dispIdList));
if(CollectionUtils.isNotEmpty(all1)){
moneyStockSuggestDTOS.stream().filter(f->all1.stream().anyMatch(s->s.getSelfDispId().equals(f.getDispId())))
.forEach(f->f.setScId(all.stream().filter(s->s.getSelfDispId().equals(f.getDispId())).findFirst().orElse(null).getMoneyScId()));
}
} }
} }
loserStockSuggestCache.put(stockType, moneyStockSuggestDTOS);
} }
} }
return moneyStockSuggestDTOS; return moneyStockSuggestDTOS;
} }
@@ -551,29 +592,34 @@ public class MoneyApiController {
@ResponseBody @ResponseBody
public List<MoneyStockSuggestDTO> getTopActive(@RequestParam String stockType) { public List<MoneyStockSuggestDTO> getTopActive(@RequestParam String stockType) {
List<MoneyStockSuggestDTO> moneyStockSuggestDTOS = null; List<MoneyStockSuggestDTO> moneyStockSuggestDTOS = null;
if(StringUtils.equals(stockType,"nse")){ moneyStockSuggestDTOS = activesStockSuggestCache.getIfPresent(stockType);
moneyStockSuggestDTOS = nseActives(); if(moneyStockSuggestDTOS ==null){
}else if(StringUtils.equals(stockType,"bse")){ if(StringUtils.equals(stockType,"nse")){
moneyStockSuggestDTOS = bseActives(); moneyStockSuggestDTOS = nseActives();
} }else if(StringUtils.equals(stockType,"bse")){
if(CollectionUtils.isNotEmpty(moneyStockSuggestDTOS)){ moneyStockSuggestDTOS = bseActives();
moneyStockSuggestDTOS.stream().forEach(f->f.setDispId(extractLastSegment(f.getStockUrl()))); }
List<String> selfUlrList = moneyStockSuggestDTOS.stream().map(MoneyStockSuggestDTO::getStockName).collect(Collectors.toList()); moneyStockSuggestDTOS = moneyStockSuggestDTOS.stream().filter(f->StringUtils.isNotBlank(f.getStockName())).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(selfUlrList)){ if(CollectionUtils.isNotEmpty(moneyStockSuggestDTOS)){
List<MoneyStock> all = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.stockName.in(selfUlrList)); moneyStockSuggestDTOS.stream().forEach(f->f.setDispId(extractLastSegment(f.getStockUrl())));
if(CollectionUtils.isNotEmpty(all)){ List<String> selfUlrList = moneyStockSuggestDTOS.stream().map(MoneyStockSuggestDTO::getStockName).collect(Collectors.toList());
moneyStockSuggestDTOS.stream().filter(f->all.stream().anyMatch(s->s.getStockName().equals(f.getStockName()))) if(CollectionUtils.isNotEmpty(selfUlrList)){
.forEach(f->f.setScId(all.stream().filter(s->s.getStockName().equals(f.getStockName())).findFirst().orElse(null).getMoneyScId())); List<MoneyStock> all = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.stockName.in(selfUlrList));
} if(CollectionUtils.isNotEmpty(all)){
List<MoneyStockSuggestDTO> noScIdList = moneyStockSuggestDTOS.stream().filter(f->StringUtils.isBlank(f.getScId())).collect(Collectors.toList()); moneyStockSuggestDTOS.stream().filter(f->all.stream().anyMatch(s->s.getStockName().equals(f.getStockName())))
if(CollectionUtils.isNotEmpty(noScIdList)){ .forEach(f->f.setScId(all.stream().filter(s->s.getStockName().equals(f.getStockName())).findFirst().orElse(null).getMoneyScId()));
List<String> dispIdList = noScIdList.stream().map(MoneyStockSuggestDTO::getDispId).collect(Collectors.toList()); }
List<MoneyStock> all1 = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.selfDispId.in(dispIdList)); List<MoneyStockSuggestDTO> noScIdList = moneyStockSuggestDTOS.stream().filter(f->StringUtils.isBlank(f.getScId())).collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(all1)){ if(CollectionUtils.isNotEmpty(noScIdList)){
moneyStockSuggestDTOS.stream().filter(f->all1.stream().anyMatch(s->s.getSelfDispId().equals(f.getDispId()))) List<String> dispIdList = noScIdList.stream().map(MoneyStockSuggestDTO::getDispId).collect(Collectors.toList());
.forEach(f->f.setScId(all.stream().filter(s->s.getSelfDispId().equals(f.getDispId())).findFirst().orElse(null).getMoneyScId())); List<MoneyStock> all1 = moneyStockRepository.findAll(QMoneyStockPO.moneyStockPO.selfDispId.in(dispIdList));
if(CollectionUtils.isNotEmpty(all1)){
moneyStockSuggestDTOS.stream().filter(f->all1.stream().anyMatch(s->s.getSelfDispId().equals(f.getDispId())))
.forEach(f->f.setScId(all.stream().filter(s->s.getSelfDispId().equals(f.getDispId())).findFirst().orElse(null).getMoneyScId()));
}
} }
} }
activesStockSuggestCache.put(stockType, moneyStockSuggestDTOS);
} }
} }
@@ -585,38 +631,87 @@ public class MoneyApiController {
@GetMapping("/api/market/money/history/kLine") @GetMapping("/api/market/money/history/kLine")
@ApiOperation(value = "获取kline的money数据源", notes = "获取kline的money数据源",response = StockHistoryResponse.class) @ApiOperation(value = "获取kline的money数据源", notes = "获取kline的money数据源",response = StockHistoryResponse.class)
@ApiImplicitParams({ @ApiImplicitParams({
@ApiImplicitParam(name = "symbol", value = "Stock symbol", required = true, dataType = "String", paramType = "query"), @ApiImplicitParam(name = "symbol", value = "Stock symbol 对应的是NSEID 或者是BSEID", required = true, dataType = "String", paramType = "query"),
@ApiImplicitParam(name = "resolution", value = "Resolution", required = true, dataType = "String", paramType = "query"), @ApiImplicitParam(name = "resolution", value = "单位:60 1D 1W 1D 对应H,D,W,Y", required = true, dataType = "String", paramType = "query"),
@ApiImplicitParam(name = "from", value = "Start timestamp", required = true, dataType = "long", paramType = "query"), @ApiImplicitParam(name = "from", value = "Start timestamp", required = true, dataType = "long", paramType = "query"),
@ApiImplicitParam(name = "to", value = "End timestamp", required = true, dataType = "long", paramType = "query"), @ApiImplicitParam(name = "to", value = "End timestamp", required = true, dataType = "long", paramType = "query"),
@ApiImplicitParam(name = "countback", value = "Countback", required = true, dataType = "int", paramType = "query"), @ApiImplicitParam(name = "countback", value = "开始时间和结束时间区间的计划展示的数量", required = true, dataType = "int", paramType = "query"),
@ApiImplicitParam(name = "currencyCode", value = "Currency code", required = true, dataType = "String", paramType = "query") @ApiImplicitParam(name = "currencyCode", value = "INR 不变", required = true, dataType = "String", paramType = "query")
}) })
@ResponseBody @ResponseBody
public ResponseEntity<StockHistoryResponse> getStockHistory( @RequestParam String symbol, public ResponseEntity<StockHistoryResponse> getStockHistory( @RequestParam String symbol,
@RequestParam String resolution, @RequestParam String resolution
@RequestParam long from, ) {
@RequestParam long to,
@RequestParam int countback,
@RequestParam String currencyCode) {
// 创建一个RestTemplate实例
RestTemplate restTemplate = new RestTemplate();
// 向外部API发起请求并获取响应 // 向外部API发起请求并获取响应
StockHistoryRequest request = new StockHistoryRequest(); StockHistoryRequest request = new StockHistoryRequest();
request.setSymbol(symbol); request.setSymbol(symbol);
request.setResolution(resolution); Long to = null;
Long from = null;
int countback = 5;
if(StringUtils.equals("H",resolution)){
to = (long) (System.currentTimeMillis() / 1000);
from = to - (1 * 60 * 60 );
countback = 60;
request.setResolution("1");
}else if(StringUtils.equals("D",resolution)){
to = (long) (System.currentTimeMillis() / 1000);
from = to - (24 * 60 * 60 );
countback = 9;
request.setResolution("60");
}else if(StringUtils.equals("W",resolution)){
to = (long) (System.currentTimeMillis() / 1000);
from = to - (10 * 24 * 60 * 60 );
countback = 7;
request.setResolution("1D");
}else if(StringUtils.equals("M",resolution)){
to = (long) (System.currentTimeMillis() / 1000);
from = to - (35 * 24 * 60 * 60 );
countback = 30;
request.setResolution("1D");
}
request.setFrom(from); request.setFrom(from);
request.setTo(to); request.setTo(to);
request.setCountback(countback); request.setCountback(countback);
request.setCurrencyCode(currencyCode); request.setCurrencyCode("INR");
String apiUrl = buildApiUrl(request); String apiUrl = buildApiUrl(request);
StockHistoryResponse response = restTemplate.getForObject(apiUrl, StockHistoryResponse.class); log.info("request url:"+apiUrl);
StockHistoryResponse response = null;
int maxRetries = 3;
int retryCount = 0;
while (response == null && retryCount < maxRetries) {
try {
response = restTemplate.getForObject(apiUrl, StockHistoryResponse.class);
} catch (RestClientException e) {
// Log the exception or perform any other error handling
log.error("Error while making API request. Retrying... (Retry count: {})", retryCount + 1);
// Increment the retry count
retryCount++;
// Add some delay before the next retry (you can adjust this as needed)
try {
Thread.sleep(300); // 1 second delay
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
if (response != null) {
// API request successful, return the response
return ResponseEntity.ok(response);
} else {
// All retries failed, return an error response
log.error("Failed to get a successful response after {} retries.", maxRetries);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
// 返回响应 // 返回响应
return ResponseEntity.ok(response);
} }
private String buildApiUrl(StockHistoryRequest request) { private String buildApiUrl(StockHistoryRequest request) {
// 构建外部API的URL // 构建外部API的URL
return String.format("%s?symbol=%s&resolution=%s&from=%d&to=%d&countback=%d&currencyCode=%s", return String.format("%s?symbol=%s&resolution=%s&from=%d&to=%d&countback=%d&currencyCode=%s",
@@ -647,4 +742,19 @@ public class MoneyApiController {
bseTopLoser(); bseTopLoser();
} }
private Cache<String, List<MoneyStockSuggestDTO>> gainerStockSuggestCache = CacheBuilder.newBuilder()
.maximumSize(100) // 设置缓存的最大大小
.expireAfterWrite(1, TimeUnit.HOURS) // 设置缓存条目的过期时间
.build();
private Cache<String, List<MoneyStockSuggestDTO>> loserStockSuggestCache = CacheBuilder.newBuilder()
.maximumSize(100) // 设置缓存的最大大小
.expireAfterWrite(1, TimeUnit.HOURS) // 设置缓存条目的过期时间
.build();
private Cache<String, List<MoneyStockSuggestDTO>> activesStockSuggestCache = CacheBuilder.newBuilder()
.maximumSize(100) // 设置缓存的最大大小
.expireAfterWrite(30, TimeUnit.MINUTES) // 设置缓存条目的过期时间
.build();
} }