이호영 이호영 2025-03-04
5011 수정 - 순서삭제, 삭제기능 추가, 링크 파라미터 자동조정
@b87785778efb37a28a227765c3cc3f8d44d6c843
src/main/java/itn/com/uss/ion/bnr/pop/service/MainPopupLinkVO.java
--- src/main/java/itn/com/uss/ion/bnr/pop/service/MainPopupLinkVO.java
+++ src/main/java/itn/com/uss/ion/bnr/pop/service/MainPopupLinkVO.java
@@ -35,5 +35,6 @@
 	private String popId; // 메인존ID
 	private String mlink; // 링크
 	private String coords; // 링크좌표
+	private String popLinkId; // 링크좌표
 	
 }
src/main/java/itn/com/uss/ion/bnr/pop/service/MainPopupManageService.java
--- src/main/java/itn/com/uss/ion/bnr/pop/service/MainPopupManageService.java
+++ src/main/java/itn/com/uss/ion/bnr/pop/service/MainPopupManageService.java
@@ -1,13 +1,8 @@
 package itn.com.uss.ion.bnr.pop.service;
 
 import java.util.List;
-import java.util.Map;
 
-import itn.com.uss.ion.pwm.service.MainzoneVO;
-import itn.com.uss.ion.pwm.service.PopupManageVO;
-import itn.com.uss.ion.pwm.service.PopupzoneVO;
-import itn.com.uss.ion.pwm.service.SocialVO;
-import itn.com.uss.ion.pwm.service.SortVO;
+import itn.com.cmm.RestResponse;
 
 /**
  * 개요
@@ -34,4 +29,6 @@
 
 	public void resetMainPopupSort(MainPopupVO mainPopupVO);
 
+	public RestResponse deleteMainPopupLink(MainPopupLinkVO mainPopupLinkVO);
+
 }
(No newline at end of file)
src/main/java/itn/com/uss/ion/bnr/pop/service/impl/MainPopupManageDAO.java
--- src/main/java/itn/com/uss/ion/bnr/pop/service/impl/MainPopupManageDAO.java
+++ src/main/java/itn/com/uss/ion/bnr/pop/service/impl/MainPopupManageDAO.java
@@ -4,6 +4,7 @@
 import org.springframework.stereotype.Repository;
 
 import itn.com.cmm.service.impl.EgovComAbstractDAO;
+import itn.com.uss.ion.bnr.pop.service.MainPopupLinkVO;
 import itn.com.uss.ion.bnr.pop.service.MainPopupVO;
 
 /**
@@ -46,8 +47,8 @@
 	}
 
 
-	public void deleteMainPopup(String mazId) {
-		delete("mainPopup.deleteMainPopup", mazId);
+	public void deleteMainPopup(String popId) {
+		delete("mainPopup.deleteMainPopup", popId);
 	}
 
 
@@ -55,4 +56,7 @@
 		update("mainPopup.resetMainPopupSort", mainPopupVO);  
 	}
 
+	public void deleteMainPopupLinkInfo(MainPopupLinkVO mainPopupLinkVO) {
+		delete("mainPopup.deleteMainPopupLinkInfo", mainPopupLinkVO);
+	}
 }
(No newline at end of file)
src/main/java/itn/com/uss/ion/bnr/pop/service/impl/MainPopupManageServiceImpl.java
--- src/main/java/itn/com/uss/ion/bnr/pop/service/impl/MainPopupManageServiceImpl.java
+++ src/main/java/itn/com/uss/ion/bnr/pop/service/impl/MainPopupManageServiceImpl.java
@@ -4,12 +4,16 @@
 
 import javax.annotation.Resource;
 
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
 
 import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
 import egovframework.rte.fdl.idgnr.EgovIdGnrService;
+import itn.com.cmm.RestResponse;
+import itn.com.uss.ion.bnr.pop.service.MainPopupLinkVO;
 import itn.com.uss.ion.bnr.pop.service.MainPopupManageService;
 import itn.com.uss.ion.bnr.pop.service.MainPopupVO;
+import itn.com.uss.ion.pwm.service.impl.PopupManageDAO;
 
 /**
  * 개요
@@ -29,7 +33,9 @@
 	@Resource(name = "mainPopupManageDAO")
 	public MainPopupManageDAO dao;
 
-    
+	@Resource(name = "popupManageDAO")
+	public PopupManageDAO popupDao;
+	
 	@Resource(name = "egovPopupManageIdGnrService")
 	private EgovIdGnrService idgenService;
 
@@ -59,6 +65,7 @@
 
 	@Override
 	public void deleteMainPopup(String id) {
+		popupDao.deleteMainPopupLinkInfo(id);
 		dao.deleteMainPopup(id);
 	}
 
@@ -68,5 +75,15 @@
 		
 	}
 
+	@Override
+	public RestResponse deleteMainPopupLink(MainPopupLinkVO mainPopupLinkVO) {
+		dao.deleteMainPopupLinkInfo(mainPopupLinkVO);
+		
+		return RestResponse.builder()
+				.status(HttpStatus.OK) // 200, Series.SUCCESSFUL, "OK"
+				.msg("삭제 되었습니다.")
+				.build();
+		
+	}
 
 }
(No newline at end of file)
src/main/java/itn/com/uss/ion/bnr/pop/web/MainPopupController.java
--- src/main/java/itn/com/uss/ion/bnr/pop/web/MainPopupController.java
+++ src/main/java/itn/com/uss/ion/bnr/pop/web/MainPopupController.java
@@ -12,11 +12,15 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 import org.springmodules.validation.commons.DefaultBeanValidator;
 
@@ -27,15 +31,16 @@
 import itn.com.cmm.ComDefaultCodeVO;
 import itn.com.cmm.EgovMessageSource;
 import itn.com.cmm.LoginVO;
+import itn.com.cmm.RestResponse;
 import itn.com.cmm.service.EgovCmmUseService;
 import itn.com.cmm.service.EgovFileMngService;
 import itn.com.cmm.service.EgovFileMngUtil;
 import itn.com.cmm.service.FileVO;
 import itn.com.cmm.util.RedirectUrlMaker;
+import itn.com.uss.ion.bnr.pop.service.MainPopupLinkVO;
 import itn.com.uss.ion.bnr.pop.service.MainPopupManageService;
 import itn.com.uss.ion.bnr.pop.service.MainPopupVO;
 import itn.com.uss.ion.bnr.sub.service.SubMainZoneManageService;
-import itn.com.uss.ion.pwm.service.MainzoneVO;
 import itn.let.sym.site.service.EgovSiteManagerService;
 
 /**
@@ -243,11 +248,35 @@
 		RedirectUrlMaker redirectUrlMaker = new RedirectUrlMaker("/uss/ion/bnr/pop/mainPopupList.do");
 		return redirectUrlMaker.getRedirectUrl();
 	}
-	
-	
-	
-	
-	
+
+	/** 
+	 * @methodName	: mainPopupLinkDeleteAjax 
+	 * @author		: 이호영
+	 * @date		: 2025.03.04 
+	 * @description	: 메인팝업링크 데이터 삭제
+	 * @param request
+	 * @param mainPopupLinkVO
+	 * @return
+	 * @throws Exception 
+	 */
+	@ResponseBody
+	@RequestMapping(value="/uss/ion/bnr/pop/mainPopupLinkDeleteAjax.do")
+	public ResponseEntity<?> mainPopupLinkDeleteAjax(
+			HttpServletRequest request
+			,@RequestBody MainPopupLinkVO mainPopupLinkVO) throws Exception {
+ 
+		Boolean isAuthenticated = EgovUserDetailsHelper.isAuthenticated();
+ 
+		if(!isAuthenticated) {
+			return ResponseEntity.ok(
+					RestResponse.builder()
+					.status(HttpStatus.UNAUTHORIZED) // 401 권한 인증 에러
+					.msg("로그인을 하셔야 이용 가능합니다.")
+					.build()
+					);
+		}
+		return ResponseEntity.ok(mainPopupManageService.deleteMainPopupLink(mainPopupLinkVO));
+	}
 	
 	
 	
src/main/resources/egovframework/sqlmap/let/uss/ion/bnr/MainPopupManage_SQL_Mysql.xml
--- src/main/resources/egovframework/sqlmap/let/uss/ion/bnr/MainPopupManage_SQL_Mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/uss/ion/bnr/MainPopupManage_SQL_Mysql.xml
@@ -12,6 +12,7 @@
 	<typeAlias  alias="PopupManageVO" type="itn.com.uss.ion.pwm.service.PopupManageVO" />
 	<typeAlias  alias="popupzoneVO" type="itn.com.uss.ion.pwm.service.PopupzoneVO"/>
 	<typeAlias  alias="mainPopupVO" type="itn.com.uss.ion.bnr.pop.service.MainPopupVO"/>
+	<typeAlias  alias="mainPopupLinkVO" type="itn.com.uss.ion.bnr.pop.service.MainPopupLinkVO"/>
 	
 
 
@@ -19,7 +20,7 @@
 		<result property="popId" column="POP_ID"></result>
 		<result property="mlink" column="MLINK"></result>
 		<result property="coords" column="COORDS"></result>
-		<result property="sort" column="SORT"></result>
+		<result property="popLinkId" column="POP_LINK_ID"></result>
 	</resultMap>
 	
 		
@@ -146,17 +147,17 @@
 		WHERE MP.POP_ID = #popId#
 	</select>
 
+
 	<select id="mainPopup.selectMainPopupVOLink" parameterClass="String" resultMap="MainPopupLinkResultMap">
 																	 
-	/* mainPopup.selectMainPopupVO */
+	/* mainPopup.selectMainPopupVOLink */
 		SELECT
+			POP_LINK_ID,
 			POP_ID,
 			MLINK,
-			COORDS,
-			SORT
+			COORDS
 		FROM MAIN_POPUP_LINK
 		WHERE POP_ID = #popId#
-		order by SORT asc
 	</select>
 
 
@@ -196,6 +197,16 @@
 		DELETE FROM MAIN_POPUP WHERE POP_ID=#popId#
 	</delete>
 	
+	<delete id="mainPopup.deleteMainPopupLinkInfo" parameterClass="mainPopupLinkVO">
+	/* mainPopup.deleteMainPopupLinkInfo */
+	
+		DELETE FROM MAIN_POPUP_LINK 
+		WHERE 
+			POP_ID=#popId#
+		AND
+			POP_LINK_ID = #popLinkId# 
+	</delete>
+
 	
 	<update id="mainPopup.resetMainPopupSort" parameterClass="mainPopupVO">
 			/*mainPopup.resetMainPopupSort*/
src/main/resources/egovframework/sqlmap/let/uss/pwm/PopupManage_SQL_Mysql.xml
--- src/main/resources/egovframework/sqlmap/let/uss/pwm/PopupManage_SQL_Mysql.xml
+++ src/main/resources/egovframework/sqlmap/let/uss/pwm/PopupManage_SQL_Mysql.xml
@@ -1083,7 +1083,6 @@
 			POP_ID
 			, MLINK
 			, COORDS
-			, SORT
 			)
 		VALUES
 		<iterate conjunction=",">
@@ -1091,7 +1090,6 @@
 				#[].popId#
 				, #[].mlink#
 				, #[].coords#
-				, #[].sort# 
 			)
 		</iterate>
 		
@@ -1123,7 +1121,6 @@
 		SET 
 			  MLINK     = #mlink#
 			, COORDS    = #coords#
-			, SORT		= #sort#
 		WHERE POP_ID = #popId#
 	</update>
 	
src/main/webapp/WEB-INF/jsp/uss/ion/bnr/pop/mainPopupModify.jsp
--- src/main/webapp/WEB-INF/jsp/uss/ion/bnr/pop/mainPopupModify.jsp
+++ src/main/webapp/WEB-INF/jsp/uss/ion/bnr/pop/mainPopupModify.jsp
@@ -31,8 +31,18 @@
 	
 	makeDate('ntceBgndeYYYMMDD');
 	makeTomorrow('ntceEnddeYYYMMDD');
-	
-	
+	// class="mlink"인 모든 input 요소에 대해 이벤트 리스너 추가
+	document.getElementById('linkTable').addEventListener('paste', function(event) {
+		if (event.target.classList.contains('mlink')) {
+			let pastedText = event.clipboardData.getData("text");
+			console.log("붙여넣기 한 URL:", pastedText);
+			let cleanedUrl = cleanUrlParameters(pastedText);
+			setTimeout(() => {
+				event.target.value = cleanedUrl;
+				console.log("정리된 URL:", cleanedUrl);
+			}, 0);
+		}
+	});
 });
 
 /**
@@ -40,39 +50,37 @@
  * @param {string} url 원본 URL 문자열
  * @returns {string} 불필요한 파라미터가 제거된 URL
  */
-	function cleanUrlParameters(url) {
-		try {
-			// URL이 절대경로 (/web/... 형태)인지 확인
-			let hasFullDomain = url.startsWith("http://") || url.startsWith("https://");
-			let urlObj;
-
-			if (hasFullDomain) {
-				// 도메인이 포함된 URL 처리
-				urlObj = new URL(url);
-			} else {
-				// 절대경로 URL 처리 (가상의 도메인 추가 후 파싱)
-				urlObj = new URL("https://www.munjaon.co.kr" + url);
-			}
-
-			let params = new URLSearchParams(urlObj.search);
-
-			// ❗ 값이 비어있는 모든 파라미터 제거
-			for (let [key, value] of [...params.entries()]) {  // `params.entries()`를 배열로 변환하여 반복
-				if (!value.trim()) {  // 값이 비어있는 경우 제거
-					params.delete(key);
-				}
-			}
-
-			// 정리된 URL 반환
-			let cleanedPath = urlObj.pathname + (params.toString() ? "?" + params.toString() : "");
-			// 정리된 URL 반환 (도메인을 제거하고 절대경로만 반환)
-			return cleanedPath.replace(/^https:\/\/www\.munjaon\.co\.kr/, "");
-
-		} catch (e) {
-			console.warn("잘못된 URL 형식:", url);
-			return url; // URL 파싱 실패 시 원본 유지
+function cleanUrlParameters(url) {
+	try {
+		// URL이 절대경로 (/web/... 형태)인지 확인
+		let hasFullDomain = url.startsWith("http://") || url.startsWith("https://");
+		let urlObj;
+		
+		if (hasFullDomain) {
+			// 도메인이 포함된 URL 처리
+			urlObj = new URL(url);
+		} else {
+			// 절대경로 URL 처리 (가상의 도메인 추가 후 파싱)
+			urlObj = new URL("https://www.munjaon.co.kr" + url);
 		}
+		
+		let params = new URLSearchParams(urlObj.search);
+		
+		// 값이 비어있는 모든 파라미터 제거
+		for (let [key, value] of [...params.entries()]) {
+			if (!value.trim()) { // 값이 비어있는 경우 제거
+				params.delete(key);
+			}
+		}
+		
+		// 정리된 URL 반환
+		let cleanedPath = urlObj.pathname + (params.toString() ? "?" + params.toString() : "");
+		return cleanedPath.replace(/^https:\/\/www\.munjaon\.co\.kr/, "");
+	} catch (e) {
+		console.warn("잘못된 URL 형식:", url);
+		return url; // URL 파싱 실패 시 원본 유지
 	}
+}
 
 //게시기간이 없으면 초기 값 입력
 function makeDate(id){
@@ -141,17 +149,6 @@
 	for (let i = 0; i < linkRows.length; i++) {
 		let linkInput = document.querySelector('input[name="mainPopupLinkList['+i+'].mlink"]');
 		let coordInput = document.querySelector('input[name="mainPopupLinkList['+i+'].coords"]');
-		let sortInput = document.querySelector('input[name="mainPopupLinkList['+i+'].sort"]');
-
-		if (!linkInput.value && !coordInput.value) {
-			if(sortInput.value){
-				let trElement = sortInput.closest("tr");
-				if (trElement) {
-					trElement.remove();
-				}
-			}
-			continue; // 요소가 없으면 건너뛴다.
-		}
 
 		if (linkInput.value.trim() === "") {
 			alert('['+(i + 1)+']번째 링크주소를 입력해 주십시오');
@@ -165,11 +162,6 @@
 			return false;
 		}
 
-		if (sortInput.value.trim() === "") {
-			alert('['+(i + 1)+']번째 순서를 입력해 주십시오');
-			sortInput.focus();
-			return false;
-		}
 	}
 	
 	console.log('isTbodyEmpty("tbody_fiielist") : ', isTbodyEmpty("tbody_fiielist"));
@@ -286,30 +278,77 @@
 	coordTd.innerHTML = '<input type="text" name="mainPopupLinkList['+rowCount+'].coords" maxlength="200" />';
 	
 	// 세 번째 컬럼 (링크 좌표)
-	let sortTh = document.createElement("th");
-	sortTh.innerHTML = '<span>순서</span>';
 	let sortTd = document.createElement("td");
-	sortTd.innerHTML = '<input type="text" name="mainPopupLinkList['+rowCount+'].sort" maxlength="200" value="'+rowCountP+'"  />';
-
+	sortTd.setAttribute("colspan", "2");
+	sortTd.innerHTML = '<input type="button" class="btnType2" value="삭제" onclick="fn_linkDel(\'\')" />';
 	// tr에 추가
 	newRow.appendChild(linkTh);
 	newRow.appendChild(linkTd);
 	newRow.appendChild(coordTh);
 	newRow.appendChild(coordTd);
-	newRow.appendChild(sortTh);
 	newRow.appendChild(sortTd);
 
 	// tbody에 추가
 	tbody.appendChild(newRow);
 }
 
-
+function fn_linkDel(p_linkId) {
+	// event.target을 저장
+	const $target = $(event.target);
+	
+	if (!p_linkId) {
+		
+		$target.closest('tr').remove();
+	}else{
+		
+		var p_popId = $('#popId').val();
+		var p_popLinkId = p_linkId;
+		
+		var sendData = {
+				"popId" : p_popId
+				, "popLinkId" : p_popLinkId
+		}
+ 
+		$.ajax({
+			type: 'POST',
+			url: '<c:url value="/uss/ion/bnr/pop/mainPopupLinkDeleteAjax.do" />',
+			contentType: 'application/json',
+			data: JSON.stringify(sendData),
+			dataType: 'json',
+			success : function(data) {
+				alert(data.msg);
+				console.log('data : ', data);
+				if(data.status == 'OK')
+				{
+					console.log('data OK : ', data);
+					$target.closest('tr').remove();
+				}
+				else
+				{
+					// 실패 처리 로직
+				}
+			},
+			error : function(jqXHR, textStatus, errorThrown) {
+				console.error("AJAX Error:", textStatus, errorThrown);
+				console.error("Response:", jqXHR.responseText);
+			}
+		});
+		
+	} 
+	
+	
+	
+}
 </script>
 <style>
 .date_format{width:91px !important;}
 .del_file_btn{border: none;background-color: transparent;background-image: url(/direct/img/upload_delect_img.png);background-repeat: no-repeat;background-position: center center;vertical-align: middle;margin-top: -4px;margin-right: 15px;}
 .file_size{color: #0388d2;font-weight: bold;}
 .uploaded_obj{width: 100%;}
+.btnType2 {
+	border: 1px solid #456ded;
+	color: #456ded;
+}
 </style>
 </head>
 <body>
@@ -441,30 +480,12 @@
 										<td>
 											<form:input path="mainPopupLinkList[${status.index}].coords" class="mlink" maxlength="200" />
 										</td>
-										<th><span>순서</span></th>
-										<td>
-											<form:input path="mainPopupLinkList[${status.index}].sort" class="mlink" maxlength="200" oninput="this.value = this.value.replace(/[^0-9]/g, '');" />
+										<td colspan="2">
+											<input type="button" class="btnType2" value="삭제" onclick="fn_linkDel('${link.popLinkId }'); return false;">
 										</td>
 									</tr>
 								</c:forEach>
 							</c:when>
-							<c:otherwise>
-								<!-- 값이 없을 때 빈 input 생성 -->
-								<tr>
-									<th><span>[1]링크주소</span></th>
-									<td>
-										<form:input path="mainPopupLinkList[0].mlink" class="mlink" maxlength="200" />
-									</td>
-									<th><span>링크좌표</span></th>
-									<td>
-										<form:input path="mainPopupLinkList[0].coords" maxlength="200" />
-									</td>
-									<th><span>순서</span></th>
-									<td>
-										<form:input path="mainPopupLinkList[0].sort" maxlength="200" value="1" oninput="this.value = this.value.replace(/[^0-9]/g, '');" />
-									</td>
-								</tr>
-							</c:otherwise>
 						</c:choose>
 						</tbody>
 						<tr>
Add a comment
List