src/main/java/com/nq/config/ThreadPoolConfig.java
New file @@ -0,0 +1,20 @@ package com.nq.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @Configuration public class ThreadPoolConfig { @Bean public ThreadPoolTaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(4); executor.setMaxPoolSize(4); executor.setQueueCapacity(10); executor.setThreadNamePrefix("stock-sync-"); executor.initialize(); return executor; } } src/main/java/com/nq/controller/StockApiController.java
@@ -54,6 +54,7 @@ @RequestMapping("getOptionStock.do") @ResponseBody() public ServerResponse getOptionStock(HttpServletRequest request){ @@ -117,4 +118,38 @@ public ServerResponse getVipByCode(String code) { return this.iStockService.getVipByCode(code); } /** * 获取首页数据 新闻和指数列表 * @param pageSize * @return */ @PostMapping({"getHomePageData.do"}) @ResponseBody public ServerResponse getHomePageData(@RequestParam(value = "pageSize", defaultValue = "5") int pageSize) { return this.iStockService.getIndicesIndexListAndNews(pageSize); } /** * 获取指数id和name 默认US * @param stockType * @return */ @RequestMapping("getIndicesList.do") @ResponseBody public ServerResponse getIndicesList(@RequestParam(value = "stockType", defaultValue = "US") String stockType) { return this.iStockService.getIndicesList(stockType); } /** * 获取单个指数数据和k线图 默认US * @param stockType * @return */ @RequestMapping("getIndicesAndKData.do") @ResponseBody public ServerResponse getIndicesAndKData(@RequestParam(value = "pid") String pid, @RequestParam(value = "stockType", defaultValue = "US") String stockType) { return this.iStockService.getIndicesAndKData(pid, stockType); } } src/main/java/com/nq/pojo/DataStockBean.java
@@ -64,5 +64,7 @@ private String Ticker; //k线 private Object kData; } src/main/java/com/nq/service/IStockService.java
@@ -104,5 +104,24 @@ Object getKData(String pid,String interval,String stockType); ServerResponse getOptionStock(HttpServletRequest request); ServerResponse getOptionStock(HttpServletRequest request); /** * 获取首页指数列表 * @param pageSize * @return */ ServerResponse getIndicesIndexListAndNews(Integer pageSize); /** * 获取指数数据 获取指数id和name * @return */ ServerResponse getIndicesList(String stockType); /** * 获取单个指数数据和k线图 * @return */ ServerResponse getIndicesAndKData(String pid, String stockType); } src/main/java/com/nq/service/impl/PriceServicesImpl.java
@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.fasterxml.jackson.core.JsonProcessingException; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.nq.dao.StockDzMapper; import com.nq.dao.StockMapper; import com.nq.dao.StockSettingMapper; @@ -13,23 +12,14 @@ import com.nq.pojo.*; import com.nq.service.IPriceServices; import com.nq.service.IStockConfigServices; import com.nq.utils.PropertiesUtil; import com.nq.utils.http.HttpClientRequest; import com.nq.utils.redis.RedisKeyUtil; import com.nq.utils.timeutil.TimeUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.io.*; import java.lang.reflect.Type; import java.math.BigDecimal; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Map; import com.fasterxml.jackson.databind.ObjectMapper; @@ -67,7 +57,7 @@ if(stockSetting.getType().equals("0")){ return new BigDecimal(stockSetting.getPrice()); }else{ String s = doPost(stock.getStockCode()); String s = RedisKeyUtil.doPost(stock.getStockCode(), stock.getStockType()); if(null != s){ Map<String, Object> stringObjectMap = jsonToMap(s); return new BigDecimal(stringObjectMap.get("Last").toString()).multiply(new BigDecimal(stockSetting.getPrice())); @@ -76,7 +66,7 @@ } } String s = doPost(stock.getStockCode()); String s = RedisKeyUtil.doPost(stock.getStockCode(), stock.getStockType()); if(null != s) { Map<String, Object> stringObjectMap = jsonToMap(s); return new BigDecimal(stringObjectMap.get("Last").toString()); @@ -87,7 +77,7 @@ @Override public Map<String, Object> getNewStock(String stockCode) { Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("stock_code",stockCode)); String s = doPost(stock.getStockCode()); String s = RedisKeyUtil.doPost(stock.getStockCode(), stock.getStockType()); if(null != s){ Map<String, Object> stringObjectMap = jsonToMap(s); return stringObjectMap; @@ -101,6 +91,9 @@ ObjectMapper objectMapper = new ObjectMapper(); try { Object[] array = objectMapper.readValue(json, Object[].class); if (array.length == 0) { return Collections.emptyMap(); } Gson gson = new Gson(); String s = gson.toJson(array[0]); Map<String, Object> map = objectMapper.readValue(s, Map.class); @@ -108,45 +101,6 @@ } catch (JsonProcessingException e) { throw new RuntimeException(e); } } public String doPost(String pid) { // 从配置中获取 API URL,并拼接 key String apiUrl = PropertiesUtil.getProperty("JS_IN_HTTP_URL") + "stock?key=" + PropertiesUtil.getProperty("JS_IN_KEY"); String result = null; try { URL url = new URL(apiUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 设置请求方法为 POST connection.setRequestMethod("POST"); // 设置请求头 connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setDoOutput(true); // 允许向连接输出 // 构建 POST 数据 String postData = "pid=" + pid; // 发送 POST 请求 try (OutputStream os = connection.getOutputStream()) { byte[] input = postData.getBytes("utf-8"); os.write(input, 0, input.length); } // 读取响应 BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); result = response.toString(); } catch (Exception e) { e.printStackTrace(); } return result; } src/main/java/com/nq/service/impl/SiteNewsServiceImpl.java
@@ -165,7 +165,8 @@ siteNews.setSourceId(newsId); siteNews.setSourceName(""); siteNews.setTitle(jsonObject.getString("title")); Long showTime = jsonObject.getLong("time"); //Long showTime = jsonObject.getLong("time"); long showTime = jsonObject.optLong("time", System.currentTimeMillis() / 1000); // 默认值,表示未找到或转换失败 siteNews.setShowTime(new Date(showTime * 1000)); if(jsonObject.has("img")){ convertBase64ToImage(jsonObject.getString("img"),PropertiesUtil.getProperty("ftp.address")+newsId+".jpg"); src/main/java/com/nq/service/impl/StockServiceImpl.java
@@ -1,8 +1,6 @@ package com.nq.service.impl; import cn.hutool.core.util.ObjectUtil; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.github.pagehelper.PageHelper; @@ -10,10 +8,8 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; import com.nq.common.ServerResponse; import com.nq.config.StockPoll; import com.nq.dao.*; import com.nq.enums.EStockType; import com.nq.pojo.*; @@ -26,28 +22,18 @@ import com.nq.utils.stock.pinyin.GetPyByChinese; import com.nq.utils.stock.qq.QqStockApi; import com.nq.utils.stock.sina.StockApi; import com.nq.utils.translate.GoogleTranslateUtil; import com.nq.vo.stock.*; import com.nq.vo.stock.k.MinDataVO; import com.nq.vo.stock.k.echarts.EchartsDataVO; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.math.BigDecimal; import java.net.HttpURLConnection; import java.net.URL; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import lombok.Data; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,14 +49,8 @@ @Autowired StockMapper stockMapper; @Resource RealTimeMapper realTimeMapper; @Autowired IStockMarketsDayService iStockMarketsDayService; @Autowired StockPoll stockPoll; @Resource StockFuturesMapper stockFuturesMapper; @@ -82,20 +62,16 @@ IUserService iUserService; @Autowired IStockOptionService iStockOptionService; @Autowired ISiteSettingService iSiteSettingService; @Autowired InStockMapper inStockMapper; @Resource StockDzMapper stockDzMapper; @Autowired IPriceServices iPriceServices; @Autowired SiteNewsMapper siteNewsMapper; public ServerResponse getMarket() { @@ -170,17 +146,26 @@ @Override public ServerResponse getStockByType(int pageNum, int pageSize, String orderBy, String keyWords, String stockType, HttpServletRequest request) { List<Stock> stockList = new ArrayList<>(); PageHelper.startPage(pageNum, pageSize); stockList.addAll(stockMapper.findStockByType(orderBy,stockType,keyWords)); List<Stock> stockList = stockMapper.findStockByType(orderBy, stockType, keyWords); // 获取分页信息 PageInfo<Stock> pageInfo = new PageInfo<>(stockList); List<StockListVO> stockListVOS = Lists.newArrayList(); if (stockList.size() > 0){ if (stockList.size() > 0) { stockListVOS.addAll(Objects.requireNonNull(StockApi.getStockReailTimes(stockList))); } RPageInfo pageInfo = new RPageInfo(); pageInfo.setList(stockListVOS); pageInfo.setStockType(stockType); return ServerResponse.createBySuccess(pageInfo); RPageInfo resultPageInfo = new RPageInfo(); resultPageInfo.setList(stockListVOS); resultPageInfo.setStockType(stockType); // 设置分页信息 resultPageInfo.setTotal(pageInfo.getTotal()); resultPageInfo.setPageNum(pageInfo.getPageNum()); resultPageInfo.setPageSize(pageInfo.getPageSize()); resultPageInfo.setPages(pageInfo.getPages()); resultPageInfo.setHasNextPage(pageInfo.isHasNextPage()); return ServerResponse.createBySuccess(resultPageInfo); } @Override @@ -193,7 +178,7 @@ if (StringUtils.isBlank(code)) return ServerResponse.createByErrorMsg(""); Stock stock = stockMapper.findStockByCode(code); DataStockBean cacheBaseStock = RedisKeyUtil.getCacheBaseStock(stock); DataStockBean cacheBaseStock = RedisKeyUtil.getCacheBaseStock(stock.getStockType(), stock.getStockCode()); Integer depositAmt = 0; String introduction = null; StockVO stockVO = StockApi.assembleInStockVO(stock); @@ -223,7 +208,7 @@ if (StringUtils.isBlank(code)) return null; Stock stock = stockMapper.findStockByCode(code); DataStockBean cacheBaseStock = RedisKeyUtil.getCacheBaseStock(stock); DataStockBean cacheBaseStock = RedisKeyUtil.getCacheBaseStock(stock.getStockType(), stock.getStockCode()); Integer depositAmt = 0; String introduction = null; StockVO stockVO = StockApi.assembleInStockVO(stock); @@ -711,4 +696,115 @@ } return ServerResponse.createBySuccess(pool); } @Override public ServerResponse getIndicesIndexListAndNews(Integer pageSize) { try { //新闻列表 List<SiteNews> newsList = this.siteNewsMapper.getTopNewsList(pageSize); String usCodeList = PropertiesUtil.getProperty("us_home_indices_code"); String mxCodeList = PropertiesUtil.getProperty("mx_home_indices_code"); List<String> usStockCodeList = Arrays.asList(usCodeList.split(",")); List<String> mxStockCodeList = Arrays.asList(mxCodeList.split(",")); List<DataStockBean> usDataStockBeans = Lists.newArrayList(); List<DataStockBean> mxDataStockBeans = Lists.newArrayList(); for (int i = 0; i < usStockCodeList.size(); i++) { String stockCode = usStockCodeList.get(i); String stockType = EStockType.US.getCode(); DataStockBean cacheBaseStock = RedisKeyUtil.getCacheBaseStock(stockType, stockCode); // 获取K线数据 Object kData = RedisKeyUtil.getCaCheStockKData(stockType, stockCode); if (kData == null) { //重新获取并缓存redis kData = getKData(stockCode, "D", stockType); RedisKeyUtil.setCaCheStockKData(stockType, stockCode, kData); } Gson gson = new Gson(); List<kData> dataList = gson.fromJson(kData.toString(), new TypeToken<List<kData>>(){}.getType()); cacheBaseStock.setKData(dataList); usDataStockBeans.add(cacheBaseStock); } for (int i = 0; i < mxStockCodeList.size(); i++) { String stockCode = mxStockCodeList.get(i); String stockType = EStockType.MX.getCode(); DataStockBean cacheBaseStock = RedisKeyUtil.getCacheBaseStock(stockType, stockCode); // 获取K线数据 Object kData = RedisKeyUtil.getCaCheStockKData(stockType, stockCode); if (kData == null) { //重新获取并缓存redis kData = getKData(stockCode, "D", stockType); RedisKeyUtil.setCaCheStockKData(stockType, stockCode, kData); } Gson gson = new Gson(); List<kData> dataList = gson.fromJson(kData.toString(), new TypeToken<List<kData>>(){}.getType()); cacheBaseStock.setKData(dataList); mxDataStockBeans.add(cacheBaseStock); } Map<String, Object> resultMap = new HashMap<>(); resultMap.put("newsList", newsList); //新闻列表 resultMap.put("usDataStockBeans", usDataStockBeans);//美国指数 resultMap.put("mxDataStockBeans", mxDataStockBeans);//墨西哥指数 return ServerResponse.createBySuccess(resultMap); } catch (Exception e){ e.printStackTrace(); } return ServerResponse.createByError(); } @Override public ServerResponse getIndicesList(String stockType) { try { String codeList; if (stockType.equals(EStockType.US.getCode())) { codeList = PropertiesUtil.getProperty("us_home_indices_code"); } else { codeList = PropertiesUtil.getProperty("mx_home_indices_code"); } List<String> stockCodeList = Arrays.asList(codeList.split(",")); Map<Integer, Object> resultMap = new HashMap<>(); for (int i = 0; i < stockCodeList.size(); i++) { String stockCode = stockCodeList.get(i); DataStockBean cacheBaseStock = RedisKeyUtil.getCacheBaseStock(stockType, stockCode); Map<String, Object> stockInfo = new HashMap<>(); stockInfo.put("pid", cacheBaseStock.getId()); stockInfo.put("name", cacheBaseStock.getName()); stockInfo.put("stockType", stockType); resultMap.put(i+1, stockInfo); } return ServerResponse.createBySuccess(resultMap); } catch (Exception e){ e.printStackTrace(); } return ServerResponse.createByError(); } @Override public ServerResponse getIndicesAndKData(String pid, String stockType) { try { Map<String, Object> resultMap = new HashMap<>(); DataStockBean cacheBaseStock = RedisKeyUtil.getCacheBaseStock(stockType, pid); if (cacheBaseStock != null) { resultMap.put("last", cacheBaseStock.getLast()); resultMap.put("chg", cacheBaseStock.getChg()); resultMap.put("chgPct", cacheBaseStock.getChgPct()); resultMap.put("kData", cacheBaseStock.getChg()); // 获取K线数据 Object kData = RedisKeyUtil.getCaCheStockKData(stockType, pid); if (kData == null) { //重新获取并缓存redis kData = getKData(pid, "D", stockType); RedisKeyUtil.setCaCheStockKData(stockType, pid, kData); } Gson gson = new Gson(); List<kData> dataList = gson.fromJson(kData.toString(), new TypeToken<List<kData>>(){}.getType()); resultMap.put("kData", dataList); return ServerResponse.createBySuccess(resultMap); } } catch (Exception e){ e.printStackTrace(); } return ServerResponse.createByError(); } } src/main/java/com/nq/utils/redis/RedisKeyConstant.java
@@ -25,5 +25,8 @@ * */ public static final String RK_COMPANY_INFO = "rk_company_info"; /** * 股票K线图数据key * */ public static final String RK_STOCK_KDATA = "rk_stock_kdata"; } src/main/java/com/nq/utils/redis/RedisKeyUtil.java
@@ -37,8 +37,8 @@ /** * 获取股票数据 * */ public static DataStockBean getCacheBaseStock(Stock stock){ String cacheBaseData = RedisShardedPoolUtils.get(RedisKeyConstant.RK_BASE_STOCK+":"+stock.getStockType()+":"+stock.getStockCode()); public static DataStockBean getCacheBaseStock(String stockType, String stockCode){ String cacheBaseData = RedisShardedPoolUtils.get(RedisKeyConstant.RK_BASE_STOCK+":"+stockType+":"+stockCode); return new Gson().fromJson(cacheBaseData, DataStockBean.class); } @@ -60,7 +60,7 @@ stockRealTimeBean = new Gson().fromJson(cacheBaseData, StockRealTimeBean.class); } if(stockRealTimeBean == null){ String s = doPost(stock.getStockCode()); String s = doPost(stock.getStockCode(), stock.getStockType()); Map<String, Object> stringObjectMap = jsonToMap(s); stockRealTimeBean = new StockRealTimeBean(); stockRealTimeBean.setPcp(stringObjectMap.get("ChgPct").toString()); @@ -89,9 +89,11 @@ } } public static String doPost(String pid) { public static String doPost(String pid, String stockType) { EStockType eStockType = EStockType.getEStockTypeByCode(stockType); // 从配置中获取 API URL,并拼接 key String apiUrl = PropertiesUtil.getProperty("JS_IN_HTTP_URL") + "stock?key=" + PropertiesUtil.getProperty("JS_IN_KEY"); //String apiUrl = PropertiesUtil.getProperty("JS_IN_HTTP_URL") + "stock?key=" + PropertiesUtil.getProperty("JS_IN_KEY"); String apiUrl = eStockType.getStockUrl() + "stock?key=" + eStockType.getStockKey(); String result = null; try { URL url = new URL(apiUrl); @@ -143,6 +145,15 @@ return JSONObject.parseObject(companiesInfo); } /** * 缓存K线数据源到redis * */ public static void setCaCheStockKData(String stockType, String stockCode, Object kData){ RedisShardedPoolUtils.set(RedisKeyConstant.RK_STOCK_KDATA+":"+stockType+":"+stockCode, kData.toString()); } public static Object getCaCheStockKData(String stockType, String stockCode){ return RedisShardedPoolUtils.get(RedisKeyConstant.RK_STOCK_KDATA+":"+stockType+":"+stockCode); } } src/main/java/com/nq/utils/redis/RedisShardedPoolUtils.java
@@ -142,11 +142,11 @@ try { if (key == null) { jedis = RedisShardedPool.getJedis(); jedis = RedisShardedPool.getJedis(); result = jedis.del(key); result = jedis.del(key); } } catch (Exception e) { log.error("redis del key: {} error ", key, e); src/main/java/com/nq/utils/task/stock/StockTask.java
@@ -1,13 +1,8 @@ package com.nq.utils.task.stock; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; import com.nq.Repository.StockRepository; import com.nq.dao.StockMapper; @@ -17,24 +12,21 @@ import com.nq.service.IMandatoryLiquidationService; import com.nq.service.IStockService; import com.nq.service.IUserPositionService; import com.nq.service.impl.StockServiceImpl; import com.nq.utils.PropertiesUtil; import com.nq.utils.http.HttpClientRequest; import com.nq.utils.http.HttpRequest; import com.nq.utils.redis.RedisKeyUtil; import net.sf.json.JSONArray; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -44,85 +36,79 @@ @Component public class StockTask { @Autowired IStockService stockService; @Autowired StockMapper stockMapper; @Autowired IUserPositionService userPositionService; @Autowired UserPositionMapper userPositionMapper; IStockService istockService; @Autowired StockRepository stockRepository; private final Lock stockConstraintLock = new ReentrantLock(); @Autowired IMandatoryLiquidationService mandatoryLiquidationService; private static final Logger log = LoggerFactory.getLogger(StockTask.class); private final AtomicBoolean syncINStockData = new AtomicBoolean(false); private final Lock syncINStockDataLock = new ReentrantLock(); @Autowired private ThreadPoolTaskExecutor taskExecutor; @Autowired private StockServiceImpl iStockService; /** * test */ //@Scheduled(cron = "0 0/1 * * * ?") @Scheduled(cron = "*/5 * * * * *") public void test() { //iStockService.getStockByType(1, 20, "desc","st" , "US", null); //istockService.getIndicesList("US"); //istockService.getIndicesAndKData("15882", "US"); } /** * 同步系统所需要的股票 */ @Scheduled(cron = "0 0/1 * * * ?") public void syncINStockData() { if (syncINStockData.get()) { // 判断任务是否在处理中 return; } if (syncINStockDataLock.tryLock()) { ExecutorService executor = Executors.newFixedThreadPool(4); Future<?> future1 = null; Future<?> future2 = null; Future<?> future3 = null; Future<?> future4 = null; try { syncINStockData.set(true); // 设置处理中标识为true syncINStockData.set(true); // 同步股票数据 future1 = executor.submit(() -> loadAllStock(EStockType.US)); future2 = executor.submit(() -> loadAllStock(EStockType.MX)); // 同步指数数据 future3 = executor.submit(() -> syncIndices(EStockType.US)); future4 = executor.submit(() -> syncIndices(EStockType.MX)); // 使用CompletableFuture并行执行任务 CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> loadAllStock(EStockType.US), taskExecutor); CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> loadAllStock(EStockType.MX), taskExecutor); CompletableFuture<Void> future3 = CompletableFuture.runAsync(() -> syncIndices(EStockType.US), taskExecutor); CompletableFuture<Void> future4 = CompletableFuture.runAsync(() -> syncIndices(EStockType.MX), taskExecutor); // 等待任务都完成 future1.get(); future2.get(); future3.get(); future4.get(); // 等待所有任务完成 CompletableFuture.allOf(future1, future2, future3, future4).join(); } catch (Exception e) { Thread.currentThread().interrupt(); log.error("同步股票数据出错", e); } finally { // 关闭线程池 if (executor != null) { executor.shutdown(); } syncINStockDataLock.unlock(); syncINStockData.set(false); // 设置处理中标识为false syncINStockData.set(false); } } } /** * 加载所有指数数据 */ private void syncIndices(EStockType eStockType) { List<DataStockBean> list = new ArrayList<>(); int totleStock = 1; try { while (totleStock > list.size()) { try { //String result = HttpClientRequest.doGet(eStockType.stockUrl + "indices?key=" + eStockType.getStockKey() + "&country_id=" + eStockType.getContryId()); //ReponseBase reponseBase = new Gson().fromJson(result, ReponseBase.class); String result = HttpRequest.doGrabGet(eStockType.stockUrl + "indices?key=" + eStockType.getStockKey() + "&country_id=" + eStockType.getContryId()); // 把JSON数据解析为List<DataStockBean> Type listType = new TypeToken<List<DataStockBean>>(){}.getType(); @@ -169,12 +155,44 @@ stockMapper.updateById(stock); }*/ RedisKeyUtil.setCaCheKeyBaseStock(eStockType, o); /*StockRealTimeBean stockRealTimeBean = new StockRealTimeBean(); stockRealTimeBean.setPid(o.getId()); stockRealTimeBean.setLast(o.getLast()); stockRealTimeBean.setHigh(o.getHigh()); stockRealTimeBean.setLow(o.getLow()); stockRealTimeBean.setPc(o.getChg()); stockRealTimeBean.setPcp(o.getChgPct()+ "%"); stockRealTimeBean.setTime(o.getTime()); RedisKeyUtil.setCacheRealTimeStock(eStockType, stockRealTimeBean);*/ } stockRepository.saveAll(updateStockList); cacheKData(eStockType.getCode(), list); log.info("同步指数 数据 成功 {} 总共同步数据 {}", eStockType.getCode(), list.size()); } catch (Exception e) { e.printStackTrace(); log.error("同步指数列表出现异常: {}", e.getMessage()); } } /** * 同步指数股票后缓存k线图 */ public void cacheKData(String stockType, List<DataStockBean> list) { String usCodeList = PropertiesUtil.getProperty("us_home_indices_code"); String mxCodeList = PropertiesUtil.getProperty("mx_home_indices_code"); for (DataStockBean dataStockBean : list) { //缓存首页指数k线图 if (usCodeList.contains(dataStockBean.getId()) || mxCodeList.contains(dataStockBean.getId())) { // 获取K线数据 Object kData = istockService.getKData(dataStockBean.getId(), "D", stockType); if (kData != null) { //缓存redis RedisKeyUtil.setCaCheStockKData(stockType, dataStockBean.getId(), kData); } } } log.info("同步指数k线图 数据 成功 {} 总共同步数据 {}", stockType, list.size()); } /** @@ -218,7 +236,7 @@ try { while (totleStock > list.size()) { try { String result = HttpClientRequest.doGet(eStockType.stockUrl + "list?country_id=" + eStockType.getContryId() + "&size=1000&page=" + page + "&key=" + eStockType.stockKey); String result = HttpClientRequest.doGet(eStockType.stockUrl + "list?country_id=" + eStockType.getContryId() + "&size=100000&page=" + page + "&key=" + eStockType.stockKey); ReponseBase reponseBase = new Gson().fromJson(result, ReponseBase.class); list.addAll(reponseBase.getData()); page++; @@ -233,9 +251,7 @@ } List<String> stockCodeList = list.stream().map(DataStockBean::getId).collect(Collectors.toList()); List<Stock> stockList = stockMapper.selectList(new QueryWrapper<Stock>().in("stock_code", stockCodeList)); int i = 1; List<Stock> updateStockList = new ArrayList<>(); System.out.println(new Date()); for (DataStockBean o : list) { //Stock stock = stockMapper.findStockByCode(o.getId()); Stock stock = stockList.stream() @@ -276,11 +292,8 @@ } updateStockList.add(stock); RedisKeyUtil.setCaCheKeyBaseStock(eStockType, o); System.out.println(i); i++; } stockRepository.saveAll(updateStockList); System.out.println(new Date()); log.info("同步股票 数据 成功 {} 总共同步数据 {}", eStockType.getCode(), list.size()); } catch ( Exception e) { src/main/java/com/nq/ws/MXWebsocketRunClient.java
@@ -51,7 +51,9 @@ heartbeatTimer.schedule(new TimerTask() { @Override public void run() { send(("key:"+ eStockType.getStockKey()+":"+eStockType.getContryId()).getBytes()); if (isOpen()) { send(("key:"+ eStockType.getStockKey()+":"+eStockType.getContryId()).getBytes()); } } }, 0, 3000); // 每3秒发送一次心跳消息 } src/main/java/com/nq/ws/WebsocketRunClient.java
@@ -52,7 +52,10 @@ heartbeatTimer.schedule(new TimerTask() { @Override public void run() { send(("key:"+ eStockType.getStockKey()+":"+eStockType.getContryId()).getBytes()); if (isOpen()) { send(("key:"+ eStockType.getStockKey()+":"+eStockType.getContryId()).getBytes()); } } }, 0, 3000); // 每3秒发送一次心跳消息 } src/main/resources/application.properties
@@ -92,9 +92,9 @@ SZHB_WS_URL = ws://api-in-ws.js-stock.top SZHB_KEY = GBZAcUPLKZzDMDjvV9Ea #默认首页显示指数code us_home_indices_code=15882,15881,16571 mx_home_indices_code=535610327,535610374,535610333 #?? ?? - ???? admin.auth.email.subject=???? - ?????? src/main/resources/mapper/StockMapper.xml
@@ -319,8 +319,10 @@ <include refid="Base_Column_List"/> FROM stock where stock_type = #{stockType} and stock_spell not like '%.st%' where stock_spell not like '%.st%' <if test="stockType != null and stockType != '' "> and stock_type = #{stockType} </if> <if test="keyWords != null and keyWords != '' "> and (stock_spell like concat('%',#{keyWords},'%') or stock_name like concat('%',#{keyWords},'%') ) </if>