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