Skip to content

Commit b9734c9

Browse files
authored
Fix 실시간 환율 정보 api 수정 (#121)
- /exchange/live api 1개에서 12개의 통화 한꺼번에 보내주는 것으로 수정
1 parent c384c28 commit b9734c9

7 files changed

Lines changed: 80 additions & 35 deletions

File tree

src/main/java/org/scoula/domain/exchange/controller/ExchangeRateController.java

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -81,25 +81,14 @@ public SuccessResponse<List<ExchangeMonthlyResponse>> calculateExchangeMonthlyGr
8181
);
8282
}
8383

84-
/**
85-
* 단일 통화 환율 조회
86-
*
87-
* @param currency 통화 코드 (USD, JPY 등)
88-
* @return 환율 정보
89-
*/
9084
@ApiOperation(
9185
value = "실시간 환율 조회",
9286
notes = "특정 통화에 대한 실시간 환율 정보를 조회합니다. "
93-
+ "예시: /exchange/USD, /exchange/EUR 등"
87+
+ "예시: /exchange/USD, /exchange/EUR 등"
9488
)
95-
@GetMapping("/live/{currency}")
96-
public SuccessResponse<ExchangeLiveResponse> getExchangeRate(HttpServletRequest request,@PathVariable String currency) {
97-
98-
ExchangeLiveResponse latestExchangeRate = exchangeRateQuickService.getLatestExchangeRate(request,
99-
currency.toUpperCase());
100-
101-
return SuccessResponse.ok(latestExchangeRate);
102-
89+
@GetMapping("/live")
90+
public SuccessResponse<List<ExchangeLiveResponse>> getExchangeRate(HttpServletRequest request) {
91+
return SuccessResponse.ok(exchangeRateQuickService.getLatestExchangeRate(request));
10392
}
10493

10594

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.scoula.domain.exchange.dto.response;
2+
3+
import java.math.BigDecimal;
4+
5+
public class ExchangeConcurrencyList {
6+
private String cuncurrency;
7+
private BigDecimal exchangeRate;
8+
}
Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
11
package org.scoula.domain.exchange.dto.response;
22

3+
import java.math.BigDecimal;
4+
5+
import io.swagger.annotations.ApiModel;
6+
import io.swagger.annotations.ApiModelProperty;
37
import lombok.AllArgsConstructor;
8+
import lombok.Builder;
49
import lombok.Data;
510

6-
@AllArgsConstructor
711
@Data
12+
@Builder
13+
@AllArgsConstructor
14+
@ApiModel(description = "실시간 환율 응답 DTO")
815
public class ExchangeLiveResponse {
9-
public String text;
16+
@ApiModelProperty(value = "환율 통황", example = "USD")
17+
private String currency;
18+
@ApiModelProperty(value = "환율 값", example = "1300.50")
19+
private BigDecimal exchangeRate;
20+
1021
}

src/main/java/org/scoula/domain/exchange/mapper/ExchangeRateMapper.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.List;
44

5+
import org.scoula.domain.exchange.dto.response.ExchangeLiveResponse;
56
import org.scoula.domain.exchange.entity.ExchangeRate;
67
import org.apache.ibatis.annotations.Param;
78

@@ -33,7 +34,6 @@ ExchangeRate findByBankAndTargetCurrencyAndType(
3334
* 최신 환율 조회 (가장 최근 날짜)
3435
*/
3536
List<ExchangeRate> findLatestRates(
36-
@Param("targetCurrency") String targetCurrency,
3737
@Param("type") String type
3838
);
3939

@@ -45,4 +45,9 @@ ExchangeRate findUsdExchangeRate(
4545
@Param("bankName") String bankName
4646
);
4747

48+
/**
49+
* 실시간 환율 조회
50+
* @return 실시간 환율 리스트
51+
*/
52+
List<ExchangeLiveResponse> getExchangeLiveList();
4853
}

src/main/java/org/scoula/domain/exchange/service/ExchangeRateQuickService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.scoula.domain.exchange.service;
22

3+
import java.util.List;
4+
35
import javax.servlet.http.HttpServletRequest;
46

57
import org.scoula.domain.exchange.dto.request.ExchangeBankRequest;
@@ -16,5 +18,5 @@ public interface ExchangeRateQuickService {
1618

1719
ExchangeQuickResponse calculateExchangeQuick(ExchangeQuickRequest request, HttpServletRequest httpServletRequest);
1820

19-
ExchangeLiveResponse getLatestExchangeRate(HttpServletRequest request,String upperCase);
21+
List<ExchangeLiveResponse> getLatestExchangeRate(HttpServletRequest request);
2022
}

src/main/java/org/scoula/domain/exchange/service/ExchangeRateQuickServiceImpl.java

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package org.scoula.domain.exchange.service;
22

3-
import static org.scoula.domain.member.exception.MemberErrorCode.*;
4-
import static org.scoula.domain.wallet.exception.WalletErrorCode.*;
5-
63
import java.math.BigDecimal;
74
import java.math.RoundingMode;
85
import java.text.DecimalFormat;
@@ -13,7 +10,6 @@
1310

1411
import javax.servlet.http.HttpServletRequest;
1512

16-
import org.scoula.domain.account.exception.AccountErrorCode;
1713
import org.scoula.domain.exchange.dto.request.ExchangeQuickRequest;
1814
import org.scoula.domain.exchange.dto.response.ExchangeLiveResponse;
1915
import org.scoula.domain.exchange.dto.response.exchangeResponse.BankRateInfo;
@@ -222,12 +218,12 @@ public ExchangeQuickResponse calculateExchangeQuick(ExchangeQuickRequest request
222218
}
223219

224220
@Override
225-
public ExchangeLiveResponse getLatestExchangeRate(HttpServletRequest request, String upperCase) {
221+
public List<ExchangeLiveResponse> getLatestExchangeRate(HttpServletRequest request) {
226222

227223
// 기준 통화(KRW)에서 목표 통화로의 환율 조회
228-
ExchangeRate baseRate = exchangeRateMapper.findLatestExchangeRate("하나은행", "BASE", upperCase);
224+
List<ExchangeLiveResponse> baseExchangeRates = exchangeRateMapper.getExchangeLiveList();
229225

230-
if (baseRate == null) {
226+
if (baseExchangeRates.isEmpty()) {
231227
throw new CustomException(ExchangeErrorCode.EXCHANGE_NOT_FOUND, LogLevel.WARNING, null,
232228
Common.builder().deviceInfo(request.getHeader("host-agent"))
233229
.srcIp(request.getRemoteAddr())
@@ -237,15 +233,13 @@ public ExchangeLiveResponse getLatestExchangeRate(HttpServletRequest request, St
237233
.build());
238234
}
239235

240-
BigDecimal exchangeValue = baseRate.getExchangeValue();
241-
String formattedRate = rateFormatter.format(exchangeValue);
242-
243-
if (upperCase.equals("JPY") || upperCase.equals("VND")) {
244-
formattedRate = String.format("%s %s (100)", formattedRate, upperCase);
245-
} else {
246-
formattedRate = String.format("%s %s", formattedRate, upperCase);
236+
for (ExchangeLiveResponse baseExchangeRate : baseExchangeRates) {
237+
// 환율값 소수 2자리에서 반올림
238+
baseExchangeRate.setExchangeRate(
239+
baseExchangeRate.getExchangeRate().setScale(2, RoundingMode.HALF_UP));
247240
}
248-
return new ExchangeLiveResponse(formattedRate);
241+
242+
return baseExchangeRates;
249243
}
250244

251245
/**

src/main/resources/org/scoula/domain/exchange/mapper/ExchangeRateMapper.xml

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
AND exchange_date = (
6969
SELECT MAX(exchange_date)
7070
FROM exchange_rate
71-
WHERE target_exchange = #{targetCurrency} AND type = #{type}
71+
WHERE type = BASE
7272
)
7373
ORDER BY exchange_value ASC
7474
</select>
@@ -85,4 +85,40 @@
8585
LIMIT 1
8686
</select>
8787

88+
<!-- 방법 3: JOIN 사용 (성능 최적화) -->
89+
<select id="getExchangeLiveList" resultType="org.scoula.domain.exchange.dto.response.ExchangeLiveResponse">
90+
SELECT e1.target_exchange AS currency,
91+
e1.exchange_value AS exchangeRate
92+
FROM exchange_rate e1
93+
INNER JOIN (
94+
SELECT target_exchange,
95+
MAX(created_at) as max_created_at
96+
FROM exchange_rate
97+
WHERE base_exchange = 'KRW'
98+
AND bank_name = '국민은행'
99+
AND type = 'BASE'
100+
AND target_exchange IN ('USD', 'JPY', 'EUR', 'GBP', 'CAD', 'HKD',
101+
'CNY', 'THB', 'IDR', 'VND', 'RUB', 'MYR')
102+
GROUP BY target_exchange
103+
) e2 ON e1.target_exchange = e2.target_exchange
104+
AND e1.created_at = e2.max_created_at
105+
WHERE e1.base_exchange = 'KRW'
106+
AND e1.bank_name = '국민은행'
107+
AND e1.type = 'BASE'
108+
ORDER BY CASE e1.target_exchange
109+
WHEN 'USD' THEN 1
110+
WHEN 'JPY' THEN 2
111+
WHEN 'EUR' THEN 3
112+
WHEN 'GBP' THEN 4
113+
WHEN 'CAD' THEN 5
114+
WHEN 'HKD' THEN 6
115+
WHEN 'CNY' THEN 7
116+
WHEN 'THB' THEN 8
117+
WHEN 'IDR' THEN 9
118+
WHEN 'VND' THEN 10
119+
WHEN 'RUB' THEN 11
120+
WHEN 'MYR' THEN 12
121+
END
122+
</select>
123+
88124
</mapper>

0 commit comments

Comments
 (0)