diff --git a/WebContent/jsp/common/acl/audit/auditLogManDetail.jsp b/WebContent/jsp/common/acl/audit/auditLogManDetail.jsp
index 7a11015..159ce8f 100644
--- a/WebContent/jsp/common/acl/audit/auditLogManDetail.jsp
+++ b/WebContent/jsp/common/acl/audit/auditLogManDetail.jsp
@@ -54,10 +54,18 @@ function detail(key){
$('#systemCode').val(data.systemCode);
$('#logTypeText').val(data.logTypeText);
$('#remoteAddress').val(data.remoteAddress);
- $('#logMsg').val(data.message);
$('#logSubMsg').val(data.command);
$('#parameters').val(data.parameters);
+ // 사유(message)는 값이 있을 때만 노출
+ if (data.message) {
+ $('#logMsg').val(data.message);
+ $('#messageRow').show();
+ } else {
+ $('#logMsg').val('');
+ $('#messageRow').hide();
+ }
+
},
error:function(e){
alert(e.responseText);
@@ -121,6 +129,9 @@ $(document).ready(function() {
+
+
<%--법인정보관리--%>
diff --git a/WebContent/jsp/onl/apim/portalorg/portalOrgManDetail.jsp b/WebContent/jsp/onl/apim/portalorg/portalOrgManDetail.jsp
index 9af8953..b4ccc1d 100644
--- a/WebContent/jsp/onl/apim/portalorg/portalOrgManDetail.jsp
+++ b/WebContent/jsp/onl/apim/portalorg/portalOrgManDetail.jsp
@@ -138,7 +138,11 @@
$("#btn_delete").hide();
}
- $("#approvalStatus").val(portalOrgData.approvalStatus);
+ $("select[name=approvalStatus]").val(portalOrgData.approvalStatus);
+ // 승인상태는 읽기전용(수정 불가) - 값은 그대로 제출되도록 disabled 대신 잠금 처리
+ $("select[name=approvalStatus]")
+ .css({'pointer-events':'none', 'background-color':'#eee'})
+ .attr('tabindex', '-1');
$("#compRegNo").val(formatCompanyRegNo(portalOrgData.compRegNo));
$("#corpRegNo").val(formatCorpRegNo(portalOrgData.corpRegNo));
$("#createdDate").inputmask("9999-99-99 99:99:99", {'autoUnmask': true});
@@ -480,8 +484,7 @@
}
}
- if (confirm("<%= localeMessage.getString("common.checkSave")%>") !== true)
- return;
+ // 저장 확인/사유 입력은 유효성 검사 및 FormData 구성 후 처리 (하단 submit 분기)
// FormData 생성 전에 분리된 전화번호 필드 제거
$("#scPhonePrefix, #scPhoneMiddle, #scPhoneLast, #orgPhonePrefix, #orgPhoneMiddle, #orgPhoneLast").removeAttr('name');
@@ -516,23 +519,47 @@
}
- // cmd 파라미터 추가
- formData.append("cmd", isDetail ? "UPDATE" : "INSERT");
-
- $.ajax({
- type : "POST",
- url:url,
- data: formData,
- processData: false,
- contentType: false,
- success:function(json){
- alert("<%= localeMessage.getString("common.saveMsg") %>");
- goNav(returnUrl);
- },
- error:function(e){
- alert(e.responseText);
+ // cmd 및 사유(auditReason) 첨부 후 전송
+ function submitOrg(cmd, auditReason) {
+ formData.append("cmd", cmd);
+ // 감사로그(AUDIT_LOG) 발화를 위한 systemCode. 법인/가입자 리포지토리는 고정 EMS 스키마라 스키마 전환 영향 없음
+ formData.append("serviceType", "APIGW");
+ if (auditReason) {
+ formData.append("auditReason", auditReason);
}
- });
+
+ $.ajax({
+ type : "POST",
+ url:url,
+ data: formData,
+ processData: false,
+ contentType: false,
+ success:function(json){
+ alert("<%= localeMessage.getString("common.saveMsg") %>");
+ goNav(returnUrl);
+ },
+ error:function(e){
+ alert(e.responseText);
+ }
+ });
+ }
+
+ if (isDetail) {
+ // 수정: 상태를 REMOVED로 바꾼 경우 삭제(cmd=DELETE)로 감사 기록 + 익명화
+ var targetCmd = ($("#orgStatus").val() === 'REMOVED') ? "DELETE" : "UPDATE";
+ var isRemove = (targetCmd === "DELETE");
+ showReasonPrompt(
+ isRemove ? "해당 법인을 삭제(탈퇴) 처리합니다. 사유를 입력해 주세요." : "법인 정보를 수정합니다. 사유를 입력해 주세요.",
+ {
+ title: isRemove ? "삭제 사유" : "수정 사유",
+ onConfirm: function(reason) { submitOrg(targetCmd, reason); }
+ }
+ );
+ } else {
+ // 신규 등록: 사유 불필요
+ if (confirm("<%= localeMessage.getString("common.checkSave")%>") !== true) return;
+ submitOrg("INSERT", null);
+ }
});
$("#btn_previous").click(function() {
@@ -541,25 +568,28 @@
$("#btn_delete").click(function(){
- if(confirm("<%= localeMessage.getString("common.confirmMsg")%>")){
- var postData = $('#ajaxForm').serializeArray();
- postData.push({name: "cmd" , value:"DELETE"});
+ showReasonPrompt("해당 법인을 삭제 처리합니다. 사유를 입력해 주세요.", {
+ title: "삭제 사유",
+ onConfirm: function(reason) {
+ var postData = $('#ajaxForm').serializeArray();
+ postData.push({name: "cmd" , value:"DELETE"});
+ postData.push({name: "serviceType", value: "APIGW"});
+ postData.push({name: "auditReason", value: reason});
- $.ajax({
- type : "POST",
- url:url,
- data:postData,
- success:function(args){
- alert("<%= localeMessage.getString("common.deleteMsg") %>");
- goNav(returnUrl);
- },
- error:function(e){
- alert(e.responseText);
- }
- });
- }else{
- return false;
- }
+ $.ajax({
+ type : "POST",
+ url:url,
+ data:postData,
+ success:function(args){
+ alert("<%= localeMessage.getString("common.deleteMsg") %>");
+ goNav(returnUrl);
+ },
+ error:function(e){
+ alert(e.responseText);
+ }
+ });
+ }
+ });
});
diff --git a/WebContent/jsp/onl/apim/portaluser/portalUserMan.jsp b/WebContent/jsp/onl/apim/portaluser/portalUserMan.jsp
index 6d828a3..3901b32 100644
--- a/WebContent/jsp/onl/apim/portaluser/portalUserMan.jsp
+++ b/WebContent/jsp/onl/apim/portaluser/portalUserMan.jsp
@@ -347,9 +347,11 @@
+
+
diff --git a/WebContent/jsp/onl/apim/portaluser/portalUserManDetail.jsp b/WebContent/jsp/onl/apim/portaluser/portalUserManDetail.jsp
index 7fc06fc..62027e4 100644
--- a/WebContent/jsp/onl/apim/portaluser/portalUserManDetail.jsp
+++ b/WebContent/jsp/onl/apim/portaluser/portalUserManDetail.jsp
@@ -165,6 +165,10 @@
$("#userStatus").val(data.userStatus);
$("#roleCode").val(data.roleCode).trigger('change');
$("#approvalStatus").val(data.approvalStatus);
+ // 승인상태는 읽기전용(수정 불가) - 값은 그대로 제출되도록 disabled 대신 잠금 처리
+ $("#approvalStatus")
+ .css({'pointer-events':'none', 'background-color':'#eee'})
+ .attr('tabindex', '-1');
// 탈퇴 상태 처리
if (originalUserStatus === STATUS.REMOVED) {
@@ -488,29 +492,49 @@
formData.push({name: 'mobileNumber', value: mobileNumber});
}
- formData.push({
- name: 'cmd',
- value: isDetail ? "UPDATE" : "INSERT"
- });
-
- if (!confirm("<%= localeMessage.getString("common.checkSave")%>")) return;
-
- $.ajax({
- type: "POST",
- url: url,
- data: formData,
- success: function (json) {
- if (json.status === "fail") {
- alert(json.errorMsg || "저장에 실패했습니다.");
- return;
- }
- alert("<%= localeMessage.getString("common.saveMsg") %>");
- goNav(returnUrl);
- },
- error: function (e) {
- alert(e.responseText);
+ // cmd 및 사유(auditReason) 첨부 후 전송
+ function submitUser(cmd, auditReason) {
+ formData.push({ name: 'cmd', value: cmd });
+ // 감사로그(AUDIT_LOG) 발화를 위한 systemCode. 가입자 리포지토리는 고정 EMS 스키마라 스키마 전환 영향 없음
+ formData.push({ name: 'serviceType', value: 'APIGW' });
+ if (auditReason) {
+ formData.push({ name: 'auditReason', value: auditReason });
}
- });
+
+ $.ajax({
+ type: "POST",
+ url: url,
+ data: formData,
+ success: function (json) {
+ if (json.status === "fail") {
+ alert(json.errorMsg || "저장에 실패했습니다.");
+ return;
+ }
+ alert("<%= localeMessage.getString("common.saveMsg") %>");
+ goNav(returnUrl);
+ },
+ error: function (e) {
+ alert(e.responseText);
+ }
+ });
+ }
+
+ if (isDetail) {
+ // 수정: 상태를 REMOVED로 바꾼 경우 삭제(cmd=DELETE)로 감사 기록 + 익명화
+ var targetCmd = ($("#userStatus").val() === 'REMOVED') ? "DELETE" : "UPDATE";
+ var isRemove = (targetCmd === "DELETE");
+ showReasonPrompt(
+ isRemove ? "해당 가입자를 삭제(탈퇴) 처리합니다. 사유를 입력해 주세요." : "가입자 정보를 수정합니다. 사유를 입력해 주세요.",
+ {
+ title: isRemove ? "삭제 사유" : "수정 사유",
+ onConfirm: function(reason) { submitUser(targetCmd, reason); }
+ }
+ );
+ } else {
+ // 신규 등록: 사유 불필요
+ if (!confirm("<%= localeMessage.getString("common.checkSave")%>")) return;
+ submitUser("INSERT", null);
+ }
});
$("#btn_previous").click(function () {
@@ -518,21 +542,26 @@
});
$("#btn_delete").click(function () {
- if (!confirm("<%= localeMessage.getString("common.confirmMsg")%>")) return;
-
- $.ajax({
- type: "POST",
- url: url,
- data: {
- cmd: "DELETE",
- id: $('input[name=id]').val()
- },
- success: function () {
- alert("<%= localeMessage.getString("common.deleteMsg") %>");
- goNav(returnUrl);
- },
- error: function (e) {
- alert(e.responseText);
+ showReasonPrompt("해당 가입자를 삭제 처리합니다. 사유를 입력해 주세요.", {
+ title: "삭제 사유",
+ onConfirm: function(reason) {
+ $.ajax({
+ type: "POST",
+ url: url,
+ data: {
+ cmd: "DELETE",
+ id: $('input[name=id]').val(),
+ serviceType: "APIGW",
+ auditReason: reason
+ },
+ success: function () {
+ alert("<%= localeMessage.getString("common.deleteMsg") %>");
+ goNav(returnUrl);
+ },
+ error: function (e) {
+ alert(e.responseText);
+ }
+ });
}
});
});
diff --git a/src/main/java/com/eactive/eai/rms/common/acl/audit/adapter/in/web/AuditLogInterceptor.java b/src/main/java/com/eactive/eai/rms/common/acl/audit/adapter/in/web/AuditLogInterceptor.java
index 2fe1393..d4f0814 100644
--- a/src/main/java/com/eactive/eai/rms/common/acl/audit/adapter/in/web/AuditLogInterceptor.java
+++ b/src/main/java/com/eactive/eai/rms/common/acl/audit/adapter/in/web/AuditLogInterceptor.java
@@ -41,10 +41,12 @@ public class AuditLogInterceptor implements HandlerInterceptor {
if (isAuditableUsecase.isAuditable(userId, command, logType, systemCode)) {
String parameters = getParametersAsString(request);
+ String message = request.getParameter("auditReason");
log
.debug("audit log save : logType={}, cmd={}, user={}, parameters={}", logType, command,
userId, parameters);
- saveAuditLogUseCase.log(systemCode, logType, command, remoteAddress, userId, parameters);
+ saveAuditLogUseCase
+ .log(systemCode, logType, command, remoteAddress, userId, parameters, message);
}
}
diff --git a/src/main/java/com/eactive/eai/rms/common/acl/audit/domain/AuditLog.java b/src/main/java/com/eactive/eai/rms/common/acl/audit/domain/AuditLog.java
index d000a9e..8631923 100644
--- a/src/main/java/com/eactive/eai/rms/common/acl/audit/domain/AuditLog.java
+++ b/src/main/java/com/eactive/eai/rms/common/acl/audit/domain/AuditLog.java
@@ -23,6 +23,8 @@ public class AuditLog {
private String logTypeText;
+ private String message;
+
private String parameters;
private LocalDateTime lastModifiedDate;
diff --git a/src/main/java/com/eactive/eai/rms/common/acl/audit/port/in/SaveAuditLogUseCase.java b/src/main/java/com/eactive/eai/rms/common/acl/audit/port/in/SaveAuditLogUseCase.java
index 00edc4f..0bcc316 100644
--- a/src/main/java/com/eactive/eai/rms/common/acl/audit/port/in/SaveAuditLogUseCase.java
+++ b/src/main/java/com/eactive/eai/rms/common/acl/audit/port/in/SaveAuditLogUseCase.java
@@ -3,6 +3,6 @@ package com.eactive.eai.rms.common.acl.audit.port.in;
public interface SaveAuditLogUseCase {
public void log(String systemCode, String logType, String command, String remoteAddress, String userId,
- String parameters);
+ String parameters, String message);
}
diff --git a/src/main/java/com/eactive/eai/rms/common/acl/audit/service/AuditLogService.java b/src/main/java/com/eactive/eai/rms/common/acl/audit/service/AuditLogService.java
index a5f959c..5ab5848 100644
--- a/src/main/java/com/eactive/eai/rms/common/acl/audit/service/AuditLogService.java
+++ b/src/main/java/com/eactive/eai/rms/common/acl/audit/service/AuditLogService.java
@@ -59,15 +59,16 @@ class AuditLogService
@Override
public void log(String systemCode, String logType, String command, String remoteAddress, String userId,
- String parameters) {
+ String parameters, String message) {
AuditLog auditLog = new AuditLog(systemCode, logType, command, userId, remoteAddress);
String auditPointKey = AuditPoint.generateKey(logType, systemCode, command);
AuditPoint auditPoint = auditPoints.get(auditPointKey);
-
+
auditLog.setLogTypeText(auditPoint.getLogTypeText());
auditLog.setLastModifiedDate(LocalDateTime.now());
auditLog.setParameters(parameters);
+ auditLog.setMessage(message);
saveAuditLogPort.save(auditLog);
}
diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/portalorg/PortalOrgManController.java b/src/main/java/com/eactive/eai/rms/onl/apim/portalorg/PortalOrgManController.java
index 4e0531c..ebc3b37 100644
--- a/src/main/java/com/eactive/eai/rms/onl/apim/portalorg/PortalOrgManController.java
+++ b/src/main/java/com/eactive/eai/rms/onl/apim/portalorg/PortalOrgManController.java
@@ -23,6 +23,7 @@ import org.springframework.data.web.SortDefault;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -37,8 +38,8 @@ public class PortalOrgManController extends BaseAnnotationController {
private final ComboService comboService;
@GetMapping(value = "/onl/apim/portalorg/portalOrgMan.view")
- public void view() {
- // view
+ public void view(Model model) {
+ model.addAttribute("hardDeleteEnabled", portalOrgManService.isHardDeleteEnabled());
}
@GetMapping(value = "/onl/apim/portalorg/portalOrgMan.view", params = "cmd=DETAIL")
diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/portalorg/PortalOrgManService.java b/src/main/java/com/eactive/eai/rms/onl/apim/portalorg/PortalOrgManService.java
index 36d1332..cda4329 100644
--- a/src/main/java/com/eactive/eai/rms/onl/apim/portalorg/PortalOrgManService.java
+++ b/src/main/java/com/eactive/eai/rms/onl/apim/portalorg/PortalOrgManService.java
@@ -18,6 +18,7 @@ import com.eactive.eai.rms.onl.apim.masking.MaskingUtils;
import com.eactive.eai.rms.onl.apim.portaluser.PortalUserCorpManagerUI;
import com.eactive.eai.rms.onl.apim.portaluser.PortalUserCorpManagerUIMapper;
import com.eactive.eai.rms.onl.common.exception.BizException;
+import com.eactive.apim.portal.portalproperty.service.PortalPropertyService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -44,15 +45,27 @@ import java.util.Optional;
@Slf4j
public class PortalOrgManService extends BaseService {
+ /** PortalProperty 그룹명 */
+ private static final String PORTAL_PROPERTY_GROUP = "Portal";
+ /** 법인 완전삭제(hard delete) 허용 프로퍼티 키 (true:허용, 기본 false) */
+ private static final String HARD_DELETE_FLAG_KEY = "org.hard-delete.enabled";
+
private final PortalOrgService portalOrgService;
private final PortalOrgUIMapper portalOrgUIMapper;
private final PortalUserService portalUserService;
private final PortalUserCorpManagerUIMapper portalUserCorpManagerUIMapper;
private final FileService fileService;
+ private final PortalPropertyService portalPropertyService;
@PersistenceContext(unitName = "entityManagerFactoryForEMS")
private EntityManager entityManager;
+ /** 법인 목록 '선택 삭제'(완전삭제) 버튼 노출 여부 */
+ public boolean isHardDeleteEnabled() {
+ Map
properties = portalPropertyService.getPortalPropertiesAsMap(PORTAL_PROPERTY_GROUP);
+ return Boolean.parseBoolean(properties.getOrDefault(HARD_DELETE_FLAG_KEY, "false"));
+ }
+
public Page selectList(Pageable pageable, PortalOrgUISearch portalOrgUISearch) {
Page portalOrg = portalOrgService.findAll(pageable, portalOrgUISearch);
return portalOrg.map(entity -> convertToUIWithMaskOption(entity, true));
diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/portaluser/PortalUserManController.java b/src/main/java/com/eactive/eai/rms/onl/apim/portaluser/PortalUserManController.java
index 0130117..0388ba1 100644
--- a/src/main/java/com/eactive/eai/rms/onl/apim/portaluser/PortalUserManController.java
+++ b/src/main/java/com/eactive/eai/rms/onl/apim/portaluser/PortalUserManController.java
@@ -13,6 +13,7 @@ import org.springframework.data.domain.Sort;
import org.springframework.data.web.SortDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@@ -32,8 +33,8 @@ public class PortalUserManController extends BaseAnnotationController {
private final ComboService comboService;
@GetMapping(value = "/onl/apim/portaluser/portalUserMan.view")
- public void view() {
- // view
+ public void view(Model model) {
+ model.addAttribute("hardDeleteEnabled", portalUserManService.isHardDeleteEnabled());
}
@GetMapping(value = "/onl/apim/portaluser/portalUserMan.view", params = "cmd=DETAIL")
diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/portaluser/PortalUserManService.java b/src/main/java/com/eactive/eai/rms/onl/apim/portaluser/PortalUserManService.java
index 17212af..4a749f6 100644
--- a/src/main/java/com/eactive/eai/rms/onl/apim/portaluser/PortalUserManService.java
+++ b/src/main/java/com/eactive/eai/rms/onl/apim/portaluser/PortalUserManService.java
@@ -46,6 +46,8 @@ public class PortalUserManService extends BaseService {
private static final String PORTAL_PROPERTY_GROUP = "Portal";
/** 사용자 별 휴대폰 번호 중복 허용 프로퍼티 키 (true:허용, false:허용안함, 기본 false) */
private static final String PROP_MOBILE_DUPLICATE_ALLOW = "user.mobile.duplicate.allow";
+ /** 가입자 완전삭제(hard delete) 허용 프로퍼티 키 (true:허용, 기본 false) */
+ private static final String HARD_DELETE_FLAG_KEY = "user.hard-delete.enabled";
private final PortalUserService portalUserService;
private final PortalUserUIMapper portalUserUIMapper;
@@ -60,6 +62,11 @@ public class PortalUserManService extends BaseService {
private final PortalInquiryService portalInquiryService;
private final PortalPropertyService portalPropertyService;
+ /** 가입자 목록 '선택 삭제'(완전삭제) 버튼 노출 여부 */
+ public boolean isHardDeleteEnabled() {
+ Map properties = portalPropertyService.getPortalPropertiesAsMap(PORTAL_PROPERTY_GROUP);
+ return Boolean.parseBoolean(properties.getOrDefault(HARD_DELETE_FLAG_KEY, "false"));
+ }
public Page selectList(Pageable pageable, PortalUserUISearch portalUserUISearch) {
Page portalUser = portalUserService.findAll(pageable, portalUserUISearch);
diff --git a/src/main/resources/message/LocaleMessage.properties b/src/main/resources/message/LocaleMessage.properties
index ae5349e..79e7759 100644
--- a/src/main/resources/message/LocaleMessage.properties
+++ b/src/main/resources/message/LocaleMessage.properties
@@ -2490,6 +2490,7 @@ deployResourceSearchMan.deleteBtn=delete
auditLogMan.command = Command
auditLogMan.logMsg = Message
+auditLogMan.message = Reason
auditLogMan.logSeqNo = Number
auditLogMan.logSubMsg = Sub Message
auditLogMan.logType.access = ACCESS
diff --git a/src/main/resources/message/LocaleMessage_ko.properties b/src/main/resources/message/LocaleMessage_ko.properties
index 6e1a4e8..0731578 100644
--- a/src/main/resources/message/LocaleMessage_ko.properties
+++ b/src/main/resources/message/LocaleMessage_ko.properties
@@ -202,6 +202,7 @@ apiScpMan.title = API-SCOPE \uB9F5\uD551
auditLogMan.command = Command
auditLogMan.logMsg = \uBA54\uC2DC\uC9C0
+auditLogMan.message = \uC0AC\uC720
auditLogMan.logSeqNo = \uBC88\uD638
auditLogMan.logSubMsg = \uC11C\uBE0C \uBA54\uC2DC\uC9C0
auditLogMan.logType.access = \uC811\uC18D