Merge remote-tracking branch 'origin/feat/dev_251201' into feat/dev_251201

This commit is contained in:
Moon
2025-12-11 17:16:58 +09:00
30 changed files with 609 additions and 372 deletions

View File

@@ -1,6 +1,8 @@
package com.kamco.cd.kamcoback.postgres.core;
import com.kamco.cd.kamcoback.auth.BCryptSaltGenerator;
import com.kamco.cd.kamcoback.common.enums.StatusType;
import com.kamco.cd.kamcoback.common.utils.UserUtil;
import com.kamco.cd.kamcoback.members.dto.MembersDto;
import com.kamco.cd.kamcoback.members.dto.MembersDto.AddReq;
import com.kamco.cd.kamcoback.members.dto.MembersDto.Basic;
@@ -8,7 +10,6 @@ import com.kamco.cd.kamcoback.members.dto.SignInRequest;
import com.kamco.cd.kamcoback.members.exception.MemberException.DuplicateMemberException;
import com.kamco.cd.kamcoback.members.exception.MemberException.DuplicateMemberException.Field;
import com.kamco.cd.kamcoback.members.exception.MemberException.MemberNotFoundException;
import com.kamco.cd.kamcoback.members.exception.MemberException.PasswordNotFoundException;
import com.kamco.cd.kamcoback.postgres.entity.MemberEntity;
import com.kamco.cd.kamcoback.postgres.repository.members.MembersRepository;
import java.time.ZonedDateTime;
@@ -24,6 +25,7 @@ import org.springframework.stereotype.Service;
public class MembersCoreService {
private final MembersRepository membersRepository;
private final UserUtil userUtil;
/**
* 관리자 계정 등록
@@ -48,6 +50,7 @@ public class MembersCoreService {
memberEntity.setPassword(hashedPassword);
memberEntity.setName(addReq.getName());
memberEntity.setEmployeeNo(addReq.getEmployeeNo());
memberEntity.setRgstrUidl(userUtil.getId());
return membersRepository.save(memberEntity).getId();
}
@@ -60,7 +63,7 @@ public class MembersCoreService {
*/
public void updateMembers(UUID uuid, MembersDto.UpdateReq updateReq) {
MemberEntity memberEntity =
membersRepository.findByUUID(uuid).orElseThrow(MemberNotFoundException::new);
membersRepository.findByUUID(uuid).orElseThrow(MemberNotFoundException::new);
if (StringUtils.isNotBlank(updateReq.getName())) {
memberEntity.setName(updateReq.getName());
@@ -75,48 +78,47 @@ public class MembersCoreService {
memberEntity.setEmployeeNo(updateReq.getEmployeeNo());
}
memberEntity.setUpdtrUid(userUtil.getId());
membersRepository.save(memberEntity);
}
/**
* 관리자 계정 미사용 처리
* 관리자 계정 삭제 처리
*
* @param uuid
*/
public void deleteAccount(UUID uuid) {
MemberEntity memberEntity =
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
memberEntity.setStatus("INACTIVE");
memberEntity.setStatus(StatusType.DELETED.getId());
memberEntity.setUpdatedDttm(ZonedDateTime.now());
memberEntity.setUpdtrUid(userUtil.getId());
membersRepository.save(memberEntity);
}
/**
* 패스워드 변경
*
* @param id
*/
public void resetPassword(Long id, MembersDto.InitReq initReq) {
public void resetPassword(String id, MembersDto.InitReq initReq) {
MemberEntity memberEntity =
membersRepository.findById(id).orElseThrow(() -> new MemberNotFoundException());
if (!memberEntity.getTempPassword().equals(initReq.getTempPassword())) {
throw new PasswordNotFoundException();
}
membersRepository.findByUserId(id).orElseThrow(() -> new MemberNotFoundException());
String salt =
BCryptSaltGenerator.generateSaltWithEmployeeNo(memberEntity.getEmployeeNo().trim());
BCryptSaltGenerator.generateSaltWithEmployeeNo(memberEntity.getEmployeeNo().trim());
// 패스워드 암호화
String hashedPassword = BCrypt.hashpw(initReq.getPassword(), salt);
memberEntity.setPassword(hashedPassword);
memberEntity.setStatus("ACTIVE");
memberEntity.setUpdatedDttm(ZonedDateTime.now());
memberEntity.setUpdtrUid(memberEntity.getId());
membersRepository.save(memberEntity);
}
//
/**
@@ -129,6 +131,20 @@ public class MembersCoreService {
return membersRepository.findByMembers(searchReq);
}
/**
* 사용자 상태 조회
*
* @param request
* @return
*/
public String getUserStatus(SignInRequest request) {
MemberEntity memberEntity =
membersRepository
.findByUserId(request.getUsername())
.orElseThrow(MemberNotFoundException::new);
return memberEntity.getStatus();
}
/**
* 최초 로그인 저장 마지막 로그인 저장
*
@@ -136,7 +152,7 @@ public class MembersCoreService {
*/
public void saveLogin(UUID uuid) {
MemberEntity memberEntity =
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
if (memberEntity.getFirstLoginDttm() == null) {
memberEntity.setFirstLoginDttm(ZonedDateTime.now());
@@ -145,33 +161,4 @@ public class MembersCoreService {
memberEntity.setLoginFailCount(0);
membersRepository.save(memberEntity);
}
/**
* 로그인 실패시 상태 저장
*
* @param uuid
*/
public void loginFail(UUID uuid) {
MemberEntity memberEntity =
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
int failCnt = memberEntity.getLoginFailCount() + 1;
if (failCnt >= 5) {
memberEntity.setStatus("INACTIVE");
}
memberEntity.setLoginFailCount(failCnt);
membersRepository.save(memberEntity);
}
/**
* 사용자 상태 조회
*
* @param request
* @return
*/
public String getUserStatus(SignInRequest request) {
MemberEntity memberEntity = membersRepository.findByUserId(request.getUsername()).orElseThrow(MemberNotFoundException::new);
return memberEntity.getStatus();
}
}

View File

@@ -2,17 +2,7 @@ package com.kamco.cd.kamcoback.postgres.entity;
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto;
import com.kamco.cd.kamcoback.postgres.CommonDateEntity;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.ZonedDateTime;
@@ -21,6 +11,7 @@ import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Where;
@Entity
@Getter
@@ -60,6 +51,7 @@ public class CommonCodeEntity extends CommonDateEntity {
private CommonCodeEntity parent;
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@Where(clause = "deleted = false or deleted is null")
private List<CommonCodeEntity> children = new ArrayList<>();
@Size(max = 255)

View File

@@ -1,5 +1,6 @@
package com.kamco.cd.kamcoback.postgres.entity;
import com.kamco.cd.kamcoback.common.enums.StatusType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
@@ -63,7 +64,7 @@ public class MemberEntity {
@Size(max = 20)
@ColumnDefault("'INACTIVE'")
@Column(name = "status", length = 20)
private String status = "INACTIVE";
private String status = StatusType.INACTIVE.getId();
@NotNull
@ColumnDefault("now()")
@@ -83,4 +84,10 @@ public class MemberEntity {
@Column(name = "login_fail_count")
@ColumnDefault("0")
private Integer loginFailCount = 0;
@Column(name = "rgstr_uid")
private Long rgstrUidl;
@Column(name = "updtr_uid")
private Long updtrUid;
}

View File

@@ -20,18 +20,8 @@ public class CommonCodeRepositoryImpl implements CommonCodeRepositoryCustom {
@Override
public Optional<CommonCodeEntity> findByCodeId(Long id) {
QCommonCodeEntity child = new QCommonCodeEntity("child");
return Optional.ofNullable(
queryFactory
.selectFrom(commonCodeEntity)
.leftJoin(commonCodeEntity.children, child)
.fetchJoin()
.where(
commonCodeEntity.id.eq(id),
commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull()),
child.deleted.isFalse().or(child.deleted.isNull()))
.orderBy(commonCodeEntity.order.asc(), child.order.asc())
.fetchOne());
queryFactory.selectFrom(commonCodeEntity).where(commonCodeEntity.id.eq(id)).fetchOne());
}
@Override
@@ -41,13 +31,12 @@ public class CommonCodeRepositoryImpl implements CommonCodeRepositoryCustom {
queryFactory
.selectFrom(commonCodeEntity)
.leftJoin(commonCodeEntity.children, child)
.fetchJoin()
.on(child.deleted.isFalse().or(child.deleted.isNull()))
.where(
commonCodeEntity.parent.isNull(),
commonCodeEntity.code.eq(code),
commonCodeEntity.used.isTrue(),
commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull()),
child.deleted.isFalse().or(child.deleted.isNull()))
commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull()))
.orderBy(child.order.asc())
.fetchOne());
}
@@ -61,8 +50,7 @@ public class CommonCodeRepositoryImpl implements CommonCodeRepositoryCustom {
.on(child.deleted.isFalse().or(child.deleted.isNull()))
.where(
commonCodeEntity.parent.isNull(),
commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull())
)
commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull()))
.orderBy(commonCodeEntity.order.asc(), child.order.asc())
.fetch();
}

View File

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