package com.ningdatech.carapi.gps.manage;


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ningdatech.cache.model.cache.CacheKey;
import com.ningdatech.cache.repository.CachePlusOps;
import com.ningdatech.carapi.homepage.entity.model.NdDataAccessGps;
import com.ningdatech.carapi.scheduler.contants.TaskConstant;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.ningdatech.carapi.gps.model.entity.DataAccessGpsRealTimeData;
import com.ningdatech.carapi.gps.service.IDataAccessGpsRealTimeDataService;
import com.ningdatech.carapi.homepage.service.IDataAccessGpsService;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.json.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;

/**
 * 车辆位置信息
 *
 * @author CMM
 * @since 2023/11/17 09:35
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class GpsDataPullManage {

    private final IDataAccessGpsService dataAccessGpsService;
    private final IDataAccessGpsRealTimeDataService dataAccessGpsRealTimeDataService;
    private final CachePlusOps cachePlusOps;

    private static final ObjectMapper objectMapper = new ObjectMapper();
    private static final Jedis jedis = new Jedis("localhost",6379);

    @Value("${spring.datasource.url}")
    private String dataBaseUrl;
    @Value("${spring.datasource.username}")
    private String username;
    @Value("${spring.datasource.password}")
    private String password;

    public String getGpsData() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        String url = "https://jtjdhcweb.z1l1.com:7443";

        // 获取当前表中的最大更新时间
        Long maxUpdateTime = null;
        Optional<DataAccessGpsRealTimeData> max = dataAccessGpsRealTimeDataService.list(Wrappers.lambdaQuery(DataAccessGpsRealTimeData.class)
                .select(DataAccessGpsRealTimeData::getUpdateTime)).stream().max(Comparator.comparing(DataAccessGpsRealTimeData::getUpdateTime));
        if (max.isPresent()){
            maxUpdateTime = max.get().getUpdateTime().atZone(ZoneId.of("Asia/Shanghai")).toInstant().toEpochMilli();
            log.info("当前表中最大更新时间：{}", Instant.ofEpochMilli(maxUpdateTime).atZone(ZoneId.of("Asia/Shanghai")).toLocalDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }
        try {
            trustAllCertificates();
            Map<String, String> requestParams = assemblyParams();
            String requestUrl = url + "/talent/gps/datalist";
            String response = sendPostRequest(requestUrl, requestParams);
            if (response == null) {
                return "下载路径请求失败！";
            }
            com.alibaba.fastjson.JSONObject object = com.alibaba.fastjson.JSONObject.parseObject(response);
            System.out.println("Response from server: " + response);
            String downloadUrl = object.getString("data");
            if (downloadUrl == null){
                return "下载路径请求失败！";
            }

            String downloadPath = url + downloadUrl;
            String result = sendDownloadRequest(downloadPath);
            if (result == null){
                return "文件下载失败！";
            }
            List<DataAccessGpsRealTimeData> dataList = JSON.parseArray(result, com.alibaba.fastjson.JSONObject.class).stream().map(jsonObject -> {
                String vehicleNo = jsonObject.getString("vehicle_no");
                Integer color = jsonObject.getInteger("color");
                // 纬度
                String longitude = jsonObject.getString("lon");
                // 经度
                String latitude = jsonObject.getString("lat");
                String direction = jsonObject.getString("direction");
                String gpsSpeed = jsonObject.getString("gps_speed");
                Long gpsTime = jsonObject.getLong("gps_time");
                DataAccessGpsRealTimeData dataAccessGpsRealTimeData = new DataAccessGpsRealTimeData();
                dataAccessGpsRealTimeData.setCarPlate(vehicleNo);
                dataAccessGpsRealTimeData.setPlateColor(color.toString());
                dataAccessGpsRealTimeData.setCarLongitude(latitude);
                dataAccessGpsRealTimeData.setCarLatitude(longitude);
                dataAccessGpsRealTimeData.setCarDirection(direction);
                dataAccessGpsRealTimeData.setCarVelocity(gpsSpeed);
                // 将毫秒时间戳转换为Instant对象
                Instant instant = Instant.ofEpochMilli(gpsTime);
                // 使用北京时间时区转换为LocalDateTime
                LocalDateTime localDateTime = instant.atZone(ZoneId.of("Asia/Shanghai")).toLocalDateTime();
                dataAccessGpsRealTimeData.setUpdateTime(localDateTime);
                dataAccessGpsRealTimeData.setCreateTime(LocalDateTime.now());
                return dataAccessGpsRealTimeData;
            }).collect(Collectors.toList());
            if (CollUtil.isEmpty(dataList)){
                return "数据为空！";
            }

            // 表中有数据 获取此次拉取到的数据中上传时间大于上次拉取数据的最大上报时间的数据
            if (Objects.nonNull(maxUpdateTime)) {
                long finalMaxUpdateTime = maxUpdateTime;
                dataList = dataList.stream().filter(e -> e.getUpdateTime().atZone(ZoneId.of("Asia/Shanghai")).toInstant().toEpochMilli() > finalMaxUpdateTime).collect(Collectors.toList());
                // 将数据库中的数据根据更新时间排序 按更新时间 从小到大 根据对应id删除此次拉取到的数据量
                List<DataAccessGpsRealTimeData> dataAccessGpsRealTimeDataList = dataAccessGpsRealTimeDataService.list(Wrappers.lambdaQuery(DataAccessGpsRealTimeData.class)
                                .select(DataAccessGpsRealTimeData::getUpdateTime, DataAccessGpsRealTimeData::getRecordId))
                        .stream().sorted(Comparator.comparing(DataAccessGpsRealTimeData::getUpdateTime)).collect(Collectors.toList());
                // 截取dataList.size()条数据
                dataAccessGpsRealTimeDataList = dataAccessGpsRealTimeDataList.subList(0, dataList.size());
                // 从旧数据中删除这些数据
                List<Long> recordIdList = dataAccessGpsRealTimeDataList.stream().map(DataAccessGpsRealTimeData::getRecordId).collect(Collectors.toList());
                String tableName = "nd_data_access_gps_real_time_data";
                dataAccessGpsRealTimeDataService.removeByRecordIds(tableName,recordIdList);
            }
            // 如果没有 说明没有新上报的数据 不更新
            if (CollUtil.isEmpty(dataList)){
                log.info("没有新上报的数据！");
                return "没有新上报的数据！";
            }
            log.info("本次拉取到{}条数据", dataList.size());

            // 先清空表中的数据
            //truncateTable();
            // 设置表的自增序号从1开始
            //resetAutoIncrement();

            // 批量保存数据 每批保存1万条
            // 分批
            List<List<DataAccessGpsRealTimeData>> batchList = new ArrayList<>(ListUtil.partition(new ArrayList<>(dataList), 10000));
            // 创建线程池 线程数是 分批的数量
            ExecutorService executorService = Executors.newFixedThreadPool(batchList.size());
            // 线程计数器,就是 分批的数
            CountDownLatch countDownLatch = new CountDownLatch(batchList.size());
            batchList.forEach(e -> {
                // 每个分批用一个线程执行
                executorService.execute(() -> dataAccessGpsRealTimeDataService.saveBatch(e, 10000));
                countDownLatch.countDown();
            });
            // 等待所有线程执行完成
            countDownLatch.await();
            executorService.shutdown();
            executorService.awaitTermination(5, TimeUnit.MINUTES);
            if (executorService.isTerminated()) {
                log.info("子线程执行完毕");
                log.info("主线程开始");
            }
            stopWatch.stop();
            log.info("=========== GPS数据拉取 ======== 任务结束 {}s",stopWatch.getTotalTimeSeconds());
            return "拉取完成!";
        } catch (Exception e) {
            log.error("Error sending POST request: {}", e.getMessage());
        }
        stopWatch.stop();
        log.info("=========== GPS数据拉取 ======== 任务结束 {}s",stopWatch.getTotalTimeSeconds());
        return "数据拉取失败!";
    }

    private void truncateTable() {
        // SQL 语句清空表
        String truncateTableSQL = "TRUNCATE TABLE nd_data_access_gps_real_time_data";

        Connection conn = null;
        Statement stmt = null;

        try {
            // 加载数据库驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 建立连接
            conn = DriverManager.getConnection(dataBaseUrl, username, password);
            // 创建 Statement 对象
            stmt = conn.createStatement();
            // 执行 SQL 语句
            stmt.executeUpdate(truncateTableSQL);
            log.info("表已被清空，自增主键已重置。");
            System.out.println("表已被清空，自增主键已重置。");
        } catch (Exception e) {
            log.info("Error truncating table: {}", e.getMessage());
        } finally {
            // 关闭资源
            try {
                if (stmt != null) {
                    stmt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (Exception e) {
                log.error("Error closing resources: {}", e.getMessage());
            }
        }
    }

    private void resetAutoIncrement() {

        // SQL 语句重置自增主键
        String resetAutoIncrementSQL = "ALTER TABLE nd_data_access_gps_real_time_data AUTO_INCREMENT = 1";

        Connection conn = null;
        Statement stmt = null;

        try {
            // 加载数据库驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 建立连接
            conn = DriverManager.getConnection(dataBaseUrl, username, password);
            // 创建 Statement 对象
            stmt = conn.createStatement();
            // 执行 SQL 语句
            stmt.executeUpdate(resetAutoIncrementSQL);
            log.info("自增主键已重置为1。");
        } catch (Exception e) {
            log.error("重置自增主键失败。{}", e.getMessage());
        } finally {
            // 关闭资源
            try {
                if (stmt != null) {
                    stmt.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (Exception e) {
                log.error("关闭资源失败。{}", e.getMessage());
            }
        }
    }

    public String sendDownloadRequest(String downloadPath) {
        try {
            // 创建URL对象
            URL url = new URL(downloadPath);
            // 打开连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            // 设置请求方法为GET
            connection.setRequestMethod("GET");
            // 设置连接超时时间（单位：毫秒）
            connection.setConnectTimeout(60000);
            // 设置读取超时时间（单位：毫秒）
            connection.setReadTimeout(60000);

            // 获取响应码
            int responseCode = connection.getResponseCode();
            System.out.println("GET Response Code :: " + responseCode);

            if (responseCode == HttpURLConnection.HTTP_OK) {
                // 使用BufferedReader读取响应内容
                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String inputLine;
                StringBuilder response = new StringBuilder();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                // 打印响应内容
                System.out.println("Response :: " + response);
                in.close();
                connection.disconnect();
                return response.toString();
            } else {
                System.out.println("GET请求未成功");
            }
        } catch (Exception e) {
            log.error("Error sending GET request: {}", e.getMessage());
        }
        return null;
    }

    public Map<String, String> assemblyParams(){
        String key = "Gps@!@163.";
        long timeNow = System.currentTimeMillis() / 1000;
        String token = generateMD5Token(timeNow, key);
        Map<String, String> params = new HashMap<>();
        params.put("timeNow", String.valueOf(timeNow));
        params.put("token", token);

        //params.put("Slat", "120.0167");
        //params.put("Elat", "120.2337");
        //
        //params.put("Slon", "29.1078");
        //params.put("Elon", "29.4697");

        return params;
    }

    public Map<String, String> assemblyParams(Long maxUpdateTime){
        String key = "Gps@!@163.";
        long timeNow = System.currentTimeMillis() / 1000;
        String token = generateMD5Token(timeNow, key);
        Map<String, String> params = new HashMap<>();
        params.put("timeNow", String.valueOf(timeNow));
        params.put("token", token);
        params.put("timeLine", String.valueOf(maxUpdateTime / 1000));

        //params.put("Slat", "120.0167");
        //params.put("Elat", "120.2337");
        //
        //params.put("Slon", "29.1078");
        //params.put("Elon", "29.4697");

        return params;
    }

    public Map<String, String> assemblyParams(String id){
        String key = "Gps@!@163.";
        long timeNow = System.currentTimeMillis() / 1000;
        String token = generateMD5Token(timeNow, key);
        Map<String, String> params = new HashMap<>();
        params.put("timeNow", String.valueOf(timeNow));
        params.put("token", token);
        params.put("id", id);

        //params.put("Slat", "120.0167");
        //params.put("Elat", "120.2337");
        //
        //params.put("Slon", "29.1078");
        //params.put("Elon", "29.4697");

        return params;
    }

    public String generateMD5Token(long timeNow, String key) {
        try {
            String data =  key + timeNow;
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hash = md.digest(data.getBytes(StandardCharsets.UTF_8));
            StringBuilder hexString = new StringBuilder();
            for (byte b : hash) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5 algorithm not found", e);
        }
    }

    public String sendPostRequest(String requestUrl, Map<String, String> params) throws Exception {
        URL url = new URL(requestUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        // 设置请求方法为POST
        connection.setRequestMethod("POST");
        // 设置请求头信息
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setDoOutput(true);

        // 构建请求参数
        StringBuilder postData = new StringBuilder();
        for (Map.Entry<String, String> param : params.entrySet()) {
            if (postData.length() != 0) postData.append('&');
            postData.append(param.getKey());
            postData.append('=');
            postData.append(param.getValue());
        }
        System.out.println("Post Data: " + postData);
        // 发送请求参数
        try (OutputStream outputStream = connection.getOutputStream()) {
            byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
            outputStream.write(postDataBytes);
        }

        // 获取响应
        int responseCode = connection.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            // 读取响应
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder response = new StringBuilder();

            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
            connection.disconnect();

            // 尝试将响应转换成JSONObject
            try {
                return new JSONObject(response.toString()).toString();
            } catch (Exception e) {
                System.err.println("Error parsing JSON: " + e.getMessage());
                return null;
            }
        } else {
            // 读取错误信息
            try (java.io.InputStream inputStream = connection.getErrorStream()) {
                java.util.Scanner scanner = new java.util.Scanner(inputStream, StandardCharsets.UTF_8.name());
                scanner.useDelimiter("\\A");
                return scanner.hasNext() ? scanner.next() : "";
            }
        }
    }

    public void trustAllCertificates() throws Exception {
        // 创建一个信任所有证书的信任管理器
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };

        // 安装信任所有证书的信任管理器
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        // 创建一个信任所有主机名的验证器
        HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
    }

    public String getAddGpsData() {
        log.info("=========== GPS增量数据拉取 ======== 任务开始");
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        String url = "https://jtjdhcweb.z1l1.com:7443";
        try {
            trustAllCertificates();
            String requestUrl = url + "/talent/gps/datalist";
            // 从缓存中获取业务数据最大id
            CacheKey key = new CacheKey(TaskConstant.RedisKey.GPS_DATA_PULL_MAX_BIZ_ID);
            String id = cachePlusOps.get(key);
            log.info("缓存中已存在id:{}", id);
            // 如果不存在 从表中数据中获取
            if (StringUtils.isBlank(id)){
                Long maxBizId = dataAccessGpsService.getMaxBizId();
                if (maxBizId != null) {
                    id = maxBizId.toString();
                }else {
                    return "未获取到id！";
                }
            }
            Map<String, String> requestAddParams = assemblyParams(id);
            String addResponse = sendPostRequest(requestUrl, requestAddParams);

            if (addResponse == null) {
                return "下载路径请求失败！";
            }
            com.alibaba.fastjson.JSONObject addObject = com.alibaba.fastjson.JSONObject.parseObject(addResponse);
            System.out.println("Response from server: " + addResponse);
            String addDownloadUrl = addObject.getString("data");
            if (addDownloadUrl == null){
                return "下载路径请求失败！";
            }

            String addDownloadPath = url + addDownloadUrl;
            String addResult = sendDownloadRequest(addDownloadPath);
            if (addResult == null){
                return "文件下载失败！";
            }
            List<NdDataAccessGps> addDataList = getNdDataAccessGps(addResult);
            if (CollUtil.isEmpty(addDataList)){
                return "数据为空！";
            }
            log.info("此次拉取到的数据条数：{}",addDataList.size());
            // 获取业务数据最大id
            String maxBizId = addDataList.stream().map(d -> {
                String bizId = d.getBizId();
                return Long.parseLong(bizId);
            }).collect(Collectors.toList()).stream().max(Long::compare).get().toString();
            // 保存到缓存中
            cachePlusOps.set(key,maxBizId,false);
            String value = cachePlusOps.get(key);
            System.out.println("已存入缓存中的id: " + value);

            // 批量保存数据 每批保存1万条
            // 分批
            List<List<NdDataAccessGps>> batchList = new ArrayList<>(ListUtil.partition(new ArrayList<>(addDataList), 10000));
            // 创建线程池 线程数是 分批的数量
            ExecutorService executorService = Executors.newFixedThreadPool(batchList.size());
            // 线程计数器,就是 分批的数
            CountDownLatch countDownLatch = new CountDownLatch(batchList.size());
            batchList.forEach(e -> {
                // 每个分批用一个线程执行
                executorService.execute(() -> dataAccessGpsService.saveBatch(e, 10000));
                countDownLatch.countDown();
            });
            // 等待所有线程执行完成
            countDownLatch.await();
            executorService.shutdown();
            executorService.awaitTermination(5, TimeUnit.MINUTES);
            if (executorService.isTerminated()) {
                log.info("子线程执行完毕");
                log.info("主线程开始");
            }
            stopWatch.stop();
            log.info("=========== GPS数据拉取 ======== 任务结束 {}s",stopWatch.getTotalTimeSeconds());
            return "拉取完成!";
        } catch (Exception e) {
            log.error("Error sending POST request: {}", e.getMessage());
        }
        stopWatch.stop();
        log.info("=========== GPS数据拉取 ======== 任务结束 {}s",stopWatch.getTotalTimeSeconds());
        return "数据拉取失败!";
    }

    public List<NdDataAccessGps> getNdDataAccessGps(String result) {
        List<NdDataAccessGps> dataList = JSON.parseArray(result, com.alibaba.fastjson.JSONObject.class).stream().map(jsonObject -> {
            String vehicleNo = jsonObject.getString("vehicle_no");
            Integer color = jsonObject.getInteger("color");
            // 纬度
            String longitude = jsonObject.getString("lon");
            // 经度
            String latitude = jsonObject.getString("lat");
            String direction = jsonObject.getString("direction");
            String gpsSpeed = jsonObject.getString("gps_speed");
            Long gpsTime = jsonObject.getLong("gps_time");
            String bizId = jsonObject.getString("id");
            NdDataAccessGps dataAccessGps = new NdDataAccessGps();
            dataAccessGps.setCarPlate(vehicleNo);
            dataAccessGps.setPlateColor(color.toString());
            dataAccessGps.setCarLongitude(BigDecimal.valueOf(Double.parseDouble(latitude)));
            dataAccessGps.setCarLatitude(BigDecimal.valueOf(Double.parseDouble(longitude)));
            dataAccessGps.setCarDirection(BigDecimal.valueOf(Double.parseDouble(direction)));
            dataAccessGps.setCarVelocity(BigDecimal.valueOf(Double.parseDouble(gpsSpeed)));
            // 将毫秒时间戳转换为Instant对象
            Instant instant = Instant.ofEpochMilli(gpsTime);
            // 使用北京时间时区转换为LocalDateTime
            LocalDateTime localDateTime = instant.atZone(ZoneId.of("Asia/Shanghai")).toLocalDateTime();
            dataAccessGps.setUpdateTime(localDateTime);
            dataAccessGps.setCreateTime(LocalDateTime.now());
            dataAccessGps.setBizId(bizId);
            return dataAccessGps;
        }).collect(Collectors.toList());
        return dataList;
    }

    public String updateRedisId() {
        log.info("=========== 更新Redis缓存数据Id ======== 任务开始");
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 从缓存中获取业务数据最大id
        CacheKey key = new CacheKey(TaskConstant.RedisKey.GPS_DATA_PULL_MAX_BIZ_ID);
        Long id = cachePlusOps.get(key);
        log.info("缓存中已存在id: {}", id);
        // 缓存中已存在
        if (Objects.nonNull(id)){
            return "缓存中已存在id: " + id;
        }

        String url = "https://jtjdhcweb.z1l1.com:7443";
        try {
            // 先查询最新的50万数据
            trustAllCertificates();
            Map<String, String> requestParams = assemblyParams();
            String requestUrl = url + "/talent/gps/datalist";
            String response = sendPostRequest(requestUrl, requestParams);
            if (response == null) {
                return "下载路径请求失败！";
            }
            com.alibaba.fastjson.JSONObject object = com.alibaba.fastjson.JSONObject.parseObject(response);
            System.out.println("Response from server: " + response);
            String downloadUrl = object.getString("data");
            if (downloadUrl == null){
                return "下载路径请求失败！";
            }

            String downloadPath = url + downloadUrl;
            String result = sendDownloadRequest(downloadPath);
            if (result == null){
                return "文件下载失败！";
            }
            List<NdDataAccessGps> dataList = getNdDataAccessGps(result);
            if (CollUtil.isEmpty(dataList)){
                return "数据为空！";
            }
            // 获取最新的50万条数据中最大的id
            // 如果不存在 从新查询的数据中获取
            id = dataList.stream().map(d -> {
                String bizId = d.getBizId();
                return Long.parseLong(bizId);
            }).collect(Collectors.toList()).stream().max(Long::compare).get();

            // 保存到缓存中
            cachePlusOps.set(key,id,false);
            Long value = cachePlusOps.get(key);
            log.info("已存入缓存中的id: {}", value);
            stopWatch.stop();
            log.info("=========== 更新Redis缓存数据Id ======== 任务结束 {}s",stopWatch.getTotalTimeSeconds());
            return "数据Id更新完成!";
        } catch (Exception e) {
            log.error("Error sending POST request: {}", e.getMessage());
        }
        stopWatch.stop();
        log.info("=========== 更新Redis缓存数据Id ======== 任务结束 {}s",stopWatch.getTotalTimeSeconds());
        return "数据Id更新失败!";
    }

    public String getRedisData() {
        // 拼接数据
        jedis.auth("Ndkj1234");
        String allData = jedis.get(TaskConstant.RedisKey.HS_YW_COME_REDIS_ALL_DATA_KEY);
        //String allData = cachePlusOps.get(new CacheKey(TaskContant.RedisKey.HS_DY_GO_REDIS_ALL_DATA_KEY));
        log.info("allData:{}", allData);
        return "allData:" + allData;
    }
}
