Compare commits

...

2 Commits

@ -0,0 +1,208 @@
package go.kr.project.baseData.adsbmtnRt.controller;
import egovframework.constant.MessageConstants;
import egovframework.constant.TilesConstants;
import egovframework.exception.MessageException;
import egovframework.util.ApiResponseUtil;
import egovframework.util.SessionUtil;
import go.kr.project.baseData.adsbmtnRt.model.AdsbmtnRtVO;
import go.kr.project.baseData.adsbmtnRt.service.AdsbmtnRtService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
/**
* packageName : go.kr.project.baseData.adsbmtnRt.controller
* fileName : AdsbmtnRtController
* author :
* date : 2025-09-24
* description : /
* : CRUD API
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2025-09-24
*/
@Controller
@RequestMapping("/baseData/adsbmtnRt")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "가감산율 등록/조회", description = "가감산율 등록/조회 관련 API")
public class AdsbmtnRtController {
/** 가감산율 서비스 */
private final AdsbmtnRtService service;
/**
* .
* @return
*/
@GetMapping("/list.do")
@Operation(summary = "가감산율 목록 화면", description = "가감산율 목록을 조회하는 화면을 제공합니다.")
public String list( Model model ) {
log.debug("가감산율 목록 화면 요청");
return "baseData/adsbmtnRt/list" + TilesConstants.BASE;
}
/**
* AJAX
* (ApiResponse) .
*
* @param paramVO VO
* @return ResponseEntity
* @throws Exception
*/
@Operation(summary = "가감산율 목록 조회 (AJAX)", description = "가감산율 목록을 조회하고 JSON 형식으로 반환합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "가감산율 목록 조회 성공"),
@ApiResponse(responseCode = "400", description = "가감산율 목록 조회 실패"),
@ApiResponse(description = "오류로 인한 실패")
})
@PostMapping("/list.ajax")
public ResponseEntity<?> listAjax(@ModelAttribute AdsbmtnRtVO paramVO) {
// 총 가감산율 수 조회
int totalCount = service.selectListTotalCount(paramVO);
paramVO.setTotalCount(totalCount);
// 페이징 처리를 위한 설정
paramVO.setPagingYn("Y");
// 페이징 처리된 가감산율 목록 조회
List<AdsbmtnRtVO> list = service.selectList(paramVO);
return ApiResponseUtil.successWithGrid(list, paramVO);
}
/**
* / .
* @param mode (C: , U: , V: )
* @param model
* @return /
*/
@GetMapping("/adsbmtnRtPopup.do")
@Operation(summary = "가감산율 등록/수정 팝업", description = "가감산율 등록/수정/조회 팝업 화면을 제공합니다.")
public ModelAndView popup(
@Parameter(description = "가감산율코드") @RequestParam(required = false) String adsbmtnRtCd,
@Parameter(description = "화면 모드 (C:등록, U:수정, V:보기)") @RequestParam String mode,
Model model) {
try {
log.debug("가감산율 팝업 화면 요청 - 모드: {}", mode);
ModelAndView mav = new ModelAndView("baseData/adsbmtnRt/adsbmtnRtRegistPopup" + TilesConstants.POPUP);
mav.addObject("mode", mode);
// 수정/조회 모드인 경우 기존 데이터 조회
if (("U".equals(mode) || "V".equals(mode))) {
AdsbmtnRtVO paramVO = new AdsbmtnRtVO();
paramVO.setAdsbmtnRtCd(adsbmtnRtCd);
AdsbmtnRtVO data = service.selectOne(paramVO);
if (data != null) {
mav.addObject("data", data);
} else {
throw new MessageException("해당 가감산율 정보를 찾을 수 없습니다.");
}
}
return mav;
} catch (Exception e) {
log.error("가감산율 팝업 화면 제공 중 오류 발생", e);
throw new MessageException("팝업 화면을 불러오는 중 오류가 발생했습니다.");
}
}
/**
* .
*
* @param paramVO VO
* @return ResponseEntity
* @throws Exception
*/
@Operation(summary = "가감산율 등록", description = "새로운 가감산율 정보를 등록합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "가감산율 등록 성공"),
@ApiResponse(responseCode = "400", description = "가감산율 등록 실패"),
@ApiResponse(description = "오류로 인한 실패")
})
@PostMapping("/insert.ajax")
public ResponseEntity<?> insert(@ModelAttribute AdsbmtnRtVO paramVO) throws Exception {
// 등록자 정보 설정
paramVO.setRgtr(SessionUtil.getUserId());
int result = service.insert(paramVO);
if (result > 0) {
return ApiResponseUtil.success(MessageConstants.Common.SAVE_SUCCESS);
} else {
return ApiResponseUtil.error(MessageConstants.Common.SAVE_ERROR);
}
}
/**
* .
*
* @param paramVO VO
* @return ResponseEntity
*/
@Operation(summary = "가감산율 수정", description = "기존 가감산율 정보를 수정합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "가감산율 수정 성공"),
@ApiResponse(responseCode = "400", description = "가감산율 수정 실패"),
@ApiResponse(description = "오류로 인한 실패")
})
@PostMapping("/update.ajax")
public ResponseEntity<?> update(@ModelAttribute AdsbmtnRtVO paramVO) {
log.debug("가감산율 정보 수정 요청 - 가감산율코드: {}", paramVO.getAdsbmtnRtCd());
int result = service.update(paramVO);
if (result > 0) {
return ApiResponseUtil.success(MessageConstants.Common.UPDATE_SUCCESS);
} else {
return ApiResponseUtil.error(MessageConstants.Common.UPDATE_ERROR);
}
}
/**
* . ( )
*
* @param adsbmtnRtCd
* @return ResponseEntity
*/
@Operation(summary = "가감산율 삭제", description = "가감산율 정보를 삭제(논리삭제)합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "가감산율 삭제 성공"),
@ApiResponse(responseCode = "400", description = "가감산율 삭제 실패"),
@ApiResponse(description = "오류로 인한 실패")
})
@PostMapping("/delete.ajax")
public ResponseEntity<?> delete(@RequestParam String adsbmtnRtCd) {
log.debug("가감산율 정보 삭제 요청 - 가감산율코드: {}", adsbmtnRtCd);
AdsbmtnRtVO paramVO = new AdsbmtnRtVO();
paramVO.setAdsbmtnRtCd(adsbmtnRtCd);
int result = service.delete(paramVO);
if (result > 0) {
return ApiResponseUtil.success(MessageConstants.Common.DELETE_SUCCESS);
} else {
return ApiResponseUtil.error(MessageConstants.Common.DELETE_ERROR);
}
}
}

@ -0,0 +1,72 @@
package go.kr.project.baseData.adsbmtnRt.mapper;
import go.kr.project.baseData.adsbmtnRt.model.AdsbmtnRtVO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* packageName : go.kr.project.baseData.adsbmtnRt.mapper
* fileName : adsbmtnRtMapper
* author :
* date : 2025-09-24
* description : MyBatis
* : (tb_adsbmtn_rt) CRUD
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2025-09-24
*/
@Mapper
public interface AdsbmtnRtMapper {
/**
* .
* @param vo VO
* @return
*/
List<AdsbmtnRtVO> selectList(AdsbmtnRtVO vo);
/**
* .
* @param vo VO
* @return
*/
int selectListTotalCount(AdsbmtnRtVO vo);
/**
* .
* @param vo PK (adsbmtnRtCd) VO
* @return
*/
AdsbmtnRtVO selectOne(AdsbmtnRtVO vo);
/**
* .
* @param vo VO
* @return
*/
int insert(AdsbmtnRtVO vo);
/**
* .
* @param vo VO
* @return
*/
int update(AdsbmtnRtVO vo);
/**
* . ( )
* @param vo PK (adsbmtnRtCd) VO
* @return
*/
int delete(AdsbmtnRtVO vo);
/**
* PK() .
* @param vo PK (adsbmtnRtCd) VO
* @return (0 , 1 )
*/
int selectDuplicateCheck(AdsbmtnRtVO vo);
}

@ -0,0 +1,79 @@
package go.kr.project.baseData.adsbmtnRt.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import go.kr.project.common.model.PagingVO;
import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* packageName : go.kr.project.baseData.adsbmtnRt.model
* fileName : adsbmtnRtVO
* author :
* date : 2025-09-24
* description : Value Object
* : (tb_adsbmtn_rt) VO .
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2025-09-24
*/
@EqualsAndHashCode(callSuper=true)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class AdsbmtnRtVO extends PagingVO {
// ==================== 기본 테이블 컬럼 ====================
/** 가감산 율 코드 */
private String adsbmtnRtCd;
/** 가감산 율 구분 코드 */
private String adsbmtnRtSeCd;
/** 가감산 율 적용 대상 */
private String adsbmtnRtAplcnTrgt;
/** 가감산 율 적용 대상 상세 */
private String adsbmtnRtAplcnTrgtDtl;
/** 가감산 율 */
private BigDecimal adsbmtnRt;
/** 사용여부 */
private String useYn;
/** 등록 일시 - 테이블은 date 컬럼을 사용하지만 화면 표시용으로 문자열 타입 사용 */
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
private LocalDateTime regDt;
/** 등록자 */
private String rgtr;
/** 수정 일시 */
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
private LocalDateTime mdfcnDt;
/** 수정자 */
private String mdfr;
/** 검색 타입 */
private String schType; // 검색 구분 (1=)
/** 검색 입력 텍스트 */
private String schTypeTxt;
/** 조회조건 : 사용여부 */
private String schUseYn; // N:사용 Y:미사용
/** 행 번호 (그리드 표시용) */
private Integer rowNum;
}

@ -0,0 +1,62 @@
package go.kr.project.baseData.adsbmtnRt.service;
import go.kr.project.baseData.adsbmtnRt.model.AdsbmtnRtVO;
import java.util.List;
/**
* packageName : go.kr.project.baseData.adsbmtnRt.service
* fileName : AdsbmtnService
* author :
* date : 2025-09-24
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2025-09-24
*/
public interface AdsbmtnRtService {
/**
* .
* @param vo VO
* @return
*/
List<AdsbmtnRtVO> selectList(AdsbmtnRtVO vo);
/**
* .
* @param vo VO
* @return
*/
int selectListTotalCount(AdsbmtnRtVO vo);
/**
* .
* @param vo PK (adsbmtnRtCd) VO
* @return
*/
AdsbmtnRtVO selectOne(AdsbmtnRtVO vo);
/**
* .
* @param vo VO
* @return
*/
int insert(AdsbmtnRtVO vo);
/**
* .
* @param vo VO
* @return
*/
int update(AdsbmtnRtVO vo);
/**
* . ( )
* @param vo PK (adsbmtnRtCd) VO
* @return
*/
int delete(AdsbmtnRtVO vo);
}

@ -0,0 +1,146 @@
package go.kr.project.baseData.adsbmtnRt.service.impl;
import egovframework.exception.MessageException;
import egovframework.util.SessionUtil;
import go.kr.project.baseData.adsbmtnRt.mapper.AdsbmtnRtMapper;
import go.kr.project.baseData.adsbmtnRt.model.AdsbmtnRtVO;
import go.kr.project.baseData.adsbmtnRt.service.AdsbmtnRtService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* packageName : go.kr.project.baseData.adsbmtnRt.service.impl
* fileName : AdsbmtnRtServiceImpl
* author :
* date : 2025-09-24
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2025-09-24
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class AdsbmtnRtServiceImpl extends EgovAbstractServiceImpl implements AdsbmtnRtService {
private final AdsbmtnRtMapper mapper;
/**
* .
*
* @param vo VO
* @return
*/
@Override
public List<AdsbmtnRtVO> selectList(AdsbmtnRtVO vo) {
return mapper.selectList(vo);
}
/**
* .
*
* @param vo VO
* @return
*/
@Override
public int selectListTotalCount(AdsbmtnRtVO vo) {
return mapper.selectListTotalCount(vo);
}
/**
* .
*
* @param vo PK (adsbmtnRtCd) VO
* @return
*/
@Override
public AdsbmtnRtVO selectOne(AdsbmtnRtVO vo) {
return mapper.selectOne(vo);
}
/**
* .
*
* @param vo VO
* @return
*/
@Override
public int insert(AdsbmtnRtVO vo) {
log.debug("가감산율 등록 - 가감산율코드: {}", vo.getAdsbmtnRtCd());
// 필수값 검증
//validateRequiredFields(vo);
// PK 중복 체크
int duplicateCount = mapper.selectDuplicateCheck(vo);
if (duplicateCount > 0) {
log.warn("가감산율 등록 실패 - 중복된 PK: 가감산율코드={}", vo.getAdsbmtnRtCd());
throw new MessageException("이미 존재하는 코드입니다. 다른 값을 입력해주세요.");
}
// 등록자 정보 설정 및 등록 수행
vo.setRgtr(SessionUtil.getUserId());
int result = mapper.insert(vo);
log.debug("가감산율 등록 완료 - 등록 건수: {}", result);
return result;
}
/**
* .
*
* @param vo VO
* @return
*/
@Override
public int update(AdsbmtnRtVO vo) {
log.debug("가감산율 수정 - 가감산율코드: {}", vo.getAdsbmtnRtCd());
// 필수값 검증
//validateRequiredFields(vo);
// 수정자 정보 설정 및 수정 수행
vo.setMdfr(SessionUtil.getUserId());
int result = mapper.update(vo);
log.debug("가감산율 수정 완료 - 수정 건수: {}", result);
return result;
}
/**
* . ( )
*
* @param vo PK (adsbmtnRtCd) VO
* @return
*/
@Override
public int delete(AdsbmtnRtVO vo) {
// 삭제자 정보 설정 및 삭제 수행
vo.setMdfr(SessionUtil.getUserId());
return mapper.delete(vo);
}
/**
* .
* @param vo VO
* @throws MessageException
*/
/*private void validateRequiredFields(PstnIdxVO vo) {
if (vo.getRrno() == null || vo.getRrno().trim().isEmpty()) {
log.warn("등록 작업 실패 - 주민번호 미입력");
throw new MessageException("주민번호/법인번호는 필수값입니다.");
}
if (vo.getFlnm() == null || vo.getFlnm().trim().isEmpty()) {
log.warn("등록 작업 실패 - 성명 미입력");
throw new MessageException("성명은 필수값입니다.");
}
if (vo.getAddr() == null || vo.getAddr().trim().isEmpty()) {
log.warn("등록 작업 실패 - 주소 미입력");
throw new MessageException("주소는 필수값입니다.");
}
}*/
}

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="go.kr.project.baseData.adsbmtnRt.mapper.AdsbmtnRtMapper">
<!-- 위치지수 목록 조회 -->
<select id="selectList" parameterType="AdsbmtnRtVO" resultType="AdsbmtnRtVO">
/* AdsbmtnRtMapper.selectList : 가감산율 목록 조회 */
SELECT
ADSBMTN_RT_CD,
ADSBMTN_RT_SE_CD,
ADSBMTN_RT_APLCN_TRGT,
ADSBMTN_RT_APLCN_TRGT_DTL,
ADSBMTN_RT,
REG_DT,
RGTR,
MDFCN_DT,
MDFR,
USE_YN
FROM tb_adsbmtn_rt
WHERE 1=1
<if test='schType == "1" and schTypeTxt != null and schTypeTxt != ""'>
AND ADSBMTN_RT_CD LIKE CONCAT('%', #{schTypeTxt}, '%')
</if>
<if test="schUseYn != null and schUseYn != ''">
AND USE_YN = #{schUseYn}
</if>
<if test='pagingYn != null and pagingYn == "Y"'>
limit #{startIndex}, #{perPage} /* 서버사이드 페이징 처리 */
</if>
</select>
<!-- 가감산율 목록 총 개수 조회 -->
<select id="selectListTotalCount" parameterType="AdsbmtnRtVO" resultType="int">
/* AdsbmtnRtMapper.selectListTotalCount : 가감산율 목록 총 개수 조회 */
SELECT COUNT(*)
FROM tb_adsbmtn_rt
WHERE 1=1
<if test='schType == "1" and schTypeTxt != null and schTypeTxt != ""'>
AND ADSBMTN_RT_CD LIKE CONCAT('%', #{schTypeTxt}, '%')
</if>
<if test="schUseYn != null and schUseYn != ''">
AND USE_YN = #{schUseYn}
</if>
</select>
<!-- 가감산율 단건 조회 -->
<select id="selectOne" parameterType="AdsbmtnRtVO" resultType="AdsbmtnRtVO">
/* AdsbmtnRtMapper.selectOne : 가감산율 조회 */
SELECT
ADSBMTN_RT_CD,
ADSBMTN_RT_SE_CD,
ADSBMTN_RT_APLCN_TRGT,
ADSBMTN_RT_APLCN_TRGT_DTL,
ADSBMTN_RT,
REG_DT,
RGTR,
MDFCN_DT,
MDFR,
USE_YN
FROM tb_adsbmtn_rt
WHERE ADSBMTN_RT_CD= #{adsbmtnRtCd}
</select>
<!--
PK(가감산율 코드) 중복 체크
- 등록 시 동일한 PK가 존재하는지 확인
- 반환값: 0이면 중복 없음, 1이상이면 중복 존재
-->
<select id="selectDuplicateCheck" parameterType="AdsbmtnRtVO" resultType="int">
select count(*) /* 중복 건수 조회 */
from tb_adsbmtn_rt
where ADSBMTN_RT_CD = #{adsbmtnRtCd} /* 가감산율 코드 */
</select>
<!-- 가감산율 등록 -->
<insert id="insert" parameterType="AdsbmtnRtVO">
/* AdsbmtnRtMapper.insert : 가감산율 등록 */
INSERT INTO tb_adsbmtn_rt (
ADSBMTN_RT_CD,
ADSBMTN_RT_SE_CD,
ADSBMTN_RT_APLCN_TRGT,
ADSBMTN_RT_APLCN_TRGT_DTL,
ADSBMTN_RT,
USE_YN,
REG_DT,
RGTR
) VALUES (
#{adsbmtnRtCd},
#{adsbmtnRtSeCd},
#{adsbmtnRtAplcnTrgt},
#{adsbmtnRtAplcnTrgtDtl},
#{adsbmtnRt},
#{useYn}
NOW(),
#{rgtr}
)
</insert>
<!-- 가감산율 수정 -->
<update id="update" parameterType="AdsbmtnRtVO">
/* AdsbmtnRtMapper.update : 가감산율 수정 */
UPDATE tb_adsbmtn_rt
SET ADSBMTN_RT_SE_CD = #{adsbmtnRtSeCd},
ADSBMTN_RT_APLCN_TRGT = #{adsbmtnRtAplcnTrgt},
ADSBMTN_RT_APLCN_TRGT_DTL = #{adsbmtnRtAplcnTrgtDtl},
ADSBMTN_RT = #{adsbmtnRt},
MDFCN_DT = NOW(),
MDFR = #{mdfr},
USE_YN = #{useYn}
WHERE ADSBMTN_RT_CD = #{adsbmtnRtCd}
</update>
<!-- 가감산율 삭제 -->
<update id="delete" parameterType="AdsbmtnRtVO">
/* AdsbmtnRtMapper.delete : 가감산율 삭제 */
UPDATE tb_adsbmtn_rt
SET USE_YN = 'Y',
MDFCN_DT = NOW(),
MDFR = #{mdfr}
WHERE ADSBMTN_RT_CD = #{adsbmtnRtCd}
AND USE_YN = 'N'
</update>
</mapper>

@ -0,0 +1,196 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="dateUtil" uri="http://egovframework.go.kr/functions/date-util" %>
<div class="popup_wrap">
<div class="popup_inner">
<div class="popup_tit">
<h2 class="tit">가감산율 관리</h2>
<a href="#" class="pop-x-btn modalclose"></a>
</div>
<div class="popup_con">
<div class="forms_table_non">
<form id="adsbmtnRtForm" name="adsbmtnRtForm">
<input type="hidden" id="mode" name="mode" value="${param.mode}" />
<table>
<colgroup>
<col style="width: 20%;" />
<col style="width: 30%;" />
<col style="width: 20%;" />
<col style="width: 30%;" />
</colgroup>
<tr>
<th class="th"><span class="required">*</span> 가감산율 코드</th>
<td colspan="3">
<input type="text" id="adsbmtnRtCd" name="adsbmtnRtCd" class="input" value="${data.adsbmtnRtCd}" validation-check="required" maxlength="100" <c:if test="${param.mode eq 'V'}">readonly="readonly"</c:if> />
</td>
</tr>
<tr>
<th class="th"><span class="required">*</span> 가감산율 구분 코드</th>
<td colspan="3">
<input type="text" id="adsbmtnRtSeCd" name="adsbmtnRtSeCd" class="input numericMask" value="${data.adsbmtnRtSeCd}" validation-check="required" maxlength="100" />
</td>
</tr>
<tr>
<th class="th"><span class="required">*</span> 가감산율 적용 대상</th>
<td colspan="3">
<input type="text" id="adsbmtnRtAplcnTrgt" name="adsbmtnRtAplcnTrgt" class="input" value="${data.adsbmtnRtAplcnTrgt}" validation-check="required" maxlength="100" />
</td>
</tr>
<tr>
<th class="th"><span class="required">*</span> 가감산율 적용 대상 상세</th>
<td colspan="3">
<input type="text" id="adsbmtnRtAplcnTrgtDtl" name="adsbmtnRtAplcnTrgtDtl" class="input" value="${data.adsbmtnRtAplcnTrgtDtl}" validation-check="required" maxlength="100" />
</td>
</tr>
<tr>
<th class="th"><span class="required">*</span> 가감산 율</th>
<td colspan="3">
<input type="text" id="adsbmtnRt" name="adsbmtnRt" class="input decimalMask" value="${data.adsbmtnRt}" validation-check="required" maxlength="100" />
</td>
</tr>
<tr>
<th class="th"><span class="required">*</span> 사용 여부</th>
<td colspan="3">
<select id="useYn" name="useYn" class="input" validation-check="required">
<option value="Y" <c:if test="${data.useYn eq 'Y'}">selected</c:if>>사용</option>
<option value="N" <c:if test="${data.useYn eq 'N'}">selected</c:if>>미사용</option>
</select>
</td>
</tr>
</table>
</form>
</div>
</div>
<div class="popup_foot">
<c:choose>
<c:when test="${param.mode eq 'V'}">
<%--<a href="#" id="btnDelete" class="newbtns bg6">삭제</a>--%>
<a href="#" id="btnSave" class="newbtns bg4">수정</a>
</c:when>
<c:otherwise>
<a href="#" id="btnSave" class="newbtns bg1">저장</a>
</c:otherwise>
</c:choose>
<a href="#" class="newbtns bg2 modalclose">닫기</a>
</div>
</div>
</div>
<script>
(function($) {
'use strict';
var adsbmtnRtPopup = {
// 자식 팝업창 참조 저장 배열
childPopups: [],
init: function() {
this.bindEvents();
},
bindEvents: function() {
var self = this;
$("#btnSave").on('click', function() {
self.save();
});
$("#btnDelete").on('click', function() {
self.delete();
});
// 닫기 버튼
$('.modalclose').on('click', function(e) {
e.preventDefault();
self.cancel();
});
},
cancel: function() {
// 공통 함수를 사용하여 자식 팝업창들을 닫고 현재 창 닫기
this.childPopups = closeChildPopupsAndSelf(this.childPopups);
},
save: function() {
if (!this.validate()) return;
var mode = $("#mode").val();
var url = mode === 'C' ? '/baseData/adsbmtnRt/insert.ajax' : '/baseData/adsbmtnRt/update.ajax';
var data = $("#adsbmtnRtForm").serialize();
$.ajax({
url: url,
type: 'POST',
data: data,
success: function(response) {
if (response.success) {
alert(response.message || '처리되었습니다.');
if (window.opener && window.opener.refreshAdsbmtnRtList) {
window.opener.refreshAdsbmtnRtList();
}
window.close();
} else {
alert(response.message || '처리 중 오류가 발생했습니다.');
}
}
});
},
delete: function() {
if (!confirm('정말 삭제하시겠습니까?')) return;
var adsbmtnRtCd = $("#adsbmtnRtCd").val();
$.ajax({
url: '<c:url value="/baseData/adsbmtnRt/delete.ajax"/>',
type: 'POST',
data: {
adsbmtnRtCd: adsbmtnRtCd
},
success: function(response) {
if (response.success) {
alert(response.message || '삭제되었습니다.');
if (window.opener && window.opener.refreshAdsbmtnRtList()) {
window.opener.refreshAdsbmtnRtList();
}
window.close();
} else {
alert(response.message || '삭제 중 오류가 발생했습니다.');
}
}
});
},
/**
* 폼 유효성 검증
* baseData/bldgNewPrcCrtrAmt/popup.jsp 패턴과 동일하게 적용
* @returns {boolean} 유효성 검증 결과
*/
validate: function() {
// 기본 validation-check 속성 기반 검증
var isValid = validateFormByAttributes('adsbmtnRtForm');
/*if (isValid) {
// 건물부속 토지시작 가격 검증
if (!$.trim($('#bldgAnxLandBgngPrc').val())) {
var rgnSeElement = document.getElementById('bldgAnxLandBgngPrc');
errorElementCreate(rgnSeElement, '건물부속 토지시작 가격을 입력하세요.', false);
$('#bldgAnxLandBgngPrc').focus();
return false;
}
}*/
return isValid;
}
};
$(document).ready(function() {
adsbmtnRtPopup.init();
});
})(jQuery);
</script>

@ -0,0 +1,436 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="dateUtil" uri="http://egovframework.go.kr/functions/date-util" %>
<!-- Main body -->
<div class="main_body">
<section id="section8" class="main_bars">
<div class="bgs-main">
<section id="section5">
<div class="sub_title"></div>
<button type="button" id="registerBtn" class="newbtn bg1">등록</button>
<button type="button" id="updaterBtn" class="newbtn bg4">수정</button>
</section>
</div>
</section>
<div class="contants_body">
<div class="gs_b_top">
<ul class="lef">
<li class="th">조회 조건</li>
<li>
<select id="schType" name="schType" class="input">
<option value="1">가감산율코드</option>
<%--<option value="2">기타</option>--%>
</select>
</li>
<li>
<input type="text" id="schTypeTxt" name="schTypeTxt" maxlength="13" class="input" style="width: 120px;" autocomplete="off"/>
</li>
<li class="th">사용 여부</li>
<li>
<select id="schUseYn" name="schUseYn" class="input">
<option value="Y">사용</option>
<option value="N">미사용</option>
</select>
</li>
</ul>
<ul class="rig2">
<li><button type="button" id="search_btn" class="newbtnss bg1">검색</button></li>
<li><button type="button" id="reset_btn" class="newbtnss bg5" style="margin-left: 5px;">초기화</button></li>
</ul>
</div>
<div class="gs_booking">
<div class="row">
<div class="col-sm-12">
<div class="box_column">
<ul class="box_title" style="display: flex; justify-content: space-between; align-items: center;">
<li class="tit">가감산율 목록</li>
<li class="rig">
<span id="totalCount" class="total-count" style="padding-left: 25px;padding-right: 25px;">총 0건</span>
<select id="perPageSelect" class="input" style="width: 112px; ">
<option value="15">페이지당 15</option>
<option value="50">페이지당 50</option>
<option value="100">페이지당 100</option>
</select>
<span class="page_number"><span id="currentPage"></span><span class="bar">/</span><span id="totalPages"></span> Pages</span>
</li>
</ul>
<div class="containers">
<div id="grid"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- /Main body -->
<script type="text/javascript">
/**
* 가감산율 등록/조회 목록 관리 모듈
* 가감산율 목록을 조회하고 관리하는 기능을 제공합니다.
*/
(function(window, $) {
'use strict';
var SEARCH_COND = {};
// 페이징 정보를 저장할 전역 변수
var GRID_PAGINATION_INFO = {
totalCount: 0,
page: 0,
perPage: 0
};
// 검색정보 설정
var setSearchCond = function() {
var schType = $.trim(nvl($("#schType").val(), ""));
var schTypeTxt = $.trim(nvl($("#schTypeTxt").val(), ""));
var schUseYn = $.trim(nvl($("#schUseYn").val(), ""));
SEARCH_COND.schType = schType;
SEARCH_COND.schTypeTxt = schTypeTxt;
SEARCH_COND.schUseYn = schUseYn;
};
/**
* 가감산율 목록 관리 네임스페이스
*/
var AdsbmtnRtList = {
/**
* 선택된 행 정보
*/
selectedRow: null,
/**
* 그리드 관련 객체
*/
grid: {
/**
* 그리드 인스턴스
*/
instance: null,
/**
* 그리드 설정 초기화
* @returns {Object} 그리드 설정 객체
*/
initConfig: function() {
// 데이터 소스 설정
var dataSource = this.createDataSource();
// 현재 선택된 perPage 값 가져오기
var perPage = parseInt($('#perPageSelect').val() || 15, 10);
// 그리드 설정 객체 생성
var gridConfig = new XitTuiGridConfig();
// 기본 설정
gridConfig.setOptDataSource(dataSource); // 데이터소스 연결
gridConfig.setOptGridId('grid'); // 그리드를 출력할 Element ID
gridConfig.setOptGridHeight(470); // 그리드 높이(단위: px)
gridConfig.setOptRowHeight(30); // 그리드 행 높이(단위: px)
gridConfig.setOptRowHeaderType('rowNum'); // 행 첫번째 셀 타입(rowNum: 순번, checkbox: 체크박스, '': 출력 안함)
gridConfig.setOptUseClientSort(false); // 서버사이드 정렬 false
// 페이징 옵션 설정
gridConfig.setOptPageOptions({
useClient: false, // 클라이언트 페이징 여부(false: 서버 페이징)
perPage: perPage // 페이지당 표시 건수
});
gridConfig.setOptColumns(this.getGridColumns());
return gridConfig;
},
/**
* 그리드 컬럼 정의
* @returns {Array} 그리드 컬럼 배열
*/
getGridColumns: function() {
var self = this;
return [
{
header: '가감산율 코드',
name: 'adsbmtnRtCd',
align: 'center',
width: 100,
sortingType: 'desc',
sortable: false
},
{
header: '가감산율 구분 코드',
name: 'adsbmtnRtSeCd',
align: 'center',
width: 100,
sortable: false
},
{
header: '가감산율 적용 대상',
name: 'adsbmtnRtAplcnTrgt',
align: 'center',
width: 250
},
{
header: '가감산율 적용 대상 상세',
name: 'adsbmtnRtAplcnTrgtDtl',
align: 'center',
width: 250
},
{
header: '가감산 율',
name: 'adsbmtnRt',
align: 'right',
width: 100,
formatter: function(props) {
var value = props.value;
return (value == null || value === '') ? '' : Number(value).toFixed(2);
}
//minWidth: 100
},
{
header: '등록일시',
name: 'regDt',
align: 'center',
width: 150
},
{
header: '수정일시',
name: 'mdfcnDt',
align: 'center',
width: 150
},
{
header: '사용여부',
name: 'useYn',
align: 'center',
width: 150,
formatter: function(e) {
return e.value === 'Y' ? '사용' : '미사용';
}
}
];
},
/**
* 데이터 소스 생성
* @returns {Object} 데이터 소스 설정 객체
*/
createDataSource: function() {
return {
api: {
readData: {
url: '<c:url value="/baseData/adsbmtnRt/list.ajax"/>',
method: 'POST',
contentType: 'application/x-www-form-urlencoded',
processData: true
}
},
initialRequest: false, // 초기 데이터 요청 여부
serializer: function(params) {
setSearchCond();
SEARCH_COND.perPage = params.perPage;
SEARCH_COND.page = params.page;
return $.param(SEARCH_COND);
}
};
},
/**
* 그리드 인스턴스 생성
*/
create: function() {
var gridConfig = this.initConfig();
var Grid = tui.Grid;
this.instance = gridConfig.instance(Grid);
// 그리드 테마 설정
Grid.applyTheme('striped');
this.gridBindEvents();
},
/**
* 그리드 이벤트 바인딩
*/
gridBindEvents: function() {
var self = this;
// 데이터 로딩 완료 이벤트 - 라디오 버튼 초기화
this.instance.on('successResponse', function(ev) {
var responseObj = JSON.parse(ev.xhr.response);
if( responseObj ){
$("#currentPage").text(responseObj.data.pagination.page);
$("#totalPages").text(responseObj.data.pagination.totalPages);
var totalCount = responseObj.data.pagination.totalCount;
$("#totalCount").text('총 ' + totalCount.toLocaleString() + '건');
// 페이징 정보를 전역 변수에 저장 (formatter에서 사용하기 위해)
GRID_PAGINATION_INFO.totalCount = responseObj.data.pagination.totalCount;
GRID_PAGINATION_INFO.page = responseObj.data.pagination.page;
GRID_PAGINATION_INFO.perPage = responseObj.data.pagination.perPage;
}
// 라디오 버튼 모두 해제
document.querySelectorAll('input[name="gridRowRadio"]').forEach(function(radio) {
radio.checked = false;
});
// 선택된 행 초기화
AdsbmtnRtList.selectedRow = null;
});
// 행 선택 이벤트
this.instance.on('selection', function(ev) {
if (ev.range && ev.range.row && ev.range.row.length > 0) {
var rowKey = ev.range.row[0];
AdsbmtnRtList.selectedRow = self.instance.getRow(rowKey);
// XitRadioRenderer 동기화 함수 사용
XitRadioRenderer.syncRadioSelection(rowKey, 'gridRowRadio');
}
});
// 행 클릭 이벤트 - 라디오 버튼 즉시 체크를 위해 추가
this.instance.on('click', function(ev) {
if (ev.rowKey !== undefined && ev.rowKey !== null) {
AdsbmtnRtList.selectedRow = self.instance.getRow(ev.rowKey);
// XitRadioRenderer 동기화 함수 사용
XitRadioRenderer.syncRadioSelection(ev.rowKey, 'gridRowRadio');
}
});
// 행 더블클릭 이벤트 - detailView 페이지를 새 탭으로 열기
this.instance.on('dblclick', function(ev) {
var rowKey = ev.rowKey;
var rowData = self.instance.getRow(rowKey);
if (rowData) {
var paramCond = Object.assign({}, SEARCH_COND);
// 새 탭으로 열기 - 컨트롤러가 요구하는 파라미터명으로 전달 (adsbmtnRtCd)
var detailUrl = buildUrlWithParamCondAndMultipleKeys(null, {"mode":"V","adsbmtnRtCd": rowData.adsbmtnRtCd}, "<c:url value="/baseData/adsbmtnRt/adsbmtnRtPopup.do"/>");
openPopup(detailUrl, 800, 500, 'adsbmtnRtView');
}
});
},
},
/**
* 팝업 관련 기능
*/
openRegisterPopup: function() {
openPopup('<c:url value="/baseData/adsbmtnRt/adsbmtnRtPopup.do"/>?mode=C', 600, 400, 'adsbmtnRtView');
},
openViewPopup: function(adsbmtnRtCd) {
var url = '<c:url value="/baseData/adsbmtnRt/adsbmtnRtPopup.do"/>?mode=V&adsbmtnRtCd=' +
encodeURIComponent(adsbmtnRtCd);
openPopup(url, 800, 500, 'adsbmtnRtView');
},
/**
* 목록 새로고침
*/
refreshList: function() {
if (this.grid.instance) {
this.grid.instance.readData(GRID_PAGINATION_INFO.page);
}
},
/**
* 이벤트 핸들러 설정
*/
eventBindEvents: function() {
var self = this;
// 검색 버튼 클릭 이벤트
$("#search_btn").on('click', function() {
self.grid.instance.readData(1);
});
// 초기화 버튼 클릭 이벤트
$("#reset_btn").on('click', function() {
// 모든 검색 조건 초기화
$("#schTypeTxt").val("");
// 라디오 버튼 초기화 (N값 선택)
$("#schUseYn").val("Y");
// 그리드 데이터 새로고침
self.grid.instance.readData(1);
});
// 등록 버튼 클릭 이벤트
$("#registerBtn").on('click', function() {
self.openRegisterPopup();
});
// 수정 버튼 클릭 이벤트
$("#updaterBtn").on('click', function() {
// 선택된 행 확인
if (!self.selectedRow) {
alert('수정할 가감산율을 선택해주세요.');
return;
}
// 선택된 행의 데이터로 팝업 열기
self.openViewPopup(self.selectedRow.adsbmtnRtCd);
});
// 엔터키 검색
$(".gs_b_top input").on('keypress', function(e) {
if (e.which === 13) {
e.preventDefault();
$("#search_btn").trigger('click');
}
});
// perPage 변경 이벤트 추가
$('#perPageSelect').on('change', function() {
var perPage = parseInt($(this).val(), 10);
self.grid.instance.setPerPage(perPage);
// 라디오 버튼 모두 해제
document.querySelectorAll('input[name="gridRowRadio"]').forEach(function(radio) {
radio.checked = false;
});
// 선택된 행 초기화
self.selectedRow = null;
});
},
/**
* 모듈 초기화
*/
init: function() {
// 그리드 생성
this.grid.create();
// 이벤트 핸들러 설정
this.eventBindEvents();
this.grid.instance.readData(${param.page eq null or param.page eq 0 ? 1 : param.page});
}
};
// 팝업 콜백 함수 (팝업에서 호출)
window.refreshAdsbmtnRtList = function() {
AdsbmtnRtList.refreshList();
};
// DOM 준비 완료 시 초기화
$(document).ready(function() {
AdsbmtnRtList.init();
});
})(window, jQuery);
</script>
Loading…
Cancel
Save