Merge pull request '사원중복체크 API 추가, 회원정보 목록 조회 수정' (#53) from feat/dev_251201 into develop

Reviewed-on: https://kamco.gitea.gs.dabeeo.com/dabeeo/kamco-dabeeo-backoffice/pulls/53
This commit is contained in:
2025-12-15 12:13:41 +09:00
7 changed files with 117 additions and 59 deletions

View File

@@ -4,6 +4,7 @@ import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import com.kamco.cd.kamcoback.members.dto.MembersDto; import com.kamco.cd.kamcoback.members.dto.MembersDto;
import com.kamco.cd.kamcoback.members.service.AdminService; import com.kamco.cd.kamcoback.members.service.AdminService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponse;
@@ -12,6 +13,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import java.util.UUID; import java.util.UUID;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
@@ -86,4 +88,25 @@ public class AdminApiController {
adminService.updateMembers(uuid, updateReq); adminService.updateMembers(uuid, updateReq);
return ApiResponseDto.createOK(UUID.randomUUID()); return ApiResponseDto.createOK(UUID.randomUUID());
} }
@Operation(summary = "사번 중복 체크", description = "사번 중복 체크")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "조회 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Boolean.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@GetMapping("/{employeeNo}")
public ApiResponseDto<Boolean> checkEmployeeNo(
@Parameter(description = "중복 체크할 사번", required = true, example = "1234567") @PathVariable
String employeeNo) {
return ApiResponseDto.ok(adminService.existsByEmployeeNo(employeeNo));
}
} }

View File

@@ -31,22 +31,27 @@ public class MembersDto {
private String employeeNo; private String employeeNo;
private String status; private String status;
private String statusName; private String statusName;
@JsonFormatDttm private ZonedDateTime createdDttm; @JsonFormatDttm
@JsonFormatDttm private ZonedDateTime updatedDttm; private ZonedDateTime createdDttm;
@JsonFormatDttm private ZonedDateTime firstLoginDttm; @JsonFormatDttm
@JsonFormatDttm private ZonedDateTime lastLoginDttm; private ZonedDateTime firstLoginDttm;
@JsonFormatDttm
private ZonedDateTime lastLoginDttm;
@JsonFormatDttm
private ZonedDateTime statusChgDttm;
public Basic( public Basic(
Long id, Long id,
UUID uuid, UUID uuid,
String userRole, String userRole,
String name, String name,
String employeeNo, String employeeNo,
String status, String status,
ZonedDateTime createdDttm, ZonedDateTime createdDttm,
ZonedDateTime updatedDttm, ZonedDateTime firstLoginDttm,
ZonedDateTime firstLoginDttm, ZonedDateTime lastLoginDttm,
ZonedDateTime lastLoginDttm) { ZonedDateTime statusChgDttm
) {
this.id = id; this.id = id;
this.uuid = uuid; this.uuid = uuid;
this.userRole = userRole; this.userRole = userRole;
@@ -56,9 +61,9 @@ public class MembersDto {
this.status = status; this.status = status;
this.statusName = getStatusName(status); this.statusName = getStatusName(status);
this.createdDttm = createdDttm; this.createdDttm = createdDttm;
this.updatedDttm = updatedDttm;
this.firstLoginDttm = firstLoginDttm; this.firstLoginDttm = firstLoginDttm;
this.lastLoginDttm = lastLoginDttm; this.lastLoginDttm = lastLoginDttm;
this.statusChgDttm = statusChgDttm;
} }
private String getUserRoleName(String roleId) { private String getUserRoleName(String roleId) {

View File

@@ -42,4 +42,14 @@ public class AdminService {
public void updateMembers(UUID uuid, MembersDto.UpdateReq updateReq) { public void updateMembers(UUID uuid, MembersDto.UpdateReq updateReq) {
membersCoreService.updateMembers(uuid, updateReq); membersCoreService.updateMembers(uuid, updateReq);
} }
/**
* 사번 중복 체크
*
* @param employeeNo
* @return
*/
public boolean existsByEmployeeNo(String employeeNo) {
return membersCoreService.existsByEmployeeNo(employeeNo);
}
} }

View File

@@ -178,4 +178,14 @@ public class MembersCoreService {
memberEntity.setLoginFailCount(0); memberEntity.setLoginFailCount(0);
membersRepository.save(memberEntity); membersRepository.save(memberEntity);
} }
/**
* 사번 중복체크
*
* @param employeeNo
* @return
*/
public boolean existsByEmployeeNo(String employeeNo) {
return membersRepository.existsByEmployeeNo(employeeNo);
}
} }

View File

@@ -33,11 +33,11 @@ public class MembersRepositoryImpl implements MembersRepositoryCustom {
@Override @Override
public boolean existsByUserId(String userId) { public boolean existsByUserId(String userId) {
return queryFactory return queryFactory
.selectOne() .selectOne()
.from(memberEntity) .from(memberEntity)
.where(memberEntity.userId.eq(userId)) .where(memberEntity.userId.eq(userId))
.fetchFirst() .fetchFirst()
!= null; != null;
} }
/** /**
@@ -49,11 +49,11 @@ public class MembersRepositoryImpl implements MembersRepositoryCustom {
@Override @Override
public boolean existsByEmployeeNo(String employeeNo) { public boolean existsByEmployeeNo(String employeeNo) {
return queryFactory return queryFactory
.selectOne() .selectOne()
.from(memberEntity) .from(memberEntity)
.where(memberEntity.employeeNo.eq(employeeNo)) .where(memberEntity.employeeNo.eq(employeeNo))
.fetchFirst() .fetchFirst()
!= null; != null;
} }
/** /**
@@ -65,7 +65,7 @@ public class MembersRepositoryImpl implements MembersRepositoryCustom {
@Override @Override
public Optional<MemberEntity> findByUserId(String userId) { public Optional<MemberEntity> findByUserId(String userId) {
return Optional.ofNullable( return Optional.ofNullable(
queryFactory.selectFrom(memberEntity).where(memberEntity.userId.eq(userId)).fetchOne()); queryFactory.selectFrom(memberEntity).where(memberEntity.userId.eq(userId)).fetchOne());
} }
/** /**
@@ -77,10 +77,10 @@ public class MembersRepositoryImpl implements MembersRepositoryCustom {
@Override @Override
public Optional<MemberEntity> findByEmployeeNo(String employeeNo) { public Optional<MemberEntity> findByEmployeeNo(String employeeNo) {
return Optional.ofNullable( return Optional.ofNullable(
queryFactory queryFactory
.selectFrom(memberEntity) .selectFrom(memberEntity)
.where(memberEntity.employeeNo.eq(employeeNo)) .where(memberEntity.employeeNo.eq(employeeNo))
.fetchOne()); .fetchOne());
} }
/** /**
@@ -99,11 +99,11 @@ public class MembersRepositoryImpl implements MembersRepositoryCustom {
String contains = "%" + searchReq.getKeyword() + "%"; String contains = "%" + searchReq.getKeyword() + "%";
builder.and( builder.and(
memberEntity memberEntity
.name .name
.likeIgnoreCase(contains) .likeIgnoreCase(contains)
.or(memberEntity.userId.likeIgnoreCase(contains)) .or(memberEntity.userId.likeIgnoreCase(contains))
.or(memberEntity.employeeNo.likeIgnoreCase(contains))); .or(memberEntity.employeeNo.likeIgnoreCase(contains)));
} }
// 권한 // 권한
@@ -112,28 +112,27 @@ public class MembersRepositoryImpl implements MembersRepositoryCustom {
} }
List<MembersDto.Basic> content = List<MembersDto.Basic> content =
queryFactory queryFactory
.select( .select(
Projections.constructor( Projections.constructor(
MembersDto.Basic.class, MembersDto.Basic.class,
memberEntity.id, memberEntity.id,
memberEntity.uuid, memberEntity.uuid,
memberEntity.userRole, memberEntity.userRole,
memberEntity.name, memberEntity.name,
memberEntity.userId, memberEntity.employeeNo,
memberEntity.employeeNo, memberEntity.status,
memberEntity.tempPassword, memberEntity.createdDttm,
memberEntity.status, memberEntity.firstLoginDttm,
memberEntity.createdDttm, memberEntity.lastLoginDttm,
memberEntity.updatedDttm, memberEntity.statusChgDttm
memberEntity.firstLoginDttm, ))
memberEntity.lastLoginDttm)) .from(memberEntity)
.from(memberEntity) .where(builder)
.where(builder) .offset(pageable.getOffset())
.offset(pageable.getOffset()) .limit(pageable.getPageSize())
.limit(pageable.getPageSize()) .orderBy(memberEntity.createdDttm.desc())
.orderBy(memberEntity.createdDttm.desc()) .fetch();
.fetch();
long total = queryFactory.select(memberEntity).from(memberEntity).fetchCount(); long total = queryFactory.select(memberEntity).from(memberEntity).fetchCount();
@@ -149,6 +148,6 @@ public class MembersRepositoryImpl implements MembersRepositoryCustom {
@Override @Override
public Optional<MemberEntity> findByUUID(UUID uuid) { public Optional<MemberEntity> findByUUID(UUID uuid) {
return Optional.ofNullable( return Optional.ofNullable(
queryFactory.selectFrom(memberEntity).where(memberEntity.uuid.eq(uuid)).fetchOne()); queryFactory.selectFrom(memberEntity).where(memberEntity.uuid.eq(uuid)).fetchOne());
} }
} }

View File

@@ -57,6 +57,10 @@ token:
refresh-cookie-name: kamco-dev # 개발용 쿠키 이름 refresh-cookie-name: kamco-dev # 개발용 쿠키 이름
refresh-cookie-secure: false # 로컬 http 테스트면 false refresh-cookie-secure: false # 로컬 http 테스트면 false
springdoc:
swagger-ui:
persist-authorization: true # 스웨거 새로고침해도 토큰 유지, 로컬스토리지에 저장
logging: logging:
level: level:
org: org:
@@ -64,6 +68,7 @@ logging:
security: DEBUG security: DEBUG
org.springframework.security: DEBUG org.springframework.security: DEBUG
mapsheet: mapsheet:
upload: upload:
skipGdalValidation: true skipGdalValidation: true

View File

@@ -38,4 +38,10 @@ token:
refresh-cookie-name: kamco-local # 개발용 쿠키 이름 refresh-cookie-name: kamco-local # 개발용 쿠키 이름
refresh-cookie-secure: false # 로컬 http 테스트면 false refresh-cookie-secure: false # 로컬 http 테스트면 false
springdoc:
swagger-ui:
persist-authorization: true # 스웨거 새로고침해도 토큰 유지, 로컬스토리지에 저장