Skip to content

Commit

Permalink
[feature/liked]
Browse files Browse the repository at this point in the history
- 프로필 조회/수정
  • Loading branch information
김해동 committed Oct 18, 2023
1 parent 7afe4ff commit 8f415d3
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.koliving.api.my.application.dto;

import com.koliving.api.file.domain.ImageFile;
import com.koliving.api.user.Gender;
import com.koliving.api.user.User;
import io.swagger.v3.oas.annotations.media.Schema;
import org.springframework.lang.Nullable;

import javax.validation.constraints.NotNull;
import java.time.LocalDate;

@Schema(description = "작성자 정보")
public record UserProfileUpdateRequest(

@NotNull
@Schema(description = "이미지 URL 고유 Key")
Long profileId,

@NotNull
@Schema(description = "성별")
Gender gender,

@NotNull
@Schema(description = "이름")
String firstName,

@NotNull
@Schema(description = "성")
String lastName,

@NotNull
@Schema(description = "생년월일")
LocalDate birthDate,

@Nullable
@Schema(description = "설명")
String description
) {
public User toUser(ImageFile imageFile) {
return User.of(imageFile, gender, firstName, lastName, birthDate, description);
}
}
73 changes: 73 additions & 0 deletions src/main/java/com/koliving/api/my/ui/MyController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.koliving.api.my.ui;

import com.koliving.api.base.ErrorResponse;
import com.koliving.api.my.application.dto.UserProfileUpdateRequest;
import com.koliving.api.user.User;
import com.koliving.api.user.application.UserService;
import com.koliving.api.user.application.dto.UserResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@Tag(name = "MY API", description = "MY API")
@RestController
@RequestMapping("api/v1/my")
@RequiredArgsConstructor
public class MyController {
private final UserService userService;

@Operation(
summary = "프로필 수정",
description = "프로필을 수정합니다.",
responses = {
@ApiResponse(
responseCode = "204",
description = "프로필 수정 성공"
),
@ApiResponse(
responseCode = "400",
description = "프로필 수정 실패",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))
),
})
@PutMapping("/profile")
public ResponseEntity<Void> updateProfile(@RequestBody UserProfileUpdateRequest request, @AuthenticationPrincipal User user) {
userService.updateProfile(request, user.getId());
return ResponseEntity.noContent().build();
}


@Operation(
summary = "프로필 조회",
description = "프로필 정보를 조회합니다",
responses = {
@ApiResponse(
responseCode = "200",
description = "프로필 조회 성공",
content = @Content(schema = @Schema(implementation = UserResponse.class))
),
@ApiResponse(
responseCode = "400",
description = "프로필 조회 실패",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))
),
})
@GetMapping
public ResponseEntity<UserResponse> myProfile(@AuthenticationPrincipal User user) {
UserResponse response = userService.findById(user.getId());

return ResponseEntity.ok()
.body(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.swagger.v3.oas.annotations.media.Schema;

import java.time.LocalDate;
import java.util.Objects;

@Schema(description = "작성자 정보")
public record WriterResponse(
Expand All @@ -17,11 +18,16 @@ public record WriterResponse(
Gender gender,
@Schema(description = "작성자 생년월일")
LocalDate birthDate,

@Schema(description = "작성자 소개")
String description,

@Schema(description = "작성자 프로필 URL")
String imageUrl
) {

public static WriterResponse of(User entity) {
return new WriterResponse(entity.getFirstName(), entity.getLastName(), entity.getGender(), entity.getBirthDate(), entity.getImageUrl());
String imageUrl = Objects.isNull(entity.getImageFile()) ? null : entity.getImageFile().getPath();
return new WriterResponse(entity.getFirstName(), entity.getLastName(), entity.getGender(), entity.getBirthDate(), entity.getDescription(), imageUrl);
}
}
34 changes: 29 additions & 5 deletions src/main/java/com/koliving/api/user/User.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package com.koliving.api.user;

import com.koliving.api.base.exception.KolivingServiceException;
import com.koliving.api.file.domain.ImageFile;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.Lob;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import lombok.AccessLevel;
Expand All @@ -25,7 +29,6 @@
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.swing.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collection;
Expand Down Expand Up @@ -61,10 +64,12 @@ public class User implements UserDetails {
@Column(name = "BIRTH_DATE")
private LocalDate birthDate;

@Lob
private String description;

@Column
private String imageUrl;
@OneToOne
@JoinColumn(name = "IMAGE_FILE_ID")
private ImageFile imageFile;

@Enumerated(EnumType.STRING)
@Column(name = "USER_ROLE")
Expand Down Expand Up @@ -95,16 +100,26 @@ public User(String email) {
this.userRole = UserRole.USER;
}

private User(String email, String password, UserRole userRole) {
private User(String email, String password, String firstName, String lastName, Gender gender, LocalDate birthDate, String description, ImageFile imageFile, UserRole userRole) {
this.email = email;
this.password = password;
this.firstName = firstName;
this.lastName = lastName;
this.gender = gender;
this.birthDate = birthDate;
this.description = description;
this.imageFile = imageFile;
this.userRole = userRole;
}

@Deprecated
public static User valueOf(String email, String encodedPassword, UserRole role) {
return new User(email, encodedPassword, role);
return new User(email, encodedPassword, null, null, null, null, null,null, role);
}

public static User of(ImageFile imageFile, Gender gender, String firstName, String lastName, LocalDate birthDate, String description) {
return new User(null, null, firstName, lastName, gender, birthDate,description, imageFile, null);
}
public void setPassword(String password) {
this.password = password;
this.signUpStatus = SignUpStatus.PROFILE_INFORMATION_PENDING;
Expand Down Expand Up @@ -159,4 +174,13 @@ public void checkPassword(PasswordEncoder passwordEncoder, String rawPassword) {
throw new KolivingServiceException(UNAUTHORIZED);
}
}

public void update(User updatable) {
this.imageFile = updatable.imageFile;
this.firstName = updatable.firstName;
this.lastName = updatable.lastName;
this.gender = updatable.gender;
this.birthDate = updatable.birthDate;
this.description = updatable.description;
}
}
34 changes: 30 additions & 4 deletions src/main/java/com/koliving/api/user/application/UserService.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.koliving.api.user.application;

import com.koliving.api.base.ServiceError;
import com.koliving.api.base.exception.KolivingServiceException;
import com.koliving.api.file.domain.ImageFile;
import com.koliving.api.file.infra.ImageFileRepository;
import com.koliving.api.my.application.dto.UserProfileUpdateRequest;
import com.koliving.api.user.User;
import com.koliving.api.user.UserRepository;
import com.koliving.api.user.application.dto.UserResponse;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
Expand All @@ -13,22 +16,26 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class UserService implements IUserService, UserDetailsService {

private final UserRepository userRepository;
private final ImageFileRepository imageFileRepository;
private final PasswordEncoder passwordEncoder;

@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String email) {
return userRepository.findByEmail(email).orElseThrow(() ->
new UsernameNotFoundException(String.format("User with email %s not found", email)));
}

@Override
@Transactional
public User save(User user) {
return userRepository.save(user);
}
Expand All @@ -51,4 +58,23 @@ public List<UserResponse> list() {
.map(UserResponse::valueOf)
.collect(Collectors.toList());
}

@Transactional
public void updateProfile(UserProfileUpdateRequest request, Long userId) {
ImageFile imageFile = getImageFile(request);
User updatable = request.toUser(imageFile);

User user = userRepository.findById(userId).orElseThrow(() -> new KolivingServiceException(ServiceError.RECORD_NOT_EXIST));
user.update(updatable);
}

private ImageFile getImageFile(UserProfileUpdateRequest request) {
return imageFileRepository.findById(request.profileId())
.orElseThrow(() -> new KolivingServiceException(ServiceError.RECORD_NOT_EXIST));
}

public UserResponse findById(Long id) {
User user = userRepository.findById(id).orElseThrow(() -> new KolivingServiceException(ServiceError.RECORD_NOT_EXIST));
return UserResponse.valueOf(user);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
package com.koliving.api.user.application.dto;


import com.koliving.api.file.domain.ImageFile;
import com.koliving.api.user.Gender;
import com.koliving.api.user.SignUpStatus;
import com.koliving.api.user.User;
import com.koliving.api.user.UserRole;

public record UserResponse(Long id, String email, String imageUrl) {
import java.time.LocalDate;

public record UserResponse(Long id, String email, String firstName, String lastName, Gender gender, LocalDate birthDate,
String description, ImageFile imageFile, UserRole userRole, SignUpStatus signUpStatus) {

public static UserResponse valueOf(User entity) {
return new UserResponse(entity.getId(), entity.getEmail(), entity.getImageUrl());
return new UserResponse(
entity.getId(),
entity.getEmail(),
entity.getFirstName(),
entity.getLastName(),
entity.getGender(),
entity.getBirthDate(),
entity.getDescription(),
entity.getImageFile(),
entity.getUserRole(),
entity.getSignUpStatus()
);
}
}
2 changes: 1 addition & 1 deletion src/test/java/com/koliving/api/user/UserServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ void list_success() {

List<UserResponse> expected = userList.stream()
.map(UserResponse::valueOf)
.collect(Collectors.toList());
.toList();

assertTrue(actual.equals(expected));
assertTrue(actual.containsAll(expected));
Expand Down

0 comments on commit 8f415d3

Please sign in to comment.