Merge pull request '회원의 정보를 가져온다.' (#110) from feat/dean/KC-68 into develop

Reviewed-on: https://kamco.gitea.gs.dabeeo.com/dabeeo/kamco-dabeeo-backoffice/pulls/110
This commit is contained in:
admin
2025-12-24 12:42:07 +09:00
6 changed files with 198 additions and 0 deletions

View File

@@ -77,8 +77,12 @@ public class SecurityConfig {
"/api/members/*/password", "/api/members/*/password",
"/v3/api-docs/**") "/v3/api-docs/**")
.permitAll() .permitAll()
// 로그인한 사용자만 가능
.requestMatchers("/api/user/**")
.authenticated()
.anyRequest() .anyRequest()
// .access(redisAuthorizationManager) // .access(redisAuthorizationManager)
.authenticated()) .authenticated())
.addFilterBefore( .addFilterBefore(
jwtAuthenticationFilter, jwtAuthenticationFilter,

View File

@@ -1,5 +1,6 @@
package com.kamco.cd.kamcoback.members.dto; package com.kamco.cd.kamcoback.members.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.kamco.cd.kamcoback.common.enums.RoleType; import com.kamco.cd.kamcoback.common.enums.RoleType;
import com.kamco.cd.kamcoback.common.enums.StatusType; import com.kamco.cd.kamcoback.common.enums.StatusType;
import com.kamco.cd.kamcoback.common.utils.enums.Enums; import com.kamco.cd.kamcoback.common.utils.enums.Enums;
@@ -181,4 +182,84 @@ public class MembersDto {
private String employeeNo; private String employeeNo;
private String role; private String role;
} }
@Getter
public static class RoleEntity {
private final RoleType type;
private final String name;
public RoleEntity(RoleType status) {
this.type = status;
this.name = status.getText();
}
}
@Getter
public static class StatusEntity {
private final StatusType type;
private final String name;
public StatusEntity(StatusType status) {
this.type = status;
this.name = status.getText();
}
}
@Getter
public static class EntityData {
@JsonIgnore private Long id;
private UUID uuid;
private String name;
private String employeeNo;
private RoleEntity role;
private StatusEntity status;
@JsonFormatDttm private ZonedDateTime createdDttm;
@JsonFormatDttm private ZonedDateTime firstLoginDttm;
@JsonFormatDttm private ZonedDateTime lastLoginDttm;
@JsonFormatDttm private ZonedDateTime statusChgDttm;
private Boolean isReset;
public EntityData(
Long id,
UUID uuid,
RoleType role,
String name,
String employeeNo,
StatusType status,
ZonedDateTime createdDttm,
ZonedDateTime firstLoginDttm,
ZonedDateTime lastLoginDttm,
ZonedDateTime statusChgDttm,
Boolean isReset) {
this.id = id;
this.uuid = uuid;
this.name = name;
this.employeeNo = employeeNo;
this.status = new StatusEntity(status);
this.createdDttm = createdDttm;
this.firstLoginDttm = firstLoginDttm;
this.lastLoginDttm = lastLoginDttm;
this.statusChgDttm = statusChgDttm;
this.isReset = isReset;
this.role = new RoleEntity(role);
}
private String getUserRoleName(String roleId) {
RoleType type = Enums.fromId(RoleType.class, roleId);
return type.getText();
}
private String getStatusName(String status, Boolean pwdResetYn) {
StatusType type = Enums.fromId(StatusType.class, status);
pwdResetYn = pwdResetYn != null && pwdResetYn;
if (type.equals(StatusType.PENDING) && pwdResetYn) {
type = StatusType.ACTIVE;
}
return type.getText();
}
}
} }

View File

@@ -23,6 +23,7 @@ import org.mindrot.jbcrypt.BCrypt;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@@ -173,4 +174,18 @@ public class MembersCoreService {
public boolean existsByEmployeeNo(String employeeNo) { public boolean existsByEmployeeNo(String employeeNo) {
return membersRepository.existsByEmployeeNo(employeeNo); return membersRepository.existsByEmployeeNo(employeeNo);
} }
/**
* 회원정보 조회 (단건 ) by uuid
*
* @param uuid
*/
@Transactional(readOnly = true)
public MembersDto.EntityData getUserInfoByUuid(String memberUuid) {
MemberEntity member =
membersRepository
.findByUUID(UUID.fromString(memberUuid))
.orElseThrow(MemberNotFoundException::new);
return member.toEntity();
}
} }

View File

@@ -1,6 +1,8 @@
package com.kamco.cd.kamcoback.postgres.entity; package com.kamco.cd.kamcoback.postgres.entity;
import com.kamco.cd.kamcoback.common.enums.RoleType;
import com.kamco.cd.kamcoback.common.enums.StatusType; import com.kamco.cd.kamcoback.common.enums.StatusType;
import com.kamco.cd.kamcoback.members.dto.MembersDto.EntityData;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
@@ -14,8 +16,10 @@ import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.annotations.ColumnDefault; import org.hibernate.annotations.ColumnDefault;
@Slf4j
@Getter @Getter
@Setter @Setter
@Entity @Entity
@@ -100,4 +104,19 @@ public class MemberEntity {
this.status = newStatus; this.status = newStatus;
this.statusChgDttm = ZonedDateTime.now(); this.statusChgDttm = ZonedDateTime.now();
} }
public EntityData toEntity() {
return new EntityData(
id,
uuid,
RoleType.valueOf(userRole),
name,
employeeNo,
StatusType.valueOf(status),
createdDttm,
firstLoginDttm,
lastLoginDttm,
statusChgDttm,
pwdResetYn);
}
} }

View File

@@ -0,0 +1,53 @@
package com.kamco.cd.kamcoback.user;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.members.dto.MembersDto;
import com.kamco.cd.kamcoback.user.service.UserInfoService;
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.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "사용자 정보", description = "사용자 정보 조회 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/user")
public class UserApiController {
private final UserInfoService userInfoService;
@Operation(
summary = "현재 로그인 사용자 정보 조회",
description = "JWT 토큰에서 사용자 ID를 추출하여 현재 로그인한 사용자의 정보를 조회합니다.")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "조회 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.EntityData.class))),
@ApiResponse(
responseCode = "401",
description = "인증 실패 (토큰 없음 또는 유효하지 않음)",
content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@GetMapping("/iam")
public ApiResponseDto<MembersDto.EntityData> iam() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String memberUuid = authentication.getName(); // JWT의 sub 값 (사용자 ID)
// Member의 정보를 조회해서 리턴한다.
return ApiResponseDto.createOK(userInfoService.getUserInfoByUuid(memberUuid));
}
}

View File

@@ -0,0 +1,26 @@
package com.kamco.cd.kamcoback.user.service;
import com.kamco.cd.kamcoback.members.dto.MembersDto;
import com.kamco.cd.kamcoback.postgres.core.MembersCoreService;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@RequiredArgsConstructor
@Service
@Transactional(readOnly = true)
public class UserInfoService {
private final MembersCoreService membersCoreService;
/**
* 회원정보 조회 (단건 ) by uuid
*
* @param uuid
* @return
*/
public MembersDto.EntityData getUserInfoByUuid(@NotNull String uuid) {
return membersCoreService.getUserInfoByUuid(uuid);
}
}