From fa626f00c92fd87c086dac18dea3b83e38789eae Mon Sep 17 00:00:00 2001 From: yunhacandy Date: Fri, 12 Jan 2024 17:34:34 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=A0=84=EC=B2=B4=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=EC=84=A4=EA=B3=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ManageController.java | 37 ++++++++ .../java/cotato/cotatomanage/domain/Part.java | 17 ++++ .../domain/dto/JoinMemberRequest.java | 11 +++ .../domain/dto/MemberResponse.java | 32 +++++++ .../cotatomanage/domain/dto/PartResponse.java | 30 ++++++ .../cotatomanage/domain/entity/Member.java | 94 +++++++++++++++++++ .../repository/MemberRepository.java | 86 +++++++++++++++++ .../cotatomanage/service/ManageService.java | 46 +++++++++ 8 files changed, 353 insertions(+) create mode 100644 src/main/java/cotato/cotatomanage/controller/ManageController.java create mode 100644 src/main/java/cotato/cotatomanage/domain/Part.java create mode 100644 src/main/java/cotato/cotatomanage/domain/dto/JoinMemberRequest.java create mode 100644 src/main/java/cotato/cotatomanage/domain/dto/MemberResponse.java create mode 100644 src/main/java/cotato/cotatomanage/domain/dto/PartResponse.java create mode 100644 src/main/java/cotato/cotatomanage/domain/entity/Member.java create mode 100644 src/main/java/cotato/cotatomanage/repository/MemberRepository.java create mode 100644 src/main/java/cotato/cotatomanage/service/ManageService.java diff --git a/src/main/java/cotato/cotatomanage/controller/ManageController.java b/src/main/java/cotato/cotatomanage/controller/ManageController.java new file mode 100644 index 0000000..2c177a2 --- /dev/null +++ b/src/main/java/cotato/cotatomanage/controller/ManageController.java @@ -0,0 +1,37 @@ +package cotato.cotatomanage.controller; + +import cotato.cotatomanage.domain.dto.JoinMemberRequest; +import cotato.cotatomanage.service.ManageService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + + +@RestController +@RequiredArgsConstructor +@RequestMapping("/member") +public class ManageController { + + private final ManageService memberService; + @PostMapping("/join") + public ResponseEntity createMember(@RequestBody JoinMemberRequest request){ + memberService.addMember(request); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } + + @GetMapping("/print/part/{period}") + public ResponseEntity printByPart(@PathVariable("period") int period){ + return ResponseEntity.ok().body(memberService.printByPart(period)); + } + + @GetMapping("/print/member/{period}") + public ResponseEntity printAllMembers(@PathVariable("period") int period) { + return ResponseEntity.ok().body(memberService.printAllMembers(period)); + } + + @GetMapping("/print/{part}/member/{period}") + public ResponseEntity printAllMembersByPart(@PathVariable("part") String part, @PathVariable("period") int period) { + return ResponseEntity.ok().body(memberService.printAllMembersByPart(period,part)); + } +} \ No newline at end of file diff --git a/src/main/java/cotato/cotatomanage/domain/Part.java b/src/main/java/cotato/cotatomanage/domain/Part.java new file mode 100644 index 0000000..48b639b --- /dev/null +++ b/src/main/java/cotato/cotatomanage/domain/Part.java @@ -0,0 +1,17 @@ +package cotato.cotatomanage.domain; + +import lombok.Getter; + +@Getter +public enum Part { + 디자이너(1), + 기획(2), + 백엔드(3), + 프론트엔드(4); + + private final int order; + + Part(int order) { + this.order = order; + } +} \ No newline at end of file diff --git a/src/main/java/cotato/cotatomanage/domain/dto/JoinMemberRequest.java b/src/main/java/cotato/cotatomanage/domain/dto/JoinMemberRequest.java new file mode 100644 index 0000000..33267be --- /dev/null +++ b/src/main/java/cotato/cotatomanage/domain/dto/JoinMemberRequest.java @@ -0,0 +1,11 @@ +package cotato.cotatomanage.domain.dto; + +import lombok.Getter; + +@Getter +public class JoinMemberRequest { + private String name; + private String period; + private int age; + private String part; +} \ No newline at end of file diff --git a/src/main/java/cotato/cotatomanage/domain/dto/MemberResponse.java b/src/main/java/cotato/cotatomanage/domain/dto/MemberResponse.java new file mode 100644 index 0000000..dce41ae --- /dev/null +++ b/src/main/java/cotato/cotatomanage/domain/dto/MemberResponse.java @@ -0,0 +1,32 @@ +package cotato.cotatomanage.domain.dto; + +import java.util.Comparator; + +public class MemberResponse implements Comparable { + + private String name; + private String period; + private int ability; + + @Override + public int compareTo(MemberResponse o) { + return Comparator + .comparing(MemberResponse::getAbility, Comparator.reverseOrder()) + .thenComparing(MemberResponse::getPeriod, Comparator.reverseOrder()) + .thenComparing(MemberResponse::getName) + .compare(this, o); + } + + public int getAbility() { + return ability; + } + + public String getPeriod() { + return period; + } + + public String getName() { + return name; + } +} + diff --git a/src/main/java/cotato/cotatomanage/domain/dto/PartResponse.java b/src/main/java/cotato/cotatomanage/domain/dto/PartResponse.java new file mode 100644 index 0000000..a979fca --- /dev/null +++ b/src/main/java/cotato/cotatomanage/domain/dto/PartResponse.java @@ -0,0 +1,30 @@ +package cotato.cotatomanage.domain.dto; + +import cotato.cotatomanage.domain.Part; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Getter +@Slf4j +public class PartResponse implements Comparable { + private Part part; + private int ability; + private int count; + + @Override + public int compareTo(PartResponse other) { + log.info(this.part.name() + " " + this.ability + " " + other.part.name() + " " + other.ability); + + int abilityComparision = Integer.compare(other.ability, this.ability); + if(abilityComparision != 0){ + return abilityComparision; + } + + int countComparison = Integer.compare(this.count, other.count); + if (countComparison != 0) { + return countComparison; + } + + return Integer.compare(this.part.getOrder(), other.part.getOrder()); + } +} diff --git a/src/main/java/cotato/cotatomanage/domain/entity/Member.java b/src/main/java/cotato/cotatomanage/domain/entity/Member.java new file mode 100644 index 0000000..613fbf1 --- /dev/null +++ b/src/main/java/cotato/cotatomanage/domain/entity/Member.java @@ -0,0 +1,94 @@ +package cotato.cotatomanage.domain.entity; + +import cotato.cotatomanage.domain.Part; +import lombok.Builder; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.time.LocalDate; +import java.util.Arrays; + +@Getter +@Slf4j +public class Member implements Comparable { + private static final int MIN_AGE = 22; + private static final int MAX_AGE = 30; + private static final int CURRENT_PERIOD = 9; + + private String name; + private String period; + private int age; + private Part part; + private int ability; + + @Builder + public Member(String name, String period, int age, String part) { + validate(name, part, age); + this.name = name; + this.period = period; + this.age = age; + this.part = Part.valueOf(part); + this.ability = setAbility(); + } + + private int setAbility() { + int intPeriod = Integer.parseInt(period.split("기")[0]); + int periodAbility = (CURRENT_PERIOD - intPeriod) * 2; + int partAbility = age < 27 ? getBuffPart(part.name()) : 0; + return age + periodAbility + partAbility; + } + + public void updateAbility(int currentPeriod) { + int intPeriod = Integer.parseInt(period.split("기")[0]); + int periodAbility = (currentPeriod - intPeriod) * 2; + int partAbility = age < 27 ? getBuffPart(part.name()) : 0; + this.ability = age + periodAbility + partAbility; + } + + private int getBuffPart(String part) { + int month = LocalDate.now().getMonthValue(); + String buffPart; + switch (month) { + case 1, 5, 9 -> buffPart = "기획"; + case 2, 6, 10 -> buffPart = "디자이너"; + case 3, 7, 11 -> buffPart = "프론트엔드"; + default -> buffPart = "백엔드"; + } + return buffPart.equals(part) ? 10 : 0; + } + + private void validate(String name, String part, int age) { + if (name.isBlank() || name.length() < 3 || name.length() > 10) { + throw new IllegalArgumentException("이름은 3자에서 10자 사이여야 합니다."); + } + if (age > MAX_AGE || age < MIN_AGE) { + throw new IllegalArgumentException("나이는 " + MIN_AGE + "에서 " + MAX_AGE + "사이여야 합니다."); + } + if (Arrays.stream(Part.values()).noneMatch(v -> v.name().equals(part))) { + throw new IllegalArgumentException("유효하지 않은 파트입니다."); + } + } + + @Override + public int compareTo(Member o) { + int abilityComparison = Integer.compare(o.getAbility(), this.ability); + + if (abilityComparison != 0) { + return abilityComparison; + } + + int ageComparison = Integer.compare(this.age, o.age); + + if (ageComparison != 0) { + return ageComparison; + } + + int periodComparison = this.period.compareTo(o.period); + + if (periodComparison != 0) { + return periodComparison; + } + + return this.name.compareTo(o.name); + } +} diff --git a/src/main/java/cotato/cotatomanage/repository/MemberRepository.java b/src/main/java/cotato/cotatomanage/repository/MemberRepository.java new file mode 100644 index 0000000..4bf274c --- /dev/null +++ b/src/main/java/cotato/cotatomanage/repository/MemberRepository.java @@ -0,0 +1,86 @@ +package cotato.cotatomanage.repository; + + +import cotato.cotatomanage.domain.entity.Member; +import cotato.cotatomanage.domain.Part; +import cotato.cotatomanage.domain.dto.PartResponse; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.PriorityQueue; + +@Getter +@Slf4j +public class MemberRepository { + private List members = new ArrayList<>(); + @Getter + private static MemberRepository instance = new MemberRepository(); + + public void addMember(Member member) { + members.add(member); + } + + public void calculateAbility(int currentPeriod){ + members.forEach(member -> member.updateAbility(currentPeriod)); + log.info("calculateAbility finished"); + } + + public List orderAllMembers() { + return printMemberWithOrder(members); + } + + public List orderByPart() { + PriorityQueue list = new PriorityQueue<>(); + for (Part part : Part.values()) { + PartResponse data = makeOrderByPartResponse(part); + if (data!=null) { + list.add(data); + } + } + List orderedList = new ArrayList<>(); + while (!list.isEmpty()){ + PartResponse tmp = list.poll(); + log.info(tmp.getPart().name()); + orderedList.add(tmp); + } + return orderedList; + } + + public List orderAllMembersByPart(String part) { + Part enumPart = Part.valueOf(part); + List members = findAllMembersByPart(enumPart); + return printMemberWithOrder(members); + } + + private List printMemberWithOrder(List members) { + PriorityQueue list = new PriorityQueue<>(); + list.addAll(members); + List orderedList = new ArrayList<>(); + while (!list.isEmpty()) { + Member tmp = list.poll(); + orderedList.add(tmp); + } + return orderedList; + } + + private PartResponse makeOrderByPartResponse(Part part) { + List findMembersByPart = findAllMembersByPart(part); + int count = findMembersByPart.size(); + if(count==0){ + return null; + } + int average = (findMembersByPart.stream().mapToInt(Member::getAbility).sum())/count; + + return PartResponse.builder() + .part(part) + .ability(average) + .count(count) + .build(); + } + + private List findAllMembersByPart(Part part) { + return members.stream().filter(member -> member.getPart().equals(part)).toList(); + } +} \ No newline at end of file diff --git a/src/main/java/cotato/cotatomanage/service/ManageService.java b/src/main/java/cotato/cotatomanage/service/ManageService.java new file mode 100644 index 0000000..f44daca --- /dev/null +++ b/src/main/java/cotato/cotatomanage/service/ManageService.java @@ -0,0 +1,46 @@ +package cotato.cotatomanage.service; + +import cotato.cotatomanage.domain.entity.Member; +import cotato.cotatomanage.repository.MemberRepository; +import cotato.cotatomanage.domain.dto.JoinMemberRequest; +import cotato.cotatomanage.domain.dto.PartResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Slf4j +@Service +public class ManageService { + MemberRepository memberRepository = MemberRepository.getInstance(); + + public void addMember(JoinMemberRequest request) { + Member member = Member.builder() + .age(request.getAge()) + .part(request.getPart()) + .name(request.getName()) + .period(request.getPeriod()) + .build(); + memberRepository.addMember(member); + memberRepository.getMembers() + .forEach(member1 -> log.info(member1.getName() + " " + member1.getPart().name() + " " + member1.getAbility())); + } + + public List printByPart(int period) { + log.info("printByPart Start"); + memberRepository.calculateAbility(period); + return memberRepository.orderByPart(); + } + + public List printAllMembers(int period) { + log.info("printAllMembers Start"); + memberRepository.calculateAbility(period); + return memberRepository.orderAllMembers(); + } + + public List printAllMembersByPart(int period, String part) { + log.info("printAllMembersByPart Start"); + memberRepository.calculateAbility(period); + return memberRepository.orderAllMembersByPart(part); + } +} \ No newline at end of file