feat: thymeleaf 설정

thymeleaf layout 설정
main
Jonguk. Lim 2 years ago
parent 1a1c6ec36f
commit 195c67c0dd

@ -311,4 +311,4 @@ Rest API-dev: <http://211.119.124.9:18090/swagger-ui/index.html>
Rest API-prod: <http://211.119.124.9:8090/swagger-ui/index.html>
배치: <http://211.119.124.9:28090/swagger-ui/index.html>
sneat documentation : <https://demos.themeselection.com/sneat-bootstrap-html-admin-template/documentation/>
sneat documentation : <https://demos.themeselection.com/sneat-bootstrap-html-admin-template/documentation/>

@ -2,7 +2,6 @@ package kr.xit.fims.biz.rt.web;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@ -37,13 +36,20 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequiredArgsConstructor
@Controller
@RequestMapping("/fims/biz/rt")
@RequestMapping(RtCrackdownMgtController.PATH)
public class RtCrackdownMgtController {
static final String PATH = "/fims/biz/rt";
private final IRtCrackdownMgtService service;
private final ICmmFileService fileService;
@RequestMapping({"/list"})
public String list() {
return "/list.html";
}
@RequestMapping(value = "/rtRegltMgtForm")
public void rtRegltMgtForm(){
}

@ -12,6 +12,7 @@ import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
@ -28,46 +29,71 @@ import lombok.extern.slf4j.Slf4j;
@Component
@Aspect
public class LogAopAdvice {
@Value("#{prop['debug.result.log.trace']}")
private boolean isRsltLog;
@Around("execution(public * kr.xit.framework..web.*.*(..))||execution(public * kr.xit.fims..web.*.*(..))")
@Pointcut("execution(public * kr.xit..web.*.*(..))")
public void pointCut() {}
// @Before("pointCut()")
// public void beforeProcess(JoinPoint joinPoint) {
// MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
// Method method = methodSignature.getMethod();
// Object[] objs = joinPoint.getArgs();
// log.info("Start-{} ", methodSignature.getDeclaringTypeName() + "." + method.getName());
// log.info("Request Param : {} ", objs);
// }
//
// @AfterReturning(value = "pointCut()", returning = "returnValue")
// public void afterReturning(JoinPoint joinPoint, Object returnValue) {
// MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
// Method method = methodSignature.getMethod();
// log.info("End-{} ", methodSignature.getDeclaringTypeName() + "." + method.getName());
// log.info("Response Param : {} ", returnValue);
// }
@Around("pointCut()")
public Object aroundProceed(ProceedingJoinPoint pjp) throws Throwable {
String methodName = pjp.getSignature().getName();
// StopWatch sw = new StopWatch(pjp.toShortString());//
//StopWatch sw = new StopWatch();//
// sw.start(methodName);
// Parameter log
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
HttpServletRequest request = servletRequestAttributes.getRequest();
requestLog(request);
Object[] args = pjp.getArgs();
//Object[] args = pjp.getArgs();
requestLog(request);
//TODO 필요시 insert log
//logInsert(methodName, request, paraMap+"");
Object rtnObj = pjp.proceed();
//sw.stop();
if(isRsltLog) {
log.info("//==============================Result====================================");
log.info("{}", rtnObj);
log.info("=========================================================================//");
StringBuilder sb = new StringBuilder();
sb.append("//==============================Result====================================").append("\n");
sb.append("Execution : ").append(pjp.getSignature()).append("\n");
sb.append("return : ").append(rtnObj).append("\n");
sb.append("=========================================================================//");
log.debug(sb.toString());
}else {
// log.info("실행시간 : {}", sw.getTotalTimeSeconds());
}
Object pageObject = RequestContextHolder.getRequestAttributes().getAttribute(PagingConstants.Session.PAGE_INFO.getCode(), RequestAttributes.SCOPE_REQUEST);
if(pageObject != null && rtnObj != null){
Paginator paginator = (Paginator)pageObject;
log.debug("###################################{}",rtnObj.getClass());
log.debug("###################################{}",rtnObj.getClass());
//if(rtnObj instanceof Map){
if(Map.class.isAssignableFrom(rtnObj.getClass())){
Map map = (Map)rtnObj;
map.putAll(getPageInfoMap(paginator));
return map;
//}else if(rtnObj instanceof List){
//}else if(rtnObj instanceof List){
}else if(List.class.isAssignableFrom(rtnObj.getClass())){
Map<String,Object> map = new HashMap<String,Object>();
map.put("rows", rtnObj);
@ -93,7 +119,6 @@ log.debug("###################################{}",rtnObj.getClass());
}
}
//TODO update Log
//update(rtnObj);
// sw.stop();
@ -101,7 +126,7 @@ log.debug("###################################{}",rtnObj.getClass());
return rtnObj;
}
@AfterThrowing(pointcut="execution(public * kr.xit.framework..*.*(..))||execution(public * kr.xit.fims..*.*(..))", throwing="error")
public void afterThrowingProceed(JoinPoint jp, Throwable error) {
error.printStackTrace();
@ -111,28 +136,27 @@ log.debug("###################################{}",rtnObj.getClass());
log.error("@@@(THORWS) getMessage: {}", error.getMessage());
log.error("@@@(THORWS) getCause: {}", error.getCause());
}
private void requestLog(HttpServletRequest request) {
if (log.isDebugEnabled()) {
String method = request.getMethod();
StringBuilder sb = new StringBuilder("\n");
sb.append("//=========================================================================\n");
//sb.append("Ajax Call : " + "XMLHttpRequest".equals(request.getHeader(Globals.AJAX_HEADER))).append("\n");
sb.append("URI : " + request.getRequestURI()).append("\n");
sb.append("URL : " + request.getRequestURL()).append("\n");
sb.append("IP : " + request.getRemoteAddr()).append("\n");
sb.append("Referer URI : " + request.getHeader("referer")).append("\n");
sb.append("Method : " + request.getMethod()).append("\n");
sb.append("User Agent : " + request.getHeader("User-Agent")).append("\n");
sb.append("Session : " + request.getSession().getId()).append("\n");
sb.append("Locale : " + request.getLocale().getCountry()).append("\n");
sb.append("ContentType : " + request.getContentType()).append("\n");
private void requestLog(HttpServletRequest request) {
if (log.isDebugEnabled()) {
String method = request.getMethod();
StringBuilder sb = new StringBuilder("\n");
sb.append("//=========================================================================\n");
//sb.append("Ajax Call : " + "XMLHttpRequest".equals(request.getHeader(Globals.AJAX_HEADER))).append("\n");
sb.append("URI : " + request.getRequestURI()).append("\n");
sb.append("URL : " + request.getRequestURL()).append("\n");
sb.append("IP : " + request.getRemoteAddr()).append("\n");
sb.append("Referer URI : " + request.getHeader("referer")).append("\n");
sb.append("Method : " + request.getMethod()).append("\n");
sb.append("User Agent : " + request.getHeader("User-Agent")).append("\n");
sb.append("Session : " + request.getSession().getId()).append("\n");
sb.append("Locale : " + request.getLocale().getCountry()).append("\n");
sb.append("ContentType : " + request.getContentType()).append("\n");
sb.append("----- Parameters ----- \n");
Enumeration<?> e = request.getParameterNames();
if (e.hasMoreElements()) {
String pName = "";
String pValue = "";
@ -144,14 +168,15 @@ log.debug("###################################{}",rtnObj.getClass());
} else {
sb.append(" is Empty \n");
}
sb.append("=========================================================================//");
log.debug(sb.toString());
sb = null;
sb.append("=========================================================================//");
log.debug(sb.toString());
sb = null;
}
}
private Map<String,Object> getPageInfoMap(Paginator paginator){
Map<String, Object> map = new HashMap<String, Object>();
Map<String, Object> map = new HashMap<String, Object>();
//map.put("recods", paginator.getTotalCount());
map.put("totalPage", paginator.getTotalPages());
map.put("totalCount", paginator.getTotalCount());

@ -0,0 +1,54 @@
package kr.xit.framework.core.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import nz.net.ultraq.thymeleaf.layoutdialect.LayoutDialect;
import nz.net.ultraq.thymeleaf.layoutdialect.decorators.strategies.GroupingStrategy;
@Configuration
public class ThymeleafViewResolverConfig {
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
//templateResolver.setPrefix("classpath:/templates");
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
templateResolver.setCacheable(false);
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine(MessageSource messageSource) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setTemplateEngineMessageSource(messageSource);
templateEngine.addDialect(layoutDialect());
return templateEngine;
}
@Bean
public LayoutDialect layoutDialect() {
return new LayoutDialect(new GroupingStrategy());
}
@Bean
@Autowired
public ViewResolver viewResolver(MessageSource messageSource) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine(messageSource));
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setOrder(1);
return viewResolver;
}
}

@ -1,40 +1,40 @@
package kr.xit.framework.core.resolver.vo;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlRootElement(name = "result")
@XmlType(name="Data", namespace="kr.xit.framework.core.resolver.vo.Data", propOrder={"key", "value"})
public class DataVO {
String key;
String value;
public String getKey() {
return key;
}
@XmlElement(name="key")
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
@XmlElement(name="value")
public void setValue(String value) {
this.value = value;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(getKey());
sb.append("__");
sb.append(getValue());
return sb.toString();
}
}
// package kr.xit.framework.core.resolver.vo;
//
// import javax.xml.bind.annotation.XmlElement;
// import javax.xml.bind.annotation.XmlRootElement;
// import javax.xml.bind.annotation.XmlType;
//
// @XmlRootElement(name = "result")
// @XmlType(name="Data", namespace="kr.xit.framework.core.resolver.vo.Data", propOrder={"key", "value"})
// public class DataVO {
//
// String key;
// String value;
//
// public String getKey() {
// return key;
// }
//
// @XmlElement(name="key")
// public void setKey(String key) {
// this.key = key;
// }
//
// public String getValue() {
// return value;
// }
//
// @XmlElement(name="value")
// public void setValue(String value) {
// this.value = value;
// }
//
// @Override
// public String toString() {
// StringBuffer sb = new StringBuffer();
// sb.append(getKey());
// sb.append("__");
// sb.append(getValue());
// return sb.toString();
// }
// }

@ -1,81 +1,81 @@
package kr.xit.framework.core.resolver.vo;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementRefs;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlRootElement(name="result")
@XmlType(name="Result", namespace="kr.xit.framework.core.resolver.vo.Result", propOrder={"code", "message", "recordset"})
public class Result<T> {
String code = ""; // 작업 결과 코드
String message = ""; // 작업 결과 메시지
List<T> recordset; // 결과셋
public Result(){
}
public String getCode() {
return code;
}
@XmlElement(name="code")
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
@XmlElement(name="message")
public void setMessage(String message) {
this.message = message;
}
@XmlElementWrapper(name="recordset")
@XmlElementRefs({
@XmlElementRef(name="record", type=DataVO.class)
})
public List<T> getRecordset() {
return recordset;
}
public void setRecordset(List<T> recordset) {
this.recordset = recordset;
}
@Override
public String toString() {
StringBuffer result = new StringBuffer();
result.append(code);
result.append("__");
result.append(message);
if(recordset != null){
if(recordset.size() != 0){
StringBuffer record = new StringBuffer();
record.append("_^");
boolean start = true;
for(T item : recordset){
if(start){
start = false;
}else{
record.append("#!");
}
record.append(item);
}
result.append(record.toString());
}
}
return result.toString();
}
}
// package kr.xit.framework.core.resolver.vo;
//
// import java.util.List;
//
// import javax.xml.bind.annotation.XmlElement;
// import javax.xml.bind.annotation.XmlElementRef;
// import javax.xml.bind.annotation.XmlElementRefs;
// import javax.xml.bind.annotation.XmlElementWrapper;
// import javax.xml.bind.annotation.XmlRootElement;
// import javax.xml.bind.annotation.XmlType;
//
// @XmlRootElement(name="result")
// @XmlType(name="Result", namespace="kr.xit.framework.core.resolver.vo.Result", propOrder={"code", "message", "recordset"})
// public class Result<T> {
//
// String code = ""; // 작업 결과 코드
// String message = ""; // 작업 결과 메시지
//
// List<T> recordset; // 결과셋
//
// public Result(){
//
// }
//
// public String getCode() {
// return code;
// }
//
// @XmlElement(name="code")
// public void setCode(String code) {
// this.code = code;
// }
//
// public String getMessage() {
// return message;
// }
//
// @XmlElement(name="message")
// public void setMessage(String message) {
// this.message = message;
// }
//
// @XmlElementWrapper(name="recordset")
// @XmlElementRefs({
// @XmlElementRef(name="record", type=DataVO.class)
// })
// public List<T> getRecordset() {
// return recordset;
// }
//
// public void setRecordset(List<T> recordset) {
// this.recordset = recordset;
// }
//
// @Override
// public String toString() {
// StringBuffer result = new StringBuffer();
// result.append(code);
// result.append("__");
// result.append(message);
//
// if(recordset != null){
// if(recordset.size() != 0){
// StringBuffer record = new StringBuffer();
// record.append("_^");
// boolean start = true;
// for(T item : recordset){
// if(start){
// start = false;
// }else{
// record.append("#!");
// }
// record.append(item);
// }
// result.append(record.toString());
// }
// }
//
// return result.toString();
// }
// }

@ -49,10 +49,10 @@
<bean id="excelView" class="kr.xit.framework.core.resolver.XitExcelViewResolver"/>
<!-- 화면처리용 JSP 파일명의 prefix, suffix 처리에 대한 mvc 설정 -->
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" p:order="1"
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" p:order="0"
p:viewClass="org.springframework.web.servlet.view.tiles3.TilesView"
/>
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" p:order="2"
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" p:order="3"
p:viewClass="org.springframework.web.servlet.view.JstlView"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>
@ -60,6 +60,7 @@
<property name="definitions">
<list>
<value>/WEB-INF/tiles/layout-tiles-defs.xml</value>
<!-- <value>/WEB-INF/freemaker/layout-freemaker-tiles-defs.xml</value>-->
</list>
</property>
<property name="preparerFactoryClass" value="org.springframework.web.servlet.view.tiles3.SpringBeanPreparerFactory"/>
@ -114,11 +115,8 @@
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
</property>
</bean>
<!-- 일반 view 호출에 대한 예외 처리 담당. -->
<bean class="kr.xit.framework.support.exception.resolver.NormalExceptionViewResolver">
<property name="order" value="2"/>
</bean>
<bean class="kr.xit.framework.support.exception.resolver.NormalExceptionViewResolver" p:order="2"/>
<!--
<bean id="marshallingView" class="org.springframework.web.servlet.view.xml.MarshallingView">
@ -144,4 +142,34 @@
</constructor-arg>
</bean>
-->
<!--
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"
p:contentType="text/html; charset=UTF-8"
p:cache="false"
p:prefix=""
p:suffix=".ftl"
p:order="3"
p:exposeSpringMacroHelpers="true"/>
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
<property name="defaultEncoding" value="UTF-8"/>
<property name="freemarkerSettings">
<map>
<entry key="template_update_delay" value="60000"/>
<entry key="auto_flush" value="false"/>
<entry key="default_encoding" value="UTF-8"/>
<entry key="whitespace_stripping" value="true"/>
</map>
</property>
<property name="freemarkerVariables">
<map>
<entry key="xml_escape" value-ref="fmXmlEscape"/>
</map>
</property>
</bean>
<bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>
-->
</beans>

@ -1,10 +0,0 @@
<#ftl encoding="utf-8"/>
<html>
<head>
<title>네이바 프리마카</title>
</head>
<body>
<h1>컨트롤러의 메세지: ${message}</h1>
</body>
</html>

@ -1,386 +0,0 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/jsp/framework/taglibs.jsp"%>
<form id="frmSearch" name="frmSearch" method="get">
<input type="hidden" id="searchGubun" name="searchGubun" value="excel">
<input type="hidden" id="sch_tab_id" name="sch_tab_id" value="0"/>
<div class="search">
<div class="detail_02" style="display: block;">
<fieldset class="frmSearch">
<legend>상세 검색</legend>
<ul class="detailGroup_02">
<li>
<span class="title"><label style="padding-right: 26px;">조회일자 :</label></span>
<select id="sch_date_opt" name="sch_date_opt" class="selectBox">
<option value="1">위반일자</option>
<option value="2">등록일자</option>
</select>
<!-- tag lib sample -->
<code:select id="sch_date_opt1" name="sch_date_opt1" codeId="ENS003" title="시작날자선택" defaultSelect="99" cls="selectBox" alt="selectBox tag"/>
<code:radio id="sch_date_opt2" name="sch_date_opt2" codeId="ENS003" defaultSelect="02" cls="radioBox" alt="radio tag"/>
</li>
<li>
<span class="cal-box">
<input id="sch_date_from" class="inputText cal" name="sch_date_from" type="text" title="시작 날짜 선택">
<button type="button" name="sch_date_from" class="calendar"><span class="ico far fa-calendar-alt">
<%-- <em>달력</em></span> --%>
<em>달력</em></span>
</button>
~
<input id="sch_date_to" class="inputText cal" name="sch_date_to" type="text" title="종료 날짜 선택" placeholder="날짜를 선택하세요">
<button type="button" name="sch_date_to" class="calendar"><span class="ico far fa-calendar-alt">
<%-- <em>달력</em></span> --%>
<em>달력</em></span>
</button>
</span>
</li>
<li style="padding-bottom:10px; padding-left: 40px;">
<span class="title">상태 : </span>
<select id="sch_opt" name="sch_opt" class="selectBox">
<option value="1">차량번호</option>
<option value="2">소유자명</option>
</select>
</li>
<input type="text" id="sch_word" name="sch_word" value="">
<button type="button" class="btnSearch" id="btnSearch" name="btnSearch">검색</button>
</ul>
</fieldset>
</div>
</div>
</form>
<div class="contents">
<div class="topBtnArea">
<ul class="btnList">
<!-- <li> -->
<!-- <button data-show-popup="sampleBox">팝업 버튼 예시</button> -->
<!-- </li> -->
<li>
<button type="button" id="btnExcel"><i class="ico far fa-file-excel"></i> 엑셀</button>
</li>
<!-- <li> -->
<!-- <button id="btnExportPdf"><i class="ico far fa-file-pdf"></i> pdf</button> -->
<!-- </li> -->
<!-- <li> -->
<!-- <button id="btnRegist"><i class="ico fas fa-save"></i> 저장</button> -->
<!-- </li> -->
<!-- <li> -->
<!-- <button id="btnModify"><i class="ico fas fa-edit"></i> 수정</button> -->
<!-- </li> -->
<!-- <li> -->
<!-- <button id="btnRemove"><i class="ico far fa-trash-alt"></i> 삭제</button> -->
<!-- </li> -->
</ul>
<div class="list clearfix" id="totCnt">전체 ㅣ <span>0</span></div>
</div>
<!-- <div class="tableArea"> -->
<!-- //버튼 및 페이지정보 -->
<div class="row">
<div id="tabs">
<ul>
<li><a href="#tabs_0" id="0">전체<span id="t0"></span></a></li>
<li><a href="#tabs_1" id="1">차적미조회<span id="t1"></span></a></li>
<li><a href="#tabs_2" id="2">차적조회<span id="t2"></span></a></li>
</ul>
<div id="tabs_0">
<div id="grid_t0"></div>
</div>
<div id="tabs_1">
<div id="grid_t1"></div>
</div>
<div id="tabs_2">
<div id="grid_t2"></div>
</div>
</div>
<!-- //tabs -->
</div>
<!-- </div> -->
</div>
<!-- 다이얼로그 팝업 예시(sampleBox) -->
<div class="modal-wrap">
<div class="modal-cell">
<!-- cont-box는 ID를 추가하여 여러개의 내용을 넣어주세요.
팝업 오픈시 해당 ID의 팝업만 노출 되도록 만들었습니다. -->
<div class="cont-box" id="sampleBox">
<p>
단순 팝업 입니다.<br>
내용이 많으면 더 쓰셔도 됩니다.
</p>
<div class="btn-box">
<button data-modal-close class="btnDark">확인</button>
<button data-modal-close class="btnDark">취소</button>
</div>
<button data-modal-close class="fas btn-close"></button>
</div>
</div>
</div>
<script type="text/javaScript">
/**************************************************************************
* Global Variable
**************************************************************************/
var callbackSearch = () => fnBiz.search();
const ARR_INSTANCE = [null,null,null];
const ARR_TOTCNT = [0,0,0];
let CUR_TAB_SEQ = 0;
/* *******************************
* Biz function
******************************* */
const fnBiz = {
search: () => {
const sch_date_opt = $('select[name=sch_date_opt]').val();
const sch_date_from = $('#sch_date_from').val();
const sch_date_to = $('#sch_date_to').val();
/*sch_date_from = sch_date_from.replace(/\./g, '');*/
if (sch_date_from != "" || sch_date_to != "") {
if (sch_date_opt == "" || sch_date_from == "" || sch_date_to == "") {
alert("조회기준 또는 일시를 선택하세요");
return false;
}
}
ARR_INSTANCE[CUR_TAB_SEQ].reloadData();
}
,add: function(){
cmmBizAjax('add', {
url: '<c:url value="/adm/send/rqst/mng/proc.do"/>'
,data: $("#frmSearch").serialize()
});
}
,modify: function(){
cmmBizAjax('modify', {
url: '<c:url value="/adm/send/rqst/mng/proc.do"/>'
,data: $("#frmSearch").serialize()
});
}
,remove: function(){
cmmBizAjax('remove', {
url: '<c:url value="/adm/send/rqst/mng/proc.do"/>'
,data: $("#frmSearch").serialize()
});
}
,pagePopup: function(flag, url, params){
let popTitle;
let popOption;
switch (flag) {
case "insert": //등록
popTitle = "";
popOption = {width: 760, height:890}
break;
case "detail": //상세
popTitle = "단속자료 상세보기";
popOption = {width: 1500, height:900}
break;
default:
break;
}
CmmPopup.open(url, params, popOption, popTitle);
}
,clickRegBtn: function(props){
const rowData = props.grid.getRow(props.rowKey);
fnBiz.pagePopup(
'detail',
'<c:url value="/cmm/fimsPopup/fimsTotalPopup.do"/>',
{tilesDef: 'popup', selectedId: rowData.reglt_id}
);
}
,validate: function(flag){
switch(flag){
case 'insert' :
break;
case 'update' :
break;
case 'delete' :
break;
}
return true;
}
};
/**************************************************************************
* event
**************************************************************************/
$(() => {
$("#tabs").on("click", "li", function () {
CUR_TAB_SEQ = parseInt($("#tabs .ui-tabs-active a").attr("id"));
$('#totCnt span').text(ARR_TOTCNT[CUR_TAB_SEQ]);
let tabId = CUR_TAB_SEQ
$('#sch_tab_id').val(tabId);
if(ARR_INSTANCE[tabId]) ARR_INSTANCE[tabId].refreshLayout();
});
$('#btnSearch').on('click', () => {
fnBiz.search();
});
$('#btnExcel').on('click', () => {
//document.frmSearch.searchAt.value = "N";
//document.frmSearch.action = "<c:out value='/adm/send/rqst/mng/excel.do'/>";
//document.frmSearch.submit();
/** 2022.04.22 최정민
* 엑셀저장기능 서버호출에서 그리드 엑셀저장 호출로 변경
*/
TuiGrid.exportExcel(ARR_INSTANCE[CUR_TAB_SEQ], DateUtil.getDate().date, 'rowNum');
}
);
$('#btnExportPdf').on('click', () => {
});
$('#btnRegist').on('click', () => {
});
// 수정 버튼 Event 설정
$('#btnModify').on('click', () => {
});
//삭제 버튼 Event 설정
$('#btnRemove').on('click', () => {
});
})
/* *******************************
* Grid
******************************* */
const initGrid = () => {
const tab0Columns = [ //Grid 컬럼 정보(명칭,매핑 field, 기타옵션 등)
{
header: '차량번호',
name: 'vhcle_no',
minWidth: 120,
sortable: false,
align: 'center'
},
{
header: '소유자명',
name: 'owner_nm',
minWidth: 120,
sortable: false,
align: 'center'
},
{
header: '위반장소',
name: 'violt_place',
width: 120,
sortable: false,
align: 'center'
},
{
header: '위반횟수',
name: 'violt_co',
width: 110,
sortable: false,
align: 'center'
},
{
header: '수납금액',
name: 'rciv_amount',
width: 150,
sortable: false,
align: 'center'
},
{
header: '등록일시',
name: 'regist_dt',
width: 110,
sortable: false,
align: 'center',
formatter({value}) {
return setDateFmt(value); //
}
},
{
header: '최종처리일시',
name: 'last_process_dt',
width: 120,
sortable: false,
align: 'center',
formatter({value}) {
return setDateTimeFmt(value);
}
}
];
//DataSource
let tab0Datasource = {
//initialRequest: false, // 화면 load시 조회 않함 - default
api: {
readData: {
url: '<c:url value="/fims/biz/rt/findRt0200List.do"/>'
,serializer: (params) => fnAddPageInfo(document.frmSearch, params)
}
}
};
const tab0Options = {
el: 'grid_t0',
rowHeaders: ['rowNum'],
columns: tab0Columns,
columnOptions: {
frozenCount: 1 //고정컬럼 갯수
, minWidth: 80 //최소 사이즈
},
};
const tab1Options = $.extend(true, {}, tab0Options, {
el: 'grid_t1'
});
const tab2Options = $.extend(true, {}, tab0Options, {
el: 'grid_t2'
});
const onDblClickEventSet = function (tabSeq) {
ARR_INSTANCE[tabSeq].on('dblclick', function (ev) {
var props = {};
props['rowKey'] = ev.rowKey;
props['grid'] = ev.instance;
fnBiz.clickRegBtn(props);
//Rt0200_main.clickRegBtn(ev.instance.getRow(ev.rowKey), tabSeq);
});
};
ARR_INSTANCE[0] = TuiGrid.of(tab0Options, tab0Datasource, (res) => {
ARR_TOTCNT[0] = res.data.pagination.totalCount;
onDblClickEventSet(0);
});
ARR_INSTANCE[1] = TuiGrid.of(tab1Options, tab0Datasource, (res) => {
ARR_TOTCNT[1] = res.data.pagination.totalCount;
onDblClickEventSet(1);
});
ARR_INSTANCE[2] = TuiGrid.of(tab2Options, tab0Datasource, (res) => {
ARR_TOTCNT[2] = res.data.pagination.totalCount;
onDblClickEventSet(2);
});
}
/**************************************************************************
* initialize
**************************************************************************/
$(document).ready(function() {
$('#sch_date_from').datepicker('setDate', DateUtil.getDateDay(-364).date);
$('#sch_date_to').datepicker('setDate', new Date());
$('#totCnt span').text(ARR_TOTCNT[CUR_TAB_SEQ]);
$("#tabs").tabs({active : CUR_TAB_SEQ});
initGrid();
});
</script>

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{common/layout}">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>Board Error Message</title>
</head>
<body>
<div layout:fragment="contents">
<table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="100%" height="100%" align="center" valign="middle" style="padding-top:150px;"><table border="0" cellspacing="0" cellpadding="0">
<img src="${pageContext.request.contextPath}/resources/framework/images/common/error_monitor.png" alt="에러"/>
</td>
</tr>
<tr>
<td width="100%" height="100%" align="center" valign="middle" style="padding-top:30px;"><table border="0" cellspacing="0" cellpadding="0">
<tr>
<td><span style="font-family:Tahoma; font-weight:bold; color:#000000; line-height:150%; width:440px; height:70px;">오류발생 알림화면(허용되지 않는 요청을 하셨습니다)</span></td>
</tr>
</table></td>
</tr>
</table>
<div class="board-read-container" style="margin-bottom: 20px; background-color: #fff; border: 1px solid; width: 700px;">
<h2>ERROR Page</h2>
<div th:if="${not #strings.isEmpty(message)}">
<h2> [[${message}]] </h2>
</div>
</div>
<div>
<button type="button" onclick="location.href='/board/list'">Back to List</button>
</div>
<script th:inline="javascript">
</script>
</div>
</body>
</html>

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<div th:fragment="cmmBody" class="contents">
<th:block layout:fragment="contents"></th:block>
</div>
</html>

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<th:block th:fragment="cmmFooter">
<h3>
cmmFooter 내용
</h3>
<th:block th:replace="layout/cmm_script::cmmScript"/>
</th:block>
</html>

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<th:block th:fragment="cmmHead">
<!-- head 공통 -->
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11" />
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>cmmHead title</title>
<!-- 공통 css -->
<th:block th:replace="layout/cmm_style::cmmStyle"/>
</th:block>
</html>

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<th:block th:fragment="cmmHeader">
<h3>
cmmHeader 내용
</h3>
</th:block>
</html>

@ -0,0 +1,312 @@
<!DOCTYPE html>
<html lang="ko"
xmlns:th="http://www.thymeleaf.org">
<th:block th:fragment="cmmScript">
<!-- cmm_script.html 공통 load -->
<script defer type="text/javascript" src="/resources/3rd-party/sneat/libs/jquery/jquery.js"></script>
<script defer type="text/javascript" src="/resources/3rd-party/sneat/js/helpers.js"></script>
<script defer type="text/javascript" src="/resources/3rd-party/jquery-ui/1.13.2/jquery-ui.js" ></script>
<script defer type="text/javascript" src="/resources/biz/common/js/jquery.serializeObject.js" ></script>
<script defer type="text/javascript" src="/resources/framework/datepicker/datepicker.js" ></script>
<script defer type="text/javascript" src="/resources/3rd-party/rolling/js/jquery.vticker-min.js"></script>
<!-- [JS/CSS] tui Grid -->
<script defer type="text/javascript" src="/resources/3rd-party/tuiGrid/js/tui-code-snippet.js" ></script>
<script defer type="text/javascript" src="/resources/3rd-party/tui/grid/4.21.5/tui-pagination/tui-pagination.js" ></script>
<script defer type="text/javascript" src="/resources/3rd-party/tuiGrid/js/xlsx.full.min.js" ></script>
<script defer type="text/javascript" src="/resources/3rd-party/tui/grid/4.21.5/tui-grid/tui-grid.js" ></script>
<script defer type="text/javascript" src="/resources/3rd-party/sheetJS/js/xlsx.full.min.js" ></script>
<script defer type="text/javascript" src="/resources/3rd-party/sheetJS/js/FileSaver.min.js" ></script> <!-- [선택]클라이언트 저장기능 필요 시 -->
<!-- [JS] framework -->
<script defer type="text/javascript" src="/resources/biz/common/js/defaultUI.js" ></script>
<script defer type="text/javascript" src="/resources/biz/common/js/fimsApiURL.js"></script>
<script defer type="text/javascript" src="/resources/framework/js/cmm/frwkApiURL.js" ></script>
<script defer type="text/javascript" src="/resources/framework/js/cmm/xit-tui-grid.js" ></script>
<script defer type="text/javascript" src="/resources/framework/js/cmm/XitCmmnUtil.js" ></script>
<script defer type="text/javascript" src="/resources/framework/js/cmm/XitExportUtil.js" ></script>
<script defer type="text/javascript" src="/resources/framework/js/cmm/cmmPopup.js"></script>
<script defer type="text/javascript" src="/resources/framework/js/cmm/cmmDateUtil.js"></script>
<script defer type="text/javascript" src="/resources/framework/js/cmm/cmmUtil.js"></script>
<script defer type="text/javascript" src="/resources/biz/common/js/codeComboData.js"></script>
<!-- <script type="text/javascript" src="/resources/framework/js/cmmn/validator.js"></script> -->
<script defer type="text/javascript" src="/resources/3rd-party/tableExport/js/jspdf.min.js"></script>
<script defer type="text/javascript" src="/resources/3rd-party/tableExport/js/html2canvas.min.js"></script>
<script type="text/javascript">
/* ====================
* 2023.03.22 이범준
* 동적 메뉴 렌더링 함수
====================*/
function MenuRender() {
let _self = this;
_self.template = null;
_self.rootUlAttrDraw = null;
_self.ulAttrDraw = null;
_self.liAttrDraw = null;
_self.liContentDraw = null;
//메뉴 렌더링 설정 초기화
this.init = function(){
switch(_self.template){
case "sneat" :
_self.rootUlAttrDraw = function(element){
element.className = "menu-inner";
};
_self.ulAttrDraw = function(element, menuObj){
element.className = "menu-sub";
};
_self.liAttrDraw = function(element, menuObj){
element.className = "menu-item";
};
_self.liContentDraw = function(element, menuObj){
let a = document.createElement("a");
a.href = "javascript:void(0)";
a.classList.add("menu-link");
if(menuObj.childCnt > 0){ //하위메뉴가 있으면
a.classList.add("menu-toggle");
} else {
a.setAttribute("onclick", "openMenu('"+menuObj.menuSid+"', '"+menuObj.menuName+"', '"+menuObj.menuUrl+"')");
}
// 아이콘
let i = document.createElement("i");
i.classList.add("menu-icon");
i.classList.add("bx");
menuObj.childCnt > 0 ? i.classList.add("bx-folder-plus") : i.classList.add("bx-file");
a.appendChild(i);
let div = document.createElement("div");
let text = document.createTextNode(menuObj.menuName);
div.appendChild(text);
a.appendChild(div);
element.appendChild(a);
};
break;
default :
_self.rootUlAttrDraw = function(element){};
_self.ulAttrDraw = function(element, menuObj){};
_self.liAttrDraw = function(element, menuObj){};
_self.liContentDraw = function(element, menuObj){};
break;
}
};
//메뉴 렌더링
this.menuDraw = function(allMenuList){
let rootUl = document.getElementById("sneatMenuUl");
_self.rootUlAttrDraw(rootUl);
for(let status1 = 0; status1 < allMenuList.length; status1++){
let dep1 = allMenuList[status1];
if(dep1.menuDepth == 1){
let li = document.createElement("li");
_self.liAttrDraw(li,dep1);
_self.liContentDraw(li,dep1);
if(Number(dep1.childCnt) > 0){
let ul = document.createElement("ul");
_self.ulAttrDraw(ul,dep1);
li.appendChild(ul);
for(let status2 = 0; status2 < allMenuList.length; status2++){
let dep2 = allMenuList[status2];
if(dep2.menuDepth == 2 && dep1.menuSid == dep2.parentSid) {
let li = document.createElement("li");
_self.liAttrDraw(li,dep2);
_self.liContentDraw(li,dep2);
if(Number(dep2.childCnt) > 0){
let ul = document.createElement("ul");
_self.ulAttrDraw(ul,dep2);
li.appendChild(ul);
for(let status3 = 0; status3 < allMenuList.length; status3++){
let dep3 = allMenuList[status3];
if(dep3.menuDepth == 3 && dep2.menuSid == dep3.parentSid) {
let li = document.createElement("li");
_self.liAttrDraw(li,dep3);
_self.liContentDraw(li,dep3);
if(Number(dep3.childCnt) > 0){
let ul = document.createElement("ul");
_self.ulAttrDraw(ul,dep3);
li.appendChild(ul);
for(let status4 = 0; status4 < allMenuList.length; status4++) {
let dep4 = allMenuList[status4];
if(dep4.menuDepth == 4 && dep3.menuSid == dep4.parentSid){
let li = document.createElement("li");
_self.liAttrDraw(li,dep4);
_self.liContentDraw(li,dep4);
ul.appendChild(li);
}
}
}
ul.appendChild(li);
}
}
}
ul.appendChild(li);
}
}
}
rootUl.append(li);
}
}
if(_self.template == "sneat"){
const menu1 = document.querySelector("#sneatMenu");
menu1.classList.add("menu");
menu1.classList.add("menu-vertical");
menu1.classList.add("bg-menu-theme");
menu1.classList.add("overflow-hidden");
if (menu1) {
new Menu(menu1 , { closeChildren : false, accordion : false });
}
} else {
}
//스크롤바 추가
new PerfectScrollbar(document.querySelector('.menu-inner'), {
wheelPropagation: false
});
}
}
</script>
<script type="text/javascript">
/* 사용자 수정 화면 오픈 */
function fn_goMyView() {
/* ====================
* 2020.11.20 박민규
* 회원 유형별 페이지 분기
====================*/
//2020.11.20. 주석처리
// var popUrl ='<c:url value="/framework/biz/mng/usr/UserRegMng_view.do"/>';
// var popOption = "width=1100px, height=600px, resizable=no, scrollbars=no, location=no, top=100px, left=100px";
let popUrl ='';
let popOption = '';
let params = {
selectedId: '${sessionScope.XitLoginSession.uniqId}'
//TODO : 개발완료후 이부분 제거
,tilesDef: 'popup'
};
// if('GNR'=='${sessionScope.XitLoginSession.userSe}'){
// popUrl ='<c:url value="/framework/biz/mng/usr/GnrUserRegMng_view.do"/>';
// popOption = {width: 738, height: 630};
// }
// else if('ENT'=='${sessionScope.XitLoginSession.userSe}'){
// popUrl ='<c:url value="/framework/biz/mng/usr/EntUserRegMng_view.do"/>';
// popOption = {width: 738, height: 777};
// }
// else{
popUrl ='<c:url value="/framework/biz/mng/usr/modifyUserPopup.do"/>';
popOption = {width: 1100, height: 600};
params = {uniqId: '${sessionScope.XitLoginSession.uniqId}'}
//}
const target = '정보수정';
$.blockUI({message: '' ,css: {width: '100%', height: '100%'}
//모달창 외부 클릭시 닫기
,onOverlayClick: () => {
$.unblockUI();
popup?.self?.close();
}
});
popup = CmmPopup.open(popUrl, params, popOption, target);
}
</script>
<script defer src="/resources/biz/common/js/jqueryTabs.js"></script>
<script defer type="text/javascript">
/**************************************************************************
* initialize
**************************************************************************/
$(document).ready(() => {
//사용자별 메뉴 목록 조회
cmmAjax({
showSuccessMsg: false
,url: "<c:url value='/framework/biz/cmm/cache/getMenuListByUser.do'/>"
,data: {uniqId: '${sessionScope.XitLoginSession.uniqId}'}
,type: "get"
,success: (data) => {
let mr;
mr = new MenuRender();
mr.template = "sneat";
mr.init();
mr.menuDraw(data.allMenuList);
}
});
$('#ifrTabs').tabs({
activate: function (e, ui){
const selTab = $('#ifrTabs').tabs('option', 'active');
if(selTab !== 0){
}
},
select: function(e, ui){
}
});
openMenu('main', '메인', '/framework/biz/cmm/mainPage2.do');
//공지사항 롤링 Event 처리
XitIncludeBase.noticeRollingEvent();
//공지 목록 조회
cmmAjax({
showSuccessMsg: false
,url: "<c:url value='/framework/biz/cmm/cache/getNoticeList.do'/>"
,data: {uniqId: '${sessionScope.XitLoginSession.uniqId}'}
,type: "get"
,success: (data) => {
if(data.resultList1 != null && data.resultList1.length > 0){
let noticeList = data.resultList1;
for(let i=0; i < noticeList.length;i++){
if(noticeList[i].useAt == "Y"){
let content = "<li class='item d-flex justify-content-between'>";
content += "<a href='/framework/biz/mng/bbs/mngBoardBasicMgtForm.do?bbsId=BBSMSTR_00001'>";
content += "<i class='bx bxs-megaphone'></i>";
content += noticeList[i].nttSj;
content += "</a>";
content += "<span>"+noticeList[i].frstRegisterPnttm+"</span>";
content += "</li>";
$("#rolling_noti ul").append(content);
}
}
}
}
});
});
</script>
</th:block>
</html>

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="ko"
xmlns:th="http://www.thymeleaf.org">
<th:block th:fragment="cmmStyle" th:with="ctx='[[@{/}]]', 3rdparty='resources/3rd-party/sneat'">
<!-- 프레임워크(폰트) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap" >
<!-- 프레임워크(아이콘) -->
<link rel="stylesheet" type="text/css" href="/resources/3rd-party/sneat/fonts/boxicons.css" />
<link rel="stylesheet" type="text/css" href="/resources/3rd-party/sneat/fonts/fontawesome.css" />
<link rel="stylesheet" type="text/css" href="/resources/3rd-party/sneat/css/core.css" />
<link rel="stylesheet" type="text/css" href="/resources/3rd-party/sneat/css/theme-default.css" />
<link rel="shortcut icon" type="image/x-icon" href="/resources/framework/images/common/favicon.ico"/>
<link rel="stylesheet" type="text/css" href="/resources/biz/common/css/index.css"/>
<link rel="stylesheet" type="text/css" href="/resources/framework/css/cmmn/common-style.css"/>
<link rel="stylesheet" type="text/css" href="/resources/3rd-party/jquery-ui/1.13.2/themes/redmond/jquery-ui.css" />
<link rel="stylesheet" type="text/css" href="/resources/framework/datepicker/datepicker.css" />
<link rel="stylesheet" type="text/css" href="/resources/3rd-party/tui/grid/4.21.5/tui-pagination/tui-pagination.css" />
<link rel="stylesheet" type="text/css" href="/resources/3rd-party/tui/grid/4.21.5/tui-grid/tui-grid.css" />
<link rel="stylesheet" type="text/css" href="/resources/framework/css/cmmn/xit-tui-grid.css" />
</th:block>
</html>

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="ko"
xmlns:th="http://www.thymeleaf.org">
<th:block th:fragment="cmmStyle"/>
<!-- 3rdparty='resources/3rd-party/sneat'">-->
<!-- cmm_style.html 공통 css load -->
<!-- js에서 const ctx = $('#ctxPathHolder').attr('data-ctx-path')로 get -->
<!-- <link id="ctxPathHolder" th:data-ctx-path="${#httpServletRequest.getContextPath()}"/>-->
<!-- 프레임워크(폰트) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&display=swap" >
<!-- 프레임워크(아이콘) -->
<!-- <link rel="stylesheet" type="text/css" href="${ctx}/${3rdparty}/fonts/boxicons.css" />-->
<!-- <link rel="stylesheet" type="text/css" href="${ctx}/${3rdparty}/fonts/fontawesome.css" />-->
<!-- <link rel="stylesheet" type="text/css" href="${ctx}/${3rdparty}/css/core.css" />-->
<!-- <link rel="stylesheet" type="text/css" href="${ctx}/${3rdparty}/css/theme-default.css" />-->
</th:block>
</html>

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<!-- <body> start -->
<body>
<!-- <Header> start -->
<Header>
<th:block th:replace="layout/cmm_header::cmmHeader"/>
</Header>
<!-- </Header end -->
<!-- biz contents start -->
<div class="iframe-wrap">
<th:block layout:fragment="contents"/>
</div>
<!-- biz contents start -->
</body>
<!-- <body> start -->
</html>

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<th:block th:replace="layout/cmm_head::cmmHead"/>
</head>
<!-- <body> start -->
<body>
<div class="layoutWrapper hamberger-open">
<!-- <Header> start -->
<Header>
<th:block th:replace="layout/cmm_header::cmmHeader"/>
</Header>
<!-- </Header end -->
<main>
<!-- 업무 화면 iframe tab add -->
<div id="ifrTabs" style="height:100%">
<ul></ul>
</div>
<th:block layout:fragment="contents"/>
</main>
<!-- <footer> start -->
<footer>
<th:block th:replace="layout/cmm_footer::cmmFooter"/>
</footer>
<!-- </footer> end -->
</div>
<div class="modal-wrap">
</div>
</body>
<!-- <body> start -->
</html>

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{/layout/layout_main}">
<!-- layout:decorate="~{/layout/layout_biz}">-->
<th:block layout:fragment="contents">
업무영역~~
</th:block>
</html>
Loading…
Cancel
Save