Skip to content

Commit

Permalink
Merge pull request #7 from YAPP-Github/feature/6-profile-usecase
Browse files Browse the repository at this point in the history
Feature: 유저 프로필 (기본, 소개글) 생성/수정 (#PC-80)
  • Loading branch information
devchlee12 authored Dec 26, 2024
2 parents 43049f5 + a98eee2 commit 048d861
Show file tree
Hide file tree
Showing 26 changed files with 822 additions and 188 deletions.
Original file line number Diff line number Diff line change
@@ -1,43 +1,45 @@
package org.yapp.domain.auth.application.oauth.service;

import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.yapp.domain.auth.application.jwt.JwtUtil;
import org.yapp.domain.auth.application.oauth.OauthProvider;
import org.yapp.domain.auth.application.oauth.OauthProviderResolver;
import org.yapp.domain.auth.dto.request.OauthLoginRequest;
import org.yapp.domain.auth.dto.response.OauthLoginResponse;
import org.yapp.domain.user.User;
import org.yapp.domain.user.dao.UserRepository;
import org.yapp.domain.user.domain.User;

import java.util.Optional;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class OauthService {
private final OauthProviderResolver oauthProviderResolver;
private final JwtUtil jwtUtil;
private final UserRepository userRepository;

public OauthLoginResponse login(OauthLoginRequest request){
OauthProvider oauthProvider = oauthProviderResolver.find(request.getProviderName());
String oauthId = request.getProviderName() + oauthProvider.getOAuthProviderUserId(request.getToken());

//이미 가입된 유저인지 확인하고 가입되어 있지 않으면 회원가입 처리
Optional<User> userOptional = userRepository.findByOauthId(oauthId);
if (userOptional.isEmpty()){
User newUser = User.builder().oauthId(oauthId).build();
User savedUser = userRepository.save(newUser);
Long userId = savedUser.getId();
String accessToken = jwtUtil.createJwt("access_token",userId, oauthId, "member", 600000L);
String refreshToken = jwtUtil.createJwt("refresh_token",userId, oauthId, "member", 864000000L);
return new OauthLoginResponse(true, accessToken, refreshToken);
}

//이미 가입한 유저인 경우 로그인 처리
Long userId = userOptional.get().getId();
String accessToken = jwtUtil.createJwt("access_token", userId,oauthId, "member", 600000L);
String refreshToken = jwtUtil.createJwt("refresh_token", userId,oauthId, "member", 864000000L);

return new OauthLoginResponse(false, accessToken, refreshToken);
private final OauthProviderResolver oauthProviderResolver;
private final JwtUtil jwtUtil;
private final UserRepository userRepository;

public OauthLoginResponse login(OauthLoginRequest request) {
OauthProvider oauthProvider = oauthProviderResolver.find(request.getProviderName());
String oauthId = request.getProviderName() + oauthProvider.getOAuthProviderUserId(request.getToken());

//이미 가입된 유저인지 확인하고 가입되어 있지 않으면 회원가입 처리
Optional<User> userOptional = userRepository.findByOauthId(oauthId);
if (userOptional.isEmpty()) {
User newUser = User.builder().oauthId(oauthId).build();
User savedUser = userRepository.save(newUser);
Long userId = savedUser.getId();
String accessToken = jwtUtil.createJwt("access_token", userId, oauthId, "member", 600000L);
String refreshToken = jwtUtil.createJwt("refresh_token", userId, oauthId, "member", 864000000L);
return new OauthLoginResponse(true, accessToken, refreshToken);
}

//이미 가입한 유저인 경우 로그인 처리
Long userId = userOptional.get().getId();
String accessToken = jwtUtil.createJwt("access_token", userId, oauthId, "member", 600000L);
String refreshToken = jwtUtil.createJwt("refresh_token", userId, oauthId, "member", 864000000L);

return new OauthLoginResponse(false, accessToken, refreshToken);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.yapp.domain.profile.api;

import org.springframework.http.HttpStatus;
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;
import org.yapp.domain.profile.Profile;
import org.yapp.domain.profile.api.request.ProfileUpdateRequest;
import org.yapp.domain.profile.api.response.ProfileResponse;
import org.yapp.domain.profile.application.ProfileService;
import org.yapp.domain.user.User;
import org.yapp.util.ApiResponse;

import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/profiles")
public class ProfileController {
private final ProfileService profileService;

@GetMapping
@Operation(summary = "프로필 조회", description = "현재 로그인된 사용자의 프로필을 조회합니다.", tags = {"Profile"})
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "프로필이 성공적으로 조회되었습니다.")
public ResponseEntity<ApiResponse<ProfileResponse>> updateProfile(@AuthenticationPrincipal User user) {
Profile profile = profileService.getProfileById(user.getProfile().getId());
return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(ProfileResponse.from(profile)));
}

@PutMapping()
@Operation(summary = "프로필 업데이트", description = "현재 로그인된 사용자의 프로필을 업데이트합니다.", tags = {"Profile"})
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "프로필이 성공적으로 업데이트되었습니다.")
public ResponseEntity<ApiResponse<ProfileResponse>> updateProfile(@AuthenticationPrincipal User user,
@RequestBody @Valid ProfileUpdateRequest request) {
Profile profile = profileService.updateByUserId(user.getId(), request);
return ResponseEntity.status(HttpStatus.OK).body(ApiResponse.success(ProfileResponse.from(profile)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.yapp.domain.profile.api.request;

import org.yapp.domain.profile.ProfileBasic;
import org.yapp.domain.profile.ProfileBio;

import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;

public record ProfileUpdateRequest(@NotBlank(message = "닉네임은 비어있을 수 없습니다.") String nickname,

@NotBlank(message = "생일은 비어있을 수 없습니다.") String birthdate,

@Min(value = 50, message = "키는 최소 50cm 이상이어야 합니다.") @Max(value = 300,
message = "키는 250cm를 초과할 수 없습니다.") int height,

@NotBlank(message = "직업은 비어있을 수 없습니다.") String job,

@NotBlank(message = "위치는 비어있을 수 없습니다.") String location,

String smokingStatus, String religion, String snsActivityLevel,

@Pattern(regexp = "^\\d{10,11}$",
message = "전화번호는 10자리에서 11자리 숫자여야 합니다.") String phoneNumber,

String imageUrl,

@Size(max = 500, message = "자기소개는 500자를 초과할 수 없습니다.") String introduction,

@Size(max = 500, message = "목표는 500자를 초과할 수 없습니다.") String goal,

@Size(max = 500, message = "관심사는 500자를 초과할 수 없습니다.") String interest) {

public ProfileBio toProfileBio() {
return ProfileBio.builder().introduction(introduction).goal(goal).interest(interest).build();
}

public ProfileBasic toProfileBasic() {
return ProfileBasic.builder()
.nickname(nickname)
.birthdate(java.sql.Date.valueOf(birthdate))
.height(height)
.job(job)
.location(location)
.smokingStatus(smokingStatus)
.religion(religion)
.snsActivityLevel(snsActivityLevel)
.phoneNumber(phoneNumber)
.imageUrl(imageUrl)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.yapp.domain.profile.api.response;

import org.yapp.domain.profile.Profile;
import org.yapp.domain.profile.ProfileBasic;
import org.yapp.domain.profile.ProfileBio;

import java.util.List;

public record ProfileResponse(Long id, String nickname, String birthdate, int height, String job, String location,
String smokingStatus, String religion, String snsActivityLevel, String phoneNumber,
String imageUrl, String introduction, String goal, String interest,
List<ProfileValueResponse> profileValues) {

public static ProfileResponse from(Profile profile) {
ProfileBasic basic = profile.getProfileBasic();
ProfileBio bio = profile.getProfileBio();

List<ProfileValueResponse> values = profile.getProfileValues().stream().map(ProfileValueResponse::from).toList();

return new ProfileResponse(profile.getId(), basic.getNickname(), basic.getBirthdate().toString(), basic.getHeight(),
basic.getJob(), basic.getLocation(), basic.getSmokingStatus(), basic.getReligion(), basic.getSnsActivityLevel(),
basic.getPhoneNumber(), basic.getImageUrl(), bio.getIntroduction(), bio.getGoal(), bio.getInterest(), values);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.yapp.domain.profile.api.response;

import org.yapp.domain.profile.ProfileValue;
import org.yapp.domain.profile.ValueItem;

public record ProfileValueResponse(Long id, ValueItem valueItem, Integer selectedValue) {
public static ProfileValueResponse from(ProfileValue profileValue) {
return new ProfileValueResponse(profileValue.getId(), profileValue.getValueItem(),
profileValue.getSelectedAnswer());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.yapp.domain.profile.application;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yapp.domain.profile.Profile;
import org.yapp.domain.profile.ProfileBasic;
import org.yapp.domain.profile.ProfileBio;
import org.yapp.domain.profile.api.request.ProfileUpdateRequest;
import org.yapp.domain.profile.application.dto.ProfileCreateDto;
import org.yapp.domain.profile.dao.ProfileRepository;
import org.yapp.domain.user.User;
import org.yapp.domain.user.application.UserService;
import org.yapp.error.dto.ProfileErrorCode;
import org.yapp.error.exception.ApplicationException;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class ProfileService {
private final UserService userService;
private final ProfileRepository profileRepository;

@Transactional
public Profile create(ProfileCreateDto dto) {
ProfileBasic profileBasic = ProfileBasic.builder().nickname(dto.nickName()).phoneNumber(dto.phoneNumber()).build();
ProfileBio profileBio = ProfileBio.builder().build();
Profile profile = Profile.builder().profileBasic(profileBasic).profileBio(profileBio).build();

return profileRepository.save(profile);
}

@Transactional
public Profile getProfileById(long profileId) {
return profileRepository.findById(profileId)
.orElseThrow(() -> new ApplicationException(ProfileErrorCode.NOTFOUND_PROFILE));
}

@Transactional
public Profile updateByUserId(long userId, ProfileUpdateRequest dto) {
User user = this.userService.getUserById(userId);
Profile profile = getProfileById(user.getProfile().getId());

ProfileBasic profileBasic = dto.toProfileBasic();
ProfileBio profileBio = dto.toProfileBio();

profile.updateBasic(profileBasic);
profile.updateBio(profileBio);

return profile;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.yapp.domain.profile.application.dto;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.Builder;

@Builder
public record ProfileCreateDto(@NotBlank String name, @NotBlank String nickName,
@NotBlank @Pattern(regexp = "\\d{3}-\\d{4}-\\d{4}") String phoneNumber) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.yapp.domain.profile.application.util;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

public class NickNameGenerator {
private static final List<String> ANIMAL_NAMES =
List.of("사자", "호랑이", "곰", "독수리", "늑대", "판다", "여우", "사슴", "토끼", "돌고래");

public static String generateNickname() {
String animal = ANIMAL_NAMES.get(ThreadLocalRandom.current().nextInt(ANIMAL_NAMES.size()));
int number = ThreadLocalRandom.current().nextInt(10000) + 1;
return animal + number;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.yapp.domain.profile.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import org.yapp.domain.profile.Profile;

@Repository
public interface ProfileRepository extends JpaRepository<Profile, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.yapp.domain.user.application;

import org.springframework.stereotype.Service;
import org.yapp.domain.user.User;
import org.yapp.domain.user.dao.UserRepository;
import org.yapp.error.dto.UserErrorCode;
import org.yapp.error.exception.ApplicationException;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;

public User getUserById(Long userId) {
return userRepository.findById(userId).orElseThrow(() -> new ApplicationException(UserErrorCode.NOTFOUND_USER));
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package org.yapp.domain.user.dao;

import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.yapp.domain.user.domain.User;
import org.yapp.domain.user.User;

import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByOauthId(String oauthId);
Optional<User> findByOauthId(String oauthId);
}
58 changes: 29 additions & 29 deletions api/src/main/java/org/yapp/domain/user/domain/User.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
package org.yapp.domain.user.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Table(name = "USER")
@Entity
@Getter
@NoArgsConstructor
public class User {
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "OAUTH_ID",nullable = false)
private String oauthId;

@Builder
public User(String oauthId) {
this.oauthId = oauthId;
}
}
//package org.yapp.domain.user.domain;
//
//import jakarta.persistence.Column;
//import jakarta.persistence.Entity;
//import jakarta.persistence.GeneratedValue;
//import jakarta.persistence.GenerationType;
//import jakarta.persistence.Id;
//import jakarta.persistence.Table;
//import lombok.Builder;
//import lombok.Getter;
//import lombok.NoArgsConstructor;
//
//@Table(name = "USER")
//@Entity
//@Getter
//@NoArgsConstructor
//public class User {
// @Id
// @Column(name = "ID")
// @GeneratedValue(strategy = GenerationType.IDENTITY)
// private Long id;
// @Column(name = "OAUTH_ID",nullable = false)
// private String oauthId;
//
// @Builder
// public User(String oauthId) {
// this.oauthId = oauthId;
// }
//}
Loading

0 comments on commit 048d861

Please sign in to comment.