Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DDING-97] 동아리 지원 폼지 통계 전체조회 API 구현 #242

Merged
merged 18 commits into from
Feb 9, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
@@ -0,0 +1,11 @@
package ddingdong.ddingdongBE.common.utils;

public class CalculationUtils {

public static int calculateRate(int count, int totalCount) {
if (totalCount == 0) {
return 0;
}
return (int) ((double) count / totalCount * 100);
}
}
41 changes: 23 additions & 18 deletions src/main/java/ddingdong/ddingdongBE/common/utils/TimeUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,36 @@

public class TimeUtils {

private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm";
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm";

public static LocalDateTime parseToLocalDateTime(String dateString) {
if (dateString == null || dateString.isBlank()) {
return null;
public static LocalDateTime parseToLocalDateTime(String dateString) {
if (dateString == null || dateString.isBlank()) {
return null;
}

return LocalDateTime.parse(dateString, DateTimeFormatter.ofPattern(DATE_FORMAT));
}

return LocalDateTime.parse(dateString, DateTimeFormatter.ofPattern(DATE_FORMAT));
}
public static LocalDateTime processDate(String dateString, LocalDateTime currentDate) {
if (dateString == null) {
return null;
}

public static LocalDateTime processDate(String dateString, LocalDateTime currentDate) {
if (dateString == null) {
return null;
}
if (dateString.isBlank()) {
return null;
}

if (dateString.isBlank()) {
return null;
return parseToLocalDateTime(dateString);
}

return parseToLocalDateTime(dateString);
}
public static boolean isDateInRange(LocalDate nowDate, LocalDate startDate, LocalDate endDate) {
if (nowDate == null || startDate == null || endDate == null) {
return false;
}
return !nowDate.isBefore(startDate) && !nowDate.isAfter(endDate);
}

public static boolean isDateInRange(LocalDate nowDate, LocalDate startDate, LocalDate endDate) {
if (nowDate == null || startDate == null || endDate == null) {
return false;
public static boolean isFirstHalf(int month) {
return month >= 1 && month <= 6;
}
return !nowDate.isBefore(startDate) && !nowDate.isAfter(endDate); }
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import ddingdong.ddingdongBE.domain.form.controller.dto.request.UpdateFormRequest;
import ddingdong.ddingdongBE.domain.form.controller.dto.response.FormListResponse;
import ddingdong.ddingdongBE.domain.form.controller.dto.response.FormResponse;
import ddingdong.ddingdongBE.domain.form.controller.dto.response.FormStatisticsResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
Expand Down Expand Up @@ -68,17 +69,21 @@ void deleteForm(
@ResponseStatus(HttpStatus.OK)
@SecurityRequirement(name = "AccessToken")
@GetMapping("/my/forms")
List<FormListResponse> getAllMyForm(
@AuthenticationPrincipal PrincipalDetails principalDetails
);
List<FormListResponse> getAllMyForm(@AuthenticationPrincipal PrincipalDetails principalDetails);

@Operation(summary = "동아리 지원 폼지 상세조회 API")
@ApiResponse(responseCode = "200", description = "동아리 지원 폼지 상세조회 성공",
content = @Content(schema = @Schema(implementation = FormResponse.class)))
@ResponseStatus(HttpStatus.OK)
@SecurityRequirement(name = "AccessToken")
@GetMapping("/my/forms/{formId}")
FormResponse getForm(
@PathVariable("formId") Long formId
);
FormResponse getForm(@PathVariable("formId") Long formId);

@Operation(summary = "동아리 지원 폼지 통계 전체조회 API")
@ApiResponse(responseCode = "200", description = "동아리 지원 폼지 통계 전체조회 성공",
content = @Content(schema = @Schema(implementation = FormStatisticsResponse.class)))
@ResponseStatus(HttpStatus.OK)
@SecurityRequirement(name = "AccessToken")
@GetMapping("/my/forms/{formId}/statistics")
FormStatisticsResponse getFormStatistics(@PathVariable("formId") Long formId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import ddingdong.ddingdongBE.domain.form.controller.dto.request.UpdateFormRequest;
import ddingdong.ddingdongBE.domain.form.controller.dto.response.FormListResponse;
import ddingdong.ddingdongBE.domain.form.controller.dto.response.FormResponse;
import ddingdong.ddingdongBE.domain.form.controller.dto.response.FormStatisticsResponse;
import ddingdong.ddingdongBE.domain.form.service.FacadeCentralFormService;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormListQuery;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormQuery;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery;
import ddingdong.ddingdongBE.domain.user.entity.User;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -58,4 +60,10 @@ public FormResponse getForm(Long formId) {
FormQuery query = facadeCentralFormService.getForm(formId);
return FormResponse.from(query);
}

@Override
public FormStatisticsResponse getFormStatistics(Long formId) {
FormStatisticsQuery query = facadeCentralFormService.getStatisticsByForm(formId);
return FormStatisticsResponse.from(query);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package ddingdong.ddingdongBE.domain.form.controller.dto.response;

import ddingdong.ddingdongBE.domain.form.entity.FieldType;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery.ApplicantRateQuery;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery.DepartmentRankQuery;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery.FieldStatisticsListQuery;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.Builder;

@Builder
public record FormStatisticsResponse(
@Schema(description = "총 지원자 수", example = "50")
int totalCount,
@ArraySchema(schema = @Schema(implementation = DepartmentRankResponse.class))
List<DepartmentRankResponse> departmentRanks,
@ArraySchema(schema = @Schema(implementation = ApplicantRateResponse.class))
List<ApplicantRateResponse> applicantRates,
@ArraySchema(schema = @Schema(implementation = FieldStatisticsListResponse.class))
List<FieldStatisticsListResponse> fields
) {

@Builder
record DepartmentRankResponse(
@Schema(description = "학과 내 경쟁 순위", example = "1")
int rank,
@Schema(description = "학과명", example = "융합소프트웨어학부")
String label,
@Schema(description = "해당 학과의 지원자 수", example = "50")
int count,
@Schema(description = "전체 지원자 수 대비 비율", example = "30")
int rate
) {

public static DepartmentRankResponse from(DepartmentRankQuery query) {
return DepartmentRankResponse.builder()
.rank(query.rank())
.label(query.label())
.count(query.count())
.rate(query.rate())
.build();
}
}

@Builder
record ApplicantRateResponse(
@Schema(description = "비교 년도 및 학기", example = "2025-1")
String label,
@Schema(description = "해당 년도 및 학기 총 지원자수", example = "40")
int count,
@Schema(description = "비교 대비 비율", example = "150")
int comparedToLastSemester
) {
public static ApplicantRateResponse from(ApplicantRateQuery query) {
return ApplicantRateResponse.builder()
.label(query.label())
.count(query.count())
.comparedToLastSemester(query.comparedToLastSemester())
.build();
}

}

@Builder
record FieldStatisticsListResponse(
@Schema(description = "폼지 질문 id", example = "1")
Long id,
@Schema(description = "폼지 질문", example = "당신 이름은 무엇인가요?")
String question,
@Schema(description = "폼지 질문에 대해 총 작성 개수", example = "20")
int count,
@Schema(description = "폼지 질문 유형", example = "CHECK_BOX")
FieldType type
) {

public static FieldStatisticsListResponse from(FieldStatisticsListQuery query) {
return FieldStatisticsListResponse.builder()
.id(query.id())
.question(query.question())
.count(query.count())
.type(query.fieldType())
.build();
}
}

public static FormStatisticsResponse from(FormStatisticsQuery query) {
List<DepartmentRankResponse> departmentRankResponses = query.departmentRanks().stream()
.map(DepartmentRankResponse::from)
.toList();
List<ApplicantRateResponse> applicantRateResponses = query.applicantRates().stream()
.map(ApplicantRateResponse::from)
.toList();
List<FieldStatisticsListResponse> fieldStatisticsListResponses = query.fields().stream()
.map(FieldStatisticsListResponse::from)
.toList();
return FormStatisticsResponse.builder()
.totalCount(query.totalCount())
.departmentRanks(departmentRankResponses)
.applicantRates(applicantRateResponses)
.fields(fieldStatisticsListResponses)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import ddingdong.ddingdongBE.domain.form.service.dto.command.UpdateFormCommand;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormListQuery;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormQuery;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery;
import ddingdong.ddingdongBE.domain.user.entity.User;
import java.util.List;

Expand All @@ -18,4 +19,6 @@ public interface FacadeCentralFormService {
List<FormListQuery> getAllMyForm(User user);

FormQuery getForm(Long formId);

FormStatisticsQuery getStatisticsByForm(Long formId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
import ddingdong.ddingdongBE.domain.form.service.dto.command.UpdateFormCommand.UpdateFormFieldCommand;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormListQuery;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormQuery;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery.ApplicantRateQuery;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery.DepartmentRankQuery;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery.FieldStatisticsListQuery;
import ddingdong.ddingdongBE.domain.user.entity.User;
import java.time.LocalDate;
import java.util.List;
Expand All @@ -28,6 +32,7 @@ public class FacadeCentralFormServiceImpl implements FacadeCentralFormService {
private final FormService formService;
private final FormFieldService formFieldService;
private final ClubService clubService;
private final FormStatisticService formStatisTicService;
KoSeonJe marked this conversation as resolved.
Show resolved Hide resolved

@Transactional
@Override
Expand Down Expand Up @@ -79,6 +84,16 @@ public FormQuery getForm(Long formId) {
return FormQuery.of(form, formFields);
}

@Override
public FormStatisticsQuery getStatisticsByForm(Long formId) {
Form form = formService.getById(formId);
int totalCount = formStatisTicService.getTotalApplicationCountByForm(form);
List<DepartmentRankQuery> departmentRankQueries = formStatisTicService.createDepartmentRankByForm(form);
List<ApplicantRateQuery> applicantRateQueries = formStatisTicService.createApplicationRateByForm(form);
List<FieldStatisticsListQuery> fieldStatisticsListQueries = formStatisTicService.createFieldStatisticsListByForm(form);
return new FormStatisticsQuery(totalCount, departmentRankQueries, applicantRateQueries, fieldStatisticsListQueries);
}

private FormListQuery buildFormListQuery(Form form) {
boolean isActive = TimeUtils.isDateInRange(LocalDate.now(), form.getStartDate(), form.getEndDate());
return FormListQuery.from(form, isActive);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ddingdong.ddingdongBE.domain.form.service;

import ddingdong.ddingdongBE.domain.form.entity.Form;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery.ApplicantRateQuery;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery.DepartmentRankQuery;
import ddingdong.ddingdongBE.domain.form.service.dto.query.FormStatisticsQuery.FieldStatisticsListQuery;
import java.util.List;

public interface FormStatisticService {

int getTotalApplicationCountByForm(Form form);

List<DepartmentRankQuery> createDepartmentRankByForm(Form form);

List<ApplicantRateQuery> createApplicationRateByForm(Form form);

List<FieldStatisticsListQuery> createFieldStatisticsListByForm(Form form);
}
Loading