Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ca44e8a967 | |||
| ce3efa299e | |||
| ad2ecb0b82 | |||
| f7bff90844 | |||
| 658958c9ef | |||
| ea031f3755 | |||
| 320e0d6011 | |||
| bda9fad391 | |||
| 363863746b | |||
| 1a12816643 | |||
| 6abb55a656 | |||
| 8cc6f775db |
@@ -77,5 +77,21 @@ public class Approval implements Serializable, com.eactive.eai.data.Data {
|
|||||||
private LocalDateTime approvalDate;
|
private LocalDateTime approvalDate;
|
||||||
|
|
||||||
@Column(name = "expect_end_date")
|
@Column(name = "expect_end_date")
|
||||||
private String expectEndDate; //예상완료일
|
private String expectEndDate; //예상완료일 (yyyyMMdd)
|
||||||
|
|
||||||
|
/** 예상완료일(yyyyMMdd)의 한글 요일. 값이 없거나 형식이 맞지 않으면 빈 문자열. (예: "토") */
|
||||||
|
@Transient
|
||||||
|
public String getExpectEndDateDayOfWeek() {
|
||||||
|
if (expectEndDate == null || expectEndDate.length() < 8) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return java.time.LocalDate
|
||||||
|
.parse(expectEndDate.substring(0, 8), java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"))
|
||||||
|
.getDayOfWeek()
|
||||||
|
.getDisplayName(java.time.format.TextStyle.SHORT, java.util.Locale.KOREAN);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package com.eactive.apim.portal.common.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 한국 전화번호/연락처 정규화 유틸 (portal·admin 공유).
|
||||||
|
*
|
||||||
|
* 전화번호 저장은 본 유틸로 하이픈 구분 정규형으로 통일한다. 저장 형식이 경로별로
|
||||||
|
* 달라(가입=원본, 초대=하이픈, SSO=숫자만) 휴대폰 기반 조회/초대 매칭이 어긋나는 것을 막는다.
|
||||||
|
* 암호화 컨버터가 붙은 필드는 {@code @PrePersist}/{@code @PreUpdate} 에서 본 메서드로 평문을
|
||||||
|
* 정규화한 뒤 암호화되므로 암복호화에 영향이 없다.
|
||||||
|
*/
|
||||||
|
public final class PhoneNumberUtil {
|
||||||
|
|
||||||
|
private PhoneNumberUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 한국 전화번호를 하이픈 구분 정규형으로 변환한다.
|
||||||
|
* 숫자만 추출 후 prefix/길이로 포맷하며, 해당 규칙에 맞지 않는 값은 원본을 그대로 반환한다.
|
||||||
|
* 멱등(이미 정규형이면 동일 결과)이며 null/blank 는 원본을 반환한다.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* 휴대폰 01X 11자리 → XXX-XXXX-XXXX (010-1234-5678)
|
||||||
|
* 휴대폰 01X 10자리 → XXX-XXX-XXXX (011-123-4567)
|
||||||
|
* 서울 02 9자리 → 02-XXX-XXXX (02-123-4567)
|
||||||
|
* 서울 02 10자리 → 02-XXXX-XXXX (02-1234-5678)
|
||||||
|
* 지역/070 0XX 10자리 → 0XX-XXX-XXXX (031-234-5678)
|
||||||
|
* 지역/070 0XX 11자리 → 0XX-XXXX-XXXX (070-1234-5678)
|
||||||
|
* 안심 050X 12자리 → 0XXX-XXXX-XXXX (0507-1234-5678)
|
||||||
|
* 대표 15/16/18XX 8자리 → XXXX-XXXX (1588-1234)
|
||||||
|
* 그 외/null → 원본 그대로
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public static String normalize(String raw) {
|
||||||
|
if (raw == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String digits = raw.replaceAll("[^0-9]", "");
|
||||||
|
int len = digits.length();
|
||||||
|
if (len == 0) {
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 대표번호 15XX/16XX/18XX (8자리, 지역번호 없음)
|
||||||
|
if (len == 8 && (digits.startsWith("15") || digits.startsWith("16") || digits.startsWith("18"))) {
|
||||||
|
return digits.substring(0, 4) + "-" + digits.substring(4);
|
||||||
|
}
|
||||||
|
// 안심번호 050X (12자리)
|
||||||
|
if (len == 12 && digits.startsWith("050")) {
|
||||||
|
return digits.substring(0, 4) + "-" + digits.substring(4, 8) + "-" + digits.substring(8);
|
||||||
|
}
|
||||||
|
// 서울 02
|
||||||
|
if (digits.startsWith("02")) {
|
||||||
|
if (len == 9) {
|
||||||
|
return "02-" + digits.substring(2, 5) + "-" + digits.substring(5);
|
||||||
|
}
|
||||||
|
if (len == 10) {
|
||||||
|
return "02-" + digits.substring(2, 6) + "-" + digits.substring(6);
|
||||||
|
}
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
// 휴대폰/지역/070 등 0XX
|
||||||
|
if (digits.startsWith("0")) {
|
||||||
|
if (len == 10) {
|
||||||
|
return digits.substring(0, 3) + "-" + digits.substring(3, 6) + "-" + digits.substring(6);
|
||||||
|
}
|
||||||
|
if (len == 11) {
|
||||||
|
return digits.substring(0, 3) + "-" + digits.substring(3, 7) + "-" + digits.substring(7);
|
||||||
|
}
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 숫자만 추출(발송 게이트웨이 전달·등가 비교용). null 은 그대로 반환.
|
||||||
|
*/
|
||||||
|
public static String digitsOnly(String raw) {
|
||||||
|
return raw == null ? null : raw.replaceAll("[^0-9]", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.eactive.apim.portal.invitation.entity;
|
package com.eactive.apim.portal.invitation.entity;
|
||||||
|
|
||||||
|
import com.eactive.apim.portal.common.util.PhoneNumberUtil;
|
||||||
import com.eactive.apim.portal.invitation.entity.UserInvitationEnums.InvitationStatus;
|
import com.eactive.apim.portal.invitation.entity.UserInvitationEnums.InvitationStatus;
|
||||||
import com.eactive.apim.portal.jpa.PersonalDataEncryptConverter;
|
import com.eactive.apim.portal.jpa.PersonalDataEncryptConverter;
|
||||||
import com.eactive.eai.data.converter.LocalDateTimeToStringConverter14;
|
import com.eactive.eai.data.converter.LocalDateTimeToStringConverter14;
|
||||||
@@ -62,4 +63,11 @@ public class UserInvitation {
|
|||||||
@Comment("만료일시")
|
@Comment("만료일시")
|
||||||
private LocalDateTime expiresOn;
|
private LocalDateTime expiresOn;
|
||||||
|
|
||||||
|
/** 저장 시 초대 휴대폰을 하이픈 구분 정규형으로 통일 */
|
||||||
|
@PrePersist
|
||||||
|
@PreUpdate
|
||||||
|
private void normalizePhones() {
|
||||||
|
this.invitationMobile = PhoneNumberUtil.normalize(this.invitationMobile);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ public class UserInvitationCancelEvent implements MessageEventHandler {
|
|||||||
Map<String, String> requestParams = new HashMap<>();
|
Map<String, String> requestParams = new HashMap<>();
|
||||||
requestParams.put("corpName", params.get("corpName").toString());
|
requestParams.put("corpName", params.get("corpName").toString());
|
||||||
requestParams.put("managerName", params.get("managerName").toString());
|
requestParams.put("managerName", params.get("managerName").toString());
|
||||||
|
// DB 템플릿 USER_INVITATION_CANCELED SMS 변수(%ORG_NAME%)에 매핑
|
||||||
|
requestParams.put("ORG_NAME", params.get("corpName").toString());
|
||||||
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ public class UserInvitationEvent implements MessageEventHandler {
|
|||||||
requestParams.put("url", params.get("url").toString());
|
requestParams.put("url", params.get("url").toString());
|
||||||
requestParams.put("loginId",params.get("corpName").toString() + " 이용자");
|
requestParams.put("loginId",params.get("corpName").toString() + " 이용자");
|
||||||
requestParams.put("authNumber", params.get("authNumber").toString());
|
requestParams.put("authNumber", params.get("authNumber").toString());
|
||||||
|
// DB 템플릿 USER_INVITATION SMS 변수(%ORG_NAME%)에 매핑 (USER_NAME 은 공통 자동주입)
|
||||||
|
requestParams.put("ORG_NAME", params.get("corpName").toString());
|
||||||
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,22 @@ public class PersonalDataEncryptConverter implements AttributeConverter<String,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("DB 복호화 : {} -> {}", dbDataOriginal, dbData);
|
if (log.isDebugEnabled()) {
|
||||||
|
// 복호화 결과(평문) 홀수 글자 마스킹
|
||||||
|
String maskedDbData = dbData;
|
||||||
|
if (StringUtils.isNotEmpty(dbData)) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < dbData.length(); i++) {
|
||||||
|
if (i % 2 == 0) {
|
||||||
|
sb.append(dbData.charAt(i));
|
||||||
|
} else {
|
||||||
|
sb.append("*");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maskedDbData = sb.toString();
|
||||||
|
}
|
||||||
|
log.debug("DB 복호화 : {} -> {}", dbDataOriginal, maskedDbData);
|
||||||
|
}
|
||||||
|
|
||||||
return dbData;
|
return dbData;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package com.eactive.apim.portal.partnership.event;
|
||||||
|
|
||||||
|
import com.eactive.apim.portal.template.entity.MessageCode;
|
||||||
|
import com.eactive.apim.portal.template.service.MessageEventHandler;
|
||||||
|
import com.eactive.apim.portal.template.service.MessageRecipient;
|
||||||
|
import com.eactive.apim.portal.template.service.MessageSendEvent;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class PartnershipCreatedEvent implements MessageEventHandler {
|
||||||
|
|
||||||
|
public static final MessageCode KEY = MessageCode.PARTNERSHIP_CREATED;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean allowAdditionalRecipients() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessageSendEvent createEvent(Object source, MessageRecipient recipient, Map<String, Object> params) {
|
||||||
|
Map<String, String> requestParams = new HashMap<>();
|
||||||
|
String subject = toStr(params.get("bizSubject"));
|
||||||
|
if (subject.isEmpty()) {
|
||||||
|
subject = toStr(params.get("subject"));
|
||||||
|
}
|
||||||
|
requestParams.put("partnershipId", toStr(params.get("partnershipId")));
|
||||||
|
requestParams.put("bizSubject", subject);
|
||||||
|
requestParams.put("subject", subject);
|
||||||
|
requestParams.put("writerName", toStr(params.get("writerName")));
|
||||||
|
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toStr(Object value) {
|
||||||
|
return value == null ? "" : value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessageCode getKey() {
|
||||||
|
return KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisplayName() {
|
||||||
|
return "개선요청/제휴 게시물 등록";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "<div>사용 가능 변수: </div><br/>"
|
||||||
|
+ "<div> - userName: 수신자 이름 </div><br/>"
|
||||||
|
+ "<div> - userId: 수신자 ID (이메일) </div><br/>"
|
||||||
|
+ "<div> - partnershipId: 신청 ID </div><br/>"
|
||||||
|
+ "<div> - bizSubject: 신청 제목 </div><br/>"
|
||||||
|
+ "<div> - subject: 신청 제목 (별칭) </div><br/>"
|
||||||
|
+ "<div> - writerName: 작성자 이름 </div><br/>";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.eactive.apim.portal.portalorg.entity;
|
package com.eactive.apim.portal.portalorg.entity;
|
||||||
|
|
||||||
import com.eactive.apim.portal.common.entity.Auditable;
|
import com.eactive.apim.portal.common.entity.Auditable;
|
||||||
|
import com.eactive.apim.portal.common.util.PhoneNumberUtil;
|
||||||
import com.eactive.apim.portal.portalorg.entity.PortalOrgEnums.ApprovalStatus;
|
import com.eactive.apim.portal.portalorg.entity.PortalOrgEnums.ApprovalStatus;
|
||||||
import com.eactive.apim.portal.portalorg.entity.PortalOrgEnums.OrgStatus;
|
import com.eactive.apim.portal.portalorg.entity.PortalOrgEnums.OrgStatus;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -95,4 +96,30 @@ public class PortalOrg extends Auditable implements Serializable, com.eactive.ea
|
|||||||
@Column(name = "reverse_proxy_path", length = 255)
|
@Column(name = "reverse_proxy_path", length = 255)
|
||||||
@Comment("리버스 프록시 경로")
|
@Comment("리버스 프록시 경로")
|
||||||
private String reverseProxyPath;
|
private String reverseProxyPath;
|
||||||
|
|
||||||
|
/** 저장 시 전화번호를 하이픈 구분 정규형으로 통일 */
|
||||||
|
@PrePersist
|
||||||
|
@PreUpdate
|
||||||
|
private void normalizePhones() {
|
||||||
|
this.orgPhoneNumber = PhoneNumberUtil.normalize(this.orgPhoneNumber);
|
||||||
|
this.scPhoneNumber = PhoneNumberUtil.normalize(this.scPhoneNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 법인 반려/삭제(탈퇴) 시 사업자등록번호·법인등록번호 등 민감/개인정보 필드를 제거한다.
|
||||||
|
* orgName·orgStatus·approvalStatus 등 상태값은 호출 측에서 별도 설정한다.
|
||||||
|
*/
|
||||||
|
public void clearSensitiveDataOnRemoval() {
|
||||||
|
this.corpRegNo = null;
|
||||||
|
this.compRegNo = null;
|
||||||
|
this.orgCode = null;
|
||||||
|
this.compRegFile = null;
|
||||||
|
this.ceoName = null;
|
||||||
|
this.orgAddr = null;
|
||||||
|
this.orgPhoneNumber = null;
|
||||||
|
this.scPhoneNumber = null;
|
||||||
|
this.orgSectors = null;
|
||||||
|
this.orgIndustryType = null;
|
||||||
|
this.serviceName = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-1
@@ -51,13 +51,24 @@ public class PortalPropertyService extends AbstractDataService<PortalPropertyGro
|
|||||||
Optional<PortalProperty> existingProperty = portalPropertyRepository.findById(propertyId);
|
Optional<PortalProperty> existingProperty = portalPropertyRepository.findById(propertyId);
|
||||||
|
|
||||||
if (existingProperty.isPresent()) {
|
if (existingProperty.isPresent()) {
|
||||||
return existingProperty.get().getPropertyValue();
|
PortalProperty property = existingProperty.get();
|
||||||
|
// 설명(property_desc)이 비어 있으면 코드가 넘긴 description 으로 채운다.
|
||||||
|
// (값이 있으면 관리자 편집분 보존 — 덮어쓰지 않음)
|
||||||
|
if (isBlank(property.getPropertyDesc()) && !isBlank(description)) {
|
||||||
|
property.setPropertyDesc(description);
|
||||||
|
portalPropertyRepository.save(property);
|
||||||
|
}
|
||||||
|
return property.getPropertyValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 프로퍼티가 없으면 기본값으로 생성
|
// 프로퍼티가 없으면 기본값으로 생성
|
||||||
return createDefaultProperty(groupName, propertyName, defaultValue, description);
|
return createDefaultProperty(groupName, propertyName, defaultValue, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isBlank(String s) {
|
||||||
|
return s == null || s.trim().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 기본 프로퍼티를 DB에 생성
|
* 기본 프로퍼티를 DB에 생성
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.eactive.apim.portal.portaluser.entity;
|
package com.eactive.apim.portal.portaluser.entity;
|
||||||
|
|
||||||
import com.eactive.apim.portal.common.entity.Auditable;
|
import com.eactive.apim.portal.common.entity.Auditable;
|
||||||
|
import com.eactive.apim.portal.common.util.PhoneNumberUtil;
|
||||||
import com.eactive.apim.portal.jpa.PersonalDataEncryptConverter;import com.eactive.apim.portal.portalorg.entity.PortalOrg;
|
import com.eactive.apim.portal.jpa.PersonalDataEncryptConverter;import com.eactive.apim.portal.portalorg.entity.PortalOrg;
|
||||||
import com.eactive.apim.portal.portaluser.entity.PortalUserEnums.ApprovalStatus;
|
import com.eactive.apim.portal.portaluser.entity.PortalUserEnums.ApprovalStatus;
|
||||||
import com.eactive.apim.portal.portaluser.entity.PortalUserEnums.RoleCode;
|
import com.eactive.apim.portal.portaluser.entity.PortalUserEnums.RoleCode;
|
||||||
@@ -98,4 +99,12 @@ public class PortalUser extends Auditable implements Serializable, com.eactive.e
|
|||||||
@Column(name = "withdrawal_reason", length=200)
|
@Column(name = "withdrawal_reason", length=200)
|
||||||
@Comment("회원탈퇴사유")
|
@Comment("회원탈퇴사유")
|
||||||
private String withdrawalReason;
|
private String withdrawalReason;
|
||||||
|
|
||||||
|
/** 저장 시 전화번호를 하이픈 구분 정규형으로 통일 */
|
||||||
|
@PrePersist
|
||||||
|
@PreUpdate
|
||||||
|
private void normalizePhones() {
|
||||||
|
this.phoneNumber = PhoneNumberUtil.normalize(this.phoneNumber);
|
||||||
|
this.mobileNumber = PhoneNumberUtil.normalize(this.mobileNumber);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ public class UserPasswordResetEvent implements MessageEventHandler {
|
|||||||
@Override
|
@Override
|
||||||
public MessageSendEvent createEvent(Object source, MessageRecipient recipient, Map<String, Object> params) {
|
public MessageSendEvent createEvent(Object source, MessageRecipient recipient, Map<String, Object> params) {
|
||||||
Map<String, String> requestParams = new HashMap<>();
|
Map<String, String> requestParams = new HashMap<>();
|
||||||
requestParams.put("tempPassword", (String) params.get("tempPassword"));
|
String tempPassword = (String) params.get("tempPassword");
|
||||||
|
requestParams.put("tempPassword", tempPassword);
|
||||||
|
// DB 템플릿 USER_PASSWORD_RESET SMS 변수(%TEMP_PASSWORD%)에 매핑
|
||||||
|
requestParams.put("TEMP_PASSWORD", tempPassword);
|
||||||
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -23,7 +23,10 @@ public class UserVerificationEmailEvent implements MessageEventHandler {
|
|||||||
@Override
|
@Override
|
||||||
public MessageSendEvent createEvent(Object source, MessageRecipient recipient, Map<String, Object> params) {
|
public MessageSendEvent createEvent(Object source, MessageRecipient recipient, Map<String, Object> params) {
|
||||||
Map<String, String> requestParams = new HashMap<>();
|
Map<String, String> requestParams = new HashMap<>();
|
||||||
requestParams.put("authNumber", (String) params.get("authNumber"));
|
String authNumber = (String) params.get("authNumber");
|
||||||
|
requestParams.put("authNumber", authNumber);
|
||||||
|
// DB 템플릿 USER_VERIFICATION_EMAIL 변수(%AUTH_NO%)에 매핑
|
||||||
|
requestParams.put("AUTH_NO", authNumber);
|
||||||
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -24,7 +24,10 @@ public class UserVerificationMobilePhoneEvent implements MessageEventHandler {
|
|||||||
@Override
|
@Override
|
||||||
public MessageSendEvent createEvent(Object source, MessageRecipient recipient, Map<String, Object> params) {
|
public MessageSendEvent createEvent(Object source, MessageRecipient recipient, Map<String, Object> params) {
|
||||||
Map<String, String> requestParams = new HashMap<>();
|
Map<String, String> requestParams = new HashMap<>();
|
||||||
requestParams.put("authNumber", (String) params.get("authNumber"));
|
String authNumber = (String) params.get("authNumber");
|
||||||
|
requestParams.put("authNumber", authNumber);
|
||||||
|
// DB 템플릿 USER_VERIFICATION_MOBILEPHONE SMS 변수(%AUTH_CODE%)에 매핑
|
||||||
|
requestParams.put("AUTH_CODE", authNumber);
|
||||||
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
return new MessageSendEvent(source, KEY, recipient, requestParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,83 +10,47 @@ public enum MessageCode {
|
|||||||
|
|
||||||
|
|
||||||
// 사용자 이벤트 영역
|
// 사용자 이벤트 영역
|
||||||
USER_VERIFICATION_EMAIL("이메일 주소 인증", "FM_APIM001", Channels.EMAIL),
|
USER_VERIFICATION_EMAIL("이메일 주소 인증", null, Channels.EMAIL),
|
||||||
USER_VERIFICATION_MOBILEPHONE("휴대폰 번호 인증", "S55_ICT_0006", Channels.KAKAO_ALIMTALK),
|
USER_VERIFICATION_MOBILEPHONE("휴대폰 번호 인증", null, Channels.KAKAO_ALIMTALK),
|
||||||
|
|
||||||
USER_PASSWORD_RESET("비밀번호 재설정", "FM_APIM002", Channels.EMAIL),
|
USER_PASSWORD_RESET("비밀번호 재설정", null, Channels.KAKAO_ALIMTALK),
|
||||||
USER_PASSWORD_CHANGED("사용자 비밀번호 변경", "FM_APIM003", Channels.EMAIL),
|
USER_PASSWORD_CHANGED("사용자 비밀번호 변경", null, Channels.KAKAO_ALIMTALK),
|
||||||
|
|
||||||
USER_ACCOUNT_LOCKED("계정 잠금 알림", "FM_APIM004", Channels.EMAIL),
|
USER_ACCOUNT_LOCKED("계정 잠금 알림", null, Channels.KAKAO_ALIMTALK),
|
||||||
|
|
||||||
// 법인관리자 이벤트 영역
|
// 법인관리자 이벤트 영역
|
||||||
USER_INVITATION("법인 이용자 이메일 초대", "FM_APIM005", Channels.EMAIL),
|
USER_INVITATION("법인 이용자 이메일 초대", null, Channels.KAKAO_ALIMTALK),
|
||||||
USER_INVITATION_CANCELED("법인 이용자 이메일 초대 취소", "FM_APIM006", Channels.EMAIL),
|
USER_INVITATION_CANCELED("법인 이용자 이메일 초대 취소", null, Channels.KAKAO_ALIMTALK),
|
||||||
|
|
||||||
MANAGER_WITH_ORG_REGISTER_APPROVED("법인관리자 및 법인 등록 승인", "FM_APIM007", Channels.EMAIL),
|
MANAGER_WITH_ORG_REGISTER_APPROVED("법인관리자 및 법인 등록 승인", null, Channels.KAKAO_ALIMTALK),
|
||||||
MANAGER_WITH_ORG_REGISTER_REJECTED("법인관리자 및 법인 등록 거절", "FM_APIM008", Channels.EMAIL),
|
MANAGER_WITH_ORG_REGISTER_REJECTED("법인관리자 및 법인 등록 거절", null, Channels.KAKAO_ALIMTALK),
|
||||||
|
|
||||||
// 관리자 영역
|
// 관리자 영역
|
||||||
APP_REGISTER_APPROVED("앱 등록 승인", "FM_APIM009", Channels.EMAIL),
|
APP_APPROVE("앱 사용 승인", null, Channels.KAKAO_ALIMTALK),
|
||||||
APP_REGISTER_REJECTED("앱 등록 거절", "FM_APIM010", Channels.EMAIL),
|
APP_REJECTED("앱 사용 거절", null, Channels.KAKAO_ALIMTALK),
|
||||||
|
|
||||||
// Q&A 등록/댓글 등록 알림 (DJBank 커스텀 — portal-admin 수신)
|
// Q&A 등록/댓글 등록 알림 (DJBank 커스텀 — portal-admin 수신)
|
||||||
INQUIRY_CREATED("Q&A 등록 알림", null, Channels.NONE),
|
INQUIRY_CREATED("Q&A 등록 알림", null, Channels.SWING),
|
||||||
INQUIRY_COMMENT_CREATED("Q&A 댓글 등록 알림", null, Channels.NONE),
|
INQUIRY_COMMENT_CREATED("Q&A 댓글 등록 알림", null, Channels.SWING),
|
||||||
|
PARTNERSHIP_CREATED("개선요청/제휴 게시물 등록 알림", null, Channels.SWING),
|
||||||
|
|
||||||
// 제주은행
|
// 제주은행
|
||||||
API_STATUS_CHANGED("API 상태 변화", "FM_APIM011", Channels.SWING),
|
API_STATUS_CHANGED("API 상태 변화", null, Channels.SWING),
|
||||||
INFLOW_TOKEN_FAILED("유량제어 토큰 획득 실패", "FM_APIM012", Channels.SWING),
|
INFLOW_TOKEN_FAILED("유량제어 토큰 획득 실패", null, Channels.SWING),
|
||||||
ADMIN_VERIFICATION_MOBILEPHONE("관리자포탈 휴대폰 번호 인증", "FM_APIM013", Channels.KAKAO_ALIMTALK),
|
ADMIN_VERIFICATION_MOBILEPHONE("관리자포탈 휴대폰 번호 인증", null, Channels.KAKAO_ALIMTALK),
|
||||||
|
|
||||||
|
// 레거시/미사용 — Event 핸들러 클래스 호환을 위해 유지 (실제 발송 없음)
|
||||||
// 미 사용, 미 분류
|
|
||||||
@Deprecated
|
|
||||||
API_APPROVED("API 승인 알림", null, Channels.NONE),
|
API_APPROVED("API 승인 알림", null, Channels.NONE),
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
API_REJECTED("API 거절 알림", null, Channels.NONE),
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
APP_REGISTER("앱 등록 완료", null, Channels.NONE),
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
USER_MANAGER_ASSIGNED("관리자 권한 부여", null, Channels.NONE),
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
REQUEST_AUTH_NUMBER("인증번호 요청", null, Channels.NONE),
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
USER_WITHDRAWAL_APPROVED("계정 비활성화", null, Channels.NONE),
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
USER_ACTIVATION("사용자 활성화 완료", null, Channels.NONE), // 이게 왜...이메일 인증인건데........
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
APP_REGISTER_REQUEST("앱 등록 요청", null, Channels.NONE),
|
APP_REGISTER_REQUEST("앱 등록 요청", null, Channels.NONE),
|
||||||
|
APP_REGISTER_REJECTED("앱 등록 거절", null, Channels.NONE),
|
||||||
@Deprecated
|
|
||||||
UNKNOWN_ERROR("알수 없는 에러 발생", null, Channels.NONE),
|
UNKNOWN_ERROR("알수 없는 에러 발생", null, Channels.NONE),
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
PASSWORD_RESET_COMPLETE("비밀번호 변경 완료", null, Channels.NONE),
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
REQUEST_PASSWORD_RESET("비밀번호 초기화 요청", null, Channels.NONE),
|
|
||||||
|
|
||||||
@Deprecated // 정확한 용도 모름
|
|
||||||
USER_REGISTRATION_APPROVED("사용자 등록 승인 완료", null, Channels.NONE),
|
|
||||||
|
|
||||||
@Deprecated // 정확한 용도 모름
|
|
||||||
USER_REGISTRATION_DENIED("사용자 등록 거절", null, Channels.NONE),
|
|
||||||
|
|
||||||
|
|
||||||
@Deprecated // 정확한 용도 모름
|
|
||||||
USER_REGISTRATION_REQUEST_ADMIN("사용자 등록 승인 요청", null, Channels.NONE),
|
USER_REGISTRATION_REQUEST_ADMIN("사용자 등록 승인 요청", null, Channels.NONE),
|
||||||
|
USER_REGISTRATION_DENIED("사용자 등록 거절", null, Channels.NONE),
|
||||||
@Deprecated // 정확한 용도 모름
|
|
||||||
USER_REGISTRATION_REQUEST_USER("사용자 등록 요청 완료", null, Channels.NONE),
|
USER_REGISTRATION_REQUEST_USER("사용자 등록 요청 완료", null, Channels.NONE),
|
||||||
|
REQUEST_PASSWORD_RESET("비밀번호 초기화 요청", null, Channels.NONE),
|
||||||
@Deprecated
|
USER_MANAGER_ASSIGNED("관리자 권한 부여", null, Channels.NONE),
|
||||||
|
USER_REGISTRATION_APPROVED("사용자 등록 승인 완료", null, Channels.NONE),
|
||||||
|
PASSWORD_RESET_COMPLETE("비밀번호 변경 완료", null, Channels.NONE),
|
||||||
INQUIRY_RESPONSE("QnA 답변 작성", null, Channels.NONE)
|
INQUIRY_RESPONSE("QnA 답변 작성", null, Channels.NONE)
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -96,7 +60,8 @@ public enum MessageCode {
|
|||||||
@Getter
|
@Getter
|
||||||
private final String serviceId;
|
private final String serviceId;
|
||||||
@Getter
|
@Getter
|
||||||
private final int channels;
|
@Deprecated // 삭제 예정
|
||||||
|
private int channels = 0;
|
||||||
|
|
||||||
|
|
||||||
public static Optional<MessageCode> findServiceId(String code) {
|
public static Optional<MessageCode> findServiceId(String code) {
|
||||||
@@ -108,6 +73,11 @@ public enum MessageCode {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageCode(String description, String serviceId) {
|
||||||
|
this.description = description;
|
||||||
|
this.serviceId = serviceId;
|
||||||
|
// this.channels = channel.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
MessageCode(String description, String serviceId, Channels channel) {
|
MessageCode(String description, String serviceId, Channels channel) {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
|
|||||||
@@ -59,8 +59,11 @@ public class MessageRequest implements Serializable {
|
|||||||
@Convert(converter = PersonalDataEncryptConverter.class)
|
@Convert(converter = PersonalDataEncryptConverter.class)
|
||||||
private String phone;
|
private String phone;
|
||||||
|
|
||||||
|
@Column(name = "user_id")
|
||||||
|
private String userId;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.EAGER)
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
@JoinColumn(name = "user_id", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
@JoinColumn(name = "user_id", insertable = false, updatable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
||||||
@NotFound(action = NotFoundAction.IGNORE)
|
@NotFound(action = NotFoundAction.IGNORE)
|
||||||
@Comment("발송 대상 사용자")
|
@Comment("발송 대상 사용자")
|
||||||
private PortalUser user;
|
private PortalUser user;
|
||||||
@@ -80,5 +83,4 @@ public class MessageRequest implements Serializable {
|
|||||||
|
|
||||||
@Column(name = "service_id")
|
@Column(name = "service_id")
|
||||||
private String serviceId;
|
private String serviceId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,12 @@ public class MessageSendService {
|
|||||||
smsRequest.setPhone(user.getPhone());
|
smsRequest.setPhone(user.getPhone());
|
||||||
smsRequest.setEaiInterfaceId(smsEaiInterfaceId);
|
smsRequest.setEaiInterfaceId(smsEaiInterfaceId);
|
||||||
smsRequest.setServiceId(portalProperties.get("ums.sms.tx_id"));
|
smsRequest.setServiceId(portalProperties.get("ums.sms.tx_id"));
|
||||||
|
smsRequest.setUserId(user.getUserId());
|
||||||
|
if ("ADMIN_VERIFICATION_MOBILEPHONE".equals(template.getMessageCode().toUpperCase())) {
|
||||||
|
smsRequest.setMessageType("KAKAO");
|
||||||
|
} else {
|
||||||
smsRequest.setMessageType("SMS");
|
smsRequest.setMessageType("SMS");
|
||||||
|
}
|
||||||
messageRequestRepository.save(smsRequest);
|
messageRequestRepository.save(smsRequest);
|
||||||
logger.debug(smsRequest.toString());
|
logger.debug(smsRequest.toString());
|
||||||
}
|
}
|
||||||
@@ -107,6 +112,7 @@ public class MessageSendService {
|
|||||||
emailRequest.setEaiInterfaceId(mailEaiInterfaceId);
|
emailRequest.setEaiInterfaceId(mailEaiInterfaceId);
|
||||||
emailRequest.setServiceId(portalProperties.get("ums.email.tx_id"));
|
emailRequest.setServiceId(portalProperties.get("ums.email.tx_id"));
|
||||||
emailRequest.setMessageType("EMAIL");
|
emailRequest.setMessageType("EMAIL");
|
||||||
|
emailRequest.setUserId(user.getUserId());
|
||||||
messageRequestRepository.save(emailRequest);
|
messageRequestRepository.save(emailRequest);
|
||||||
logger.debug(emailRequest.toString());
|
logger.debug(emailRequest.toString());
|
||||||
}
|
}
|
||||||
@@ -124,16 +130,21 @@ public class MessageSendService {
|
|||||||
messengerRequest.setEaiInterfaceId(swingEaiInterfaceId);
|
messengerRequest.setEaiInterfaceId(swingEaiInterfaceId);
|
||||||
messengerRequest.setServiceId(portalProperties.get("ums.messenger.tx_id"));
|
messengerRequest.setServiceId(portalProperties.get("ums.messenger.tx_id"));
|
||||||
messengerRequest.setMessageType("MESSENGER");
|
messengerRequest.setMessageType("MESSENGER");
|
||||||
|
messengerRequest.setUserId(user.getUserId());
|
||||||
messageRequestRepository.save(messengerRequest);
|
messageRequestRepository.save(messengerRequest);
|
||||||
logger.debug(messengerRequest.toString());
|
logger.debug(messengerRequest.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateMessageParams(MessageRecipient user, Map<String, String> messageParams) {
|
private void updateMessageParams(MessageRecipient user, Map<String, String> messageParams) {
|
||||||
|
// 공통 자동주입. 대문자 별칭(USER_ID/USER_NAME)은 DB 템플릿 변수 표기와 맞춘다.
|
||||||
|
// putIfAbsent 이므로 개별 이벤트(createEvent)가 먼저 넣은 값이 있으면 그대로 둔다(오버라이드).
|
||||||
messageParams.put("userId", user.getUserId());
|
messageParams.put("userId", user.getUserId());
|
||||||
|
messageParams.putIfAbsent("USER_ID", user.getUserId());
|
||||||
|
|
||||||
if (StringUtils.hasText(user.getUsername())) {
|
if (StringUtils.hasText(user.getUsername())) {
|
||||||
messageParams.put("userName", user.getUsername());
|
messageParams.put("userName", user.getUsername());
|
||||||
|
messageParams.putIfAbsent("USER_NAME", user.getUsername());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.eactive.apim.portal.user.entity;
|
package com.eactive.apim.portal.user.entity;
|
||||||
|
|
||||||
|
import com.eactive.apim.portal.common.util.PhoneNumberUtil;
|
||||||
import com.eactive.apim.portal.jpa.PersonalDataEncryptConverter;
|
import com.eactive.apim.portal.jpa.PersonalDataEncryptConverter;
|
||||||
import com.eactive.eai.data.converter.LocalDateTimeToStringConverter14;
|
import com.eactive.eai.data.converter.LocalDateTimeToStringConverter14;
|
||||||
import com.eactive.eai.data.converter.StringTrimConverter;
|
import com.eactive.eai.data.converter.StringTrimConverter;
|
||||||
@@ -139,4 +140,12 @@ public class UserInfo extends AbstractEntity<String> implements Serializable {
|
|||||||
public @NonNull String getId() {
|
public @NonNull String getId() {
|
||||||
return userid;
|
return userid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 저장 시 전화번호를 하이픈 구분 정규형으로 통일 */
|
||||||
|
@PrePersist
|
||||||
|
@PreUpdate
|
||||||
|
private void normalizePhones() {
|
||||||
|
this.cphnno = PhoneNumberUtil.normalize(this.cphnno);
|
||||||
|
this.ofctelno = PhoneNumberUtil.normalize(this.ofctelno);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user