From b6c57b550483b3f91685731a24df903898c3c077 Mon Sep 17 00:00:00 2001
From: zj <1772600164@qq.com>
Date: Fri, 25 Apr 2025 19:18:30 +0800
Subject: [PATCH] 1
---
src/main/resources/application.properties | 2
src/main/java/com/nq/enums/EStockType.java | 5
src/main/java/com/nq/service/impl/StockServiceImpl.java | 116 +++--------
src/main/java/com/nq/pojo/reponse/kResponse.java | 37 +++
src/main/java/com/nq/controller/StockApiController.java | 31 ++-
src/main/java/com/nq/utils/task/stock/StockTask.java | 321 ++++++++++++++++++++++---------
src/main/java/com/nq/service/IStockService.java | 5
src/main/java/com/nq/service/impl/UserPositionServiceImpl.java | 8
pom.xml | 6
src/main/java/com/nq/utils/redis/RedisKeyConstant.java | 21 +
10 files changed, 355 insertions(+), 197 deletions(-)
diff --git a/pom.xml b/pom.xml
index 93707c7..fb2bb19 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,7 +25,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
-
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ <version>2.12.5</version>
+ </dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
diff --git a/src/main/java/com/nq/controller/StockApiController.java b/src/main/java/com/nq/controller/StockApiController.java
index 4bedfff..c545ae9 100644
--- a/src/main/java/com/nq/controller/StockApiController.java
+++ b/src/main/java/com/nq/controller/StockApiController.java
@@ -1,5 +1,6 @@
package com.nq.controller;
+import com.fasterxml.jackson.core.JsonProcessingException;
import com.nq.common.ServerResponse;
import com.nq.pojo.SiteSetting;
import com.nq.service.IStockService;
@@ -60,20 +61,22 @@
@ResponseBody
public ServerResponse getGoldCrudeOil(HttpServletRequest request) {
- String gold = RedisShardedPoolUtils.get(RedisKeyConstant.gold);
- String crudeOil = RedisShardedPoolUtils.get(RedisKeyConstant.crude_oil);
+ String gold = RedisShardedPoolUtils.get(RedisKeyConstant.XAUUSD);
+ String crudeOil = RedisShardedPoolUtils.get(RedisKeyConstant.USOIL);
HashMap<String,HashMap> hashMap = new HashMap<>();
HashMap<String,String> goldMap = new HashMap<>();
- String goldName = new GoogleTranslateUtil().translate("GOLD", request.getHeader("lang"));
- goldMap.put(goldName,gold);
- hashMap.put("GOLD",goldMap);
+ goldMap.put("XAUUSD",gold);
+ goldMap.put("hcrate",RedisShardedPoolUtils.get("XAUUSD"+"_H"));
+ goldMap.put("hcrateP",RedisShardedPoolUtils.get("XAUUSD"+"_H")+"%");
+ hashMap.put("XAUUSD",goldMap);
HashMap<String,String> crudOilMap = new HashMap<>();
- String crudeOilName = new GoogleTranslateUtil().translate("CRUDE OIL", request.getHeader("lang"));
- crudOilMap.put(crudeOilName,crudeOil);
- hashMap.put("CRUDE OIL",crudOilMap);
+ crudOilMap.put("USOIL",crudeOil);
+ crudOilMap.put("hcrate",RedisShardedPoolUtils.get("USOIL"+"_H"));
+ crudOilMap.put("hcrateP",RedisShardedPoolUtils.get("USOIL"+"_H")+"%");
+ hashMap.put("USOIL",crudOilMap);
return ServerResponse.createBySuccess(hashMap);
}
@@ -90,7 +93,7 @@
//通过股票代码查询股票信息
@RequestMapping({"getSingleStock.do"})
@ResponseBody
- public ServerResponse getSingleStock(@RequestParam("code") String code, HttpServletRequest request) {
+ public ServerResponse getSingleStock(@RequestParam("code") String code, HttpServletRequest request) throws JsonProcessingException {
return this.iStockService.getSingleStock(code, request);
}
@@ -101,9 +104,15 @@
public Object getKData(
@RequestParam("pid") String pid,
@RequestParam("interval") String interval,
- @RequestParam("stockType") String stockType
+ @RequestParam("stockType") String stockType,
+ HttpServletRequest request
) {
- return this.iStockService.getKData(pid,interval,stockType);
+ try {
+ return this.iStockService.getKData(pid,interval,stockType);
+ }catch (Exception e){
+ log.error("获取k线失败",e.getMessage());
+ }
+ return ServerResponse.createByErrorMsg("获取k线失败",request);
}
diff --git a/src/main/java/com/nq/enums/EStockType.java b/src/main/java/com/nq/enums/EStockType.java
index 4d119a0..45e834e 100644
--- a/src/main/java/com/nq/enums/EStockType.java
+++ b/src/main/java/com/nq/enums/EStockType.java
@@ -16,7 +16,8 @@
MAS("MAS","马来西亚股票","42",PropertiesUtil.getProperty("MAS_HTTP_API"),PropertiesUtil.getProperty("MAS_KEY"),"MYR","RM"),
IN("IN","印度股票","14", PropertiesUtil.getProperty("JS_IN_HTTP_URL"),PropertiesUtil.getProperty("JS_IN_KEY"),"INR","₹"),
- ST("ST","沙特股票","52", PropertiesUtil.getProperty("ST_HTTP_API"),PropertiesUtil.getProperty("ST_KEY"),"SAR","﷼");
+ ST("ST","沙特股票","52", PropertiesUtil.getProperty("ST_HTTP_API"),PropertiesUtil.getProperty("ST_KEY"),"SAR","﷼"),
+ USDT("USDT","USDT","52", PropertiesUtil.getProperty("ST_HTTP_API"),PropertiesUtil.getProperty("ST_KEY"),"USDT","$");
// TH("TH","泰国股票","41",PropertiesUtil.getProperty("TH_HTTP_API"),PropertiesUtil.getProperty("TH_KEY")),
// HG("HG","韩国股票","11",PropertiesUtil.getProperty("HG_HTTP_API"),PropertiesUtil.getProperty("HG_KEY")),
// SZHB("SZHB","数字货币","41",PropertiesUtil.getProperty("SZHB_HTTP_API"),PropertiesUtil.getProperty("SZHB_KEY"));
@@ -54,7 +55,7 @@
}else if(EStockType.ST.getCode().equals(code)){
return ST;
}else{
- return MAS;
+ return USDT;
}
}
diff --git a/src/main/java/com/nq/pojo/reponse/kResponse.java b/src/main/java/com/nq/pojo/reponse/kResponse.java
new file mode 100644
index 0000000..07010e5
--- /dev/null
+++ b/src/main/java/com/nq/pojo/reponse/kResponse.java
@@ -0,0 +1,37 @@
+package com.nq.pojo.reponse;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @program: dabaogp
+ * @description:
+ * @create: 2025-04-25 17:29
+ **/
+@Data
+public class kResponse {
+ private int ret;
+ private String msg;
+ private String trace;
+ private Data data;
+
+ @lombok.Data
+ public static class Data {
+ @SerializedName("kline_list")
+ private List<KlineData> klineList;
+ }
+
+ @lombok.Data
+ public static class KlineData {
+ private long timestamp;
+ private String open_price;
+ private String close_price;
+ private String high_price;
+ private String low_price;
+ private String volume;
+ private String turnover;
+ }
+}
diff --git a/src/main/java/com/nq/service/IStockService.java b/src/main/java/com/nq/service/IStockService.java
index 4763888..140331a 100644
--- a/src/main/java/com/nq/service/IStockService.java
+++ b/src/main/java/com/nq/service/IStockService.java
@@ -1,5 +1,6 @@
package com.nq.service;
+import com.fasterxml.jackson.core.JsonProcessingException;
import com.github.pagehelper.PageInfo;
import com.nq.common.ServerResponse;
import com.nq.pojo.Stock;
@@ -46,7 +47,7 @@
// void bj1();
ServerResponse getDateline(HttpServletResponse paramHttpServletResponse, String paramString);
- ServerResponse getSingleStock(String paramString,HttpServletRequest request);
+ ServerResponse getSingleStock(String paramString,HttpServletRequest request) throws JsonProcessingException;
ServerResponse getMinK(String paramString, Integer paramInteger1, Integer paramInteger2, Integer paramInteger3);
@@ -101,7 +102,7 @@
ServerResponse getStockDayK(String code);
- Object getKData(String pid,String interval,String stockType);
+ Object getKData(String pid,String interval,String stockType) throws JsonProcessingException;
ServerResponse getOptionStock(HttpServletRequest request);
diff --git a/src/main/java/com/nq/service/impl/StockServiceImpl.java b/src/main/java/com/nq/service/impl/StockServiceImpl.java
index 9e99419..fee5b73 100644
--- a/src/main/java/com/nq/service/impl/StockServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/StockServiceImpl.java
@@ -5,6 +5,8 @@
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
@@ -18,6 +20,7 @@
import com.nq.enums.EStockType;
import com.nq.pojo.*;
import com.nq.pojo.reponse.RPageInfo;
+import com.nq.pojo.reponse.kResponse;
import com.nq.service.*;
import com.nq.utils.http.HttpClientRequest;
import com.nq.utils.PropertiesUtil;
@@ -63,6 +66,7 @@
import org.springframework.web.client.RestTemplate;
import static com.nq.utils.timeutil.DateTimeUtil.getWeekDay;
+import static net.sf.jsqlparser.util.validation.metadata.NamedObject.user;
@Service("iStockService")
public class StockServiceImpl implements IStockService {
@@ -208,21 +212,24 @@
}
- public ServerResponse getSingleStock(String code, HttpServletRequest request) {
+ public ServerResponse getSingleStock(String code, HttpServletRequest request) throws JsonProcessingException {
- if(code.equals("GOLD")){
- String price = RedisShardedPoolUtils.get(RedisKeyConstant.gold);
+ if(code.equals("XAUUSD")){
+ String price = RedisShardedPoolUtils.get(RedisKeyConstant.XAUUSD);
+ getKData(null, "1", code);//只是为了得到下面redis的值
StockVO stockVO = new StockVO();
stockVO.setNowPrice(price);
stockVO.setName(code);
+ stockVO.setHcrate(RedisShardedPoolUtils.get(code+"_H"));
Map map = Maps.newHashMap();
map.put("stock", stockVO);
return ServerResponse.createBySuccess(map);
- }else if(code.equals("CRUDE OIL")){
- String price = RedisShardedPoolUtils.get(RedisKeyConstant.crude_oil);
+ }else if(code.equals("USOIL")){
+ String price = RedisShardedPoolUtils.get(RedisKeyConstant.USOIL);
StockVO stockVO = new StockVO();
stockVO.setNowPrice(price);
stockVO.setName(code);
+ stockVO.setHcrate(RedisShardedPoolUtils.get(code+"_H"));
Map map = Maps.newHashMap();
map.put("stock", stockVO);
return ServerResponse.createBySuccess(map);
@@ -470,22 +477,15 @@
}
- //黄金
- private static final String gold_API_URL = "http://139.196.211.109/ldMetal_k.action?username=Qq112233&password=3ce25a66d5b3a8cd661024fea6c79388&id=AUUSDO&num=-100&period=";
-
- //原油
- private static final String crude_oil_API_URL = "http://47.112.169.122/fOption_k.action?username=Qq112233&password=3ce25a66d5b3a8cd661024fea6c79388&id=@CL0W&num=-100&period=";
-
/*股票日线-K线*/
@Override
- public Object getKData(String pid, String interval, String stockType) {
- if(stockType.equals("GOLD")){
+ public Object getKData(String pid, String interval, String stockType) throws JsonProcessingException {
+ if(stockType.equals("XAUUSD")){
// 使用RestTemplate发起HTTP请求
String response = RedisShardedPoolUtils.get("k_gold_"+interval.toLowerCase());
return parseData(interval,response, stockType);
- }else if(stockType.equals("CRUDE OIL")){
+ }else if(stockType.equals("USOIL")){
// 使用RestTemplate发起HTTP请求
- RestTemplate restTemplate = new RestTemplate();
String response = RedisShardedPoolUtils.get("k_crude_oil_"+interval.toLowerCase());
return parseData(interval,response, stockType);
}else{
@@ -508,82 +508,34 @@
}
}
- public List<kData> parseData(String interval,String data,String key) {
+ public List<kData> parseData(String interval,String data,String key) throws JsonProcessingException {
String price = null;
- if(key.equals("GOLD")){
- price = RedisShardedPoolUtils.get(RedisKeyConstant.gold);
- }else if(key.equals("CRUDE OIL")){
- price = RedisShardedPoolUtils.get(RedisKeyConstant.crude_oil);
+ if(key.equals("XAUUSD")){
+ price = RedisShardedPoolUtils.get(RedisKeyConstant.XAUUSD);
+ }else if(key.equals("USOIL")){
+ price = RedisShardedPoolUtils.get(RedisKeyConstant.USOIL);
}
List<kData> kDataList = new ArrayList<>();
+ // 使用 Gson 解析 JSON 字符串
+ Gson gson = new Gson();
+ kResponse kResponse = gson.fromJson(data, kResponse.class);
- // 将数据按行分割
- String[] lines = data.split("\n");
-
- // 跳过第一行(列名)
- for (int i = 1; i < lines.length; i++) {
- String line = lines[i].trim();
- // 确保行不为空
- if (!line.isEmpty()) {
- String[] fields = line.split(",");
-
- // 确保每行有至少7个字段:日期、开盘价、最高价、最低价、收盘价、成交量、持仓量
- if ((key.equals("CRUDE OIL") && fields.length == 7) || (key.equals("GOLD") && fields.length == 5)) {
- kData kData = new kData();
- kData.setT(convDate(fields[0],interval));
- kData.setC(fields[4]);
- kData.setO(fields[1]);
- kData.setH(fields[2]);
- kData.setL(fields[3]);
- if(key.equals("CRUDE OIL")){
- kData.setV(fields[5]);
- kData.setVo(fields[6]);
- }else{
- kData.setV("0");
- kData.setVo("0");
- }
- // 将每一条 KData 对象添加到列表中
- kDataList.add(kData);
- }
- }
+ // 打印 kline_list 的内容
+ for (kResponse.KlineData item : kResponse.getData().getKlineList()) {
+ kData kData = new kData();
+ kData.setT(item.getTimestamp());
+ kData.setC(item.getClose_price());
+ kData.setO(item.getOpen_price());
+ kData.setH(item.getHigh_price());
+ kData.setL(item.getLow_price());
+ kData.setV(item.getVolume());
+ kData.setVo(item.getTurnover());
+ kDataList.add(kData);
}
kDataList.get(kDataList.size() - 1).setC(price);
return kDataList;
}
-
- // 常量,定义日期格式
- private static final String DATE_PATTERN = "yyyyMMdd";
- private static final String DATE_TIME_PATTERN = "yyyyMMdd HH:mm";
-
- public long convDate(String dateStr, String interval) {
- // 输入校验,确保 dateStr 和 interval 不为 null 或空
- if (dateStr == null || dateStr.trim().isEmpty() || interval == null || interval.trim().isEmpty()) {
- throw new IllegalArgumentException("日期字符串或时间间隔不能为空。");
- }
-
- // 根据 interval 的值,选择日期格式
- String pattern = (interval.equalsIgnoreCase("D") || interval.equalsIgnoreCase("W") || interval.equalsIgnoreCase("M"))
- ? DATE_PATTERN : DATE_TIME_PATTERN;
-
- // 创建 DateTimeFormatter,使用合适的格式
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
-
- try {
- // 根据是否包含时间部分,选择 LocalDate 或 LocalDateTime 进行解析
- if (pattern.equals(DATE_PATTERN)) {
- LocalDate localDate = LocalDate.parse(dateStr, formatter);
- Instant timestamp = localDate.atStartOfDay(ZoneOffset.UTC).toInstant();
- return timestamp.getEpochSecond();
- } else {
- LocalDateTime localDateTime = LocalDateTime.parse(dateStr, formatter);
- Instant timestamp = localDateTime.toInstant(ZoneOffset.UTC);
- return timestamp.getEpochSecond();
- }
- } catch (Exception e) {
- throw new IllegalArgumentException("无效的日期格式: " + dateStr, e);
- }
- }
@Override
public ServerResponse getOptionStock(HttpServletRequest request) {
diff --git a/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java b/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
index 1a6fd94..c117324 100644
--- a/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
@@ -395,7 +395,7 @@
BigDecimal nowPrice = BigDecimal.ZERO;
String stockType;
- if(userPosition.getStockSpell().equals("GOLD") || userPosition.getStockSpell().equals("CRUDE_OIL")){
+ if(userPosition.getStockSpell().equals("XAUUSD") || userPosition.getStockSpell().equals("USOIL")){
nowPrice = new BigDecimal(RedisShardedPoolUtils.get(userPosition.getStockSpell()));
stockType = "USDT";
}else{
@@ -451,7 +451,7 @@
}
BigDecimal nowPrice = BigDecimal.ZERO;
String stockType = null;
- if(userPosition.getStockSpell().equals("GOLD") || userPosition.getStockSpell().equals("CRUDE_OIL")){
+ if(userPosition.getStockSpell().equals("XAUUSD") || userPosition.getStockSpell().equals("USOIL")){
nowPrice = new BigDecimal(RedisShardedPoolUtils.get(userPosition.getStockSpell()));
stockType = "USDT";
}else{
@@ -745,7 +745,7 @@
if (userPositions.size() > 0) {
for (UserPosition position : userPositions) {
BigDecimal nowPrice = BigDecimal.ZERO;
- if(position.getStockSpell().equals("GOLD") || position.getStockSpell().equals("CRUDE_OIL")){
+ if(position.getStockSpell().equals("XAUUSD") || position.getStockSpell().equals("USOIL")){
nowPrice = new BigDecimal(RedisShardedPoolUtils.get(position.getStockSpell()));
}else{
if(state == 0){
@@ -1323,7 +1323,7 @@
adminPositionVO.setStockPlate(position.getStockPlate());
BigDecimal nowPrice = BigDecimal.ZERO;
- if(position.getStockSpell().equals("GOLD") || position.getStockSpell().equals("CRUDE_OIL")){
+ if(position.getStockSpell().equals("XAUUSD") || position.getStockSpell().equals("USOIL")){
nowPrice = new BigDecimal(RedisShardedPoolUtils.get(position.getStockSpell()));
}else{
nowPrice = priceServices.getNowPrice(position.getStockCode());
diff --git a/src/main/java/com/nq/utils/redis/RedisKeyConstant.java b/src/main/java/com/nq/utils/redis/RedisKeyConstant.java
index 0ce0b5b..ac77d88 100644
--- a/src/main/java/com/nq/utils/redis/RedisKeyConstant.java
+++ b/src/main/java/com/nq/utils/redis/RedisKeyConstant.java
@@ -35,10 +35,27 @@
/**
* 黄金行情
*/
- public static final String gold= "GOLD";
+ public static final String XAUUSD= "XAUUSD";
/**
* 原油行情
*/
- public static final String crude_oil= "CRUDE_OIL";
+ public static final String USOIL= "USOIL";
+
+ /**
+ * 根据传入的 key 名称获取对应的 Redis key 常量
+ *
+ * @param key 名称
+ * @return 对应的 Redis Key 或者 null 如果没有匹配的 key
+ */
+ public static String getRedisKey(String key) {
+ switch (key) {
+ case "XAUUSD":
+ return XAUUSD;
+ case "USOIL":
+ return USOIL;
+ default:
+ return null; // 如果没有匹配的 key,返回 null
+ }
+ }
}
diff --git a/src/main/java/com/nq/utils/task/stock/StockTask.java b/src/main/java/com/nq/utils/task/stock/StockTask.java
index c076153..d4a1b6b 100644
--- a/src/main/java/com/nq/utils/task/stock/StockTask.java
+++ b/src/main/java/com/nq/utils/task/stock/StockTask.java
@@ -1,8 +1,7 @@
package com.nq.utils.task.stock;
+import cn.hutool.json.JSONArray;
import com.alibaba.fastjson2.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
@@ -13,13 +12,16 @@
import com.nq.pojo.ReponseBase;
import com.nq.pojo.Stock;
import com.nq.pojo.UserPosition;
+import com.nq.pojo.reponse.kResponse;
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.http.HttpClientRequest;
import com.nq.utils.redis.RedisKeyConstant;
import com.nq.utils.redis.RedisKeyUtil;
import com.nq.utils.redis.RedisShardedPoolUtils;
+import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -27,9 +29,14 @@
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.text.DecimalFormat;
+import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -81,116 +88,246 @@
}
}
}
+ //最新价格url
+ private static final String PRICE_URL = "https://quote.alltick.io/quote-b-api/trade-tick?token=794ea65dc03c5af582cddec476fbb0d7-c-app&query=";
+ //k线url
+ private static final String K_URL = "https://quote.alltick.io/quote-b-api/kline?token=794ea65dc03c5af582cddec476fbb0d7-c-app&query=";
- //黄金
- private static final String gold_API_URL = "http://139.196.211.109/exchange_curr.action?username=Qq112233&password=3ce25a66d5b3a8cd661024fea6c79388&id=AUUSDO";
- //原油
- private static final String crude_oil_API_URL = "http://47.112.169.122/fOption_curr.action?username=Qq112233&password=3ce25a66d5b3a8cd661024fea6c79388&id=@CL0W";
+ public String getPriceData() {
+ // 创建查询数据
+ JSONObject data = new JSONObject();
- @Scheduled(cron = "0/6 * * * * ?") // 每6秒执行一次
+ // 用于存储符号的列表
+ JSONArray symbolList = new JSONArray();
+
+ // 需要查询的符号列表(按你的要求,这里符号从 ["857.HK", "UNH.US"] 开始)
+ String[] symbols = {"GOLD", "USOIL"};
+
+ // 遍历符号列表,构建 JSON 对象
+ for (String symbol : symbols) {
+ JSONObject symbolObject = new JSONObject();
+ symbolObject.put("code", symbol);
+ symbolList.put(symbolObject);
+ }
+
+ // 将 symbol_list 放入 data 对象中
+ data.put("symbol_list", symbolList);
+
+ // 创建查询请求对象
+ JSONObject query = new JSONObject();
+ query.put("trace", generateTraceCode()); // 假设 generateTraceCode() 是生成唯一追踪代码的方法
+ query.put("data", data);
+ // 返回构建的查询对象
+ return buildUrlWithQuery(query);
+ }
+
+ // 生成唯一追踪码
+ public static String generateTraceCode() {
+ // 获取当前时间戳
+ long timestamp = System.currentTimeMillis();
+
+ // 生成唯一的 UUID
+ String uuid = UUID.randomUUID().toString();
+
+ // 组合时间戳和 UUID,保证唯一性
+ return uuid + "-" + timestamp;
+ }
+
+ @Scheduled(cron = "0/2 * * * * ?") // 每6秒执行一次
+ public void sync() throws InterruptedException {
+ ReentrantLock lock = new ReentrantLock();
+ if (lock.tryLock()) { // 尝试获取锁
+ try {
+ gold();
+ Thread.sleep(1000);
+ getKDate();
+ } finally {
+ lock.unlock(); // 释放锁
+ }
+ } else {
+ // 如果锁不可用,可以选择不执行或打印日志等
+ System.out.println("任务正在执行,跳过本次执行。");
+ }
+ }
+
public void gold() {
try {
- // 使用RestTemplate发起HTTP请求
- RestTemplate restTemplate = new RestTemplate();
- String response = restTemplate.getForObject(gold_API_URL, String.class);
+ String url = PRICE_URL+getPriceData();
+ URL obj = new URL(url);
+ HttpURLConnection con = (HttpURLConnection) obj.openConnection();
+ con.setRequestMethod("GET");
+ int responseCode = con.getResponseCode();
+ BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
+ String inputLine;
+ StringBuffer response = new StringBuffer();
+ while ((inputLine = in.readLine()) != null) {
+ response.append(inputLine);
+ }
+ in.close();
+ if(responseCode == 200){
+ // 创建 ObjectMapper 对象
+ ObjectMapper objectMapper = new ObjectMapper();
- // 解析返回的CSV格式数据,去除可能存在的换行符
- if (response != null && !response.contains("参数错误")) {
- // 清除换行符并按逗号分割数据
- String[] parts = response.trim().split(",");
- String price = parts[2].trim(); // "3348.4"
- // 转换价格为Double类型
- // 保存价格到Redis
- RedisShardedPoolUtils.set(RedisKeyConstant.gold, String.valueOf(price));
- log.info("黄金定时任务------成功");
- } else {
- log.info("黄金定时任务------没有接收到数据");
+ // 解析 JSON 字符串
+ JsonNode rootNode = objectMapper.readTree(response.toString());
+
+ // 获取 "data" 节点下的 "tick_list" 数组
+ JsonNode tickList = rootNode.path("data").path("tick_list");
+
+ // 遍历 tick_list 数组并提取 code 和 price
+ for (JsonNode tick : tickList) {
+ String code = tick.path("code").asText().equals("GOLD") ? "XAUUSD" : tick.path("code").asText();
+ String price = tick.path("price").asText();
+ RedisShardedPoolUtils.set(RedisKeyConstant.getRedisKey(code), price);
+ }
+ }else{
+ log.info("黄金原油获实时价格定时任务------没有接收到数据:"+response);
}
} catch (Exception e) {
e.printStackTrace();
- log.error("黄金定时任务------请求或数据解析失败:" + e.getMessage());
}
}
- @Scheduled(cron = "0/7 * * * * ?") // 每6秒执行一次
- public void crudeOil() {
+ public static String buildUrlWithQuery(JSONObject jsonObject) {
try {
- // 使用RestTemplate发起HTTP请求
- RestTemplate restTemplate = new RestTemplate();
- String response = restTemplate.getForObject(crude_oil_API_URL, String.class);
-
- // 解析返回的CSV格式数据,去除可能存在的换行符
- if (response != null && !response.contains("参数错误")) {
- // 清除换行符并按逗号分割数据
- String[] parts = response.trim().split(",");
- String price = parts[2].trim(); // "3348.4"
- // 转换价格为Double类型
- // 保存价格到Redis
- RedisShardedPoolUtils.set(RedisKeyConstant.crude_oil, String.valueOf(price));
- log.info("原油定时任务------没有接收到数据");
- } else {
- log.info("原油定时任务------没有接收到数据");
- }
- } catch (Exception e) {
+ // 将 JSON 对象转换为字符串
+ String jsonString = jsonObject.toString();
+ // 使用 URLEncoder 编码 JSON 字符串
+ String encodedJson = URLEncoder.encode(jsonString, "UTF-8");
+ return encodedJson;
+ } catch (UnsupportedEncodingException e) {
e.printStackTrace();
- log.error("原油定时任务------请求或数据解析失败:" + e.getMessage());
+ return null;
}
}
- //黄金
- private static final String k_gold_API_URL = "http://139.196.211.109/ldMetal_k.action?username=Qq112233&password=3ce25a66d5b3a8cd661024fea6c79388&id=AUUSDO&num=-100&period=";
-
- //原油
- private static final String k_crude_oil_API_URL = "http://47.112.169.122/fOption_k.action?username=Qq112233&password=3ce25a66d5b3a8cd661024fea6c79388&id=@CL0W&num=-100&period=";
-
- @Scheduled(cron = "0/6 * * * * ?") // 每6秒执行一次
public void getKDate() throws InterruptedException {
- RestTemplate restTemplate = new RestTemplate();
- String[] arr = {"d", "w", "m", "1", "5", "30"};
- for (String str : arr) {
- String g = restTemplate.getForObject(k_gold_API_URL+str, String.class);
- if(!g.contains("参数错误")){
- RedisShardedPoolUtils.set("k_gold_"+str, g);
- Thread.sleep(10000);
+ // 创建Map对象
+ Map<String, Integer> map = new HashMap<>();
+
+ // 写死键值对
+ map.put("d", 8);
+ map.put("w", 9);
+ map.put("m", 10);
+ map.put("1", 1);
+ map.put("5", 2);
+ map.put("30", 4);
+
+ for (Map.Entry<String, Integer> entry : map.entrySet()) {
+ String gold = getResp(K_URL + getKQueryData(entry.getValue(), "XAUUSD"));
+ if(StringUtils.isNotEmpty(gold)){
+ if(entry.getKey().equals("d")){
+ priceLimit(gold,"XAUUSD");
+ }
+ RedisShardedPoolUtils.set("k_gold_"+entry.getKey(), gold);
}
- String c = restTemplate.getForObject(k_crude_oil_API_URL+str, String.class);
- if(!c.contains("参数错误")){
- RedisShardedPoolUtils.set("k_crude_oil_"+str, c);
- Thread.sleep(10000);
+
+ Thread.sleep(1000);
+ String c = getResp(K_URL+getKQueryData(entry.getValue(),"USOIL"));
+ if(StringUtils.isNotEmpty(c)){
+ if(entry.getKey().equals("d")) {
+ priceLimit(c, "USOIL");
+ }
+ RedisShardedPoolUtils.set("k_crude_oil_"+entry.getKey(), c);
}
+ Thread.sleep(1000);
}
}
- /**
- * 同步美国股票
- */
-// @Scheduled(cron = "0 0/30 * * * ?")
-// public void loadStockCompanies() {
-// loadAllCompanies();
-// }
-//
-//
-// /**
-// * 加载公司信息
-// */
-// public void loadAllCompanies() {
-// List<Stock> list = stockMapper.findStockList();
-// for (int i = 0; i < list.size(); i++) {
-// Stock stock = list.get(i);
-// EStockType eStockType = EStockType.getEStockTypeByCode(stock.getStockType());
-// String result = HttpClientRequest.doGet(eStockType.stockUrl + "companies?pid=+" + stock.getStockCode() + "+country_id=" + eStockType.getContryId() + "&size=1&page=1&key=" + eStockType.stockKey);
-// try {
-// JSONObject jsonObject = JSONObject.parseObject(result);
-// JSONObject companiesInfo = jsonObject.getJSONArray("data").getJSONObject(0);
-// RedisKeyUtil.setCacheCompanies(stock, new Gson().toJson(companiesInfo));
-// } catch (Exception e) {
-// log.info("");
-//
-// }
-// }
-//
-// }
+
+ @lombok.Data
+ class kData {
+ long t;
+ String c;
+ String o;
+ String h;
+ String l;
+ String v;
+ String vo;
+ }
+ public void priceLimit(String data,String key){
+ List<kData> kDataList = new ArrayList<>();
+ // 使用 Gson 解析 JSON 字符串
+ Gson gson = new Gson();
+ kResponse kResponse = gson.fromJson(data, kResponse.class);
+
+ // 打印 kline_list 的内容
+ for (kResponse.KlineData item : kResponse.getData().getKlineList()) {
+ kData kData = new kData();
+ kData.setT(item.getTimestamp());
+ kData.setC(item.getClose_price());
+ kData.setO(item.getOpen_price());
+ kData.setH(item.getHigh_price());
+ kData.setL(item.getLow_price());
+ kData.setV(item.getVolume());
+ kData.setVo(item.getTurnover());
+ kDataList.add(kData);
+ }
+ DecimalFormat decimalFormat = new DecimalFormat("#.00");
+ double oneC = Double.valueOf(kDataList.get(kDataList.size() - 1).getC());
+ double twoC = Double.valueOf(kDataList.get(kDataList.size() - 2).getC());
+ String h = String.valueOf(decimalFormat.format(((oneC - twoC) / oneC * 100)));
+ RedisShardedPoolUtils.set(key+"_H",h);
+ RedisShardedPoolUtils.set(key+"_H",h);
+ }
+
+ public String getResp(String url){
+ try {
+ URL obj = new URL(url);
+ HttpURLConnection con = (HttpURLConnection) obj.openConnection();
+ con.setRequestMethod("GET");
+ int responseCode = con.getResponseCode();
+ BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
+ String inputLine;
+ StringBuffer response = new StringBuffer();
+ while ((inputLine = in.readLine()) != null) {
+ response.append(inputLine);
+ }
+ in.close();
+ if(responseCode == 200){
+ return response.toString();
+ }
+ }catch (Exception e){
+ e.printStackTrace();
+ log.error("k线请求错误!", e.getMessage());
+ }
+ return null;
+ }
+
+ //k线请求组装数据
+ public String getKQueryData(Integer k_data,String code){
+ JSONObject queryData = new JSONObject();
+ queryData.put("trace", generateTraceCode());
+ JSONObject data = new JSONObject();
+ data.put("code", code);//产品code
+ /**
+ * k线类型
+ * 1、1是1分钟K,2是5分钟K,3是15分钟K,4是30分钟K,5是小时K,6是2小时K(股票不支持2小时),7是4小时K(股票不支持4小时),8是日K,9是周K,10是月K (注:股票不支持2小时K、4小时K)
+ * 2、最短的k线只支持1分钟
+ * 3、查询昨日收盘价,kline_type 传8
+ */
+ data.put("kline_type", k_data);
+ /**
+ * 从指定时间往前查询K线
+ * 1、传0表示从当前最新的交易日往前查k线
+ * 2、指定时间请传时间戳,传时间戳表示从该时间戳往前查k线
+ * 3、只有外汇贵金属加密货币支持传时间戳,股票类的code不支持
+ */
+ data.put("kline_timestamp_end", 0);
+ /**
+ * 1、表示查询多少根K线,每次最大请求1000根,可根据时间戳循环往前请求
+ * 2、通过该字段可查询昨日收盘价,kline_type 传8,query_kline_num传2,返回2根k线数据中,时间戳较小的数据是昨日收盘价
+ */
+ data.put("query_kline_num", 200);
+ /*
+ 复权类型,对于股票类的code才有效,例如:0:除权,1:前复权,目前仅支持0
+ */
+ data.put("adjust_type", 0);
+ queryData.put("data", data);
+ return buildUrlWithQuery(queryData);
+ }
+
/**
* 加载所有股票数据
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index ee90313..28daf15 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -62,7 +62,7 @@
ST_HTTP_API = http://api-sa.js-stock.top/
ST_WS_URL = ws://api-sa-ws.js-stock.top
-ST_KEY = DP6jTI2ow7unfakP0fRM
+ST_KEY = chetm43ZxsgzEzqr3dZ0
#HK_HTTP_API = http://api-v1.js-stock.top/
--
Gitblit v1.9.3