최초 커밋

master
mjkhan21 2 years ago
commit 81e977cce5

@ -0,0 +1,96 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cokr.xit.interfaces</groupId>
<artifactId>xit-smg</artifactId>
<version>23.04.01-SNAPSHOT</version>
<packaging>jar</packaging>
<name>xit-smg</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>mvn2s</id>
<url>https://repo1.maven.org/maven2/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>egovframe</id>
<url>http://maven.egovframe.kr:8080/maven/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>egovframe2</id>
<url>http://www.egovframe.go.kr/maven/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>maven-public</id>
<url>http://xit.xit-nexus.com:8081/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>cokr.xit.interfaces</groupId>
<artifactId>xit-filejob</artifactId>
<version>23.04.01-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
<finalName>${artifactId}-${version}</finalName>
<resources>
<resource><directory>${basedir}/src/main/resources</directory></resource>
</resources>
<testResources>
<testResource><directory>${basedir}/src/test/resources</directory></testResource>
<testResource><directory>${basedir}/src/main/resources</directory></testResource>
</testResources>
</build>
<!-- Nexus deploy -->
<distributionManagement>
<snapshotRepository>
<id>maven-snapshot</id>
<url>http://xit.xit-nexus.com:8081/repository/maven-snapshots/</url>
</snapshotRepository>
<repository>
<id>maven-release</id>
<url>http://xit.xit-nexus.com:8081/repository/maven-releases/</url>
</repository>
</distributionManagement>
<!-- Nexus deploy -->
</project>

@ -0,0 +1,765 @@
package cokr.xit.interfaces.smg;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import cokr.xit.base.file.FileInfo;
import cokr.xit.foundation.AbstractEntity;
import cokr.xit.foundation.Assert;
import cokr.xit.foundation.util.RandomNumber;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* @author mjkhan
*/
@Getter
@Setter
@XmlRootElement(name = "dmndinfo")
@XmlAccessorType(XmlAccessType.FIELD)
public class Petition extends AbstractEntity {
/** :
* 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;
//-----------------------------------------------------------------------------
/** :
* 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;
//------------------------------------------------------------------------------------
/** 1:
* varchar2(400)
* 0 / / 0
*/
@XmlElement(name = "pcd_gubun_v")
private String pcdGubunV;
/** 2:
* varchar2(400)
*/
@XmlElement(name = "pcd_gubun2_v")
private String pcdGubun2V;
/** 3:
* varchar2(400)
*/
@XmlElement(name = "pcd_gubun3_v")
private String pcdGubun3V;
/**xml :
* varchar2(10)
*/
@XmlElement(name = "ifid")
private String ifid;
/** :
* varchar2(7)
*
*/
@XmlElement(name = "srcorgcd")
private String srcorgcd;
/** :
* varchar2(7)
* insert 1140100
*/
@XmlElement(name = "tgtorgcd")
private String tgtorgcd;
@XmlElement(name = "apndfilinfo")
private ApndFileInfo appendFileInfo;
//-------------------------------------------------------------------------------------
@XmlElement(name = "peti_path_gubun_c")
private String petiPathGubunC;
/** :
* 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;
/**
* date
*/
@XmlElement(name = "anc_reg_d")
private String ancRegD;
/**
* varchar2(4000)
*/
@XmlElement(name = "more_again_v")
private String moreAgainV;
/** 1
* char(8)
*/
@XmlElement(name = "satisfy_c")
private String satisfyC;
/** 2
* char(8)
*/
@XmlElement(name = "satisfy2_c")
private String satisfy2C;
/** 3
* char(8)
*/
@XmlElement(name = "satisfy3_c")
private String satisfy3C;
/**
* date
*/
@XmlElement(name = "satisfy_reg_d")
private String satisfyRegD;
/** :
* 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;
//----------------------------------------------------------------------------------------------------
// 결과(응답) 처리
//----------------------------------------------------------------------------------------------------
/** :
* varchar2(512)
*
*/
@XmlElement(name = "civil_gist_v")
private String civilGistV;
/** :
* clob
*
*/
@XmlElement(name = "civil_abstract_l")
private String civilAbstractL;
/** :
* clob
*/
@XmlElement(name = "pcd_rst_cont_l")
private String pcdRstContL;
/** :
* varchar2(14) : YYYYMMDDHH24MISS
*/
@XmlElement(name = "do_reg_d")
private String doRegD;
/** :
* char(1)
* Y = , N = (default)
*/
@XmlElement(name = "pcd_rst_cont_attach_yn_c")
private String pcdRstContAttachYnC;
/**
* number(10)
*/
@XmlElement(name = "pcd_file_size_n")
private String pcdFileSizeN;
/** 민원 처리 첨부파일명 1 */
@XmlTransient
private String pcdFilePath1V;
/** 민원 처리 첨부파일명 2 */
@XmlTransient
private String pcdFilePath2V;
/** 민원 처리 첨부파일명 3 */
@XmlTransient
private String pcdFilePath3V;
/** 민원 처리 첨부파일명 4 */
@XmlTransient
private String pcdFilePath4V;
/** 민원 처리 첨부파일명 5 */
@XmlTransient
private String pcdFilePath5V;
/** 원본 파일 이름 */
@XmlTransient
private String originalFilename;
/** 첨부파일 저장경로1 */
@XmlTransient
private String attachmentPath1;
/** 첨부파일 저장경로2 */
@XmlTransient
private String attachmentPath2;
/** 첨부파일 저장경로3 */
@XmlTransient
private String attachmentPath3;
/** 첨부파일 저장경로4 */
@XmlTransient
private String attachmentPath4;
/** 첨부파일 저장경로5 */
@XmlTransient
private String attachmentPath5;
/**
* number(30) - YYYYMMDDHH24MISS + 0000000 + random(9)
*/
@XmlTransient
private String sendInterfaceSeqN;
/**
*/
@XmlTransient
private String sendStatus;
/**
*/
@XmlTransient
private String sendStatusMsg;
/* yyyy-MM-dd hh:mm:ss -> yyyyMMddhhmmss */
private static String dateText(String str) {
if (str == null) return "";
return str.replaceAll("[-: ]", "");
}
/**(yyyy-MM-dd hh:mm:ss) .
* @return Petition
*/
public Petition normalize() {
petiRegD = dateText(petiRegD);
petiEndD = dateText(petiEndD);
ancRegD = dateText(ancRegD);
regD = dateText(regD);
return this;
}
/** /
*
* interfaceSeqN sendInterfaceSeqN .
* @return Petition
*/
public Petition swapInterfaceSeqs() {
String tmp = interfaceSeqN;
interfaceSeqN = sendInterfaceSeqN;
sendInterfaceSeqN = tmp;
return this;
}
/** /
* <ul><li> , </li>
* <li> (Y) </li>
* <li> </li>
* </ul>
* .
* @param now (yyyyMMddhhmmss)
* @return Petition
*/
public Petition setNow(String now) {
setSendInterfaceSeqN(now + "0000000" + RandomNumber.get(9));
setApplyGubunC("Y");
setSendD(now);
setApplyD(now);
setSrcorgcd(ancCodeV);
setTgtorgcd("");
setIfid("");
return this;
}
/** .
* @param attachments
* @return Petition
*/
public Petition setAttachmentPaths(List<FileInfo> attachments) {
for (int i = 0; i < attachments.size(); ++i) {
FileInfo attachment = attachments.get(i);
String path = attachment.getPath();
switch (i + 1) {
case 1: attachmentPath1 = path; break;
case 2: attachmentPath2 = path; break;
case 3: attachmentPath3 = path; break;
case 4: attachmentPath4 = path; break;
case 5: attachmentPath5 = path; break;
default: break;
}
}
return this;
}
/** .
* @return (EPOUGB$ + + .xml)
*/
public String sendFilename() {
return "EPOUGB$" + getSendInterfaceSeqN() + ".xml";
}
/**
* @author mjkhan
*/
@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;
/** 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;
@XmlElement(name = "apndfilcount")
private String apndfilcount;
@XmlElement(name = "apndfilcont1")
private String apndfilcont1;
@XmlElement(name = "apndfilcont2")
private String apndfilcont2;
@XmlElement(name = "apndfilcont3")
private String apndfilcont3;
@XmlElement(name = "apndfilcont4")
private String apndfilcont4;
@XmlElement(name = "apndfilcont5")
private String apndfilcont5;
/** .
* @param infoType
* @param infoKey
* @return
*/
public List<FileInfo> getFileInfo(String infoType, String infoKey) {
int count = Integer.valueOf(apndfilcount);
if (count < 1)
return Collections.emptyList();
FileInfo.Relation relation = new FileInfo.Relation()
.setInfoType(infoType)
.setInfoKey(infoKey);
ArrayList<FileInfo.DataHolder> dataHolders = new ArrayList<>();
for (int i = 1; i <= 5; ++i) {
String filename = "";
String filecontent = "";
switch (i) {
case 1:
filename = petiFilePath1V;
filecontent = apndfilcont1;
break;
case 2:
filename = petiFilePath2V;
filecontent = apndfilcont2;
break;
case 3:
filename = petiFilePath3V;
filecontent = apndfilcont3;
break;
case 4:
filename = petiFilePath4V;
filecontent = apndfilcont4;
break;
case 5:
filename = petiFilePath5V;
filecontent = apndfilcont5;
break;
}
FileInfo.DataHolder dataHolder = getDataHolder(relation, filename, filecontent);
if (dataHolder != null)
dataHolders.add(dataHolder);
}
if (count != dataHolders.size())
throw new RuntimeException("첨부파일 수가 다릅니다.");
return new FileInfo.Factory().createFileInfos(dataHolders);
}
private FileInfo.DataHolder getDataHolder(FileInfo.Relation relation, String filename, String filecontent) {
return !Assert.isEmpty(filename) && !Assert.isEmpty(filecontent) ?
new FileInfo.DataHolder(relation, filename, filecontent) : null;
}
}
/**
* @author mjkhan
*/
public static class Violation {
private static RegexPattern
vehicleNoDatetime = new RegexPattern("(\\*\\s\\(\\d.*\\/\\d.*\\)\\s[GCS]:\\s)(.*)(\\s차량번호\\s:\\s)(.*)"),
coordinates = new RegexPattern("(\\*\\s발생지역\\s위도:)(.*)(\\s경도:)(.*)"),
location = new RegexPattern("(\\[사고발생지역\\])(.*)"),
description = new RegexPattern("(\\(.*\\))(.*)(\\s신고입니다.*)"),
entryType = new RegexPattern("(\\[민원 유입 경로\\]:\\s)(.*)");
private String reason;
/** Violation() .
* @param reason
*/
public Violation (String reason) {
this.reason = reason;
}
/** , .
* @return ,
* <ul><li>datetime: </li>
* <li>vehicleNo: </li>
* </ul>
*/
public List<Map<String, String>> getVehicleNoDatetimes() {
Matcher matcher = vehicleNoDatetime.matcher(reason);
ArrayList<Map<String, String>> list = new ArrayList<>();
while (matcher.find()) {
String[] found = matcher.group()
.replaceAll(vehicleNoDatetime.regex, "$2,$4")
.replaceAll("\\(위·변조 없음\\)", "")
.replaceAll("[: /]", "")
.split(",");
HashMap<String, String> info = new HashMap<>();
info.put("datetime", found[0]);
info.put("vehicleNo", found.length > 1 ? found[1] : "");
list.add(info);
}
return list;
}
/** .
* @return
* <ul><li>latitude: </li>
* <li>longitude: </li>
* </ul>
*/
public Map<String, String> getCoordinates() {
Matcher matcher = coordinates.matcher(reason);
HashMap<String, String> info = new HashMap<>();
while (matcher.find()) {
String[] found = matcher.group()
.replaceAll(coordinates.regex, "$2,$4")
.split(",");
info.put("latitude", found[0]);
info.put("longitude", found[1]);
}
return info;
}
/** .
* @return
*/
public String getLocation() {
Matcher matcher = location.matcher(reason);
String found = "";
while (matcher.find()) {
found = matcher.group().replaceAll(location.regex, "$2");
}
return found;
}
/** .
* @param title
* @return
*/
public String getDescription(String title) {
Matcher matcher = description.matcher(title);
String found = "";
while (matcher.find()) {
found = matcher.group().replaceAll(description.regex, "$2");
}
return found;
}
/** .
* @return
*/
public String getEntryType() {
Matcher matcher = entryType.matcher(reason);
String found = "";
while (matcher.find()) {
found = matcher.group().replaceAll(entryType.regex, "$2");
}
return found;
}
}
private static class RegexPattern {
private String regex;
private Pattern pattern;
private RegexPattern(String regex) {
pattern = Pattern.compile(this.regex = regex);
}
private Matcher matcher(String str) {
return pattern.matcher(str);
}
}
}

@ -0,0 +1,110 @@
package cokr.xit.interfaces.smg.dao;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.egovframe.rte.psl.dataaccess.mapper.Mapper;
import cokr.xit.foundation.component.AbstractMapper;
import cokr.xit.interfaces.smg.Petition;
/** DAO
* @author mjkhan
*/
@Mapper("smgMapper")
public interface SmgMapper extends AbstractMapper {
/** .
* @param interfaceSequences
* @return
*/
List<Petition> selectPetitions(List<String> interfaceSequences);
/** .
* @param interfaceSequences
* @return
*/
default List<Petition> selectPetitions(String... interfaceSequences) {
return selectPetitions(!isEmpty(interfaceSequences) ? Arrays.asList(interfaceSequences) : null);
}
/** .
* @param petition
* @return
*/
int insertPetition(Petition petition);
/** .
* @param petition
* @return
*/
int insertFile(Petition petition);
/** .
* @param petition
* @return
*/
default int create(Petition petition) {
int affected = insertPetition(petition);
insertFile(petition);
return affected;
}
/** / .
* / .
* / .
* @param interfaceSequences
* @return /
*/
List<Petition> selectReplies(List<String> interfaceSequences);
/** / .<br />
* / .
* @param interfaceSequences
* @return /
*/
default List<Petition> selectReplies(String... interfaceSequences) {
return selectReplies(!isEmpty(interfaceSequences) ? Arrays.asList(interfaceSequences) : null);
}
/** / .
* @param params
* <ul><li>reply - / </li>
* <li>currentUser - </li>
* </ul>
* @return
*/
int insertReply(Map<String, Object> params);
/** / .
* @param reply /
* @return
*/
default int createReply(Petition reply) {
return insertReply(
params().set("reply", reply)
);
}
/** / / .
* @param params
* <ul><li>replies - / </li>
* <li>now - (yyyyMMddhhmmss)</li>
* </ul>
* @return
*/
int updateSendStatus(Map<String, Object> params);
/** / / .
* @param replies /
* @param now (yyyyMMddhhmmss)
* @return
*/
default int updateSendStatus(List<Petition> replies, String now) {
if (isEmpty(replies)) return 0;
return updateSendStatus(params()
.set("replies", replies)
.set("now", now)
);
}
}

@ -0,0 +1,3 @@
/** DAO
*/
package cokr.xit.interfaces.smg.dao;

@ -0,0 +1,17 @@
/** .
* <p>
* <ul><li> - </li>
* <li> - /</li>
* </ul>
* .
* <p> <a href="{@docRoot}/doc-files/xit-smg.sql" target="_blank"> </a> .
* <ul><li> - TB_ESB_INTERFACE</li>
* <li> - TB_ESB_INTERFACE_FILE</li>
* <li> - TB_FILE</li>
* </ul>
* / .
* <ul><li> / - TB_ESB_INTERFACE_TRSM</li>
* </ul>
* 'conf/file-job.conf' .
*/
package cokr.xit.interfaces.smg;

@ -0,0 +1,48 @@
package cokr.xit.interfaces.smg.service;
import java.util.List;
import cokr.xit.interfaces.smg.Petition;
/**
* <ul><li>{@link #receivePetitions() }</li>
* <li>{@link #getPetitions(List) }</li>
* <li>{@link #sendReplies() / }</li>
* <li>{@link #createReply(Petition) / }</li>
* <li>{@link #getReplies(List) / }</li>
* </ul>
* .
* @author mjkhan
*/
public interface SmgService {
/** .
* @param interfaceSequences
* @return
*/
List<Petition> getPetitions(List<String> interfaceSequences);
/** .
* @return
*/
List<String> receivePetitions();
/** / .
* @param interfaceSequences
* @return /
*/
List<Petition> getReplies(List<String> interfaceSequences);
/** / .
* @param reply /
* @return
* <ul><li> true</li>
* <li> false</li>
* </ul>
*/
boolean createReply(Petition reply);
/** / .
* @return
*/
List<String> sendReplies();
}

@ -0,0 +1,161 @@
package cokr.xit.interfaces.smg.service.bean;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import cokr.xit.base.file.FileInfo;
import cokr.xit.base.file.service.bean.FileBean;
import cokr.xit.foundation.data.XML;
import cokr.xit.foundation.web.Http;
import cokr.xit.interfaces.filejob.service.bean.FileJobBean;
import cokr.xit.interfaces.smg.Petition;
import cokr.xit.interfaces.smg.dao.SmgMapper;
/** Bean
* @author mjkhan
*/
@Component("smgInBean")
public class SmgInBean extends FileJobBean {
@Resource(name = "smgMapper")
private SmgMapper smgMapper;
@Resource(name = "fileBean")
private FileBean fileBean;
private XML xml = new XML(config("charset"));
/** (smg-in) .
*/
@Override
public String jobName() {
return "smg-in";
}
/** .
* @param interfaceSequences
* @return
*/
public List<Petition> getPetitions(List<String> interfaceSequences) {
return smgMapper.selectPetitions(interfaceSequences);
}
/** .
* @param interfaceSequences
* @return
*/
public List<Petition> getPetitions(String... interfaceSequences) {
return smgMapper.selectPetitions(interfaceSequences);
}
/**
* <ul><li> </li>
* <li> </li>
* <li> </li>
* <li>{@link #alert(List) }.</li>
* </ul>
* @return
*/
public List<String> receivePetitions() {
List<FileStatus> parsed = parse();
if (parsed.isEmpty()) return Collections.emptyList();
Map<Boolean, List<FileStatus>> received = parsed.stream()
.collect(Collectors.groupingBy(status -> status.isSuccess()));
List<FileStatus> fileStatus = received.get(true);
List<String> interfaceSequences = processSuccess(fileStatus);
alert(interfaceSequences);
if (!isEmpty(fileStatus))
move(
fileStatus.stream().map(FileStatus::getPath).collect(Collectors.toList()),
successDir()
);
fileStatus = received.get(false);
if (!isEmpty(fileStatus))
move(
fileStatus.stream().map(FileStatus::getPath).collect(Collectors.toList()),
failDir()
);
return interfaceSequences;
}
private List<FileStatus> parse() {
String infoType = config("infoType");
List<Path> paths = getReceivedFilePaths();
return paths.stream()
.map(path -> parse(infoType, path))
.collect(Collectors.toList());
}
private FileStatus parse(String infoType, Path path) {
FileStatus status = new FileStatus().setPath(path);
try {
File file = path.toFile();
Petition petition = xml.parse(file, Petition.class);
petition.setOriginalFilename(file.getName());
List<FileInfo> attachments = petition.getAppendFileInfo().getFileInfo(infoType, petition.getInterfaceSeqN());
return status
.set("petition", petition)
.set("attachments", attachments);
} catch (Exception e) {
return status.setCause(e);
}
}
private List<String> processSuccess(List<FileStatus> success) {
if (isEmpty(success)) return Collections.emptyList();
String registID = jobName();
ArrayList<String> interfaceSequences = new ArrayList<>();
success.forEach(status -> {
List<FileInfo> attachments = status.get("attachments");
fileBean.create(attachments);
Petition petition = status.get("petition");
petition.setCreatedBy(registID);
petition.setAttachmentPaths(attachments);
smgMapper.create(petition);
interfaceSequences.add(petition.getInterfaceSeqN());
});
return interfaceSequences;
}
/** http .
* <ul><li> : http POST </li>
* <li>: "interfaceSequences" - </li>
* </ul>
* "alert" url .
* @param interfaceSequences
*/
protected void alert(List<String> interfaceSequences) {
if (isEmpty(interfaceSequences)) return;
String alert = config("alert");
if (isEmpty(alert)) return;
new Http().post(new Http.Conf()
.url(alert)
.param("interfaceSequences", String.join(",", interfaceSequences))
);
}
}

@ -0,0 +1,168 @@
package cokr.xit.interfaces.smg.service.bean;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import cokr.xit.foundation.data.XML;
import cokr.xit.foundation.web.Http;
import cokr.xit.interfaces.filejob.service.bean.FileJobBean;
import cokr.xit.interfaces.smg.Petition;
import cokr.xit.interfaces.smg.dao.SmgMapper;
/** / Bean
* @author mjkhan
*/
@Component("smgOutBean")
public class SmgOutBean extends FileJobBean {
private static final SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyyMMddhhmmss");
@Resource(name = "smgMapper")
private SmgMapper smgMapper;
private XML xml = new XML(config("charset"));
/** / (smg-out) .
*/
@Override
public String jobName() {
return "smg-out";
}
/** / .
* @param interfaceSequences
* @return /
*/
public List<Petition> getReplies(List<String> interfaceSequences) {
return !isEmpty(interfaceSequences) ? smgMapper.selectReplies(interfaceSequences) : Collections.emptyList();
}
/** / .
* @param reply /
* @return
* <ul><li> true</li>
* <li> false</li>
* </ul>
*/
public boolean createReply(Petition reply) {
if (!getReplies(Arrays.asList(reply.getInterfaceSeqN())).isEmpty())
throw applicationException(null).setMessage(message("duplicate.object", "답변/반송"));
return smgMapper.createReply(reply) > 0;
}
/** /
* <ul><li> / </li>
* <li> </li>
* <li> / </li>
* <li> </li>
* <li>{@link #alert(List) / }</li>
* </ul>
* / .
* @return /
*/
public List<String> sendReplies() {
List<Petition> replies = smgMapper.selectReplies();
if (replies.isEmpty()) return Collections.emptyList();
String now = datetimeFormat.format(new Date());
String dir = sendWorkingDir();
mkdirs(dir);
List<FileStatus> processed = replies.stream()
.map(write(dir, now))
.collect(Collectors.toList());
processed.forEach(status -> {
boolean success = status.isSuccess();
Petition reply = status.get("reply");
reply.setSendStatus(success ? "Y" : "N");
reply.setSendStatusMsg(success ? "전송 성공" : "전송 실패");
reply.setApplyGubunC(success ? "Y" : "N");
reply.setSendD(success ? now : null);
reply.setApplyD(success ? now : null);
});
smgMapper.updateSendStatus(
processed.stream()
.map(status -> (Petition)status.get("reply"))
.collect(Collectors.toList()),
now
);
List<Path> paths = processed.stream()
.filter(FileStatus::isSuccess)
.map(FileStatus::getPath)
.collect(Collectors.toList());
move(paths, sendDir());
alert(replies);
return replies.stream()
.map(reply -> reply.getInterfaceSeqN())
.collect(Collectors.toList());
}
private Function<Petition, FileStatus> write(String dir, String now) {
return reply -> {
reply.setNow(now);
Path path = Paths.get(dir, reply.sendFilename());
FileStatus status = new FileStatus()
.setPath(path)
.set("reply", reply);
try {
File file = path.toFile();
xml.write(reply.swapInterfaceSeqs(), file);
return status;
} catch (Exception e) {
return status.setCause(e);
} finally {
reply.swapInterfaceSeqs();
}
};
}
/** / http .
* <ul><li> : http POST </li>
* <li>
* <ul><li>"success" - </li>
* <li>"fail" - </li>
* </ul>
* </li>
* </ul>
* "alert" url .
* @param replies /
*/
protected void alert(List<Petition> replies) {
if (isEmpty(replies)) return;
String alert = config("alert");
if (isEmpty(alert)) return;
Map<String, List<Petition>> processed = replies.stream().collect(Collectors.groupingBy(Petition::getSendStatus));
List<Petition> list = processed.get("Y");
String success = list != null ? list.stream().map(Petition::getInterfaceSeqN).collect(Collectors.joining(",")) : "";
list = processed.get("N");
String fail = list != null ? list.stream().map(Petition::getInterfaceSeqN).collect(Collectors.joining(",")) : "";
new Http().post(new Http.Conf()
.url(alert)
.param("success", success)
.param("fail", fail)
);
}
}

@ -0,0 +1,51 @@
package cokr.xit.interfaces.smg.service.bean;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import cokr.xit.interfaces.filejob.service.bean.FileJobServiceBean;
import cokr.xit.interfaces.smg.Petition;
import cokr.xit.interfaces.smg.service.SmgService;
/**
* <ul><li> {@link SmgInBean}</li>
* <li> / {@link SmgOutBean}</li>
* </ul>
* .
* @author mjkhan
*/
@Service("smgService")
public class SmgServiceBean extends FileJobServiceBean implements SmgService {
@Resource(name = "smgInBean")
private SmgInBean smgIn;
@Resource(name = "smgOutBean")
private SmgOutBean smgOut;
@Override
public List<Petition> getPetitions(List<String> interfaceSequences) {
return smgIn.getPetitions(interfaceSequences);
}
@Override
public List<String> receivePetitions() {
return execute(smgIn, smgIn::receivePetitions);
}
@Override
public List<Petition> getReplies(List<String> interfaceSequences) {
return smgOut.getReplies(interfaceSequences);
}
@Override
public boolean createReply(Petition reply) {
return smgOut.createReply(reply);
}
@Override
public List<String> sendReplies() {
return execute(smgOut, smgOut::sendReplies);
}
}

@ -0,0 +1,3 @@
/**
*/
package cokr.xit.interfaces.smg.service.bean;

@ -0,0 +1,3 @@
/**
*/
package cokr.xit.interfaces.smg.service;

@ -0,0 +1,56 @@
package cokr.xit.interfaces.smg.web;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import cokr.xit.foundation.web.AbstractController;
import cokr.xit.interfaces.smg.service.SmgService;
/**
* @author mjkhan
*/
@Controller
@RequestMapping(value = "/api/smg", name = "국민 신문고 민원")
public class SmgController extends AbstractController {
/** 국민 신문고 파일 연계 서비스 */
@Resource(name = "smgService")
protected SmgService smgService;
/** .
* @param interfaceSequences
* @return jsonView
* <ul><li>received - (true || false)</li>
* <li>saved - (true || false)</li>
* </ul>
*/
@PostMapping(value = "/petition/receive.do", name = "국민 신문고 민원 수신")
public ModelAndView receivePetitions(String[] interfaceSequences) {
log().debug("interfaceSequences received: {}", String.join(", ", interfaceSequences));
return new ModelAndView("jsonView")
.addObject("received", !isEmpty(interfaceSequences))
.addObject("saved", true);
}
/** / .
* @param success
* @param fail
* @return jsonView
* <ul><li>received - (true || false)</li>
* <li>saved - (true || false)</li>
* </ul>
*/
@PostMapping(value = "/petition/reply.do", name = "국민 신문고 민원 답변/반송 생성")
public ModelAndView sendReplies(String[] success, String[] fail) {
log().debug("success: {}", String.join(", ", success));
log().debug("fail: {}", String.join(", ", fail));
return new ModelAndView("jsonView")
.addObject("received", !isEmpty(success) || !isEmpty(fail))
.addObject("saved", true);
}
}

@ -0,0 +1,3 @@
/**
*/
package cokr.xit.interfaces.smg.web;

@ -0,0 +1,111 @@
CREATE OR REPLACE TABLE tb_esb_interface (
INTERFACE_SEQ_N VARCHAR(30) NOT NULL COMMENT '인터페이스 키',
SYS_GUBUN_C VARCHAR(8) NULL DEFAULT NULL COMMENT '시스템 구분',
ANC_CODE_V VARCHAR(7) NULL DEFAULT NULL COMMENT '기관 코드',
PETI_GUBUN_C VARCHAR(3) NULL DEFAULT NULL COMMENT '민원 구분',
PETI_ANC_CODE_V VARCHAR(7) NULL DEFAULT NULL COMMENT '민원 기관 코드',
PETI_NO_C VARCHAR(16) NULL DEFAULT NULL COMMENT '민원 신청 번호',
CIVIL_NO_C VARCHAR(16) NULL DEFAULT NULL COMMENT '민원 접수 번호',
PETER_NAME_V VARCHAR(128) NULL DEFAULT NULL COMMENT '민원 신청인 명',
ZIP_CODE_C VARCHAR(7) NULL DEFAULT NULL COMMENT '민원 신청인 우편번호',
ADDRESS_V VARCHAR(400) NULL DEFAULT NULL COMMENT '민원 신청인 주소',
EMAIL_V VARCHAR(64) NULL DEFAULT NULL COMMENT '민원 신청인 이메일',
CEL_NO_V VARCHAR(20) NULL DEFAULT NULL COMMENT '민원 신청인 핸드폰번호',
TEL_NO_V VARCHAR(20) NULL DEFAULT NULL COMMENT '민원 신청인 전화번호',
PETI_TITLE_V VARCHAR(500) NULL DEFAULT NULL COMMENT '민원 신청 제목',
PETI_REASON_L VARCHAR(4000) NULL DEFAULT NULL COMMENT '민원 신청 내용',
OPEN_YN_C VARCHAR(1) NULL DEFAULT NULL COMMENT '민원 공개 여부',
PETI_REG_D VARCHAR(30) NULL DEFAULT NULL COMMENT '민원 신청 일자',
PETI_REASON_ATTACH_YN_C VARCHAR(1) NULL DEFAULT NULL COMMENT '민원 신청 내용 첨부 여부',
CIVIL_GIST_V VARCHAR(512) NULL DEFAULT NULL COMMENT '민원 요지',
CIVIL_ABSTRACT_L VARCHAR(4000) NULL DEFAULT NULL COMMENT '민원 처리 요약',
PCD_DEPT_V VARCHAR(7) NULL DEFAULT NULL COMMENT '처리 부서 코드',
PCD_DEPT_NM_V VARCHAR(50) NULL DEFAULT NULL COMMENT '민원 처리 부서명',
DUTY_ID_V VARCHAR(50) NULL DEFAULT NULL COMMENT '민원 처리 담당자 명',
PCD_EMAIL_V VARCHAR(64) NULL DEFAULT NULL COMMENT '담당자 이메일',
PCD_TEL_V VARCHAR(20) NULL DEFAULT NULL COMMENT '담당자 전화번호',
PCD_RST_CONT_L VARCHAR(4000) NULL DEFAULT NULL COMMENT '민원 처리 결과',
DO_REG_D VARCHAR(30) NULL DEFAULT NULL COMMENT '민원 처리 완료 일자',
PCD_RST_CONT_ATTACH_YN_C VARCHAR(1) NULL DEFAULT NULL COMMENT '민원 처리 결과 첨부 여부',
PCD_ANC_CODE_V VARCHAR(7) NULL DEFAULT NULL COMMENT '민원 실 처리 기관 코드',
PETI_PROC_DUR_N INT(5) NULL DEFAULT NULL COMMENT '민원 처리 기간',
PETI_END_D VARCHAR(30) NULL DEFAULT NULL COMMENT '처리 예정 일자',
ANC_REG_D VARCHAR(30) NULL DEFAULT NULL COMMENT '접수 일자',
MORE_AGAIN_V VARCHAR(1000) NULL DEFAULT NULL COMMENT '한마디더',
SATISFY_C VARCHAR(8) NULL DEFAULT NULL COMMENT '만족도 항목1',
SATISFY2_C VARCHAR(8) NULL DEFAULT NULL COMMENT '만족도 항목2',
SATISFY3_C VARCHAR(8) NULL DEFAULT NULL COMMENT '만족도 항목3',
SATISFY_REG_D VARCHAR(30) NULL DEFAULT NULL COMMENT '만족도 입력일',
REG_D VARCHAR(30) NULL DEFAULT NULL COMMENT '등록 일자',
SEND_YN_C VARCHAR(1) NULL DEFAULT NULL COMMENT '송신 여부',
SEND_D VARCHAR(30) NULL DEFAULT NULL COMMENT '송신 일자',
APPLY_D VARCHAR(30) NULL DEFAULT NULL COMMENT '적용 일자',
APPLY_GUBUN_C VARCHAR(1) NULL DEFAULT NULL COMMENT '완료 구분',
PCD_GUBUN_V VARCHAR(100) NULL DEFAULT NULL COMMENT '처리 구분1',
PCD_GUBUN2_V VARCHAR(100) NULL DEFAULT NULL COMMENT '처리 구분2',
PCD_GUBUN3_V VARCHAR(100) NULL DEFAULT NULL COMMENT '처리 구분3',
PETI_PATH_GUBUN_C VARCHAR(8) NULL DEFAULT NULL COMMENT '신청 경로 코드',
ORGNL_FILE_NM VARCHAR(200) NULL DEFAULT NULL COMMENT '원본 파일 명',
REG_DT VARCHAR(14) NULL DEFAULT NULL COMMENT '등록 일시',
RGTR VARCHAR(10) NULL DEFAULT NULL COMMENT '등록자',
PRIMARY KEY (INTERFACE_SEQ_N) USING BTREE
) COMMENT='국민신문고 민원 수신';
CREATE OR REPLACE TABLE tb_esb_interface_file (
INTERFACE_SEQ_N VARCHAR(30) NOT NULL COMMENT '인터페이스 키',
PETI_FILE_SIZE_N INT(10) NULL DEFAULT NULL COMMENT '민원 신청 첨부파일 크기',
PETI_FILE_PATH1_V VARCHAR(2000) NULL DEFAULT NULL COMMENT '민원 신청 첨부파일 명1',
PETI_FILE_PATH2_V VARCHAR(2000) NULL DEFAULT NULL COMMENT '민원 신청 첨부파일 명2',
PETI_FILE_PATH3_V VARCHAR(2000) NULL DEFAULT NULL COMMENT '민원 신청 첨부파일 명3',
PETI_FILE_PATH4_V VARCHAR(2000) NULL DEFAULT NULL COMMENT '민원 신청 첨부파일 명4',
PETI_FILE_PATH5_V VARCHAR(2000) NULL DEFAULT NULL COMMENT '민원 신청 첨부파일 명5',
PCD_FILE_SIZE_N INT(10) NULL DEFAULT NULL COMMENT '민원 처리 첨부파일 크기',
PCD_FILE_PATH1_V VARCHAR(1000) NULL DEFAULT NULL COMMENT '민원 처리 첨부파일 명1',
PCD_FILE_PATH2_V VARCHAR(1000) NULL DEFAULT NULL COMMENT '민원 처리 첨부파일 명2',
PCD_FILE_PATH3_V VARCHAR(1000) NULL DEFAULT NULL COMMENT '민원 처리 첨부파일 명3',
PCD_FILE_PATH4_V VARCHAR(1000) NULL DEFAULT NULL COMMENT '민원 처리 첨부파일 명4',
PCD_FILE_PATH5_V VARCHAR(1000) NULL DEFAULT NULL COMMENT '민원 처리 첨부파일 명5',
STRG_ATCHFILE_NM1 VARCHAR(1000) NULL DEFAULT NULL COMMENT '저장 첨부파일 명1',
STRG_ATCHFILE_NM2 VARCHAR(1000) NULL DEFAULT NULL COMMENT '저장 첨부파일 명2',
STRG_ATCHFILE_NM3 VARCHAR(1000) NULL DEFAULT NULL COMMENT '저장 첨부파일 명3',
STRG_ATCHFILE_NM4 VARCHAR(1000) NULL DEFAULT NULL COMMENT '저장 첨부파일 명4',
STRG_ATCHFILE_NM5 VARCHAR(1000) NULL DEFAULT NULL COMMENT '저장 첨부파일 명5',
PRIMARY KEY (INTERFACE_SEQ_N) USING BTREE
) COMMENT='국민신문고 민원 첨부 파일';
CREATE OR REPLACE TABLE tb_esb_interface_trsm (
INTERFACE_SEQ_N VARCHAR(30) NOT NULL COMMENT '인터페이스 키',
SYS_GUBUN_C VARCHAR(8) NULL DEFAULT NULL COMMENT '시스템 구분',
ANC_CODE_V VARCHAR(7) NULL DEFAULT NULL COMMENT '기관 코드',
PETI_GUBUN_C VARCHAR(3) NULL DEFAULT NULL COMMENT '민원 구분',
PETI_ANC_CODE_V VARCHAR(7) NULL DEFAULT NULL COMMENT '민원 기관 코드',
PETI_NO_C VARCHAR(16) NULL DEFAULT NULL COMMENT '민원 신청 번호',
CIVIL_NO_C VARCHAR(16) NULL DEFAULT NULL COMMENT '민원 접수 번호',
CIVIL_GIST_V VARCHAR(512) NULL DEFAULT NULL COMMENT '민원 요지',
CIVIL_ABSTRACT_L VARCHAR(4000) NULL DEFAULT NULL COMMENT '민원 처리 요약',
PCD_DEPT_V VARCHAR(7) NULL DEFAULT NULL COMMENT '처리 부서 코드',
PCD_DEPT_NM_V VARCHAR(50) NULL DEFAULT NULL COMMENT '민원 처리 부서명',
DUTY_ID_V VARCHAR(50) NULL DEFAULT NULL COMMENT '민원 처리 담당자 명',
PCD_EMAIL_V VARCHAR(64) NULL DEFAULT NULL COMMENT '담당자 이메일',
PCD_TEL_V VARCHAR(20) NULL DEFAULT NULL COMMENT '담당자 전화번호',
PCD_RST_CONT_L VARCHAR(4000) NULL DEFAULT NULL COMMENT '민원 처리 결과',
DO_REG_D VARCHAR(14) NULL DEFAULT NULL COMMENT '민원 처리 완료 일시',
PCD_RST_CONT_ATTACH_YN_C VARCHAR(1) NULL DEFAULT NULL COMMENT '민원 처리 결과 첨부 여부',
PCD_ANC_CODE_V VARCHAR(7) NULL DEFAULT NULL COMMENT '민원 실 처리 기관 코드',
REG_D VARCHAR(14) NULL DEFAULT NULL COMMENT '등록 일자',
SEND_YN_C VARCHAR(1) NULL DEFAULT NULL COMMENT '송신 여부',
SEND_D VARCHAR(14) NULL DEFAULT NULL COMMENT '송신 일자',
APPLY_D VARCHAR(14) NULL DEFAULT NULL COMMENT '적용 일자',
APPLY_GUBUN_C VARCHAR(1) NULL DEFAULT NULL COMMENT '완료 구분',
PCD_GUBUN_V VARCHAR(400) NULL DEFAULT NULL COMMENT '처리 구분1',
PCD_GUBUN2_V VARCHAR(400) NULL DEFAULT NULL COMMENT '처리 구분2',
PCD_GUBUN3_V VARCHAR(400) NULL DEFAULT NULL COMMENT '처리 구분3',
TRSM_INTERFACE_SEQ_N VARCHAR(30) NULL DEFAULT NULL COMMENT '전송 인터페이스키',
TRSM_STTS_CD VARCHAR(2) NULL DEFAULT NULL COMMENT '전송 상태 코드',
TRSM_STTS_MSG VARCHAR(1000) NULL DEFAULT NULL COMMENT '전송 상태 메시지',
REG_DT VARCHAR(14) NULL DEFAULT NULL COMMENT '등록 일시',
RGTR VARCHAR(10) NULL DEFAULT NULL COMMENT '등록자',
MDFCN_DT VARCHAR(14) NULL DEFAULT NULL COMMENT '수정 일시',
MDFR VARCHAR(10) NULL DEFAULT NULL COMMENT '수정자',
PRIMARY KEY (INTERFACE_SEQ_N) USING BTREE
) COMMENT='국민신문고 답변 전송';
Loading…
Cancel
Save