5011 수정 - 순서삭제, 삭제기능 추가, 링크 파라미터 자동조정

This commit is contained in:
hehihoho3@gmail.com 2025-03-04 16:57:05 +09:00
parent e8ac84e413
commit b87785778e
8 changed files with 175 additions and 98 deletions

View File

@ -35,5 +35,6 @@ public class MainPopupLinkVO extends ComDefaultVO implements Serializable {
private String popId; // 메인존ID
private String mlink; // 링크
private String coords; // 링크좌표
private String popLinkId; // 링크좌표
}

View File

@ -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 interface MainPopupManageService {
public void resetMainPopupSort(MainPopupVO mainPopupVO);
public RestResponse deleteMainPopupLink(MainPopupLinkVO mainPopupLinkVO);
}

View File

@ -4,6 +4,7 @@ import java.util.List;
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 class MainPopupManageDAO extends EgovComAbstractDAO {
}
public void deleteMainPopup(String mazId) {
delete("mainPopup.deleteMainPopup", mazId);
public void deleteMainPopup(String popId) {
delete("mainPopup.deleteMainPopup", popId);
}
@ -55,4 +56,7 @@ public class MainPopupManageDAO extends EgovComAbstractDAO {
update("mainPopup.resetMainPopupSort", mainPopupVO);
}
public void deleteMainPopupLinkInfo(MainPopupLinkVO mainPopupLinkVO) {
delete("mainPopup.deleteMainPopupLinkInfo", mainPopupLinkVO);
}
}

View File

@ -4,12 +4,16 @@ import java.util.List;
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 @@ public class MainPopupManageServiceImpl extends EgovAbstractServiceImpl implemen
@Resource(name = "mainPopupManageDAO")
public MainPopupManageDAO dao;
@Resource(name = "popupManageDAO")
public PopupManageDAO popupDao;
@Resource(name = "egovPopupManageIdGnrService")
private EgovIdGnrService idgenService;
@ -59,6 +65,7 @@ public class MainPopupManageServiceImpl extends EgovAbstractServiceImpl implemen
@Override
public void deleteMainPopup(String id) {
popupDao.deleteMainPopupLinkInfo(id);
dao.deleteMainPopup(id);
}
@ -68,5 +75,15 @@ public class MainPopupManageServiceImpl extends EgovAbstractServiceImpl implemen
}
@Override
public RestResponse deleteMainPopupLink(MainPopupLinkVO mainPopupLinkVO) {
dao.deleteMainPopupLinkInfo(mainPopupLinkVO);
return RestResponse.builder()
.status(HttpStatus.OK) // 200, Series.SUCCESSFUL, "OK"
.msg("삭제 되었습니다.")
.build();
}
}

View File

@ -12,11 +12,15 @@ import javax.servlet.http.HttpSession;
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 egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
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 @@ public class MainPopupController {
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));
}

View File

@ -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*/

View File

@ -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>

View File

@ -31,8 +31,18 @@ $( document ).ready(function(){
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 @@ $( document ).ready(function(){
* @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 @@ function validate(method_parm) {
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 @@ function validate(method_parm) {
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 @@ function addLinkRow() {
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 @@ function addLinkRow() {
<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>