22
33import io .swagger .v3 .oas .annotations .media .Schema ;
44import lombok .*;
5+ import org .springframework .data .domain .Page ;
56import targeter .aim .domain .challenge .dto .ChallengeDto ;
7+ import targeter .aim .domain .challenge .entity .ChallengeMode ;
8+ import targeter .aim .domain .file .dto .FileDto ;
69import targeter .aim .domain .post .dto .PostDto ;
10+ import targeter .aim .domain .post .entity .PostType ;
11+ import targeter .aim .domain .user .dto .TierDto ;
12+ import targeter .aim .domain .user .entity .User ;
13+
14+ import java .time .LocalDate ;
15+ import java .time .LocalDateTime ;
16+ import java .util .List ;
717
818public class SearchDto {
919
1020 @ Data
21+ @ NoArgsConstructor
22+ @ AllArgsConstructor
1123 @ Builder
24+ @ Schema (description = "전체 검색글 목록 조회 조건" )
25+ public static class ListSearchCondition {
26+ @ Builder .Default
27+ @ Schema (
28+ description = """
29+ 정렬 기준
30+ - LATEST : 최신순
31+ - OLDEST : 오래된순
32+ - LIKED : 좋아요순
33+ - TITLE : 가나다순
34+ """ ,
35+ example = "LATEST" ,
36+ allowableValues = {"LATEST" , "OLDEST" , "LIKED" , "TITLE" }
37+ )
38+ private SortType sort = SortType .LATEST ;
39+
40+ @ Schema (description = "검색 키워드 (제목 기준 포함 검색)" , example = "개발" )
41+ private String keyword ;
42+ }
43+
44+ public enum SortType {
45+ LATEST , // 최신순
46+ OLDEST , // 오래된순
47+ LIKED , // 좋아요순
48+ TITLE // 가나다순
49+ }
50+
51+ public enum Type {
52+ CHALLENGE , // 챌린지
53+ POST // 게시글
54+ }
55+
56+ @ Data
57+ @ AllArgsConstructor
58+ @ NoArgsConstructor
59+ @ Schema (description = "페이지네이션 정보" )
60+ public static class PageInfo {
61+ private int size ;
62+
63+ private int number ;
64+
65+ private long totalElements ;
66+
67+ private int totalPages ;
68+ }
69+
70+ @ Data
1271 @ NoArgsConstructor
1372 @ AllArgsConstructor
14- @ Schema (description = "통합 검색 응답" )
15- public static class SearchResponse {
73+ @ Builder
74+ @ Schema (description = "글 작성자 정보" )
75+ public static class UserResponse {
76+
77+ @ Schema (description = "유저 아이디" , example = "1" )
78+ private Long userId ;
79+
80+ @ Schema (description = "유저 닉네임" , example = "닉네임" )
81+ private String nickname ;
1682
17- @ Schema (description = "게시글 검색 결과" )
18- private PostDto .PostPageResponse posts ;
83+ @ Schema (description = "티어명" , example = "BRONZE" )
84+ private TierDto .TierResponse tier ;
85+
86+ @ Schema (description = "프로필 이미지" )
87+ private FileDto .FileResponse profileImage ;
88+
89+ public static UserResponse from (User user ) {
90+ return UserResponse .builder ()
91+ .userId (user .getId ())
92+ .nickname (user .getNickname ())
93+ .tier (TierDto .TierResponse .from (user .getTier ()))
94+ .profileImage (FileDto .FileResponse .from (user .getProfileImage ()))
95+ .build ();
96+ }
97+ }
98+
99+ @ Data
100+ @ NoArgsConstructor
101+ @ AllArgsConstructor
102+ @ Getter
103+ @ Builder
104+ @ Schema (description = "검색된 글 목록 응답" )
105+ public static class SearchListResponse {
106+ @ Schema (description = "글 종류" , example = "CHALLENGE | POST" )
107+ private Type type ;
108+
109+ @ Schema (description = "챌린지/게시글 아이디" , example = "1" )
110+ private Long id ;
111+
112+ @ Schema (
113+ description = """
114+ 게시글 종류
115+ - VS_RECRUIT : VS 모집글
116+ - Q_AND_A : Q&A
117+ - REVIEW : 후기글
118+ """ ,
119+ example = "VS_RECRUIT | Q_AND_A | REVIEW"
120+ )
121+ private PostType postType ;
122+
123+ @ Schema (
124+ description = "연관된 챌린지 모드" ,
125+ example = "VS | SOLO"
126+ )
127+ private ChallengeMode challengeMode ;
128+
129+ @ Schema (description = "썸네일 정보(uuid값 참고)" )
130+ private FileDto .FileResponse thumbnail ;
131+
132+ @ Schema (description = "작성자 정보" )
133+ private UserResponse user ;
134+
135+ @ Schema (description = "시작일" , example = "2026-01-01" )
136+ private LocalDate startedAt ;
137+
138+ @ Schema (description = "챌린지 기간(주)" , example = "4주" )
139+ private Integer durationWeek ;
140+
141+ @ Schema (description = "VS모집글 제목" , example = "제목" )
142+ private String name ;
143+
144+ @ Schema (description = "분야 리스트" , example = "[\" IT\" , \" BUSINESS\" ]" )
145+ private List <String > fields ;
146+
147+ @ Schema (description = "태그 리스트" , example = "[\" 태그1\" , \" 태그2\" , \" 태그3\" ]" )
148+ private List <String > tags ;
149+
150+ @ Schema (description = "직무" , example = "직무" )
151+ private String job ;
152+
153+ @ Schema (description = "좋아요 여부(좋아요 했으면 true)" , example = "true | false" )
154+ private Boolean isLiked ;
155+
156+ @ Schema (description = "좋아요수" , example = "1" )
157+ private Integer likeCount ;
158+
159+ @ Schema (description = "글 생성일" , example = "ISO DateTime" )
160+ private LocalDateTime createdAt ;
161+ }
162+
163+ @ Data
164+ @ AllArgsConstructor
165+ @ NoArgsConstructor
166+ @ Schema (description = "게시글 목록 페이지 응답" )
167+ public static class SearchPageResponse {
168+ private List <SearchListResponse > content ;
169+ private PostDto .PageInfo page ;
19170
20- @ Schema (description = "챌린지 검색 결과" )
21- private ChallengeDto .ChallengePageResponse challenges ;
171+ public static SearchPageResponse from (Page <SearchListResponse > page ) {
172+ return new SearchPageResponse (
173+ page .getContent (),
174+ new PostDto .PageInfo (
175+ page .getSize (),
176+ page .getNumber (),
177+ page .getTotalElements (),
178+ page .getTotalPages ()
179+ )
180+ );
181+ }
22182 }
23- }
183+ }
0 commit comments