포탈 법인, 사용자 기본폼 변경

This commit is contained in:
Rinjae
2026-01-17 22:38:49 +09:00
parent c6012711f0
commit cb551d6888
8 changed files with 246 additions and 30 deletions
@@ -308,26 +308,7 @@
clientId: clientId clientId: clientId
}, },
success: function(response) { success: function(response) {
if (response.success) { showSyncResultModal(response);
var msg = "포탈 정보 반영 완료";
if (response.action === 'INSERTED') {
msg = "포탈 정보를 새로 생성했습니다.";
} else if (response.action === 'UPDATED') {
msg = "포탈 정보를 업데이트했습니다.";
} else if (response.action === 'SKIPPED_NO_ORG') {
msg = "반영을 건너뜁니다.\n법인(orgId)이 설정되지 않은 클라이언트입니다.";
} else if (response.action === 'SKIPPED_INVALID_API') {
msg = "반영을 건너뜁니다.\n존재하지 않는 API가 포함되어 있습니다.\n\n";
if (response.invalidApis && response.invalidApis.length > 0) {
msg += "누락된 API: " + response.invalidApis.join(", ");
}
}
alert(msg);
} else {
alert("반영 실패\n\n" + response.message);
}
}, },
error: function(xhr) { error: function(xhr) {
alert("반영 중 오류가 발생했습니다."); alert("반영 중 오류가 발생했습니다.");
@@ -628,5 +609,193 @@
</div> </div>
</div><!-- end content_middle --> </div><!-- end content_middle -->
</div><!-- end right_box --> </div><!-- end right_box -->
<!-- 포탈 반영 결과 Modal -->
<div id="syncResultModal" class="modal-overlay" style="display:none;">
<div class="modal-content" style="width:700px; max-height:80vh; overflow-y:auto;">
<div class="modal-header">
<h3 id="syncResultTitle">개발자포탈 반영 결과</h3>
<button type="button" class="modal-close" onclick="closeSyncResultModal()">&times;</button>
</div>
<div class="modal-body">
<div id="syncResultStatus" style="padding:15px; margin-bottom:15px; border-radius:4px;"></div>
<div id="syncResultApiSection">
<h4 style="margin:10px 0;">반영 대상 API 목록 (<span id="targetApiCount">0</span>건)</h4>
<table class="table_row" cellspacing="0" style="width:100%;">
<thead>
<tr>
<th style="width:50px;">No</th>
<th>API ID</th>
<th style="width:120px;">상태</th>
</tr>
</thead>
<tbody id="syncResultApiList">
</tbody>
</table>
</div>
</div>
<div class="modal-footer" style="text-align:center; padding:15px;">
<button type="button" class="cssbtn" onclick="closeSyncResultModal()">
<i class="material-icons">close</i> 닫기
</button>
</div>
</div>
</div>
<style>
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
z-index: 9999;
display: flex;
justify-content: center;
align-items: center;
}
.modal-content {
background: white;
border-radius: 8px;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 20px;
border-bottom: 1px solid #ddd;
background: #f5f5f5;
border-radius: 8px 8px 0 0;
}
.modal-header h3 {
margin: 0;
font-size: 16px;
}
.modal-close {
background: none;
border: none;
font-size: 24px;
cursor: pointer;
color: #666;
}
.modal-close:hover {
color: #333;
}
.modal-body {
padding: 20px;
}
.modal-footer {
border-top: 1px solid #ddd;
}
.status-success {
background-color: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.status-fail {
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.status-warning {
background-color: #fff3cd;
color: #856404;
border: 1px solid #ffeeba;
}
.api-synced {
color: #28a745;
font-weight: bold;
}
.api-invalid {
color: #dc3545;
font-weight: bold;
}
</style>
<script>
function closeSyncResultModal() {
$("#syncResultModal").hide();
}
function showSyncResultModal(response) {
var $modal = $("#syncResultModal");
var $status = $("#syncResultStatus");
var $apiList = $("#syncResultApiList");
var $targetCount = $("#targetApiCount");
// 상태 메시지
var statusClass = "";
var statusMsg = "";
if (response.success) {
statusClass = "status-success";
if (response.action === 'INSERTED') {
statusMsg = "<strong>반영 완료</strong> - 포탈에 새로운 인증정보가 생성되었습니다.";
} else if (response.action === 'UPDATED') {
statusMsg = "<strong>반영 완료</strong> - 기존 포탈 인증정보가 업데이트되었습니다.";
} else {
statusMsg = "<strong>반영 완료</strong> - " + response.message;
}
} else {
if (response.action === 'SKIPPED_NO_ORG') {
statusClass = "status-warning";
statusMsg = "<strong>반영 건너뜀</strong> - 법인(orgId)이 설정되지 않은 클라이언트입니다.";
} else if (response.action === 'SKIPPED_INVALID_API') {
statusClass = "status-fail";
statusMsg = "<strong>반영 실패</strong> - 존재하지 않는 API가 포함되어 있어 반영을 중단합니다.";
} else {
statusClass = "status-fail";
statusMsg = "<strong>반영 실패</strong> - " + response.message;
}
}
$status.removeClass("status-success status-fail status-warning").addClass(statusClass).html(statusMsg);
// API 목록 표시
$apiList.empty();
var targetApis = response.targetApis || [];
var syncedApis = response.syncedApis || [];
var invalidApis = response.invalidApis || [];
$targetCount.text(targetApis.length);
if (targetApis.length === 0) {
$apiList.append('<tr><td colspan="3" style="text-align:center;">등록된 API가 없습니다.</td></tr>');
} else {
targetApis.forEach(function(apiId, index) {
var status = "";
var statusClass = "";
if (invalidApis.includes(apiId)) {
status = "미존재 (APIGW에 없음)";
statusClass = "api-invalid";
} else if (syncedApis.includes(apiId)) {
status = "반영됨";
statusClass = "api-synced";
} else if (response.success) {
status = "반영됨";
statusClass = "api-synced";
} else {
status = "미반영";
statusClass = "";
}
$apiList.append(
'<tr>' +
'<td style="text-align:center;">' + (index + 1) + '</td>' +
'<td>' + apiId + '</td>' +
'<td class="' + statusClass + '" style="text-align:center;">' + status + '</td>' +
'</tr>'
);
});
}
$modal.show();
}
</script>
</body> </body>
</html> </html>
@@ -87,8 +87,8 @@
callback(); callback();
} }
if(!isDetail) { if(!isDetail) {
$("select[name=orgStatus]").val("READY").prop("disabled", true); $("select[name=orgStatus]").val("ACTIVE").prop("disabled", true);
$("select[name=approvalStatus]").val("PENDING").prop("disabled", true); $("select[name=approvalStatus]").val("COMPLETED").prop("disabled", true);
} }
}, },
error:function(e){ error:function(e){
@@ -363,8 +363,9 @@
} else { } else {
$("#title").append(" 등록") $("#title").append(" 등록")
$("#btn_modify").html('<i class="material-icons">save</i> <%= localeMessage.getString("button.register") %>'); $("#btn_modify").html('<i class="material-icons">save</i> <%= localeMessage.getString("button.register") %>');
$("#userStatus").val("READY"); $("#userStatus").val("ACTIVE");
$("#approvalStatus").val("PENDING"); $("#approvalStatus").val("COMPLETED");
$("#accountLockYn").val("N");
$("#roleCode").val("ROLE_USER").trigger('change'); $("#roleCode").val("ROLE_USER").trigger('change');
updateButtonStates(STATUS.READY, false); updateButtonStates(STATUS.READY, false);
} }
@@ -645,7 +646,7 @@
</th> </th>
<td> <td>
<div class="input-group" style="width: 60%; display: flex;"> <div class="input-group" style="width: 60%; display: flex;">
<div class="select-style" style="width: 25%; display: inline-block;"> <div class="select-style" style="width: 35%; display: inline-block;">
<select id="mobilePrefix" style="padding-left: 10px;"> <select id="mobilePrefix" style="padding-left: 10px;">
<option value="010">010</option> <option value="010">010</option>
<option value="011">011</option> <option value="011">011</option>
@@ -75,11 +75,11 @@ public class PortalOrgManService extends BaseService {
} }
if (portalOrg.getOrgStatus() == null) { if (portalOrg.getOrgStatus() == null) {
portalOrg.setOrgStatus(OrgStatus.READY); portalOrg.setOrgStatus(OrgStatus.ACTIVE);
} }
if (portalOrg.getApprovalStatus() == null) { if (portalOrg.getApprovalStatus() == null) {
portalOrg.setApprovalStatus(ApprovalStatus.PENDING); portalOrg.setApprovalStatus(ApprovalStatus.COMPLETED);
} }
if (portalOrg.getId() == null || portalOrg.getId().isEmpty()) { if (portalOrg.getId() == null || portalOrg.getId().isEmpty()) {
@@ -130,6 +130,14 @@ public class PortalUserManService extends BaseService {
portalUser.setEmailAddr(portalUserUI.getLoginId()); portalUser.setEmailAddr(portalUserUI.getLoginId());
portalUser.setId(null); portalUser.setId(null);
// 기본 상태 설정
if (portalUser.getUserStatus() == null) {
portalUser.setUserStatus(PortalUserEnums.UserStatus.ACTIVE);
}
if (portalUser.getApprovalStatus() == null) {
portalUser.setApprovalStatus(PortalUserEnums.ApprovalStatus.COMPLETED);
}
if (StringUtils.isNotBlank(portalUserUI.getOrgId())) { if (StringUtils.isNotBlank(portalUserUI.getOrgId())) {
portalUser.setPortalOrg(portalOrgService.getById(portalUserUI.getOrgId())); portalUser.setPortalOrg(portalOrgService.getById(portalUserUI.getOrgId()));
} }
@@ -139,7 +139,19 @@ public class ClientController extends OnlBaseAnnotationController {
response.put("message", result.getMessage()); response.put("message", result.getMessage());
response.put("action", result.getAction().name()); response.put("action", result.getAction().name());
// 유효하지 않은 API 목록 포함 // 반영 대상 API 목록 포함
if (result.getTargetApis() != null) {
response.put("targetApis", result.getTargetApis());
response.put("targetApiCount", result.getTargetApiCount());
}
// 반영된 API 목록 포함
if (result.getSyncedApis() != null) {
response.put("syncedApis", result.getSyncedApis());
response.put("syncedApiCount", result.getSyncedApiCount());
}
// 유효하지 않는 API 목록 포함 (사유: APIGW에 미존재)
if (result.getInvalidApis() != null && !result.getInvalidApis().isEmpty()) { if (result.getInvalidApis() != null && !result.getInvalidApis().isEmpty()) {
response.put("invalidApis", result.getInvalidApis()); response.put("invalidApis", result.getInvalidApis());
} }
@@ -157,8 +157,10 @@ public class ClientManService extends OnlBaseService {
return SyncResult.builder() return SyncResult.builder()
.success(false) .success(false)
.action(SyncResult.SyncAction.SKIPPED_INVALID_API) .action(SyncResult.SyncAction.SKIPPED_INVALID_API)
.targetApis(requestedApiIds)
.targetApiCount(requestedApiIds.size())
.invalidApis(invalidApis) .invalidApis(invalidApis)
.message("존재하지 않는 API: " + String.join(", ", invalidApis)) .message("존재하지 않는 API가 있어 반영을 중단합니다.")
.build(); .build();
} }
@@ -204,6 +206,10 @@ public class ClientManService extends OnlBaseService {
.success(true) .success(true)
.action(action) .action(action)
.message("포탈 정보 반영 완료") .message("포탈 정보 반영 완료")
.targetApis(requestedApiIds)
.targetApiCount(requestedApiIds.size())
.syncedApis(requestedApiIds)
.syncedApiCount(requestedApiIds.size())
.build(); .build();
} catch (Exception e) { } catch (Exception e) {
@@ -32,7 +32,27 @@ public class SyncResult {
private SyncAction action; private SyncAction action;
/** /**
* 존재하지 않는 API 목록 (SKIPPED_INVALID_API인 경우) * 반영 대상 API 목록 (ClientEntity에 등록된 전체 API)
*/
private List<String> targetApis;
/**
* 반영 대상 API 개수
*/
private int targetApiCount;
/**
* 반영된 API 목록 (성공한 경우)
*/
private List<String> syncedApis;
/**
* 반영된 API 개수
*/
private int syncedApiCount;
/**
* 존재하지 않는 API 목록 (SKIPPED_INVALID_API인 경우, 사유: APIGW에 미존재)
*/ */
private List<String> invalidApis; private List<String> invalidApis;