Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,17 @@ public ResponseEntity<?> createClubApplicationForm(@CurrentUser CustomUserDetail
return Response.ok("success create application");
}

@PutMapping("/application/{applicationFormId}")
@Operation(summary = "클럽 지원서 양식 수정", description = "클럽 지원서 양식을 수정합니다")
@PatchMapping("/application/{applicationFormId}")
@Operation(summary = "클럽 지원서 양식 수정",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

부분 업데이트 꽤나 좋군여,,

description = "클럽 지원서 양식을 부분적으로 수정합니다.<br>" +
"수정 가능한 정보는 다음과 같습니다.<br>" +
"- 지원서 제목 (title)<br>" +
"- 지원서 설명 (description)<br>" +
"- 활성화 여부 (active)<br>" +
"- 질문 목록 (questions)<br>" +
"- 모집 학년도 (semesterYear)<br>" +
"- 모집 학기 (semesterTerm)"
)
@PreAuthorize("isAuthenticated()")
@SecurityRequirement(name = "BearerAuth")
public ResponseEntity<?> editClubApplicationForm(@PathVariable String applicationFormId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
package moadong.club.payload.request;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import jakarta.validation.constraints.*;
import moadong.club.enums.SemesterTerm;

import java.util.List;

public record ClubApplicationFormEditRequest(
@NotBlank
@Size(max = 50)
String title,

@NotBlank
@Size(max = 3000)
String description,

@NotNull
Boolean active,

@NotNull
@Valid
List<ClubApplyQuestion> questions
List<ClubApplyQuestion> questions,

@Min(2000)
@Max(2999)
Integer semesterYear,

SemesterTerm semesterTerm
) {
}
113 changes: 49 additions & 64 deletions backend/src/main/java/moadong/club/service/ClubApplyAdminService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
import moadong.club.entity.*;
import moadong.club.enums.SemesterTerm;
import moadong.club.payload.dto.*;
import moadong.club.payload.request.ClubApplicantDeleteRequest;
import moadong.club.payload.request.ClubApplicantEditRequest;
import moadong.club.payload.request.ClubApplicationFormCreateRequest;
import moadong.club.payload.request.ClubApplicationFormEditRequest;
import moadong.club.payload.request.*;
import moadong.club.payload.response.ClubApplicationFormsResponse;
import moadong.club.payload.response.ClubApplyInfoResponse;
import moadong.club.repository.ClubApplicantsRepository;
Expand All @@ -22,17 +19,17 @@
import moadong.user.payload.CustomUserDetails;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CompletableFuture;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -91,12 +88,12 @@ private void validateSemester(Integer semesterYear, SemesterTerm semesterTerm) {
public void createClubApplicationForm(CustomUserDetails user, ClubApplicationFormCreateRequest request) {
validateSemester(request.semesterYear(), request.semesterTerm());

ClubApplicationForm clubApplicationForm = createQuestions(
ClubApplicationForm clubApplicationForm = createApplicationForm(
ClubApplicationForm.builder()
.clubId(user.getClubId())
.build(),
request);
clubApplicationFormsRepository.save(createQuestions(clubApplicationForm, request));
clubApplicationFormsRepository.save(clubApplicationForm);
}

@Transactional
Expand All @@ -106,15 +103,15 @@ public void editClubApplication(String applicationFormId, CustomUserDetails user
.orElseThrow(() -> new RestApiException(ErrorCode.APPLICATION_NOT_FOUND));

clubApplicationForm.updateEditedAt();
clubApplicationFormsRepository.save(updateQuestions(clubApplicationForm, request));
clubApplicationFormsRepository.save(updateApplicationForm(clubApplicationForm, request));
}

@Transactional //test 사용
public void editClubApplicationQuestion(String applicationFormId, CustomUserDetails user, ClubApplicationFormEditRequest request) {
ClubApplicationForm clubApplicationForm = clubApplicationFormsRepository.findById(applicationFormId)
.orElseThrow(() -> new RestApiException(ErrorCode.APPLICATION_NOT_FOUND));

updateQuestions(clubApplicationForm, request);
updateApplicationForm(clubApplicationForm, request);
clubApplicationForm.updateEditedAt();

clubApplicationFormsRepository.save(clubApplicationForm);
Expand Down Expand Up @@ -253,12 +250,12 @@ public void editApplicantDetail(String applicationFormId, List<ClubApplicantEdit

// SSE 이벤트 발송
ApplicantStatusEvent event = new ApplicantStatusEvent(
app.getId(),
editRequest.status(),
editRequest.memo(),
ZonedDateTime.now(ZoneId.of("Asia/Seoul")).toLocalDateTime(),
clubId,
applicationFormId
app.getId(),
editRequest.status(),
editRequest.memo(),
ZonedDateTime.now(ZoneId.of("Asia/Seoul")).toLocalDateTime(),
clubId,
applicationFormId
);

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
Expand All @@ -283,35 +280,8 @@ public void deleteApplicant(String applicationFormId, ClubApplicantDeleteRequest
clubApplicantsRepository.deleteAll(applicants);
}

private ClubApplicationForm createQuestions(ClubApplicationForm clubApplicationForm, ClubApplicationFormCreateRequest request) {
List<ClubApplicationFormQuestion> newQuestions = new ArrayList<>();

for (var question : request.questions()) {
List<ClubQuestionItem> items = new ArrayList<>();

for (var item : question.items()) {
items.add(ClubQuestionItem.builder()
.value(item.value())
.build());
}

ClubQuestionOption options = ClubQuestionOption.builder()
.required(question.options().required())
.build();

ClubApplicationFormQuestion clubApplicationFormQuestion = ClubApplicationFormQuestion.builder()
.id(question.id())
.title(question.title())
.description(question.description())
.type(question.type())
.options(options)
.items(items)
.build();

newQuestions.add(clubApplicationFormQuestion);
}

clubApplicationForm.updateQuestions(newQuestions);
private ClubApplicationForm createApplicationForm(ClubApplicationForm clubApplicationForm, ClubApplicationFormCreateRequest request) {
clubApplicationForm.updateQuestions(buildClubFormQuestions(request.questions()));
clubApplicationForm.updateFormTitle(request.title());
clubApplicationForm.updateFormDescription(request.description());
clubApplicationForm.updateSemesterYear(request.semesterYear());
Expand All @@ -320,13 +290,32 @@ private ClubApplicationForm createQuestions(ClubApplicationForm clubApplicationF
return clubApplicationForm;
}

/**
* update와 create 메서드는 추후 변경예정
*/
private ClubApplicationForm updateQuestions(ClubApplicationForm clubApplicationForm, ClubApplicationFormEditRequest request) {
List<ClubApplicationFormQuestion> newQuestions = new ArrayList<>();
private ClubApplicationForm updateApplicationForm(ClubApplicationForm clubApplicationForm, ClubApplicationFormEditRequest request) {
if (request.questions() != null)
clubApplicationForm.updateQuestions(buildClubFormQuestions(request.questions()));
if (request.title() != null)
clubApplicationForm.updateFormTitle(request.title());
if (request.description() != null)
clubApplicationForm.updateFormDescription(request.description());
if (request.active() != null)
clubApplicationForm.updateFormStatus(request.active());

if (request.semesterYear() != null || request.semesterTerm() != null) {
Integer semesterYear = Optional.ofNullable(request.semesterYear()).orElse(clubApplicationForm.getSemesterYear());
SemesterTerm semesterTerm = Optional.ofNullable(request.semesterTerm()).orElse(clubApplicationForm.getSemesterTerm());
validateSemester(semesterYear, semesterTerm);

clubApplicationForm.updateSemesterYear(semesterYear);
clubApplicationForm.updateSemesterTerm(semesterTerm);
}

for (var question : request.questions()) {
return clubApplicationForm;
}

private List<ClubApplicationFormQuestion> buildClubFormQuestions(List<ClubApplyQuestion> questions) {
List<ClubApplicationFormQuestion> formQuestions = new ArrayList<>();

for (var question : questions) {
List<ClubQuestionItem> items = new ArrayList<>();

for (var item : question.items()) {
Expand All @@ -348,18 +337,12 @@ private ClubApplicationForm updateQuestions(ClubApplicationForm clubApplicationF
.items(items)
.build();

newQuestions.add(clubApplicationFormQuestion);
formQuestions.add(clubApplicationFormQuestion);
}

clubApplicationForm.updateQuestions(newQuestions);
clubApplicationForm.updateFormTitle(request.title());
clubApplicationForm.updateFormDescription(request.description());
clubApplicationForm.updateFormStatus(request.active());

return clubApplicationForm;
return formQuestions;
}


// SSE 연결 생성
public SseEmitter createSseConnection(String applicationFormId, CustomUserDetails user) {
String clubId = user.getClubId();
Expand All @@ -376,7 +359,8 @@ public SseEmitter createSseConnection(String applicationFormId, CustomUserDetail
if (prev != null) {
try {
prev.complete();
} catch (Exception ignored) {}
} catch (Exception ignored) {
}
}

sseConnections.put(connectionKey, emitter);
Expand Down Expand Up @@ -409,7 +393,7 @@ private void sendStatusChangeEvent(String clubId, String applicationFormId, Appl
entries.forEach(entry -> {
String key = entry.getKey();
SseEmitter emitter = entry.getValue();

try {
emitter.send(SseEmitter.event()
.name("applicant-status-changed") // 이벤트 이름 지정
Expand All @@ -420,7 +404,8 @@ private void sendStatusChangeEvent(String clubId, String applicationFormId, Appl
sseConnections.remove(key, emitter);
try {
emitter.completeWithError(e); // emitter 쪽도 정상 종료
} catch (Exception ignore) {}
} catch (Exception ignore) {
}
}
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package moadong.fixture;

import moadong.club.enums.SemesterTerm;
import moadong.club.payload.request.ClubApplicationFormEditRequest;
import java.util.ArrayList;

Expand All @@ -18,7 +19,9 @@ public static ClubApplicationFormEditRequest createClubApplicationEditRequest(){
"테스트123",
"테스트 지원서입니다",
false,
new ArrayList<>()
new ArrayList<>(),
2025,
SemesterTerm.SECOND
);
}
}
Loading