Skip to content

Commit af9bcb1

Browse files
authored
Merge pull request #25 from Nexters/dev
Dev
2 parents 576f4b6 + d73f867 commit af9bcb1

File tree

7 files changed

+120
-34
lines changed

7 files changed

+120
-34
lines changed

src/main/java/donmani/donmani_server/expense/controller/ExpenseController.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,21 @@
2020
public class ExpenseController {
2121
private final ExpenseService expenseService;
2222

23-
@GetMapping("/{userKey}")
24-
public ResponseEntity<ExpenseResponseDTO> getExpenses(
23+
@GetMapping("/calendar/{userKey}")
24+
public ResponseEntity<ExpenseResponseDTO> getExpensesCalendar(
2525
@PathVariable String userKey,
2626
@RequestParam int year,
2727
@RequestParam int month) {
28-
ExpenseResponseDTO response = expenseService.getExpenses(userKey, year, month);
28+
ExpenseResponseDTO response = expenseService.getExpenses(userKey, year, month, false);
29+
return ResponseEntity.ok(response);
30+
}
31+
32+
@GetMapping("/list/{userKey}")
33+
public ResponseEntity<ExpenseResponseDTO> getExpensesList(
34+
@PathVariable String userKey,
35+
@RequestParam int year,
36+
@RequestParam int month) {
37+
ExpenseResponseDTO response = expenseService.getExpenses(userKey, year, month, true);
2938
return ResponseEntity.ok(response);
3039
}
3140

src/main/java/donmani/donmani_server/expense/dto/RecordDTO.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,16 @@
1616
@NoArgsConstructor
1717
@AllArgsConstructor
1818
@Builder
19-
@JsonInclude(JsonInclude.Include.NON_NULL) // null 값 제외
2019
public class RecordDTO {
2120
private LocalDate date;
2221
private List<ContentDTO> contents; // null 가능
22+
23+
public static RecordDTO of(LocalDate localDate, List<ContentDTO> contents) {
24+
RecordDTO recordDTO = new RecordDTO();
25+
26+
recordDTO.setDate(localDate);
27+
recordDTO.setContents(contents.get(0) == null ? null : contents);
28+
29+
return recordDTO;
30+
}
2331
}
Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
package donmani.donmani_server.expense.entity;
22

33
public enum CategoryType {
4-
// TODO : 19가지 카테고리 추가
5-
FIRST, SECOND, THIRD, FOURTH
4+
// 좋은 소비
5+
ENERGY, // 활력
6+
GROWTH, // 성장
7+
HEALING, // 힐링
8+
HAPPINESS, // 소확행
9+
FLEX, // 플렉스
10+
DIGNITY, // 품위 유지
11+
AFFECTION, // 마음 전달
12+
HEALTH, // 건강
13+
14+
// 2.나쁜 소비
15+
GREED, // 욕심
16+
ADDICTION, // 중독
17+
LAZINESS, // 게으름
18+
IMPULSE, // 충동
19+
MEANINGLESSNESS, // 무의미
20+
BOASTFULNESS, // 과시
21+
HABIT, // 습관 반복
22+
OVERFRUGALITY, // 과한 절약
23+
24+
// 좋은 소비, 나쁜 소비 공통
25+
NONE // 카테고리 없음
626
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package donmani.donmani_server.expense.entity;
22

33
public enum FlagType {
4-
GOOD, BAD, NONE
4+
GOOD, // 좋은 소비
5+
BAD // 나쁜 소비
56
}

src/main/java/donmani/donmani_server/expense/repository/ExpenseRepository.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.time.LocalDateTime;
44
import java.util.List;
55

6+
import org.springframework.data.domain.Page;
7+
import org.springframework.data.domain.Pageable;
68
import org.springframework.data.jpa.repository.JpaRepository;
79
import org.springframework.data.jpa.repository.Query;
810
import org.springframework.data.repository.query.Param;
@@ -11,7 +13,13 @@
1113

1214
public interface ExpenseRepository extends JpaRepository<Expense, Long> {
1315
List<Expense> findByUserId(Long userId);
16+
1417
@Query("SELECT e FROM Expense e WHERE e.userId = :userId AND YEAR(e.createdAt) = :year AND MONTH(e.createdAt) = :month")
1518
List<Expense> findByUserIdAndMonth(@Param("userId") Long userId, @Param("year") int year, @Param("month") int month);
1619

20+
@Query("SELECT DISTINCT e.createdAt FROM Expense e WHERE e.userId = :userId ORDER BY e.createdAt DESC")
21+
Page<LocalDateTime> findDistinctCreatedAt(@Param("userId") Long userId, Pageable pageable);
22+
23+
@Query("SELECT e FROM Expense e WHERE e.createdAt IN :localDateTimes ORDER BY e.createdAt DESC")
24+
List<Expense> findByCreatedAtIn(@Param("userId") Long userId, List<LocalDateTime> localDateTimes);
1725
}

src/main/java/donmani/donmani_server/expense/service/ExpenseService.java

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package donmani.donmani_server.expense.service;
22

3-
import java.util.Collections;
4-
import java.util.List;
3+
import java.time.LocalDate;
4+
import java.time.LocalDateTime;
5+
import java.util.*;
56
import java.util.stream.Collectors;
67
import java.util.stream.Stream;
78

9+
import org.springframework.data.domain.Page;
10+
import org.springframework.data.domain.PageRequest;
11+
import org.springframework.data.domain.Pageable;
812
import org.springframework.stereotype.Service;
913
import org.springframework.transaction.annotation.Transactional;
1014

@@ -25,6 +29,8 @@ public class ExpenseService {
2529
private final ExpenseRepository expenseRepository;
2630
private final UserService userService;
2731

32+
private final static int SIZE = 20; // 전체 조회 페이지 사이즈 고정
33+
2834
@Transactional
2935
public void addExpense(ExpenseRequestDTO request) {
3036
Long userId = userService.getUserIdByUserKey(request.getUserKey());
@@ -59,7 +65,7 @@ public void addExpense(ExpenseRequestDTO request) {
5965

6066

6167
@Transactional(readOnly = true)
62-
public ExpenseResponseDTO getExpenses(String userKey, int year, int month) {
68+
public ExpenseResponseDTO getExpenses(String userKey, int year, int month, boolean sortedDesc) {
6369
Long userId = userService.getUserIdByUserKey(userKey);
6470

6571
if (userId == null) {
@@ -69,29 +75,65 @@ public ExpenseResponseDTO getExpenses(String userKey, int year, int month) {
6975
// userId와 year, month로 직접 expense를 조회
7076
List<Expense> expenses = expenseRepository.findByUserIdAndMonth(userId, year, month);
7177

72-
// 하루에 하나의 기록이라면, groupBy 없이 바로 리스트로 변환
73-
List<RecordDTO> records = expenses.stream()
74-
.map(expense -> {
75-
// 해당 expense에서 contents가 없으면 null로 설정
76-
List<ContentDTO> contents = (expense.getCategory() == null || expense.getFlag() == null || expense.getMemo() == null)
77-
? Collections.emptyList()
78-
: List.of(ContentDTO.builder()
79-
.flag(expense.getFlag())
80-
.category(expense.getCategory())
81-
.memo(expense.getMemo())
82-
.build());
83-
84-
return RecordDTO.builder()
85-
.date(expense.getCreatedAt().toLocalDate()) // 날짜 설정
86-
.contents(contents) // 내용이 없으면 null
78+
if(expenses.isEmpty()) {
79+
return ExpenseResponseDTO.builder()
80+
.userKey(userKey)
81+
.records(null)
8782
.build();
88-
})
89-
.collect(Collectors.toList());
83+
}
9084

9185
return ExpenseResponseDTO.builder()
9286
.userKey(userKey)
93-
.records(records)
87+
.records(expenseToDto(expenses, sortedDesc))
9488
.build();
9589
}
9690

91+
private List<RecordDTO> expenseToDto(List<Expense> expenses, boolean sortedDesc) {
92+
Map<LocalDate, List<ContentDTO>> groupedContents = expenses.stream()
93+
.collect(Collectors.groupingBy(
94+
expense -> expense.getCreatedAt().toLocalDate(), // 날짜별 그룹핑 Map 형태로 담아줌
95+
Collectors.mapping(exp -> {
96+
if (exp.getCategory() == null && exp.getFlag() == null && exp.getMemo() == null) {
97+
return null;
98+
}
99+
return ContentDTO.builder()
100+
.flag(exp.getFlag())
101+
.category(exp.getCategory())
102+
.memo(exp.getMemo())
103+
.build();
104+
}, Collectors.toList())
105+
));
106+
107+
return groupedContents.entrySet().stream()
108+
.map(entry -> RecordDTO.of(entry.getKey(), entry.getValue())
109+
)
110+
.sorted(sortedDesc ? Comparator.comparing(RecordDTO::getDate).reversed() : Comparator.comparing(RecordDTO::getDate))
111+
.collect(Collectors.toList());
112+
}
113+
// 미사용
114+
@Transactional(readOnly = true)
115+
public ExpenseResponseDTO getAllExpenses(String userKey, int page) {
116+
Long userId = userService.getUserIdByUserKey(userKey);
117+
118+
if (userId == null) {
119+
throw new EntityNotFoundException("유저 정보를 찾을 수 없습니다.");
120+
}
121+
122+
// 시간순 정렬 20개
123+
Page<LocalDateTime> localDateTimes = expenseRepository.findDistinctCreatedAt(userId, PageRequest.of(page, SIZE));
124+
if (localDateTimes.isEmpty()) {
125+
return ExpenseResponseDTO.builder()
126+
.userKey(userKey)
127+
.records(null)
128+
.build();
129+
}
130+
131+
List<Expense> expenses = expenseRepository.findByCreatedAtIn(userId, localDateTimes.getContent());
132+
133+
return ExpenseResponseDTO.builder()
134+
.userKey(userKey)
135+
.records(expenseToDto(expenses, true))
136+
.build();
137+
}
138+
97139
}

src/main/java/donmani/donmani_server/user/entity/User.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,9 @@ public class User {
2323
private int level;
2424

2525
public static String generateRandomUsername() {
26-
String[] adjectives = {"Blue", "Red", "Green", "Fast", "Lucky"};
27-
String[] animals = {"Tiger", "Panda", "Eagle", "Lion", "Wolf"};
28-
int number = (int) (Math.random() * 100);
29-
return adjectives[(int) (Math.random() * adjectives.length)] +
30-
animals[(int) (Math.random() * animals.length)] +
31-
number;
26+
String[] adjectives = {"기쁜", "슬픈", "화난", "즐거운", "부끄러운", "당황한", "설레는", "외로운", "초조한", "뿌듯한", "시원한", "우울한", "황홀한", "씁쓸한", "의기양양한", "서운한", "후련한", "억울한", "두근거리는", "운이 좋은"};
27+
String[] animals = {"고양이", "강아지", "호랑이", "사자", "여우", "늑대", "토끼", "다람쥐", "판다", "코끼리", "원숭이", "곰", "독수리", "올빼미", "수달", "두더지", "너구리", "고슴도치", "하마", "피카츄"};
28+
29+
return adjectives[(int) (Math.random() * adjectives.length)] + " " + animals[(int) (Math.random() * animals.length)];
3230
}
3331
}

0 commit comments

Comments
 (0)