From 1e132115656d95287cfbbbcdb2db367ec33b0085 Mon Sep 17 00:00:00 2001 From: bbbang105 <2018111366@dgu.ac.kr> Date: Fri, 14 Jun 2024 21:01:39 +0900 Subject: [PATCH] =?UTF-8?q?#42=20[refactor]=20:=20=ED=98=84=EC=9E=AC?= =?UTF-8?q?=EA=B0=80=20=EA=B8=B0=EC=A4=80=EC=9C=BC=EB=A1=9C=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/service/DashBoardServiceImpl.java | 136 ++++++++++-------- 1 file changed, 79 insertions(+), 57 deletions(-) diff --git a/backend/src/main/java/org/dgu/backend/service/DashBoardServiceImpl.java b/backend/src/main/java/org/dgu/backend/service/DashBoardServiceImpl.java index ef5b7dc..04a8dd0 100644 --- a/backend/src/main/java/org/dgu/backend/service/DashBoardServiceImpl.java +++ b/backend/src/main/java/org/dgu/backend/service/DashBoardServiceImpl.java @@ -14,6 +14,7 @@ import org.dgu.backend.repository.UpbitKeyRepository; import org.dgu.backend.repository.UserCoinRepository; import org.dgu.backend.util.JwtUtil; +import org.springframework.beans.factory.annotation.Value; import org.springframework.http.*; import org.springframework.stereotype.Service; import org.springframework.web.client.HttpClientErrorException; @@ -30,6 +31,10 @@ @RequiredArgsConstructor @Slf4j public class DashBoardServiceImpl implements DashBoardService { + @Value("${upbit.url.account}") + private String UPBIT_URL_ACCOUNT; + @Value("${upbit.url.ticker}") + private String UPBIT_URL_TICKER; private final RestTemplate restTemplate; private final JwtUtil jwtUtil; private final UpbitKeyRepository upbitKeyRepository; @@ -39,18 +44,9 @@ public class DashBoardServiceImpl implements DashBoardService { @Override public DashBoardDto.UserAccountResponse getUserAccount(String authorizationHeader) { User user = jwtUtil.getUserFromHeader(authorizationHeader); - UpbitKey upbitKey = upbitKeyRepository.findByUser(user); - if (Objects.isNull(upbitKey)) { - throw new UpbitException(UpbitErrorResult.NOT_FOUND_UPBIT_KEY); - } + UpbitDto.Account[] accounts = getUpbitAccounts(user); - String token = jwtUtil.generateUpbitToken(upbitKey); - String url = "https://api.upbit.com/v1/accounts"; - UpbitDto.Account[] responseBody = getUserAccountsAtUpbit(url, token); - if (Objects.isNull(responseBody)) { - throw new UpbitException(UpbitErrorResult.FAIL_ACCESS_USER_ACCOUNT); - } - BigDecimal accountSum = getAccountSum(responseBody); + BigDecimal accountSum = getAccountSum(accounts); return DashBoardDto.UserAccountResponse.builder() .account(accountSum.setScale(3, RoundingMode.HALF_UP)) @@ -61,86 +57,109 @@ public DashBoardDto.UserAccountResponse getUserAccount(String authorizationHeade @Override public List getUserCoins(String authorizationHeader) { User user = jwtUtil.getUserFromHeader(authorizationHeader); - UpbitKey upbitKey = upbitKeyRepository.findByUser(user); - if (Objects.isNull(upbitKey)) { - throw new UpbitException(UpbitErrorResult.NOT_FOUND_UPBIT_KEY); - } + UpbitDto.Account[] accounts = getUpbitAccounts(user); - String token = jwtUtil.generateUpbitToken(upbitKey); - String url = "https://api.upbit.com/v1/accounts"; - UpbitDto.Account[] responseBody = getUserAccountsAtUpbit(url, token); - if (Objects.isNull(responseBody)) { - throw new UpbitException(UpbitErrorResult.FAIL_ACCESS_USER_ACCOUNT); - } + return processUserCoins(accounts, user); + } + // 유저 보유 코인을 처리하는 메서드 + private List processUserCoins(UpbitDto.Account[] accounts, User user) { List userCoinResponses = new ArrayList<>(); - for (UpbitDto.Account account : responseBody) { + for (UpbitDto.Account account : accounts) { String coinName = account.getCurrency(); - if (coinName.equals("KRW")) { - continue; - } - - UserCoin userCoin = userCoinRepository.findByCoinName(account.getCurrency()); - boolean isIncrease = false; - if (!Objects.isNull(userCoin)) { - isIncrease = isBalanceIncreased(account, userCoin); - userCoinRepository.delete(userCoin); + // 현금은 제외 + if (!coinName.equals("KRW")) { + userCoinResponses.add(processSingleCoin(account, user, coinName)); } + } + return userCoinResponses; + } - DashBoardDto.UserCoinResponse userCoinResponse = DashBoardDto.UserCoinResponse.builder() - .coinName(coinName) - .balance(account.getBalance()) - .price(account.getAvgBuyPrice()) - .isIncrease(isIncrease) - .build(); - userCoinResponses.add(userCoinResponse); - - userCoinRepository.save(userCoinResponse.to(user)); + // 단일 코인 정보를 처리하는 메서드 + private DashBoardDto.UserCoinResponse processSingleCoin(UpbitDto.Account account, User user, String coinName) { + coinName = "KRW-" + coinName; + UserCoin userCoin = userCoinRepository.findByCoinName(coinName); + UpbitDto.Ticker[] ticker = getTickerPriceAtUpbit(UPBIT_URL_TICKER + coinName); + BigDecimal curPrice = BigDecimal.valueOf(ticker[0].getPrice()); + BigDecimal curCoinCount = account.getCoinCount(); + boolean isIncrease = false; + BigDecimal rate = BigDecimal.ZERO; + if (!Objects.isNull(userCoin)) { + rate = getCoinPriceIncreaseRate(userCoin, curPrice, curCoinCount); + isIncrease = rate.compareTo(BigDecimal.ZERO) > 0; + userCoinRepository.delete(userCoin); } - return userCoinResponses; + DashBoardDto.UserCoinResponse userCoinResponse = DashBoardDto.UserCoinResponse.builder() + .coinName(coinName) + .coinCount(curCoinCount) + .price(curPrice) + .balance(curPrice.multiply(curCoinCount).setScale(4, RoundingMode.HALF_UP)) + .isIncrease(isIncrease) + .rate(rate) + .build(); + + userCoinRepository.save(userCoinResponse.to(user)); + return userCoinResponse; } // 대표 코인 5개 정보를 반환하는 메서드 @Override public List getRepresentativeCoins() { - String url = "https://api.upbit.com/v1/ticker?markets="; List representativeCoinResponses = new ArrayList<>(); for (Coin coin : Coin.values()) { - UpbitDto.Ticker[] responseBody = getTickerPriceAtUpbit(url + coin.getMarketName()); - if (Objects.isNull(responseBody[0])) { - throw new UpbitException(UpbitErrorResult.FAIL_ACCESS_COIN_INFO); - } - representativeCoinResponses.add(DashBoardDto.RepresentativeCoinResponse.of(responseBody[0], coin.getKoreanName())); + UpbitDto.Ticker[] ticker = getTickerPriceAtUpbit(UPBIT_URL_TICKER + coin.getMarketName()); + representativeCoinResponses.add(DashBoardDto.RepresentativeCoinResponse.of(ticker[0], coin.getKoreanName())); } return representativeCoinResponses; } // 현재 업비트 잔고를 계산하는 메서드 - private BigDecimal getAccountSum(UpbitDto.Account[] responseBody) { + private BigDecimal getAccountSum(UpbitDto.Account[] accounts) { BigDecimal accountSum = BigDecimal.ZERO; - for (UpbitDto.Account account : responseBody) { + for (UpbitDto.Account account : accounts) { if (account.getCurrency().equals("KRW")) { - accountSum = accountSum.add(account.getBalance()); + accountSum = accountSum.add(account.getCoinCount()); } else { - BigDecimal balance = account.getBalance(); - BigDecimal avgBuyPrice = account.getAvgBuyPrice(); - accountSum = accountSum.add(balance.multiply(avgBuyPrice)); + // 현재가를 가져옴 + String coinName = "KRW-" + account.getCurrency(); + UpbitDto.Ticker[] ticker = getTickerPriceAtUpbit(UPBIT_URL_TICKER + coinName); + BigDecimal curPrice = BigDecimal.valueOf(ticker[0].getPrice()); + BigDecimal userCoinCount = account.getCoinCount(); + accountSum = accountSum.add(curPrice.multiply(userCoinCount)); } } return accountSum; } - // 코인 가격 상승 여부를 판단하는 메서드 - private boolean isBalanceIncreased(UpbitDto.Account account, UserCoin userCoin) { + // 기존 대비 코인 가격 상승률을 계산하는 메서드 + private BigDecimal getCoinPriceIncreaseRate(UserCoin userCoin, BigDecimal curPrice, BigDecimal curCoinCount) { + BigDecimal pastValue = userCoin.getPrice().multiply(userCoin.getCoinCount()); + BigDecimal currentValue = curPrice.multiply(curCoinCount); - return account.getBalance().compareTo(userCoin.getBalance()) > 0; + return currentValue.subtract(pastValue) + .divide(pastValue, 6, RoundingMode.HALF_UP) + .multiply(new BigDecimal("100")); + } + + // 유저 업비트 계좌 정보를 조회하는 메서드 + private UpbitDto.Account[] getUpbitAccounts(User user) { + UpbitKey upbitKey = upbitKeyRepository.findByUser(user); + if (Objects.isNull(upbitKey)) { + throw new UpbitException(UpbitErrorResult.NOT_FOUND_UPBIT_KEY); + } + + String token = jwtUtil.generateUpbitToken(upbitKey); + UpbitDto.Account[] responseBody = getUserAccountsAtUpbit(UPBIT_URL_ACCOUNT, token); + if (Objects.isNull(responseBody)) { + throw new UpbitException(UpbitErrorResult.FAIL_ACCESS_USER_ACCOUNT); + } + return responseBody; } // 전체 계좌 조회 업비트 API와 통신하는 메서드 private UpbitDto.Account[] getUserAccountsAtUpbit(String url, String token) { - String authenticationToken = "Bearer " + token; HttpHeaders headers = new HttpHeaders(); headers.set("accept", MediaType.APPLICATION_JSON_VALUE); @@ -175,6 +194,9 @@ private UpbitDto.Ticker[] getTickerPriceAtUpbit(String url) { new HttpEntity<>(headers), UpbitDto.Ticker[].class ); + if (Objects.isNull(responseEntity.getBody()[0])) { + throw new UpbitException(UpbitErrorResult.FAIL_ACCESS_COIN_INFO); + } return responseEntity.getBody(); } catch (HttpClientErrorException e) { if (e.getStatusCode() == HttpStatus.UNAUTHORIZED && e.getResponseBodyAsString().contains("no_authorization_ip")) {