package com.bb.api; import java.nio.charset.Charset; import java.security.MessageDigest; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClientRequestException; import org.springframework.web.reactive.function.client.WebClientResponseException; import org.springframework.web.util.UriComponentsBuilder; import com.bb.exception.ApiException; import com.bb.jwt.JwtManager; import com.bb.model.ApiResponse; import com.bb.model.BetParam; import com.bb.model.NexusApiInfo; import com.bb.model.PageFormVO; import com.bb.model.Site; import com.bb.model.TransSearchVO; import com.bb.service.AsyncSiteService; import com.bb.service.PandaService; import com.bb.service.SiteService; import com.bb.service.ThenutService; import com.bb.service.TransService; import com.bb.util.AesUtil; import com.bb.util.IPKit; import com.bb.util.PagingUtil; import com.bb.util.StringUtils; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import okhttp3.OkHttpClient; @Slf4j @Controller @RequiredArgsConstructor @RequestMapping(value = "/api/v1/trans") public class ApiTransController { @Autowired SiteService siteService; @Autowired TransService transService; @Autowired ThenutService thenutService; @Autowired PandaService pandaService; @Autowired WebClient webClient; @Autowired private final JwtManager jwtManager; @Autowired private AsyncSiteService asyncSiteService; @ResponseBody @PostMapping("/betList") public ApiResponse betList(@RequestHeader String token, HttpServletRequest request, @Valid @RequestBody TransSearchVO search) throws Exception { ApiResponse apiResponse = new ApiResponse(); try { Site site = siteService.getSiteInfoAPI(request); if(site == null) { apiResponse.setResultCode("9999"); apiResponse.setResultMessage("Authorization apiKey check"); return apiResponse; } if( !( site.getSiteIp()==null || "".equals(site.getSiteIp()) || "3.3.3.3".equals(site.getSiteIp()) || site.getSiteIp().indexOf(IPKit.getIpAddressByRequest(request)) >= 0) ) { log.error("site.getSiteIp("+site.getSiteIp()+"), denied" + IPKit.getIpAddressByRequest(request)); apiResponse.setResultCode("10001"); return apiResponse; } // TO DO 토큰체크 Map responseData = new HashMap(); try { JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfoAdmin(token); final String LOG_PREFIX = "#-API::TRANS::betlist::"+tokenInfo.getSid()+"::::"; ObjectMapper objectMapper = new ObjectMapper(); String reqJsonStr = objectMapper.writeValueAsString(search); JSONObject reqObj = new JSONObject(reqJsonStr); log.info(LOG_PREFIX+ "Request {}", reqObj); // 여기서 부터 로직 PageFormVO pageVo = new PageFormVO(); search.setSiteId(site.getSiteId()); search.setSiteIdx((long) site.getSiteIdx()); if(search.getOrderStr() == null || search.getOrderStr().equals("")) { search.setOrderStr("BETDATE_DESC"); } if(search.getBetWinAmt() == null || search.getBetWinAmt().equals("")) { search.setBetWinAmt("0"); } search.setTopId(tokenInfo.getSid()); search.setStartDatePartition(StringUtils.convertToDateOnly(search.getStartDate())); search.setEndDatePartition(StringUtils.convertToDateOnly(search.getEndDate())); log.info(LOG_PREFIX+ "TransSearchVO::"+search.toString()); if(search.getBetWinAmt().equals("0") && search.getOldYN().equals("N") && search.getWithBottomYN().equals("N") && (search.getResultInfo()==null || search.getResultInfo().equals(""))) { // Fast Search log.info(LOG_PREFIX+ "BetList Fast Search!!!"); int totalCount = transService.getTransBetFastListCnt(search); if (totalCount != 0) { PageFormVO commonForm = new PageFormVO(); commonForm.setFunction_name("goPage"); commonForm.setPage(search.getPage()); commonForm.setCount_per_page(20); if(search.getCount_per_list()==0) { commonForm.setCount_per_list(30); } else { commonForm.setCount_per_list(search.getCount_per_list()); } commonForm.setTatal_list_count(totalCount); pageVo = PagingUtil.setPageUtil(commonForm); search.setLimit(pageVo.getLimit()); search.setOffset(pageVo.getOffset()); search.setTatal_list_count(totalCount); responseData.put("pageInfo", pageVo); } List> fastList = transService.getTransBetFastList(search); List> list = new ArrayList>(); for(HashMap item : fastList) { String refId = item.get("betId"); search.setRefId(refId); HashMap betItem = transService.getBetListItem(search); list.add(betItem); } responseData.put("list", list); HashMap listSum = transService.getTransBetFastListSum(search); responseData.put("listSum", listSum); log.info(LOG_PREFIX+ "BetList Total count::"+totalCount); log.info(LOG_PREFIX+ "BetList list count::"+list.size()); log.info(LOG_PREFIX+ "BetList listSum::"+listSum); } else { // ORG Search log.info(LOG_PREFIX+ "BetList ORG Search!!!"); int totalCount = transService.getTransBetListCnt(search); if (totalCount != 0) { PageFormVO commonForm = new PageFormVO(); commonForm.setFunction_name("goPage"); commonForm.setPage(search.getPage()); commonForm.setCount_per_page(20); if(search.getCount_per_list()==0) { commonForm.setCount_per_list(30); } else { commonForm.setCount_per_list(search.getCount_per_list()); } commonForm.setTatal_list_count(totalCount); pageVo = PagingUtil.setPageUtil(commonForm); search.setLimit(pageVo.getLimit()); search.setOffset(pageVo.getOffset()); search.setTatal_list_count(totalCount); responseData.put("pageInfo", pageVo); } List> list = transService.getTransBetList(search); responseData.put("list", list); HashMap listSum = transService.getTransBetListSum(search); responseData.put("listSum", listSum); log.info(LOG_PREFIX+ "BetList Total count::"+totalCount); log.info(LOG_PREFIX+ "BetList list count::"+list.size()); log.info(LOG_PREFIX+ "BetList listSum::"+listSum); } } catch(Exception e) { log.info(e.toString()); e.printStackTrace(); apiResponse.setResultCode("99995"); apiResponse.setResultMessage("token is no valid"); return apiResponse; } apiResponse.setData(responseData); apiResponse.success(); } catch (Exception e) { e.printStackTrace(); apiResponse.fail(); } return apiResponse; } @ResponseBody @PostMapping(value="/betDetail") public ApiResponse betDetail(@RequestHeader String token, HttpServletRequest request, @RequestBody BetParam param) throws Exception { ApiResponse apiResponse = new ApiResponse(); JSONObject saveObj = null; JSONArray saveObjs = null; boolean isSaveEvoDetail = false; try { // apiKey 체크 Site site = siteService.getSiteInfoAPI(request); if(site == null) { apiResponse.setResultCode("9999"); apiResponse.setResultMessage("Authorization apiKey check"); return apiResponse; } if( !( site.getSiteIp()==null || "".equals(site.getSiteIp()) || "3.3.3.3".equals(site.getSiteIp()) || site.getSiteIp().indexOf(IPKit.getIpAddressByRequest(request)) >= 0) ) { log.error("site.getSiteIp("+site.getSiteIp()+"), denied" + IPKit.getIpAddressByRequest(request)); apiResponse.setResultCode("10001"); return apiResponse; } // TO DO 토큰체크 Map responseData = new HashMap(); try { JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfoAdmin(token); final String LOG_PREFIX = "#-API::TRANS::betDetail::"+tokenInfo.getSid()+"::::"; // 여기서 부터 로직 log.info(LOG_PREFIX+ "BetParam::"+param.toString()); responseData.put("betId", param.getBetId()); String dType = "detail_0"; HashMap betInfo = transService.getBetInfoByBetId(param); if(betInfo == null) { betInfo = transService.getSiteBetByRefIdFromOld(param); log.info(LOG_PREFIX+ "betInfo_OLD {}", betInfo); } log.info(LOG_PREFIX+ "betINfp {}", betInfo); if(betInfo != null) { param.setBetId(betInfo.get("refId").toString()); String category = betInfo.get("vendorCetegory").toString(); log.info(LOG_PREFIX+ "Game category : " + category); if("pragmatic".equals(betInfo.get("vendorCode").toString())) { dType = "detail_2"; responseData.put("dType", dType); String detailURL = transService.getPragmaticDetails(LOG_PREFIX, betInfo); if(detailURL != null && !detailURL.equals("")) { HashMap url = new HashMap(); url.put("url", detailURL); responseData.put("detail", url); } else { responseData.put("detail", "betId is not exist"); } } else if("svendor".equals(betInfo.get("vendorCode").toString()) || "pink".equals(betInfo.get("vendorCode").toString())) { String jsonStr = siteService.getOrgDetailData(param); log.info(LOG_PREFIX+ "jsonStr : " + jsonStr); if(jsonStr != null && !"".equals(jsonStr) && !"{}".equals(jsonStr)) { dType = "detail_6"; responseData.put("dType", dType); HashMap detailMap = new Gson().fromJson(jsonStr, HashMap.class); responseData.put("detail", detailMap); } else { isSaveEvoDetail = true; JSONObject dataObj = transService.getSvendorDetail(LOG_PREFIX, betInfo); if(dataObj == null) { responseData.put("detail", "betId is not exist"); } else { if(dataObj.has("gameDetail") && !dataObj.isNull("gameDetail")) { String detailType = StringUtils.getType(dataObj.getString("gameDetail")); if(detailType.equals("URL")) { dType = "detail_2"; responseData.put("dType", dType); String detailUrl = dataObj.getString("gameDetail"); HashMap url = new HashMap(); url.put("url", detailUrl); responseData.put("detail", url); } else if(detailType.equals("JSON")) { dType = "detail_6"; responseData.put("dType", dType); JSONObject detailObj = dataObj.getJSONObject("gameDetail"); saveObj = detailObj; HashMap detailMap = new Gson().fromJson(detailObj.toString(), HashMap.class); responseData.put("detail", detailMap); } else { apiResponse.put("detail", "betId is not exist"); } } else { responseData.put("detail", "betId is not exist"); } } } } else if(Integer.parseInt(betInfo.get("vendorIdx").toString())==17 && "tower".equals(betInfo.get("vendorCode").toString())) { dType = "detail_2"; responseData.put("dType", dType); String detailUrl = betInfo.get("vendorApiUrl").toString() +"/v2/detail_url" + "?site_code="+betInfo.get("vendorApiId").toString() + "&user_id="+betInfo.get("siteHex").toString()+betInfo.get("memberId").toString() + "&transaction_id="+betInfo.get("transactionId").toString() + "&vendorCode=pp" + "&gameCode="+betInfo.get("gameIdx").toString(); log.info(LOG_PREFIX+" {}" ,detailUrl); OkHttpClient client = new OkHttpClient().newBuilder().build(); okhttp3.Request requestok2 = new okhttp3.Request.Builder() .url(detailUrl) .method("GET", null)// .addHeader("User-agent", "Mozilla") .addHeader("Authorization", betInfo.get("vendorApiKey").toString()) .build(); okhttp3.Response response = client.newCall(requestok2).execute(); if(response.isSuccessful()){ okhttp3.ResponseBody body = response.body(); String responseString = body.string(); log.info(LOG_PREFIX+ responseString+" {}" ,StringUtils.extractLink(responseString)); HashMap url = new HashMap(); url.put("url", StringUtils.extractLink(responseString)); responseData.put("detail", url); } else { responseData.put("detail", "betId is not exist"); } } else if(Integer.parseInt(betInfo.get("vendorIdx").toString())==83 && "splus".equals(betInfo.get("vendorCode").toString())) { log.info(LOG_PREFIX+ "========== BetDetail::Splus =========="); dType = "detail_1"; responseData.put("dType", dType); HashMap d = new HashMap(); List splusDetail = siteService.getSplusDetailData(param); for(HashMap ttype : splusDetail) { log.info(LOG_PREFIX+ "{}, {}", ttype.get("tranType").toString(), ttype.get("data").toString()); HashMap detailMap = new Gson().fromJson(ttype.get("data").toString(), HashMap.class); d.put(ttype.get("tranType").toString(), detailMap); } responseData.put("detail", d); } else if("nexus".equals(betInfo.get("vendorCode").toString()) || "ace2".equals(betInfo.get("vendorCode").toString())) { log.info(LOG_PREFIX+ "========== BetDetail::Hlink or Xtreem =========="); String jsonStr = siteService.getOrgDetailData(param); log.info(LOG_PREFIX+ "jsonStr : " + jsonStr); if(jsonStr != null && !"".equals(jsonStr) && !"{}".equals(jsonStr)) { dType = "detail_3"; responseData.put("dType", dType); JSONObject detailObj = new JSONObject(jsonStr); String gameType = detailObj.optString("gameType"); JSONArray participants = detailObj.optJSONArray("participants"); if (participants != null) { for (int i = 0; i < participants.length(); i++) { // result 객체 가져오기 (없으면 생성) JSONObject participant = participants.optJSONObject(i); JSONObject result = participant.optJSONObject("result"); if (result == null) { result = new JSONObject(); participant.put("result", result); } // link 값 세팅 String raw = "betId="+param.getBetId()+"&gameType="+gameType; String encrypted = AesUtil.encrypt(raw); result.put("link", "https://fst.tx-direction.cc/detailsPage/"+encrypted); } } HashMap detailMap = new Gson().fromJson(detailObj.toString(), HashMap.class); responseData.put("detail", detailMap); } else { isSaveEvoDetail = true; long siteIdx = (long) betInfo.get("siteIdx"); long memberIdx = (long) betInfo.get("memberIdx"); String trxId = betInfo.get("vendorTranKey").toString(); String apiBaseUrl = betInfo.get("vendorApiUrl").toString(); String apiAgentId = betInfo.get("vendorApiId").toString(); String apiSecretKey = betInfo.get("vendorApiKey").toString(); NexusApiInfo nexusApiInfo = NexusApiInfo.builder() .siteIdx(siteIdx) .memberIdx(memberIdx) .apiBaseUrl(apiBaseUrl) .agentId(apiAgentId) .agentSecretKey(apiSecretKey) .build(); if("CASINO".equals(betInfo.get("vendorCetegory").toString())) { dType = "detail_3"; responseData.put("dType", dType); JSONObject detailObj = transService.getNexusBetDetail(LOG_PREFIX, nexusApiInfo, trxId); int resultCode = detailObj.getInt("code"); if(resultCode == 0) { JSONArray transactions = detailObj.getJSONArray("transactions"); if(transactions.length() > 0) { saveObjs = transactions; List> detailMap = new Gson().fromJson(transactions.toString(), List.class); responseData.put("detail", detailMap); } else { responseData.put("detail", "betId is not exist"); } } else { responseData.put("detail", "betId is not exist"); } } else { dType = "detail_2"; responseData.put("dType", dType); JSONObject detailObj = transService.getNexusBetDetailUrl(LOG_PREFIX, nexusApiInfo, trxId); log.info(LOG_PREFIX+ "detailObj::"+detailObj.toString()); int resultCode = detailObj.getInt("code"); if(resultCode == 0) { HashMap url = new HashMap<>(); url.put("url", detailObj.getString("url")); responseData.put("detail", url); } else { responseData.put("detail", "betId is not exist"); } } } } else if("prime".equals(betInfo.get("vendorCode").toString()) || "dpcore".equals(betInfo.get("vendorCode").toString())) { log.info(LOG_PREFIX+ "========== BetDetail::PRIME =========="); dType = "detail_9"; responseData.put("dType", dType); String jsonStr = siteService.getOrgDetailData(param); if(jsonStr != null && !"".equals(jsonStr) && !"{}".equals(jsonStr)) { JSONObject detailObj = new JSONObject(jsonStr); String gameType = detailObj.optString("gameType"); JSONArray participants = detailObj.optJSONArray("participants"); if (participants != null) { for (int i = 0; i < participants.length(); i++) { // result 객체 가져오기 (없으면 생성) JSONObject participant = participants.optJSONObject(i); JSONObject result = participant.optJSONObject("result"); if (result == null) { result = new JSONObject(); participant.put("result", result); } // link 값 세팅 String raw = "betId="+param.getBetId()+"&gameType="+gameType; String encrypted = AesUtil.encrypt(raw); result.put("link", "https://fst.tx-direction.cc/detailsPage/"+encrypted); } } HashMap detailMap = new Gson().fromJson(detailObj.toString(), HashMap.class); responseData.put("detail", detailMap); } else { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); String apiKey = "Bearer "+betInfo.get("vendorApiKey").toString(); headers.set("Authorization", apiKey); String detailUrl = betInfo.get("vendorApiUrl").toString() + "/api/getBettingDetails5?"; String detailParam = "referer="+param.getBetId(); detailUrl = detailUrl + detailParam; log.info(LOG_PREFIX+ "PRIME::Detail Url: " + detailUrl); log.info(LOG_PREFIX+ "PRIME::Detail Headers: " + headers.toString()); ResponseEntity response = null; JSONObject resJson = null; try { response = webClient.get() .uri(detailUrl) .headers(h -> h.addAll(headers)) .retrieve() .toEntity(String.class) .block(); } catch(WebClientResponseException e) { log.error(LOG_PREFIX+ "PRIME::Detail WebClientResponseException : " + e.getMessage()); log.error(LOG_PREFIX+ "PRIME::Detail status code : " + e.getStatusCode().value()); log.error(LOG_PREFIX+ "PRIME::Detail response body : " + e.getResponseBodyAsString()); resJson = new JSONObject(e.getResponseBodyAsString()); log.error(LOG_PREFIX+ "PRIME::Detail error : " + resJson.getString("message")); throw new ApiException("P209", resJson.getString("message")); } catch (WebClientRequestException rae) { if(rae.getCause() instanceof io.netty.channel.ConnectTimeoutException) { log.error(LOG_PREFIX+ "PRIME::Detail ConnectTimeoutException::"+rae.getMessage()); } if(rae.getCause() instanceof io.netty.handler.timeout.ReadTimeoutException) { log.error(LOG_PREFIX+ "PRIME::Detail SocketTimeoutException::"+rae.getMessage()); } if(rae.getCause() instanceof InterruptedException) { log.error(LOG_PREFIX+ "PRIME::Detail InterruptedException::"+rae.getMessage()); } throw new ApiException("P210", rae.getMessage()); } catch (Exception e) { log.error(LOG_PREFIX+ "PRIME::Detail Exception : " + e.getMessage()); throw new ApiException("P211", e.getMessage()); } if(response != null && response.getStatusCode() == HttpStatus.OK) { isSaveEvoDetail = true; log.info(LOG_PREFIX+ "PRIME::Play response : " + response.getBody()); resJson = new JSONObject(response.getBody()); JSONObject dataObj = resJson; String gameType = dataObj.optString("gameType"); JSONArray participants = dataObj.optJSONArray("participants"); if (participants != null) { for (int i = 0; i < participants.length(); i++) { // result 객체 가져오기 (없으면 생성) JSONObject participant = participants.optJSONObject(i); JSONObject result = participant.optJSONObject("result"); if (result == null) { result = new JSONObject(); participant.put("result", result); } // link 값 세팅 String raw = "betId="+param.getBetId()+"&gameType="+gameType; String encrypted = AesUtil.encrypt(raw); result.put("link", "https://fst.tx-direction.cc/detailsPage/"+encrypted); } } saveObj = dataObj; HashMap detailMap = new Gson().fromJson(dataObj.toString(), HashMap.class); responseData.put("detail", detailMap); } else { responseData.put("detail", "betId is not exist"); } } } else if("grand".equals(betInfo.get("vendorCode").toString())) { dType = "detail_2"; responseData.put("dType", dType); String detailUrl = betInfo.get("vendorApiUrl").toString() +"/transactions/detail" + "?round_id="+betInfo.get("vendorTranKey").toString(); log.info(LOG_PREFIX+"Request Url : {}" ,detailUrl); OkHttpClient client = new OkHttpClient().newBuilder().build(); okhttp3.Request requestok2 = new okhttp3.Request.Builder() .url(detailUrl) .method("GET", null)// .addHeader("User-agent", "Mozilla") .addHeader("Authorization", "Bearer "+betInfo.get("vendorApiKey").toString()) .build(); okhttp3.Response response = client.newCall(requestok2).execute(); if(response.isSuccessful()){ okhttp3.ResponseBody body = response.body(); String responseString = body.string(); log.info(LOG_PREFIX+ "responseString : " , responseString); JSONObject responseObj = new JSONObject(responseString); JSONObject dataObj = responseObj.getJSONObject("data"); if(dataObj != null) { HashMap url = new HashMap(); url.put("url", dataObj.getString("url")); responseData.put("detail", url); } else { responseData.put("detail", "betId is not exist"); } } else { responseData.put("detail", "betId is not exist"); } } else if("pracp".equals(betInfo.get("vendorCode").toString())) { dType = "detail_2"; responseData.put("dType", dType); HashMap apiInfo = new HashMap<>(); apiInfo.put("apiAgentCode", betInfo.get("vendorApiId").toString()); apiInfo.put("apiToken", betInfo.get("vendorApiKey").toString()); apiInfo.put("apiBaseUrl", betInfo.get("vendorApiUrl").toString()); apiInfo.put("uuid", betInfo.get("uuid").toString()); apiInfo.put("round_id", betInfo.get("roundId").toString()); JSONObject dataObj = transService.getPracpDetail(LOG_PREFIX, apiInfo); log.info(LOG_PREFIX+ "dataObj : " + dataObj.toString()); if(dataObj != null) { HashMap url = new HashMap(); url.put("url", dataObj.getString("url")); responseData.put("detail", url); } else { responseData.put("detail", "betId is not exist"); } } else if("tplus".equals(betInfo.get("vendorCode").toString())) { dType = "detail_2"; responseData.put("dType", dType); String apiBaseUrl = betInfo.get("vendorApiUrl").toString(); String apiAuthKey = betInfo.get("vendorApiKey").toString(); String pairTransactionKey = betInfo.get("refId").toString(); HashMap apiInfo = new HashMap<>(); apiInfo.put("apiBaseUrl", apiBaseUrl); apiInfo.put("apiAuthKey", apiAuthKey); apiInfo.put("pairTransactionKey", pairTransactionKey); log.info(LOG_PREFIX+ "tplus::apiInfo: " + apiInfo.toString()); String detailURL = transService.getTplusDetails(LOG_PREFIX, apiInfo); if(detailURL != null && !detailURL.equals("")) { HashMap url = new HashMap(); url.put("url", detailURL); responseData.put("detail", url); } else { responseData.put("detail", "betId is not exist"); } } else if("onix".equals(betInfo.get("vendorCode").toString())) { log.info(LOG_PREFIX+ "========== BetDetail::ONIX =========="); dType = "detail_8"; responseData.put("dType", dType); String jsonStr = siteService.getOrgDetailData(param); if(jsonStr != null && !"".equals(jsonStr) && !"{}".equals(jsonStr)) { JSONObject detailObj = new JSONObject(jsonStr); String gameType = detailObj.optString("gameType"); JSONArray participants = detailObj.optJSONArray("participants"); if (participants != null) { for (int i = 0; i < participants.length(); i++) { // result 객체 가져오기 (없으면 생성) JSONObject participant = participants.optJSONObject(i); JSONObject result = participant.optJSONObject("result"); if (result == null) { result = new JSONObject(); participant.put("result", result); } // link 값 세팅 String raw = "betId="+param.getBetId()+"&gameType="+gameType; String encrypted = AesUtil.encrypt(raw); result.put("link", "https://fst.tx-direction.cc/detailsPage/"+encrypted); } } HashMap detailMap = new Gson().fromJson(detailObj.toString(), HashMap.class); responseData.put("detail", detailMap); } else { String apiBaseUrl = betInfo.get("vendorApiUrl").toString(); String fullDateTime = betInfo.get("betTime").toString(); String dateOnly = fullDateTime.substring(0, 10); // Step 1: Get round info from /csapi/getBetting String bettingUrl = apiBaseUrl + "/csapi/getBetting"; JSONObject bettingBody = new JSONObject(); bettingBody.put("userid", betInfo.get("siteIdxHex").toString()+betInfo.get("memberId").toString()); bettingBody.put("sdate", dateOnly+" 00:00:00.000"); bettingBody.put("edate", dateOnly+" 23:59:59.999"); bettingBody.put("pagesize", "1"); bettingBody.put("gameid", "0"); bettingBody.put("roundcode", betInfo.get("uuid").toString()); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); headers.set("Authorization", "Bearer " + betInfo.get("vendorApiKey").toString()); log.info(LOG_PREFIX+ "ONIX::Step1 getBetting Url: " + bettingUrl); log.info(LOG_PREFIX+ "ONIX::Step1 getBetting Body: " + bettingBody.toString()); try { ResponseEntity bettingRes = webClient.post() .uri(bettingUrl) .headers(h -> h.addAll(headers)) .bodyValue(bettingBody.toString()) .retrieve() .toEntity(String.class) .block(); if(bettingRes != null && bettingRes.getBody() != null) { JSONObject bettingObj = new JSONObject(bettingRes.getBody()); log.info(LOG_PREFIX+ "ONIX::Step1 getBetting Response: " + bettingObj.toString()); int bettingResult = bettingObj.getInt("result"); if(bettingResult == 1 && bettingObj.has("data")) { JSONArray dataArray = bettingObj.getJSONArray("data"); if(dataArray.length() > 0) { isSaveEvoDetail = true; JSONObject dataObj = dataArray.getJSONObject(0); JSONObject detailObj = dataObj.getJSONArray("details").getJSONObject(0); String gameType = detailObj.optString("gameType"); JSONArray participants = detailObj.optJSONArray("participants"); if (participants != null) { for (int i = 0; i < participants.length(); i++) { // result 객체 가져오기 (없으면 생성) JSONObject participant = participants.optJSONObject(i); JSONObject result = participant.optJSONObject("result"); if (result == null) { result = new JSONObject(); participant.put("result", result); } // link 값 세팅 String raw = "betId="+param.getBetId()+"&gameType="+gameType; String encrypted = AesUtil.encrypt(raw); result.put("link", "https://fst.tx-direction.cc/detailsPage/"+encrypted); } } HashMap detailMap = new Gson().fromJson(detailObj.toString(), HashMap.class); responseData.put("detail", detailMap); saveObj = detailObj; } else { responseData.put("detail", "betId is not exist"); } } else { responseData.put("detail", "betId is not exist"); String errorMsg = bettingObj.has("msg") ? bettingObj.getString("msg") : "Unknown error"; log.error(LOG_PREFIX+ "ONIX::Betting Error: " + errorMsg); } } else { responseData.put("detail", "betId is not exist"); log.error(LOG_PREFIX+ "ONIX::Betting Response is null"); } } catch(WebClientResponseException e) { log.error(LOG_PREFIX+ "ONIX::Betting HttpClientErrorException : " + e.getMessage()); log.error(LOG_PREFIX+ "ONIX::Betting status code : " + e.getStatusCode().value()); log.error(LOG_PREFIX+ "ONIX::Betting response body : " + e.getResponseBodyAsString()); JSONObject errorJson = new JSONObject(e.getResponseBodyAsString()); String errorMsg = errorJson.has("msg") ? errorJson.getString("msg") : "Betting API error"; log.error(LOG_PREFIX+ "ONIX::Betting error : " + errorMsg); throw new ApiException("P209", errorMsg); } catch (WebClientRequestException rae) { if(rae.getCause() instanceof io.netty.channel.ConnectTimeoutException) { log.error(LOG_PREFIX+ "ONIX::Betting ConnectTimeoutException::" + rae.getMessage()); } if(rae.getCause() instanceof io.netty.handler.timeout.ReadTimeoutException) { log.error(LOG_PREFIX+ "ONIX::Betting ReadTimeoutException::" + rae.getMessage()); } if(rae.getCause() instanceof InterruptedException) { log.error(LOG_PREFIX+ "ONIX::Betting InterruptedException::" + rae.getMessage()); } throw new ApiException("P210", rae.getMessage()); } catch(Exception e) { log.error(LOG_PREFIX+ "ONIX::Betting Exception : " + e.getMessage()); throw new ApiException("P211", e.getMessage()); } } } else if("bet_radar".equals(betInfo.get("vendorCode").toString())) { log.info(LOG_PREFIX+ "========== BetDetail::BET_RADAR =========="); // TODO: 베팅상세 내려주기 /* * param.getBetId() 기준으로 bet_radar_log 테이블 조회시 베팅과 결과 두가지가 나옴. * 결과가 없는경우 베팅만 한가지 있을 수 있음. * param.getBetId() 기준 bet_radar_log에서 jsonstr(베팅상세 json 원본)을 가져와서 * 하나의 json으로 합쳐서 내려주기 구현. */ // bet_radar_log 테이블에서 조회 String radarLogJson = siteService.getMergedBetRadarLog(param.getBetId()); if(radarLogJson != null && !radarLogJson.isEmpty()) { log.info(LOG_PREFIX+ "bet_radar_log found, returning merged json"); dType = "detail_radar"; responseData.put("dType", dType); HashMap detailMap = new Gson().fromJson(radarLogJson, HashMap.class); String detailUrl = "https://sportsbook.spokok.com/bets/detail/"+param.getBetId(); detailMap.put("dLink", detailUrl); responseData.put("detail", detailMap); apiResponse.setData(responseData); apiResponse.success(); return apiResponse; } } else if("thenut".equals(betInfo.get("vendorCode").toString())) { log.info(LOG_PREFIX+ "========== BetDetail::THENUT =========="); String jsonStr = siteService.getOrgDetailData(param); log.info(LOG_PREFIX+ "jsonStr : " + jsonStr); if(jsonStr != null && !"".equals(jsonStr) && !"{}".equals(jsonStr)) { String detailType = StringUtils.getType(jsonStr); if(detailType.equals("URL")) { dType = "detail_2"; responseData.put("dType", dType); String detailUrl = jsonStr; HashMap url = new HashMap<>(); url.put("url", detailUrl); responseData.put("detail", url); } else if(detailType.equals("JSON")) { dType = "detail_3"; responseData.put("dType", dType); JSONObject detailObj = new JSONObject(jsonStr); String gameType = detailObj.optString("gameType"); JSONArray participants = detailObj.optJSONArray("participants"); if (participants != null) { for (int i = 0; i < participants.length(); i++) { // result 객체 가져오기 (없으면 생성) JSONObject participant = participants.optJSONObject(i); JSONObject result = participant.optJSONObject("result"); if (result == null) { result = new JSONObject(); participant.put("result", result); } // link 값 세팅 String raw = "betId="+param.getBetId()+"&gameType="+gameType; String encrypted = AesUtil.encrypt(raw); result.put("link", "https://fst.tx-direction.cc/detailsPage/"+encrypted); } } HashMap detailMap = new Gson().fromJson(detailObj.toString(), HashMap.class); responseData.put("detail", detailMap); } else { responseData.put("dType", dType); responseData.put("detail", "betId is not exist"); } } else { String apiBaseUrl = betInfo.get("vendorApiUrl").toString(); String apiKey = betInfo.get("vendorApiKey").toString(); HashMap apiInfo = new HashMap<>(); apiInfo.put("apiBaseUrl", apiBaseUrl); apiInfo.put("apiKey", apiKey); apiInfo.put("betId", param.getBetId()); if("CASINO".equals(betInfo.get("vendorCetegory").toString())) { isSaveEvoDetail = true; dType = "detail_3"; responseData.put("dType", dType); JSONObject detailObj = thenutService.getBetDetail(LOG_PREFIX, apiInfo); if(detailObj == null) { responseData.put("detail", "betId is not exist"); } else { String gameType = detailObj.optString("gameType"); JSONArray participants = detailObj.optJSONArray("participants"); if (participants != null) { for (int i = 0; i < participants.length(); i++) { // result 객체 가져오기 (없으면 생성) JSONObject participant = participants.optJSONObject(i); JSONObject result = participant.optJSONObject("result"); if (result == null) { result = new JSONObject(); participant.put("result", result); } // link 값 세팅 String raw = "betId="+param.getBetId()+"&gameType="+gameType; String encrypted = AesUtil.encrypt(raw); result.put("link", "https://fst.tx-direction.cc/detailsPage/"+encrypted); } } HashMap detailMap = new Gson().fromJson(detailObj.toString(), HashMap.class); responseData.put("detail", detailMap); saveObj = detailObj; } } else { dType = "detail_2"; responseData.put("dType", dType); String detailUrl = thenutService.getBetDetailUrl(LOG_PREFIX, apiInfo); if(detailUrl == null) { responseData.put("detail", "betId is not exist"); } else { log.info(LOG_PREFIX+ "detailUrl::"+detailUrl); HashMap url = new HashMap<>(); url.put("url", detailUrl); responseData.put("detail", url); } } } } else if("panda".equals(betInfo.get("vendorCode").toString())) { dType = "detail_2"; responseData.put("dType", dType); String apiBaseUrl = betInfo.get("vendorApiUrl").toString(); String apiKey = betInfo.get("vendorApiKey").toString(); String tranId = betInfo.get("uuid").toString(); HashMap apiInfo = new HashMap<>(); apiInfo.put("apiBaseUrl", apiBaseUrl); apiInfo.put("apiKey", apiKey); apiInfo.put("tranId", tranId); String detailUrl = pandaService.getDetail(LOG_PREFIX, apiInfo); if(detailUrl == null) { responseData.put("detail", "betId is not exist"); } else { log.info(LOG_PREFIX+ "detailUrl::"+detailUrl); HashMap url = new HashMap<>(); url.put("url", detailUrl); responseData.put("detail", url); } } else { responseData.put("dType", dType); responseData.put("detail", "betId is not exist"); } } else { responseData.put("dType", dType); responseData.put("detail", "betId is not exist"); } if(saveObj != null || saveObjs != null) { // check detail data if(isSaveEvoDetail) { asyncSiteService.insertEvoDetailProc(LOG_PREFIX, param.getBetId(), saveObj, saveObjs); } } else { log.info(LOG_PREFIX+ "saved detail is null"); } } catch(Exception e) { e.printStackTrace(); log.error("#-API::TRANS::betDetail::Exception1::" +e.toString()); log.error("#-API::TRANS::betDetail::Exception1::" +e.getMessage()); apiResponse.setResultCode("99995"); apiResponse.setResultMessage("token is no valid"); return apiResponse; } apiResponse.setData(responseData); apiResponse.success(); } catch (Exception e) { e.printStackTrace(); log.error("#-API::TRANS::betDetail::Exception2::" +e.toString()); log.error("#-API::TRANS::betDetail::Exception2::" +e.getMessage()); apiResponse.fail(); } return apiResponse; } @ResponseBody @PostMapping(value="/nexusDetail") public ApiResponse nexusDetail(@RequestHeader String token, HttpServletRequest request, @RequestBody BetParam param) throws Exception { ApiResponse apiResponse = new ApiResponse(); try { // apiKey 체크 Site site = siteService.getSiteInfoAPI(request); if(site == null) { apiResponse.setResultCode("9999"); apiResponse.setResultMessage("Authorization apiKey check"); return apiResponse; } if( !( site.getSiteIp()==null || "".equals(site.getSiteIp()) || "3.3.3.3".equals(site.getSiteIp()) || site.getSiteIp().indexOf(IPKit.getIpAddressByRequest(request)) >= 0) ) { log.error("site.getSiteIp("+site.getSiteIp()+"), denied" + IPKit.getIpAddressByRequest(request)); apiResponse.setResultCode("10001"); return apiResponse; } // TO DO 토큰체크 Map responseData = new HashMap(); try { JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfoAdmin(token); final String LOG_PREFIX = "#-nexusDetail::"+tokenInfo.getSid()+"::::"; // 여기서 부터 로직 log.info(LOG_PREFIX+ "BetParam::"+param.toString()); responseData.put("betId", param.getBetId()); HashMap betInfo = transService.getBetInfoByBetId(param); if(betInfo == null) { betInfo = transService.getSiteBetByRefIdFromOld(param); log.info(LOG_PREFIX+ "betInfo_OLD {}", betInfo); } log.info(LOG_PREFIX+ "betINfp {}", betInfo); if(betInfo != null) { if("nexus".equals(betInfo.get("vendorCode").toString()) || "xtreem".equals(betInfo.get("vendorCode").toString())) { log.info(LOG_PREFIX+ "========== BetDetail::Hlink or Xtreem =========="); long siteIdx = (long) betInfo.get("siteIdx"); long memberIdx = (long) betInfo.get("memberIdx"); String trxId = betInfo.get("vendorTranKey").toString(); String apiBaseUrl = betInfo.get("vendorApiUrl").toString(); String apiAgentId = betInfo.get("vendorApiId").toString(); String apiSecretKey = betInfo.get("vendorApiKey").toString(); NexusApiInfo nexusApiInfo = NexusApiInfo.builder() .siteIdx(siteIdx) .memberIdx(memberIdx) .apiBaseUrl(apiBaseUrl) .agentId(apiAgentId) .agentSecretKey(apiSecretKey) .build(); if("CASINO".equals(betInfo.get("vendorCetegory").toString())) { JSONObject responseObj = transService.getNexusBetDetail(LOG_PREFIX, nexusApiInfo, trxId); log.info(LOG_PREFIX+ "responseObj {}", responseObj); int resultCode = responseObj.getInt("code"); if(resultCode == 0) { JSONArray transactions = responseObj.getJSONArray("transactions"); // 금애기치환 JSONObject transaction = transactions.getJSONObject(0); JSONObject detailObj = transaction.getJSONObject("detail"); if(detailObj.isNull("result")) { // resultObj가 존재하지 않으면 상세가 없다는 뜻. HashMap detailMap = new HashMap<>(); detailMap.put("refId", param.getBetId()); int result = transService.deleteEvoDetailNull(detailMap); log.info(LOG_PREFIX+ "deleteEvoDetailNull result::" + result + ", refId::"+param.getBetId()); } else { HashMap detailMap = new HashMap<>(); detailMap.put("refId", param.getBetId()); detailMap.put("orgDetail", detailObj.toString()); detailMap.put("parDetail", null); try { int result = siteService.insertEvoDetail(detailMap); log.info(LOG_PREFIX+ "insertEvoDetail result::" + result + ", refId::"+param.getBetId()); // TODO : 베팅상세 파싱 치환 작업 if(result > 0) { changePaseDetail(LOG_PREFIX, param.getBetId(), detailObj); } result = transService.deleteEvoDetailNull(detailMap); log.info(LOG_PREFIX+ "deleteEvoDetailNull result::" + result + ", refId::"+param.getBetId()); } catch(DataIntegrityViolationException de) { log.error(LOG_PREFIX+ "Duplicate refId::"+param.getBetId()); } } } else { responseData.put("detail", "betId is not exist"); } } } } } catch(Exception e) { e.printStackTrace(); log.error("#-nexusDetail::Exception1::" +e.toString()); log.error("#-nexusDetail::Exception1::" +e.getMessage()); apiResponse.setResultCode("99995"); apiResponse.setResultMessage("token is no valid"); return apiResponse; } apiResponse.setData(responseData); apiResponse.success(); } catch (Exception e) { e.printStackTrace(); log.error("#-nexusDetail::Exception2::" +e.toString()); log.error("#-nexusDetail::Exception2::" +e.getMessage()); apiResponse.fail(); } return apiResponse; } @ResponseBody @GetMapping("/nexusDetails") public ApiResponse nexusDetails(HttpServletRequest request, @RequestHeader String token, @RequestParam String startDate, @RequestParam String endDate) throws Exception { ApiResponse apiResponse = new ApiResponse(); try { Site site = siteService.getSiteInfoAPI(request); if(site == null) { apiResponse.setResultCode("9999"); apiResponse.setResultMessage("Authorization apiKey check"); return apiResponse; } if( !( site.getSiteIp()==null || "".equals(site.getSiteIp()) || "3.3.3.3".equals(site.getSiteIp()) || site.getSiteIp().indexOf(IPKit.getIpAddressByRequest(request)) >= 0) ) { log.error("site.getSiteIp("+site.getSiteIp()+"), denied" + IPKit.getIpAddressByRequest(request)); apiResponse.setResultCode("10001"); return apiResponse; } // TO DO 토큰체크 Map responseData = new HashMap(); try { JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfoAdmin(token); final String LOG_PREFIX = "#-nexusDetails::"+tokenInfo.getSid()+"::::"; if(startDate == null || "".equals(startDate)) { log.error(LOG_PREFIX+ "startDate is not null or empty or blank"); apiResponse.setResultCode("-1"); apiResponse.setResultMessage("startDate is not null or empty or blank"); return apiResponse; } if(endDate == null || "".equals(endDate)) { log.error(LOG_PREFIX+ "endDate is not null or empty or blank"); apiResponse.setResultCode("-2"); apiResponse.setResultMessage("endDate is not null or empty or blank"); return apiResponse; } SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 문자열 -> Date Date date1 = sdf.parse(startDate); Date date2 = sdf.parse(endDate); // Date -> 밀리세컨즈 long timeMil1 = date1.getTime(); long timeMil2 = date2.getTime(); // 비교 long diff = timeMil2 - timeMil1; long diffMin = diff / (1000 * 60); if(diffMin > 60) { log.error(LOG_PREFIX+ "End_Start_60분_초과"); apiResponse.setResultCode("-3"); apiResponse.setResultMessage("End_Start_60분_초과"); return apiResponse; } startDate = startDate+".000"; endDate = endDate+".000"; responseData.put("BF_START_DATE", startDate); responseData.put("BF_END_DATE", endDate); startDate = makeDateStrForUTC(true, makeEdate(startDate)); endDate = makeDateStrForUTC(true, makeEdate(endDate)); String nextReqSDate = endDate; String resultMsg = ""; int totalCnt = 0; int bfDataCnt = 0; int afDataCnt = 0; int nullDataCnt = 0; int duplDataCnt = 0; log.info(LOG_PREFIX+ "Start 시각 : " + startDate); log.info(LOG_PREFIX+ "End 시각 : " + endDate); responseData.put("AF_START_DATE", startDate); responseData.put("AF_END_DATE", endDate); // 여기서 부터 로직 HashMap apiInfo = transService.getApiInfo("nexus"); // asyncTransService.getNexusEvoDetail(LOG_PREFIX, apiInfo, startDate, endDate); log.info(LOG_PREFIX+ "BATCH_INFO::"); log.info(LOG_PREFIX+ "BATCH_INFO::"); log.info(LOG_PREFIX+ "BATCH_INFO:: ============================== S T A R T =============================="); log.info(LOG_PREFIX+ "BATCH_INFO::"); log.info(LOG_PREFIX+ "BATCH_INFO::apiInfo : " + apiInfo.toString()); JSONObject bodyObj = new JSONObject(); bodyObj.put("vendorKey", "evolution-n"); bodyObj.put("sdate", startDate); bodyObj.put("eDate", endDate); bodyObj.put("username", ""); bodyObj.put("limit", 2000); String bodyJson = bodyObj.toString(); log.info(LOG_PREFIX+ "BATCH_INFO::bodyJson :"+bodyJson); HttpHeaders headers = getHeader(LOG_PREFIX, apiInfo, bodyJson); String apiUrl = apiInfo.get("apiBaseUrl").toString() + "/transaction"; UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(apiInfo.get("apiBaseUrl").toString() + "/transaction"); MultiValueMap params = new LinkedMultiValueMap<>(); params.add("vendorKey", "evolution-n"); params.add("sdate", startDate); params.add("eDate", endDate); params.add("username", ""); params.add("limit", 2000); log.info(LOG_PREFIX+ "BATCH_INFO::apiUrl :"+apiUrl); ResponseEntity response = null; try { response = webClient.post() .uri(uriBuilder.toUriString()) .headers(h -> h.addAll(headers)) .bodyValue(params) .retrieve() .toEntity(String.class) .block(); } catch(WebClientResponseException e) { log.error(LOG_PREFIX+ "BATCH_INFO::WebClientResponseException : " + e.getMessage()); log.error(LOG_PREFIX+ "BATCH_INFO::status code : " + e.getStatusCode().value()); log.error(LOG_PREFIX+ "BATCH_INFO::response body : " + e.getResponseBodyAsString()); throw new ApiException("NX001", e.getResponseBodyAsString()); } catch (WebClientRequestException rae) { if(rae.getCause() instanceof io.netty.channel.ConnectTimeoutException) { log.error(LOG_PREFIX+ "BATCH_INFO::ConnectTimeoutException::"+rae.getMessage()); } if(rae.getCause() instanceof io.netty.handler.timeout.ReadTimeoutException) { log.error(LOG_PREFIX+ "BATCH_INFO::SocketTimeoutException::"+rae.getMessage()); } if(rae.getCause() instanceof InterruptedException) { log.error(LOG_PREFIX+ "BATCH_INFO::InterruptedException::"+rae.getMessage()); } throw new ApiException("NX002", rae.getMessage()); } catch (Exception e) { log.error(LOG_PREFIX+ "BATCH_INFO::Exception : " + e.getMessage()); throw new ApiException("NX003", e.getMessage()); } if(response.getStatusCode() == HttpStatus.OK) { JSONObject responseObj = new JSONObject(response.getBody()); JSONArray transactionsArr = responseObj.getJSONArray("transactions"); log.info(LOG_PREFIX+ "BATCH_INFO::transactionsArr.length() : " + transactionsArr.length()); totalCnt = transactionsArr.length(); for(int i=0; i(); detailMap.put("refId", refId); int result = transService.deleteEvoDetailNull(detailMap); log.info(LOG_PREFIX+ "deleteEvoDetailNull result::" + result + ", refId::"+refId); nullDataCnt++; } else { HashMap detailMap = new HashMap<>(); detailMap.put("refId", refId); detailMap.put("orgDetail", detailObj.toString()); detailMap.put("parDetail", null); try { int result = siteService.insertEvoDetail(detailMap); log.info(LOG_PREFIX+ "insertEvoDetail result::" + result + ", refId::"+refId); // TODO : 베팅상세 파싱 치환 작업 if(result > 0) { changePaseDetail(LOG_PREFIX, refId, detailObj); } result = transService.deleteEvoDetailNull(detailMap); log.info(LOG_PREFIX+ "deleteEvoDetailNull result::" + result + ", refId::"+refId); afDataCnt++; } catch(DataIntegrityViolationException de) { //log.error(LOG_PREFIX+ "Duplicate refId::"+refId); duplDataCnt++; } } } } resultMsg = "Success"; } else { resultMsg = "Request Fail::"; log.error(LOG_PREFIX+ "Fail response::"+response.toString()); } responseData.put("resultMsg", resultMsg); responseData.put("totalCnt", totalCnt); responseData.put("bfDataCnt", bfDataCnt); responseData.put("afDataCnt", afDataCnt); responseData.put("nullDataCnt", nullDataCnt); responseData.put("duplDataCnt", duplDataCnt); responseData.put("nextStartDate", nextReqSDate); log.info(LOG_PREFIX+ "BATCH_INFO::"); log.info(LOG_PREFIX+ "BATCH_INFO:: ============================== E N D =============================="); log.info(LOG_PREFIX+ "BATCH_INFO::"); log.info(LOG_PREFIX+ "BATCH_INFO::"); } catch(Exception e) { log.info(e.toString()); e.printStackTrace(); apiResponse.setResultCode("99995"); apiResponse.setResultMessage("token is no valid"); return apiResponse; } apiResponse.setData(responseData); apiResponse.success(); } catch (Exception e) { e.printStackTrace(); apiResponse.fail(); } return apiResponse; } private void changePaseDetail(String LOG_PREFIX, String refId, JSONObject detailObj) { } @ResponseBody @PostMapping(value="/betDetail2") public ApiResponse betDetail2(@RequestHeader String token, HttpServletRequest request, @RequestBody BetParam param) throws Exception { ApiResponse apiResponse = new ApiResponse(); try { // apiKey 체크 Site site = siteService.getSiteInfoAPI(request); if(site == null) { apiResponse.setResultCode("9999"); apiResponse.setResultMessage("Authorization apiKey check"); return apiResponse; } if( !( site.getSiteIp()==null || "".equals(site.getSiteIp()) || "3.3.3.3".equals(site.getSiteIp()) || site.getSiteIp().indexOf(IPKit.getIpAddressByRequest(request)) >= 0) ) { log.error("site.getSiteIp("+site.getSiteIp()+"), denied" + IPKit.getIpAddressByRequest(request)); apiResponse.setResultCode("10001"); return apiResponse; } // TO DO 토큰체크 Map responseData = new HashMap(); try { JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfoAdmin(token); final String LOG_PREFIX = "#-API::TRANS::betDetail::"+tokenInfo.getSid()+"::::"; // 여기서 부터 로직 log.info(LOG_PREFIX+ "BetParam::"+param.toString()); responseData.put("betId", param.getBetId()); String betDetail = siteService.getBetInfo(param); String dType = "detail_0"; if("".equals(betDetail) || betDetail == null) { HashMap betInfo = transService.getBetInfoByBetId(param); if(betInfo == null) { betInfo = transService.getSiteBetByRefIdFromOld(param); log.info(LOG_PREFIX+ "betInfo_OLD {}", betInfo); } log.info(LOG_PREFIX+ "betINfp {}", betInfo); if(betInfo != null) { String category = betInfo.get("vendorCetegory").toString(); log.info(LOG_PREFIX+ "Game category : " + category); if("svendor".equals(betInfo.get("vendorCode").toString())) { String jsonStr = siteService.getOrgDetailData(param); log.info(LOG_PREFIX+ "jsonStr : " + jsonStr); if(jsonStr != null && !"".equals(jsonStr)) { dType = "detail_6"; responseData.put("dType", dType); HashMap detailMap = new Gson().fromJson(jsonStr, HashMap.class); responseData.put("detail", detailMap); } else { JSONObject dataObj = transService.getSvendorDetail(LOG_PREFIX, betInfo); if(dataObj == null) { responseData.put("detail", "betId is not exist"); } else { if(dataObj.has("gameDetail") && !dataObj.isNull("gameDetail")) { String gameType = dataObj.getString("game_type"); if(gameType.equals("slot")) { dType = "detail_2"; responseData.put("dType", dType); String detailUrl = dataObj.getString("gameDetail"); responseData.put("detail", detailUrl); } else { dType = "detail_6"; responseData.put("dType", dType); JSONObject detailObj = dataObj.getJSONObject("gameDetail"); JSONObject parseJsonObj = null; detailObj.put("parseData", parseJsonObj); HashMap detailMap = new Gson().fromJson(detailObj.toString(), HashMap.class); responseData.put("detail", detailMap); } } else { responseData.put("detail", "betId is not exist"); } } } } else if(Integer.parseInt(betInfo.get("vendorIdx").toString())==17 && "tower".equals(betInfo.get("vendorCode").toString())) { dType = "detail_2"; responseData.put("dType", dType); String detailUrl = betInfo.get("vendorApiUrl").toString() +"/v2/detail_url" + "?site_code="+betInfo.get("vendorApiId").toString() + "&user_id="+betInfo.get("siteHex").toString()+betInfo.get("memberId").toString() + "&transaction_id="+betInfo.get("transactionId").toString() + "&vendorCode=pp" + "&gameCode="+betInfo.get("gameIdx").toString(); log.info(LOG_PREFIX+" {}" ,detailUrl); OkHttpClient client = new OkHttpClient().newBuilder().build(); okhttp3.Request requestok2 = new okhttp3.Request.Builder() .url(detailUrl) .method("GET", null)// .addHeader("User-agent", "Mozilla") .addHeader("Authorization", betInfo.get("vendorApiKey").toString()) .build(); okhttp3.Response response = client.newCall(requestok2).execute(); if(response.isSuccessful()){ okhttp3.ResponseBody body = response.body(); String responseString = body.string(); log.info(LOG_PREFIX+ responseString+" {}" ,StringUtils.extractLink(responseString)); HashMap url = new HashMap(); url.put("url", StringUtils.extractLink(responseString)); responseData.put("detail", url); } else { responseData.put("detail", "betId is not exist"); } } else if(Integer.parseInt(betInfo.get("vendorIdx").toString())==83 && "splus".equals(betInfo.get("vendorCode").toString())) { log.info(LOG_PREFIX+ "========== BetDetail::Splus =========="); dType = "detail_1"; responseData.put("dType", dType); HashMap d = new HashMap(); List splusDetail = siteService.getSplusDetailData(param); for(HashMap ttype : splusDetail) { log.info(LOG_PREFIX+ "{}, {}", ttype.get("tranType").toString(), ttype.get("data").toString()); HashMap detailMap = new Gson().fromJson(ttype.get("data").toString(), HashMap.class); d.put(ttype.get("tranType").toString(), detailMap); } responseData.put("detail", d); } else if(Integer.parseInt(betInfo.get("vendorIdx").toString())==17 && "gsoft".equals(betInfo.get("vendorCode").toString())) { log.info(LOG_PREFIX+ "========== BetDetail::Gsoft =========="); dType = "detail_2"; responseData.put("dType", dType); String betId = betInfo.get("refId").toString(); String roundId = transService.getGsoftRoundIdByBetId(betId); OkHttpClient client = new OkHttpClient().newBuilder().build(); okhttp3.Request requestok2 = new okhttp3.Request.Builder() .url("https://api.iblive.net/api/apigamedetail.aspx?gtype=sxprg&roundId="+roundId) .method("GET", null)// .addHeader("User-agent", "Mozilla") .addHeader("Content-Type", "application/json") .build(); okhttp3.Response response = client.newCall(requestok2).execute(); if(response.isSuccessful()){ okhttp3.ResponseBody body = response.body(); String responseString = body.string(); log.info(LOG_PREFIX+ responseString+" {}" ,responseString); org.codehaus.jettison.json.JSONObject resJson = new org.codehaus.jettison.json.JSONObject(responseString); HashMap url = new HashMap(); url.put("url", resJson.getString("link")); responseData.put("detail", url); } } else if("nexus".equals(betInfo.get("vendorCode").toString())) { log.info(LOG_PREFIX+ "========== BetDetail::Hlink or Xtreem =========="); String jsonStr = siteService.getOrgDetailData(param); log.info(LOG_PREFIX+ "jsonStr : " + jsonStr); if(jsonStr != null && !"".equals(jsonStr)) { dType = "detail_3"; responseData.put("dType", dType); HashMap detailMap = new Gson().fromJson(jsonStr, HashMap.class); responseData.put("detail", detailMap); } else { long siteIdx = (long) betInfo.get("siteIdx"); long memberIdx = (long) betInfo.get("memberIdx"); String trxId = betInfo.get("vendorTranKey").toString(); String apiBaseUrl = betInfo.get("vendorApiUrl").toString(); String apiAgentId = betInfo.get("vendorApiId").toString(); String apiSecretKey = betInfo.get("vendorApiKey").toString(); NexusApiInfo nexusApiInfo = NexusApiInfo.builder() .siteIdx(siteIdx) .memberIdx(memberIdx) .apiBaseUrl(apiBaseUrl) .agentId(apiAgentId) .agentSecretKey(apiSecretKey) .build(); if("CASINO".equals(betInfo.get("vendorCetegory").toString())) { dType = "detail_3"; responseData.put("dType", dType); JSONObject detailObj = transService.getNexusBetDetail(LOG_PREFIX, nexusApiInfo, trxId); log.info(LOG_PREFIX+ "detailObj {}", detailObj); int resultCode = detailObj.getInt("code"); if(resultCode == 0) { JSONArray transactions = detailObj.getJSONArray("transactions"); if(transactions.length() > 0) { List> detailMap = new Gson().fromJson(transactions.toString(), List.class); responseData.put("detail", detailMap); } else { responseData.put("detail", "betId is not exist"); } } else { responseData.put("detail", "betId is not exist"); } } else { dType = "detail_2"; responseData.put("dType", dType); JSONObject detailObj = transService.getNexusBetDetailUrl(LOG_PREFIX, nexusApiInfo, trxId); log.info(LOG_PREFIX+ "detailObj::"+detailObj.toString()); int resultCode = detailObj.getInt("code"); if(resultCode == 0) { HashMap detailMap = new HashMap<>(); detailMap.put("url", detailObj.getString("url")); responseData.put("detail", detailMap); } else { responseData.put("detail", "betId is not exist"); } } } } else if("honor".equals(betInfo.get("vendorCode").toString()) || "xhlnk".equals(betInfo.get("vendorCode").toString())) { log.info(LOG_PREFIX+ "========== BetDetail::Honor =========="); dType = "detail_5"; responseData.put("dType", dType); String jsonStr = siteService.getOrgDetailData(param); log.info(LOG_PREFIX+ "jsonStr : " + jsonStr); if(jsonStr != null && !"".equals(jsonStr)) { HashMap detailMap = new Gson().fromJson(jsonStr, HashMap.class); responseData.put("detail", detailMap); } else { responseData.put("detail", "betId is not exist"); } } else if("prime".equals(betInfo.get("vendorCode").toString())) { log.info(LOG_PREFIX+ "========== BetDetail::PRIME =========="); dType = "detail_9"; responseData.put("dType", dType); String jsonStr = siteService.getOrgDetailData(param); log.info(LOG_PREFIX+ "jsonStr : " + jsonStr); if(jsonStr != null && !"".equals(jsonStr)) { HashMap detailMap = new Gson().fromJson(jsonStr, HashMap.class); responseData.put("detail", detailMap); } else { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); String apiKey = "Bearer "+betInfo.get("vendorApiKey").toString(); headers.set("Authorization", apiKey); String detailUrl = betInfo.get("vendorApiUrl").toString() + "/api/getBettingDetails5?"; String detailParam = "referer="+param.getBetId(); detailUrl = detailUrl + detailParam; log.info(LOG_PREFIX+ "PRIME::Detail Url: " + detailUrl); log.info(LOG_PREFIX+ "PRIME::Detail Headers: " + headers.toString()); ResponseEntity response = null; JSONObject resJson = null; try { response = webClient.get() .uri(detailUrl) .headers(h -> h.addAll(headers)) .retrieve() .toEntity(String.class) .block(); } catch(WebClientResponseException e) { log.error(LOG_PREFIX+ "PRIME::Detail WebClientResponseException : " + e.getMessage()); log.error(LOG_PREFIX+ "PRIME::Detail status code : " + e.getStatusCode().value()); log.error(LOG_PREFIX+ "PRIME::Detail response body : " + e.getResponseBodyAsString()); resJson = new JSONObject(e.getResponseBodyAsString()); log.error(LOG_PREFIX+ "PRIME::Detail error : " + resJson.getString("message")); throw new ApiException("P209", resJson.getString("message")); } catch (WebClientRequestException rae) { if(rae.getCause() instanceof io.netty.channel.ConnectTimeoutException) { log.error(LOG_PREFIX+ "PRIME::Detail ConnectTimeoutException::"+rae.getMessage()); } if(rae.getCause() instanceof io.netty.handler.timeout.ReadTimeoutException) { log.error(LOG_PREFIX+ "PRIME::Detail SocketTimeoutException::"+rae.getMessage()); } if(rae.getCause() instanceof InterruptedException) { log.error(LOG_PREFIX+ "PRIME::Detail InterruptedException::"+rae.getMessage()); } throw new ApiException("P210", rae.getMessage()); } catch (Exception e) { log.error(LOG_PREFIX+ "PRIME::Detail Exception : " + e.getMessage()); throw new ApiException("P211", e.getMessage()); } if(response != null && response.getStatusCode() == HttpStatus.OK) { log.info(LOG_PREFIX+ "PRIME::Play response : " + response.getBody()); resJson = new JSONObject(response.getBody()); JSONObject dataObj = resJson; HashMap detailMap = new Gson().fromJson(dataObj.toString(), HashMap.class); responseData.put("detail", detailMap); } else { responseData.put("detail", "betId is not exist"); } } } else { responseData.put("dType", dType); responseData.put("detail", "betId is not exist"); } } else { responseData.put("dType", dType); responseData.put("detail", "betId is not exist"); } } else { responseData.put("dType", dType); log.info(LOG_PREFIX+ "BetDetail::"+betDetail); HashMap detailMap = new Gson().fromJson(betDetail, HashMap.class); responseData.put("detail", detailMap); } } catch(Exception e) { e.printStackTrace(); log.error("#-API::TRANS::betDetail::Exception1::" +e.toString()); log.error("#-API::TRANS::betDetail::Exception1::" +e.getMessage()); apiResponse.setResultCode("99995"); apiResponse.setResultMessage("token is no valid"); return apiResponse; } apiResponse.setData(responseData); apiResponse.success(); } catch (Exception e) { e.printStackTrace(); log.error("#-API::TRANS::betDetail::Exception2::" +e.toString()); log.error("#-API::TRANS::betDetail::Exception2::" +e.getMessage()); apiResponse.fail(); } return apiResponse; } private HttpHeaders getHeader(String LOG_PREFIX, HashMap apiInfo, String bodyJson) { LOG_PREFIX = LOG_PREFIX + "getHeader::"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); headers.setAcceptCharset(Arrays.asList(Charset.forName("UTF-8"))); String hashCode = getHashCode(LOG_PREFIX, bodyJson, apiInfo.get("apiSecretKey").toString()); headers.set("hash", hashCode); headers.set("agent", apiInfo.get("apiAgentId").toString()); log.info(LOG_PREFIX+ "BATCH_INFO::HttpHeaders::"+headers.toString()); return headers; } private String getHashCode(String LOG_PREFIX, String body, String secretKey) { String hashCode = ""; LOG_PREFIX = LOG_PREFIX + "BATCH_INFO::getHashCode::"; try { // Json String Body + Secret Key String result = body + secretKey; // String result = "{\"username\":\"057007mptest01\",\"nickname\":\"007mptest01\",\"siteUsername\":\"057007mptest01\"}"; log.info(LOG_PREFIX+ "BATCH_INFO::Body + Secret Key::"+result); // SHA-256 Hash make MessageDigest digestObj = MessageDigest.getInstance("SHA-256"); byte[] hash_data = digestObj.digest(result.getBytes("UTF-8")); // Base64 encoding hashCode = Base64.getEncoder().encodeToString(hash_data); log.info(LOG_PREFIX+ "BATCH_INFO::hashCode::"+hashCode); } catch(Exception e) { log.error(LOG_PREFIX+ "BATCH_INFO::#-NexusService::getHashCode::Exception::"+e.getMessage()); } return hashCode; } private String makeDateStrForUTC(boolean flag, String strDate) { String result = ""; if(flag) { // 2022-05-01 00:00:00.000 => 2022-05-01T00:00:00.000Z result = strDate.replace(" ", "T") + "Z"; } else { // 2022-05-01T00:00:00.000Z => 2022-05-01 00:00:00.000 result = strDate.replace("T", " ").replace("Z", ""); } return result; } private String makeEdate(String paramDate) { // TODO Auto-generated method stub String eDate = ""; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); try { Date date = sdf.parse(paramDate); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.HOUR_OF_DAY, -9); Date date2 = calendar.getTime(); eDate = sdf.format(date2); } catch(Exception e) { log.error(e.getMessage()); } return eDate; } }