ESB수신용 국민신문고 XML 테스트 파일 생성 기능 추가
parent
0669f5fcd5
commit
e6d20c8bd0
@ -0,0 +1,138 @@
|
||||
package cokr.xit.custom.boot;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import org.springframework.web.servlet.view.BeanNameViewResolver;
|
||||
import org.springframework.web.servlet.view.JstlView;
|
||||
import org.springframework.web.servlet.view.UrlBasedViewResolver;
|
||||
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
|
||||
import org.springframework.web.servlet.view.xml.MappingJackson2XmlView;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
|
||||
|
||||
import cokr.xit.foundation.web.AccessInitializer;
|
||||
|
||||
@EnableWebMvc
|
||||
@Configuration
|
||||
public class MvcConfig1 implements WebMvcConfigurer {
|
||||
protected static String[] URL_PATTERNS = {"/", "/**/*.do"};
|
||||
@Resource(name = "staticResource")
|
||||
private StaticResourceConfig1 staticResource;
|
||||
|
||||
/**AccessInitializer를 반환한다.
|
||||
* @return AccessInitializer
|
||||
*/
|
||||
@Bean
|
||||
public AccessInitializer accessInitializer() {
|
||||
return new AccessInitializer();
|
||||
}
|
||||
|
||||
@Value("${spring.web.resources.static-locations}")
|
||||
private String staticLocations;
|
||||
|
||||
/**정적 파일 자원 접근에 대한 설정을 추가한다.
|
||||
* <ul><li>url: /resources/** </li>
|
||||
* <li>위치: /resources/</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
staticResource.getMappings().forEach((k, v) ->
|
||||
registry
|
||||
.addResourceHandler(k)
|
||||
.addResourceLocations(v)
|
||||
);
|
||||
}
|
||||
|
||||
/**AccessInitializer를 interceptor로 추가한다.
|
||||
*/
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(accessInitializer()).addPathPatterns(URL_PATTERNS);
|
||||
}
|
||||
|
||||
/**BeanNameViewResolver를 반환한다.
|
||||
* @return BeanNameViewResolver
|
||||
*/
|
||||
@Bean
|
||||
public BeanNameViewResolver beanNameViewResolver() {
|
||||
BeanNameViewResolver bean = new BeanNameViewResolver();
|
||||
bean.setOrder(0);
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**UrlBasedViewResolver를 반환한다.
|
||||
* @return UrlBasedViewResolver
|
||||
*/
|
||||
@Bean
|
||||
public UrlBasedViewResolver urlBasedViewResolver() {
|
||||
UrlBasedViewResolver bean = new UrlBasedViewResolver();
|
||||
bean.setViewClass(JstlView.class);
|
||||
bean.setPrefix("/WEB-INF/jsp/");
|
||||
bean.setSuffix(".jsp");
|
||||
bean.setExposeContextBeansAsAttributes(true);
|
||||
bean.setOrder(1);
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
/**MappingJackson2JsonView를 반환한다.
|
||||
* @return MappingJackson2JsonView
|
||||
*/
|
||||
@Bean
|
||||
public MappingJackson2JsonView jsonView() {
|
||||
MappingJackson2JsonView bean = new MappingJackson2JsonView();
|
||||
bean.setContentType("application/json; charset=UTF-8");
|
||||
bean.setObjectMapper(objectMapper);
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**MappingJackson2XmlView를 반환한다.
|
||||
* @return MappingJackson2XmlView
|
||||
*/
|
||||
@Bean
|
||||
public MappingJackson2XmlView xmlView() {
|
||||
XmlMapper xmlMapper = new XmlMapper();
|
||||
xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);
|
||||
xmlMapper.configure(ToXmlGenerator.Feature.WRITE_XML_1_1, true);
|
||||
|
||||
MappingJackson2XmlView bean = new MappingJackson2XmlView();
|
||||
bean.setContentType("application/xml; charset=UTF-8");
|
||||
bean.setObjectMapper(xmlMapper);
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**CommonsMultipartResolver를 반환한다.
|
||||
* @return CommonsMultipartResolver
|
||||
*/
|
||||
@Bean
|
||||
public CommonsMultipartResolver multipartResolver() {
|
||||
CommonsMultipartResolver bean = new CommonsMultipartResolver();
|
||||
int oneGB = 1_073_741_824; // 1GB=1,073,741,824 byte
|
||||
bean.setMaxUploadSize(oneGB);
|
||||
bean.setMaxInMemorySize(oneGB);
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**RequestMappingHandlerMapping을 반환한다.
|
||||
* @return RequestMappingHandlerMapping
|
||||
*/
|
||||
@Bean
|
||||
public RequestMappingHandlerMapping requestHandlers() {
|
||||
return new RequestMappingHandlerMapping();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package cokr.xit.custom.boot;
|
||||
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
||||
|
||||
@SpringBootApplication(exclude = {
|
||||
WebMvcAutoConfiguration.class
|
||||
})
|
||||
@ImportAutoConfiguration({
|
||||
CommonConfig1.class,
|
||||
DatasourceConfig1.class,
|
||||
TransactionConfig1.class,
|
||||
})
|
||||
public class StandAloneApplication1 implements CommandLineRunner {
|
||||
@Override
|
||||
public void run(String... args) throws Exception {}
|
||||
|
||||
protected static void start(Class<?> klass, String... args) {
|
||||
SpringApplication app = new SpringApplication(klass);
|
||||
app.setWebApplicationType(WebApplicationType.NONE);
|
||||
app.run(args);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
package cokr.xit.custom.boot;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import cokr.xit.foundation.Assert;
|
||||
import cokr.xit.foundation.data.StringMap;
|
||||
|
||||
@Configuration("staticResource")
|
||||
public class StaticResourceConfig1 {
|
||||
|
||||
@Value("${spring.mvc.static-path-pattern}")
|
||||
private String staticURLs;
|
||||
@Value("${spring.web.resources.static-locations}")
|
||||
private String staticLocations;
|
||||
|
||||
public Map<String, String> getMappings() {
|
||||
if (Assert.isEmpty(staticURLs) && Assert.isEmpty(staticLocations))
|
||||
return Collections.emptyMap();
|
||||
|
||||
List<String>
|
||||
urls = Arrays.asList(staticURLs.split(",")),
|
||||
locations = Arrays.asList(staticLocations.split(","));
|
||||
if (urls.size() != locations.size())
|
||||
throw new RuntimeException("URLs and locations do not match in size for static resources");
|
||||
|
||||
StringMap<String> resMap = new StringMap<>();
|
||||
for (int i = 0; i < urls.size(); ++i) {
|
||||
String url = urls.get(i),
|
||||
location = locations.get(i);
|
||||
resMap.put(url.trim(), location.trim());
|
||||
}
|
||||
|
||||
return resMap;
|
||||
}
|
||||
|
||||
public String[] getURLs(Predicate<Map.Entry<String, String>> filter) {
|
||||
Predicate<Map.Entry<String, String>> test = filter != null ? filter : entry -> true;
|
||||
List<String> urls = getMappings().entrySet().stream()
|
||||
.filter(test)
|
||||
.map(entry -> entry.getKey())
|
||||
.toList();
|
||||
return urls.toArray(new String[urls.size()]);
|
||||
}
|
||||
|
||||
public String[] getLocations() {
|
||||
List<String> locations = getMappings().values().stream().toList();
|
||||
return locations.toArray(new String[locations.size()]);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
package cokr.xit.custom.boot;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
|
||||
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
|
||||
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
|
||||
import org.springframework.transaction.interceptor.TransactionInterceptor;
|
||||
|
||||
@Configuration
|
||||
@Aspect
|
||||
@EnableTransactionManagement
|
||||
@EnableAspectJAutoProxy(proxyTargetClass = true)
|
||||
public class TransactionConfig1 {
|
||||
@Resource(name = "dataSource")
|
||||
private DataSource dataSource;
|
||||
|
||||
@Bean
|
||||
public DataSourceTransactionManager txManager() {
|
||||
DataSourceTransactionManager bean = new DataSourceTransactionManager();
|
||||
bean.setDataSource(dataSource);
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TransactionInterceptor txAdvice() {
|
||||
RuleBasedTransactionAttribute read = new RuleBasedTransactionAttribute(
|
||||
TransactionDefinition.PROPAGATION_REQUIRED,
|
||||
List.of(new RollbackRuleAttribute(Throwable.class))
|
||||
);
|
||||
read.setReadOnly(true);
|
||||
RuleBasedTransactionAttribute write = new RuleBasedTransactionAttribute(
|
||||
TransactionDefinition.PROPAGATION_REQUIRED,
|
||||
List.of(new RollbackRuleAttribute(Throwable.class))
|
||||
);
|
||||
|
||||
NameMatchTransactionAttributeSource txAttrSrc = new NameMatchTransactionAttributeSource();
|
||||
txAttrSrc.setNameMap(Map.of(
|
||||
"get*", read,
|
||||
"*", write
|
||||
));
|
||||
|
||||
TransactionInterceptor bean = new TransactionInterceptor();
|
||||
bean.setTransactionManager(txManager());
|
||||
bean.setTransactionAttributeSource(txAttrSrc);
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Advisor txAdvisor() {
|
||||
String expression = "execution(* cokr.xit..service.bean.*ServiceBean.*(..))";
|
||||
AspectJExpressionPointcut requiredTx = new AspectJExpressionPointcut();
|
||||
requiredTx.setExpression(expression);
|
||||
|
||||
DefaultPointcutAdvisor bean = new DefaultPointcutAdvisor();
|
||||
bean.setPointcut(requiredTx);
|
||||
bean.setAdvice(txAdvice());
|
||||
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,126 @@
|
||||
package cokr.xit.custom.boot;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.boot.env.YamlPropertySourceLoader;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import cokr.xit.foundation.Assert;
|
||||
|
||||
public class Yml1 {
|
||||
private Map<String, ?> source;
|
||||
|
||||
/**새 Yml을 생성한다.
|
||||
* @param rootName 프로퍼티 소스의 루트 이름
|
||||
* @param path 클래스패스에서 yml 파일의 경로
|
||||
*/
|
||||
public Yml1(String rootName, String path) {
|
||||
load(rootName, path);
|
||||
}
|
||||
|
||||
/**지정하는 yml 파일의 프로퍼티들을 읽어들인다.
|
||||
* @param rootName 프로퍼티 소스의 루트 이름
|
||||
* @param path 클래스패스에서 yml 파일의 경로
|
||||
* @return 현재 Yml
|
||||
*/
|
||||
public Yml1 load(String rootName, String path) {
|
||||
source = null;
|
||||
try {
|
||||
List<PropertySource<?>> sources = new YamlPropertySourceLoader()
|
||||
.load(rootName, new ClassPathResource(path));
|
||||
if (!sources.isEmpty())
|
||||
source = (Map<String, ?>)sources.get(0).getSource();
|
||||
return this;
|
||||
} catch (Exception e) {
|
||||
throw Assert.runtimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**지정하는 프로퍼티(아래 참고)의 값을 반환한다.
|
||||
* @param key 키. 프로퍼티 이름
|
||||
* <pre><code> spring:
|
||||
* application:
|
||||
* name: my-application
|
||||
* </code></pre>
|
||||
* @return 지정하는 키의 프로퍼티 값
|
||||
*/
|
||||
public String getValue(String key) {
|
||||
if (source == null) return "";
|
||||
|
||||
Object obj = source.get(key);
|
||||
return obj != null ? obj.toString() : "";
|
||||
}
|
||||
|
||||
/**지정하는 문자열로 시작하는 프로퍼티(아래 참고) 값들을 반환한다.
|
||||
* <pre><code> list:
|
||||
* - item-0
|
||||
* - item-2
|
||||
* - item-3</code></pre>
|
||||
* @param prefix 프로퍼티 접두어
|
||||
* @return 지정하는 문자열로 시작하는 프로퍼티 값
|
||||
*/
|
||||
public List<String> getValues(String prefix) {
|
||||
if (source == null) return Collections.emptyList();
|
||||
|
||||
return getPrefixed(prefix).stream()
|
||||
.map(entry -> entry.getValue().toString())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<Map.Entry<String, ?>> getPrefixed(String prefix) {
|
||||
return source.entrySet().stream()
|
||||
.filter(entry -> entry.getKey().startsWith(prefix))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**지정하는 문자열로 시작하는 프로퍼티(아래 참고) 값들을 Map으로 반환한다.
|
||||
* <pre><code> parent:
|
||||
* - property-0: value-0
|
||||
* - property-1: value-1
|
||||
* - property-2: value-2</code></pre>
|
||||
* @param prefix 프로퍼티 접두어
|
||||
* @return 지정하는 문자열로 시작하는 프로퍼티로 된 Map
|
||||
*/
|
||||
public Map<String, String> getMap(String prefix) {
|
||||
if (source == null) return Collections.emptyMap();
|
||||
|
||||
LinkedHashMap<String, String> map = new LinkedHashMap<>();
|
||||
getPrefixed(prefix).stream().forEach(entry -> putTo(map, entry));
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private void putTo(LinkedHashMap<String, String> map, Map.Entry<String, ?> entry) {
|
||||
String key = entry.getKey();
|
||||
key = key.substring(key.lastIndexOf(".") + 1);
|
||||
String val = entry.getValue().toString();
|
||||
map.put(key, val);
|
||||
}
|
||||
|
||||
/**지정하는 문자열로 시작하는 프로퍼티들(아래 참고)을 Map 목록으로 반환한다.
|
||||
* <pre><code> parent:
|
||||
* - property-0: value-0.0
|
||||
* property-1: value-0.1
|
||||
* - property-0: value-1.0
|
||||
* property-1: value-1.1</code></pre>
|
||||
* @param prefix 프로퍼티 접두어
|
||||
* @return 지정하는 문자열로 시작하는 프로퍼티들의 Map 목록
|
||||
*/
|
||||
public List<Map<String, String>> getMaps(String prefix) {
|
||||
if (source == null) return Collections.emptyList();
|
||||
|
||||
return getPrefixed(prefix).stream()
|
||||
.map(entry -> {
|
||||
String str = entry.getKey();
|
||||
return str.substring(0, str.lastIndexOf("."));
|
||||
})
|
||||
.collect(Collectors.toSet()).stream()
|
||||
.map(this::getMap)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,505 @@
|
||||
package externalsystem.sinmungo;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import cokr.xit.foundation.AbstractComponent;
|
||||
import jakarta.xml.bind.annotation.XmlAccessType;
|
||||
import jakarta.xml.bind.annotation.XmlAccessorType;
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@XmlRootElement(name = "dmndinfo")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class Epouga extends AbstractComponent {
|
||||
|
||||
@XmlTransient
|
||||
private String sinmungoInnerKey;
|
||||
|
||||
/**인터페이스 키: 필수
|
||||
* PK : number(30) - YYYYMMDDHH24MISSFF+random(9)
|
||||
*/
|
||||
@XmlElement(name = "interface_seq_n")
|
||||
private String interfaceSeqN;
|
||||
|
||||
/**시스템 구분: 필수
|
||||
* char(88)
|
||||
* EC010008 과태료시스템
|
||||
*/
|
||||
@XmlElement(name = "sys_gubun_c")
|
||||
private String sysGubunC;
|
||||
|
||||
/**송신 기관 코드: 필수
|
||||
* varchar2(7)
|
||||
* 1140100 / 신청기관코드 / 신청기관코드
|
||||
* ex)경기도 - 641000
|
||||
*/
|
||||
@XmlElement(name = "anc_code_v")
|
||||
private String ancCodeV;
|
||||
|
||||
/**민원 구분: 필수
|
||||
* char(3)
|
||||
* 140:민원이송(기관코드-신문고) / 180: 답변 / 140: 반송(기관코드-연계기관)
|
||||
*/
|
||||
@XmlElement(name = "peti_gubun_c")
|
||||
private String petiGubunC;
|
||||
|
||||
/**민원 기관 코드: 필수
|
||||
* varchar2(7)
|
||||
* 최초 신청기관코드 그대로 사용(절대변경불가)
|
||||
*/
|
||||
@XmlElement(name = "peti_anc_code_v")
|
||||
private String petiAncCodeV;
|
||||
|
||||
/**민원 신청 번호: 필수
|
||||
* varchar2(16)
|
||||
* 국민신문고에서 생성(국민신문고의 민원 번호), 최초 이송이첩시는 null값 임.
|
||||
* (신문고에서 생성된 데이터가 있을 경우는 넣어줌)
|
||||
*/
|
||||
@XmlElement(name = "peti_no_c")
|
||||
private String petiNoC;
|
||||
|
||||
/**민원 접수 번호: 필수
|
||||
* varchar2(16)
|
||||
* 국민신문고에서 생성(국민신문고의 접수 번호), 최초 이송이첩시는 null값 임.
|
||||
* (신문고에서 생성된 데이터가 있을 경우는 넣어줌)"
|
||||
*/
|
||||
@XmlElement(name = "civil_no_c")
|
||||
private String civilNoC;
|
||||
|
||||
/**민원 신청인 명: 이관 / 반송시 필수
|
||||
* varchar2(128)
|
||||
*/
|
||||
@XmlElement(name = "peter_name_v")
|
||||
private String peterNameV;
|
||||
|
||||
/**민원 신청인 우편번호: 이관 / 반송시 필수
|
||||
* varchar2(7)
|
||||
*/
|
||||
@XmlElement(name = "zip_code_c")
|
||||
private String zipCodeC;
|
||||
|
||||
/**민원 신청인 주소: 이관 / 반송시 필수
|
||||
* varchar2(400)
|
||||
*/
|
||||
@XmlElement(name = "address_v")
|
||||
private String addressV;
|
||||
|
||||
/**민원 신청인 이메일
|
||||
* varchar2(64)
|
||||
*/
|
||||
@XmlElement(name = "email_v")
|
||||
private String emailV;
|
||||
|
||||
/**민원 신청인 핸드폰 번호
|
||||
* varchar2(20)
|
||||
*/
|
||||
@XmlElement(name = "cel_no_v")
|
||||
private String celNoV;
|
||||
|
||||
/**민원 신청인 전화 번호
|
||||
* varchar2(20)
|
||||
*/
|
||||
@XmlElement(name = "tel_no_v")
|
||||
private String telNoV;
|
||||
|
||||
/**민원 신청 제목: 이관 / 반송시 필수
|
||||
* varchar2(500)
|
||||
*/
|
||||
@XmlElement(name = "peti_title_v")
|
||||
private String petiTitleV;
|
||||
|
||||
/**민원 신청 내용: 이관 / 반송시 필수
|
||||
* clob
|
||||
*/
|
||||
@XmlElement(name = "peti_reason_l")
|
||||
private String petiReasonL;
|
||||
|
||||
/**민원 공개 여부: 이관 / 반송시 필수
|
||||
* char(1)
|
||||
* Y = 공개, N = 비공개 (default N)
|
||||
* Y로 수신 시에도 내부적용 시에는 비공개로 적용 요함(개인정보보호지침)
|
||||
* 송신 시는 모두 N으로 송신
|
||||
*/
|
||||
@XmlElement(name = "open_yn_c")
|
||||
private String openYnC;
|
||||
|
||||
/**민원 신청일: 이관 / 반송시 필수
|
||||
* date : YYYYMMDDHH24MISS
|
||||
*/
|
||||
@XmlElement(name = "peti_reg_d")
|
||||
private String petiRegD;
|
||||
|
||||
/**민원 신청 내용 첨부 여부: 이관시 필수
|
||||
* char(1)
|
||||
* Y = 첨부, N = 미첨부(default)
|
||||
*/
|
||||
@XmlElement(name = "peti_reason_attach_yn_c")
|
||||
private String petiReasonAttachYnC;
|
||||
|
||||
/**민원 신청 첨부파일 크기: 이관시 필수
|
||||
* number(10)
|
||||
*/
|
||||
@XmlElement(name = "peti_file_size_n")
|
||||
private String petiFileSizeN;
|
||||
|
||||
//-------------------------------------------------------------
|
||||
/**민원 신청 첨부파일명1
|
||||
* varchar2(2000)
|
||||
*/
|
||||
@XmlElement(name = "peti_file_path1_v")
|
||||
private String petiFilePath1V;
|
||||
|
||||
/**민원 신청 첨부파일명2
|
||||
* varchar2(2000)
|
||||
*/
|
||||
@XmlElement(name = "peti_file_path2_v")
|
||||
private String petiFilePath2V;
|
||||
|
||||
/**민원 신청 첨부파일명3
|
||||
* varchar2(2000)
|
||||
*/
|
||||
@XmlElement(name = "peti_file_path3_v")
|
||||
private String petiFilePath3V;
|
||||
|
||||
/**민원 신청 첨부파일명4
|
||||
* varchar2(2000)
|
||||
*/
|
||||
@XmlElement(name = "peti_file_path4_v")
|
||||
private String petiFilePath4V;
|
||||
|
||||
/**민원 신청 첨부파일명5
|
||||
* varchar2(2000)
|
||||
*/
|
||||
@XmlElement(name = "peti_file_path5_v")
|
||||
private String petiFilePath5V;
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**민원 실 처리 기관 코드: 처리 결과시 필수
|
||||
* varchar2(7)
|
||||
* ex)경기도 6410000
|
||||
*/
|
||||
@XmlElement(name = "pcd_anc_code_v")
|
||||
private String pcdAncCodeV;
|
||||
|
||||
/**민원 처리 기간
|
||||
* number(5)
|
||||
*/
|
||||
@XmlElement(name = "peti_proc_dur_n")
|
||||
private String petiProcDurN;
|
||||
|
||||
/**처리 예정일
|
||||
* date
|
||||
*/
|
||||
@XmlElement(name = "peti_end_d")
|
||||
private String petiEndD;
|
||||
|
||||
/**접수 일자
|
||||
* date
|
||||
*/
|
||||
@XmlElement(name = "anc_reg_d")
|
||||
private String ancRegD;
|
||||
|
||||
/**등록 일자: 필수
|
||||
* date
|
||||
* 반영시에 sysdate(YYYYMMDDHH24MISS)로 생성
|
||||
*/
|
||||
@XmlElement(name = "reg_d")
|
||||
private String regD;
|
||||
|
||||
/**송신 여부: 필수
|
||||
* char(1)
|
||||
* 1:송신 / 2:수신 / 1:송신
|
||||
*/
|
||||
@XmlElement(name = "send_yn_c")
|
||||
private String sendYnC;
|
||||
|
||||
/**송신 일자
|
||||
* date : YYYYMMDDHH24MISS
|
||||
*/
|
||||
@XmlElement(name = "send_d")
|
||||
private String sendD;
|
||||
|
||||
/**적용 일자: 필수
|
||||
* date
|
||||
* interface DB->XML로 적용 시 sysdate(YYYYMMDDHH24MISS)로 생성
|
||||
*/
|
||||
@XmlElement(name = "apply_d")
|
||||
private String applyD;
|
||||
|
||||
/**완료 구분: 필수
|
||||
* char(1)
|
||||
* 적용완료:Y OR N (default:N , 각 기관의 실 민원 DB에 반영 후 Y로 변경)
|
||||
*/
|
||||
@XmlElement(name = "apply_gubun_c")
|
||||
private String applyGubunC;
|
||||
|
||||
/**처리 부서 코드: 결과 처리시 필수
|
||||
* varchar2(7)
|
||||
*/
|
||||
@XmlElement(name = "pcd_dept_v")
|
||||
private String pcdDeptV;
|
||||
|
||||
/**민원 처리 부서명: 결과 처리시 필수
|
||||
* varchar2(50)
|
||||
*/
|
||||
@XmlElement(name = "pcd_dept_nm_v")
|
||||
private String pcdDeptNmV;
|
||||
|
||||
/**민원 처리 담당자 명: 결과 처리시 필수
|
||||
* varchar2(50)
|
||||
*/
|
||||
@XmlElement(name = "duty_id_v")
|
||||
private String dutyIdV;
|
||||
|
||||
/**담당자 이메일: 결과 처리시 필수
|
||||
* varchar2(64)
|
||||
*/
|
||||
@XmlElement(name = "pcd_email_v")
|
||||
private String pcdEmailV;
|
||||
|
||||
/**담당자 전화 번호: 결과 처리시 필수
|
||||
* varchar2(20)
|
||||
*/
|
||||
@XmlElement(name = "pcd_tel_v")
|
||||
private String pcdTelV;
|
||||
|
||||
/**민원 경로 구분
|
||||
*
|
||||
*/
|
||||
@XmlElement(name = "peti_path_gubun_c")
|
||||
private String petiPathGubunC;
|
||||
|
||||
@XmlElement(name = "apndfilinfo")
|
||||
private ApndFileInfo appendFileInfo;
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlRootElement(name="apndfilinfo")
|
||||
public static class ApndFileInfo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**민원 신청 첨부파일명1
|
||||
* varchar2(2000)
|
||||
*/
|
||||
@XmlElement(name = "peti_file_path1_v")
|
||||
private String petiFilePath1V;
|
||||
|
||||
@XmlElement(name = "apndfilcont1")
|
||||
private String apndfilcont1;
|
||||
|
||||
/**민원 신청 첨부파일명2
|
||||
* varchar2(2000)
|
||||
*/
|
||||
@XmlElement(name = "peti_file_path2_v")
|
||||
private String petiFilePath2V;
|
||||
|
||||
@XmlElement(name = "apndfilcont2")
|
||||
private String apndfilcont2;
|
||||
|
||||
/**민원 신청 첨부파일명3
|
||||
* varchar2(2000)
|
||||
*/
|
||||
@XmlElement(name = "peti_file_path3_v")
|
||||
private String petiFilePath3V;
|
||||
|
||||
@XmlElement(name = "apndfilcont3")
|
||||
private String apndfilcont3;
|
||||
|
||||
/**민원 신청 첨부파일명4
|
||||
* varchar2(2000)
|
||||
*/
|
||||
@XmlElement(name = "peti_file_path4_v")
|
||||
private String petiFilePath4V;
|
||||
|
||||
@XmlElement(name = "apndfilcont4")
|
||||
private String apndfilcont4;
|
||||
|
||||
/**민원 신청 첨부파일명5
|
||||
* varchar2(2000)
|
||||
*/
|
||||
@XmlElement(name = "peti_file_path5_v")
|
||||
private String petiFilePath5V;
|
||||
|
||||
@XmlElement(name = "apndfilcont5")
|
||||
private String apndfilcont5;
|
||||
|
||||
@XmlElement(name = "apndfilcount")
|
||||
private String apndfilcount;
|
||||
}
|
||||
|
||||
|
||||
public void fixedValue() {
|
||||
this.sysGubunC = "EC010008";//시스템구분:과태료시스템
|
||||
this.ancCodeV = "1140100"; //송신기관코드:1140100
|
||||
this.petiGubunC = "140"; //민원구분:이송요청
|
||||
this.sendYnC = "Y";
|
||||
this.sendD = "";
|
||||
this.applyD = "";
|
||||
this.applyGubunC = "";
|
||||
this.openYnC = "N";
|
||||
this.sendYnC = "N";
|
||||
this.petiFileSizeN = "0";
|
||||
}
|
||||
|
||||
public void appendCDATA() {
|
||||
this.interfaceSeqN = appendCDATA1(this.interfaceSeqN);
|
||||
this.sysGubunC = appendCDATA1(this.sysGubunC);
|
||||
this.ancCodeV = appendCDATA1(this.ancCodeV);
|
||||
this.petiGubunC = appendCDATA1(this.petiGubunC);
|
||||
this.petiAncCodeV = appendCDATA1(this.petiAncCodeV);
|
||||
this.petiNoC = appendCDATA1(this.petiNoC);
|
||||
this.civilNoC = appendCDATA1(this.civilNoC);
|
||||
this.peterNameV = appendCDATA1(this.peterNameV);
|
||||
this.zipCodeC = appendCDATA1(this.zipCodeC);
|
||||
this.addressV = appendCDATA1(this.addressV);
|
||||
this.emailV = appendCDATA1(this.emailV);
|
||||
this.celNoV = appendCDATA1(this.celNoV);
|
||||
this.telNoV = appendCDATA1(this.telNoV);
|
||||
this.petiTitleV = appendCDATA1(this.petiTitleV);
|
||||
this.petiReasonL = appendCDATA1(this.petiReasonL);
|
||||
this.openYnC = appendCDATA1(this.openYnC);
|
||||
this.petiRegD = appendCDATA1(this.petiRegD);
|
||||
this.petiReasonAttachYnC = appendCDATA1(this.petiReasonAttachYnC);
|
||||
this.petiFileSizeN = appendCDATA1(this.petiFileSizeN);
|
||||
this.petiFilePath1V = appendCDATA1(this.petiFilePath1V);
|
||||
this.petiFilePath2V = appendCDATA1(this.petiFilePath2V);
|
||||
this.petiFilePath3V = appendCDATA1(this.petiFilePath3V);
|
||||
this.petiFilePath4V = appendCDATA1(this.petiFilePath4V);
|
||||
this.petiFilePath5V = appendCDATA1(this.petiFilePath5V);
|
||||
this.regD = appendCDATA1(this.regD);
|
||||
this.sendYnC = appendCDATA1(this.sendYnC);
|
||||
this.sendD = appendCDATA1(this.sendD);
|
||||
this.applyD = appendCDATA1(this.applyD);
|
||||
this.applyGubunC = appendCDATA1(this.applyGubunC);
|
||||
|
||||
this.petiPathGubunC = appendCDATA1(this.petiPathGubunC);
|
||||
this.pcdDeptV = appendCDATA1(this.pcdDeptV);
|
||||
this.pcdDeptNmV = appendCDATA1(this.pcdDeptNmV);
|
||||
this.dutyIdV = appendCDATA1(this.dutyIdV);
|
||||
this.pcdEmailV = appendCDATA1(this.pcdEmailV);
|
||||
this.pcdTelV = appendCDATA1(this.pcdTelV);
|
||||
this.ancRegD = appendCDATA1(this.ancRegD);
|
||||
|
||||
this.pcdAncCodeV = appendCDATA1(this.pcdAncCodeV);
|
||||
this.petiProcDurN = appendCDATA1(this.petiProcDurN);
|
||||
this.petiEndD = appendCDATA1(this.petiEndD);
|
||||
|
||||
if(this.appendFileInfo == null) {
|
||||
this.appendFileInfo = new ApndFileInfo();
|
||||
}
|
||||
if(this.appendFileInfo.apndfilcount == null
|
||||
|| this.appendFileInfo.apndfilcount.equals("")) {
|
||||
this.appendFileInfo.apndfilcount = "0";
|
||||
}
|
||||
this.appendFileInfo.apndfilcount = "<![CDATA["+this.appendFileInfo.apndfilcount+"]]>";
|
||||
|
||||
if(this.appendFileInfo.apndfilcont1 != null) {
|
||||
this.appendFileInfo.apndfilcont1 = appendCDATA1(this.appendFileInfo.apndfilcont1);
|
||||
}
|
||||
if(this.appendFileInfo.apndfilcont2 != null) {
|
||||
this.appendFileInfo.apndfilcont2 = appendCDATA1(this.appendFileInfo.apndfilcont2);
|
||||
}
|
||||
if(this.appendFileInfo.apndfilcont3 != null) {
|
||||
this.appendFileInfo.apndfilcont3 = appendCDATA1(this.appendFileInfo.apndfilcont3);
|
||||
}
|
||||
if(this.appendFileInfo.apndfilcont4 != null) {
|
||||
this.appendFileInfo.apndfilcont4 = appendCDATA1(this.appendFileInfo.apndfilcont4);
|
||||
}
|
||||
if(this.appendFileInfo.apndfilcont5 != null) {
|
||||
this.appendFileInfo.apndfilcont5 = appendCDATA1(this.appendFileInfo.apndfilcont5);
|
||||
}
|
||||
if(this.appendFileInfo.petiFilePath1V != null) {
|
||||
this.appendFileInfo.petiFilePath1V = appendCDATA1(this.appendFileInfo.petiFilePath1V);
|
||||
}
|
||||
if(this.appendFileInfo.petiFilePath2V != null) {
|
||||
this.appendFileInfo.petiFilePath2V = appendCDATA1(this.appendFileInfo.petiFilePath2V);
|
||||
}
|
||||
if(this.appendFileInfo.petiFilePath3V != null) {
|
||||
this.appendFileInfo.petiFilePath3V = appendCDATA1(this.appendFileInfo.petiFilePath3V);
|
||||
}
|
||||
if(this.appendFileInfo.petiFilePath4V != null) {
|
||||
this.appendFileInfo.petiFilePath4V = appendCDATA1(this.appendFileInfo.petiFilePath4V);
|
||||
}
|
||||
if(this.appendFileInfo.petiFilePath5V != null) {
|
||||
this.appendFileInfo.petiFilePath5V = appendCDATA1(this.appendFileInfo.petiFilePath5V);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String appendCDATA1(String str) {
|
||||
if(str == null) {
|
||||
str = "";
|
||||
}
|
||||
|
||||
if(str.equals("")) {
|
||||
return "";
|
||||
} else {
|
||||
return "<![CDATA["+str+"]]>";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void makeAppendFileInfo() {
|
||||
this.appendFileInfo = new ApndFileInfo();
|
||||
int fileCount = 0;
|
||||
if(!ifEmpty(this.petiFilePath1V, () -> "").equals("")) {
|
||||
this.appendFileInfo.petiFilePath1V = FilenameUtils.getName(this.petiFilePath1V);
|
||||
this.appendFileInfo.apndfilcont1 = replaceBase64(this.petiFilePath1V);
|
||||
fileCount++;
|
||||
}
|
||||
|
||||
if(!ifEmpty(this.petiFilePath2V, () -> "").equals("")) {
|
||||
this.appendFileInfo.petiFilePath2V = FilenameUtils.getName(this.petiFilePath2V);
|
||||
this.appendFileInfo.apndfilcont2 = replaceBase64(this.petiFilePath2V);
|
||||
fileCount++;
|
||||
}
|
||||
|
||||
if(!ifEmpty(this.petiFilePath3V, () -> "").equals("")) {
|
||||
this.appendFileInfo.petiFilePath3V = FilenameUtils.getName(this.petiFilePath3V);
|
||||
this.appendFileInfo.apndfilcont3 = replaceBase64(this.petiFilePath3V);
|
||||
fileCount++;
|
||||
}
|
||||
|
||||
if(!ifEmpty(this.petiFilePath4V, () -> "").equals("")) {
|
||||
this.appendFileInfo.petiFilePath4V = FilenameUtils.getName(this.petiFilePath4V);
|
||||
this.appendFileInfo.apndfilcont4 = replaceBase64(this.petiFilePath4V);
|
||||
fileCount++;
|
||||
}
|
||||
|
||||
if(!ifEmpty(this.petiFilePath5V, () -> "").equals("")) {
|
||||
this.appendFileInfo.petiFilePath5V = FilenameUtils.getName(this.petiFilePath5V);
|
||||
this.appendFileInfo.apndfilcont5 = replaceBase64(this.petiFilePath5V);
|
||||
fileCount++;
|
||||
}
|
||||
|
||||
this.appendFileInfo.apndfilcount = Integer.toString(fileCount);
|
||||
|
||||
}
|
||||
|
||||
public String replaceBase64(String filePath) {
|
||||
try {
|
||||
File file = new File(filePath);
|
||||
byte[] encoded = Base64.encodeBase64(FileUtils.readFileToByteArray(file));
|
||||
String result = new String(encoded, "euc-kr");
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("base64오류");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,208 @@
|
||||
package externalsystem.sinmungo;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.glassfish.jaxb.core.marshaller.CharacterEscapeHandler;
|
||||
|
||||
import cokr.xit.foundation.AbstractComponent;
|
||||
import jakarta.xml.bind.JAXBContext;
|
||||
import jakarta.xml.bind.Marshaller;
|
||||
import jakarta.xml.bind.Unmarshaller;
|
||||
|
||||
|
||||
public class JAXB2 extends AbstractComponent {
|
||||
private String charset;
|
||||
private HashMap<Class<?>, Support> xctxes;
|
||||
|
||||
/**새 XML을(를) 생성한다.
|
||||
* @param charset 문자셋 이름. 지정하지 않으면 시스템 기본 문자셋을 사용한다.
|
||||
*/
|
||||
public JAXB2(String charset) {
|
||||
this.charset = ifEmpty(charset, () -> Charset.defaultCharset().name());
|
||||
}
|
||||
|
||||
private Support jaxb(Class<?> klass) throws Exception {
|
||||
if (xctxes == null)
|
||||
xctxes = new HashMap<>();
|
||||
Support support = xctxes.get(klass);
|
||||
if (support == null) {
|
||||
|
||||
JAXBContext xctx = JAXBContext.newInstance(klass);
|
||||
xctxes.put(klass, support = new Support(xctx, charset));
|
||||
}
|
||||
return support;
|
||||
}
|
||||
|
||||
/**xml 문자열을 파싱하여 주어진 클래스의 객체로 변환한다.
|
||||
* @param <T> 클래스 유형
|
||||
* @param str xml 문자열
|
||||
* @param klass 클래스
|
||||
* @return xml 문자열을 변환하여 만든 객체
|
||||
*/
|
||||
public <T> T parse(String str, Class<T> klass) {
|
||||
try {
|
||||
return klass.cast(jaxb(klass).unmarshal(str));
|
||||
} catch (Exception e) {
|
||||
throw runtimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**xml input의 내용을 파싱하여 주어진 클래스의 객체로 변환한다.
|
||||
* @param <T> 클래스 유형
|
||||
* @param input xml input
|
||||
* @param klass 클래스
|
||||
* @return xml input의 내용을 변환하여 만든 객체
|
||||
*/
|
||||
public <T> T parse(InputStream input, Class<T> klass) {
|
||||
try {
|
||||
return klass.cast(jaxb(klass).unmarshal(input));
|
||||
} catch (Exception e) {
|
||||
throw runtimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**xml 파일의 내용을 파싱하여 주어진 클래스의 객체로 변환한다.
|
||||
* @param <T> 클래스 유형
|
||||
* @param file xml 파일
|
||||
* @param klass 클래스
|
||||
* @return xml 파일의 내용을 변환하여 만든 객체
|
||||
*/
|
||||
public <T> T parse(File file, Class<T> klass) {
|
||||
try (FileInputStream input = new FileInputStream(file)) {
|
||||
return parse(input, klass);
|
||||
} catch (Exception e) {
|
||||
throw runtimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**주어진 객체를 xml 문자열로 변환한다.<br />
|
||||
* 이 때 객체는 JAXB(Java Architecture for XML Binding - javax.xml.*)가 제공하는 다음과 같은 어노테이션이 적용되어 있어야 한다.
|
||||
* <pre><code> @XmlRootElement
|
||||
* @XmlType
|
||||
* @XmlElement
|
||||
* @XmlAttribute
|
||||
* @XmlTransient
|
||||
* </code></pre>
|
||||
* @param obj 객체
|
||||
* @return xml 문자열
|
||||
*/
|
||||
public String stringify(Object obj) {
|
||||
try {
|
||||
return jaxb(obj.getClass()).stringify(obj);
|
||||
} catch (Exception e) {
|
||||
throw runtimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**주어진 객체를 xml 포맷으로 out에 저장한다.<br />
|
||||
* 이 때 객체는 JAXB(Java Architecture for XML Binding - javax.xml.*)가 제공하는 다음과 같은 어노테이션이 적용되어 있어야 한다.
|
||||
* <pre><code> @XmlRootElement
|
||||
* @XmlType
|
||||
* @XmlElement
|
||||
* @XmlAttribute
|
||||
* @XmlTransient
|
||||
* </code></pre>
|
||||
* @param obj 객체
|
||||
* @param out OutputStream
|
||||
*/
|
||||
public void write(Object obj, OutputStream out) {
|
||||
try {
|
||||
jaxb(obj.getClass()).marshal(obj, out);
|
||||
} catch (Exception e) {
|
||||
throw runtimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**주어진 객체를 xml 포맷으로 파일에 저장한다.<br />
|
||||
* 이 때 객체는 JAXB(Java Architecture for XML Binding - javax.xml.*)가 제공하는 다음과 같은 어노테이션이 적용되어 있어야 한다.
|
||||
* <pre><code> {@code @XmlRootElement}
|
||||
* {@code @XmlType}
|
||||
* {@code @XmlElement}
|
||||
* {@code @XmlAttribute}
|
||||
* {@code @XmlTransient}</code></pre>
|
||||
* @param obj 객체
|
||||
* @param file 파일
|
||||
*/
|
||||
public void write(Object obj, File file) {
|
||||
try (FileOutputStream out = new FileOutputStream(file)) {
|
||||
write(obj, out);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw runtimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class Support {
|
||||
String charset;
|
||||
JAXBContext xctx;
|
||||
Marshaller marshaller;
|
||||
Unmarshaller unmarshaller;
|
||||
|
||||
Support(JAXBContext xctx, String charset) {
|
||||
this.xctx = xctx;
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
Object unmarshal(String input) throws Exception {
|
||||
if (unmarshaller == null) {
|
||||
unmarshaller = xctx.createUnmarshaller();
|
||||
}
|
||||
try (StringReader reader = new StringReader(input)) {
|
||||
return unmarshaller.unmarshal(reader);
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
Object unmarshal(InputStream input) throws Exception {
|
||||
if (unmarshaller == null) {
|
||||
unmarshaller = xctx.createUnmarshaller();
|
||||
}
|
||||
return unmarshaller.unmarshal(input);
|
||||
}
|
||||
|
||||
Marshaller marshaller() throws Exception {
|
||||
|
||||
if (marshaller == null) {
|
||||
|
||||
marshaller = xctx.createMarshaller();
|
||||
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
|
||||
marshaller.setProperty(Marshaller.JAXB_ENCODING, charset);
|
||||
marshaller.setProperty("org.glassfish.jaxb.characterEscapeHandler", new CharacterEscapeHandler() {
|
||||
|
||||
@Override
|
||||
public void escape(char[] ch, int start, int length, boolean isAttVal, Writer out) throws IOException {
|
||||
out.write(ch, start, length);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
return marshaller;
|
||||
}
|
||||
|
||||
String stringify(Object obj) throws Exception {
|
||||
try (StringWriter writer = new StringWriter()) {
|
||||
marshaller().marshal(obj, writer);
|
||||
|
||||
return writer.toString();
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
void marshal(Object obj, OutputStream out) throws Exception {
|
||||
|
||||
marshaller().marshal(obj, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package externalsystem.sinmungo.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.egovframe.rte.psl.dataaccess.mapper.Mapper;
|
||||
|
||||
import cokr.xit.foundation.component.AbstractMapper;
|
||||
import cokr.xit.foundation.data.DataObject;
|
||||
import externalsystem.sinmungo.Epouga;
|
||||
|
||||
@Mapper("sinmungoMapper")
|
||||
public interface SinmungoMapper extends AbstractMapper {
|
||||
|
||||
Epouga getInfo(String sinmungoInnerKey);
|
||||
|
||||
int baebun(Epouga epouga);
|
||||
|
||||
List<DataObject> selectList();
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package externalsystem.sinmungo.service;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import cokr.xit.foundation.data.DataObject;
|
||||
|
||||
|
||||
|
||||
public interface SinmungoService {
|
||||
|
||||
Map<String,String> makeEpougaXml(String sinmungoInnerKey);
|
||||
|
||||
List<DataObject> getList();
|
||||
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package externalsystem.sinmungo.service.bean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import cokr.xit.foundation.AbstractComponent;
|
||||
import cokr.xit.foundation.data.DataObject;
|
||||
import externalsystem.sinmungo.Epouga;
|
||||
import externalsystem.sinmungo.dao.SinmungoMapper;
|
||||
|
||||
@Component("sinmungoBean")
|
||||
public class SinmungoBean extends AbstractComponent {
|
||||
|
||||
@Resource(name = "sinmungoMapper")
|
||||
private SinmungoMapper sinmungoMapper;
|
||||
|
||||
public Epouga getInfo(String sinmungoInnerKey) {
|
||||
return sinmungoMapper.getInfo(sinmungoInnerKey);
|
||||
}
|
||||
|
||||
public boolean baebun(Epouga epouga) {
|
||||
return sinmungoMapper.baebun(epouga) == 1 ? true : false;
|
||||
}
|
||||
|
||||
public List<DataObject> getList() {
|
||||
return sinmungoMapper.selectList();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,191 @@
|
||||
package externalsystem.sinmungo.service.bean;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import cokr.xit.foundation.component.AbstractServiceBean;
|
||||
import cokr.xit.foundation.data.DataFormat;
|
||||
import cokr.xit.foundation.data.DataObject;
|
||||
import cokr.xit.foundation.util.Random;
|
||||
import externalsystem.sinmungo.Epouga;
|
||||
import externalsystem.sinmungo.JAXB2;
|
||||
import externalsystem.sinmungo.service.SinmungoService;
|
||||
|
||||
@Service("sinmungoService")
|
||||
public class SinmungoServiceBean extends AbstractServiceBean implements SinmungoService {
|
||||
|
||||
@Resource(name = "sinmungoBean")
|
||||
private SinmungoBean sinmungoBean;
|
||||
|
||||
@Override
|
||||
public List<DataObject> getList() {
|
||||
List<DataObject> list = sinmungoBean.getList();
|
||||
|
||||
String videoYn = "N";
|
||||
|
||||
for(DataObject one : list) {
|
||||
int fileCnt = 0;
|
||||
|
||||
if(!ifEmpty(one.string("PETI_FILE_PATH1_V"), ()-> "").equals("")) {
|
||||
fileCnt++;
|
||||
if(videoCheck(one.string("PETI_FILE_PATH1_V"))) {
|
||||
videoYn = "Y";
|
||||
}
|
||||
}
|
||||
if(!ifEmpty(one.string("PETI_FILE_PATH2_V"), ()-> "").equals("")) {
|
||||
fileCnt++;
|
||||
if(videoCheck(one.string("PETI_FILE_PATH2_V"))) {
|
||||
videoYn = "Y";
|
||||
}
|
||||
}
|
||||
if(!ifEmpty(one.string("PETI_FILE_PATH3_V"), ()-> "").equals("")) {
|
||||
fileCnt++;
|
||||
if(videoCheck(one.string("PETI_FILE_PATH3_V"))) {
|
||||
videoYn = "Y";
|
||||
}
|
||||
}
|
||||
if(!ifEmpty(one.string("PETI_FILE_PATH4_V"), ()-> "").equals("")) {
|
||||
fileCnt++;
|
||||
if(videoCheck(one.string("PETI_FILE_PATH4_V"))) {
|
||||
videoYn = "Y";
|
||||
}
|
||||
}
|
||||
if(!ifEmpty(one.string("PETI_FILE_PATH5_V"), ()-> "").equals("")) {
|
||||
fileCnt++;
|
||||
if(videoCheck(one.string("PETI_FILE_PATH5_V"))) {
|
||||
videoYn = "Y";
|
||||
}
|
||||
}
|
||||
|
||||
one.put("FILE_CNT", Integer.toString(fileCnt));
|
||||
one.put("VIDEO_YN", videoYn);
|
||||
}
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String,String> makeEpougaXml(String sinmungoInnerKey) {
|
||||
|
||||
Epouga epouga = sinmungoBean.getInfo(sinmungoInnerKey);
|
||||
|
||||
SimpleDateFormat ff2 = new SimpleDateFormat("yyyyMMddHHmmssFF");
|
||||
SimpleDateFormat date14 = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
|
||||
String cur_ff2 = ff2.format(new Date());
|
||||
String random9 = Random.number(9);
|
||||
String ifKey = cur_ff2 + random9;
|
||||
String xmlFileFolderPath = "files"+File.separator+"thisIsEpouga";
|
||||
File xmlFileFolder = new File(xmlFileFolderPath);
|
||||
if(!xmlFileFolder.exists()) {
|
||||
xmlFileFolder.mkdirs();
|
||||
}
|
||||
|
||||
String random6 = Random.number(6);
|
||||
String cur_date14 = date14.format(new Date());
|
||||
String xmlFileName = cur_date14 + random6 + "$EPOUGA$1140100_" +ifKey + ".xml";
|
||||
|
||||
String xmlFilePath = xmlFileFolderPath + File.separator + xmlFileName;
|
||||
|
||||
File outFile = new File(xmlFilePath);
|
||||
|
||||
JAXB2 xml = new JAXB2("euc-kr");
|
||||
|
||||
epouga.fixedValue();
|
||||
|
||||
epouga.setInterfaceSeqN(ifKey);
|
||||
|
||||
int defaultDuring = 14;
|
||||
epouga.setPetiProcDurN(Integer.toString(defaultDuring));
|
||||
|
||||
epouga.setRegD(yyyy_mm_dd_hh_mm_ss(cur_date14));
|
||||
|
||||
String AncRegD = epouga.getAncRegD();
|
||||
String AncRegD_Ymd = AncRegD.substring(0, 8);
|
||||
|
||||
//*계산값
|
||||
//처리예정일자=접수일자+처리예정일수
|
||||
String petiEndD = addDay(AncRegD_Ymd, defaultDuring);
|
||||
epouga.setPetiEndD(DataFormat.yyyy_mm_dd(petiEndD)+" 23:59:59");
|
||||
//*민원파일첨부여부
|
||||
if(!ifEmpty(epouga.getPetiFilePath1V(),()->"").equals("")
|
||||
|| !ifEmpty(epouga.getPetiFilePath2V(),()->"").equals("")
|
||||
|| !ifEmpty(epouga.getPetiFilePath3V(),()->"").equals("")
|
||||
|| !ifEmpty(epouga.getPetiFilePath4V(),()->"").equals("")
|
||||
|| !ifEmpty(epouga.getPetiFilePath5V(),()->"").equals("")) {
|
||||
epouga.setPetiReasonAttachYnC("Y");
|
||||
} else {
|
||||
epouga.setPetiReasonAttachYnC("N");
|
||||
}
|
||||
|
||||
//*포맷팅
|
||||
String petiRegD = yyyy_mm_dd_hh_mm_ss(epouga.getPetiRegD());
|
||||
epouga.setPetiRegD(petiRegD);
|
||||
//*포맷팅
|
||||
epouga.setAncRegD(yyyy_mm_dd_hh_mm_ss(AncRegD));
|
||||
|
||||
//base64생성
|
||||
epouga.makeAppendFileInfo();
|
||||
|
||||
//CDATA삽입
|
||||
epouga.appendCDATA();
|
||||
|
||||
//파일생성
|
||||
epouga.setSinmungoInnerKey(null);
|
||||
xml.write(epouga, outFile);
|
||||
|
||||
|
||||
Map<String, String> result = Map.of(
|
||||
"filePath", xmlFilePath,
|
||||
"fileName", xmlFileName
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String yyyy_mm_dd_hh_mm_ss(String dateStr) {
|
||||
if (dateStr == null || dateStr.equals("")) return "";
|
||||
|
||||
return dateStr.substring(0, 4) + "-" + dateStr.substring(4, 6) + "-" + dateStr.substring(6, 8)
|
||||
+ " " + dateStr.substring(8, 10) + ":" + dateStr.substring(10, 12) + ":" + dateStr.substring(12, 14);
|
||||
}
|
||||
|
||||
public static String addDay(String yyyyMMdd, int add) {
|
||||
|
||||
SimpleDateFormat yyyyMMddFormat = new SimpleDateFormat("yyyyMMdd");
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
||||
try {
|
||||
Date dt = yyyyMMddFormat.parse(yyyyMMdd);
|
||||
cal.setTime(dt);
|
||||
} catch (Exception e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
cal.add(Calendar.DATE, add);
|
||||
|
||||
return yyyyMMddFormat.format(cal.getTime());
|
||||
}
|
||||
|
||||
public boolean videoCheck(String filePath) {
|
||||
String ext = FilenameUtils.getExtension(filePath).toUpperCase();
|
||||
if(ext.equals("MP4") || ext.equals("OGV") || ext.equals("OGG") || ext.equals("WEBM")
|
||||
|| ext.equals("MKV") || ext.equals("MOV") || ext.equals("AVI") || ext.equals("WMV")
|
||||
) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
package externalsystem.sinmungo.web;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import cokr.xit.foundation.data.DataObject;
|
||||
import cokr.xit.foundation.web.AbstractController;
|
||||
import externalsystem.sinmungo.Epouga;
|
||||
import externalsystem.sinmungo.service.SinmungoService;
|
||||
import externalsystem.sinmungo.service.bean.SinmungoBean;
|
||||
|
||||
@Controller
|
||||
@RequestMapping(name="신문고 업무", value="/sinmungo")
|
||||
public class SinmungoController extends AbstractController {
|
||||
|
||||
@Resource(name = "sinmungoBean")
|
||||
private SinmungoBean sinmungoBean;
|
||||
|
||||
@Resource(name="sinmungoService")
|
||||
private SinmungoService sinmungoService;
|
||||
|
||||
@RequestMapping(name="신문고 담당자 화면", value="/openSinmungoAdmin.do")
|
||||
public ModelAndView openSinmungoAdmin() {
|
||||
ModelAndView mav = new ModelAndView();
|
||||
|
||||
mav.setViewName("sinmungo/admin-main");
|
||||
mav.addObject("pageName", "sinmungoAdmin");
|
||||
return mav;
|
||||
}
|
||||
|
||||
@RequestMapping(name="신문고 자료 목록", value="/list.do")
|
||||
public ModelAndView list() {
|
||||
ModelAndView mav = new ModelAndView("jsonView");
|
||||
|
||||
List<DataObject> list = sinmungoService.getList();
|
||||
mav.addObject("list", list);
|
||||
return mav;
|
||||
}
|
||||
|
||||
@RequestMapping(name="접수 및 배분 정보 저장", value="/saveBaebunInfo.do")
|
||||
public ModelAndView saveBaebunInfo(Epouga epouga) {
|
||||
|
||||
ModelAndView mav = new ModelAndView("jsonView");
|
||||
|
||||
boolean saved = sinmungoBean.baebun(epouga);
|
||||
|
||||
mav.addObject("saved", saved);
|
||||
return mav;
|
||||
}
|
||||
|
||||
@RequestMapping(name="xml(epuoga)생성", value="/sinmungoToXml.do")
|
||||
public ModelAndView sinmungoToXml(String sinmungoInnerKey) {
|
||||
ModelAndView mav = new ModelAndView("jsonView");
|
||||
|
||||
Map<String, String> result = sinmungoService.makeEpougaXml(sinmungoInnerKey);
|
||||
|
||||
|
||||
|
||||
mav.addAllObjects(result);
|
||||
return mav;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,99 @@
|
||||
<?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="externalsystem.sinmungo.dao.SinmungoMapper">
|
||||
|
||||
<select id="getInfo" parameterType="string" resultType="externalsystem.sinmungo.Epouga">
|
||||
SELECT SINMUNGO_INNER_KEY AS sinmungoInnerKey
|
||||
, PETI_NO_C AS petiNoC
|
||||
, PETI_REG_D AS petiRegD
|
||||
, PETI_ANC_CODE_V AS petiAncCodeV
|
||||
, PETI_PATH_GUBUN_C AS petiPathGubunC
|
||||
, PETER_NAME_V AS peterNameV
|
||||
, ZIP_CODE_C AS zipCodeC
|
||||
, ADDRESS_V AS addressV
|
||||
, EMAIL_V AS emailV
|
||||
, CEL_NO_V AS celNoV
|
||||
, TEL_NO_V AS telNoV
|
||||
, PETI_TITLE_V AS petiTitleV
|
||||
, PETI_REASON_L AS petiReasonL
|
||||
, PETI_FILE_PATH1_V AS petiFilePath1V
|
||||
, PETI_FILE_PATH2_V AS petiFilePath2V
|
||||
, PETI_FILE_PATH3_V AS petiFilePath3V
|
||||
, PETI_FILE_PATH4_V AS petiFilePath4V
|
||||
, PETI_FILE_PATH5_V AS petiFilePath5V
|
||||
, CIVIL_NO_C AS civilNoC
|
||||
, ANC_REG_D AS ancRegD
|
||||
, PCD_ANC_CODE_V AS pcdAncCodeV
|
||||
, PCD_DEPT_V AS pcdDeptV
|
||||
, PCD_DEPT_NM_V AS pcdDeptNmV
|
||||
, DUTY_ID_V AS dutyIdV
|
||||
, PCD_EMAIL_V AS pcdEmailV
|
||||
, PCD_TEL_V AS pcdTelV
|
||||
FROM EXTERNAL_TB_SINMUNGO
|
||||
WHERE SINMUNGO_INNER_KEY = #{sinmungoInnerKey}
|
||||
</select>
|
||||
|
||||
<select id="selectList" parameterType="string" resultType="dataObject">
|
||||
SELECT SINMUNGO_INNER_KEY
|
||||
, PETI_NO_C
|
||||
, PETI_REG_D
|
||||
, PETI_ANC_CODE_V
|
||||
, PETI_PATH_GUBUN_C
|
||||
, PETER_NAME_V
|
||||
, ZIP_CODE_C
|
||||
, ADDRESS_V
|
||||
, EMAIL_V
|
||||
, CEL_NO_V
|
||||
, TEL_NO_V
|
||||
, PETI_TITLE_V
|
||||
, PETI_REASON_L
|
||||
, PETI_FILE_PATH1_V
|
||||
, PETI_FILE_PATH2_V
|
||||
, PETI_FILE_PATH3_V
|
||||
, PETI_FILE_PATH4_V
|
||||
, PETI_FILE_PATH5_V
|
||||
, CIVIL_NO_C
|
||||
, ANC_REG_D
|
||||
, PCD_ANC_CODE_V
|
||||
, PCD_DEPT_V
|
||||
, PCD_DEPT_NM_V
|
||||
, DUTY_ID_V
|
||||
, PCD_EMAIL_V
|
||||
, PCD_TEL_V
|
||||
FROM EXTERNAL_TB_SINMUNGO
|
||||
</select>
|
||||
|
||||
<update id="baebun" parameterType="externalsystem.sinmungo.Epouga">
|
||||
<selectKey resultType="string" keyProperty="civilNoC" keyColumn="NEW_NO" order="BEFORE">
|
||||
SELECT
|
||||
CONCAT('2AA-'
|
||||
, TO_CHAR(CURRENT_DATE, 'YYMM')
|
||||
, '-'
|
||||
, LPAD(CAST(IFNULL(MAX(SUBSTRING(CIVIL_NO_C, 10)) + 1, 1) AS INT), 7, '0')
|
||||
) AS NEW_NO
|
||||
FROM EXTERNAL_TB_SINMUNGO
|
||||
WHERE CIVIL_NO_C LIKE CONCAT('2AA-', TO_CHAR(CURRENT_DATE, 'YYMM'), '%')
|
||||
</selectKey>
|
||||
UPDATE EXTERNAL_TB_SINMUNGO
|
||||
SET CIVIL_NO_C = #{civilNoC}
|
||||
, ANC_REG_D = <include refid="utility.now" />
|
||||
, PETI_ANC_CODE_V = #{petiAncCodeV}
|
||||
, PETI_PATH_GUBUN_C = #{petiPathGubunC}
|
||||
, PETER_NAME_V = #{peterNameV}
|
||||
, ZIP_CODE_C = #{zipCodeC}
|
||||
, ADDRESS_V = #{addressV}
|
||||
, EMAIL_V = #{emailV}
|
||||
, CEL_NO_V = #{celNoV}
|
||||
, TEL_NO_V = #{telNoV}
|
||||
, PETI_TITLE_V = #{petiTitleV}
|
||||
, PETI_REASON_L = #{petiReasonL}
|
||||
, PCD_ANC_CODE_V = #{pcdAncCodeV}
|
||||
, PCD_DEPT_V = #{pcdDeptV}
|
||||
, PCD_DEPT_NM_V = #{pcdDeptNmV}
|
||||
, DUTY_ID_V = #{dutyIdV}
|
||||
, PCD_EMAIL_V = #{pcdEmailV}
|
||||
, PCD_TEL_V = #{pcdTelV}
|
||||
WHERE SINMUNGO_INNER_KEY = #{sinmungoInnerKey}
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
@ -0,0 +1,35 @@
|
||||
<?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="utility">
|
||||
|
||||
<!-- For Maria DB -->
|
||||
<sql id="paging-prefix"><if test="fetchSize != null and fetchSize > 0">
|
||||
SELECT QROWS.* FROM (
|
||||
SELECT ROW_NUMBER() OVER(<include refid="utility.sortBy" />) ROW_NUM
|
||||
, COUNT(*) OVER() TOT_CNT, QBODY.*
|
||||
FROM (</if></sql>
|
||||
|
||||
<sql id="paging-suffix"><if test="fetchSize != null and fetchSize > 0"> ) QBODY
|
||||
) QROWS
|
||||
WHERE ROW_NUM BETWEEN ((#{pageNum} - 1) * #{fetchSize}) + 1 AND (#{pageNum} * #{fetchSize})</if></sql>
|
||||
|
||||
<select id="foundRows" resultType="dataobject">/* 전체 결과수 가져오기(utility.foundRows) */
|
||||
SELECT FOUND_ROWS() TOT_CNT</select>
|
||||
|
||||
<sql id="sortBy"><if test="orderBy != null and orderBy != ''">ORDER BY ${orderBy}</if></sql>
|
||||
|
||||
<sql id="orderBy"><if test="fetchSize == null or fetchSize < 1"><include refid="utility.sortBy" /></if></sql>
|
||||
|
||||
<sql id="now">DATE_FORMAT(CURRENT_TIMESTAMP(), '%Y%m%d%H%i%s')</sql>
|
||||
|
||||
<sql id="selectNow">SELECT<include refid="utility.now" />NOW</sql>
|
||||
|
||||
<sql id="today">DATE_FORMAT(CURRENT_DATE, '%Y%m%d')</sql>
|
||||
|
||||
<sql id="selectToday">SELECT<include refid="utility.today" />TODAY</sql>
|
||||
|
||||
<sql id="thisDay">IFNULL(#{thisDay},<include refid="utility.today" />)</sql>
|
||||
|
||||
<sql id="selectThisDay">SELECT<include refid="utility.thisDay" />THIS_DAY</sql>
|
||||
|
||||
</mapper>
|
||||
@ -0,0 +1,240 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" session="false"%>
|
||||
<%@ include file="/WEB-INF/jsp/include/taglib.jsp"%>
|
||||
<form id="frmEdit--${pageName}">
|
||||
<div class="d-flex flex-row justify-content-evenly">
|
||||
<div class="card" style="width:800px;">
|
||||
<h3>민원</h3>
|
||||
|
||||
<div class="card-datatable text-nowrap">
|
||||
<div id="DataTables_Table_0_wrapper--${pageName}" class="dataTables_wrapper dt-bootstrap5 no-footer">
|
||||
<div id="table-responsive--${pageName}" class="table-responsive"
|
||||
style="overflow-x: scroll;height:250px;overflow-y: scroll;">
|
||||
<table id="DataTables_Table_0--${pageName}"
|
||||
class="table-layout-fixed datatables-ajax table table-bordered dataTable no-footer">
|
||||
<thead class="sticky-thead">
|
||||
<tr data-key="{SINMUNGO_INNER_KEY}">
|
||||
<th style="width: 160px;" >신청번호</th>
|
||||
<th style="width: 160px;" >신청일시</th>
|
||||
<th style="width: 180px;" >파일갯수</th>
|
||||
<th style="width: 180px;" >동영상 첨부 여부</th>
|
||||
<th class="cmn dummy-th"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="sinmungoTbody--${pageName}">
|
||||
</tbody>
|
||||
<template id="sinmungoRow--${pageName}">
|
||||
<tr data-key="{SINMUNGO_INNER_KEY}">
|
||||
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-center cmn">{PETI_NO_C}</td>
|
||||
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-center cmn">{PETI_REG_D}</td>
|
||||
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-center cmn">{FILE_CNT}</td>
|
||||
<td onclick="{onclick}" ondblclick="{ondblclick}" class="text-center cmn">{VIDEO_YN}</td>
|
||||
<td class="dummy-td cmn"></td>
|
||||
</tr>
|
||||
</template>
|
||||
<template id="sinmungoNotFound--${pageName}">
|
||||
<tr>
|
||||
<td valign="top" colspan="14" class="dataTables_empty text-center">
|
||||
정보를 찾지 못했습니다.
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card" style="width:800px;">
|
||||
<h3>접수및배분</h3>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">실처리기관코드</label>
|
||||
<input type="text" data-map="PCD_ANC_CODE_V" name="pcdAncCodeV" class="w-px-300" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">처리부서코드</label>
|
||||
<input type="text" data-map="PCD_DEPT_V" name="pcdDeptV" class="w-px-300" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">처리부서명</label>
|
||||
<input type="text" data-map="PCD_DEPT_NM_V" name="pcdDeptNmV" class="w-px-300" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">민원처리담당자명</label>
|
||||
<input type="text" data-map="DUTY_ID_V" name="dutyIdV" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">담당자이메일</label>
|
||||
<input type="text" data-map="PCD_EMAIL_V" name="pcdEmailV" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">담당자전화번호</label>
|
||||
<input type="text" data-map="PCD_TEL_V" name="pcdTelV" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" id="btnSaveBaebunInfo" class="btn btn-primary w-px-100">배분</button>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-center">
|
||||
<div class="card" style="width:1600px;">
|
||||
<h3>민원상세</h3>
|
||||
<input type="text" data-map="SINMUNGO_INNER_KEY" name="sinmungoInnerKey" hidden />
|
||||
<input type="text" data-map="PETI_NO_C" name="petiNoC" hidden />
|
||||
<input type="text" data-map="PETI_REG_D" name="petiRegD" hidden />
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">신고인명</label>
|
||||
<input type="text" data-map="PETER_NAME_V" name="peterNameV" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">신고인우편번호</label>
|
||||
<input type="text" data-map="ZIP_CODE_C" name="zipCodeC" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">신고인주소</label>
|
||||
<input type="text" data-map="ADDRESS_V" name="addressV" class="w-px-500" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">신고인이메일</label>
|
||||
<input type="text" data-map="EMAIL_V" name="emailV" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">신고인휴대폰</label>
|
||||
<input type="text" data-map="CEL_NO_V" name="celNoV" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">신고인유선전화</label>
|
||||
<input type="text" data-map="TEL_NO_V" name="telNoV" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">민원최초신청기관코드</label>
|
||||
<input type="text" data-map="PETI_ANC_CODE_V" name="petiAncCodeV" list="firstReqInstList" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">신청경로코드</label>
|
||||
<input type="text" data-map="PETI_PATH_GUBUN_C" name="petiPathGubunC" list="reqPathList" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="bg-lighter col-form-label w-px-150">민원제목</label>
|
||||
<input type="text" data-map="PETI_TITLE_V" name="petiTitleV" class="w-px-500" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<textarea data-map="PETI_REASON_L" name="petiReasonL" cols="100%" rows="15">
|
||||
</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<datalist id="firstReqInstList">
|
||||
<option value="1741000">행정안전부</option>
|
||||
<option value="1140100">국민신문고</option>
|
||||
<option value="1320000">경찰청</option>
|
||||
</datalist>
|
||||
<datalist id="reqPathList">
|
||||
<option value="00020029">안전신문고</option>
|
||||
<option value="00020013">국민신문고모바일앱</option>
|
||||
</datalist>
|
||||
<div id="tempArea" hidden></div>
|
||||
<script>
|
||||
|
||||
var sinmungoDataset = new Dataset({
|
||||
keymapper : info => info ? info.SINMUNGO_INNER_KEY : ""
|
||||
});
|
||||
var sinmungoFields = new FormFields("#frmEdit--${pageName}");
|
||||
|
||||
$("#sinmungoAdminDialog").find(".modal-footer").hide();
|
||||
|
||||
$("#btnSaveBaebunInfo").on("click",function(){
|
||||
if($("#frmEdit--${pageName}").find("[name='sinmungoInnerKey']").val() == ""){
|
||||
return;
|
||||
}
|
||||
|
||||
var obj = sinmungoFields.get();
|
||||
|
||||
ajax.post({
|
||||
url : wctx.url("sinmungo/saveBaebunInfo.do"),
|
||||
data : obj,
|
||||
success : (resp) => {
|
||||
if(resp.saved){
|
||||
fnSinmungoToXml();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function fnSinmungoToXml(){
|
||||
var key = $("#frmEdit--${pageName}").find("[name='sinmungoInnerKey']").val();
|
||||
|
||||
ajax.get({
|
||||
url : wctx.url("sinmungo/sinmungoToXml.do"),
|
||||
data : { "sinmungoInnerKey" : key},
|
||||
success : (resp) => {
|
||||
if(resp.filePath){
|
||||
var a = document.createElement("a");
|
||||
a.href = resp.filePath;
|
||||
a.download = resp.fileName;
|
||||
document.getElementById("tempArea").appendChild(a);
|
||||
a.click();
|
||||
document.getElementById("tempArea").removeChild(a);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fnClickSinmungoList(key){
|
||||
$("#sinmungoTbody--${pageName}").setCurrentRow(key);
|
||||
var data = sinmungoDataset.getData(key);
|
||||
sinmungoFields.set(data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function(){
|
||||
ajax.get({
|
||||
url : wctx.url("sinmungo/list.do"),
|
||||
data : {},
|
||||
success : (resp) => {
|
||||
|
||||
$("#sinmungoTbody--${pageName}").html("");
|
||||
|
||||
var list = resp.list;
|
||||
if(list != null && list.length > 0){
|
||||
sinmungoDataset.setData(list);
|
||||
} else {
|
||||
sinmungoDataset.setData([]);
|
||||
}
|
||||
|
||||
var empty = sinmungoDataset.empty;
|
||||
|
||||
var notFound = [document.getElementById("sinmungoNotFound--${pageName}").innerHTML];
|
||||
var found = document.getElementById("sinmungoRow--${pageName}").innerHTML;
|
||||
var replacer = (str, dataItem) => str
|
||||
.replace(/{onclick}/gi, "fnClickSinmungoList('" + dataItem.getValue("SINMUNGO_INNER_KEY") + "');");
|
||||
|
||||
var trs = empty ? notFound : sinmungoDataset.inStrings(found, replacer);
|
||||
|
||||
$("#sinmungoTbody--${pageName}").html(trs.join());
|
||||
|
||||
$("#sinmungoTbody--${pageName}").find("tr").find("td").eq(0).click();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
@ -0,0 +1,22 @@
|
||||
@CHARSET "UTF-8";
|
||||
|
||||
*[onclick], *[href] {cursor:pointer;}
|
||||
|
||||
.hidden {display:none;}
|
||||
|
||||
.wait {
|
||||
position:fixed; top:35%; left:50%;
|
||||
filter:alpha(opacity=50); -moz-opacity:0.5; opacity:0.5;
|
||||
z-index:99999;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.current-row {background-color:rgba(105, 108, 255, 0.16);}
|
||||
|
||||
.table th {font-size:1rem;}
|
||||
|
||||
.col-form-label {font-size:1rem;}
|
||||
|
||||
input[readonly] {
|
||||
background-color: #eceef1;
|
||||
}
|
||||
Loading…
Reference in New Issue