Skip to content

Commit a9014cf

Browse files
authored
[feat] 프로필 조회 기능 구현 #16 (#20)
* feat: User엔티티에 JPA Auditing 적용 * feat: 프로필 요청 DTO 추가 * feat: ABV 레벨 및 퍼센트 라벨링 기능 추가 * feat: 닉네임 중복 확인 메서드 추가 * feat: 프로필 조회 로직 추가 * fix: 불필요한 필드 삭제 * feat: 로그인한 사용자 프로필 조회 API 추가
1 parent 3b7f868 commit a9014cf

File tree

6 files changed

+113
-2
lines changed

6 files changed

+113
-2
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.back.domain.profile.controller;
2+
3+
import com.back.domain.profile.dto.ProfileResponseDto;
4+
import com.back.domain.profile.service.ProfileService;
5+
import com.back.domain.user.service.UserService;
6+
import com.back.global.rsData.RsData;
7+
import lombok.RequiredArgsConstructor;
8+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
9+
import org.springframework.web.bind.annotation.GetMapping;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.RestController;
12+
13+
@RestController
14+
@RequestMapping("/me/profile")
15+
@RequiredArgsConstructor
16+
public class ProfileController {
17+
18+
private final UserService userService;
19+
private final ProfileService profileService;
20+
21+
@GetMapping
22+
public RsData<ProfileResponseDto> getProfile(@AuthenticationPrincipal(expression = "id") Long userId) {
23+
ProfileResponseDto body = profileService.getProfile(userId);
24+
return RsData.successOf(body); // code=200, message="success"
25+
}
26+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.back.domain.profile.dto;
2+
3+
import lombok.Builder;
4+
import lombok.Getter;
5+
6+
@Getter
7+
@Builder
8+
public class ProfileResponseDto {
9+
private Long id;
10+
private String nickname;
11+
private String email;
12+
13+
// 서버에 저장된 실제 값(0~100)
14+
private Double abvDegree; // 83.2
15+
// 표현용(서버에서 계산)
16+
private Integer abvLevel; // 1~6
17+
private String abvLabel; // "83.2%"
18+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.back.domain.profile.service;
2+
3+
import com.back.domain.profile.dto.ProfileResponseDto;
4+
import com.back.domain.user.entity.User;
5+
import com.back.domain.user.repository.UserRepository;
6+
import com.back.domain.user.support.AbvView;
7+
import com.back.global.exception.ServiceException;
8+
import lombok.RequiredArgsConstructor;
9+
import org.springframework.stereotype.Service;
10+
import org.springframework.transaction.annotation.Transactional;
11+
12+
@Service
13+
@RequiredArgsConstructor
14+
public class ProfileService {
15+
16+
private final UserRepository userRepository;
17+
18+
@Transactional(readOnly = true)
19+
public ProfileResponseDto getProfile(Long id) {
20+
User user = userRepository.findById(id).orElseThrow(() -> new ServiceException(404, "사용자를 찾을 수 없습니다."));
21+
22+
Double percent = user.getAbvDegree();
23+
int level = AbvView.levelOf(percent);
24+
String label = AbvView.percentLabel(percent);
25+
26+
return ProfileResponseDto.builder()
27+
.id(user.getId())
28+
.nickname(user.getNickname())
29+
.abvDegree(percent)
30+
.abvLevel(level)
31+
.abvLabel(label)
32+
.build();
33+
}
34+
}

src/main/java/com/back/domain/user/entity/User.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import lombok.*;
55
import org.springframework.security.core.GrantedAuthority;
66
import org.springframework.security.core.authority.SimpleGrantedAuthority;
7+
import org.springframework.data.annotation.CreatedDate;
8+
import org.springframework.data.annotation.LastModifiedDate;
79

810
import java.time.LocalDateTime;
911
import java.util.ArrayList;
@@ -33,16 +35,18 @@ public class User {
3335

3436
private Double abvDegree; // 알콜도수(회원 등급)
3537

38+
@CreatedDate // JPA Auditing 적용
39+
@Column(nullable = false, updatable = false)
3640
private LocalDateTime createdAt; // 생성 날짜
3741

42+
@LastModifiedDate // JPA Auditing 적용
43+
@Column(nullable = false)
3844
private LocalDateTime updatedAt; // 수정 날짜
3945

4046
@Builder.Default
4147
@Column(nullable = false, length = 20)
4248
private String role = "USER";
4349

44-
private String profileImgUrl;
45-
4650
public boolean isAdmin() {
4751
return "ADMIN".equalsIgnoreCase(role);
4852
}

src/main/java/com/back/domain/user/repository/UserRepository.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66

77
@Repository
88
public interface UserRepository extends JpaRepository<User, Long> {
9+
boolean existsByNicknameAndIdNot(String nickname, Long id);
910
}
1011

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.back.domain.user.support;
2+
3+
public final class AbvView {
4+
5+
private AbvView(){}
6+
7+
// 0~100%를 6단계로 매핑
8+
public static int levelOf(Double percent) {
9+
if (percent == null) return 1;
10+
11+
double x = Math.max(0, Math.min(100, percent));
12+
int p = (int) x;
13+
14+
if (p <= 10) return 1; // 0~10
15+
if (p <= 25) return 2; // 11~25
16+
if (p <= 45) return 3; // 26~45
17+
if (p <= 65) return 4; // 46~65
18+
if (p <= 85) return 5; // 66~85
19+
return 6; // 86~100
20+
}
21+
22+
// 화면용 "23.5%" 라벨
23+
public static String percentLabel(Double percent) {
24+
if (percent == null) return "0%";
25+
double x = Math.max(0.0, Math.min(100.0, percent));
26+
return (x % 1.0 == 0.0) ? String.format("%.0f%%", x) : String.format("%.1f%%", x);
27+
}
28+
}

0 commit comments

Comments
 (0)