This commit is contained in:
+33
@@ -8,12 +8,14 @@ import com.eactive.apim.portal.template.entity.QMessageRequest;
|
||||
import com.eactive.eai.rms.data.jpa.AbstractEMSDataSerivce;
|
||||
import com.querydsl.core.BooleanBuilder;
|
||||
import com.querydsl.core.types.dsl.BooleanExpression;
|
||||
import com.querydsl.jpa.JPAExpressions;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
@@ -54,9 +56,40 @@ public class PortalUserService extends AbstractEMSDataSerivce<PortalUser, String
|
||||
predicate.and(qPortalUser.roleCode.eq(PortalUserEnums.RoleCode.valueOf(portalUserUISearch.getSearchRoleCode())));
|
||||
}
|
||||
|
||||
// 휴대폰번호 중복(2명 이상 공유) 사용자만 조회
|
||||
if (portalUserUISearch.isOnlyDuplicateMobile()) {
|
||||
// 자바 리스트 .in() 은 컨버터가 IN 파라미터를 암호화하므로 레거시 평문 데이터와 매칭되지 않는다.
|
||||
// 대신 서브쿼리 .in() 으로 컬럼 대 컬럼(SQL 내부) 비교를 하여 평문/암호문 저장 방식과 무관하게 동작시킨다.
|
||||
QPortalUser dupUser = new QPortalUser("dupUser");
|
||||
predicate.and(qPortalUser.mobileNumber.in(
|
||||
JPAExpressions.select(dupUser.mobileNumber)
|
||||
.from(dupUser)
|
||||
.where(dupUser.mobileNumber.isNotNull()
|
||||
.and(dupUser.userStatus.ne(PortalUserEnums.UserStatus.REMOVED)))
|
||||
.groupBy(dupUser.mobileNumber)
|
||||
.having(dupUser.count().gt(1L))));
|
||||
}
|
||||
|
||||
return repository.findAll(predicate, pageable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 휴대폰번호가 중복되는 사용자 총 인원수(중복 그룹에 속한 사용자 수의 합)를 반환한다.
|
||||
*/
|
||||
public long countDuplicateMobileUsers() {
|
||||
QPortalUser qPortalUser = QPortalUser.portalUser;
|
||||
// Oracle 빈 문자열=NULL 이슈로 isNotNull 만 사용 (findDuplicateMobileNumbers 와 동일 기준)
|
||||
List<Long> duplicateGroupCounts = getJPAQueryFactory()
|
||||
.select(qPortalUser.count())
|
||||
.from(qPortalUser)
|
||||
.where(qPortalUser.mobileNumber.isNotNull()
|
||||
.and(qPortalUser.userStatus.ne(PortalUserEnums.UserStatus.REMOVED)))
|
||||
.groupBy(qPortalUser.mobileNumber)
|
||||
.having(qPortalUser.count().gt(1L))
|
||||
.fetch();
|
||||
return duplicateGroupCounts.stream().mapToLong(Long::longValue).sum();
|
||||
}
|
||||
|
||||
public boolean existsByLoginId(String loginId) {
|
||||
BooleanExpression predicate = QPortalUser.portalUser.loginId.eq(loginId);
|
||||
return repository.exists(predicate);
|
||||
|
||||
+3
@@ -23,4 +23,7 @@ public class PortalUserUISearch {
|
||||
|
||||
private boolean includeRemoved;
|
||||
|
||||
/** true 인 경우 휴대폰번호가 중복(2명 이상 공유)되는 사용자만 조회 */
|
||||
private boolean onlyDuplicateMobile;
|
||||
|
||||
}
|
||||
|
||||
@@ -102,6 +102,12 @@ public class PortalUserManController extends BaseAnnotationController {
|
||||
resultMap.put("userStatusRows", userStatusList);
|
||||
resultMap.put("roleCodeRows", roleCodeList);
|
||||
resultMap.put("isProdServer", SystemUtil.isProdServer());
|
||||
|
||||
// 휴대폰번호 중복 허용안함 여부 및 중복 사용자 수 (배너 노출용)
|
||||
Map<String, Object> mobileDuplicateInfo = portalUserManService.getMobileDuplicateInfo();
|
||||
resultMap.put("mobileDuplicateCheckEnabled", mobileDuplicateInfo.get("enabled"));
|
||||
resultMap.put("mobileDuplicateUserCount", mobileDuplicateInfo.get("count"));
|
||||
|
||||
return ResponseEntity.ok(resultMap);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.eactive.apim.portal.file.entity.FileDetail;
|
||||
import com.eactive.apim.portal.file.entity.FileInfo;
|
||||
import com.eactive.apim.portal.file.service.FileService;
|
||||
import com.eactive.apim.portal.portalorg.entity.PortalOrg;
|
||||
import com.eactive.apim.portal.portalproperty.service.PortalPropertyService;
|
||||
import com.eactive.apim.portal.portaluser.entity.PortalUser;
|
||||
import com.eactive.apim.portal.portaluser.entity.PortalUserEnums;
|
||||
import com.eactive.apim.portal.portaluser.entity.PortalUserPrivacyAgreement;
|
||||
@@ -31,7 +32,9 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@Transactional(transactionManager = "transactionManagerForEMS")
|
||||
@@ -39,6 +42,11 @@ import java.util.List;
|
||||
@Slf4j
|
||||
public class PortalUserManService extends BaseService {
|
||||
|
||||
/** PortalProperty 그룹명 */
|
||||
private static final String PORTAL_PROPERTY_GROUP = "Portal";
|
||||
/** 사용자 별 휴대폰 번호 중복 허용 프로퍼티 키 (Y:허용, N:허용안함) */
|
||||
private static final String PROP_MOBILE_DUPLICATE_ALLOW = "user.mobile.duplicate.allow";
|
||||
|
||||
private final PortalUserService portalUserService;
|
||||
private final PortalUserUIMapper portalUserUIMapper;
|
||||
private final LocaleMessage localeMessage;
|
||||
@@ -50,6 +58,7 @@ public class PortalUserManService extends BaseService {
|
||||
private final PortalUserTermsService portalUserTermsService;
|
||||
private final ApprovalService approvalService;
|
||||
private final PortalInquiryService portalInquiryService;
|
||||
private final PortalPropertyService portalPropertyService;
|
||||
|
||||
|
||||
public Page<PortalUserUI> selectList(Pageable pageable, PortalUserUISearch portalUserUISearch) {
|
||||
@@ -57,6 +66,11 @@ public class PortalUserManService extends BaseService {
|
||||
return portalUser.map(entity -> {
|
||||
PortalUserUI ui = convertToUIWithMaskOption(entity, false);
|
||||
|
||||
// 목록의 휴대폰번호는 항상 마스킹 (중복 조회 모드에서만 컬럼이 노출되며 개인정보 보호)
|
||||
if (ui != null && StringUtils.isNotBlank(ui.getMobileNumber())) {
|
||||
ui.setMobileNumber(MaskingUtils.maskPhoneNumber(ui.getMobileNumber()));
|
||||
}
|
||||
|
||||
if (entity.getPortalOrg() != null) {
|
||||
setPortalOrgUI(entity, ui);
|
||||
}
|
||||
@@ -64,6 +78,28 @@ public class PortalUserManService extends BaseService {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 사용자 별 휴대폰 번호 중복 허용 프로퍼티(Portal/user.mobile.duplicate.allow)를 확인한다.
|
||||
* 프로퍼티가 없으면 기본값 'N'(허용안함)으로 생성하며, '허용안함'일 때 중복 휴대폰번호 사용자 수를 함께 반환한다.
|
||||
*
|
||||
* @return enabled(boolean): 중복 조회 기능 활성 여부, count(long): 중복 휴대폰번호 사용자 수
|
||||
*/
|
||||
public Map<String, Object> getMobileDuplicateInfo() {
|
||||
String allowValue = portalPropertyService.getOrCreateProperty(
|
||||
PORTAL_PROPERTY_GROUP,
|
||||
PROP_MOBILE_DUPLICATE_ALLOW,
|
||||
"N",
|
||||
"사용자 별 휴대폰 번호 중복 허용 여부 (Y:허용, N:허용안함). 허용안함일 때 사용자 관리 목록에 중복 휴대폰번호 사용자 조회 기능을 노출");
|
||||
|
||||
boolean checkEnabled = "N".equalsIgnoreCase(allowValue);
|
||||
long duplicateUserCount = checkEnabled ? portalUserService.countDuplicateMobileUsers() : 0L;
|
||||
|
||||
Map<String, Object> info = new HashMap<>();
|
||||
info.put("enabled", checkEnabled);
|
||||
info.put("count", duplicateUserCount);
|
||||
return info;
|
||||
}
|
||||
|
||||
public PortalUserUI selectDetail(String id, boolean isMasked) {
|
||||
PortalUser portalUser = portalUserService.getById(id);
|
||||
PortalUserUI portalUserUI = convertToUIWithMaskOption(portalUser, isMasked);
|
||||
|
||||
Reference in New Issue
Block a user