feat: NICE CI 전문 처리 반영

-> 한글 2, 그외 1 자리로 처리 하도록 반영
      -> name, message 필드
dev
Jonguk. Lim 2 months ago
parent de9138de55
commit 462f03d932

@ -0,0 +1,236 @@
package cokr.xit.ens.modules.nice.cmm;
import java.io.*;
import java.nio.charset.*;
import java.util.concurrent.atomic.*;
import org.apache.commons.lang3.*;
import cokr.xit.ens.core.exception.*;
import lombok.extern.slf4j.*;
/**
* <pre>
* description :
* packageName : cokr.xit.ens.modules.nice.cmm
* fileName : NiceCiUtils
* author : limju
* date : 2024 9 25
* ======================================================================
*
* ----------------------------------------------------------------------
* 2024 9 25 limju
*
* </pre>
*/
@Slf4j
public class NiceCiUtils {
/**
* "ISO-8859-1", "UTF-8", "EUC-KR"
* @param src
* @param charset
* @return String
*/
public static String covertCharset(final String src, final String charset){
try {
return new String(src.getBytes(), charset);
} catch (UnsupportedEncodingException e) {
throw BizRuntimeException.create(e.getMessage());
}
}
/**
* "ISO-8859-1", "UTF-8", "EUC-KR" -> "ISO-8859-1", "UTF-8", "EUC-KR"
* @param src "ISO-8859-1", "UTF-8", "EUC-KR"
* @param srcCharset "ISO-8859-1", "UTF-8", "EUC-KR"
* @param tgtCharset "ISO-8859-1", "UTF-8", "EUC-KR"
* @return String
*/
public static String covertCharset(final String src, final Charset srcCharset, final Charset tgtCharset) {
//CharBuffer cb = srcCharset.decode(ByteBuffer.wrap(src.getBytes(srcCharset)));
//try {
return new String(src.getBytes(srcCharset), tgtCharset);
//} catch (UnsupportedEncodingException e) {
// throw BizRuntimeException.create(e.getMessage());
// }
}
/**
* "ISO-8859-1", "UTF-8", "EUC-KR" -> "ISO-8859-1", "UTF-8", "EUC-KR"
* @param src "ISO-8859-1", "UTF-8", "EUC-KR"
* @param srcCharset "ISO-8859-1", "UTF-8", "EUC-KR"
* @param tgtCharset "ISO-8859-1", "UTF-8", "EUC-KR"
* @return String
*/
public static String covertCharset(final String src, final String srcCharset, final String tgtCharset) {
try {
return new String(src.getBytes(srcCharset), tgtCharset);
} catch (UnsupportedEncodingException e) {
throw BizRuntimeException.create(e.getMessage());
}
}
public static String leftKr(String str, int len) {
if (str == null) {
return null;
} else if (len < 0) {
return "";
} else {
return str.length() <= len ? str : getStringKr(str, len);
}
}
public static String rightPadKr(String str, int size, String padStr) {
if (str == null) {
return null;
} else {
if (StringUtils.isEmpty(padStr)) {
padStr = " ";
}
int padLen = padStr.length();
int strLen = lengthKr(str);
int pads = size - strLen;
if (pads <= 0) {
return str;
} else if (padLen == 1 && pads <= 8192) {
return rightPadKr(str, size, padStr.charAt(0));
} else if (pads == padLen) {
return str.concat(padStr);
} else if (pads < padLen) {
return str.concat(padStr.substring(0, pads));
} else {
char[] padding = new char[pads];
char[] padChars = padStr.toCharArray();
for(int i = 0; i < pads; ++i) {
padding[i] = padChars[i % padLen];
}
return str.concat(new String(padding));
}
}
}
/**
* <pre>
* 2, 1 : UTF-8
* 10 , 10 .
* -> 10 2
* -> 2 , 10-2 = 8 .
* @param strText
* @param beginIndex
* @return
* </pre>
*/
public static String substringKr(String strText, int beginIndex) {
if(beginIndex == 0) return strText;
StringBuilder strRtnText = new StringBuilder();
boolean isSkip = true;
for (int i = 0, skipIdx = 0; i<strText.length(); i++) {
if(!isSkip) {
strRtnText.append(strText.charAt(i));
continue;
}
if (strText.charAt(i) > 127)
skipIdx += 2;
else
skipIdx++;
if (skipIdx >= beginIndex){
isSkip = false;
if(skipIdx > beginIndex) strRtnText.append(strText.charAt(i));
}
}
return strRtnText.toString();
}
/**
* <pre>
* : UTF-8
* 2(2), 1(1)
* @param strText
* @param iBytes
* @return
* </pre>
*/
public static String getStringKr(String strText, int iBytes) {
StringBuilder strRtnText = new StringBuilder();
AtomicInteger iByte = new AtomicInteger();
strText.chars().limit(iBytes).forEach(c -> {
strRtnText.append((char) c);
iByte.addAndGet((c > 127) ? 2 : 1);
if (iByte.get() >= iBytes) return;
});
return strRtnText.toString();
}
public static int lengthKr(String strText) {
return strText.chars()
.map(ch -> ch > 127 ? 2 : 1) // 한글(또는 다른 비 ASCII 문자)인 경우 2바이트, 아니면 1바이트
.sum();
}
public static String rightPadKr(String str, int size, char padChar) {
if (str == null) {
return null;
} else {
int pads = size - lengthKr(str);
if (pads <= 0) {
return str;
} else {
return pads > 8192 ? rightPadKr(str, size, java.lang.String.valueOf(padChar)) : str.concat(StringUtils.repeat(padChar, pads));
}
}
}
public static String decodeText(String input, String sourceEncoding, String encoding) throws IOException {
return
new BufferedReader(
new InputStreamReader(
new ByteArrayInputStream(input.getBytes("euc-kr")),
Charset.forName(encoding)))
.readLine();
}
public static void main(String[] args) throws IOException {
final String tgt = new String("123ab한글이ㅂa들어있다열자ㅁ".getBytes(), StandardCharsets.UTF_8);
final String tgt2 = new String("123ab한글이ㅂa들어있다열자ㅁ".getBytes(), StandardCharsets.ISO_8859_1);
final String tgt3 = new String("123ab한글이ㅂa들어있다열자ㅁ".getBytes(), "euc-kr");
System.out.println(tgt2);
System.out.println(covertCharset(tgt2, StandardCharsets.ISO_8859_1, StandardCharsets.UTF_8));
//System.out.println(decodeText(tgt3, "ISO_8859_1", "UTF-8"));
System.out.println(tgt3);
System.out.println(decodeText(tgt3, "euc-kr", "UTF-8"));
System.out.println(covertCharset(tgt3, Charset.forName("euc-kr"), StandardCharsets.UTF_8));
//System.out.println(covertCharset(tgt3, "EUC-KR", "UTF-8"));
System.out.println(substringKr(tgt, 1));
System.out.println(substringKr(tgt, 5));
System.out.println(substringKr(tgt, 6));
System.out.println(substringKr(tgt, 7));
System.out.println(substringKr(tgt, 8));
System.out.println(substringKr("gks한글이시작되는데", 8));
System.out.println(substringKr("한글로abcdefgh계속", 12));
System.out.println(substringKr("1한글2ㅇ ab", 10));
//System.out.println(substringKor(tgt, 11));
;
System.out.println(leftKr(tgt, 18));
System.out.println(leftKr(tgt2, 18));
System.out.println(leftKr(tgt3, 18));
System.out.println("["+rightPadKr("1한글2ㅇ", 10, " ")+"]");
}
}

@ -0,0 +1,289 @@
package cokr.xit.ens.modules.nice.model;
import javax.validation.constraints.*;
import org.apache.commons.lang3.*;
import cokr.xit.ens.core.utils.*;
import io.swagger.v3.oas.annotations.media.*;
import lombok.*;
import lombok.extern.slf4j.*;
/**
* <pre>
* description :
* packageName : cokr.xit.ens.modules.nice.model
* fileName : NiceCiCommon
* author : limju
* date : 2024 9 25
* ======================================================================
*
* ----------------------------------------------------------------------
* 2024 9 25 limju
*
* </pre>
*/
@Schema(name = "NiceCiCommon", description = "NICE CI 전문 공통 DTO")
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Slf4j
public class NiceCiCommon {
/**
* <pre>
* - 9
* "NICEIF "
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "전문그룹코드(9자리)", example = "NICEIF ")
@Size(min = 9, max = 9, message = "전문그룹코드는 9자리 입니다.")
private String grpCode = StringUtils.rightPad("NICEIF", 9, StringUtils.SPACE);
public void setGrpCode(String grpCode) {
this.grpCode = StringUtils.rightPad(nvl(grpCode), 9, StringUtils.SPACE);
}
/**
* <pre>
* - / 4
* "0200" set
* NICE "0210" set
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "거래종별코드(4자리)", example = "0200")
@Size(min = 4, max = 4, message = "거래 종별 코드는 4자리 입니다.")
private String trType = "0200";
public void setTrType(String trType) {
this.trType = StringUtils.rightPad(nvl(trType), 4, StringUtils.SPACE);
}
/**
* <pre>
* - 5
* "31895" set
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "거래구분코드(5자리)", example = "31895")
@Size(min = 5, max = 5, message = "거래 구분 코드는 5자리 입니다.")
private String trClassification = "31895";
public void setTrClassification(String trClassification) {
this.trClassification = StringUtils.rightPad(nvl(trClassification), 5, StringUtils.SPACE);
}
/**
* <pre>
* - / 1
* : "B" set
* NICE "N" set
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "송수신플래그(1자리)", example = "B")
@Size(min = 1, max = 1, message = "송수신 플래그는 1자리 입니다.")
@Setter
private String sndAndRcvFlag = "B";
/**
* <pre>
* - 3
* "503" set
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "단말기구분(3자리)", example = "503")
@Size(min = 1, max = 1, message = "단말기 구분은 3자리 입니다.")
private String deviceClassification = "503";
public void setDeviceClassification(String deviceClassification) {
this.deviceClassification = StringUtils.rightPad(nvl(deviceClassification), 3, StringUtils.SPACE);
}
/**
* <pre>
* - 4 NICE 4
* P000
* P001
* P005 ID
* E998 TimeOut
* E999
* S602
* S702
* S722 Server System
* S316 ( )
* S317 10
* </pre>
*/
@Schema(title = "응답코드(4자리)", example = " ")
@Pattern(regexp = "^$|^[P|E|S][\\d]{3}$", message = "응답코드(4자리)는 4자리 입니다")
private String rsltCode = StringUtils.rightPad(StringUtils.EMPTY, 4, StringUtils.SPACE);
public void setRsltCode(String rsltCode) {
this.rsltCode = StringUtils.rightPad(nvl(rsltCode), 4, StringUtils.SPACE);
}
/**
* <pre>
* ID - 9
* CB H/I NICE USER ID
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "참가기관ID(9자리)", example = "503")
@Size(min = 9, max = 9, message = "참가기관ID는 3자리 입니다.")
private String orgId = StringUtils.rightPad(StringUtils.EMPTY, 9, StringUtils.SPACE);
public void setOrgId(String orgId) {
this.orgId = StringUtils.rightPad(nvl(orgId), 9, StringUtils.SPACE);
}
/**
* <pre>
* - 10
* set
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "기관전문관리번호(10자리)", example = " ")
@Size(min = 10, max = 10, message = "기관전문관리번호는 10자리 입니다.")
private String orgMngNo = StringUtils.rightPad(StringUtils.EMPTY, 10, StringUtils.SPACE);
public void setOrgMngNo(String orgMngNo) {
this.orgMngNo = StringUtils.rightPad(nvl(orgMngNo), 10, StringUtils.SPACE);
}
/**
* <pre>
* - 14
* set
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "기관전문전송시간(14자리)", example = " ")
@Size(min = 14, max = 14, message = "기관전문전송시간은 14자리 입니다.")
private String orgSndDt = DateUtil.getTodayAndNowTime("yyyyMMddHHmmss");
public void setOrgSndDt(String orgSndDt) {
this.orgSndDt = StringUtils.rightPad(nvl(orgSndDt), 14, StringUtils.SPACE);
}
/**
* <pre>
* NICE - 10
* NICE set
* </pre>
*/
@Schema(title = "NICE전문관리번호(10자리)", example = " ")
@Size(min = 10, max = 10, message = "NICE전문관리번호 10자리 입니다.")
private String niceMngNo = StringUtils.rightPad(StringUtils.EMPTY, 10, StringUtils.SPACE);
public void setNiceMngNo(String niceMngNo) {
this.niceMngNo = StringUtils.rightPad(nvl(niceMngNo), 10, StringUtils.SPACE);
}
/**
* <pre>
* NICE - 14
* NICE set
* </pre>
*/
@Schema(title = "NICE전문전송시간(14자리)", example = " ")
@Size(min = 14, max = 14, message = "NICE전문전송시간은 14자리 입니다.")
private String niceSndDt = StringUtils.rightPad(StringUtils.EMPTY, 14, StringUtils.SPACE);
public void setNiceSndDt(String niceSndDt) {
this.niceSndDt = StringUtils.rightPad(nvl(niceSndDt), 14, StringUtils.SPACE);
}
public String ofString() {
StringBuilder sb = new StringBuilder();
sb.append(grpCode);
sb.append(trType);
sb.append(trClassification);
sb.append(sndAndRcvFlag);
sb.append(deviceClassification);
sb.append(rsltCode);
sb.append(orgId);
sb.append(orgMngNo);
sb.append(orgSndDt);
sb.append(niceMngNo);
sb.append(niceSndDt);
return sb.toString();
}
public static NiceCiCommon parse(String tgtString) {
final int[] parseLength = {
9, // 전문그룹코드
4, // 거래종별코드
5, // 거래구분코드
1, // 송수신Flag
3, // 단말기구분
4, // 응답코드
9, // 참가기관ID
10, // 기관전문관리번호
14, // 기관전문전송시간
10, //NICE 전문관리번호
14 // NICE 전문전송시간
};
if (StringUtils.isNotBlank(tgtString) && tgtString.length() >= 83) {
NiceCiCommon nc = new NiceCiCommon();
int idx = 0;
nc.setGrpCode(StringUtils.trim(StringUtils.left(tgtString, parseLength[idx])));
tgtString = tgtString.substring(parseLength[idx++]);
nc.setTrType(StringUtils.trim(StringUtils.left(tgtString, parseLength[idx])));
tgtString = tgtString.substring(parseLength[idx++]);
nc.setTrClassification(StringUtils.trim(StringUtils.left(tgtString, parseLength[idx])));
tgtString = tgtString.substring(parseLength[idx++]);
nc.setSndAndRcvFlag(StringUtils.trim(StringUtils.left(tgtString, parseLength[idx])));
tgtString = tgtString.substring(parseLength[idx++]);
nc.setDeviceClassification(StringUtils.trim(StringUtils.left(tgtString, parseLength[idx])));
tgtString = tgtString.substring(parseLength[idx++]);
nc.setRsltCode(StringUtils.trim(StringUtils.left(tgtString, parseLength[idx])));
tgtString = tgtString.substring(parseLength[idx++]);
nc.setOrgId(StringUtils.trim(StringUtils.left(tgtString, parseLength[idx])));
tgtString = tgtString.substring(parseLength[idx++]);
nc.setOrgMngNo(StringUtils.trim(StringUtils.left(tgtString, parseLength[idx])));
tgtString = tgtString.substring(parseLength[idx++]);
nc.setOrgSndDt(StringUtils.trim(StringUtils.left(tgtString, parseLength[idx])));
tgtString = tgtString.substring(parseLength[idx++]);
nc.setNiceMngNo(StringUtils.trim(StringUtils.left(tgtString, parseLength[idx])));
tgtString = tgtString.substring(parseLength[idx++]);
nc.setNiceSndDt(StringUtils.trim(StringUtils.left(tgtString, parseLength[idx])));
return nc;
}
return null;
}
private static String nvl(String src){
return StringUtils.defaultIfEmpty(src, StringUtils.EMPTY);
}
public static void main(String[] args) {
NiceCiHistoryDTO.Request nr = new NiceCiHistoryDTO.Request();
nr.setTrCode("0000006150");
// // 공통부
//
// // 개별요청부
// nr.setQueryReason(StringUtils.EMPTY);
// nr.setQueryReqCnt(46);
// nr.setSmsSndReqCode("1");
// nr.setSndPhoneNo("010");
// nr.setContactSearchCode("1");
// 공통부
NiceCiCommon nc = new NiceCiCommon();
// nc.setGrpCode("grpCode");
//nc.setTrType("Type");
nc.setTrClassification("31895"); // 거래구분
nc.setOrgId("Z755400"); // 참가기관Id - property 에서
nc.setOrgMngNo("0000000103"); // 기관관리번호
nc.setOrgSndDt("20240919");
System.out.println(NiceCiCommon.parse(nc.ofString()));
//sendNiceSocket();
//serverSocket();
}
}

@ -0,0 +1,724 @@
package cokr.xit.ens.modules.nice.model;
import java.io.*;
import java.util.*;
import java.util.stream.*;
import javax.validation.*;
import javax.validation.constraints.*;
import org.apache.commons.lang3.*;
import cokr.xit.ens.modules.nice.cmm.*;
import io.swagger.v3.oas.annotations.media.*;
import lombok.*;
/**
* <pre>
* description : Nice CI DTO
* Builder X
* -> setter
* packageName : cokr.xit.ens.modules.nice.model
* fileName : NiceDTO
* author : limju
* date : 2024 9 23
* ======================================================================
*
* ----------------------------------------------------------------------
* 2024 9 23 limju
*
* </pre>
*/
public class NiceCiDTO {
@Schema(name = "Request(Nice CI) DTO", description = "NICE CI 요청 전문 DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Request implements Serializable {
private static final long serialVersionUID = 1L;
//----------------------------------------------------------------------------------------------
// TR-CODE : 0 ~ 9 자리
//----------------------------------------------------------------------------------------------
/**
* <pre>
* TR-CODE
* 10
* set
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "TR Code", example = " ")
@Size(min = 10, max = 10, message = "트랜잭션 코드는 10자리 입니다.")
private String trCode = StringUtils.rightPad(StringUtils.EMPTY, 10, StringUtils.SPACE);
public void setTrCode(String trCode) {
this.trCode = StringUtils.rightPad(nvl(trCode), 10, StringUtils.SPACE);
}
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
// 공통부 : 100 자리
//----------------------------------------------------------------------------------------------
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
@Valid
NiceCiCommon niceCommon;
/**
* <pre>
* - 16
* </pre>
*/
@Schema(title = "공란", example = " ")
@Size(min = 16, max = 16, message = "공란(16자리)")
private String commonEmptyField = StringUtils.rightPad(StringUtils.EMPTY, 16, StringUtils.SPACE);
/**
* <pre>
* : 4
* </pre>
*/
@Schema(title = "조회동의사유", example = "4")
@Size(min = 1, max = 1, message = "조회동의사유는 1자리 입니다")
private String queryConsentReason = "4";
//----------------------------------------------------------------------------------------------
// 공통부 : 100 자리
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
// 개별요청부 : 3000 자리
//----------------------------------------------------------------------------------------------
/**
* <pre>
* : 2
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "조회사유", example = " ")
@Size(min = 2, max = 2, message = "조회사유는 2자리 입니다")
private String queryReason = StringUtils.rightPad(StringUtils.EMPTY, 2, StringUtils.SPACE);
public void setQueryReason(String queryReason) {
this.queryReason = StringUtils.rightPad(nvl(queryReason), 2, StringUtils.SPACE);
}
/**
* <pre>
* : 2
* 48
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "조회요청건수", example = " ")
@Max(value = 48, message = "조회요청 최대건수는 48입니다")
private String queryReqCnt = StringUtils.rightPad(StringUtils.EMPTY, 2, StringUtils.SPACE);
public void setQueryReqCnt(Integer queryReqCnt) {
this.queryReqCnt = StringUtils.rightPad(nvl(queryReqCnt == null? "": queryReqCnt.toString()), 2, StringUtils.SPACE);
}
/**
* <pre>
* SMS: 1
* 1 ~ 3
* 0 : ,
* 1: 1 ,
* 2: 1 ~ 2 1
* 3: 1 ~ 3 1
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "SMS발송요청구분코드", example = " ", allowableValues = {"0", "1", "2", "3"})
@Pattern(regexp = "[0-3]", message = "SMS발송요청구분코드 0 ~ 3 입니다(1자리)")
private String smsSndReqCode = StringUtils.SPACE;;
/**
* <pre>
* : 10 ~ 2000
* (smsSndReqCode) 1, 2, 3
* </pre>
*/
@Schema(title = "SMS 발송메세지", example = " ")
@Pattern(regexp = "^$|[\\s]{10,2000}", message = "SMS발송메세지는 10 ~ 2000자리 입니다")
private String sndMessage = StringUtils.rightPad(StringUtils.EMPTY, 2000, StringUtils.SPACE);
public void setSndMessage(String sndMessage) {
this.sndMessage = NiceCiUtils.rightPadKr(nvl(sndMessage), 2000, StringUtils.SPACE);
}
/**
* <pre>
* : 12
* (smsSndReqCode) 1, 2, 3
* </pre>
*/
@Schema(title = "SMS 발신번호", example = " ")
@Pattern(regexp = "^$|[\\d]{3,12}", message = "SMS 발신번호는 3 ~ 12자리 입니다")
private String sndPhoneNo = StringUtils.rightPad(StringUtils.EMPTY, 12, StringUtils.SPACE);
public void setSndPhoneNo(String sndPhoneNo) {
this.sndPhoneNo = StringUtils.rightPad(nvl(sndPhoneNo), 12, StringUtils.SPACE);
}
/**
* <pre>
* : 1
* default: 3
* 1: 1 ,
* 2: 2
* 3: 3
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "연락처조회구분코드", example = " ", allowableValues = {"1", "2", "3"})
@Pattern(regexp = "[1-3]", message = "연락처조회구분 코드는 1 ~ 3 입니다(1자리)")
private String contactSearchCode = "3";
/**
* <pre>
* : 1
* 1(+SMS), 2( ), 3(default: SMS)
* 릿 .
* 1 , SMS. 2 .
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "알림톡발송요청구분", example = " ")
@Size(min = 1, max = 1, message = "알림톡발송요청구분 코드는 1자리 입니다")
private String alimtalkSndReqDiv = "1";
/**
* <pre>
* 릿: 100
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "알림톡템플릿코드", example = " ")
@Size(min = 100, max = 100, message = "알림톡템플릿 코드는 100자리 입니다")
private String alimtalkTmpltCode = StringUtils.rightPad(StringUtils.EMPTY, 100, StringUtils.SPACE);
public void setAlimtalkTmpltCode(String alimtalkTmpltCode) {
this.alimtalkTmpltCode = StringUtils.rightPad(nvl(alimtalkTmpltCode), 100, StringUtils.SPACE);
}
/**
* <pre>
* : 1
* 5
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "버튼요청건수", example = " ")
@Max(value = 5, message = "버튼요청건수는 1자리 입니다")
private String btnReqCnt = StringUtils.SPACE;
public void setBtnReqCnt(Integer btnReqCnt) {
this.btnReqCnt = StringUtils.rightPad(nvl(btnReqCnt == null ? "" : btnReqCnt.toString()), 2, StringUtils.SPACE);
}
/**
* <pre>
* - 880
* </pre>
*/
@Schema(title = "공란", example = " ")
@Size(min = 880, max = 880, message = "공란(880자리)")
private String privateEmptyField = StringUtils.rightPad(StringUtils.EMPTY, 880, StringUtils.SPACE);
//----------------------------------------------------------------------------------------------
// 개별요청부 : 3000 자리
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
// 조회요청부 반복: 50 자리
//----------------------------------------------------------------------------------------------
List<QueryRequest> queryRequests = new ArrayList<>();
//----------------------------------------------------------------------------------------------
// 조회요청부 반복: 50 자리
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
// 버튼요청부 반복: 3000 자리
//----------------------------------------------------------------------------------------------
List<ButtonRequest> buttonRequests = new ArrayList<>();
//----------------------------------------------------------------------------------------------
// 버튼요청부 반복: 3000 자리
//----------------------------------------------------------------------------------------------
public String ofString() {
StringBuilder sb = new StringBuilder();
sb.append(trCode);
// 공통부
sb.append(niceCommon.ofString());
sb.append(commonEmptyField);
sb.append(queryConsentReason);
// 개별요청부
sb.append(queryReason);
sb.append(queryReqCnt);
sb.append(smsSndReqCode);
sb.append(sndMessage);
sb.append(sndPhoneNo);
sb.append(contactSearchCode);
sb.append(alimtalkSndReqDiv);
sb.append(alimtalkTmpltCode);
sb.append(btnReqCnt);
sb.append(privateEmptyField);
sb.append(queryRequests.stream().map(QueryRequest::ofString).collect(Collectors.joining()));
sb.append(buttonRequests.stream().map(ButtonRequest::ofString).collect(Collectors.joining()));
// FIXME: 인코딩확인후 적용
return NiceCiUtils.covertCharset(sb.toString(), "EUC-KR");
}
// public Request parse(String tgtStr) {
// final int repeatLength = 110;
// final int[] parseLength = {
// 10, // tr-code
// 83, // 공통부
// 16, // 공란
// 1, // 조회동의사유
// 2, // 조회사유
// 2, // 조회요청건수
// 1, // SMS발송요청구분코드
// 2000, // SMS 발송메세지
// 12, // SMS 발신번호
// 1, // 연락처조회구분
// 1, // 알림톡발송요청구분
// 100, // 알림톡템플릿코드
// 1, // 버튼요청건수
// 880, // 공란
// 110, // 조회요청반복부
// 3000, // 버튼요청반복
// };
// // FIXME: 인코딩확인후 적용
// String tgtString = new String(tgtStr.getBytes(), StandardCharsets.UTF_8);
//
// if (StringUtils.isNotBlank(tgtString) && tgtString.length() >= 2319) {
// Response response = new Response();
// int idx = 0;
// response.setTrCode(StringUtils.left(tgtString, parseLength[idx]));
// tgtString = tgtString.substring(parseLength[idx++]);
//
// response.setNiceCommon(NiceCommonDTO.parse(tgtString));
// tgtString = tgtString.substring(parseLength[idx++]);
//
// response.setCommonEmptyField(StringUtils.left(tgtString, parseLength[idx]));
// tgtString = tgtString.substring(parseLength[idx++]);
//
// response.setResCnt(StringUtils.left(tgtString, parseLength[idx]));
// tgtString = tgtString.substring(parseLength[idx++]);
//
// response.setSmsSndReqCode(StringUtils.left(tgtString, parseLength[idx]));
// tgtString = tgtString.substring(parseLength[idx++]);
//
// response.setSndMessage(StringUtils.left(tgtString, parseLength[idx]));
// tgtString = tgtString.substring(parseLength[idx++]);
//
// response.setSndPhoneNo(StringUtils.left(tgtString, parseLength[idx]));
// tgtString = tgtString.substring(parseLength[idx++]);
//
// response.setContactSearchCode(StringUtils.left(tgtString, parseLength[idx]));
// tgtString = tgtString.substring(parseLength[idx++]);
//
// response.setPrivateEmptyField(StringUtils.left(tgtString, parseLength[idx]));
// tgtString = tgtString.substring(parseLength[idx]);
//
// if(tgtString.length() % repeatLength == 0){
// int repeat = tgtString.length() / repeatLength;
// String finalTgtString = tgtString;
// List<ResResult> resResults = IntStream.range(0, repeat)
// .mapToObj(i -> {
// String currentString = finalTgtString.substring(i * repeatLength, (i + 1) * repeatLength);
// return ResResult.parse(currentString);
// })
// .collect(Collectors.toList());
// response.setResResults(resResults);
// }
// return response;
// }
// return null;
// }
}
@Schema(name = "Response(Nice CI) DTO", description = "NICE CI 응답 전문 DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Response implements Serializable {
private static final long serialVersionUID = 1L;
//----------------------------------------------------------------------------------------------
// TR-CODE : 0 ~ 9 자리
//----------------------------------------------------------------------------------------------
/**
* <pre>
* TR-CODE
* - max: 9
* </pre>
*/
private String trCode;
public void setTrCode(String trCode) {
this.trCode = StringUtils.trim(trCode);
}
//----------------------------------------------------------------------------------------------
// 공통부 : 100 자리
//----------------------------------------------------------------------------------------------
NiceCiCommon niceCommon;
/**
* <pre>
* - 16
* </pre>
*/
private String commonEmptyField;
public void setCommonEmptyField(String commonEmptyField) {
this.commonEmptyField = StringUtils.trim(commonEmptyField);
}
//----------------------------------------------------------------------------------------------
// 공통부 : 100 자리
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
// 개별응답부 : 2100 자리
//----------------------------------------------------------------------------------------------
/**
* <pre>
* : 2
* 48
* </pre>
*/
private String resCnt;
public void setResCnt(String resCnt) {
this.resCnt = StringUtils.trim(resCnt);
}
/**
* <pre>
* SMS: 1
* 1 ~ 3
* 0 : ,
* 1: 1 ,
* 2: 1 ~ 2 1
* 3: 1 ~ 3 1
* </pre>
*/
private String smsSndReqCode;
public void setSmsSndReq(String smsSndReqCode) {
this.smsSndReqCode = StringUtils.trim(smsSndReqCode);
}
/**
* <pre>
* : 10 ~ 2000
* (smsSndReqCode) 1, 2, 3
* NiceCiUtils.leftKr, substringKr
* </pre>
*/
private String sndMessage;
public void setSndMessage(String sndMessage) {
this.sndMessage = StringUtils.trim(sndMessage);
}
/**
* <pre>
* : 12
* (smsSndReqCode) 1, 2, 3
* </pre>
*/
private String sndPhoneNo;
public void setSndPhoneNo(String sndPhoneNo) {
this.sndPhoneNo = StringUtils.trim(sndPhoneNo);
}
/**
* <pre>
* : 1
* default: 3
* 1: 1 ,
* 2: 2
* 3: 3
* </pre>
*/
private String contactSearchCode = "3";
/**
* <pre>
* - 84
* </pre>
*/
private String privateEmptyField;
public void setPrivateEmptyField(String privateEmptyField) {
this.privateEmptyField = StringUtils.trim(privateEmptyField);
}
//----------------------------------------------------------------------------------------------
// 개별응답부 : 2100 자리
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
// 응답반복부 : 110 자리
//----------------------------------------------------------------------------------------------
List<NiceCiResult> niceCiResults = new ArrayList<>();
//----------------------------------------------------------------------------------------------
// 응답반복부 : 110 자리
//----------------------------------------------------------------------------------------------
// public String ofString() {
// StringBuilder sb = new StringBuilder();
// sb.append(trCode);
// sb.append(niceCommon.ofString());
// sb.append(commonEmptyField);
// sb.append(resCnt);
// sb.append(smsSndReqCode);
// sb.append(sndMessage);
// sb.append(sndPhoneNo);
// sb.append(contactSearchCode);
// sb.append(privateEmptyField);
// sb.append(resResults.stream().map(ResResult::ofString).collect(Collectors.joining()));
// return sb.toString();
// }
public static Response parse(String tgtStr) {
final int repeatLength = 110;
final int[] parseLength = {
10, // tr-code
83, // 공통부
17, // 공란
2, // 응답건수
1, // SMS발송요청구분코드
2000, // SMS 발송메세지
12, // SMS 발신번호
1, // 연락처조회구분
84, // 공란
};
// FIXME: 인코딩확인후 적용
String tgtString = NiceCiUtils.covertCharset(tgtStr, "EUC-KR");
if (StringUtils.isNotBlank(tgtString) && tgtString.length() >= 2319) {
Response response = new Response();
int idx = 0;
response.setTrCode(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
response.setNiceCommon(NiceCiCommon.parse(tgtString));
tgtString = tgtString.substring(parseLength[idx++]);
response.setCommonEmptyField(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
response.setResCnt(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
response.setSmsSndReqCode(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
response.setSndMessage(NiceCiUtils.leftKr(tgtString, parseLength[idx]));
tgtString = NiceCiUtils.substringKr(tgtString, parseLength[idx++]);
response.setSndPhoneNo(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
response.setContactSearchCode(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
response.setPrivateEmptyField(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx]);
if(tgtString.length() % repeatLength == 0){
int repeat = tgtString.length() / repeatLength;
String finalTgtString = tgtString;
List<NiceCiResult> resResults = IntStream.range(0, repeat)
.mapToObj(i -> {
String currentString = finalTgtString.substring(i * repeatLength, (i + 1) * repeatLength);
return NiceCiResult.parse(currentString);
})
.collect(Collectors.toList());
response.setNiceCiResults(resResults);
}
return response;
}
return null;
}
}
@Schema(name = "QueryRequest", description = "NICE CI 조회 요청 DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class QueryRequest {
/**
* <pre>
* // - 1
* 1()
* </pre>
*/
@Schema(title = "개인/사업자/법인구분", example = "1")
@Size(min = 1, max = 1, message = "개인/사업자/법인구분은 1자리 입니다.")
private String idDiv = "1";
/**
* <pre>
* - 13
* </pre>
*/
@Schema(title = "주민번호", example = " ")
@Size(min = 13, max = 13, message = "주민번호는 13자리 입니다.")
private String jumin = StringUtils.rightPad(StringUtils.EMPTY, 13, StringUtils.SPACE);
public void setJumin(String jumin) {
this.jumin = StringUtils.rightPad(nvl(jumin), 13, StringUtils.SPACE);
}
/**
* <pre>
* - 880
* </pre>
*/
@Schema(title = "공란", example = " ")
@Size(min = 36, max = 36, message = "공란(36자리)")
private String emptyField = StringUtils.rightPad(StringUtils.EMPTY, 36, StringUtils.SPACE);
public String ofString() {
StringBuilder sb = new StringBuilder();
sb.append(idDiv);
sb.append(jumin);
sb.append(emptyField);
return sb.toString();
}
}
@Schema(name = "ButtonRequest", description = "NICE CI 버튼 요청 DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class ButtonRequest {
/**
* <pre>
* - 2
* WL|AL
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "버튼타입", example = " ", allowableValues = {"WL", "AL"})
@Pattern(regexp = "[WL|AL]", message = "버튼 타입은 2자리 입니다.")
private String btnType = "WL";
public void setBtnType(String btnType) {
this.btnType = StringUtils.rightPad(nvl(btnType), 2, StringUtils.SPACE);
}
/**
* <pre>
* - 56
* </pre>
*/
@Schema(title = "버튼이름", example = "1")
@Size(min = 56, max = 56, message = "버튼이름은 56자리 입니다.")
private String btnName = StringUtils.rightPad(StringUtils.EMPTY, 56, StringUtils.SPACE);
public void setBtnName(String jumin) {
this.btnName = StringUtils.rightPad(nvl(btnName), 56, StringUtils.SPACE);
}
/**
* <pre>
* URL1 - 1000
* (btnType) WL URL, AL Android scheme
* </pre>
*/
@Schema(title = "버튼URL웹링크1", example = " ")
@Size(min = 1000, max = 1000, message = "버튼URL웹링크1 은 1000자리 입니다.")
private String btnUrlWebLink1 = StringUtils.rightPad(StringUtils.EMPTY, 1000, StringUtils.SPACE);
public void setBtnUrlWebLink1(String btnUrlWebLink1) {
this.btnUrlWebLink1 = StringUtils.rightPad(nvl(btnUrlWebLink1), 1000, StringUtils.SPACE);
}
/**
* <pre>
* URL2 - 1000
* (btnType) WL PC URL, AL IOS scheme
* </pre>
*/
@Schema(title = "버튼URL웹링크2", example = " ")
@Size(min = 1000, max = 1000, message = "버튼URL웹링크2 은 1000자리 입니다.")
private String btnUrlWebLink2 = StringUtils.rightPad(StringUtils.EMPTY, 1000, StringUtils.SPACE);
public void setBtnUrlWebLink2(String btnUrlWebLink2) {
this.btnUrlWebLink2 = StringUtils.rightPad(nvl(btnUrlWebLink2), 1000, StringUtils.SPACE);
}
/**
* <pre>
* - 942
* </pre>
*/
@Schema(title = "공란", example = " ")
@Size(min = 942, max = 942, message = "공란(36자리)")
private String emptyField = StringUtils.rightPad(StringUtils.EMPTY, 942, StringUtils.SPACE);
public String ofString() {
StringBuilder sb = new StringBuilder();
sb.append(btnType);
sb.append(btnName);
sb.append(btnUrlWebLink1);
sb.append(btnUrlWebLink2);
sb.append(emptyField);
return sb.toString();
}
}
public static void main(String[] args) {
NiceCiDTO.Request ciRequest = new NiceCiDTO.Request();
ciRequest.setTrCode("0000006150");
// // 공통부
//
// // 개별요청부
// nr.setQueryReason(StringUtils.EMPTY);
// nr.setQueryReqCnt(46);
// nr.setSmsSndReqCode("1");
ciRequest.setSndMessage("민자도로 관리지원센터에서 김해찬님께 발송한 미납통행료 고지서가 도착했습니다.\n"
+ "\n"
+ "민자도로 미납통행료 고지서\n"
+ "\n"
+ "□ 차량번호 : 19너0914\n"
+ "□ 미납발생 노선 : 서울-문산\n"
+ "□ 미납발생 기간 : 2021년 04월 12일~2023년 08월 30일\n"
+ "□ 납부금액 : 819,500원(42건)\n"
+ "□ 납부기한 : 2024년10월01일\n"
+ "□ 납부방법 : \n"
+ "① 하단의 (납부하기) 클릭\n"
+ "② 가상계좌 납부\n"
+ "-(가상계좌) : 농협은행 792000-36-986609\n"
+ "국민은행 731190-72-253083\n"
+ "우리은행 283752-73-918780\n"
+ "신한은행 562146-27-470101\n"
+ "\n"
+ "※ 알림톡 수신 시 종이고지서는 발송되지 않습니다.\n"
+ "\n"
+ "문의처 : 044-211-3377");
// nr.setSndPhoneNo("010");
// nr.setContactSearchCode("1");
// 공통부
NiceCiCommon nc = new NiceCiCommon();
// nc.setGrpCode("grpCode");
//nc.setTrType("Type");
nc.setTrClassification("31895"); // 거래구분
nc.setOrgId("Z755400"); // 참가기관Id - property 에서
nc.setOrgMngNo("0000000103"); // 기관관리번호
nc.setOrgSndDt("20240919");
QueryRequest qr = new QueryRequest();
ButtonRequest br = new ButtonRequest();
ciRequest.setNiceCommon(nc);
ciRequest.getQueryRequests().add(qr);
ciRequest.getButtonRequests().add(br);
// nc.setNiceMngNo(StringUtils.EMPTY);
// nc.setNiceSndDt(StringUtils.EMPTY);
String fullText = ciRequest.ofString();
System.out.println(String.format("[%s] %d", fullText, fullText.length()));
String resStr = "trCode " +
// NiceCommon
"NICEIF 020031895B503rsltorgId orgMngNo orgSndDt niceMngNo niceSndDt" +
" "+
// 개별응답부
"241~~~~~~~~~~~~~~~~~~~~~~~ 010 1 "+
// 응답반복부
"18401011449211name2 001 "+
"19412341234567이름2 1 ";
NiceCiDTO.Response niceResponse = NiceCiDTO.Response.parse(resStr);
System.out.println(niceResponse);
//sendNiceSocket();
//serverSocket();
}
private static String nvl(String src){
return StringUtils.defaultIfEmpty(src, StringUtils.EMPTY);
}
}

@ -0,0 +1,418 @@
package cokr.xit.ens.modules.nice.model;
import java.io.*;
import java.nio.charset.*;
import java.util.*;
import java.util.stream.*;
import javax.validation.*;
import javax.validation.constraints.*;
import org.apache.commons.lang3.*;
import io.swagger.v3.oas.annotations.media.*;
import lombok.*;
/**
* <pre>
* description : Nice CI DTO
* Builder X
* -> setter
* packageName : cokr.xit.ens.modules.nice.model
* fileName : NiceDTO
* author : limju
* date : 2024 9 23
* ======================================================================
*
* ----------------------------------------------------------------------
* 2024 9 23 limju
*
* </pre>
*/
public class NiceCiHistoryDTO {
@Schema(name = "Request(Nice CI History) DTO", description = "NICE CI 이력 요청 전문 DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Request implements Serializable {
private static final long serialVersionUID = 1L;
//----------------------------------------------------------------------------------------------
// TR-CODE : 0 ~ 9 자리
//----------------------------------------------------------------------------------------------
/**
* <pre>
* TR-CODE
* 10
* set
* </pre>
*/
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, title = "TR Code", example = " ")
@Size(min = 10, max = 10, message = "트랜잭션 코드는 10자리 입니다.")
private String trCode = StringUtils.rightPad(StringUtils.EMPTY, 10, StringUtils.SPACE);
public void setTrCode(String trCode) {
this.trCode = StringUtils.rightPad(nvl(trCode), 10, StringUtils.SPACE);
}
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
// 공통부 : 100 자리
//----------------------------------------------------------------------------------------------
@Schema(requiredMode = Schema.RequiredMode.REQUIRED)
@Valid
NiceCiCommon niceCommon;
/**
* <pre>
* - 17
* </pre>
*/
@Schema(title = "공란", example = " ")
@Size(min = 17, max = 17, message = "공란(16자리)")
private String commonEmptyField = StringUtils.rightPad(StringUtils.EMPTY, 17, StringUtils.SPACE);
//----------------------------------------------------------------------------------------------
// 공통부 : 100 자리
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
// 개별요청부 : 100 자리
//----------------------------------------------------------------------------------------------
/**
* <pre>
* from - 20
* YYYYMMDDHHMMSS(14)+microSecond(6)
* DateUtils.getNowTimeMicrosecond()
* </pre>
*/
@Schema(title = "검색기간 from", example = " ")
@Size(min = 20, max = 20, message = "검색기간 from")
private String fromDt = StringUtils.rightPad(StringUtils.EMPTY, 20, StringUtils.SPACE);
public void setFromDt(String fromDt) {
this.fromDt = StringUtils.rightPad(nvl(fromDt), 20, StringUtils.SPACE);
}
/**
* <pre>
* to - 20
* YYYYMMDDHHMMSS(14)+microSecond(6)
* </pre>
*/
@Schema(title = "검색기간 to", example = " ")
@Size(min = 20, max = 20, message = "검색기간 to")
private String toDt = StringUtils.rightPad(StringUtils.EMPTY, 20, StringUtils.SPACE);
public void setToDt(String toDt) {
this.toDt = StringUtils.rightPad(nvl(toDt), 20, StringUtils.SPACE);
}
/**
* <pre>
* // - 1
* 1()
* </pre>
*/
@Schema(title = "개인/사업자/법인구분", example = "1")
@Size(min = 1, max = 1, message = "개인/사업자/법인구분은 1자리 입니다.")
private String idDiv = "1";
/**
* <pre>
* - 13
* </pre>
*/
@Schema(title = "주민번호", example = " ")
@Size(min = 13, max = 13, message = "주민번호는 13자리 입니다.")
private String jumin = StringUtils.rightPad(StringUtils.EMPTY, 13, StringUtils.SPACE);
public void setJumin(String jumin) {
this.jumin = StringUtils.rightPad(nvl(jumin), 13, StringUtils.SPACE);
}
/**
* <pre>
* - 2
* " " -
* 00 - (SMS , SMS )
* 01 - (// )
* 10 - ( SMS )
* </pre>
*/
@Schema(title = "결과구분코드", example = " ", allowableValues = {" ", "00", "01", "10"})
@Size(min = 2, max = 2, message = "결과구분코드는 2자리 입니다.")
private String rsltDivCode = " ";
public void setRsltDivCode(String rsltDivCode) {
this.rsltDivCode = StringUtils.rightPad(nvl(rsltDivCode), 2, StringUtils.SPACE);
}
/**
* <pre>
* SMS - 1
* 0 : ,
* 1: 1 ,
* 2: 1 ~ 2 1
* 3: 1 ~ 3 1
* 4: 1{1 } + 2{1~2 } + 3{1~3 }
* </pre>
*/
@Schema(title = "SMS발송요청구분", example = " ", allowableValues = {"0", "1", "2", "3", "4"})
@Size(min = 1, max = 1, message = "SMS발송요청구분은 1자리 입니다.")
private String smsSndReqCode = "0";
/**
* <pre>
* - 10
* : 100
* </pre>
*/
@Schema(title = "요청건수", example = " ")
@Max(value = 100, message = "요청건수는 최대 10자리 입니다.")
private String reqCnt = StringUtils.rightPad(StringUtils.EMPTY, 9, StringUtils.SPACE);
public void setReqCnt(String reqCnt){
this.reqCnt = StringUtils.rightPad(nvl(reqCnt), 13, StringUtils.SPACE);
}
/**
* <pre>
* - 10
* "0000000000"
* </pre>
*/
@Schema(title = "누적수신건수", example = " ")
@Max(value = 100, message = "누적수신건수는 최대 10자리 입니다.")
private String accRecvCnt = "0000000000";
public void setAccRecvCnt(String accRecvCnt) {
this.accRecvCnt = StringUtils.rightPad(nvl(accRecvCnt), 10, StringUtils.SPACE);
}
/**
* <pre>
* - 880
* </pre>
*/
@Schema(title = "공란", example = " ")
@Size(min = 23, max = 23, message = "공란(23자리)")
private String privateEmptyField = StringUtils.rightPad(StringUtils.EMPTY, 23, StringUtils.SPACE);
//----------------------------------------------------------------------------------------------
// 개별요청부 : 100 자리
//----------------------------------------------------------------------------------------------
public String ofString() {
StringBuilder sb = new StringBuilder();
sb.append(trCode);
// 공통부
sb.append(niceCommon.ofString());
sb.append(commonEmptyField);
// 개별요청부
sb.append(fromDt);
sb.append(toDt);
sb.append(idDiv);
sb.append(jumin);
sb.append(rsltDivCode);
sb.append(smsSndReqCode);
sb.append(reqCnt);
sb.append(accRecvCnt);
sb.append(privateEmptyField);
// FIXME: 인코딩확인후 적용
return new String(sb.toString().getBytes(), StandardCharsets.UTF_8);
}
}
@Schema(name = "Response(Nice CI History) DTO", description = "NICE CI 이력 응답 전문 DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Response implements Serializable {
private static final long serialVersionUID = 1L;
//----------------------------------------------------------------------------------------------
// TR-CODE : 0 ~ 9 자리
//----------------------------------------------------------------------------------------------
/**
* <pre>
* TR-CODE
* - max: 9
* </pre>
*/
private String trCode;
public void setTrCode(String trCode) {
this.trCode = StringUtils.trim(trCode);
}
//----------------------------------------------------------------------------------------------
// 공통부 : 100 자리
//----------------------------------------------------------------------------------------------
NiceCiCommon niceCommon;
/**
* <pre>
* - 16
* </pre>
*/
private String commonEmptyField;
public void setCommonEmptyField(String commonEmptyField) {
this.commonEmptyField = StringUtils.trim(commonEmptyField);
}
//----------------------------------------------------------------------------------------------
// 공통부 : 100 자리
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
// 개별응답부 : 30 자리
//----------------------------------------------------------------------------------------------
/**
* <pre>
* : 10
* </pre>
*/
private String totalCnt;
public void setTotalCnt(String totalCnt) {
this.totalCnt = StringUtils.trim(totalCnt);
}
/**
* <pre>
* : 10
* </pre>
*/
private String accCnt;
public void setAccCnt(String accCnt) {
this.accCnt = StringUtils.trim(accCnt);
}
/**
* <pre>
* : 10
* 100
* </pre>
*/
private String resCnt;
public void setResCnt(String resCnt) {
this.resCnt = StringUtils.trim(resCnt);
}
//----------------------------------------------------------------------------------------------
// 개별응답부 : 30 자리
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
// 응답반복부 : 1150 자리
//----------------------------------------------------------------------------------------------
List<NiceCiResult> niceCiResults = new ArrayList<>();
//----------------------------------------------------------------------------------------------
// 응답반복부 : 1150 자리
//----------------------------------------------------------------------------------------------
// public String ofString() {
// StringBuilder sb = new StringBuilder();
// sb.append(trCode);
// sb.append(niceCommon.ofString());
// sb.append(commonEmptyField);
// sb.append(resCnt);
// sb.append(smsSndReqCode);
// sb.append(sndMessage);
// sb.append(sndPhoneNo);
// sb.append(contactSearchCode);
// sb.append(privateEmptyField);
// sb.append(resResults.stream().map(ResResult::ofString).collect(Collectors.joining()));
// return sb.toString();
// }
public static Response parse(String tgtStr) {
final int repeatLength = 1150;
final int[] parseLength = {
10, // tr-code
83, // 공통부
17, // 공란
10, // 총건수
10, // 누적건수
10, // 응답건수
};
// FIXME: 인코딩확인후 적용
String tgtString = new String(tgtStr.getBytes(), StandardCharsets.UTF_8);
if (StringUtils.isNotBlank(tgtString) && tgtString.length() >= 1289) {
Response nr = new Response();
int idx = 0;
nr.setTrCode(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
nr.setNiceCommon(NiceCiCommon.parse(tgtString));
tgtString = tgtString.substring(parseLength[idx++]);
nr.setCommonEmptyField(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
nr.setResCnt(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
nr.setTotalCnt(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
nr.setAccCnt(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
nr.setResCnt(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
if(tgtString.length() % repeatLength == 0){
int repeat = tgtString.length() / repeatLength;
String finalTgtString = tgtString;
List<NiceCiResult> resResults = IntStream.range(0, repeat)
.mapToObj(i -> {
String currentString = finalTgtString.substring(i * repeatLength, (i + 1) * repeatLength);
return NiceCiResult.parse(currentString);
})
.collect(Collectors.toList());
nr.setNiceCiResults(resResults);
}
return nr;
}
return null;
}
}
private static String nvl(String src){
return StringUtils.defaultIfEmpty(src, StringUtils.EMPTY);
}
public static void main(String[] args) {
NiceCiHistoryDTO.Request ciHisRequest = new NiceCiHistoryDTO.Request();
ciHisRequest.setTrCode("0000006150");
// // 공통부
//
// // 개별요청부
// ciHisRequest.setQueryReason(StringUtils.EMPTY);
// ciHisRequest.setQueryReqCnt(46);
// ciHisRequest.setSmsSndReqCode("1");
// ciHisRequest.setSndPhoneNo("010");
// ciHisRequest.setContactSearchCode("1");
// 공통부
NiceCiCommon nc = new NiceCiCommon();
// nc.setGrpCode("grpCode");
//nc.setTrType("Type");
nc.setTrClassification("31895"); // 거래구분
nc.setOrgId("Z755400"); // 참가기관Id - property 에서
nc.setOrgMngNo("0000000103"); // 기관관리번호
nc.setOrgSndDt("20240919");
String fullText = ciHisRequest.ofString();
System.out.println(String.format("[%s] %d", fullText, fullText.length()));
String resStr = "trCode " +
// NiceCommon
"NICEIF 020031895B503rsltorgId orgMngNo orgSndDt niceMngNo niceSndDt" +
" "+
// 개별응답부
"241~~~~~~~~~~~~~~~~~~~~~~~ 010 1 "+
// 응답반복부
"18401011449211name2 001 "+
"19412341234567이름2 1 ";
NiceCiHistoryDTO.Response niceResponse = NiceCiHistoryDTO.Response.parse(resStr);
System.out.println(niceResponse);
//sendNiceSocket();
//serverSocket();
}
}

@ -0,0 +1,401 @@
package cokr.xit.ens.modules.nice.model;
import org.apache.commons.lang3.*;
import cokr.xit.ens.modules.nice.cmm.*;
import io.swagger.v3.oas.annotations.media.*;
import lombok.*;
/**
* <pre>
* description :
* packageName : cokr.xit.ens.modules.nice.model
* fileName : NiceCiResult
* author : limju
* date : 2024 9 25
* ======================================================================
*
* ----------------------------------------------------------------------
* 2024 9 25 limju
*
* </pre>
*/
@Schema(name = "NiceCiResult", description = "NICE CI 결과 DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class NiceCiResult {
//------------------------------------------------------------------------------------
// 연락처 이력 조회시만
//------------------------------------------------------------------------------------
/**
* <pre>
* - - 20
* YYYYMMDDHHMMSS(14)+microSecond(6)
* </pre>
*/
private String queryDt;
public void setQueryDt(String queryDt) {
this.queryDt = StringUtils.trim(queryDt);
}
//------------------------------------------------------------------------------------
// 연락처 이력 조회시만
//------------------------------------------------------------------------------------
/**
* <pre>
* // - 1
* 1()
* </pre>
*/
private String idDiv = "1";
/**
* <pre>
* - 13
* </pre>
*/
private String jumin;
public void setJumin(String jumin) {
this.jumin = StringUtils.trim(jumin);
}
/**
* <pre>
* - 20
* NiceCiUtils.leftKr, substringKr
* </pre>
*/
private String name;
public void setName(String name) {
this.name = StringUtils.trim(name);
}
/**
* <pre>
* 1 - 11
* </pre>
*/
private String contractOf1st;
public void setContractOf1st(String contractOf1st) {
this.contractOf1st = StringUtils.trim(contractOf1st);
}
/**
* <pre>
* 2 - 11
* </pre>
*/
private String contractOf2nd;
public void setContractOf2nd(String contractOf2nd) {
this.contractOf2nd = StringUtils.trim(contractOf2nd);
}
/**
* <pre>
* 3 - 11
* </pre>
*/
private String contractOf3rd;
public void setContractOf3rd(String contractOf3rd) {
this.contractOf3rd = StringUtils.trim(contractOf3rd);
}
/**
* <pre>
* - 2
* 00 (SMS , SMS )
* 01
* 02
* 10 ( SMS )
* 99
* </pre>
*/
private String rsltDivCode;
public void setRsltDivCode(String rsltDivCode) {
this.rsltDivCode = StringUtils.trim(rsltDivCode);
}
//------------------------------------------------------------------------------------
// 연락처 이력 조회시만
//------------------------------------------------------------------------------------
/**
* <pre>
* - SMS: 1
* 1 ~ 3 :
* 0 : ,
* 4: (31894)
* </pre>
*/
private String smsSndReqCode;
public void setSmsSndReq(String smsSndReqCode) {
this.smsSndReqCode = StringUtils.trim(smsSndReqCode);
}
/**
* <pre>
* - : 10 ~ 2000
* (smsSndReqCode) 1, 2, 3
* NiceCiUtils.leftKr, substringKr
* </pre>
*/
private String sndMessage;
public void setSndMessage(String sndMessage) {
this.sndMessage = StringUtils.trim(sndMessage);
}
/**
* <pre>
* - : 12
* (smsSndReqCode) 1, 2, 3
* </pre>
*/
private String sndPhoneNo;
public void setSndPhoneNo(String sndPhoneNo) {
this.sndPhoneNo = StringUtils.trim(sndPhoneNo);
}
//------------------------------------------------------------------------------------
// 연락처 이력 조회시만
//------------------------------------------------------------------------------------
/**
* <pre>
* SMS - 1
* 0 : ,
* 1: 1 ,
* 2: 2
* 3: 3
* </pre>
*/
private String smsSndContractOrder = "1";
/**
* <pre>
* SMS - 11
* </pre>
*/
private String smsSndContractNo;
public void setSmsSndContractNo(String smsSndContractNo) {
this.smsSndContractNo = StringUtils.trim(smsSndContractNo);
}
/**
* <pre>
* SMS - 14
* </pre>
*/
private String smsSndWillDt;
public void setSmsSndWillDt(String smsSndWillDt) {
this.smsSndWillDt = StringUtils.trim(smsSndWillDt);
}
//------------------------------------------------------------------------------------
// 연락처 이력 조회시만
//------------------------------------------------------------------------------------
/**
* <pre>
* - ID : 9
* </pre>
*/
private String procId;
public void setProcId(String procId) {
this.procId = StringUtils.trim(procId);
}
/**
* <pre>
* - : 1
* default: 3
* 1: 1 ,
* 2: 2
* 3: 3
* </pre>
*/
private String contactSearchCode = "3";
/**
* <pre>
* - : 1
* 0(), 1( ), 2(SMS/LMS)
* , 0
* </pre>
*/
private String msgSndRsltDivCode;
//------------------------------------------------------------------------------------
// 연락처 이력 조회시만
//------------------------------------------------------------------------------------
/**
* <pre>
* - 15, 11
* </pre>
*/
private String emptyField;
public void setEmptyField(String emptyField) {
this.emptyField = StringUtils.trim(emptyField);
}
// public String ofString() {
// StringBuilder sb = new StringBuilder();
// sb.append(idDiv);
// sb.append(jumin);
// sb.append(name);
// sb.append(contractOf1st);
// sb.append(contractOf2nd);
// sb.append(contractOf3rd);
// sb.append(rsltDivCode);
// sb.append(smsSndContractOrder);
// sb.append(smsSndContractNo);
// sb.append(smsSndWillDt);
// sb.append(emptyField);
// return sb.toString();
// }
public static NiceCiResult parse(String tgtString) {
// 110 자리
final int[] parseLength = {
1, // 개인.사업자.법인구분
13, // 주민번호
20, // 성명
11, // 1순위 연락처
11, // 2순위 연락처
11, // 3순위 연락처
2, // 결과구분
1, // SMS발송 연락처 순위
11, // SMS발송 연락처 번호
14, // SMS발송(예정)일시
15, // 공란
};
if (StringUtils.isNotBlank(tgtString) && tgtString.length()%110 == 0) {
NiceCiResult result = new NiceCiResult();
int idx = 0;
result.setIdDiv(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setJumin(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setName(NiceCiUtils.leftKr(tgtString, parseLength[idx]));
tgtString = NiceCiUtils.substringKr(tgtString, parseLength[idx++]);
result.setContractOf1st(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setContractOf2nd(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setContractOf3rd(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setRsltDivCode(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setSmsSndContractOrder(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setSmsSndContractNo(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setSmsSndWillDt(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setEmptyField(StringUtils.left(tgtString, parseLength[idx]));
return result;
}
return null;
}
public static NiceCiResult parseHistory(String tgtString) {
// 1150
final int[] parseLength = {
20, // 조회일시 - 이력조회시만 사용
1, // 개인.사업자.법인구분
13, // 주민번호
20, // 성명
11, // 1순위 연락처
11, // 2순위 연락처
11, // 3순위 연락처
2, // 결과구분
1, // SMS발송 요청 구분 - 이력조회시만 사용
1000, // 발송메세지 - 이력조회시만 사용
12, // 발신번호 - 이력조회시만 사용
1, // SMS발송 연락처 순위
11, // SMS발송 연락처 번호
14, // SMS발송(예정)일시
9, // 처리자ID - 이력조회시만 사용
1, // 연락처 조회 구분 - 이력조회시만 사용
1, // 메세지발송결과 구붑
11, // 공란
};
if (StringUtils.isNotBlank(tgtString) && tgtString.length()%1150 == 0) {
NiceCiResult result = new NiceCiResult();
int idx = 0;
// 이력조회시만 사용 ////////////////////////////////////////////////////////
result.setQueryDt(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
// 이력조회시만 사용 ////////////////////////////////////////////////////////
result.setIdDiv(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setJumin(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setName(NiceCiUtils.leftKr(tgtString, parseLength[idx]));
tgtString = NiceCiUtils.substringKr(tgtString, parseLength[idx++]);
result.setContractOf1st(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setContractOf2nd(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setContractOf3rd(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setRsltDivCode(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
// 이력조회시만 사용 ////////////////////////////////////////////////////////
result.setSmsSndReqCode(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setSndMessage(NiceCiUtils.leftKr(tgtString, parseLength[idx]));
tgtString = NiceCiUtils.substringKr(tgtString, parseLength[idx++]);
result.setSmsSndContractNo(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
// 이력조회시만 사용 ////////////////////////////////////////////////////////
result.setSmsSndContractOrder(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setSmsSndContractNo(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setSmsSndWillDt(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
// 이력조회시만 사용 ////////////////////////////////////////////////////////
result.setProcId(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setContactSearchCode(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
result.setRsltDivCode(StringUtils.left(tgtString, parseLength[idx]));
tgtString = tgtString.substring(parseLength[idx++]);
// 이력조회시만 사용 ////////////////////////////////////////////////////////
result.setEmptyField(StringUtils.left(tgtString, parseLength[idx]));
return result;
}
return null;
}
private static String nvl(String src){
return StringUtils.defaultIfEmpty(src, StringUtils.EMPTY);
}
}

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save