Skip to content

Commit

Permalink
Merge pull request #94 from Media-XI/feat/member-조회-관련-api
Browse files Browse the repository at this point in the history
Feat/member 조회 관련 api
  • Loading branch information
Hoon9901 authored Nov 22, 2023
2 parents 2f542fb + 1fccf1c commit 133ef53
Show file tree
Hide file tree
Showing 7 changed files with 391 additions and 228 deletions.
82 changes: 61 additions & 21 deletions src/main/java/com/example/codebase/controller/MemberController.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package com.example.codebase.controller;

import com.example.codebase.domain.member.dto.*;
import com.example.codebase.domain.member.entity.RoleStatus;
import com.example.codebase.domain.member.service.MemberService;
import com.example.codebase.exception.NotAcceptTypeException;
import com.example.codebase.util.FileUtil;
import com.example.codebase.util.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
Expand Down Expand Up @@ -73,7 +80,7 @@ public ResponseEntity createCurator(@Valid @RequestBody CreateCuratorMemberDTO c
public ResponseEntity updateMember(@PathVariable String uesrname,
@Valid @RequestBody UpdateMemberDTO updateMemberDTO) {
String loginUsername = SecurityUtil.getCurrentUsername()
.orElseThrow(() -> new RuntimeException("로그인이 필요합니다."));
.orElseThrow(() -> new RuntimeException("로그인이 필요합니다."));

if (!uesrname.equals(loginUsername)) {
throw new RuntimeException("본인의 정보만 수정할 수 있습니다.");
Expand All @@ -87,11 +94,11 @@ public ResponseEntity updateMember(@PathVariable String uesrname,
@PreAuthorize("isAuthenticated() and hasAnyRole('ROLE_USER')")
@PutMapping("/{username}/picture")
public ResponseEntity updateProfile(
@PathVariable String username,
@RequestPart MultipartFile profile
@PathVariable String username,
@RequestPart MultipartFile profile
) throws Exception {
String currentUsername = SecurityUtil.getCurrentUsername()
.orElseThrow(() -> new RuntimeException("로그인이 필요합니다."));
.orElseThrow(() -> new RuntimeException("로그인이 필요합니다."));
if (!currentUsername.equals(username)) {
throw new RuntimeException("본인의 프로필 사진만 수정할 수 있습니다.");
}
Expand All @@ -108,15 +115,42 @@ public ResponseEntity updateProfile(
return new ResponseEntity(member, HttpStatus.OK);
}

@Operation(summary = "회원 리스트 조회", description = "[ADMIN] 회원 리스트를 조회합니다.")
@Operation(summary = "회원 전체 조회", description = "[ADMIN] 회원 리스트를 조회합니다.")
@PreAuthorize("hasAnyRole('ROLE_ADMIN')")
@GetMapping
public ResponseEntity getAllMember() {
List<MemberResponseDTO> members = memberService.getAllMember();
public ResponseEntity getAllMember(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "DESC", required = false) String sortDirection
) {
Sort sort = Sort.by(Sort.Direction.fromString(sortDirection), "createdTime");
PageRequest pageRequest = PageRequest.of(page, size, sort);

MembersResponseDTO members = memberService.getAllMember(pageRequest);
return new ResponseEntity(members, HttpStatus.OK);
}

@Operation(summary = "회원 프로필 조회", description = "[USER] 회원의 프로필을 조회합니다.")
@Operation(summary = "역할 상태로 회원 전체 조회", description = "[ADMIN] 역할 상태로 회원 전체 조회합니다.",
parameters = @Parameter(
name = "roleStatus",
description = "역할 상태",
example = "NONE | PENDING | REJECTED | ARTIST | CURATOR")
)
@PreAuthorize("hasAnyRole('ROLE_ADMIN')")
@GetMapping("/role-status")
public ResponseEntity getAllRoleStatusMember(
@RequestParam(defaultValue = "NONE") @NotBlank(message = "역할 상태는 필수입니다.") String roleStatus,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "DESC", required = false) String sortDirection
) {
Sort sort = Sort.by(Sort.Direction.fromString(sortDirection), "createdTime");
PageRequest pageRequest = PageRequest.of(page, size, sort);
MembersResponseDTO members = memberService.getAllRoleStatusMember(roleStatus, pageRequest);
return new ResponseEntity(members, HttpStatus.OK);
}

@Operation(summary = "내 프로필 조회", description = "[USER] 내 프로필을 조회합니다.")
@PreAuthorize("isAuthenticated() and hasAnyRole('ROLE_USER')")
@GetMapping("/profile")
public ResponseEntity getProfile() {
Expand All @@ -125,19 +159,20 @@ public ResponseEntity getProfile() {
return new ResponseEntity(member, HttpStatus.OK);
}

@Operation(summary = "회원 프로필 조회", description = "[USER] 회원의 프로필을 조회합니다.")
@Operation(summary = "회원 프로필 조회", description = "[USER] 회원의 프로필을 조회합니다.")
@GetMapping("/{username}")
public ResponseEntity getProfile(@PathVariable String username) {
MemberResponseDTO member = memberService.getProfile(username);
return new ResponseEntity(member, HttpStatus.OK);
}

@Operation(summary = "회원 삭제", description = "[USER] 회원을 삭제합니다.")
@Operation(summary = "회원 삭제", description = "[USER] 회원을 삭제합니다.")
@PreAuthorize("isAuthenticated() and hasAnyRole('ROLE_USER')")
@DeleteMapping("/{username}")
public ResponseEntity deleteMember(@PathVariable String username) {
String currentUsername = SecurityUtil.getCurrentUsername()
.orElseThrow(() -> new RuntimeException("로그인이 필요합니다."));
.orElseThrow(() -> new RuntimeException("로그인이 필요합니다."));

if (!currentUsername.equals(username)) {
throw new RuntimeException("본인의 정보만 삭제할 수 있습니다.");
}
Expand All @@ -164,36 +199,41 @@ public ResponseEntity checkUsername(@Valid @NotBlank @PathVariable String userna
return new ResponseEntity("사용 가능한 아이디 입니다.", HttpStatus.OK);
}

@Operation(summary = "아티스트 승인", description = "[ADMIN] 아티스트를 승인합니다.")
@Operation(summary = "회원 역할 상태 변경", description = "[ADMIN] 해당 회원의 역할 상태를 변경합니다.",
parameters = @Parameter(
name = "roleStatus",
description = "역할 상태",
example = "NONE | ARTIST_PENDING | ARTIST_REJECTED | ARTIST | CURATOR_PENDING | CURATOR_REJECTED | CURATOR")
)
@PreAuthorize("hasAnyRole('ROLE_ADMIN')")
@PutMapping("/artist/{username}")
public ResponseEntity updateArtistStatus(@Valid @NotBlank @PathVariable String username,
@Valid @NotBlank @RequestParam String status) {
MemberResponseDTO member = memberService.updateArtistStatus(username, status);
@PutMapping("/{username}/role-status")
public ResponseEntity updateRoleStatus(@PathVariable @Valid @NotBlank String username,
@RequestParam @Valid @NotBlank(message = "역할 상태는 필수입니다.") String roleStatus) {
MemberResponseDTO member = memberService.updateRoleStatus(username, RoleStatus.create(roleStatus));
return new ResponseEntity(member, HttpStatus.OK);
}

@Operation(summary = "큐레이터 승인", description = "[ADMIN] 큐레이터를 승인합니다.")
@Operation(summary = "닉네임 변경", description = "[USER] 닉네임을 변경합니다.")
@PreAuthorize("isAuthenticated() and hasAnyRole('ROLE_USER')")
@PutMapping("/{username}/username")
public ResponseEntity updateUsername(@PathVariable String username,
@Valid @RequestParam UsernameDTO newUsername) {
String currentUsername = SecurityUtil.getCurrentUsername()
.orElseThrow(() -> new RuntimeException("로그인이 필요합니다."));
.orElseThrow(() -> new RuntimeException("로그인이 필요합니다."));
if (!SecurityUtil.isAdmin() && !currentUsername.equals(username)) { // 관리자가 아니고, 본인의 아이디가 아닐 경우
throw new RuntimeException("본인의 정보만 수정할 수 있습니다.");
}

MemberResponseDTO member = memberService.updateUsername(username, newUsername.getUsername());
return new ResponseEntity(member, HttpStatus.OK);
}

@Operation(summary = "비밀번호 변경", description = "[USER] 비밀번호를 변경합니다.")
@PreAuthorize("isAuthenticated() and hasAnyRole('ROLE_USER', 'ROLE_ADMIN')")
@PutMapping("/{username}/password")
public ResponseEntity updatePassword(@PathVariable String username,
@NotBlank @RequestParam(value = "newPassword") String newPassword) {
String currentUsername = SecurityUtil.getCurrentUsername()
.orElseThrow(() -> new RuntimeException("로그인이 필요합니다."));
.orElseThrow(() -> new RuntimeException("로그인이 필요합니다."));

if (!SecurityUtil.isAdmin() && !currentUsername.equals(username)) {
throw new RuntimeException("본인의 정보만 수정할 수 있습니다.");
Expand All @@ -203,7 +243,7 @@ public ResponseEntity updatePassword(@PathVariable String username,
return new ResponseEntity("비밀번호가 변경되었습니다.", HttpStatus.OK);
}

@Operation(summary = "관리자 권한 부여", description = "[ADMIN] 관리자 권한을 부여합니다.")
@Operation(summary = "관리자 권한 부여", description = "[ADMIN] 관리자 권한을 부여합니다.")
@PreAuthorize("hasAnyRole('ROLE_ADMIN')")
@PutMapping("/{username}/admin")
public ResponseEntity updateAdmin(@PathVariable String username) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.example.codebase.domain.member.dto;

import com.example.codebase.controller.dto.PageInfo;
import com.example.codebase.domain.member.entity.Member;
import lombok.Getter;
import org.springframework.data.domain.Page;

import java.util.List;

@Getter
public class MembersResponseDTO {

List<MemberResponseDTO> members;

PageInfo pageInfo;

public static MembersResponseDTO of (List<MemberResponseDTO> members, PageInfo pageInfo) {
MembersResponseDTO dto = new MembersResponseDTO();
dto.members = members;
dto.pageInfo = pageInfo;
return dto;
}

public static MembersResponseDTO from(Page<Member> members) {
PageInfo pageInfo = PageInfo.from(members);
List<MemberResponseDTO> dtos = members.stream()
.map(MemberResponseDTO::from)
.toList();
return MembersResponseDTO.of(dtos, pageInfo);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,13 @@ public void addAuthority(MemberAuthority memberAuthority) {
this.authorities.add(memberAuthority);
}

public void addAuthority(Authority authority) {
this.authorities.add(MemberAuthority.builder()
.member(this)
.authority(authority)
.build());
}

public Member update(String name, String picture) {
this.name = name;
this.picture = picture;
Expand Down Expand Up @@ -215,8 +222,8 @@ public void setArtist(CreateArtistMemberDTO dto) {
this.updatedTime = LocalDateTime.now();
}

public void updateArtistStatus(String status) {
this.roleStatus = RoleStatus.create(status);
public void updateRoleStatus(RoleStatus roleStatus) {
this.roleStatus = roleStatus;
this.updatedTime = LocalDateTime.now();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
package com.example.codebase.domain.member.entity;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.stream.Stream;

public enum RoleStatus {
NONE, ARTIST_PENDING, ARTIST_REJECTED, ARTIST, CURATOR_PENDING, CURATOR_REJECTED, CURATOR;

@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static RoleStatus create(String value) {
public static RoleStatus create(String roleStatus) {
return Stream.of(RoleStatus.values())
.filter(status -> status.name().equals(value))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("부적절한 미디어 타입입니다. 지원하는 형식 : " +
Stream.of(RoleStatus.values())
.map(RoleStatus::name)
.reduce((a, b) -> a + ", " + b)
.get()));
.filter(status -> status.name().equals(roleStatus))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("부적절한 역할 상태 입니다."));
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.example.codebase.domain.member.repository;

import com.example.codebase.domain.member.entity.Member;
import com.example.codebase.domain.member.entity.RoleStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
Expand All @@ -13,13 +14,6 @@

public interface MemberRepository extends JpaRepository<Member, UUID> {

/*
* Deprecated!
* Authorities를 Fetch.Lazy 에서 Eager로 변경하여 지연 로딩 없이 가져오므로
* 해당 메소드는 사용하지 않아도 됨.
*/
Optional<Member> findOneWithAuthoritiesByUsername(String username);

Optional<Member> findByUsername(String username);

@Query(" SELECT m " +
Expand All @@ -29,8 +23,6 @@ public interface MemberRepository extends JpaRepository<Member, UUID> {

Optional<Member> findByOauthProviderId(String oauthProviderId);

Optional<Member> findByOauthProviderIdAndEmail(String oauthProviderId, String email);

Boolean existsByEmail(String email);

Boolean existsByUsername(String username);
Expand All @@ -52,4 +44,11 @@ List<Member> findMembersByNoneActrivatedAndCreatedTimeAfter(

@Query("SELECT m FROM Member m WHERE m.name LIKE ?1%")
Page<Member> searchByName(String username, Pageable pageable);

@Query("SELECT m FROM Member m WHERE m.roleStatus = :roleStatus")
Page<Member> findAllByRoleStatus(RoleStatus roleStatus, Pageable pageable);

@Query("SELECT m FROM Member m WHERE m.roleStatus = ?1 OR m.roleStatus = ?2")
Page<Member> findAllByRoleStatus(RoleStatus pending1, RoleStatus pending2, Pageable pageable);

}
Loading

0 comments on commit 133ef53

Please sign in to comment.