diff --git a/src/main/java/com/soogung/simblue/domain/group/domain/Group.java b/src/main/java/com/soogung/simblue/domain/group/domain/Group.java new file mode 100644 index 0000000..49ba2b4 --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/domain/Group.java @@ -0,0 +1,35 @@ +package com.soogung.simblue.domain.group.domain; + +import com.soogung.simblue.domain.group.domain.type.GroupType; +import com.soogung.simblue.global.entity.BaseTimeEntity; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Entity +@Table(name = "tbl_group") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class Group extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "group_id") + private Long id; + + @Column(nullable = false, length = 20) + private String name; + + @Enumerated(EnumType.STRING) + @Column(nullable = false, length = 10) + private GroupType type; + + @Builder + public Group(String name, GroupType type) { + this.name = name; + this.type = type; + } +} diff --git a/src/main/java/com/soogung/simblue/domain/group/domain/Member.java b/src/main/java/com/soogung/simblue/domain/group/domain/Member.java new file mode 100644 index 0000000..c125143 --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/domain/Member.java @@ -0,0 +1,36 @@ +package com.soogung.simblue.domain.group.domain; + +import com.soogung.simblue.domain.user.domain.Student; +import com.soogung.simblue.global.entity.BaseTimeEntity; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Entity +@Table(name = "tbl_member") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class Member extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "member_id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "student_id", nullable = false) + private Student student; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "group_id", nullable = false) + private Group group; + + @Builder + public Member(Student student, Group group) { + this.student = student; + this.group = group; + } +} \ No newline at end of file diff --git a/src/main/java/com/soogung/simblue/domain/group/domain/repository/GroupRepository.java b/src/main/java/com/soogung/simblue/domain/group/domain/repository/GroupRepository.java new file mode 100644 index 0000000..1d29d28 --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/domain/repository/GroupRepository.java @@ -0,0 +1,13 @@ +package com.soogung.simblue.domain.group.domain.repository; + +import com.soogung.simblue.domain.group.domain.Group; +import com.soogung.simblue.domain.group.domain.Member; +import org.springframework.data.repository.CrudRepository; + +import java.util.List; + + +public interface GroupRepository extends CrudRepository { + + List findAll(); +} diff --git a/src/main/java/com/soogung/simblue/domain/group/domain/repository/MemberRepository.java b/src/main/java/com/soogung/simblue/domain/group/domain/repository/MemberRepository.java new file mode 100644 index 0000000..3f4b447 --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/domain/repository/MemberRepository.java @@ -0,0 +1,9 @@ +package com.soogung.simblue.domain.group.domain.repository; + +import com.soogung.simblue.domain.group.domain.Member; +import org.springframework.data.repository.CrudRepository; + +public interface MemberRepository extends CrudRepository { + + +} diff --git a/src/main/java/com/soogung/simblue/domain/group/domain/type/GroupType.java b/src/main/java/com/soogung/simblue/domain/group/domain/type/GroupType.java new file mode 100644 index 0000000..b57d526 --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/domain/type/GroupType.java @@ -0,0 +1,6 @@ +package com.soogung.simblue.domain.group.domain.type; + +public enum GroupType { + + CLASS, YEAR, MAJOR, ETC +} diff --git a/src/main/java/com/soogung/simblue/domain/group/exception/GroupNotFoundException.java b/src/main/java/com/soogung/simblue/domain/group/exception/GroupNotFoundException.java new file mode 100644 index 0000000..20a0918 --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/exception/GroupNotFoundException.java @@ -0,0 +1,12 @@ +package com.soogung.simblue.domain.group.exception; + + +import com.soogung.simblue.domain.group.exception.error.GroupErrorProperty; +import com.soogung.simblue.domain.user.exception.UserNotFoundException; +import com.soogung.simblue.global.error.exception.SimblueException; + +public class GroupNotFoundException extends SimblueException { + + public final static GroupNotFoundException EXCEPTION = new GroupNotFoundException(); + private GroupNotFoundException() { super(GroupErrorProperty.GROUP_NOT_FOUND); } +} diff --git a/src/main/java/com/soogung/simblue/domain/group/exception/error/GroupErrorProperty.java b/src/main/java/com/soogung/simblue/domain/group/exception/error/GroupErrorProperty.java new file mode 100644 index 0000000..8d40cf9 --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/exception/error/GroupErrorProperty.java @@ -0,0 +1,15 @@ +package com.soogung.simblue.domain.group.exception.error; + +import com.soogung.simblue.global.error.exception.ErrorProperty; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum GroupErrorProperty implements ErrorProperty { + + GROUP_NOT_FOUND(404, "그룹이 없습니다."); + + private final int status; + private final String message; +} \ No newline at end of file diff --git a/src/main/java/com/soogung/simblue/domain/group/facade/GroupFacade.java b/src/main/java/com/soogung/simblue/domain/group/facade/GroupFacade.java new file mode 100644 index 0000000..f0b4341 --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/facade/GroupFacade.java @@ -0,0 +1,23 @@ +package com.soogung.simblue.domain.group.facade; + +import com.soogung.simblue.domain.application.domain.Application; +import com.soogung.simblue.domain.application.exception.ApplicationNotFoundException; +import com.soogung.simblue.domain.group.domain.Group; +import com.soogung.simblue.domain.group.domain.repository.GroupRepository; +import com.soogung.simblue.domain.group.exception.GroupNotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +@Component +@RequiredArgsConstructor +public class GroupFacade { + + private final GroupRepository groupRepository; + + @Transactional(readOnly = true) + public Group findGroup(Long id) { + return groupRepository.findById(id) + .orElseThrow(() -> GroupNotFoundException.EXCEPTION); + } +} diff --git a/src/main/java/com/soogung/simblue/domain/group/presentation/GroupController.java b/src/main/java/com/soogung/simblue/domain/group/presentation/GroupController.java new file mode 100644 index 0000000..94f480c --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/presentation/GroupController.java @@ -0,0 +1,32 @@ +package com.soogung.simblue.domain.group.presentation; + +import com.soogung.simblue.domain.group.presentation.dto.request.GroupRequest; +import com.soogung.simblue.domain.group.presentation.dto.response.GroupListResponse; +import com.soogung.simblue.domain.group.service.CreateGroupService; +import com.soogung.simblue.domain.group.service.QueryGroupService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +@RestController +@RequestMapping("/group") +@RequiredArgsConstructor +public class GroupController { + + private final CreateGroupService createGroupService; + + private final QueryGroupService queryGroupService; + + @PostMapping + public void createGroup(@RequestBody @Valid GroupRequest request) { + createGroupService.execute(request); + } + + @GetMapping + public GroupListResponse getGroupList(){ + return queryGroupService.execute(); + } + +} diff --git a/src/main/java/com/soogung/simblue/domain/group/presentation/MemberController.java b/src/main/java/com/soogung/simblue/domain/group/presentation/MemberController.java new file mode 100644 index 0000000..72cb243 --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/presentation/MemberController.java @@ -0,0 +1,21 @@ +package com.soogung.simblue.domain.group.presentation; + +import com.soogung.simblue.domain.group.presentation.dto.request.AddGroupRequest; +import com.soogung.simblue.domain.group.service.AddGroupService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +@RestController +@RequestMapping("/group") +@RequiredArgsConstructor +public class MemberController { + + private final AddGroupService addGroupService; + + @PostMapping("/{id}/add") + public void addMember(@PathVariable Long id,@RequestBody @Valid AddGroupRequest request) { + addGroupService.execute(id, request); + } +} diff --git a/src/main/java/com/soogung/simblue/domain/group/presentation/dto/request/AddGroupRequest.java b/src/main/java/com/soogung/simblue/domain/group/presentation/dto/request/AddGroupRequest.java new file mode 100644 index 0000000..58da09e --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/presentation/dto/request/AddGroupRequest.java @@ -0,0 +1,13 @@ +package com.soogung.simblue.domain.group.presentation.dto.request; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Getter +@NoArgsConstructor +public class AddGroupRequest { + + private List memberList; +} diff --git a/src/main/java/com/soogung/simblue/domain/group/presentation/dto/request/GroupRequest.java b/src/main/java/com/soogung/simblue/domain/group/presentation/dto/request/GroupRequest.java new file mode 100644 index 0000000..5b39baf --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/presentation/dto/request/GroupRequest.java @@ -0,0 +1,31 @@ +package com.soogung.simblue.domain.group.presentation.dto.request; + +import com.soogung.simblue.domain.group.domain.Group; +import com.soogung.simblue.domain.group.domain.type.GroupType; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class GroupRequest { + + @NotNull + @Size(min = 1, max = 20) + private String name; + + @NotNull + private GroupType type; + + public Group toEntity() { + return Group.builder() + .name(name) + .type(type) + .build(); + } + +} diff --git a/src/main/java/com/soogung/simblue/domain/group/presentation/dto/request/MemberRequest.java b/src/main/java/com/soogung/simblue/domain/group/presentation/dto/request/MemberRequest.java new file mode 100644 index 0000000..9aae7ff --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/presentation/dto/request/MemberRequest.java @@ -0,0 +1,14 @@ +package com.soogung.simblue.domain.group.presentation.dto.request; + +import com.sun.istack.NotNull; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class MemberRequest { + + private Long studentId; +} diff --git a/src/main/java/com/soogung/simblue/domain/group/presentation/dto/response/GroupListResponse.java b/src/main/java/com/soogung/simblue/domain/group/presentation/dto/response/GroupListResponse.java new file mode 100644 index 0000000..fd15b3c --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/presentation/dto/response/GroupListResponse.java @@ -0,0 +1,17 @@ +package com.soogung.simblue.domain.group.presentation.dto.response; + +import com.soogung.simblue.domain.group.domain.Group; +import com.soogung.simblue.domain.group.domain.type.GroupType; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +import java.util.List; + +@Getter +@AllArgsConstructor +public class GroupListResponse { + + private List groupList; + +} diff --git a/src/main/java/com/soogung/simblue/domain/group/presentation/dto/response/GroupResponse.java b/src/main/java/com/soogung/simblue/domain/group/presentation/dto/response/GroupResponse.java new file mode 100644 index 0000000..776dd9e --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/presentation/dto/response/GroupResponse.java @@ -0,0 +1,24 @@ +package com.soogung.simblue.domain.group.presentation.dto.response; + +import com.soogung.simblue.domain.group.domain.Group; +import com.soogung.simblue.domain.group.domain.type.GroupType; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class GroupResponse { + + private Long id; + private String name; + private GroupType type; + + public static GroupResponse of(Group group) { + return GroupResponse.builder() + .id(group.getId()) + .name(group.getName()) + .type(group.getType()) + .build(); + } + +} diff --git a/src/main/java/com/soogung/simblue/domain/group/service/AddGroupService.java b/src/main/java/com/soogung/simblue/domain/group/service/AddGroupService.java new file mode 100644 index 0000000..3f4c7c7 --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/service/AddGroupService.java @@ -0,0 +1,41 @@ +package com.soogung.simblue.domain.group.service; + +import com.soogung.simblue.domain.group.domain.Group; +import com.soogung.simblue.domain.group.domain.Member; +import com.soogung.simblue.domain.group.domain.repository.GroupRepository; +import com.soogung.simblue.domain.group.domain.repository.MemberRepository; +import com.soogung.simblue.domain.group.facade.GroupFacade; +import com.soogung.simblue.domain.group.presentation.dto.request.AddGroupRequest; +import com.soogung.simblue.domain.user.facade.UserFacade; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import javax.transaction.Transactional; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class AddGroupService { + + private final GroupRepository groupRepository; + private final MemberRepository memberRepository; + private final UserFacade userFacade; + private final GroupFacade groupFacade; + + @Transactional + public void execute(Long id, AddGroupRequest request) { + + Group group = groupFacade.findGroup(id); + + memberRepository.saveAll( + request.getMemberList().stream().map( + (member) -> Member.builder() + .student(userFacade.findStudentById(member.getStudentId())) + .group(group) + .build() + ).collect(Collectors.toList()) + ); + + } + +} diff --git a/src/main/java/com/soogung/simblue/domain/group/service/CreateGroupService.java b/src/main/java/com/soogung/simblue/domain/group/service/CreateGroupService.java new file mode 100644 index 0000000..770625e --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/service/CreateGroupService.java @@ -0,0 +1,22 @@ +package com.soogung.simblue.domain.group.service; + +import com.soogung.simblue.domain.group.domain.Group; +import com.soogung.simblue.domain.group.domain.repository.GroupRepository; +import com.soogung.simblue.domain.group.presentation.dto.request.GroupRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import javax.transaction.Transactional; + +@Service +@RequiredArgsConstructor +public class CreateGroupService { + + private final GroupRepository groupRepository; + + @Transactional + public void execute(GroupRequest request) { + groupRepository.save(request.toEntity()); + } + +} diff --git a/src/main/java/com/soogung/simblue/domain/group/service/QueryGroupService.java b/src/main/java/com/soogung/simblue/domain/group/service/QueryGroupService.java new file mode 100644 index 0000000..79a64d7 --- /dev/null +++ b/src/main/java/com/soogung/simblue/domain/group/service/QueryGroupService.java @@ -0,0 +1,28 @@ +package com.soogung.simblue.domain.group.service; + +import com.soogung.simblue.domain.application.presentation.dto.response.ApplicationResponse; +import com.soogung.simblue.domain.group.domain.Group; +import com.soogung.simblue.domain.group.domain.repository.GroupRepository; +import com.soogung.simblue.domain.group.presentation.dto.response.GroupListResponse; +import com.soogung.simblue.domain.group.presentation.dto.response.GroupResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import org.springframework.transaction.annotation.Transactional; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class QueryGroupService { + + private final GroupRepository groupRepository; + + @Transactional(readOnly = true) + public GroupListResponse execute(){ + return new GroupListResponse( + groupRepository.findAll() + .stream().map(GroupResponse::of).collect(Collectors.toList()) + ); + } + +} diff --git a/src/main/java/com/soogung/simblue/domain/user/facade/UserFacade.java b/src/main/java/com/soogung/simblue/domain/user/facade/UserFacade.java index 77cd255..2b7f4d9 100644 --- a/src/main/java/com/soogung/simblue/domain/user/facade/UserFacade.java +++ b/src/main/java/com/soogung/simblue/domain/user/facade/UserFacade.java @@ -86,7 +86,11 @@ public String getName(Long userId) { if (user.getAuthority() == Authority.ROLE_TEACHER) { return user.getName() + " 선생님"; } - return findStudentByUser(user).getStudentNumber() + " " + user.getName(); } + + public Student findStudentById(Long id) { + return studentRepository.findById(id) + .orElseThrow(() -> UserNotFoundException.EXCEPTION); + } } diff --git a/src/main/java/com/soogung/simblue/global/security/SecurityConfig.java b/src/main/java/com/soogung/simblue/global/security/SecurityConfig.java index 2605746..7e0de0d 100644 --- a/src/main/java/com/soogung/simblue/global/security/SecurityConfig.java +++ b/src/main/java/com/soogung/simblue/global/security/SecurityConfig.java @@ -60,6 +60,7 @@ public SecurityFilterChain configure(HttpSecurity http) throws Exception { .antMatchers(HttpMethod.GET, "/application/{\\d+}/form").hasRole(Authority.ROLE_TEACHER.getRole()) .antMatchers(HttpMethod.GET, "/application/{\\d+}/result").hasRole(Authority.ROLE_TEACHER.getRole()) .antMatchers(HttpMethod.POST, "/application").hasRole(Authority.ROLE_TEACHER.getRole()) + .antMatchers(HttpMethod.POST, "/group/{\\d+}/add").hasRole(Authority.ROLE_TEACHER.getRole()) .antMatchers(HttpMethod.GET, "/application/**").permitAll() .antMatchers(HttpMethod.GET, "/banner").permitAll() .anyRequest().authenticated()