Skip to content

Commit a67ab42

Browse files
authored
Merge pull request #24 from oodd-team/OD-51
매칭 리스트 조회 기능
2 parents 19ab5ac + 05af6dc commit a67ab42

File tree

5 files changed

+156
-4
lines changed

5 files changed

+156
-4
lines changed

src/common/entities/user.entity.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Entity, OneToMany, Column } from 'typeorm';
1+
import { Entity, OneToMany, Column, OneToOne } from 'typeorm';
22
import { BaseEntity } from './base.entity';
33
import { Post } from './post.entity';
44
import { PostComment } from './post-comment.entity';
@@ -83,5 +83,6 @@ export class User extends BaseEntity {
8383
postReports!: PostReport[];
8484

8585
// 대표 게시물 필드 추가
86+
@OneToOne(() => Post, (post) => post.user)
8687
representativePost?: Post | null;
8788
}
+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { Type } from 'class-transformer';
2+
import { ApiProperty } from '@nestjs/swagger';
3+
4+
class RequesterResponse {
5+
@ApiProperty({
6+
description: '매칭 요청자의 ID',
7+
example: '19',
8+
})
9+
requesterId: number;
10+
11+
@ApiProperty({
12+
description: '매칭 요청자의 닉네임',
13+
example: '1d1d1d',
14+
})
15+
nickname: string;
16+
17+
@ApiProperty({
18+
description: '매칭 요청자의 프로필 이미지 url',
19+
example: 'https://example.com/image1.jpg',
20+
})
21+
profilePictureUrl: string;
22+
}
23+
24+
class RequesterPostResponse {
25+
@ApiProperty({
26+
description: '매칭 요청자의 게시물 이미지 목록',
27+
type: [String],
28+
example: [
29+
{ url: 'https://example.com/image1.jpg', orderNum: 1 },
30+
{ url: 'https://example.com/image2.jpg', orderNum: 2 },
31+
],
32+
})
33+
postImages: { url: string; orderNum: number }[];
34+
35+
@ApiProperty({
36+
description: '매칭 요청자의 게시물 스타일 태그 목록',
37+
type: [String],
38+
example: ['classic', 'basic'],
39+
})
40+
styleTags: string[];
41+
}
42+
43+
class MatchingResponse {
44+
@ApiProperty({
45+
description: '매칭 요청자 정보',
46+
type: RequesterResponse,
47+
})
48+
@Type(() => RequesterResponse)
49+
requester: RequesterResponse;
50+
51+
@ApiProperty({
52+
description: '매칭 요청자의 대표 게시물이 없을 경우, 가장 최근 게시물 정보',
53+
type: RequesterPostResponse,
54+
})
55+
@Type(() => RequesterPostResponse)
56+
requesterPost: RequesterPostResponse;
57+
}
58+
59+
export class GetMatchingsResponse {
60+
@ApiProperty({
61+
description: '매칭 존재 여부',
62+
example: true,
63+
})
64+
isMatching: boolean;
65+
66+
@ApiProperty({
67+
description: '받은 매칭 수',
68+
example: 10,
69+
})
70+
matchingCount: number;
71+
72+
@ApiProperty({
73+
description: '매칭 정보',
74+
type: [MatchingResponse],
75+
})
76+
@Type(() => MatchingResponse)
77+
matching: MatchingResponse[];
78+
}

src/matching/matching.controller.ts

+38-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { BaseResponse } from 'src/common/response/dto';
2828
import { PostMatchingResponse } from './dto/matching.response';
2929
import { AuthGuard } from 'src/auth/guards/jwt.auth.guard';
3030
import { PatchMatchingRequestDto } from './dto/Patch-matching.request';
31+
import { GetMatchingsResponse } from './dto/get-matching.response';
3132

3233
@ApiBearerAuth('Authorization')
3334
@Controller('matching')
@@ -88,9 +89,44 @@ export class MatchingController {
8889
}
8990

9091
@Get()
92+
@UseGuards(AuthGuard)
9193
@GetMatchingsSwagger('매칭 리스트 조회 API')
92-
getMatchings() {
93-
// return this.userService.getHello()
94+
async getMatchings(
95+
@Req() req: Request,
96+
): Promise<BaseResponse<GetMatchingsResponse>> {
97+
const matchings = await this.matchingService.getMatchings(req.user.id);
98+
const response: GetMatchingsResponse = {
99+
isMatching: true,
100+
matchingCount: matchings.length,
101+
matching: matchings.map((matching) => {
102+
const requesterPost =
103+
matching.requester.posts.find((post) => post.isRepresentative) ||
104+
matching.requester.posts.sort(
105+
(a, b) =>
106+
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
107+
)[0];
108+
109+
return {
110+
requester: {
111+
requesterId: matching.requester.id,
112+
nickname: matching.requester.nickname,
113+
profilePictureUrl: matching.requester.profilePictureUrl,
114+
},
115+
requesterPost: {
116+
postImages: requesterPost.postImages.map((image) => ({
117+
url: image.url,
118+
orderNum: image.orderNum,
119+
})),
120+
styleTags: requesterPost.postStyletags
121+
? requesterPost.postStyletags.map(
122+
(styleTag) => styleTag.styletag.tag,
123+
)
124+
: [],
125+
},
126+
};
127+
}),
128+
};
129+
return new BaseResponse(true, 'SUCCESS', response);
94130
}
95131

96132
@Get()

src/matching/matching.service.ts

+16
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,22 @@ export class MatchingService {
8585
}
8686
}
8787

88+
async getMatchings(currentUserId: number): Promise<Matching[]> {
89+
return await this.matchingRepository.find({
90+
where: {
91+
requestStatus: 'pending',
92+
status: 'activated',
93+
target: { id: currentUserId },
94+
},
95+
relations: [
96+
'requester',
97+
'requester.posts',
98+
'requester.posts.postImages',
99+
'requester.posts.postStyletags.styletag',
100+
],
101+
});
102+
}
103+
88104
async getMatchingById(matchingId: number): Promise<Matching> {
89105
const matching = await this.matchingRepository.findOne({
90106
where: { id: matchingId },

src/matching/matching.swagger.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
import { BaseSwaggerDecorator } from 'nestjs-swagger-decorator';
1010
import { PostMatchingResponse } from './dto/matching.response';
1111
import { BaseResponse } from 'src/common/response/dto';
12+
import { GetMatchingsResponse } from './dto/get-matching.response';
1213

1314
// 매칭 생성 API Swagger
1415
export function CreateMatchingSwagger(apiSummary: string) {
@@ -51,7 +52,27 @@ export function PatchMatchingRequestStatusSwagger(apiSummary: string) {
5152

5253
// 매칭 리스트 조회 API Swagger
5354
export function GetMatchingsSwagger(apiSummary: string) {
54-
return ApiOperation({ summary: apiSummary });
55+
return BaseSwaggerDecorator(
56+
{ summary: apiSummary },
57+
[
58+
{
59+
statusCode: 200,
60+
responseOptions: [
61+
{
62+
model: GetMatchingsResponse,
63+
exampleTitle: '성공',
64+
exampleDescription: '성공했을 때 값',
65+
},
66+
],
67+
baseResponseDto: BaseResponse,
68+
},
69+
],
70+
[
71+
ApiBadRequestResponse({ description: 'Bad Request' }),
72+
ApiNotFoundResponse({ description: '해당 유저가 존재하지 않습니다.' }),
73+
ApiInternalServerErrorResponse({ description: 'Internal Server Error' }),
74+
],
75+
);
5576
}
5677

5778
// 매칭 조회 API Swagger

0 commit comments

Comments
 (0)