From 08354837b164990ae9b30f409767ef461fc03ce3 Mon Sep 17 00:00:00 2001
From: Rinjae
Date: Fri, 7 Aug 2026 13:40:49 +0900
Subject: [PATCH] =?UTF-8?q?OpenAPI=20Spec=C2=B7=ED=8F=AC=ED=83=88=20?=
=?UTF-8?q?=EB=85=B8=EC=B6=9C=20=ED=95=84=ED=84=B0=20=EC=B6=94=EA=B0=80=20?=
=?UTF-8?q?-=20EAIMessage=20=EA=B2=80=EC=83=89=20=EC=A1=B0=EA=B1=B4=20?=
=?UTF-8?q?=EC=B6=94=EA=B0=80=20-=20API=20Group=20=ED=8C=9D=EC=97=85=20?=
=?UTF-8?q?=EA=B2=80=EC=83=89=20=EA=B0=9C=EC=84=A0=20-=20JSP=20=EC=B2=B4?=
=?UTF-8?q?=ED=81=AC=EB=B0=95=EC=8A=A4=20=EC=97=B0=EB=8F=99=20=EC=B2=98?=
=?UTF-8?q?=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../onl/apim/apigroup/apiGroupManPopup.jsp | 30 +++++++++-
.../portalnotice/portalNoticeManDetail.jsp | 5 +-
.../entity/onl/eaimsg/EAIMessageService.java | 56 ++++++++++++++++++-
.../entity/onl/eaimsg/EAIMessageUISearch.java | 6 ++
4 files changed, 92 insertions(+), 5 deletions(-)
diff --git a/WebContent/jsp/onl/apim/apigroup/apiGroupManPopup.jsp b/WebContent/jsp/onl/apim/apigroup/apiGroupManPopup.jsp
index 24e579b..c286573 100644
--- a/WebContent/jsp/onl/apim/apigroup/apiGroupManPopup.jsp
+++ b/WebContent/jsp/onl/apim/apigroup/apiGroupManPopup.jsp
@@ -72,13 +72,22 @@
});
}
- function detail(){
+ // 체크박스는 name 을 search* 로 두면 getSearchForJqgrid 가 해제 상태에서도 value 를 담아버린다
+ // (input[type!=radio][name^=search] 를 checked 여부와 무관하게 수집) → 여기서 직접 붙인다
+ function getPopupSearchData() {
var postData = getSearchForJqgrid("cmd","LIST"); //jqgrid에서는 object 로
+ postData.searchApiSpecYn = $("#chkApiSpec").is(":checked") ? "Y" : "";
+ postData.searchPortalDisplayYn = $("#chkPortalDisplay").is(":checked") ? "Y" : "";
+ return postData;
+ }
+
+ function detail(){
+ var postData = getPopupSearchData();
$("#grid").setGridParam({ url:url,postData: postData }).trigger("reloadGrid");
}
function search(){
- var postData = getSearchForJqgrid("cmd","LIST"); //jqgrid에서는 object 로
+ var postData = getPopupSearchData();
$("#grid").setGridParam({ url:url,postData: postData ,page:1 }).trigger("reloadGrid");
}
function ioFormatter(cellvalue,options,rowObject){
@@ -97,7 +106,7 @@
function list(){
detail()
- var gridPostData = getSearchForJqgrid("cmd","LIST"); //jqgrid에서는 object 로
+ var gridPostData = getPopupSearchData();
// gridPostData.searchApiEnableYn = 'Y';
var urlParams = new URLSearchParams(window.location.search);
var selectedApiIds = urlParams.get("selectedApiIds");
@@ -189,6 +198,9 @@
$("select[name=searchEaiBzwkDstcd]").change(function() {
search();
});
+ $("#chkApiSpec, #chkPortalDisplay").change(function() {
+ search();
+ });
$("#btn_search").click(function(){
search();
});
@@ -247,6 +259,18 @@
+
+
포탈 노출
+
+
+
+
+
+
diff --git a/WebContent/jsp/onl/apim/portalnotice/portalNoticeManDetail.jsp b/WebContent/jsp/onl/apim/portalnotice/portalNoticeManDetail.jsp
index 6bee1a8..f47bc19 100644
--- a/WebContent/jsp/onl/apim/portalnotice/portalNoticeManDetail.jsp
+++ b/WebContent/jsp/onl/apim/portalnotice/portalNoticeManDetail.jsp
@@ -189,8 +189,11 @@
// AuthorizeInterceptor 가 정상적으로 권한 인식. window.open 직접 호출 시 권한 부족 발생.
// 본 페이지는 summernote 본문 에디터 등 다른 iframe 이 함께 존재할 수 있어
// frames[0] 가정은 위험 → DOM 에서 .ui-dialog 내 iframe 중 src=apiGroupMan 인 것을 식별.
+ // 공지 영향 API 는 포탈에 실제 노출되는 것만 고르면 되므로 두 조건을 켠 채로 연다.
+ // (타 화면에서 여는 팝업은 파라미터가 없어 해제 상태 — 팝업 기본값은 건드리지 않는다)
var selectedIds = affectedApis.map(function(a) { return a.apiId; }).join(',');
- var url2 = apiPopupUrl + '?cmd=POPUP&selectedApiIds=' + encodeURIComponent(selectedIds);
+ var url2 = apiPopupUrl + '?cmd=POPUP&searchApiSpecYn=Y&searchPortalDisplayYn=Y'
+ + '&selectedApiIds=' + encodeURIComponent(selectedIds);
var args = {};
showModal(url2, args, 1280, 860, function () {
var doc = args.self && args.self.document;
diff --git a/src/main/java/com/eactive/eai/rms/data/entity/onl/eaimsg/EAIMessageService.java b/src/main/java/com/eactive/eai/rms/data/entity/onl/eaimsg/EAIMessageService.java
index f6c1c45..22b3db8 100644
--- a/src/main/java/com/eactive/eai/rms/data/entity/onl/eaimsg/EAIMessageService.java
+++ b/src/main/java/com/eactive/eai/rms/data/entity/onl/eaimsg/EAIMessageService.java
@@ -13,7 +13,10 @@ import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import com.eactive.apim.portal.apispec.repository.ApiSpecInfoRepository;
import com.eactive.eai.data.entity.onl.adapter.QAdapter;
+import com.eactive.eai.data.entity.onl.apim.apigroup.QApiGroup;
+import com.eactive.eai.data.entity.onl.apim.apigroup.QApiGroupApi;
import com.eactive.eai.data.entity.onl.authserver.QScopeEntity;
import com.eactive.eai.data.entity.onl.logger.QStatLog;
import com.eactive.eai.data.entity.onl.message.EAIMessageEntity;
@@ -31,6 +34,9 @@ import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions;
+import com.querydsl.core.types.dsl.StringPath;
+import com.querydsl.jpa.JPAExpressions;
+import com.querydsl.jpa.JPQLQuery;
import com.querydsl.jpa.impl.JPAQuery;
@Service
@@ -38,8 +44,14 @@ import com.querydsl.jpa.impl.JPAQuery;
@RequiredArgsConstructor
public class EAIMessageService extends AbstractDataService {
+ /** Oracle IN 절 표현식 개수 상한. 넘기면 ORA-01795 라 나눠 OR 로 잇는다 */
+ private static final int ORACLE_IN_LIMIT = 1000;
+
private final UserBusinessService userBusinessService;
+ /** EMSAPP(PTL_API_SPEC_INFO) 조회용. 다른 스키마라 EAI 메시지 쿼리에 조인할 수 없다 */
+ private final ApiSpecInfoRepository apiSpecInfoRepository;
+
public Page selectList(EAIMessageUISearch eaiMessageUISearch, Pageable pageable, String sortname, String sortorder) {
QEAIMessageEntity qeaiMessageEntity = QEAIMessageEntity.eAIMessageEntity;
@@ -196,10 +208,52 @@ public class EAIMessageService extends AbstractDataServicePTL_API_SPEC_INFO 는 EMSAPP 스키마라 TSEAIHE01 쿼리에 조인하면 ORA-00942 다. 스펙이 있는
+ * API ID 를 EMS 커넥션에서 따로 읽어 IN 절로 넘긴다.
+ */
+ private BooleanExpression apiSpecRegisteredExpression(StringPath eaiSvcNamePath) {
+ List specApiIds = apiSpecInfoRepository.findAllApiIds();
+ if (specApiIds.isEmpty()) {
+ // in(빈 리스트) 는 JPQL 이 깨지므로 항상 거짓인 조건으로 대체한다
+ return Expressions.ONE.eq(Expressions.TWO);
+ }
+
+ BooleanExpression expression = null;
+ for (int from = 0; from < specApiIds.size(); from += ORACLE_IN_LIMIT) {
+ int to = Math.min(from + ORACLE_IN_LIMIT, specApiIds.size());
+ BooleanExpression chunk = eaiSvcNamePath.in(specApiIds.subList(from, to));
+ expression = (expression == null) ? chunk : expression.or(chunk);
+ }
+ return expression;
+ }
+
+ /** 노출 중인(display_yn='1') API 그룹에 편성된 API ID. API_GROUP 은 EAI 메시지와 같은 스키마다 */
+ private JPQLQuery displayedGroupApiIdSubQuery() {
+ QApiGroupApi qApiGroupApi = QApiGroupApi.apiGroupApi;
+ QApiGroup qApiGroup = QApiGroup.apiGroup;
+
+ return JPAExpressions
+ .select(qApiGroupApi.id.apiId)
+ .from(qApiGroupApi)
+ .join(qApiGroupApi.apiGroup, qApiGroup)
+ .where(qApiGroup.displayYn.eq("1"));
+ }
+
public Page findAll(Pageable pageable, RoutingEaiMsgSearch routingEaiMsgSearch) {
List result = routingEaiMsgDtoList(pageable, routingEaiMsgSearch);
diff --git a/src/main/java/com/eactive/eai/rms/data/entity/onl/eaimsg/EAIMessageUISearch.java b/src/main/java/com/eactive/eai/rms/data/entity/onl/eaimsg/EAIMessageUISearch.java
index 52d30a5..5006451 100644
--- a/src/main/java/com/eactive/eai/rms/data/entity/onl/eaimsg/EAIMessageUISearch.java
+++ b/src/main/java/com/eactive/eai/rms/data/entity/onl/eaimsg/EAIMessageUISearch.java
@@ -22,4 +22,10 @@ public class EAIMessageUISearch {
private String searchApiFullPath;
+ /** "Y" 면 PTL_API_SPEC_INFO 에 OpenAPI Spec 이 등록된 API 만 조회 */
+ private String searchApiSpecYn;
+
+ /** "Y" 면 노출 중인(display_yn='1') API 그룹에 편성된 API 만 조회 */
+ private String searchPortalDisplayYn;
+
}