diff --git a/src/main/java/com/back/domain/profile/controller/ProfileController.java b/src/main/java/com/back/domain/profile/controller/ProfileController.java new file mode 100644 index 00000000..2bd8e66f --- /dev/null +++ b/src/main/java/com/back/domain/profile/controller/ProfileController.java @@ -0,0 +1,26 @@ +package com.back.domain.profile.controller; + +import com.back.domain.profile.dto.ProfileResponseDto; +import com.back.domain.profile.service.ProfileService; +import com.back.domain.user.service.UserService; +import com.back.global.rsData.RsData; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/me/profile") +@RequiredArgsConstructor +public class ProfileController { + + private final UserService userService; + private final ProfileService profileService; + + @GetMapping + public RsData getProfile(@AuthenticationPrincipal(expression = "id") Long userId) { + ProfileResponseDto body = profileService.getProfile(userId); + return RsData.successOf(body); // code=200, message="success" + } +} diff --git a/src/main/java/com/back/domain/profile/dto/ProfileResponseDto.java b/src/main/java/com/back/domain/profile/dto/ProfileResponseDto.java new file mode 100644 index 00000000..f42277f1 --- /dev/null +++ b/src/main/java/com/back/domain/profile/dto/ProfileResponseDto.java @@ -0,0 +1,18 @@ +package com.back.domain.profile.dto; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class ProfileResponseDto { + private Long id; + private String nickname; + private String email; + + // 서버에 저장된 실제 값(0~100) + private Double abvDegree; // 83.2 + // 표현용(서버에서 계산) + private Integer abvLevel; // 1~6 + private String abvLabel; // "83.2%" +} diff --git a/src/main/java/com/back/domain/profile/service/ProfileService.java b/src/main/java/com/back/domain/profile/service/ProfileService.java new file mode 100644 index 00000000..5fe694d2 --- /dev/null +++ b/src/main/java/com/back/domain/profile/service/ProfileService.java @@ -0,0 +1,34 @@ +package com.back.domain.profile.service; + +import com.back.domain.profile.dto.ProfileResponseDto; +import com.back.domain.user.entity.User; +import com.back.domain.user.repository.UserRepository; +import com.back.domain.user.support.AbvView; +import com.back.global.exception.ServiceException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class ProfileService { + + private final UserRepository userRepository; + + @Transactional(readOnly = true) + public ProfileResponseDto getProfile(Long id) { + User user = userRepository.findById(id).orElseThrow(() -> new ServiceException(404, "사용자를 찾을 수 없습니다.")); + + Double percent = user.getAbvDegree(); + int level = AbvView.levelOf(percent); + String label = AbvView.percentLabel(percent); + + return ProfileResponseDto.builder() + .id(user.getId()) + .nickname(user.getNickname()) + .abvDegree(percent) + .abvLevel(level) + .abvLabel(label) + .build(); + } +} diff --git a/src/main/java/com/back/domain/user/entity/User.java b/src/main/java/com/back/domain/user/entity/User.java index d1d64476..036d95d2 100644 --- a/src/main/java/com/back/domain/user/entity/User.java +++ b/src/main/java/com/back/domain/user/entity/User.java @@ -4,6 +4,8 @@ import lombok.*; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; import java.time.LocalDateTime; import java.util.ArrayList; @@ -33,16 +35,18 @@ public class User { private Double abvDegree; // 알콜도수(회원 등급) + @CreatedDate // JPA Auditing 적용 + @Column(nullable = false, updatable = false) private LocalDateTime createdAt; // 생성 날짜 + @LastModifiedDate // JPA Auditing 적용 + @Column(nullable = false) private LocalDateTime updatedAt; // 수정 날짜 @Builder.Default @Column(nullable = false, length = 20) private String role = "USER"; - private String profileImgUrl; - public boolean isAdmin() { return "ADMIN".equalsIgnoreCase(role); } diff --git a/src/main/java/com/back/domain/user/repository/UserRepository.java b/src/main/java/com/back/domain/user/repository/UserRepository.java index ce4bcc8a..040d5ef1 100644 --- a/src/main/java/com/back/domain/user/repository/UserRepository.java +++ b/src/main/java/com/back/domain/user/repository/UserRepository.java @@ -6,5 +6,6 @@ @Repository public interface UserRepository extends JpaRepository { + boolean existsByNicknameAndIdNot(String nickname, Long id); } diff --git a/src/main/java/com/back/domain/user/support/AbvView.java b/src/main/java/com/back/domain/user/support/AbvView.java new file mode 100644 index 00000000..72d26e8f --- /dev/null +++ b/src/main/java/com/back/domain/user/support/AbvView.java @@ -0,0 +1,28 @@ +package com.back.domain.user.support; + +public final class AbvView { + + private AbvView(){} + + // 0~100%를 6단계로 매핑 + public static int levelOf(Double percent) { + if (percent == null) return 1; + + double x = Math.max(0, Math.min(100, percent)); + int p = (int) x; + + if (p <= 10) return 1; // 0~10 + if (p <= 25) return 2; // 11~25 + if (p <= 45) return 3; // 26~45 + if (p <= 65) return 4; // 46~65 + if (p <= 85) return 5; // 66~85 + return 6; // 86~100 + } + + // 화면용 "23.5%" 라벨 + public static String percentLabel(Double percent) { + if (percent == null) return "0%"; + double x = Math.max(0.0, Math.min(100.0, percent)); + return (x % 1.0 == 0.0) ? String.format("%.0f%%", x) : String.format("%.1f%%", x); + } +}