Skip to content

Commit 65cfb16

Browse files
committed
feat: 이미지 퀴즈 추가
1 parent 739ebc9 commit 65cfb16

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+778
-315
lines changed

backend/src/main/java/io/f1/backend/domain/game/app/GameService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public void gameStart(Long roomId, UserPrincipal principal) {
8989
timerService.startTimer(room, START_DELAY);
9090

9191
messageSender.sendBroadcast(
92-
destination, MessageType.GAME_START, toGameStartResponse(questions));
92+
destination, MessageType.GAME_START, toGameStartResponse(quiz.getQuizType(), questions));
9393
messageSender.sendBroadcast(
9494
destination, MessageType.RANK_UPDATE, toRankUpdateResponse(room));
9595
messageSender.sendBroadcast(

backend/src/main/java/io/f1/backend/domain/game/app/RoomService.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,15 @@ public void reconnectSendResponse(Long roomId, UserPrincipal principal) {
249249
String destination = getDestination(roomId);
250250
String userDestination = getUserDestination();
251251

252+
Long quizId = room.getGameSetting().getQuizId();
253+
252254
messageSender.sendBroadcast(
253255
destination,
254256
MessageType.SYSTEM_NOTICE,
255257
ofPlayerEvent(principal.getUserNickname(), RoomEventType.RECONNECT));
256258

257259
if (room.isPlaying()) {
260+
Quiz quiz = quizService.findQuizById(quizId);
258261
messageSender.sendPersonal(
259262
userDestination,
260263
MessageType.SYSTEM_NOTICE,
@@ -269,13 +272,11 @@ public void reconnectSendResponse(Long roomId, UserPrincipal principal) {
269272
messageSender.sendPersonal(
270273
userDestination,
271274
MessageType.GAME_START,
272-
toGameStartResponse(room.getQuestions()),
275+
toGameStartResponse(quiz.getQuizType(), room.getQuestions()),
273276
principal.getName());
274277
} else {
275278
RoomSettingResponse roomSettingResponse = toRoomSettingResponse(room);
276279

277-
Long quizId = room.getGameSetting().getQuizId();
278-
279280
Quiz quiz = quizService.getQuizWithQuestionsById(quizId);
280281

281282
GameSettingResponse gameSettingResponse =
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package io.f1.backend.domain.game.dto.response;
22

33
import io.f1.backend.domain.quiz.dto.GameQuestionResponse;
4+
import io.f1.backend.domain.quiz.entity.QuizType;
45

56
import java.util.List;
67

7-
public record GameStartResponse(List<GameQuestionResponse> questions) {}
8+
public record GameStartResponse(QuizType quizType, List<GameQuestionResponse> questions) {}
Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
package io.f1.backend.domain.question.api;
22

3-
import io.f1.backend.domain.question.app.QuestionService;
4-
53
import lombok.RequiredArgsConstructor;
64

7-
import org.springframework.http.ResponseEntity;
8-
import org.springframework.web.bind.annotation.DeleteMapping;
9-
import org.springframework.web.bind.annotation.PathVariable;
105
import org.springframework.web.bind.annotation.RequestMapping;
116
import org.springframework.web.bind.annotation.RestController;
127

@@ -15,12 +10,4 @@
1510
@RequiredArgsConstructor
1611
public class QuestionController {
1712

18-
private final QuestionService questionService;
19-
20-
@DeleteMapping("/{questionId}")
21-
public ResponseEntity<Void> deleteQuestion(@PathVariable Long questionId) {
22-
questionService.deleteQuestion(questionId);
23-
24-
return ResponseEntity.noContent().build();
25-
}
2613
}
Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,81 @@
11
package io.f1.backend.domain.question.app;
22

3-
import static io.f1.backend.domain.question.mapper.QuestionMapper.questionRequestToQuestion;
4-
import static io.f1.backend.domain.question.mapper.TextQuestionMapper.questionRequestToTextQuestion;
5-
import static io.f1.backend.domain.quiz.app.QuizService.verifyUserAuthority;
6-
3+
import io.f1.backend.domain.question.dao.ContentQuestionRepository;
74
import io.f1.backend.domain.question.dao.QuestionRepository;
8-
import io.f1.backend.domain.question.dao.TextQuestionRepository;
9-
import io.f1.backend.domain.question.dto.QuestionRequest;
10-
import io.f1.backend.domain.question.dto.QuestionUpdateRequest;
5+
import io.f1.backend.domain.question.dto.ContentQuestionRequest;
6+
import io.f1.backend.domain.question.dto.ContentQuestionUpdateRequest;
7+
import io.f1.backend.domain.question.entity.ContentQuestion;
118
import io.f1.backend.domain.question.entity.Question;
12-
import io.f1.backend.domain.question.entity.TextQuestion;
139
import io.f1.backend.domain.quiz.entity.Quiz;
10+
import io.f1.backend.domain.quiz.entity.QuizType;
1411
import io.f1.backend.global.exception.CustomException;
1512
import io.f1.backend.global.exception.errorcode.QuestionErrorCode;
16-
13+
import io.f1.backend.global.util.FileManager;
1714
import lombok.RequiredArgsConstructor;
1815

1916
import org.springframework.stereotype.Service;
20-
import org.springframework.transaction.annotation.Transactional;
2117

2218
@Service
2319
@RequiredArgsConstructor
2420
public class QuestionService {
2521

2622
private final QuestionRepository questionRepository;
27-
private final TextQuestionRepository textQuestionRepository;
28-
29-
@Transactional
30-
public void saveQuestion(Quiz quiz, QuestionRequest request) {
23+
private final ContentQuestionRepository contentQuestionRepository;
3124

32-
Question question = questionRequestToQuestion(quiz, request);
25+
public void saveContentQuestion(Quiz quiz, ContentQuestionRequest request) {
26+
Question question = new Question(quiz, request.getAnswer());
3327
quiz.addQuestion(question);
3428
questionRepository.save(question);
3529

36-
TextQuestion textQuestion = questionRequestToTextQuestion(question, request.getContent());
37-
textQuestionRepository.save(textQuestion);
38-
question.addTextQuestion(textQuestion);
30+
ContentQuestion contentQuestion = request.toContentQuestion(question);
31+
contentQuestionRepository.save(contentQuestion);
32+
question.addContentQuestion(contentQuestion);
3933
}
4034

41-
public void updateQuestions(Quiz quiz, QuestionUpdateRequest request) {
42-
35+
public void updateContentQuestions(Quiz quiz, ContentQuestionUpdateRequest request) {
4336
if (request.getId() == null) {
44-
saveQuestion(quiz, QuestionRequest.of(request));
37+
saveContentQuestion(
38+
quiz,
39+
ContentQuestionRequest.of(request.getContent(), request.getAnswer()));
40+
4541
return;
4642
}
4743

48-
Question question =
49-
questionRepository
50-
.findById(request.getId())
51-
.orElseThrow(
52-
() -> new CustomException(QuestionErrorCode.QUESTION_NOT_FOUND));
44+
Question question = getQuestionWithContent(request.getId());
5345

54-
TextQuestion textQuestion = question.getTextQuestion();
55-
textQuestion.changeContent(request.getContent());
46+
if (request.getContent() != null) {
47+
ContentQuestion contentQuestion = question.getContentQuestion();
48+
contentQuestion.changeContent(request.getContent());
49+
}
50+
5651
question.changeAnswer(request.getAnswer());
5752
}
5853

59-
@Transactional
60-
public void deleteQuestion(Long questionId) {
54+
public void deleteQuestion(Long questionId, QuizType quizType) {
55+
Question question;
56+
57+
if (quizType.name().equals("IMAGE")) {
58+
question = getQuestionWithContent(questionId);
59+
String filePath = question.getContentQuestion().getContent();
60+
FileManager.deleteFile(filePath);
61+
} else {
62+
question = getQuestion(questionId);
63+
}
6164

62-
Question question =
63-
questionRepository
65+
questionRepository.delete(question);
66+
}
67+
68+
private Question getQuestion(Long questionId) {
69+
return questionRepository
6470
.findById(questionId)
6571
.orElseThrow(
6672
() -> new CustomException(QuestionErrorCode.QUESTION_NOT_FOUND));
73+
}
6774

68-
verifyUserAuthority(question.getQuiz());
69-
70-
questionRepository.delete(question);
75+
private Question getQuestionWithContent(Long questionId) {
76+
return questionRepository
77+
.findByIdWithContent(questionId)
78+
.orElseThrow(
79+
() -> new CustomException(QuestionErrorCode.QUESTION_NOT_FOUND));
7180
}
7281
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.f1.backend.domain.question.dao;
2+
3+
import io.f1.backend.domain.question.entity.ContentQuestion;
4+
5+
import org.springframework.data.jpa.repository.JpaRepository;
6+
7+
public interface ContentQuestionRepository extends JpaRepository<ContentQuestion, Long> {}

backend/src/main/java/io/f1/backend/domain/question/dao/QuestionRepository.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,12 @@
33
import io.f1.backend.domain.question.entity.Question;
44

55
import org.springframework.data.jpa.repository.JpaRepository;
6+
import org.springframework.data.jpa.repository.Query;
67

7-
public interface QuestionRepository extends JpaRepository<Question, Long> {}
8+
import java.util.Optional;
9+
10+
public interface QuestionRepository extends JpaRepository<Question, Long> {
11+
12+
@Query("SELECT q FROM Question q JOIN FETCH q.contentQuestion WHERE q.id = :id")
13+
Optional<Question> findByIdWithContent(Long id);
14+
}

backend/src/main/java/io/f1/backend/domain/question/dao/TextQuestionRepository.java

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.f1.backend.domain.question.dto;
2+
3+
import io.f1.backend.domain.question.entity.ContentQuestion;
4+
import io.f1.backend.domain.question.entity.Question;
5+
import io.f1.backend.domain.quiz.entity.Quiz;
6+
import lombok.AccessLevel;
7+
import lombok.AllArgsConstructor;
8+
import lombok.Getter;
9+
10+
@Getter
11+
@AllArgsConstructor(access = AccessLevel.PRIVATE)
12+
public class ContentQuestionRequest {
13+
private String content;
14+
private String answer;
15+
16+
public static ContentQuestionRequest of(String content, String answer) {
17+
return new ContentQuestionRequest(content, answer);
18+
}
19+
20+
public ContentQuestion toContentQuestion(Question question) {
21+
return new ContentQuestion(question, content);
22+
}
23+
24+
public Question toQuestion(Quiz quiz) {
25+
return new Question(quiz, answer);
26+
}
27+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.f1.backend.domain.question.dto;
2+
3+
import lombok.AccessLevel;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Getter;
6+
7+
@Getter
8+
@AllArgsConstructor(access = AccessLevel.PRIVATE)
9+
public class ContentQuestionUpdateRequest {
10+
private Long id;
11+
private String content;
12+
private String answer;
13+
14+
public static ContentQuestionUpdateRequest of(Long id, String content, String answer) {
15+
return new ContentQuestionUpdateRequest(id, content, answer);
16+
}
17+
}

0 commit comments

Comments
 (0)