@@ -10,9 +10,9 @@ import { InternalServerException } from 'src/common/exception/service.exception'
10
10
import { ChatMessageService } from 'src/chat-message/chat-message.service' ;
11
11
import { InjectRepository } from '@nestjs/typeorm' ;
12
12
import {
13
- CreateMatchingResponse ,
14
13
GetMatchingsResponse ,
15
14
GetOneMatchingResponse ,
15
+ MatchingRequest ,
16
16
} from './dto/matching.response' ;
17
17
import { MatchingRequestStatusEnum } from 'src/common/enum/matchingRequestStatus' ;
18
18
import { StatusEnum } from 'src/common/enum/entityStatus' ;
@@ -38,9 +38,7 @@ export class MatchingService {
38
38
} ) ;
39
39
}
40
40
41
- async createMatching (
42
- body : CreateMatchingRequest ,
43
- ) : Promise < CreateMatchingResponse > {
41
+ async createMatching ( body : CreateMatchingRequest ) : Promise < void > {
44
42
const queryRunner = this . dataSource . createQueryRunner ( ) ;
45
43
await queryRunner . connect ( ) ;
46
44
await queryRunner . startTransaction ( ) ;
@@ -63,46 +61,8 @@ export class MatchingService {
63
61
body ,
64
62
) ;
65
63
66
- const matchingInfo = await queryRunner . manager
67
- . createQueryBuilder ( Matching , 'matching' )
68
- . leftJoinAndSelect ( 'matching.target' , 'target' )
69
- . leftJoinAndSelect ( 'matching.requester' , 'requester' )
70
- . leftJoinAndSelect ( 'requester.posts' , 'post' )
71
- . leftJoinAndSelect ( 'post.postImages' , 'image' )
72
- . leftJoinAndSelect ( 'post.postStyletags' , 'styleTag' )
73
- . leftJoinAndSelect ( 'styleTag.styletag' , 'styletag' )
74
- . where ( 'matching.id = :id' , { id : matching . id } )
75
- . getOne ( ) ;
76
-
77
- const requesterPost = matchingInfo . requester . posts [ 0 ] ;
78
-
79
64
await queryRunner . commitTransaction ( ) ;
80
-
81
- return {
82
- id : matchingInfo . id ,
83
- message : body . message ,
84
- createdAt : dayjs ( matching . createdAt ) . format ( 'YYYY-MM-DDTHH:mm:ssZ' ) ,
85
- chatRoomId : chatRoom . id ,
86
- targetId : body . targetId ,
87
- requester : {
88
- id : body . requesterId ,
89
- nickname : matchingInfo . requester . nickname ,
90
- profilePictureUrl : matchingInfo . requester . profilePictureUrl ,
91
- representativePost : requesterPost
92
- ? {
93
- postImages : requesterPost . postImages . map ( ( image ) => ( {
94
- url : image . url ,
95
- orderNum : image . orderNum ,
96
- } ) ) ,
97
- styleTags : requesterPost . postStyletags
98
- ? requesterPost . postStyletags . map (
99
- ( styleTag ) => styleTag . styletag . tag ,
100
- )
101
- : [ ] ,
102
- }
103
- : { } ,
104
- } ,
105
- } ;
65
+ await this . addMatchingQueues ( body . targetId ) ;
106
66
} catch ( error ) {
107
67
await queryRunner . rollbackTransaction ( ) ;
108
68
throw InternalServerException ( error . message ) ;
@@ -122,7 +82,6 @@ export class MatchingService {
122
82
matching . id ,
123
83
) ;
124
84
try {
125
- console . log ( body . requestStatus ) ;
126
85
if ( body . requestStatus === 'accept' ) {
127
86
matching . requestStatus = MatchingRequestStatusEnum . ACCEPTED ;
128
87
matching . acceptedAt = new Date ( ) ;
@@ -157,7 +116,7 @@ export class MatchingService {
157
116
} ) ;
158
117
159
118
if ( ! matching ) {
160
- return { } ;
119
+ return null ;
161
120
}
162
121
163
122
return {
@@ -169,16 +128,96 @@ export class MatchingService {
169
128
} ;
170
129
}
171
130
172
- async getMatchings ( currentUserId : number ) : Promise < GetMatchingsResponse > {
131
+ private matchingQueues : { [ key : number ] : MatchingRequest [ ] } = [ ] ;
132
+ // 매칭 추가
133
+ async addMatchingQueues ( userId : number ) {
134
+ try {
135
+ const matchingInfo = await this . matchingRepository
136
+ . createQueryBuilder ( 'matching' )
137
+ . leftJoinAndSelect ( 'matching.requester' , 'requester' )
138
+ . leftJoinAndSelect ( 'requester.posts' , 'post' )
139
+ . leftJoinAndSelect ( 'post.postImages' , 'image' )
140
+ . leftJoinAndSelect ( 'post.postStyletags' , 'styleTag' )
141
+ . leftJoinAndSelect ( 'styleTag.styletag' , 'styletag' )
142
+ . where ( 'matching.targetId = :userId' , { userId } )
143
+ . andWhere ( 'matching.requestStatus = :status' , {
144
+ status : MatchingRequestStatusEnum . PENDING ,
145
+ } )
146
+ . andWhere ( 'matching.status = :activated' , {
147
+ activated : StatusEnum . ACTIVATED ,
148
+ } )
149
+ . andWhere ( 'requester.status = :activated' , {
150
+ activated : StatusEnum . ACTIVATED ,
151
+ } )
152
+ . orderBy ( 'matching.createdAt' , 'DESC' )
153
+ . addOrderBy ( 'post.isRepresentative' , 'DESC' )
154
+ . addOrderBy ( 'post.createdAt' , 'DESC' )
155
+ . orderBy ( 'matching.createdAt' , 'DESC' )
156
+ . getOne ( ) ;
157
+
158
+ const requesterPost = matchingInfo . requester . posts [ 0 ] ;
159
+ const chatRoom = await this . chatRoomService . getChatRoomByMatchingId (
160
+ matchingInfo . id ,
161
+ ) ;
162
+
163
+ const formattedMatching : MatchingRequest = {
164
+ id : matchingInfo . id ,
165
+ message : matchingInfo . message ,
166
+ createdAt : dayjs ( matchingInfo . createdAt ) . format ( 'YYYY-MM-DDTHH:mm:ssZ' ) ,
167
+ requestStatus : matchingInfo . requestStatus ,
168
+ chatRoomId : chatRoom . id ,
169
+ targetId : userId ,
170
+ requester : {
171
+ id : matchingInfo . requester . id ,
172
+ nickname : matchingInfo . requester . nickname ,
173
+ profilePictureUrl : matchingInfo . requester . profilePictureUrl ,
174
+ representativePost : requesterPost
175
+ ? {
176
+ postImages : requesterPost . postImages . map ( ( image ) => ( {
177
+ url : image . url ,
178
+ orderNum : image . orderNum ,
179
+ } ) ) ,
180
+ styleTags : requesterPost . postStyletags
181
+ ? requesterPost . postStyletags . map (
182
+ ( styleTag ) => styleTag . styletag . tag ,
183
+ )
184
+ : [ ] ,
185
+ }
186
+ : undefined ,
187
+ } ,
188
+ } ;
189
+
190
+ if ( ! this . matchingQueues [ userId ] ) {
191
+ this . matchingQueues [ userId ] = [ ] ;
192
+ }
193
+ this . matchingQueues [ userId ] . push ( formattedMatching ) ;
194
+ } catch ( error ) {
195
+ throw InternalServerException ( error ) ;
196
+ }
197
+ }
198
+
199
+ // 다음 매칭 가져오기 (큐에서 제거)
200
+ getNextMatching ( userId : number ) : MatchingRequest | { } {
201
+ if (
202
+ ! this . matchingQueues [ userId ] ||
203
+ this . matchingQueues [ userId ] . length === 0
204
+ ) {
205
+ return { } ;
206
+ }
207
+ return this . matchingQueues [ userId ] . shift ( ) || { } ;
208
+ }
209
+
210
+ async getMatchings ( userId : number ) : Promise < GetMatchingsResponse > {
173
211
const matchings = await this . matchingRepository
174
212
. createQueryBuilder ( 'matching' )
175
213
. leftJoinAndSelect ( 'matching.requester' , 'requester' )
176
214
. leftJoinAndSelect ( 'requester.posts' , 'post' )
177
215
. leftJoinAndSelect ( 'post.postImages' , 'image' )
178
216
. leftJoinAndSelect ( 'post.postStyletags' , 'styleTag' )
179
217
. leftJoinAndSelect ( 'styleTag.styletag' , 'styletag' )
180
- . where ( 'matching.targetId = :currentUserId' , { currentUserId } )
181
- . andWhere ( 'matching.requestStatus = :status' , {
218
+ . where ( 'matching.targetId = :userId' , { userId } )
219
+ // Pending이 아닌 매칭 조회
220
+ . andWhere ( 'matching.requestStatus <> :status' , {
182
221
status : MatchingRequestStatusEnum . PENDING ,
183
222
} )
184
223
. andWhere ( 'matching.status = :activated' , {
@@ -193,35 +232,49 @@ export class MatchingService {
193
232
. getMany ( ) ;
194
233
195
234
const response : GetMatchingsResponse = {
196
- hasMatching : matchings . length > 0 ,
197
- matchingsCount : matchings . length ,
198
- matching : matchings . map ( ( matching ) => {
199
- const requesterPost = matching . requester . posts [ 0 ] ;
235
+ matching : await Promise . all (
236
+ matchings . map ( async ( matching ) => {
237
+ try {
238
+ const requesterPost = matching . requester . posts [ 0 ] ;
239
+ const chatRoom = await this . chatRoomService . getChatRoomByMatchingId (
240
+ matching . id ,
241
+ ) ;
200
242
201
- return {
202
- id : matching . id ,
203
- requester : {
204
- id : matching . requester . id ,
205
- nickname : matching . requester . nickname ,
206
- profilePictureUrl : matching . requester . profilePictureUrl ,
207
- representativePost : requesterPost
208
- ? {
209
- postImages : requesterPost . postImages . map ( ( image ) => ( {
210
- url : image . url ,
211
- orderNum : image . orderNum ,
212
- } ) ) ,
213
- styleTags : requesterPost . postStyletags
214
- ? requesterPost . postStyletags . map (
215
- ( styleTag ) => styleTag . styletag . tag ,
216
- )
217
- : [ ] ,
218
- }
219
- : { } ,
220
- } ,
221
- } ;
222
- } ) ,
243
+ return {
244
+ id : matching . id ,
245
+ message : matching . message ,
246
+ createdAt : dayjs ( matching . createdAt ) . format (
247
+ 'YYYY-MM-DDTHH:mm:ssZ' ,
248
+ ) ,
249
+ requestStatus : matching . requestStatus ,
250
+ chatRoomId : chatRoom . id ,
251
+ targetId : userId ,
252
+ requester : {
253
+ id : matching . requester . id ,
254
+ nickname : matching . requester . nickname ,
255
+ profilePictureUrl : matching . requester . profilePictureUrl ,
256
+ representativePost : requesterPost
257
+ ? {
258
+ postImages : requesterPost . postImages . map ( ( image ) => ( {
259
+ url : image . url ,
260
+ orderNum : image . orderNum ,
261
+ } ) ) ,
262
+ styleTags : requesterPost . postStyletags
263
+ ? requesterPost . postStyletags . map (
264
+ ( styleTag ) => styleTag . styletag . tag ,
265
+ )
266
+ : [ ] ,
267
+ }
268
+ : { } ,
269
+ } ,
270
+ } ;
271
+ } catch ( error ) {
272
+ throw InternalServerException ( error ) ;
273
+ }
274
+ } ) ,
275
+ ) ,
223
276
} ;
224
- return response ;
277
+ return response . matching . length ? response : { matching : [ ] } ;
225
278
}
226
279
227
280
async getMatchingById ( matchingId : number ) : Promise < Matching > {
0 commit comments