diff --git a/src/main/java/com/econovation/third_project/agrregate/AdminPageQuery.java b/src/main/java/com/econovation/third_project/agrregate/AdminPageQuery.java new file mode 100644 index 0000000..a2b73bf --- /dev/null +++ b/src/main/java/com/econovation/third_project/agrregate/AdminPageQuery.java @@ -0,0 +1,9 @@ +package com.econovation.third_project.agrregate; + +import java.util.List; + +public interface AdminPageQuery { + String getType(); + List execute(); + +} diff --git a/src/main/java/com/econovation/third_project/agrregate/AdminPageQueryAggregator.java b/src/main/java/com/econovation/third_project/agrregate/AdminPageQueryAggregator.java new file mode 100644 index 0000000..69c5ed1 --- /dev/null +++ b/src/main/java/com/econovation/third_project/agrregate/AdminPageQueryAggregator.java @@ -0,0 +1,52 @@ +package com.econovation.third_project.agrregate; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.springframework.stereotype.Component; + +//TODO: 제네릭? +@Component +public class AdminPageQueryAggregator { + private final Map queries; + public AdminPageQueryAggregator(List queries) { + this.queries = queries.stream() + .collect(Collectors.toMap(AdminPageQuery::getType, Function.identity())); + } + + public Map> aggregate(Set requests){ + List queriesToExecute = getQueriesToExecute(requests); + Map>> executedQueries = executeQueriesAsync(queriesToExecute); + return aggregateResults(executedQueries); + } + + private List getQueriesToExecute(Set requests){ + return requests.stream() + .map(request -> Optional.ofNullable(queries.get(request)) + .orElseThrow(IllegalArgumentException::new) + ) + .toList(); + } + + private Map>> executeQueriesAsync(List queriesToExecute){ + return queriesToExecute.stream() + .collect(Collectors.toMap( + AdminPageQuery::getType, + query-> CompletableFuture.supplyAsync(query::execute) + )); + } + + private Map> aggregateResults(Map>> executedQueries) { + return CompletableFuture.allOf(executedQueries.values().toArray(new CompletableFuture[0])) + .>>thenApply(v -> + executedQueries.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().join())) + ) + .join(); + } + +} diff --git a/src/main/java/com/econovation/third_project/agrregate/PathQuery.java b/src/main/java/com/econovation/third_project/agrregate/PathQuery.java new file mode 100644 index 0000000..cdd14f1 --- /dev/null +++ b/src/main/java/com/econovation/third_project/agrregate/PathQuery.java @@ -0,0 +1,21 @@ +package com.econovation.third_project.agrregate; + +import com.econovation.third_project.service.PathService; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class PathQuery implements AdminPageQuery{ + private final PathService pathService; + @Override + public String getType() { + return "path"; + } + + @Override + public List execute() { + return pathService.getApplicantNumberEachPath(); + } +} diff --git a/src/main/java/com/econovation/third_project/config/Field.java b/src/main/java/com/econovation/third_project/config/Field.java new file mode 100644 index 0000000..3d9ebb2 --- /dev/null +++ b/src/main/java/com/econovation/third_project/config/Field.java @@ -0,0 +1,20 @@ +package com.econovation.third_project.config; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Getter +public enum Field { + WEB("WEB"), + APP("APP"), + AI("AI"), + GAME("GAME"), + IOT("IoT"), + ARVR("AR/VR"), + NONE("선택없음"); + + private final String fieldName; + + +} diff --git a/src/main/java/com/econovation/third_project/config/Job.java b/src/main/java/com/econovation/third_project/config/Job.java new file mode 100644 index 0000000..0c431da --- /dev/null +++ b/src/main/java/com/econovation/third_project/config/Job.java @@ -0,0 +1,14 @@ +package com.econovation.third_project.config; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Getter +public enum Job { + DEVELOPER("개발자"), + PLANNER("기획자"), + DESIGNER("디자이너"); + + private final String jobName; +} diff --git a/src/main/java/com/econovation/third_project/config/SupportPath.java b/src/main/java/com/econovation/third_project/config/SupportPath.java new file mode 100644 index 0000000..be783e4 --- /dev/null +++ b/src/main/java/com/econovation/third_project/config/SupportPath.java @@ -0,0 +1,16 @@ +package com.econovation.third_project.config; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Getter +public enum SupportPath { + POSTER("홍보 포스터"), + DEPARTMENT_ANNOUNCEMENT("학과 공지사항"), + ACQUAINTANCE("지인 소개"), + INSTAGRAM("인스타그램"), + EVERYTIME("에브리타임"); + private final String entryPathName; + +} diff --git a/src/main/java/com/econovation/third_project/controller/AdminQueryController.java b/src/main/java/com/econovation/third_project/controller/AdminQueryController.java index 4c15adb..5d911ce 100644 --- a/src/main/java/com/econovation/third_project/controller/AdminQueryController.java +++ b/src/main/java/com/econovation/third_project/controller/AdminQueryController.java @@ -1,28 +1,36 @@ package com.econovation.third_project.controller; -import com.econovation.third_project.database.Database; -import com.econovation.third_project.database.Registration; +import com.econovation.third_project.agrregate.AdminPageQueryAggregator; +import java.util.List; +import java.util.Map; +import java.util.Set; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequiredArgsConstructor +@RequestMapping("/api/admin") public class AdminQueryController { - private final Database database; + private final AdminPageQueryAggregator adminPageQueryAggregator; - // 예시 코드 - @PostMapping("/registration") - public ResponseEntity postRegistrate(@RequestBody Registration registration) { - database.register(registration); - return ResponseEntity.ok().build(); - } - @GetMapping("/registration") - public ResponseEntity getRegistration(String userId) { - return ResponseEntity.ok().body(database.getRegistration(userId)); + @GetMapping("/applicants/async-test") + public ResponseEntity>> getApplicantsInfo(@RequestBody Set fields){ + return ResponseEntity.ok().body( + adminPageQueryAggregator.aggregate(fields)); } + + //TODO: + // 병렬 스트림 + async의 장점, + // 병렬 스트림, async 각각 적절한 상황, + // 서비스 메서드마다 다른 인자가 필요한 경우, + // 일부 의존 관계가 있을경우 어떻게 처리할지 + // 서비스 메서드 맵 어떻게 뺄지, + // 적절한 스레드 수 알아보기, + // 자바 비동기 기초, + } diff --git a/src/main/java/com/econovation/third_project/controller/ApplicationController.java b/src/main/java/com/econovation/third_project/controller/ApplicationController.java new file mode 100644 index 0000000..ce15d15 --- /dev/null +++ b/src/main/java/com/econovation/third_project/controller/ApplicationController.java @@ -0,0 +1,22 @@ +package com.econovation.third_project.controller; + +import com.econovation.third_project.dto.CreateApplicationReq; +import com.econovation.third_project.service.ApplicationService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RequestMapping("/api") +@RequiredArgsConstructor +@RestController +public class ApplicationController { + private final ApplicationService applicationService; + + @PostMapping("/application") + public ResponseEntity createApplication(@RequestBody CreateApplicationReq createApplicationReq){ + return ResponseEntity.ok().body(applicationService.createApplication(createApplicationReq)); + } +} diff --git a/src/main/java/com/econovation/third_project/database/Application.java b/src/main/java/com/econovation/third_project/database/Application.java new file mode 100644 index 0000000..2654ba9 --- /dev/null +++ b/src/main/java/com/econovation/third_project/database/Application.java @@ -0,0 +1,36 @@ +package com.econovation.third_project.database; + +import java.util.concurrent.atomic.AtomicInteger; +import lombok.Builder; +import lombok.Getter; +import lombok.NonNull; + + +@Getter +public final class Application { + private static final AtomicInteger lastUsedId = new AtomicInteger(0); + @NonNull + private final Integer applicationId = lastUsedId.getAndIncrement(); + @NonNull + private final Registration registration; + @NonNull + private final PersonalInformation personalInformation; + @NonNull + private final Path path; + @NonNull + private final DesiredTime desiredTime; + + @Builder + public Application(Registration registration, PersonalInformation personalInformation, + Path path, + DesiredTime desiredTime) { + this.registration = registration; + this.personalInformation = personalInformation; + this.path = path; + this.desiredTime = desiredTime; + } +} + + + + diff --git a/src/main/java/com/econovation/third_project/database/Database.java b/src/main/java/com/econovation/third_project/database/Database.java index 33b8710..f7eee3c 100644 --- a/src/main/java/com/econovation/third_project/database/Database.java +++ b/src/main/java/com/econovation/third_project/database/Database.java @@ -1,8 +1,9 @@ package com.econovation.third_project.database; -import java.util.HashMap; +import java.util.Collection; import java.util.Map; -import java.util.UUID; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.stereotype.Component; /** @@ -11,18 +12,65 @@ */ @Component public class Database { - private final Map registration = new HashMap<>(); - private final Map path = new HashMap<>(); - private final Map personalInformation = new HashMap<>(); - private final Map desiredTime = new HashMap<>(); + //key: user id, value: application id + private final Map applications = new ConcurrentHashMap<>(); + //key: application id + private final Map registrations = new ConcurrentHashMap<>(); + //key: application id + private final Map paths = new ConcurrentHashMap<>(); + //key: application id + private final Map personalInformation = new ConcurrentHashMap<>(); + //key: application id + private final Map desiredTimes = new ConcurrentHashMap<>(); - - public void register(Registration registrationRequest) { - // 기본적으로 이전 제출시 등록된 정보가 있으면 덮어쓰기를 지원합니다. - registration.put(UUID.randomUUID().toString(), registrationRequest); + public Collection getAllRegistrations(){ + return registrations.values(); + } + public Collection getAllPersonalInformation(){ + return personalInformation.values(); + } + public Collection getAllPath() { + return paths.values(); + } + public Collection getAllDesiredTime(){ + return desiredTimes.values(); } - public Registration getRegistration(String userId) { - return registration.get(userId); + //지원자는 userId가 없으니 같은 지원서인지 판단할 기준을 따로 만들어야 함 + public Integer upsertApplication(Integer userId, Application application){ + Integer applicationId = applications.computeIfAbsent(userId, k -> application.getApplicationId()); + upsertRegistration(applicationId, application.getRegistration()); + upsertPath(applicationId, application.getPath()); + upsertDesiredTime(applicationId, application.getDesiredTime()); + upsertPersonalInformation(applicationId, application.getPersonalInformation()); + return applicationId; + } + public void upsertRegistration(Integer applicationId, Registration registration){ + registrations.put(applicationId, registration); + } + public void upsertPath(Integer applicationId, Path path){ + paths.put(applicationId, path); + } + public void upsertPersonalInformation(Integer applicationId, PersonalInformation personalInformation){ + this.personalInformation.put(applicationId, personalInformation); + } + public void upsertDesiredTime(Integer applicationId, DesiredTime desiredTime){ + desiredTimes.put(applicationId, desiredTime); } + + + +// public void register(Registration registrationRequest) { +// // 기본적으로 이전 제출시 등록된 정보가 있으면 덮어쓰기를 지원합니다. +// registration.put(UUID.randomUUID().toString(), registrationRequest); +// } +// +// public Registration getRegistration(String userId) { +// return registration.get(userId); +// } + + + + + } \ No newline at end of file diff --git a/src/main/java/com/econovation/third_project/database/DesiredTime.java b/src/main/java/com/econovation/third_project/database/DesiredTime.java index 2d7a140..475fe64 100644 --- a/src/main/java/com/econovation/third_project/database/DesiredTime.java +++ b/src/main/java/com/econovation/third_project/database/DesiredTime.java @@ -1,13 +1,32 @@ package com.econovation.third_project.database; +import java.util.HashMap; import java.util.List; -import lombok.AllArgsConstructor; +import java.util.Map; import lombok.Getter; -@AllArgsConstructor @Getter public class DesiredTime { - String registrationId; - // 희망 시간 (11 * 3)의 테이블 형태를 준수합니다. - private List desiredTime; + private static final Map, List> cachedTimes = new HashMap<>(); + private final List> desiredTimes; + + public DesiredTime(List> desiredTimes) { + validateDesiredTime(desiredTimes); + this.desiredTimes = desiredTimes.stream() + .map(time-> cachedTimes.computeIfAbsent(time, t->t)) + .toList(); + } + private void validateDesiredTime(List> desiredTimes) { + //27기 기준 + int interviewDays = 3; + int hoursPerDay = 11; + + desiredTimes.forEach( + time -> { + if (time.get(0) >= interviewDays || time.get(1) >= hoursPerDay) + throw new IllegalArgumentException("면접 시간 잘못 입력"); + } + ); + + } } diff --git a/src/main/java/com/econovation/third_project/database/Path.java b/src/main/java/com/econovation/third_project/database/Path.java index 727433c..b7ddc9a 100644 --- a/src/main/java/com/econovation/third_project/database/Path.java +++ b/src/main/java/com/econovation/third_project/database/Path.java @@ -1,12 +1,27 @@ package com.econovation.third_project.database; +import com.econovation.third_project.config.SupportPath; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collector; import lombok.AllArgsConstructor; import lombok.Getter; -@AllArgsConstructor @Getter -public class Path { - String registrationId; +public class Path{ // 지원 경로 - private String supportPath; + private final EnumSet supportPaths; + + public Path(EnumSet supportPaths) { + this.supportPaths = supportPaths; + } + + public static Path from(Set stringPaths){ + EnumSet enumPaths = EnumSet.noneOf(SupportPath.class); + stringPaths.stream() + .forEach(stringPath-> enumPaths.add(SupportPath.valueOf(stringPath.toUpperCase()))); + return new Path(enumPaths); + } } diff --git a/src/main/java/com/econovation/third_project/database/PersonalInformation.java b/src/main/java/com/econovation/third_project/database/PersonalInformation.java index 8a17b8a..40f8c7a 100644 --- a/src/main/java/com/econovation/third_project/database/PersonalInformation.java +++ b/src/main/java/com/econovation/third_project/database/PersonalInformation.java @@ -1,12 +1,13 @@ package com.econovation.third_project.database; +import java.util.Optional; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; -@AllArgsConstructor @Getter +@Builder public class PersonalInformation { - private String registrationId; // 이름 private String name; @@ -31,8 +32,15 @@ public class PersonalInformation { // 부전공 private String minor; - - // 이메일 private String email; + + public Optional getDoubleMajor() { + return Optional.ofNullable(this.doubleMajor); + } + + public Optional getMinor() { + return Optional.ofNullable(this.minor); + } + } diff --git a/src/main/java/com/econovation/third_project/database/Registration.java b/src/main/java/com/econovation/third_project/database/Registration.java index be42739..e1df4c6 100644 --- a/src/main/java/com/econovation/third_project/database/Registration.java +++ b/src/main/java/com/econovation/third_project/database/Registration.java @@ -1,21 +1,30 @@ package com.econovation.third_project.database; +import com.econovation.third_project.config.Field; +import com.econovation.third_project.config.Job; +import java.util.Optional; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NonNull; @Getter +@AllArgsConstructor(access = AccessLevel.PRIVATE) public class Registration { - // 희망분야 - private String hopeField; + @NonNull + private Job hopeJob; + @NonNull + private Field firstPriority; + @Getter + private Field secondPriority; - // 1지망 - private String firstPriority; + public static Registration of(@NonNull String hopeJob, @NonNull String firstJobFieldName, String secondJobFieldName){ + Job job = Job.valueOf(hopeJob.toUpperCase()); - // 2지망 - private String secondPriority; + Field firstPriority = Field.valueOf(firstJobFieldName.toUpperCase()); + Field secondPriority = Field.valueOf(secondJobFieldName.toUpperCase()); - public Registration(String hopeField, String firstPriority, String secondPriority) { - this.hopeField = hopeField; - this.firstPriority = firstPriority; - this.secondPriority = secondPriority; + return new Registration(job, firstPriority, secondPriority); } + } diff --git a/src/main/java/com/econovation/third_project/database/User.java b/src/main/java/com/econovation/third_project/database/User.java new file mode 100644 index 0000000..79f2eec --- /dev/null +++ b/src/main/java/com/econovation/third_project/database/User.java @@ -0,0 +1,12 @@ +package com.econovation.third_project.database; + +import java.util.concurrent.atomic.AtomicInteger; + +public class User { + private static final AtomicInteger lastUsedId = new AtomicInteger(0); + + private static int nextId(){ + return lastUsedId.getAndIncrement(); + } + +} diff --git a/src/main/java/com/econovation/third_project/dto/ApplicantNumberInField.java b/src/main/java/com/econovation/third_project/dto/ApplicantNumberInField.java new file mode 100644 index 0000000..59b277d --- /dev/null +++ b/src/main/java/com/econovation/third_project/dto/ApplicantNumberInField.java @@ -0,0 +1,19 @@ +package com.econovation.third_project.dto; + +import com.econovation.third_project.config.Field; +import java.util.Map.Entry; + +public record ApplicantNumberInField(String fieldName, int firstNumber, int secondNumber) implements Comparable{ + @Override + public int compareTo(ApplicantNumberInField o) { + return (this.firstNumber+this.secondNumber) - (o.firstNumber + o.secondNumber); + } + + public ApplicantNumberInField(Entry entry) { + this( + entry.getKey().getFieldName(), + entry.getValue()[0], + entry.getValue()[1] + ); + } +} diff --git a/src/main/java/com/econovation/third_project/dto/ApplicantNumberInJob.java b/src/main/java/com/econovation/third_project/dto/ApplicantNumberInJob.java new file mode 100644 index 0000000..08440d9 --- /dev/null +++ b/src/main/java/com/econovation/third_project/dto/ApplicantNumberInJob.java @@ -0,0 +1,5 @@ +package com.econovation.third_project.dto; + +public record ApplicantNumberInJob(String jobName, int number) { + +} diff --git a/src/main/java/com/econovation/third_project/dto/ApplicantNumberInMajor.java b/src/main/java/com/econovation/third_project/dto/ApplicantNumberInMajor.java new file mode 100644 index 0000000..454b647 --- /dev/null +++ b/src/main/java/com/econovation/third_project/dto/ApplicantNumberInMajor.java @@ -0,0 +1,5 @@ +package com.econovation.third_project.dto; + +public record ApplicantNumberInMajor(String majorName, int number){ + +} diff --git a/src/main/java/com/econovation/third_project/dto/ApplicantNumberInPath.java b/src/main/java/com/econovation/third_project/dto/ApplicantNumberInPath.java new file mode 100644 index 0000000..14ca7f7 --- /dev/null +++ b/src/main/java/com/econovation/third_project/dto/ApplicantNumberInPath.java @@ -0,0 +1,5 @@ +package com.econovation.third_project.dto; + +public record ApplicantNumberInPath(String entryPathName, int number){ + +} diff --git a/src/main/java/com/econovation/third_project/dto/ApplicantNumberInTime.java b/src/main/java/com/econovation/third_project/dto/ApplicantNumberInTime.java new file mode 100644 index 0000000..6946684 --- /dev/null +++ b/src/main/java/com/econovation/third_project/dto/ApplicantNumberInTime.java @@ -0,0 +1,7 @@ +package com.econovation.third_project.dto; + +import java.util.List; + +public record ApplicantNumberInTime(List time, int number) { + +} diff --git a/src/main/java/com/econovation/third_project/dto/CreateApplicationReq.java b/src/main/java/com/econovation/third_project/dto/CreateApplicationReq.java new file mode 100644 index 0000000..1962db6 --- /dev/null +++ b/src/main/java/com/econovation/third_project/dto/CreateApplicationReq.java @@ -0,0 +1,17 @@ +package com.econovation.third_project.dto; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.NonNull; + +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +public record CreateApplicationReq( + @NonNull + RegistrationReq registration, + @NonNull + PersonalInformationReq personalInformation, + @NonNull + PathReq path, + @NonNull + DesiredTimeReq desiredTime + ){} diff --git a/src/main/java/com/econovation/third_project/dto/DesiredTimeReq.java b/src/main/java/com/econovation/third_project/dto/DesiredTimeReq.java new file mode 100644 index 0000000..97db7ea --- /dev/null +++ b/src/main/java/com/econovation/third_project/dto/DesiredTimeReq.java @@ -0,0 +1,10 @@ +package com.econovation.third_project.dto; + +import com.econovation.third_project.database.DesiredTime; +import java.util.List; + +public record DesiredTimeReq(List> desiredTimes){ + public DesiredTime toEntity(){ + return new DesiredTime(desiredTimes); + } +} diff --git a/src/main/java/com/econovation/third_project/dto/PathReq.java b/src/main/java/com/econovation/third_project/dto/PathReq.java new file mode 100644 index 0000000..b6bf969 --- /dev/null +++ b/src/main/java/com/econovation/third_project/dto/PathReq.java @@ -0,0 +1,10 @@ +package com.econovation.third_project.dto; + +import com.econovation.third_project.database.Path; +import java.util.Set; + +public record PathReq(Set paths) { + public Path toEntity(){ + return Path.from(paths); + } +} diff --git a/src/main/java/com/econovation/third_project/dto/PersonalInformationReq.java b/src/main/java/com/econovation/third_project/dto/PersonalInformationReq.java new file mode 100644 index 0000000..e0abbde --- /dev/null +++ b/src/main/java/com/econovation/third_project/dto/PersonalInformationReq.java @@ -0,0 +1,28 @@ +package com.econovation.third_project.dto; + +import com.econovation.third_project.database.PersonalInformation; + +public record PersonalInformationReq( + String name, + String phoneNumber, + Integer studentId, + Integer grade, + Integer semester, + String major, + String doubleMajor, + String minor, + String email) { + public PersonalInformation toEntity(){ + return PersonalInformation.builder() + .name(this.name) + .doubleMajor(this.doubleMajor) + .email(this.email) + .grade(this.grade) + .major(this.major) + .minor(this.minor) + .phoneNumber(this.phoneNumber) + .semester(this.semester) + .studentId(this.studentId) + .build(); + } +} diff --git a/src/main/java/com/econovation/third_project/dto/PostRegistrationRes.java b/src/main/java/com/econovation/third_project/dto/PostRegistrationRes.java new file mode 100644 index 0000000..e247f17 --- /dev/null +++ b/src/main/java/com/econovation/third_project/dto/PostRegistrationRes.java @@ -0,0 +1,5 @@ +package com.econovation.third_project.dto; + +public record PostRegistrationRes(String registrationId) { + +} diff --git a/src/main/java/com/econovation/third_project/dto/RegistrationReq.java b/src/main/java/com/econovation/third_project/dto/RegistrationReq.java new file mode 100644 index 0000000..b02f82c --- /dev/null +++ b/src/main/java/com/econovation/third_project/dto/RegistrationReq.java @@ -0,0 +1,12 @@ +package com.econovation.third_project.dto; + +import com.econovation.third_project.database.Registration; + +public record RegistrationReq(String job, String firstPriority, String secondPriority) { + public RegistrationReq{ + System.out.println(job); + } + public Registration toEntity(){ + return Registration.of(this.job, this.firstPriority, this.secondPriority); + } +} diff --git a/src/main/java/com/econovation/third_project/service/ApplicationService.java b/src/main/java/com/econovation/third_project/service/ApplicationService.java new file mode 100644 index 0000000..d702f3b --- /dev/null +++ b/src/main/java/com/econovation/third_project/service/ApplicationService.java @@ -0,0 +1,23 @@ +package com.econovation.third_project.service; + +import com.econovation.third_project.database.Application; +import com.econovation.third_project.database.Database; +import com.econovation.third_project.dto.CreateApplicationReq; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class ApplicationService { + private final Database db; + public int createApplication(CreateApplicationReq createApplicationReq){ + Application application = Application.builder() + .registration(createApplicationReq.registration().toEntity()) + .personalInformation(createApplicationReq.personalInformation().toEntity()) + .path(createApplicationReq.path().toEntity()) + .desiredTime(createApplicationReq.desiredTime().toEntity()) + .build(); + return db.upsertApplication(1, application); + } + +} diff --git a/src/main/java/com/econovation/third_project/service/DesiredTimeService.java b/src/main/java/com/econovation/third_project/service/DesiredTimeService.java new file mode 100644 index 0000000..bbe21cb --- /dev/null +++ b/src/main/java/com/econovation/third_project/service/DesiredTimeService.java @@ -0,0 +1,32 @@ +package com.econovation.third_project.service; + +import com.econovation.third_project.database.Database; +import com.econovation.third_project.dto.ApplicantNumberInJob; +import com.econovation.third_project.dto.ApplicantNumberInTime; +import java.util.List; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class DesiredTimeService { + private final Database db; + + //입력할 때 2개인지 확인해야 함 + + public List getApplicantNumberEachTime(){ + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + return db.getAllDesiredTime().stream() + .flatMap(desiredTime -> desiredTime.getDesiredTimes().stream()) + .collect(Collectors.groupingBy(time -> time, Collectors.counting())) + .entrySet().stream() + .map(entry->new ApplicantNumberInTime(entry.getKey(), entry.getValue().intValue())) + .toList(); + } + +} diff --git a/src/main/java/com/econovation/third_project/service/PathService.java b/src/main/java/com/econovation/third_project/service/PathService.java new file mode 100644 index 0000000..84158c5 --- /dev/null +++ b/src/main/java/com/econovation/third_project/service/PathService.java @@ -0,0 +1,30 @@ +package com.econovation.third_project.service; + +import com.econovation.third_project.database.Database; +import com.econovation.third_project.dto.ApplicantNumberInPath; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class PathService { + private final Database db; + + public List getApplicantNumberEachPath(){ + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + return db.getAllPath().stream() + .flatMap(path-> path.getSupportPaths().stream()) + .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) + .entrySet().stream() + .map(entry->new ApplicantNumberInPath(entry.getKey().getEntryPathName(), entry.getValue().intValue())) + .toList(); + } + +} diff --git a/src/main/java/com/econovation/third_project/service/PersonalInformationService.java b/src/main/java/com/econovation/third_project/service/PersonalInformationService.java new file mode 100644 index 0000000..b53964f --- /dev/null +++ b/src/main/java/com/econovation/third_project/service/PersonalInformationService.java @@ -0,0 +1,36 @@ +package com.econovation.third_project.service; + +import com.econovation.third_project.database.Database; +import com.econovation.third_project.dto.ApplicantNumberInMajor; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class PersonalInformationService { + private final Database db; + + //학과별 지원자 수 + public List getApplicantNumberEachMajor(){ + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + return db.getAllPersonalInformation().stream() + .flatMap(info-> Stream.of(info.getMajor(), info.getDoubleMajor().orElse(null))) + .filter(Objects::nonNull) + .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) + .entrySet().stream() + .map(entry-> new ApplicantNumberInMajor(entry.getKey(), entry.getValue().intValue())) + .toList(); + } +} \ No newline at end of file diff --git a/src/main/java/com/econovation/third_project/service/RegistrationService.java b/src/main/java/com/econovation/third_project/service/RegistrationService.java new file mode 100644 index 0000000..9d93610 --- /dev/null +++ b/src/main/java/com/econovation/third_project/service/RegistrationService.java @@ -0,0 +1,74 @@ +package com.econovation.third_project.service; + + +import com.econovation.third_project.database.Database; +import com.econovation.third_project.config.Field; +import com.econovation.third_project.config.Job; +import com.econovation.third_project.database.Registration; +import com.econovation.third_project.dto.ApplicantNumberInJob; +import com.econovation.third_project.dto.ApplicantNumberInField; +import static java.util.Comparator.reverseOrder; + +import java.util.Collection; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + + + + +@Service +@RequiredArgsConstructor +public class RegistrationService { + private final Database db; + + //분야별 지원자 수 + public List getApplicantNumbersEachJob(){ + return db.getAllRegistrations().stream() + .collect(Collectors.groupingBy(Registration::getHopeJob, Collectors.counting())) + .entrySet().stream() + .sorted(Map.Entry.comparingByValue().reversed()) + .map(entry->new ApplicantNumberInJob(entry.getKey().getJobName(), entry.getValue().intValue())) + .toList(); + } + + //세부 분야별 지원자 수 + public List getApplicantNumberEachField(){ + return PriorityCounts.of(db.getAllRegistrations()) + .getJobPriorityCounts() + .entrySet().stream() + .map(ApplicantNumberInField::new) + .sorted(reverseOrder()) + .toList(); + } + +} + +@Getter +final class PriorityCounts{ + private final Map jobPriorityCounts = new EnumMap<>(Field.class); + + private PriorityCounts() { + for (Field field : Field.values()) + jobPriorityCounts.put(field, new int[2]); + } + static PriorityCounts of(Collection registrations){ + PriorityCounts priorityCounts = new PriorityCounts(); + registrations.forEach(regi->{ + priorityCounts.incrementFirstPriority(regi.getFirstPriority()); + priorityCounts.incrementSecondPriority(regi.getSecondPriority()); + }); + return priorityCounts; + } + + private void incrementFirstPriority(Field field){ + jobPriorityCounts.get(field)[0]++; + } + private void incrementSecondPriority(Field field){ + jobPriorityCounts.get(field)[1]++; + } +}