package com.integrated.zyyt.util; import cn.hutool.core.convert.Convert; import cn.hutool.core.io.IORuntimeException; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.integrated.zyyt.ZyytConstant; import com.integrated.zyyt.enetity.TokenResult; import com.integrated.zyyt.enetity.ZyytDataResult; import com.integrated.zyyt.enetity.business.Zyyt; import com.integrated.zyyt.enetity.business.ZyytStationInfo; import com.integrated.zyyt.enetity.business.ZyytTDjtjb; import com.integrated.zyyt.enetity.business.ZyytTShkdrb; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.time.LocalDate; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @ClassName ZyytGetData * @Author cy * @Date 2022/11/11 * @Description * @Version 1.0 **/ @Component @Slf4j public class ZyytUtil { /** * 超时重试次数 */ private static int TRYNUM = 3; @Value("${pullData.tryNum}") public void setTRYNUM(Integer tryNum) { tryNum = tryNum <= 0 ? 3 : tryNum; this.TRYNUM = tryNum; } /** * http超时时间设置 */ private static int TRYTIMEOUT = 3 * 1000; @Value("${pullData.tryTimeOut}") public void setTRYTIMEOUT(Integer tryTimeOut) { this.TRYTIMEOUT = tryTimeOut * 1000; } private static JdbcTemplate jdbcTemplate; @Autowired public void setAlphaService(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } /** * 获取批次号 * * @return */ public static String getBatchNo(LocalDate date) { if (date == null) { date = LocalDate.now(); } // return batchNoPrefix + DateUtil.format(date, "yyyyMMddHHmmss"); return ZyytConstant.batchNoPrefix + date; } /** * 获取授权 * * @param url 请求地址 * @param eciphrtext false * @param client 为数据服务平台API授权中的授权账号; * @param secret secret 为数据服务平台API授权中的登陆密钥。 * @return */ public static TokenResult getAuth(String url, boolean eciphrtext, String client, String secret, String sourceSysKey) { HashMap params = new HashMap(); params.put("ciphertext", eciphrtext); params.put("client", client); params.put("secret", secret); HttpRequest httpRequest = HttpRequest.post(url) .form(params) .header("X-EOS-SourceSysKey", sourceSysKey) .timeout(TRYTIMEOUT); log.info("超时时间为{}毫秒", TRYTIMEOUT); log.info("url =》》{}", url); log.info("params =》》{}", params); HttpResponse httpResponse = null; int tryNumTemp = 1; boolean isTimeOut = false; try { httpResponse = httpRequest.execute(); } catch (IORuntimeException e) { // e.printStackTrace(); // 超时重试 isTimeOut = true; log.error(e.getMessage()); } while (tryNumTemp <= TRYNUM && isTimeOut) { log.error("请求接口超时,进行第{}次重试!", tryNumTemp); try { httpResponse = httpRequest.execute(); isTimeOut = false; } catch (IORuntimeException e) { // e.printStackTrace(); // 超时重试 log.error(e.getMessage()); } tryNumTemp++; } if (httpResponse == null) { log.error("请求接口超时,请联系接口提供方!"); return null; } int responseStatus = httpResponse.getStatus(); if (HttpStatus.NOT_FOUND.value() == responseStatus) { log.error("接口API异常,请联系接口提供方!HttpStatus:{}", responseStatus); return null; } else if (HttpStatus.OK.value() != responseStatus) { log.error("请求接口状态有误!HttpStatus:{}", responseStatus); return null; } String httpResult = httpResponse.body(); log.info("result =》》{}", httpResult); try { return JSONObject.parseObject(httpResult, TokenResult.class); } catch (Exception e) { log.error("Token解析失败!", e.getMessage()); return null; } } /** * 获取数据 * * @param url * @param bearToken * @param sourceSysKey * @param params * @return */ public static ZyytDataResult getData(String url, String bearToken, String sourceSysKey, JSONObject params, int pageNum, int pageSize, Class tClass) { if (StringUtils.isEmpty(bearToken)) { log.error("bearToken不能为null!"); return null; } HashMap header = new HashMap(); header.put("Authorization", "Bearer " + bearToken); header.put("X-EOS-SourceSysKey", sourceSysKey); String trueUrl = url + "?pageNumber=" + pageNum + "&pageSize=" + pageSize; log.info("url =》》{}", trueUrl); log.info("header=>>bearToken》》{}\r\nSourceSysKey=>>{}", bearToken, sourceSysKey); log.info("params =》》{}", params); HttpRequest httpRequest = HttpRequest.post(trueUrl) .addHeaders(header) .contentType("application/json") .body(params.toJSONString()) .timeout(TRYTIMEOUT); log.info("超时时间为{}毫秒", TRYTIMEOUT); HttpResponse httpResponse = null; int tryNumTemp = 1; boolean isTimeOut = false; try { httpResponse = httpRequest.execute(); } catch (IORuntimeException e) { // 超时重试 isTimeOut = true; log.error(e.getMessage()); } while (tryNumTemp <= TRYNUM && isTimeOut) { log.error("请求接口超时,进行第{}次重试!", tryNumTemp); try { httpResponse = httpRequest.execute(); isTimeOut = false; } catch (IORuntimeException e) { // e.printStackTrace(); // 超时重试 log.error(e.getMessage()); } tryNumTemp++; } if (httpResponse == null) { log.error("请求接口超时,请联系接口提供方!"); return null; } int responseStatus = httpResponse.getStatus(); if (HttpStatus.NOT_FOUND.value() == responseStatus) { log.error("接口API异常,请联系接口提供方!HttpStatus:{}", responseStatus); return null; } else if (HttpStatus.OK.value() != responseStatus) { log.error("请求接口状态有误!HttpStatus:{}", responseStatus); return null; } String httpResult = httpResponse.body(); try { JSONObject respJson = JSONObject.parseObject(httpResult); Long contentSize = respJson.getLong("contentSize"); if (contentSize != null && contentSize.compareTo(0L) > 0) { JSONArray dataArray = respJson.getJSONArray("content"); List content = dataArray.toJavaList(tClass); respJson.remove("content"); ZyytDataResult zyytDataResult = respJson.toJavaObject(ZyytDataResult.class); zyytDataResult.setContent(content); return zyytDataResult; } else { log.info("result =》》{}", httpResult); return respJson.toJavaObject(ZyytDataResult.class); } } catch (Exception e) { log.error("getData 异常"); // e.printStackTrace(); return null; } } /** * 查询执行日期是否在执行 * * @param tableName * @param date */ public static Map getLastRecord(String tableName, LocalDate date) { String sql = "SELECT*FROM (SELECT*FROM ZYYT_RECORD WHERE BATCH_NO='" + getBatchNo(date) + "' AND TABLE_NAME='" + tableName + "' ORDER BY START_TIME DESC) tmp WHERE ROWNUM<=1"; Map map = null; try { // map = jdbcTemplate.queryForMap(sql); List> maps = jdbcTemplate.queryForList(sql); if (CollectionUtils.isEmpty(maps)) { return map; } map = maps.get(0); } catch (Exception e) { log.error("sql=={} 查询发生了异常,可能因为没有查询到数据", sql); log.error(e.getMessage()); } return map; } /** * 查询指定批次是否有正在运行的任务 * * @param tableName * @param date * @return true 正在运行 false 没有运行 */ public static boolean isRunning(String tableName, LocalDate date) { Map lastRecord = getLastRecord(tableName, date); if (lastRecord != null) { String isFinish = Convert.toStr(lastRecord.get("IS_FINISH")); return !"1".equals(isFinish); } else { return false; } } /** * 判断指定日期是否需要重新执行 * * @param tableName * @param date * @return true 需要执行,false 不需要 */ public static boolean canGetAgain(String tableName, LocalDate date) { Map map = getLastRecord(tableName, date); if (map != null) { String isFinish = Convert.toStr(map.get("IS_FINISH")); if (!"1".equals(isFinish)) { log.info("表:{} 日期: {},上次执行未完成,不执行拉取", tableName, date); return false; } //下面 isFinish都是1 String isError = Convert.toStr(map.get("IS_ERROR")); if ("1".equals(isError)) { log.info("表:{} 日期: {},上次执行有误,执行拉取", tableName, date); return true; } // 成功执行没有错 String countNum = Convert.toStr(map.get("COUNT_NUM")); // 同接口返回的最新业务数据条数比较,如果不相同则重新拉取 Long apiTotalElements = getApiTotalElements(tableName, date); if (apiTotalElements == null) { log.error("API获取总数失败,不执行拉取"); return false; } if (apiTotalElements.compareTo(Convert.toLong(countNum)) == 0) { log.info("API返回总数 与 数据库条数相同,不执行拉取"); return false; } else { log.info("API返回总数 与 数据库条数 不相同,执行拉取"); return true; } } else { // 该批次未执行 log.info("表:{} 日期: {},未执行过", tableName, date); return true; } } public static Zyyt getBusinessEntity(String tableName, LocalDate date) { if ("STATIONINFO".equalsIgnoreCase(tableName)) { return new ZyytStationInfo( ZyytConstant.URL_AUTHON, ZyytConstant.URL_STATIONINFO_QUERY, false, ZyytConstant.CLIENT_STATIONINFO, ZyytConstant.SECRET_STATIONINFO, ZyytConstant.X_EOS_SOURCESYSKEY_STATIONINFO, new JSONObject() ); } else { JSONObject queryParams = new JSONObject(); JSONObject criteria = new JSONObject(); criteria.put("match", "and"); JSONArray matchChildren = new JSONArray(); JSONObject children1 = new JSONObject(); children1.put("name", "dRbrq"); JSONArray child1C = new JSONArray(); child1C.add(date + " 00:00:00"); children1.put("value", child1C); children1.put("match", "eq"); matchChildren.add(children1); criteria.put("children", matchChildren); queryParams.put("criteria", criteria); if ("YYZT_T_SHKDRB".equalsIgnoreCase(tableName)) { return new ZyytTShkdrb( ZyytConstant.URL_AUTHON, ZyytConstant.URL_SHKDRB_QUERY, false, ZyytConstant.CLIENT_SHKDRB, ZyytConstant.SECRET_SHKDRB, ZyytConstant.X_EOS_SOURCESYSKEY_SHKDRB, queryParams ); } else if ("YYZT_T_DJTJB".equalsIgnoreCase(tableName)) { return new ZyytTDjtjb( ZyytConstant.URL_AUTHON, ZyytConstant.URL_DJTJB_QUERY, false, ZyytConstant.CLIENT_DJTJB, ZyytConstant.SECRET_DJTJB, ZyytConstant.X_EOS_SOURCESYSKEY_DJTJB, queryParams ); } } return null; } /** * 获取API中返回的记录总数 * * @param tableName * @param date * @return */ public static Long getApiTotalElements(String tableName, LocalDate date) { Zyyt businessEntity = getBusinessEntity(tableName, date); ZyytDataResult zyytDataResult = businessEntity.getData(0, 1); if (zyytDataResult == null) { log.info("拉取数据失败,拉取返回值为null"); return 0l; } log.info("总共拉取到数据{}条", zyytDataResult.getTotalElements()); return zyytDataResult.getTotalElements(); } public static Long calcPages(Long totalElements, int pageSize) { Long totalPages = 0L; totalPages = totalElements / pageSize; if (totalElements % pageSize != 0) { totalPages++; } return totalPages; } }