Skip to content

Commit 0ee6b1e

Browse files
authored
Merge pull request #69 from nimuy99/fix/3-chartList
#24 Fix: 대시보드 트렌드 api - 순위 방향(rankChangeDirection) 필드 반영
2 parents 87dfe5f + 8acc2bc commit 0ee6b1e

File tree

7 files changed

+79
-28
lines changed

7 files changed

+79
-28
lines changed

src/main/java/com/memesphere/domain/dashboard/controller/DashboardController.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,10 @@ public ApiResponse<DashboardOverviewResponse> getOverview() {
6060
- "volume": 밈코인 거래량(확인용)
6161
- "price": 밈코인 현재가
6262
- "priceChange": 가격 변화량
63-
- "changeAbsolute": 가격 변화량(절대값)
64-
- "changeDirection": 밈코인 상승(up, 0 이상)/하락(down)
65-
- "changeRate": 가격 변화율
63+
- "priceChangeAbsolute": 가격 변화량(절대값)
64+
- "priceChangeDirection": 밈코인 상승(up, 0 이상)/하락(down)
65+
- "priceChangeRate": 가격 변화율
66+
- "rankChangeDirection": 순위 상승(up, 0 이상)/하락(down)
6667
```""")
6768
public ApiResponse<DashboardTrendListResponse> getTrendList() {
6869
return ApiResponse.onSuccess(dashboardQueryService.getTrendList());

src/main/java/com/memesphere/domain/dashboard/converter/DashboardConverter.java

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
import com.memesphere.domain.dashboard.dto.response.DashboardTrendListResponse;
77
import com.memesphere.domain.dashboard.dto.response.DashboardTrendResponse;
88

9+
910
import java.math.BigDecimal;
1011
import java.time.LocalDateTime;
12+
import java.util.ArrayList;
1113
import java.util.List;
12-
import java.util.stream.Collectors;
1314

1415
public class DashboardConverter {
1516
// ** 총 거래량 및 총 개수 응답 형식 ** //
@@ -21,20 +22,46 @@ public static DashboardOverviewResponse toOverView(BigDecimal totalVolume, Long
2122
}
2223

2324
// ** 트렌드 응답 형식 ** //
24-
public static DashboardTrendListResponse toTrendList(LocalDateTime recordedTime, List<ChartData> dataList) {
25-
List<DashboardTrendResponse> trendList = dataList.stream()
26-
.map(data -> toTrend(data))
27-
.collect(Collectors.toList());
25+
public static DashboardTrendListResponse toTrendList(LocalDateTime recordedTime,
26+
List<ChartData> dataList,
27+
List<MemeCoin> prevCoinList) {
28+
29+
List<DashboardTrendResponse> trendList = new ArrayList<>();
30+
31+
// 현재 top5에 들지 않는 밈코인 순위 처리
32+
List<MemeCoin> currCoinList = dataList.stream().map(ChartData::getMemeCoin).toList();
33+
for (MemeCoin prevCoin : prevCoinList) {
34+
if (!currCoinList.contains(prevCoin)) prevCoin.updateRank(null);
35+
}
36+
37+
38+
// 현재 top5 밈코인
39+
for (int i = 0; i < 5; i++) {
40+
ChartData data = dataList.get(i);
41+
DashboardTrendResponse trend = toTrend(data, prevCoinList, i + 1);
42+
trendList.add(trend);
43+
}
2844

2945
return DashboardTrendListResponse.builder()
3046
.timestamp(recordedTime)
3147
.trendList(trendList)
3248
.build();
3349
}
3450

35-
public static DashboardTrendResponse toTrend(ChartData data) {
51+
public static DashboardTrendResponse toTrend(ChartData data,
52+
List<MemeCoin> prevCoinList,
53+
Integer currRank) {
3654
MemeCoin memeCoin = data.getMemeCoin();
3755

56+
// 이전에 기록된 밈코인 순위와 현재 밈코인 순위 변화
57+
// prevRank == -1 : 새로 등록 순위
58+
Integer prevRank = prevCoinList.indexOf(memeCoin);
59+
prevRank = (prevRank == -1) ? null : prevRank + 1;
60+
String rankDirection = (prevRank == null || currRank <= prevRank) ? "up" : "down";
61+
62+
// 순위 업데이트
63+
memeCoin.updateRank(currRank);
64+
3865
return DashboardTrendResponse.builder()
3966
.coinId(memeCoin.getId())
4067
.image(memeCoin.getImage())
@@ -43,9 +70,10 @@ public static DashboardTrendResponse toTrend(ChartData data) {
4370
.volume(data.getVolume())
4471
.price(data.getPrice())
4572
.priceChange(data.getPriceChange())
46-
.changeAbsolute(data.getPriceChange().abs())
47-
.changeDirection(data.getPriceChangeRate().compareTo(BigDecimal.ZERO) < 0 ? "down" : "up")
48-
.changeRate(data.getPriceChangeRate())
73+
.priceChangeAbsolute(data.getPriceChange().abs())
74+
.priceChangeDirection(data.getPriceChangeRate().compareTo(BigDecimal.ZERO) < 0 ? "down" : "up")
75+
.priceChangeRate(data.getPriceChangeRate())
76+
.rankChangeDirection(rankDirection)
4977
.build();
5078
}
5179
}

src/main/java/com/memesphere/domain/dashboard/dto/response/DashboardTrendResponse.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,15 @@ public class DashboardTrendResponse {
3030
@Schema(description = "가격 변화량", example = "-0.03")
3131
private BigDecimal priceChange;
3232

33-
@Schema(description = "변화량 절대값", example = "0.03")
34-
private BigDecimal changeAbsolute;
33+
@Schema(description = "가격 변화량 절대값", example = "0.03")
34+
private BigDecimal priceChangeAbsolute;
3535

36-
@Schema(description = "변화 방향", example = "down")
37-
private String changeDirection;
36+
@Schema(description = "가격 변화 방향", example = "down")
37+
private String priceChangeDirection;
3838

39-
@Schema(description = "변화율", example = "-6.35")
40-
private BigDecimal changeRate;
39+
@Schema(description = "가격 변화율", example = "-6.35")
40+
private BigDecimal priceChangeRate;
41+
42+
@Schema(description = "순위 변화 방향", example = "down")
43+
private String rankChangeDirection;
4144
}

src/main/java/com/memesphere/domain/dashboard/service/DashboardQueryServiceImpl.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package com.memesphere.domain.dashboard.service;
22

3+
import com.memesphere.domain.chartdata.entity.ChartData;
34
import com.memesphere.domain.collection.service.CollectionQueryService;
45
import com.memesphere.domain.dashboard.converter.DashboardConverter;
56
import com.memesphere.domain.dashboard.dto.response.DashboardOverviewResponse;
6-
import com.memesphere.domain.chartdata.entity.ChartData;
77
import com.memesphere.domain.dashboard.dto.response.DashboardTrendListResponse;
88
import com.memesphere.domain.chartdata.repository.ChartDataRepository;
9-
import com.memesphere.domain.user.entity.User;
109
import com.memesphere.domain.user.repository.UserRepository;
1110
import com.memesphere.global.apipayload.code.status.ErrorStatus;
1211
import com.memesphere.global.apipayload.exception.GeneralException;
@@ -30,16 +29,15 @@
3029
import java.util.List;
3130

3231
@Service
33-
@Transactional(readOnly = true)
3432
@RequiredArgsConstructor
3533
public class DashboardQueryServiceImpl implements DashboardQueryService {
36-
private final UserRepository userRepository;
3734
private final MemeCoinRepository memeCoinRepository;
3835
private final ChartDataRepository chartDataRepository;
3936
private final CollectionQueryService collectionQueryService;
4037

4138
// ** 총 거래량 및 총 개수 ** //
4239
@Override
40+
@Transactional(readOnly = true)
4341
public DashboardOverviewResponse getOverview() {
4442
// 등록된 모든 밈코인의 총 거래량
4543
BigDecimal totalVolume = chartDataRepository.findTotalVolume();
@@ -52,18 +50,25 @@ public DashboardOverviewResponse getOverview() {
5250

5351
// ** 트렌드 ** //
5452
@Override
53+
@Transactional
5554
public DashboardTrendListResponse getTrendList() {
56-
// 거래량 top5 밈코인-차트데이터
55+
// 이전에 기록된 top5 밈코인
56+
List<MemeCoin> prevCoinList = memeCoinRepository.findTop5OrderByRank();
57+
58+
// 최신 거래량 top5 밈코인-차트데이터
5759
List<ChartData> dataList = chartDataRepository.findTop5OrderByVolumeDesc();
5860

5961
// 코인 아이디 1 기준 기록 시간
6062
LocalDateTime recordedTime = chartDataRepository.findRecordedTimeByCoinId1();
6163

62-
return DashboardConverter.toTrendList(recordedTime, dataList);
64+
DashboardTrendListResponse trendList = DashboardConverter.toTrendList(recordedTime, dataList, prevCoinList);
65+
memeCoinRepository.saveAll(prevCoinList); // 순위 업데이트
66+
return trendList;
6367
}
6468

6569
// ** 차트 ** //
6670
@Override
71+
@Transactional(readOnly = true)
6772
public SearchPageResponse getChartPage(Long userId, ViewType viewType, SortType sortType, Integer pageNumber) {
6873

6974
// 로그인 x -> 콜렉션 빈 리스트
@@ -87,7 +92,7 @@ public SearchPageResponse getChartPage(Long userId, ViewType viewType, SortType
8792
Pageable pageable = PageRequest.of(pageNumber, pageSize, Sort.by(Sort.Direction.DESC, sortField));
8893
Page<MemeCoin> coinPage = memeCoinRepository.findAllLatestChartData(pageable);
8994

90-
// null 체크 후 예외 처리}
95+
// null 체크 후 예외 처리
9196
return SearchConverter.toSearchPageDTO(coinPage, viewType, userCollectionIds);
9297
}
9398
}

src/main/java/com/memesphere/domain/memecoin/entity/MemeCoin.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import lombok.*;
1010
import org.hibernate.annotations.DynamicInsert;
1111
import org.hibernate.annotations.DynamicUpdate;
12+
import org.springframework.transaction.annotation.Transactional;
1213

1314
import java.util.ArrayList;
1415
import java.util.List;
@@ -43,6 +44,9 @@ public class MemeCoin extends BaseEntity {
4344
@Column
4445
private boolean collectionActive;
4546

47+
@Column
48+
private Integer trendRank;
49+
4650
@ElementCollection
4751
@CollectionTable(name = "CoinKeywords", joinColumns = @JoinColumn(name = "coin_id"))
4852
@Column(name = "keyword")
@@ -63,5 +67,11 @@ public class MemeCoin extends BaseEntity {
6367

6468
@OneToMany(mappedBy = "memeCoin", cascade = CascadeType.ALL, orphanRemoval = true)
6569
@OrderBy("recordedTime DESC")
70+
@Builder.Default
6671
private List<ChartData> chartDataList = new ArrayList<>();
72+
73+
@Transactional
74+
public void updateRank(Integer trendRank) {
75+
this.trendRank = trendRank;
76+
}
6777
}

src/main/java/com/memesphere/domain/memecoin/repository/MemeCoinRepository.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33
import com.memesphere.domain.memecoin.entity.MemeCoin;
44
import org.springframework.data.domain.Page;
55
import org.springframework.data.domain.Pageable;
6-
import org.springframework.data.jpa.repository.EntityGraph;
76
import org.springframework.data.jpa.repository.JpaRepository;
87
import org.springframework.data.jpa.repository.Query;
98
import org.springframework.data.repository.query.Param;
10-
import org.springframework.lang.NonNull;
119

10+
import java.util.List;
1211
import java.util.Optional;
1312

1413
public interface MemeCoinRepository extends JpaRepository<MemeCoin, Long> {
@@ -34,4 +33,8 @@ Page<MemeCoin> findWithLatestChartDataSorted(
3433
Page<MemeCoin> findAllLatestChartData( Pageable pageable);
3534

3635
Optional<MemeCoin> findByName(String name);
36+
37+
@Query("SELECT m FROM MemeCoin m " +
38+
"WHERE m.trendRank IS NOT NULL ORDER BY m.trendRank ASC")
39+
List<MemeCoin> findTop5OrderByRank();
3740
}

src/main/java/com/memesphere/global/config/SwaggerConfig.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ public OpenAPI MemeSphereAPI() {
3434
.bearerFormat("JWT"));
3535

3636
return new OpenAPI()
37-
.addServersItem(new Server().url("https://15.164.103.195.nip.io")) // 기본 URL을 nip.io 도메인으로 설정
37+
// .addServersItem(new Server().url("https://15.164.103.195.nip.io")) // 기본 URL을 nip.io 도메인으로 설정
38+
.addServersItem(new Server().url("/"))
3839
.info(info)
3940
.addSecurityItem(securityRequirement)
4041
.components(components);

0 commit comments

Comments
 (0)