Merge branch 'api_advc'
This commit is contained in:
commit
6700d30ba6
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
HELP.md
|
HELP.md
|
||||||
target/
|
target/
|
||||||
|
log/
|
||||||
!.mvn/wrapper/maven-wrapper.jar
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
!**/src/main/**/target/
|
!**/src/main/**/target/
|
||||||
!**/src/test/**/target/
|
!**/src/test/**/target/
|
||||||
@ -198,3 +199,4 @@ fabric.properties
|
|||||||
rebel.xml
|
rebel.xml
|
||||||
/mvnw
|
/mvnw
|
||||||
/mvnw.cmd
|
/mvnw.cmd
|
||||||
|
/log.config.path_IS_UNDEFINED/
|
||||||
|
|||||||
5
pom.xml
5
pom.xml
@ -38,6 +38,11 @@
|
|||||||
<!-- <scope>test</scope>-->
|
<!-- <scope>test</scope>-->
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.modelmapper/modelmapper -->
|
<!-- https://mvnrepository.com/artifact/org.modelmapper/modelmapper -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.modelmapper</groupId>
|
<groupId>org.modelmapper</groupId>
|
||||||
|
|||||||
@ -4,10 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
|||||||
import com.itn.mjonApi.cmn.idgen.service.IdgenService;
|
import com.itn.mjonApi.cmn.idgen.service.IdgenService;
|
||||||
import com.itn.mjonApi.cmn.msg.FailRestResponse;
|
import com.itn.mjonApi.cmn.msg.FailRestResponse;
|
||||||
import com.itn.mjonApi.cmn.msg.RestResponse;
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
import com.itn.mjonApi.mjon.api.access.mapper.domain.AccessKeyVO;
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.SendSucRestResponse;
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.MsgRequestVO;
|
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.MsgsRequestVO;
|
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.SendSucRestResponse;
|
|
||||||
import com.itn.mjonApi.mjon.log.service.mapper.LettnAccessLogMapper;
|
import com.itn.mjonApi.mjon.log.service.mapper.LettnAccessLogMapper;
|
||||||
import com.itn.mjonApi.mjon.log.service.mapper.LettnApiSendMsgLogMapper;
|
import com.itn.mjonApi.mjon.log.service.mapper.LettnApiSendMsgLogMapper;
|
||||||
import com.itn.mjonApi.mjon.log.service.mapper.MjMsgGroupDataMapper;
|
import com.itn.mjonApi.mjon.log.service.mapper.MjMsgGroupDataMapper;
|
||||||
@ -59,6 +56,7 @@ public class LogAspect {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
MjMsgGroupDataMapper mjMsgGroupDataMapper;
|
MjMsgGroupDataMapper mjMsgGroupDataMapper;
|
||||||
|
|
||||||
@Resource(name = "apiAccessLog")
|
@Resource(name = "apiAccessLog")
|
||||||
private IdgenService idgenApiAccessLogId;
|
private IdgenService idgenApiAccessLogId;
|
||||||
|
|
||||||
@ -72,16 +70,28 @@ public class LogAspect {
|
|||||||
* - mberId
|
* - mberId
|
||||||
* - accessKey
|
* - accessKey
|
||||||
*/
|
*/
|
||||||
@Before(value = "execution(* com.itn.mjonApi.mjon.api.*..*Impl.*(..))" )
|
// @Before(value = "execution(* com.itn.mjonApi.mjon.api.*..*Impl.*(..))" )
|
||||||
|
@Before("execution(* com.itn.mjonApi.mjon.api..*Controller.*(..)) || execution(* com.itn.mjonApi.mjon.api..*Impl.*(..))")
|
||||||
public void before(JoinPoint joinPoint) throws IllegalAccessException, JsonProcessingException {
|
public void before(JoinPoint joinPoint) throws IllegalAccessException, JsonProcessingException {
|
||||||
log.info(" :: AOP before :: ");
|
log.info(" :: AOP before :: ");
|
||||||
|
//
|
||||||
|
// for (Object arg : joinPoint.getArgs()) {
|
||||||
|
// if (arg == null) continue;
|
||||||
|
//
|
||||||
|
// // JSON 직렬화해서 VO 전체 출력
|
||||||
|
// log.info("VO 전체: {}", new ObjectMapper().writeValueAsString(arg));
|
||||||
|
// log.info("VO 클래스명: {}", arg.getClass().getName());
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
HttpServletRequest request = this.getHttpServletRequest();
|
HttpServletRequest request = this.getHttpServletRequest();
|
||||||
|
|
||||||
// VO 객체를 가져옴
|
// VO 객체를 가져옴
|
||||||
Object objectVO = joinPoint.getArgs()[0];
|
Object objectVO = joinPoint.getArgs()[0];
|
||||||
|
|
||||||
log.info("joinPoint.getArgs()[0] :: [{}]", joinPoint.getArgs()[0]);
|
// log.info("joinPoint.getArgs()[0] :: [{}]", joinPoint.getArgs()[0]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -91,16 +101,27 @@ public class LogAspect {
|
|||||||
String mberId = "";
|
String mberId = "";
|
||||||
String accessKey = "";
|
String accessKey = "";
|
||||||
for(Field field : objectVO.getClass().getDeclaredFields()){;
|
for(Field field : objectVO.getClass().getDeclaredFields()){;
|
||||||
field.setAccessible(true);
|
try {
|
||||||
|
// JDK 내부 클래스 필드는 무시
|
||||||
log.info("field.getName() :: [{}]", field.getName());
|
if (field.getDeclaringClass().getName().startsWith("java.")) continue;
|
||||||
log.info("field.get(objectVO) :: [{}]", field.get(objectVO));
|
field.setAccessible(true);
|
||||||
|
if ("mberId".equals(field.getName())) {
|
||||||
|
mberId = String.valueOf(field.get(objectVO));
|
||||||
|
log.info("mberId :: [{}]", mberId);
|
||||||
|
}
|
||||||
|
// log.info("field.get(objectVO) :: [{}]", field.get(objectVO));
|
||||||
|
|
||||||
|
|
||||||
if("mberId".equals(field.getName())){ mberId=field.get(objectVO).toString(); }
|
if("mberId".equals(field.getName())){ mberId=field.get(objectVO).toString(); }
|
||||||
else if("accessKey".equals(field.getName())){ accessKey=field.get(objectVO).toString(); }
|
else if("accessKey".equals(field.getName())){ accessKey=field.get(objectVO).toString(); }
|
||||||
|
|
||||||
if(StringUtils.isNotEmpty(mberId) && StringUtils.isNotEmpty(accessKey)){ break; }
|
if(StringUtils.isNotEmpty(mberId) && StringUtils.isNotEmpty(accessKey)){ break; }
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
log.warn("접근 불가 필드 스킵: {}", field.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String nextStringId = idgenApiAccessLogId.getNextStringId();
|
String nextStringId = idgenApiAccessLogId.getNextStringId();
|
||||||
@ -162,7 +183,9 @@ public class LogAspect {
|
|||||||
lettnApiSendMsgLogMapper.insert(apiSendMsgLogVO);
|
lettnApiSendMsgLogMapper.insert(apiSendMsgLogVO);
|
||||||
|
|
||||||
// 메세지 그룹 테이블에 발송 구분 업데이트
|
// 메세지 그룹 테이블에 발송 구분 업데이트
|
||||||
this.updateMsgGroupTbSendKind(apiSendMsgLogVO);
|
// mjon_git에서 처리하는걸로 수정
|
||||||
|
// 20250729 이호영
|
||||||
|
// this.updateMsgGroupTbSendKind(apiSendMsgLogVO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,18 +195,18 @@ public class LogAspect {
|
|||||||
* @description 메세지 그룹 테이블에 발송 구분 업데이트
|
* @description 메세지 그룹 테이블에 발송 구분 업데이트
|
||||||
* @param apiSendMsgLogVO
|
* @param apiSendMsgLogVO
|
||||||
*/
|
*/
|
||||||
private void updateMsgGroupTbSendKind(LettnApiSendMsgLogVO apiSendMsgLogVO) {
|
// private void updateMsgGroupTbSendKind(LettnApiSendMsgLogVO apiSendMsgLogVO) {
|
||||||
if(StringUtils.isNotEmpty(apiSendMsgLogVO.getMsgGroupId()))
|
// if(StringUtils.isNotEmpty(apiSendMsgLogVO.getMsgGroupId()))
|
||||||
{
|
// {
|
||||||
String[] msgGroupIds = null;
|
// String[] msgGroupIds = null;
|
||||||
if(apiSendMsgLogVO.getMsgGroupId().indexOf(",") > -1){
|
// if(apiSendMsgLogVO.getMsgGroupId().indexOf(",") > -1){
|
||||||
msgGroupIds = apiSendMsgLogVO.getMsgGroupId().split(",");
|
// msgGroupIds = apiSendMsgLogVO.getMsgGroupId().split(",");
|
||||||
}else{
|
// }else{
|
||||||
msgGroupIds = new String[]{apiSendMsgLogVO.getMsgGroupId()};
|
// msgGroupIds = new String[]{apiSendMsgLogVO.getMsgGroupId()};
|
||||||
}
|
// }
|
||||||
mjMsgGroupDataMapper.update(msgGroupIds);
|
// mjMsgGroupDataMapper.update(msgGroupIds);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description lettngnrlmber_api_send_msg_log 테이블에 저장할 데이터 만들기
|
* @description lettngnrlmber_api_send_msg_log 테이블에 저장할 데이터 만들기
|
||||||
@ -252,6 +275,7 @@ public class LogAspect {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private static String getClassNmFromObject(Object returnValue) {
|
private static String getClassNmFromObject(Object returnValue) {
|
||||||
String classNmTemp = returnValue.getClass().getName();
|
String classNmTemp = returnValue.getClass().getName();
|
||||||
|
log.info("getClassNmFromObject :: [{}]", classNmTemp);
|
||||||
String classNm = classNmTemp.substring(classNmTemp.lastIndexOf(".")+1, classNmTemp.length());
|
String classNm = classNmTemp.substring(classNmTemp.lastIndexOf(".")+1, classNmTemp.length());
|
||||||
return classNm;
|
return classNm;
|
||||||
}
|
}
|
||||||
@ -312,37 +336,29 @@ public class LogAspect {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String getJsonToString(Object returnValue) throws JsonProcessingException {
|
public String getJsonToString(Object returnValue) throws JsonProcessingException {
|
||||||
|
if (ObjectUtils.isEmpty(returnValue)) {
|
||||||
if(ObjectUtils.isEmpty(returnValue)){
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String classNm = this.getClassNmFromObject(returnValue);
|
String classNm = this.getClassNmFromObject(returnValue);
|
||||||
|
|
||||||
/**
|
// 처리 대상 클래스 목록 (선택적으로 필터링하고 싶다면 여기에 조건)
|
||||||
* @description : return Class가 추가되면 여기에 추가
|
switch (classNm) {
|
||||||
*/
|
case "AccessKeyVO":
|
||||||
if("AccessKeyVO".equals(classNm)) {
|
case "RestResponse":
|
||||||
AccessKeyVO accessKeyVO = (AccessKeyVO) returnValue;
|
case "MsgsRequestVO":
|
||||||
return ApiObjectUtil.getAccessKeyVOToJsonString(accessKeyVO);
|
case "MsgRequestVO":
|
||||||
|
case "MjKakaoProfileInfoVO":
|
||||||
|
case "BizTemplateRequest":
|
||||||
|
case "MsgAtRequestVO":
|
||||||
|
case "MsgFtRequestVO":
|
||||||
|
case "String":
|
||||||
|
case "ArrayList":
|
||||||
|
return ApiObjectUtil.toJson(returnValue);
|
||||||
|
default:
|
||||||
|
log.info("데이터를 추가해 주세요 [{}]", classNm);
|
||||||
|
return "데이터를 추가해 주세요";
|
||||||
}
|
}
|
||||||
else if("RestResponse".equals(classNm)){
|
|
||||||
RestResponse restResponse = (RestResponse) returnValue;
|
|
||||||
return ApiObjectUtil.getRestResponseToJsonString(restResponse);
|
|
||||||
}
|
|
||||||
else if("MsgsRequestVO".equals(classNm)){
|
|
||||||
MsgsRequestVO msgsRequestVO = (MsgsRequestVO) returnValue;
|
|
||||||
return ApiObjectUtil.getMsgsRequestVOToJsonString(msgsRequestVO);
|
|
||||||
}
|
|
||||||
else if("MsgRequestVO".equals(classNm)){
|
|
||||||
MsgRequestVO restResponse = (MsgRequestVO) returnValue;
|
|
||||||
return ApiObjectUtil.getMsgRequestVOToJsonString(restResponse);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return "데이터를 추가해 주세요";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,22 @@
|
|||||||
package com.itn.mjonApi.cmn.apiServer;
|
package com.itn.mjonApi.cmn.apiServer;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.MjonResponseVO;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import org.springframework.http.ResponseEntity;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.itn.mjonApi.cmn.domain.StatusResponse;
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.BizTemplateRequest;
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.detail.TemplateDetailResponse;
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.list.TemplateListResponse;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.MsgFtRequestVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.MjonResponseVO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.*;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* packageName : com.itn.mjonApi.cmn.apiServer
|
* packageName : com.itn.mjonApi.cmn.apiServer
|
||||||
@ -18,6 +30,7 @@ import org.springframework.web.client.RestTemplate;
|
|||||||
* -----------------------------------------------------------
|
* -----------------------------------------------------------
|
||||||
* 2023-05-15 hylee 최초 생성
|
* 2023-05-15 hylee 최초 생성
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class ApiService <T> {
|
public class ApiService <T> {
|
||||||
|
|
||||||
@ -37,13 +50,120 @@ public class ApiService <T> {
|
|||||||
* @throws JsonProcessingException
|
* @throws JsonProcessingException
|
||||||
*/
|
*/
|
||||||
public MjonResponseVO postForEntity(String url, Object request, Class<String> responseType) throws JsonProcessingException {
|
public MjonResponseVO postForEntity(String url, Object request, Class<String> responseType) throws JsonProcessingException {
|
||||||
ResponseEntity<String> spamChkEntity = (ResponseEntity<String>) restTemplate.postForEntity(
|
ResponseEntity<String> returnEntity = (ResponseEntity<String>) restTemplate.postForEntity(
|
||||||
url
|
url
|
||||||
, request
|
, request
|
||||||
, responseType
|
, responseType
|
||||||
);
|
);
|
||||||
MjonResponseVO spamResponse = MjonResponseVO.getMjonResponse(spamChkEntity);
|
log.info("returnEntity :: [{}]", returnEntity.toString());
|
||||||
return spamResponse;
|
// ObjectMapper로 JSON 파싱
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
JsonNode rootNode = mapper.readTree(returnEntity.getBody());
|
||||||
|
|
||||||
|
// log.info("rootNode :: [{}]", rootNode.toString());
|
||||||
|
|
||||||
|
|
||||||
|
// "apiReturn" 필드만 추출
|
||||||
|
JsonNode apiReturnNode = rootNode.get("apiReturn");
|
||||||
|
if (apiReturnNode == null || apiReturnNode.isNull()) {
|
||||||
|
log.warn("apiReturn 필드가 응답에 존재하지 않습니다.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MjonResponseVO.getMjonResponse(apiReturnNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param
|
||||||
|
* @return
|
||||||
|
* @throws Exception 처리 중 예외 발생 가능
|
||||||
|
* @date 2025-07-29
|
||||||
|
* @Discription 알림톡 템플릿 리스트 조회
|
||||||
|
* @author hylee
|
||||||
|
*/
|
||||||
|
public TemplateListResponse postForBizTemplateListEntity(String url, BizTemplateRequest requestDto) throws JsonProcessingException {
|
||||||
|
|
||||||
|
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<BizTemplateRequest> requestEntity = new HttpEntity<>(requestDto, headers);
|
||||||
|
|
||||||
|
TemplateListResponse returnEntity = restTemplate.exchange(
|
||||||
|
url,
|
||||||
|
HttpMethod.POST,
|
||||||
|
requestEntity,
|
||||||
|
TemplateListResponse.class
|
||||||
|
).getBody();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return returnEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param
|
||||||
|
* @return
|
||||||
|
* @throws Exception 처리 중 예외 발생 가능
|
||||||
|
* @date 2025-07-29
|
||||||
|
* @Discription 알림톡 템플릿 상세 조회
|
||||||
|
* @author hylee
|
||||||
|
*/
|
||||||
|
public TemplateDetailResponse postForBizTemplateDetailEntity(String url, BizTemplateRequest requestDto) throws JsonProcessingException {
|
||||||
|
|
||||||
|
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<BizTemplateRequest> requestEntity = new HttpEntity<>(requestDto, headers);
|
||||||
|
|
||||||
|
TemplateDetailResponse returnEntity = restTemplate.exchange(
|
||||||
|
url,
|
||||||
|
HttpMethod.POST,
|
||||||
|
requestEntity,
|
||||||
|
TemplateDetailResponse.class
|
||||||
|
).getBody();
|
||||||
|
|
||||||
|
log.info("returnEntity :: [{}]", returnEntity.toString());
|
||||||
|
|
||||||
|
|
||||||
|
return returnEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatusResponse postMultipartForEntity(String url, MsgFtRequestVO msgFtRequestVO, MultipartFile templateImage) {
|
||||||
|
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
|
||||||
|
|
||||||
|
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
|
||||||
|
|
||||||
|
// 파일 추가
|
||||||
|
body.add("templateImage", templateImage.getResource());
|
||||||
|
|
||||||
|
// MsgFtRequestVO 필드들을 kakaoVO에 맞게 매핑
|
||||||
|
if (msgFtRequestVO.getSendKind() != null) {
|
||||||
|
body.add("sendKind", msgFtRequestVO.getSendKind());
|
||||||
|
}
|
||||||
|
if ( msgFtRequestVO.getTemplateMsgType() != null) {
|
||||||
|
body.add("imageType", msgFtRequestVO.getTemplateMsgType());
|
||||||
|
}
|
||||||
|
if (msgFtRequestVO.getTemplateCode() != null) {
|
||||||
|
body.add("templateCode", msgFtRequestVO.getTemplateCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
|
||||||
|
|
||||||
|
ResponseEntity<StatusResponse> response = restTemplate.exchange(
|
||||||
|
url,
|
||||||
|
HttpMethod.POST,
|
||||||
|
requestEntity,
|
||||||
|
StatusResponse.class
|
||||||
|
);
|
||||||
|
|
||||||
|
// log.info("Upload response :: [{}]", response.getBody());
|
||||||
|
return response.getBody();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
src/main/java/com/itn/mjonApi/cmn/domain/CmnVO.java
Normal file
19
src/main/java/com/itn/mjonApi/cmn/domain/CmnVO.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@SuperBuilder
|
||||||
|
public class CmnVO {
|
||||||
|
|
||||||
|
private String mberId; // 사용자 ID
|
||||||
|
|
||||||
|
private String accessKey; // Api Key
|
||||||
|
}
|
||||||
@ -1,104 +1,15 @@
|
|||||||
package com.itn.mjonApi.mjon.api.send.mapper.domain;
|
package com.itn.mjonApi.cmn.domain;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* packageName : com.itn.mjonApi.mjon.api.send.mapper.domain
|
|
||||||
* fileName : MjonMsgVO
|
|
||||||
* author : hylee
|
|
||||||
* date : 2023-05-23
|
|
||||||
* description : 문자 발송에 필요한 값들을 받는 vo
|
|
||||||
* 1건~500건 대량 문자 개인별로 발송
|
|
||||||
* ===========================================================
|
|
||||||
* DATE AUTHOR NOTE
|
|
||||||
* -----------------------------------------------------------
|
|
||||||
* 2023-05-09 hylee 최초 생성
|
|
||||||
*/
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class MsgsRequestVO implements Serializable {
|
public class SendRequestCmnVO {
|
||||||
|
|
||||||
/**
|
|
||||||
* 값이 있는 경우
|
|
||||||
* 문자온 프로젝트에서 처리해줌
|
|
||||||
* null이면 에러
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private String mberId; // 사용자 ID
|
|
||||||
|
|
||||||
private String accessKey; // Api Key
|
|
||||||
|
|
||||||
private String smsTxt; // SMS용 메시지본문
|
|
||||||
|
|
||||||
private String[] callToList; // 수신번호리스트
|
|
||||||
|
|
||||||
private String callFrom; // 발신번호 :: 정책이 필요함
|
|
||||||
|
|
||||||
private String eachPrice = "0"; // 전송문자 개별가격
|
|
||||||
private String sPrice = "0"; // 임시
|
|
||||||
|
|
||||||
private String totPrice = "0"; // 전송문자 토탈가격
|
|
||||||
|
|
||||||
private String fileCnt = "0"; // 첨부파일 갯수
|
|
||||||
|
|
||||||
private String msgType = "4"; // 메시지의 (4: SMS 전송, 5: URL 전송, 6: MMS전송, 7: BARCODE전송, 8: 카카오 알림톡 전송)
|
|
||||||
|
|
||||||
// ==== 단가 ====
|
|
||||||
private float smsPrice = 0; // sms 단가 null 이면 에러
|
|
||||||
|
|
||||||
private float mmsPrice = 0; // mms 단가 null 이면 에러
|
|
||||||
// private float kakaoAtPrice; // 카카오 알림톡 단가
|
|
||||||
// private float kakaoFtPrice; // 카카오 친구톡 단가
|
|
||||||
// private float kakaoFtImgPrice;// 카카오 이미지 단가
|
|
||||||
// private float kakaoFtWideImgPrice; // 카카오 와이드 이미지 단가
|
|
||||||
|
|
||||||
private String[] imgFilePath = new String[0]; // 그림 이미지 경로
|
|
||||||
|
|
||||||
|
|
||||||
private String spamStatus; // 스팸문자 유무 (Y/N) - 서비스단에서 처리 함
|
|
||||||
|
|
||||||
private String txtReplYn = "N"; // 변환문자 유무 (Y/N) - 서비스단에서 처리 함
|
|
||||||
|
|
||||||
// private String nameStr; // value = "치환 이름 리스트 |로 구분", example = "홍길동1|홍길동2|홍길동3"
|
|
||||||
|
|
||||||
// private String rep1Str; // value = "치환 문자1 리스트 |로 구분", example = ""
|
|
||||||
|
|
||||||
// private String rep2Str; // value = "치환 문자2 리스트 |로 구분", example = ""
|
|
||||||
|
|
||||||
// private String rep3Str; // value = "치환 문자3 리스트 |로 구분", example = ""
|
|
||||||
|
|
||||||
// private String rep4Str; // value = "치환 문자4 리스트 |로 구분", example = ""
|
|
||||||
|
|
||||||
// private String[] nameList= new String[0]; // value = "nameStr 을 |로 split 후 담는 변수", example = ""
|
|
||||||
|
|
||||||
// private String[] rep1List= new String[0]; // value = "rep1Str 을 |로 split 후 담는 변수", example = ""
|
|
||||||
|
|
||||||
// private String[] rep2List= new String[0]; // value = "rep2Str 을 |로 split 후 담는 변수", example = ""
|
|
||||||
|
|
||||||
// private String[] rep3List= new String[0]; // value = "rep3Str 을 |로 split 후 담는 변수", example = ""
|
|
||||||
|
|
||||||
// private String[] rep4List= new String[0]; // value = "rep4Str 을 |로 split 후 담는 변수", example = ""
|
|
||||||
|
|
||||||
private String reserveYn = "N"; // value = "예약 유무 (Y/N)", example = "N"
|
|
||||||
|
|
||||||
// 치환 있을 경우 사용
|
|
||||||
// private String shortMsgCnt; // value = "치환 후 단문 건수", example = ""
|
|
||||||
|
|
||||||
// private String longMsgCnt; // value = "치환 후 장문 건수", example = ""
|
|
||||||
|
|
||||||
|
|
||||||
// @ApiModelProperty(value = "문자 종류 일반:N, 광고:A, 선거:C", example = "N", hidden = true)
|
|
||||||
private String msgKind = "N"; // '문자 종류 일반:N, 광고:A, 선거:C',
|
|
||||||
|
|
||||||
private String test_yn; // 테스트 여부
|
|
||||||
|
|
||||||
// 수신자 발송txt 각각 _1~_100
|
// 수신자 발송txt 각각 _1~_100
|
||||||
// 교차로 있어야 로직이 가능함
|
// 교차로 있어야 로직이 가능함
|
||||||
@ -1105,6 +1016,4 @@ public class MsgsRequestVO implements Serializable {
|
|||||||
// private String smsTxt_498;
|
// private String smsTxt_498;
|
||||||
// private String smsTxt_499;
|
// private String smsTxt_499;
|
||||||
// private String smsTxt_500;
|
// private String smsTxt_500;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
41
src/main/java/com/itn/mjonApi/cmn/domain/StatusResponse.java
Normal file
41
src/main/java/com/itn/mjonApi/cmn/domain/StatusResponse.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* • 1XX : 조건부 응답
|
||||||
|
* • 2XX : 성공
|
||||||
|
* • 3XX : 리다이렉션 완료
|
||||||
|
* • 4XX : 요청 오류
|
||||||
|
* • 500 : 서버 오류
|
||||||
|
*
|
||||||
|
* 참고 : https://km0830.tistory.com/33
|
||||||
|
*
|
||||||
|
* ====== 자주 사용하는 코드 =====
|
||||||
|
* 200 : Ok : 서버가 클라이언트의 요청을 성공적으로 처리, 웹 페이지에서는 페이지 요청이 정상적으로 완료 (Ok)
|
||||||
|
* 400 : Bad Request : 잘못 요청 (Bad Request)
|
||||||
|
* 401 : Unauthorized : 권한 없음, 예를 들면, 로그인 페이지가 필요한 페이지를 로그인 없이 접속하려는 경우 반환되는 코드 (인증 실패) (Unauthorized)
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@ToString
|
||||||
|
public class StatusResponse {
|
||||||
|
|
||||||
|
private HttpStatus status;
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
private Object object;
|
||||||
|
|
||||||
|
private Object apiReturn;
|
||||||
|
|
||||||
|
private String messageTemp;
|
||||||
|
|
||||||
|
// private String timestamp;
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template;
|
||||||
|
|
||||||
|
import com.itn.mjonApi.cmn.domain.CmnVO;
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@SuperBuilder
|
||||||
|
public class BizTemplateRequest extends CmnVO {
|
||||||
|
private String bizId;
|
||||||
|
private String apiKey;
|
||||||
|
private String senderKey;
|
||||||
|
private String templateCode;
|
||||||
|
private String test_yn;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template.detail;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class CommentsAttachment {
|
||||||
|
private String originalFileName;
|
||||||
|
private String filePath;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template.detail;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class TemplateButton {
|
||||||
|
private String bizFormId;
|
||||||
|
private String linkAnd;
|
||||||
|
private String linkIos;
|
||||||
|
private String linkMo;
|
||||||
|
private String linkPc;
|
||||||
|
private String linkType;
|
||||||
|
private String name;
|
||||||
|
private String ordering;
|
||||||
|
private String pluginId;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template.detail;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class TemplateComments {
|
||||||
|
private String content;
|
||||||
|
private String createdAt;
|
||||||
|
private String status;
|
||||||
|
private List<CommentsAttachment> attachment;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template.detail;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class TemplateDetail {
|
||||||
|
private String block;
|
||||||
|
private String categoryCode;
|
||||||
|
private String createdAt;
|
||||||
|
private String dormant;
|
||||||
|
private String inspectionStatus;
|
||||||
|
private String modifiedAt;
|
||||||
|
private String securityFlag;
|
||||||
|
private String senderKey;
|
||||||
|
private String senderKeyType;
|
||||||
|
private String status;
|
||||||
|
private String templateCode;
|
||||||
|
private String templateContent;
|
||||||
|
private String templateEmphasizeType;
|
||||||
|
private String templateExtra;
|
||||||
|
private String templateHeader;
|
||||||
|
private String templateImageName;
|
||||||
|
private String templateImageUrl;
|
||||||
|
private String templateMessageType;
|
||||||
|
private String templateName;
|
||||||
|
private String templateSubtitle;
|
||||||
|
private String templateTitle;
|
||||||
|
private TemplateItemHighlight templateItemHighlight;
|
||||||
|
private TemplateItem templateItem;
|
||||||
|
private List<TemplateButton> buttons;
|
||||||
|
private List<TemplateComments> comments;
|
||||||
|
private List<TemplateQuickReplies> quickReplies;
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template.detail;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class TemplateDetailResponse {
|
||||||
|
|
||||||
|
private String code;
|
||||||
|
private String message;
|
||||||
|
private TemplateDetail data;
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template.detail;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class TemplateItem {
|
||||||
|
private List<TemplateItemItem> list;
|
||||||
|
private TemplateItemSummary summary;
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template.detail;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class TemplateItemHighlight {
|
||||||
|
private String title; // 아이템 타이틀
|
||||||
|
private String description; // 상세 설명
|
||||||
|
private String imageUrl; // 썸네일 이미지 주소
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template.detail;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class TemplateItemItem {
|
||||||
|
private String title;
|
||||||
|
private String description;
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template.detail;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class TemplateItemSummary {
|
||||||
|
private String title;
|
||||||
|
private String description;
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template.detail;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class TemplateQuickReplies {
|
||||||
|
private String name;
|
||||||
|
private String linkType;
|
||||||
|
private String linkAnd;
|
||||||
|
private String linkIos;
|
||||||
|
private String linkMo;
|
||||||
|
private String linkPc;
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template.list;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 템플릿 상태를 나타내는 열거형 클래스.
|
||||||
|
* - API 응답의 상태 코드(EX: REG)를 사람이 읽기 쉽게 변환하는 데 사용됨.
|
||||||
|
*/
|
||||||
|
public enum ServiceStatusEnum {
|
||||||
|
|
||||||
|
REG("등록완료"), // REG: 등록 완료된 템플릿
|
||||||
|
RDY("대기"), // RDY: 대기 상태
|
||||||
|
ACT("활성"), // ACT: 활성화 상태
|
||||||
|
DMT("중단"), // DMT: 중단된 템플릿
|
||||||
|
REJ("반려"), // REJ: 반려된 템플릿
|
||||||
|
UNKNOWN("알 수 없음"); // 정의되지 않은 상태
|
||||||
|
|
||||||
|
private final String label; // 한글 설명
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 생성자
|
||||||
|
* @param label 상태의 한글 설명
|
||||||
|
*/
|
||||||
|
ServiceStatusEnum(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 한글 설명 반환
|
||||||
|
*/
|
||||||
|
public String getLabel() {
|
||||||
|
return this.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 코드값을 받아 "[코드](한글설명)" 형태 문자열로 반환
|
||||||
|
* @param code 상태 코드 (예: REG, ACT 등)
|
||||||
|
* @return 예: "REG(등록완료)", "DMT(중단)", "FOO(알 수 없음)"
|
||||||
|
*/
|
||||||
|
public static String getLabelByCode(String code) {
|
||||||
|
for (ServiceStatusEnum status : values()) {
|
||||||
|
if (status.name().equalsIgnoreCase(code)) {
|
||||||
|
return status.name() + "(" + status.getLabel() + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return code + "(알 수 없음)";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template.list;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
public class TemplateInfo {
|
||||||
|
private String senderKey;
|
||||||
|
private String senderKeyType;
|
||||||
|
private String templateCode;
|
||||||
|
private String templateName;
|
||||||
|
private String createdAt;
|
||||||
|
private String modifiedAt;
|
||||||
|
private String categoryCode;
|
||||||
|
private String serviceStatus;
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template.list;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
public class TemplateListData {
|
||||||
|
private List<TemplateInfo> list;
|
||||||
|
private boolean hasNext;
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.itn.mjonApi.cmn.domain.biz.template.list;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
public class TemplateListResponse {
|
||||||
|
private String code;
|
||||||
|
private String message;
|
||||||
|
private int totalCount;
|
||||||
|
private int totalPage;
|
||||||
|
private int currentPage;
|
||||||
|
private TemplateListData data;
|
||||||
|
}
|
||||||
@ -58,7 +58,6 @@ public class IdgenServiceImpl implements IdgenService {
|
|||||||
// nextId 값 만들기
|
// nextId 값 만들기
|
||||||
String nextId = prefixTemp + idgenVO.getNextId();
|
String nextId = prefixTemp + idgenVO.getNextId();
|
||||||
|
|
||||||
log.info(" userId : [{}]", nextId);
|
|
||||||
return nextId;
|
return nextId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -53,6 +53,33 @@ public class CertifInterceptor implements HandlerInterceptor{
|
|||||||
String serverIp = ""; //접속 server IP
|
String serverIp = ""; //접속 server IP
|
||||||
|
|
||||||
try{
|
try{
|
||||||
|
/*
|
||||||
|
|
||||||
|
String contentType = request.getContentType();
|
||||||
|
log.info("요청 contentType: {}", contentType);
|
||||||
|
//
|
||||||
|
if("application/json".equals(contentType) )
|
||||||
|
{
|
||||||
|
|
||||||
|
BufferedReader reader = request.getReader();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
sb.append(line);
|
||||||
|
}
|
||||||
|
String body = sb.toString();
|
||||||
|
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
JsonNode jsonNode = mapper.readTree(body);
|
||||||
|
String mberId = jsonNode.get("mberId").asText();
|
||||||
|
String accessKey = jsonNode.get("accessKey").asText();
|
||||||
|
|
||||||
|
log.info("mberId :: [{}]", mberId);
|
||||||
|
log.info("accessKey :: [{}]", accessKey);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
String clientIp = null;
|
String clientIp = null;
|
||||||
boolean isIpInHeader = false;
|
boolean isIpInHeader = false;
|
||||||
|
|
||||||
@ -150,8 +177,9 @@ public class CertifInterceptor implements HandlerInterceptor{
|
|||||||
//referer 값이 없으면 serverIP 값으로 대체한다.
|
//referer 값이 없으면 serverIP 값으로 대체한다.
|
||||||
if ("".equals(referer) || referer==null) {
|
if ("".equals(referer) || referer==null) {
|
||||||
referer = serverIp;
|
referer = serverIp;
|
||||||
}
|
}
|
||||||
log.info("certi request.getParameter(\"accessKey\") :: [{}]", request.getParameter("accessKey"));
|
referer= "119.193.215.98";
|
||||||
|
// log.info("certi request.getParameter(\"accessKey\") :: [{}]", request.getParameter("accessKey"));
|
||||||
// hylee Builder 패턴으로 변경 => 20230516
|
// hylee Builder 패턴으로 변경 => 20230516
|
||||||
AccessKeyVO accessKeyVO = accessKeyService.selectRKey(
|
AccessKeyVO accessKeyVO = accessKeyService.selectRKey(
|
||||||
new AccessKeyVO().builder()
|
new AccessKeyVO().builder()
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
package com.itn.mjonApi.cmn.model;
|
package com.itn.mjonApi.cmn.model;
|
||||||
|
|
||||||
import com.itn.mjonApi.mjon.api.inqry.mapper.PriceMapper;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.PriceMapper;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.mapper.domain.PriceVO;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.PriceVO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
@ -19,6 +20,7 @@ import java.util.Map;
|
|||||||
* 2023-07-03 hylee 최초 생성
|
* 2023-07-03 hylee 최초 생성
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class Price {
|
public class Price {
|
||||||
|
|
||||||
@ -29,48 +31,88 @@ public class Price {
|
|||||||
double mberMoney = priceMapper.selectMberMoney(mberId);
|
double mberMoney = priceMapper.selectMberMoney(mberId);
|
||||||
|
|
||||||
//시스템 단가 변수
|
//시스템 단가 변수
|
||||||
double sys_shortPrice = 0.0f;
|
double sys_shortPrice = 0.0f;
|
||||||
double sys_longPrice = 0.0f;
|
double sys_longPrice = 0.0f;
|
||||||
double sys_picturePrice = 0.0f;
|
double sys_picturePrice = 0.0f;
|
||||||
|
double sys_kakaoAtPrice = 0.0f;
|
||||||
|
double sys_kakaoFtPrice = 0.0f;
|
||||||
|
double sys_kakaoFtImgPrice = 0.0f;
|
||||||
|
double sys_kakaoFtWideImgPrice = 0.0f;
|
||||||
|
|
||||||
//최종 단가 변수
|
//최종 단가 변수
|
||||||
double shortPrice = 0.0f;
|
double shortPrice = 0.0f;
|
||||||
double longPrice = 0.0f;
|
double longPrice = 0.0f;
|
||||||
double picturePrice = 0.0f;
|
double picturePrice = 0.0f;
|
||||||
|
double kakaoAtPrice = 0.0f;
|
||||||
|
double kakaoFtPrice = 0.0f;
|
||||||
|
double kakaoFtImgPrice = 0.0f;
|
||||||
|
double kakaoFtWideImgPrice = 0.0f;
|
||||||
|
|
||||||
//1.시스템 기본 단가, 사용자 개인단가 정보 불러오기
|
//1.시스템 기본 단가, 사용자 개인단가 정보 불러오기
|
||||||
Map<String, String> priceMap = priceMapper.selectMberPriceInfo(mberId);
|
Map<String, String> priceMap = priceMapper.selectMberPriceInfo(mberId);
|
||||||
|
|
||||||
//1-2.단가 계산을 위한 set
|
//1-2.단가 계산을 위한 set
|
||||||
sys_shortPrice = Double.parseDouble(String.valueOf(priceMap.get("sysShortPrice")));
|
sys_shortPrice = Double.parseDouble(String.valueOf(priceMap.get("sysShortPrice")));
|
||||||
sys_longPrice = Double.parseDouble(String.valueOf(priceMap.get("sysLongPrice")));
|
sys_longPrice = Double.parseDouble(String.valueOf(priceMap.get("sysLongPrice")));
|
||||||
sys_picturePrice = Double.parseDouble(String.valueOf(priceMap.get("sysPicturePrice")));
|
sys_picturePrice = Double.parseDouble(String.valueOf(priceMap.get("sysPicturePrice")));
|
||||||
|
|
||||||
|
sys_kakaoAtPrice = Double.parseDouble(String.valueOf(priceMap.get("sysKakaoAtPrice")));
|
||||||
|
sys_kakaoFtPrice = Double.parseDouble(String.valueOf(priceMap.get("sysKakaoFtPrice")));
|
||||||
|
sys_kakaoFtImgPrice = Double.parseDouble(String.valueOf(priceMap.get("sysKakaoFtImgPrice")));
|
||||||
|
sys_kakaoFtWideImgPrice = Double.parseDouble(String.valueOf(priceMap.get("sysKakaoFtWideImgPrice")));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
shortPrice = Double.parseDouble(String.valueOf(priceMap.get("shortPrice")));
|
shortPrice = Double.parseDouble(String.valueOf(priceMap.get("shortPrice")));
|
||||||
longPrice = Double.parseDouble(String.valueOf(priceMap.get("longPrice")));
|
longPrice = Double.parseDouble(String.valueOf(priceMap.get("longPrice")));
|
||||||
picturePrice = Double.parseDouble(String.valueOf(priceMap.get("picturePrice")));
|
picturePrice = Double.parseDouble(String.valueOf(priceMap.get("picturePrice")));
|
||||||
|
|
||||||
|
kakaoAtPrice = Double.parseDouble(String.valueOf(priceMap.get("kakaoAtPrice")));
|
||||||
|
kakaoFtPrice = Double.parseDouble(String.valueOf(priceMap.get("kakaoFtPrice")));
|
||||||
|
kakaoFtImgPrice = Double.parseDouble(String.valueOf(priceMap.get("kakaoFtImgPrice")));
|
||||||
|
kakaoFtWideImgPrice = Double.parseDouble(String.valueOf(priceMap.get("kakaoFtWideImgPrice")));
|
||||||
|
|
||||||
//1-3. 최종 단가 계산
|
//1-3. 최종 단가 계산
|
||||||
shortPrice = shortPrice == 0.0f ? sys_shortPrice : shortPrice;
|
shortPrice = shortPrice == 0.0f ? sys_shortPrice : shortPrice;
|
||||||
longPrice = longPrice == 0.0f ? sys_longPrice : longPrice;
|
longPrice = longPrice == 0.0f ? sys_longPrice : longPrice;
|
||||||
picturePrice = picturePrice == 0.0f ? sys_picturePrice : picturePrice;
|
picturePrice = picturePrice == 0.0f ? sys_picturePrice : picturePrice;
|
||||||
|
|
||||||
|
kakaoAtPrice = kakaoAtPrice == 0.0f ? sys_kakaoAtPrice : kakaoAtPrice;
|
||||||
|
kakaoFtPrice = kakaoFtPrice == 0.0f ? sys_kakaoFtPrice : kakaoFtPrice;
|
||||||
|
kakaoFtImgPrice = kakaoFtImgPrice == 0.0f ? sys_kakaoFtImgPrice : kakaoFtImgPrice;
|
||||||
|
kakaoFtWideImgPrice = kakaoFtWideImgPrice == 0.0f ? sys_kakaoFtWideImgPrice : kakaoFtWideImgPrice;
|
||||||
|
|
||||||
//2. 단가별 발송 가능건수 계산을위한 변수 set
|
//2. 단가별 발송 가능건수 계산을위한 변수 set
|
||||||
int shortSendPsbltEa = 0;
|
int shortSendPsbltEa = 0;
|
||||||
int longSendPsbltEa = 0;
|
int longSendPsbltEa = 0;
|
||||||
int pictureSendPsbltEa = 0;
|
int pictureSendPsbltEa = 0;
|
||||||
|
|
||||||
|
int kakaoAtSendPsbltEa = 0;
|
||||||
|
int kakaoFtSendPsbltEa = 0;
|
||||||
|
int kakaoFtImgSendPsbltEa = 0;
|
||||||
|
int kakaoFtWideImgSendPsbltEa = 0;
|
||||||
|
|
||||||
//2-1. 소수점 연산을 위한 BigDecimal Casting
|
//2-1. 소수점 연산을 위한 BigDecimal Casting
|
||||||
BigDecimal mberMoney_big = new BigDecimal(String.valueOf(mberMoney));
|
BigDecimal mberMoney_big = new BigDecimal(String.valueOf(mberMoney));
|
||||||
BigDecimal shortPrice_big = new BigDecimal(String.valueOf(priceMap.get("sysShortPrice")));
|
BigDecimal shortPrice_big = new BigDecimal(String.valueOf(shortPrice));
|
||||||
BigDecimal longPrice_big = new BigDecimal(String.valueOf(priceMap.get("sysLongPrice")));
|
BigDecimal longPrice_big = new BigDecimal(String.valueOf(longPrice));
|
||||||
BigDecimal picturePrice_big = new BigDecimal(String.valueOf(priceMap.get("sysPicturePrice")));
|
BigDecimal picturePrice_big = new BigDecimal(String.valueOf(picturePrice));
|
||||||
|
|
||||||
|
BigDecimal kakaoAtPrice_big = new BigDecimal(String.valueOf(kakaoAtPrice));
|
||||||
|
BigDecimal kakaoFtPrice_big = new BigDecimal(String.valueOf(kakaoFtPrice));
|
||||||
|
BigDecimal kakaoFtImgPrice_big = new BigDecimal(String.valueOf(kakaoFtImgPrice));
|
||||||
|
BigDecimal kakaoFtWideImgPrice_big = new BigDecimal(String.valueOf(kakaoFtWideImgPrice));
|
||||||
|
|
||||||
//2-2. mberMoney가 0일경우 제외
|
//2-2. mberMoney가 0일경우 제외
|
||||||
if(mberMoney_big.compareTo(BigDecimal.ZERO) != 0) {
|
if(mberMoney_big.compareTo(BigDecimal.ZERO) != 0) {
|
||||||
shortSendPsbltEa = mberMoney_big.divide(shortPrice_big, BigDecimal.ROUND_DOWN).intValue();
|
shortSendPsbltEa = mberMoney_big.divide(shortPrice_big, BigDecimal.ROUND_DOWN).intValue();
|
||||||
longSendPsbltEa = mberMoney_big.divide(longPrice_big, BigDecimal.ROUND_DOWN).intValue();
|
longSendPsbltEa = mberMoney_big.divide(longPrice_big, BigDecimal.ROUND_DOWN).intValue();
|
||||||
pictureSendPsbltEa = mberMoney_big.divide(picturePrice_big, BigDecimal.ROUND_DOWN).intValue();
|
pictureSendPsbltEa = mberMoney_big.divide(picturePrice_big, BigDecimal.ROUND_DOWN).intValue();
|
||||||
|
|
||||||
|
kakaoAtSendPsbltEa = mberMoney_big.divide(kakaoAtPrice_big, BigDecimal.ROUND_DOWN).intValue();
|
||||||
|
kakaoFtSendPsbltEa = mberMoney_big.divide(kakaoFtPrice_big, BigDecimal.ROUND_DOWN).intValue();
|
||||||
|
kakaoFtImgSendPsbltEa = mberMoney_big.divide(kakaoFtImgPrice_big, BigDecimal.ROUND_DOWN).intValue();
|
||||||
|
kakaoFtWideImgSendPsbltEa = mberMoney_big.divide(kakaoFtWideImgPrice_big, BigDecimal.ROUND_DOWN).intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
//result set
|
//result set
|
||||||
@ -78,11 +120,28 @@ public class Price {
|
|||||||
.shortPrice(shortPrice)
|
.shortPrice(shortPrice)
|
||||||
.longPrice(longPrice)
|
.longPrice(longPrice)
|
||||||
.picturePrice(picturePrice)
|
.picturePrice(picturePrice)
|
||||||
|
|
||||||
|
.kakaoAtPrice(kakaoAtPrice)
|
||||||
|
.kakaoFtPrice(kakaoFtPrice)
|
||||||
|
.kakaoFtImgPrice(kakaoFtImgPrice)
|
||||||
|
.kakaoFtWideImgPrice(kakaoFtWideImgPrice)
|
||||||
|
|
||||||
|
|
||||||
.shortSendPsbltEa(shortSendPsbltEa)
|
.shortSendPsbltEa(shortSendPsbltEa)
|
||||||
.longSendPsbltEa(longSendPsbltEa)
|
.longSendPsbltEa(longSendPsbltEa)
|
||||||
.pictureSendPsbltEa(pictureSendPsbltEa)
|
.pictureSendPsbltEa(pictureSendPsbltEa)
|
||||||
|
|
||||||
|
.kakaoAtSendPsbltEa(kakaoAtSendPsbltEa)
|
||||||
|
.kakaoFtSendPsbltEa(kakaoFtSendPsbltEa)
|
||||||
|
.kakaoFtImgSendPsbltEa(kakaoFtImgSendPsbltEa)
|
||||||
|
.kakaoFtWideImgSendPsbltEa(kakaoFtWideImgSendPsbltEa)
|
||||||
|
|
||||||
.mberMoney(mberMoney)
|
.mberMoney(mberMoney)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
log.info(" + priceVO :: [{}]", priceVO);
|
||||||
|
|
||||||
|
|
||||||
return priceVO;
|
return priceVO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
package com.itn.mjonApi.cmn.msg;
|
package com.itn.mjonApi.cmn.msg;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.*;
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@ -11,6 +8,7 @@ import java.time.LocalDateTime;
|
|||||||
@Getter
|
@Getter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ToString
|
||||||
public class RestResponse{
|
public class RestResponse{
|
||||||
|
|
||||||
private String resultCode = "0";
|
private String resultCode = "0";
|
||||||
|
|||||||
@ -33,7 +33,8 @@ public enum StatMsg {
|
|||||||
// 문자보내기 ======================================================================
|
// 문자보내기 ======================================================================
|
||||||
STAT_0("0","")
|
STAT_0("0","")
|
||||||
, STAT_1010("1010","발신자 전화번호 사용 불가")
|
, STAT_1010("1010","발신자 전화번호 사용 불가")
|
||||||
, STAT_1020("1020","수신자 전화번호 오류")
|
, STAT_1020("1020","수신자 전화번호 오류") // ㅂ
|
||||||
|
, STAT_1021("1021","수신거부 번호 제거 후 수신자 목록 없음")
|
||||||
, STAT_1030("1030","문자 내용 발송 불가")
|
, STAT_1030("1030","문자 내용 발송 불가")
|
||||||
, STAT_1040("1040","치환 데이터 오류")
|
, STAT_1040("1040","치환 데이터 오류")
|
||||||
, STAT_1050("1050","치환 후 문자 길이 초과")
|
, STAT_1050("1050","치환 후 문자 길이 초과")
|
||||||
@ -43,6 +44,28 @@ public enum StatMsg {
|
|||||||
, STAT_1090("1090","요청 발송일시에 발송 불가") // 아직 사용 안함
|
, STAT_1090("1090","요청 발송일시에 발송 불가") // 아직 사용 안함
|
||||||
, STAT_1099("1099","기타 시스템 오류")
|
, STAT_1099("1099","기타 시스템 오류")
|
||||||
|
|
||||||
|
//카톡발송======================================================================
|
||||||
|
, STAT_2010("2010","발신프로필 KEY 오류")
|
||||||
|
, STAT_2030("2030","템플릿 코드 오류")
|
||||||
|
, STAT_2040("2040","본문 데이터 오류")
|
||||||
|
, STAT_2041("2041","타이틀 데이터 오류")
|
||||||
|
, STAT_2042("2042","대체문자 데이터 오류")
|
||||||
|
, STAT_2043("2043","대체문자 발송 시 발신번호가 필요합니다.")
|
||||||
|
|
||||||
|
, STAT_2050("2050","지원하지 않는 이미지 형식입니다.")
|
||||||
|
, STAT_2051("2051","이미지 용량은 5MB 이내여야 합니다.")
|
||||||
|
, STAT_2052("2052","이미지를 읽을 수 없습니다.")
|
||||||
|
, STAT_2053("2053","지원하지 않는 이미지 형식입니다.")
|
||||||
|
, STAT_2054("2054","이미지 가로폭인 500px 미만입니다.")
|
||||||
|
, STAT_2055("2055","유효한 이미지 파일이 없습니다.")
|
||||||
|
, STAT_2056("2056","비율 2:1 이상 또는 3:4 이하만 허용됩니다.")
|
||||||
|
, STAT_2057("2057","대체문자(MMS) 이미지는 10MB를 초과할 수 없습니다.")
|
||||||
|
|
||||||
|
, STAT_2080("2080","친구톡은 20시 50분부터 익일 08시까지 발송이 제한됩니다.")
|
||||||
|
|
||||||
|
, STAT_2099("2099","기타 시스템 오류")
|
||||||
|
|
||||||
|
|
||||||
//전체발송======================================================================
|
//전체발송======================================================================
|
||||||
, STAT_3099("3099","기타 시스템 오류")
|
, STAT_3099("3099","기타 시스템 오류")
|
||||||
|
|
||||||
@ -52,9 +75,12 @@ public enum StatMsg {
|
|||||||
//발송가능건수======================================================================
|
//발송가능건수======================================================================
|
||||||
, STAT_5099("5099","기타 시스템 오류")
|
, STAT_5099("5099","기타 시스템 오류")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
, msgType4("단문","SMS")
|
, msgType4("단문","SMS")
|
||||||
, msgType6("장문","LMS")
|
, msgType6("장문","LMS")
|
||||||
|
, msgType8("알림톡","AT")
|
||||||
|
|
||||||
|
|
||||||
;
|
;
|
||||||
@ -68,13 +94,17 @@ public enum StatMsg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Random을 만들기 위한 코드
|
// Random을 만들기 위한 코드
|
||||||
|
// 모든 enum 항목을 불변 리스트로 저장
|
||||||
private static final List<StatMsg> VALUES = Collections.unmodifiableList(Arrays.asList(values()));
|
private static final List<StatMsg> VALUES = Collections.unmodifiableList(Arrays.asList(values()));
|
||||||
|
// 전체 항목 수
|
||||||
private static final int SIZE = VALUES.size();
|
private static final int SIZE = VALUES.size();
|
||||||
|
// 랜덤 인스턴스
|
||||||
private static final Random RANDOM = new Random();
|
private static final Random RANDOM = new Random();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description : 랜덤한 에러코드를 반환한다.
|
* 랜덤한 에러코드를 반환한다.
|
||||||
* @return errorCode
|
* 단, 코드 값이 3자리 이하(예: "단문", "장문")인 항목은 제외된다.
|
||||||
|
* @return "STAT_코드" 형식의 문자열
|
||||||
*/
|
*/
|
||||||
public static String randomErrorStatCode() {
|
public static String randomErrorStatCode() {
|
||||||
String errorCode = "";
|
String errorCode = "";
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import com.itn.mjonApi.util.email.EmailVO;
|
|||||||
import com.itn.mjonApi.util.email.SendMail;
|
import com.itn.mjonApi.util.email.SendMail;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jsoup.Jsoup;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -16,7 +15,6 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* packageName : com.itn.mjonApi.etc.ganpandaum.service.impl
|
* packageName : com.itn.mjonApi.etc.ganpandaum.service.impl
|
||||||
@ -70,33 +68,16 @@ public class GdServiceImpl implements GdService {
|
|||||||
SendMail sMail = new SendMail();
|
SendMail sMail = new SendMail();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
emailContent = Jsoup.connect(GANPANDAUP_ESTIMATE_TEMPLATE_URL)
|
|
||||||
.data("query", "Java")
|
|
||||||
.userAgent("Mozilla")
|
|
||||||
.cookie("auth", "token")
|
|
||||||
.timeout(3000)
|
|
||||||
.post()
|
|
||||||
.toString();
|
|
||||||
// ./src/main/resources/templates/estimate.html
|
|
||||||
emailContent = emailContent
|
|
||||||
.replace("[[_Company_]]", gdVO.getGdCompany())
|
|
||||||
.replace("[[_Name_]]", gdVO.getGdName())
|
|
||||||
.replace("[[_Phone_]]", gdVO.getGdPhone())
|
|
||||||
.replace("[[_Email_]]", gdVO.getGdEmail())
|
|
||||||
.replace("[[_Addr_]]", gdVO.getGdAddr())
|
|
||||||
.replace("[[_Content_]]", gdVO.getGdContent())
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 메일 첨부파일을 위한 절대경로
|
// 메일 첨부파일을 위한 절대경로
|
||||||
// 메일 제목
|
// 메일 제목
|
||||||
String mailTitle = "[간판다움 견적의뢰] "+gdVO.getGdName()+"["+gdVO.getGdCompany()+"]님의 견적 의뢰입니다._"+LocalDate.now();
|
|
||||||
|
|
||||||
sMail.itnSendMail(
|
sMail.itnSendMail(
|
||||||
EmailVO.builder()
|
EmailVO.builder()
|
||||||
.title(mailTitle)
|
.title("현재달 월급명세서 전달드립니다.")
|
||||||
.contents(emailContent)
|
.contents("안녕하세요 귀하에 노고에 감사드립니다. 비밀번호는 생년워일입니다.")
|
||||||
.fileInfo(p_file)
|
.fileInfo(p_file)
|
||||||
.atch_file_name(fileNm)
|
.atch_file_name(fileNm)
|
||||||
.send_to(GANPANDAUP_RECEIVER_EMAIL)
|
.send_to(GANPANDAUP_RECEIVER_EMAIL)
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
package com.itn.mjonApi.mjon.api.inqry.mapper.domain;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@Builder
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class PriceVO implements Serializable{
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -7865729705175845268L;
|
|
||||||
|
|
||||||
private String mberId; // 사용자 ID
|
|
||||||
|
|
||||||
private double shortPrice; // 단문 이용단가
|
|
||||||
private double longPrice; // 장문 이용단가
|
|
||||||
private double picturePrice; // 그림 이용단가
|
|
||||||
|
|
||||||
private double mberMoney; // 잔액
|
|
||||||
|
|
||||||
private int shortSendPsbltEa; // 단문 발송 가능건 수
|
|
||||||
private int longSendPsbltEa; // 장문 발송 가능건 수
|
|
||||||
private int pictureSendPsbltEa; // 그림 발송 가능건 수
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper;
|
||||||
|
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.domain.MjKakaoProfileInfoVO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* packageName : com.itn.mjonApi.mjon.api.kakao.inqry.mapper
|
||||||
|
* fileName : InqryMapper
|
||||||
|
* author : hylee
|
||||||
|
* date : 2025-06-27
|
||||||
|
* description :
|
||||||
|
* ===========================================================
|
||||||
|
* DATE AUTHOR NOTE
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* 2025-06-27 hylee 최초 생성
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface InqryMapper {
|
||||||
|
|
||||||
|
List<MjKakaoProfileInfoVO> getChnlIds(String mberId);
|
||||||
|
|
||||||
|
int isTemplateExist(Map<String, Object> params);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.domain;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.itn.mjonApi.cmn.domain.CmnVO;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@ToString
|
||||||
|
public class MjKakaoProfileInfoVO extends CmnVO {
|
||||||
|
private String profileId; // 회원 프로필 번호
|
||||||
|
private String userId; // 회원 아이디
|
||||||
|
private String senderKey; // 발신 프로필 키
|
||||||
|
private String token; // 수신받은 인증 토큰정보
|
||||||
|
private String phoneNumber; // 카카오톡 채널 핸드폰 번호
|
||||||
|
private String yellowId; // 카카오톡 채널(@ID)
|
||||||
|
private String categoryCode; // 카테고리 코드
|
||||||
|
private String categoryName; // 카테고리 코드 명칭
|
||||||
|
private String frstRegistPnttm; // 등록 일자
|
||||||
|
private String frstRegisterId; // 등록자
|
||||||
|
private String lastUpdtPnttm; // 수정 일자
|
||||||
|
private String lastUpdusrId; // 수정자
|
||||||
|
private String deleteYn; // 삭제 여부 (Y/N)
|
||||||
|
}
|
||||||
@ -0,0 +1,190 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.at.inqry.service.Impl;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.itn.mjonApi.cmn.apiServer.ApiService;
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.BizTemplateRequest;
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.detail.TemplateDetailResponse;
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.list.ServiceStatusEnum;
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.list.TemplateInfo;
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.list.TemplateListResponse;
|
||||||
|
import com.itn.mjonApi.cmn.msg.FailRestResponse;
|
||||||
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.InqryMapper;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.domain.MjKakaoProfileInfoVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.inqry.service.InqryService;
|
||||||
|
import com.itn.mjonApi.util.TestDataUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.catalina.connector.Response;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* packageName : com.itn.mjonApi.mjon.api.kakao.inqry.service.Impl
|
||||||
|
* fileName : InqryServiceImpl
|
||||||
|
* author : hylee
|
||||||
|
* date : 2025-06-27
|
||||||
|
* description :
|
||||||
|
* ===========================================================
|
||||||
|
* DATE AUTHOR NOTE
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* 2025-06-27 hylee 최초 생성
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class InqryServiceImpl implements InqryService {
|
||||||
|
|
||||||
|
|
||||||
|
private ApiService<Response> apiService;
|
||||||
|
|
||||||
|
@Value("${biz.root.url}")
|
||||||
|
private String BIZ_ROOT_URL;
|
||||||
|
@Value("${biz.api.key}")
|
||||||
|
private String BIZ_API_KEY;
|
||||||
|
@Value("${biz.id}")
|
||||||
|
private String BIZ_ID;
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
InqryMapper inqryMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public InqryServiceImpl(ApiService<Response> apiService) {
|
||||||
|
this.apiService = apiService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RestResponse getChnlId(BizTemplateRequest bizTemplateRequest) {
|
||||||
|
|
||||||
|
String mberId = bizTemplateRequest.getMberId();
|
||||||
|
String testYn = bizTemplateRequest.getTest_yn();
|
||||||
|
|
||||||
|
// 테스트 모드 확인
|
||||||
|
if(StringUtils.isNotEmpty(bizTemplateRequest.getTest_yn())) {
|
||||||
|
return TestDataUtil.getChnlIdTestData(testYn);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<MjKakaoProfileInfoVO> voList = inqryMapper.getChnlIds(mberId);
|
||||||
|
|
||||||
|
return new RestResponse(voList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RestResponse getTemplates(BizTemplateRequest bizTemplateRequest) throws JsonProcessingException {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 테스트 모드 확인
|
||||||
|
if(StringUtils.isNotEmpty(bizTemplateRequest.getTest_yn())) {
|
||||||
|
return TestDataUtil.getTemplateListTestData(bizTemplateRequest.getTest_yn());
|
||||||
|
}
|
||||||
|
|
||||||
|
// SenderKey 검증
|
||||||
|
RestResponse STAT_2010 = isSenderKeyChk(bizTemplateRequest);
|
||||||
|
if (STAT_2010 != null) return STAT_2010;
|
||||||
|
|
||||||
|
|
||||||
|
// 1. 템플릿 목록 조회 요청 DTO 생성 (BIZ ID, API Key, senderKey 포함)
|
||||||
|
BizTemplateRequest requestDto= BizTemplateRequest.builder()
|
||||||
|
.bizId(BIZ_ID)
|
||||||
|
.apiKey(BIZ_API_KEY)
|
||||||
|
.senderKey(bizTemplateRequest.getSenderKey())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 2. 외부 API 호출 - 템플릿 목록 요청 (/v3/kakao/template/list)
|
||||||
|
TemplateListResponse response = apiService.postForBizTemplateListEntity(
|
||||||
|
BIZ_ROOT_URL+"/v3/kakao/template/list"
|
||||||
|
, requestDto
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// 3. 응답 코드가 "0" (성공) 이 **아닌 경우** => 실패 처리 (STAT_4099 반환 : 기타 시스템 오류)
|
||||||
|
if(!"200".equals(response.getCode()) )
|
||||||
|
{
|
||||||
|
// STAT_4099 = 템플릿 조회 실패 (내부 enum 기반 메시지 사용)
|
||||||
|
return new RestResponse(new FailRestResponse("STAT_4099",""));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 성공 시 템플릿 리스트 추출
|
||||||
|
List<TemplateInfo> templateList = response.getData().getList();
|
||||||
|
|
||||||
|
// 5. 각 템플릿 객체에 대해 가공 처리
|
||||||
|
templateList.forEach(t -> {
|
||||||
|
// log.info(" + t.toString() :: [{}]",t.toString());
|
||||||
|
// 서비스 상태 코드 → 한글 라벨로 변환 ( 예: REG → REG(등록완료) )
|
||||||
|
String originalCode = t.getServiceStatus();
|
||||||
|
String convertedLabel = ServiceStatusEnum.getLabelByCode(originalCode);
|
||||||
|
t.setServiceStatus(convertedLabel);
|
||||||
|
|
||||||
|
// 응답에 불필요한 필드 제거 (null 처리)
|
||||||
|
t.setSenderKeyType(null);
|
||||||
|
t.setCategoryCode(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 6. 최종 응답 반환 (가공된 템플릿 리스트 포함)
|
||||||
|
return new RestResponse(templateList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RestResponse getTemplateDetail(BizTemplateRequest bizTemplateRequest) throws JsonProcessingException {
|
||||||
|
|
||||||
|
// 테스트 모드 확인
|
||||||
|
if(StringUtils.isNotEmpty(bizTemplateRequest.getTest_yn())) {
|
||||||
|
return TestDataUtil.getTemplateDetailTestData(bizTemplateRequest.getTest_yn());
|
||||||
|
}
|
||||||
|
|
||||||
|
// SenderKey 검증
|
||||||
|
RestResponse STAT_2010 = isSenderKeyChk(bizTemplateRequest);
|
||||||
|
if (STAT_2010 != null) return STAT_2010;
|
||||||
|
|
||||||
|
// 1. 템플릿 목록 조회 요청 DTO 생성 (BIZ ID, API Key, senderKey 포함)
|
||||||
|
BizTemplateRequest requestDto= BizTemplateRequest.builder()
|
||||||
|
.bizId(BIZ_ID)
|
||||||
|
.apiKey(BIZ_API_KEY)
|
||||||
|
.senderKey(bizTemplateRequest.getSenderKey())
|
||||||
|
.templateCode(bizTemplateRequest.getTemplateCode())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 2. 외부 API 호출 - 템플릿 목록 요청 (/v3/kakao/template/list)
|
||||||
|
TemplateDetailResponse response = apiService.postForBizTemplateDetailEntity(
|
||||||
|
BIZ_ROOT_URL+"/v3/kakao/template/detail"
|
||||||
|
, requestDto
|
||||||
|
);
|
||||||
|
|
||||||
|
log.info(" + response :: [{}]", response.toString());
|
||||||
|
|
||||||
|
|
||||||
|
// 6. 최종 응답 반환 (가공된 템플릿 리스트 포함)
|
||||||
|
return new RestResponse(response.getData());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTemplateExist(String senderKey, String templateCode) {
|
||||||
|
Map<String, Object> params = new HashMap<>();
|
||||||
|
params.put("senderKey", senderKey);
|
||||||
|
params.put("templateCode", templateCode);
|
||||||
|
return inqryMapper.isTemplateExist(params) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable RestResponse isSenderKeyChk(BizTemplateRequest bizTemplateRequest) {
|
||||||
|
List<MjKakaoProfileInfoVO> chnlIdList = (List<MjKakaoProfileInfoVO>) this.getChnlId(bizTemplateRequest).getData();
|
||||||
|
|
||||||
|
log.info("bizTemplateRequest.getSenderKey() :: [{}]", bizTemplateRequest.getSenderKey());
|
||||||
|
log.info("chnlIdList :: [{}]", chnlIdList.toString());
|
||||||
|
|
||||||
|
boolean skErr = chnlIdList.stream()
|
||||||
|
.anyMatch(p -> bizTemplateRequest.getSenderKey().equals(p.getSenderKey()));
|
||||||
|
if(!skErr){
|
||||||
|
return new RestResponse(new FailRestResponse("STAT_2010", ""));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.at.inqry.service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.BizTemplateRequest;
|
||||||
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
|
|
||||||
|
public interface InqryService {
|
||||||
|
RestResponse getChnlId(BizTemplateRequest bizTemplateRequest);
|
||||||
|
|
||||||
|
RestResponse getTemplates(BizTemplateRequest bizTemplateRequest) throws JsonProcessingException;
|
||||||
|
|
||||||
|
RestResponse getTemplateDetail(BizTemplateRequest bizTemplateRequest) throws JsonProcessingException;
|
||||||
|
|
||||||
|
boolean isTemplateExist(String senderKey, String templateCode);
|
||||||
|
}
|
||||||
@ -0,0 +1,87 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.at.inqry.web;
|
||||||
|
|
||||||
|
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.BizTemplateRequest;
|
||||||
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.inqry.service.InqryService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fileName : InqryRestContoller.java
|
||||||
|
* author : hylee
|
||||||
|
* date : 2025-06-27
|
||||||
|
* description :
|
||||||
|
* ===========================================================
|
||||||
|
* DATE AUTHOR NOTE
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* 2025-06-27 hylee 최초 생성
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@CrossOrigin("*") // 모든 요청에 접근 허용
|
||||||
|
@RestController
|
||||||
|
public class InqryRestContoller {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InqryService inqryService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param
|
||||||
|
* @return
|
||||||
|
* @throws Exception 처리 중 예외 발생 가능
|
||||||
|
* @date 2025-06-27
|
||||||
|
* @author hylee
|
||||||
|
*/
|
||||||
|
@PostMapping("/api/kakao/inqry/chnlId")
|
||||||
|
public ResponseEntity<RestResponse> getChnlId(BizTemplateRequest bizTemplateRequest) throws Exception {
|
||||||
|
|
||||||
|
// List<MjKakaoProfileInfoVO> resultList = inqryService.getChnlId(bizTemplateRequest.getMberId(), bizTemplateRequest.getTest_yn());
|
||||||
|
// List<MjKakaoProfileInfoVO> resultList = inqryService.getChnlId(bizTemplateRequest.getMberId(), bizTemplateRequest.getTest_yn());
|
||||||
|
|
||||||
|
return ResponseEntity.ok().body(inqryService.getChnlId(bizTemplateRequest));
|
||||||
|
// return ResponseEntity.ok().body(new RestResponse(resultList));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param
|
||||||
|
* @return
|
||||||
|
* @throws Exception 처리 중 예외 발생 가능
|
||||||
|
* @date 2025-07-29
|
||||||
|
* @Discription 템플릿 리스트 호출
|
||||||
|
* @author hylee
|
||||||
|
*/
|
||||||
|
@PostMapping("/api/kakao/inqry/templates/list")
|
||||||
|
public ResponseEntity<RestResponse> getTemplates(BizTemplateRequest bizTemplateRequest) throws Exception {
|
||||||
|
|
||||||
|
return ResponseEntity.ok().body(inqryService.getTemplates(bizTemplateRequest));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param
|
||||||
|
* @return
|
||||||
|
* @throws Exception 처리 중 예외 발생 가능
|
||||||
|
* @date 2025-07-29
|
||||||
|
* @Discription 템플릿 상세
|
||||||
|
* @author hylee
|
||||||
|
*/
|
||||||
|
@PostMapping("/api/kakao/inqry/templates/detail")
|
||||||
|
public ResponseEntity<RestResponse> getTemplateDetail(BizTemplateRequest bizTemplateRequest) throws Exception {
|
||||||
|
|
||||||
|
// log.info("bizTemplateRequest :: [{}]", bizTemplateRequest.toString());
|
||||||
|
return ResponseEntity.ok().body(inqryService.getTemplateDetail(bizTemplateRequest));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,9 +1,8 @@
|
|||||||
package com.itn.mjonApi.mjon.api.send.mapper.domain;
|
package com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* packageName : com.itn.mjonApi.cmn.msg
|
* packageName : com.itn.mjonApi.cmn.msg
|
||||||
@ -21,7 +20,9 @@ import org.springframework.http.ResponseEntity;
|
|||||||
@Builder
|
@Builder
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class MjonResponseVO {
|
@JsonIgnoreProperties(ignoreUnknown = true) // JSON에 있지만 VO에 없는 필드를 무시하고 무사히 역직렬화해 줌
|
||||||
|
@ToString
|
||||||
|
public class MjonAtResponseVO {
|
||||||
|
|
||||||
private String result;
|
private String result;
|
||||||
private String message;
|
private String message;
|
||||||
@ -30,17 +31,16 @@ public class MjonResponseVO {
|
|||||||
private String msgGroupId;
|
private String msgGroupId;
|
||||||
private String afterCash;
|
private String afterCash;
|
||||||
private String msgType;
|
private String msgType;
|
||||||
|
private String statCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param stringResponseEntity
|
* @param apiReturnNode
|
||||||
* @return ResponseEntity vo convert
|
* @return ResponseEntity vo convert
|
||||||
* @throws JsonProcessingException
|
* @throws JsonProcessingException
|
||||||
*/
|
*/
|
||||||
public static MjonResponseVO getMjonResponse(ResponseEntity<String> stringResponseEntity) throws JsonProcessingException {
|
// public static MjonAtResponseVO getMjonResponse(JsonNode apiReturnNode) throws JsonProcessingException {
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
// ObjectMapper objectMapper = new ObjectMapper();
|
||||||
MjonResponseVO mjonResponseVO = objectMapper.readValue(stringResponseEntity.getBody(), MjonResponseVO.class);
|
// return objectMapper.treeToValue(apiReturnNode, MjonAtResponseVO.class);
|
||||||
return mjonResponseVO;
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fileName : MsgAtRequestVO.java
|
||||||
|
* author : hylee
|
||||||
|
* date : 2025-07-29
|
||||||
|
* description : 알림톡
|
||||||
|
* ===========================================================
|
||||||
|
* DATE AUTHOR NOTE
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* 2025-07-29 hylee 최초 생성
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@ToString
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class MsgAtRequestVO implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String sendKind = "A";
|
||||||
|
|
||||||
|
private String mberId; // value = "사용자 ID", example = "goodgkdus"
|
||||||
|
|
||||||
|
private String accessKey; // value = "Api Key", example = "0367a25ec370d1141898a0b9767103"
|
||||||
|
|
||||||
|
private String senderKey; // 카카오 알림톡 채널ID
|
||||||
|
|
||||||
|
private String templateCode; // 카카오 알림톡 템플릿 코드
|
||||||
|
|
||||||
|
private String callFrom; // value = "발신번호 :: 정책이 필요함", example = "01011112222"
|
||||||
|
|
||||||
|
private String reserveYn = "N"; // 예약발송 여부 (기본: N)
|
||||||
|
// 대체문자 여부
|
||||||
|
private String subMsgSendYn;
|
||||||
|
|
||||||
|
private Boolean hasTemplateTitle = false; // 템플릿에 타이틀이 있으면 true
|
||||||
|
|
||||||
|
private String test_yn;
|
||||||
|
|
||||||
|
private List<VarAtListMapVO> varListMap = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
public class VarAtListMapVO {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : 수신자번호
|
||||||
|
*/
|
||||||
|
private String callToList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : 카카오 내용
|
||||||
|
*/
|
||||||
|
private String templateContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : 카카오템플릿
|
||||||
|
*/
|
||||||
|
private String templateTitle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : 치환문자
|
||||||
|
*/
|
||||||
|
private String subMsgTxt;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @description : [*3*] - 치환문자
|
||||||
|
// */
|
||||||
|
// private String rep3;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @description : [*4*] - 치환문자
|
||||||
|
// */
|
||||||
|
// private String rep4;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @description : 제목
|
||||||
|
// */
|
||||||
|
// private String subject;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @description : 내용
|
||||||
|
// */
|
||||||
|
// private String message;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.at.send.service;
|
||||||
|
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain.MsgAtRequestVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain.VarAtListMapVO;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fileName : IndexedParameterParserService.java
|
||||||
|
* author : hylee
|
||||||
|
* date : 2025-08-18
|
||||||
|
* description : 알림톡 인덱스된 파라미터 파싱 서비스
|
||||||
|
* parseIndexedParametersFromRequest 메서드의 아키텍처 분리를 위해 생성
|
||||||
|
* ===========================================================
|
||||||
|
* DATE AUTHOR NOTE
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* 2025-08-18 hylee 최초 생성
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class AtIndexedParameterParserService {
|
||||||
|
|
||||||
|
// 정규식 패턴을 static final로 캐싱하여 성능 최적화
|
||||||
|
private static final Pattern INDEX_PATTERN =
|
||||||
|
Pattern.compile("^(callTo|templateContent|templateTitle|subMsgTxt)_(\\d+)$");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HttpServletRequest에서 동적으로 인덱스된 파라미터들을 파싱하여 VarListMapVO 리스트로 변환
|
||||||
|
* callTo_1~100, templateContent_1~100, templateTitle_1~100, subMsgTxt_1~100 등을 동적 처리
|
||||||
|
*
|
||||||
|
* @param request HTTP 요청 객체
|
||||||
|
* @return 파싱된 VarListMapVO 리스트
|
||||||
|
*/
|
||||||
|
public List<VarAtListMapVO> parseIndexedParameters(MsgAtRequestVO msgAtRequestVO, HttpServletRequest request) {
|
||||||
|
List<VarAtListMapVO> varListMap = new ArrayList<>();
|
||||||
|
|
||||||
|
// 모든 파라미터 맵 가져오기
|
||||||
|
Map<String, String[]> parameterMap = request.getParameterMap();
|
||||||
|
|
||||||
|
// 인덱스별 데이터를 저장할 맵
|
||||||
|
Map<Integer, Map<String, String>> indexedDataMap = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 모든 파라미터를 순회하며 인덱스된 파라미터 찾기
|
||||||
|
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
|
||||||
|
String paramName = entry.getKey();
|
||||||
|
String[] paramValues = entry.getValue();
|
||||||
|
|
||||||
|
Matcher matcher = INDEX_PATTERN.matcher(paramName);
|
||||||
|
if (matcher.matches() && paramValues.length > 0) {
|
||||||
|
String fieldName = matcher.group(1); // callTo, templateContent 등
|
||||||
|
int index = Integer.parseInt(matcher.group(2)); // 1, 2, 3 등
|
||||||
|
String value = paramValues[0]; // 파라미터 값
|
||||||
|
|
||||||
|
// 인덱스별 데이터 맵에 저장
|
||||||
|
indexedDataMap.computeIfAbsent(index, k -> new HashMap<>()).put(fieldName, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 인덱스 순서대로 VarListMapVO 생성
|
||||||
|
List<Integer> sortedIndexes = new ArrayList<>(indexedDataMap.keySet());
|
||||||
|
Collections.sort(sortedIndexes);
|
||||||
|
|
||||||
|
// 대체문자전송여부
|
||||||
|
String subMsgSendYn = msgAtRequestVO.getSubMsgSendYn();
|
||||||
|
for (Integer index : sortedIndexes) {
|
||||||
|
Map<String, String> dataMap = indexedDataMap.get(index);
|
||||||
|
|
||||||
|
VarAtListMapVO vo = new VarAtListMapVO();
|
||||||
|
vo.setCallToList(dataMap.get("callTo"));
|
||||||
|
vo.setTemplateContent(dataMap.get("templateContent"));
|
||||||
|
vo.setTemplateTitle(dataMap.get("templateTitle"));
|
||||||
|
|
||||||
|
// 치환 데이터는 subMsgSendYn 이 Y일때
|
||||||
|
if("Y".equals(subMsgSendYn)){
|
||||||
|
vo.setSubMsgTxt(dataMap.get("subMsgTxt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 필수 필드 중 하나라도 있으면 리스트에 추가
|
||||||
|
if (vo.getCallToList() != null || vo.getTemplateContent() != null || vo.getTemplateTitle() != null) {
|
||||||
|
varListMap.add(vo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return varListMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,134 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.at.send.service;
|
||||||
|
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.BizTemplateRequest;
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.detail.TemplateDetail;
|
||||||
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.domain.MjKakaoProfileInfoVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.inqry.service.InqryService;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain.MsgAtRequestVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain.VarAtListMapVO;
|
||||||
|
import com.itn.mjonApi.util.MunjaUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fileName : AtParameterProcessingService.java
|
||||||
|
* author : hylee
|
||||||
|
* date : 2025-08-18
|
||||||
|
* description : 알림톡 파라미터 처리 서비스
|
||||||
|
* MsgAtRequestVO의 비즈니스 로직을 담당
|
||||||
|
* ===========================================================
|
||||||
|
* DATE AUTHOR NOTE
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* 2025-08-18 hylee 최초 생성
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class AtParameterProcessingService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AtIndexedParameterParserService indexedParameterParserService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InqryService inqryService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HttpServletRequest에서 동적으로 인덱스된 파라미터들을 파싱하고 검증하여
|
||||||
|
* MsgAtRequestVO의 varListMap에 설정
|
||||||
|
*
|
||||||
|
* @param msgAtRequestVO 요청 VO 객체
|
||||||
|
* @param request HTTP 요청 객체
|
||||||
|
* @return 검증 실패 시 오류 코드, 성공 시 null
|
||||||
|
*/
|
||||||
|
public String processIndexedParameters(MsgAtRequestVO msgAtRequestVO, HttpServletRequest request) {
|
||||||
|
|
||||||
|
// 기존 varListMap 초기화
|
||||||
|
msgAtRequestVO.setVarListMap(new ArrayList<>());
|
||||||
|
|
||||||
|
|
||||||
|
log.info(" msgAtRequestVO :: [{}]", msgAtRequestVO.toString());
|
||||||
|
// 채널ID 확인
|
||||||
|
String STAT_2010 = this.validateSenderKey(msgAtRequestVO.getMberId(), msgAtRequestVO.getSenderKey());
|
||||||
|
if (STAT_2010 != null) return STAT_2010;
|
||||||
|
|
||||||
|
// 템플릿 코드 확인
|
||||||
|
String STAT_2030 = this.validateTemplateCode(msgAtRequestVO);
|
||||||
|
if (STAT_2030 != null) return STAT_2030;
|
||||||
|
|
||||||
|
// 파싱 로직을 IndexedParameterParserService에 위임
|
||||||
|
List<VarAtListMapVO> parsedList = indexedParameterParserService.parseIndexedParameters(msgAtRequestVO, request);
|
||||||
|
|
||||||
|
// 파싱된 각 VO에 대해 검증 수행
|
||||||
|
for (VarAtListMapVO vo : parsedList) {
|
||||||
|
String validationError = MunjaUtil.kakaoAtValidate(vo, msgAtRequestVO);
|
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(validationError)) {
|
||||||
|
return validationError; // 검증 실패 시 오류 코드 반환
|
||||||
|
}
|
||||||
|
|
||||||
|
// 검증 통과한 VO를 리스트에 추가
|
||||||
|
msgAtRequestVO.getVarListMap().add(vo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null; // 모든 검증 통과
|
||||||
|
}
|
||||||
|
|
||||||
|
private String validateTemplateCode(MsgAtRequestVO msgAtRequestVO) {
|
||||||
|
// private String validateTemplateCode(String mberId, String senderKey, String templateCode) {
|
||||||
|
|
||||||
|
String mberId = msgAtRequestVO.getMberId();
|
||||||
|
String senderKey = msgAtRequestVO.getSenderKey();
|
||||||
|
String templateCode = msgAtRequestVO.getTemplateCode();
|
||||||
|
|
||||||
|
try {
|
||||||
|
BizTemplateRequest request = BizTemplateRequest.builder()
|
||||||
|
.mberId(mberId)
|
||||||
|
.senderKey(senderKey)
|
||||||
|
.templateCode(templateCode)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
RestResponse response = inqryService.getTemplateDetail(request);
|
||||||
|
|
||||||
|
if (response.getData() == null) {
|
||||||
|
return "STAT_2030"; // 템플릿 상세 정보를 가져올 수 없음
|
||||||
|
}
|
||||||
|
|
||||||
|
TemplateDetail detail = (TemplateDetail) response.getData();
|
||||||
|
|
||||||
|
// 로그 출력
|
||||||
|
log.info("template detail :: [{}]", detail);
|
||||||
|
|
||||||
|
// templateTitle 존재 여부 확인
|
||||||
|
if (StringUtils.isNotEmpty(detail.getTemplateTitle())) {
|
||||||
|
msgAtRequestVO.setHasTemplateTitle(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return detail != null ? null : "STAT_2030";
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "STAT_2099";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String validateSenderKey(String mberId, String senderKey) {
|
||||||
|
if (StringUtils.isEmpty(senderKey)) {
|
||||||
|
return "STAT_2010";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
List<MjKakaoProfileInfoVO> resultList = (List<MjKakaoProfileInfoVO>) inqryService.getChnlId(BizTemplateRequest.builder().mberId(mberId).build()).getData();
|
||||||
|
boolean ok = resultList.stream().anyMatch(p -> senderKey.equals(p.getSenderKey()));
|
||||||
|
return ok ? null : "STAT_2010";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.at.send.service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain.MsgAtRequestVO;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
public interface SendAtService {
|
||||||
|
|
||||||
|
|
||||||
|
// RestResponse sendMsgData(MsgRequestVO msgRequestVO) throws Exception;
|
||||||
|
//
|
||||||
|
// RestResponse sendMsgData_advc(MsgRequestVO msgRequestVO) throws Exception;
|
||||||
|
//
|
||||||
|
// RestResponse sendMsgsData(MsgsRequestVO msgsRequestVO) throws Exception;
|
||||||
|
//
|
||||||
|
// RestResponse sendMsgsData_advc(MsgsRequestVO msgsRequestVO) throws Exception;
|
||||||
|
|
||||||
|
RestResponse sendAtData(MsgAtRequestVO msgAtRequestVO, HttpServletRequest request) throws JsonProcessingException;
|
||||||
|
}
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.at.send.service.impl;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.itn.mjonApi.cmn.apiServer.ApiService;
|
||||||
|
import com.itn.mjonApi.cmn.msg.FailRestResponse;
|
||||||
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain.MsgAtRequestVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.send.service.AtParameterProcessingService;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.send.service.SendAtService;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.PriceMapper;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.SendMapper;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.MjonResponseVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.SendSucRestResponse;
|
||||||
|
import com.itn.mjonApi.util.TestDataUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.catalina.connector.Response;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class SendAtServiceImpl implements SendAtService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AtParameterProcessingService atParameterProcessingService;
|
||||||
|
|
||||||
|
private ApiService<Response> apiService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
SendMapper sendMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
PriceMapper priceMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public SendAtServiceImpl(ApiService<Response> apiService) {
|
||||||
|
this.apiService = apiService;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String replaseStrList = "[*이름*],[*1*],[*2*],[*3*],[*4*]";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param
|
||||||
|
* @return
|
||||||
|
* @throws Exception 처리 중 예외 발생 가능
|
||||||
|
* @date 2025-07-29
|
||||||
|
* @Discription 치환없는 알림톡 데이터
|
||||||
|
* @author hylee
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public RestResponse sendAtData(MsgAtRequestVO msgAtRequestVO, HttpServletRequest request) throws JsonProcessingException {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(StringUtils.isNotEmpty(msgAtRequestVO.getTest_yn())){
|
||||||
|
// YF => 실패 테스트 데이터, YS => 성공 테스트 데이터 (알림톡 전용)
|
||||||
|
return TestDataUtil.getTestAtSendReturnData(msgAtRequestVO.getTest_yn());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Form-data의 인덱스된 파라미터들을 VarListMapVO 리스트로 변환 (동적 처리 _1~_100)
|
||||||
|
String falseCode = atParameterProcessingService.processIndexedParameters(msgAtRequestVO, request);
|
||||||
|
if(StringUtils.isNotEmpty(falseCode)){
|
||||||
|
return new RestResponse(new FailRestResponse(falseCode,""));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MjonResponseVO munjaSendResponse = apiService.postForEntity(
|
||||||
|
"/web/mjon/kakao/alimtalk/kakaoAlimTalkMsgSendAjax_advc.do"
|
||||||
|
, msgAtRequestVO
|
||||||
|
, String.class
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// convertMjonDataToApiResponse => MjonResponseVO 데이터를 ApiResponse 데이터로 변환하는 메소드
|
||||||
|
log.info(" + munjaSendResponse :: [{}]", munjaSendResponse.toString());
|
||||||
|
if("OK".equals(munjaSendResponse.getResult())){ // 성공
|
||||||
|
return new RestResponse(SendSucRestResponse.convertMjonDataToApiResponse(munjaSendResponse));
|
||||||
|
}else{ // 실패
|
||||||
|
return new RestResponse(new FailRestResponse(munjaSendResponse.getStatCode(),""));
|
||||||
|
}
|
||||||
|
|
||||||
|
// return new RestResponse(msgAtRequestVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.at.send.web;
|
||||||
|
|
||||||
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain.MsgAtRequestVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.send.service.SendAtService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* packageName : com.itn.mjonApi.mjon.send.web
|
||||||
|
* fileName : SendRestController
|
||||||
|
* author : hylee
|
||||||
|
* date : 2023-02-15
|
||||||
|
* description :
|
||||||
|
* ===========================================================
|
||||||
|
* DATE AUTHOR NOTE
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* 2023-02-15 hylee 최초 생성
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 치환문자가 있으면 , => §로 치환
|
||||||
|
|
||||||
|
@CrossOrigin("*") // 모든 요청에 접근 허용
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
public class SendAtRestController {
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SendAtService sendAtService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param msgAtRequestVO
|
||||||
|
* @param request
|
||||||
|
* @Discription [문자 발송] 같은 내용으로 여려명에게 보냄
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/api/kakao/at/sendMsg")
|
||||||
|
public ResponseEntity<RestResponse> sendMsg(MsgAtRequestVO msgAtRequestVO, HttpServletRequest request) throws Exception {
|
||||||
|
|
||||||
|
// https://smartsms.aligo.in/alimapi.html
|
||||||
|
|
||||||
|
return ResponseEntity.ok().body(sendAtService.sendAtData(msgAtRequestVO, request));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@ToString
|
||||||
|
public class FtButtonVO {
|
||||||
|
private String name;
|
||||||
|
private String linkType; // AC, DS, WL, AL, BK, MD
|
||||||
|
private String linkTypeName; // 채널 추가, 배송조회, 웹링크, 앱링크, 봇키워드, 메시지전달
|
||||||
|
private String linkMo; // 모바일 링크
|
||||||
|
private String linkPc; // PC 링크
|
||||||
|
private String linkIos; // iOS Scheme
|
||||||
|
private String linkAnd; // Android Scheme
|
||||||
|
}
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class FtSendSuccessResponse {
|
||||||
|
|
||||||
|
private String resultCode = "0"; // 성공 코드
|
||||||
|
|
||||||
|
private String msgType = "FT"; // 메시지 타입 (친구톡 고정)
|
||||||
|
|
||||||
|
private List<String> msgGroupIdList; // 메시지 전송 그룹 ID 리스트
|
||||||
|
|
||||||
|
private String successCnt; // 성공 건수
|
||||||
|
|
||||||
|
private String failCnt; // 실패 건수
|
||||||
|
|
||||||
|
private String test_yn; // 테스트 여부
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 친구톡 발송 결과를 SMS API 형태로 변환
|
||||||
|
* @param totalCount 총 발송 건수
|
||||||
|
* @param successCount 성공 건수
|
||||||
|
* @param failCount 실패 건수
|
||||||
|
* @param successPhoneList 성공한 전화번호 리스트
|
||||||
|
* @return FtSendSuccessResponse
|
||||||
|
*/
|
||||||
|
public static FtSendSuccessResponse createFtResponse(int totalCount, int successCount, int failCount,
|
||||||
|
List<String> successPhoneList) {
|
||||||
|
|
||||||
|
// 성공한 발송별로 msgGroupId 생성
|
||||||
|
List<String> msgGroupIdList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < successCount; i++) {
|
||||||
|
msgGroupIdList.add(generateMsgGroupId());
|
||||||
|
}
|
||||||
|
|
||||||
|
return FtSendSuccessResponse.builder()
|
||||||
|
.resultCode("0")
|
||||||
|
.msgGroupIdList(msgGroupIdList)
|
||||||
|
.msgType("FT") // 친구톡 고정
|
||||||
|
.successCnt(String.valueOf(successCount))
|
||||||
|
.failCnt(String.valueOf(failCount))
|
||||||
|
.test_yn(null)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 메시지 그룹 ID 생성 (SMS API와 동일한 형태)
|
||||||
|
* MSGGID_0000000013451, MSGGID_0000000013452 형태
|
||||||
|
* @return MSGGID_xxxxxxxxxxxx 형태의 ID
|
||||||
|
*/
|
||||||
|
private static String generateMsgGroupId() {
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
// 13자리 숫자로 맞추기 위해 currentTime을 조정
|
||||||
|
String msgId = String.format("%013d", currentTime % 10000000000000L);
|
||||||
|
return "MSGGID_" + msgId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@ToString
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class KakaoButtonVO {
|
||||||
|
|
||||||
|
private String name; // 버튼명
|
||||||
|
private String linkType; // 링크타입 (WL: 웹링크, AL: 앱링크)
|
||||||
|
private String linkTypeName; // 링크타입명
|
||||||
|
|
||||||
|
// 웹링크용
|
||||||
|
private String linkMo; // 모바일 웹링크
|
||||||
|
private String linkPc; // PC 웹링크
|
||||||
|
|
||||||
|
// 앱링크용
|
||||||
|
private String linkIos; // iOS 앱링크
|
||||||
|
private String linkAnd; // Android 앱링크
|
||||||
|
|
||||||
|
// 기타
|
||||||
|
private String pluginId; // 플러그인 ID
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@ToString
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class KakaoFTSendVO {
|
||||||
|
|
||||||
|
// 카카오 발신 관련
|
||||||
|
private String mberId; // mberId
|
||||||
|
private String senderKey; // 카카오 발신 키 (필수)
|
||||||
|
private String adFlag; // 카카오 발신 키 (필수)
|
||||||
|
|
||||||
|
// 이미지 관련
|
||||||
|
private String imageFileName; // 이미지 파일명
|
||||||
|
private String imageType; // 이미지 타입 (I: 이미지, null: 텍스트만)
|
||||||
|
private String atchFileId; // 첨부파일 ID
|
||||||
|
private String templateImageUrl; // 친구톡 이미지 URL
|
||||||
|
|
||||||
|
// 메시지 내용
|
||||||
|
private String templateContent; // 친구톡 발송 내용 (개별 수신자별)
|
||||||
|
private String subMsgSendYn; // 대체문자 발송여부
|
||||||
|
private String subMsgTxt; // 대체문자 내용 (개별 수신자별)
|
||||||
|
|
||||||
|
// 발송 관련
|
||||||
|
private String reserveYn; // 예약발송 여부 (기본: N)
|
||||||
|
private String callFrom; // 발신번호
|
||||||
|
private String reqDate; // 요청일시 (예약발송시)
|
||||||
|
private String sendKind; // 발송 구분 , A : API / H : 사이트
|
||||||
|
|
||||||
|
// 버튼 정보 (모든 수신자 공통)
|
||||||
|
@Builder.Default
|
||||||
|
private List<KakaoButtonVO> buttonVOList = new ArrayList<>();
|
||||||
|
|
||||||
|
// 수신자 목록 (핵심: 개별 발송시 1명만 포함)
|
||||||
|
@Builder.Default
|
||||||
|
private List<MjonFTSendVO> mjonFTSendVOList = new ArrayList<>();
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@ToString
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class MjonFTSendVO {
|
||||||
|
|
||||||
|
// 수신자 정보 (핵심)
|
||||||
|
private String phone; // 수신번호 (필수)
|
||||||
|
private String name; // 수신자명
|
||||||
|
|
||||||
|
// 치환문자 (현재 사용안함)
|
||||||
|
private String rep1; // 치환문자1
|
||||||
|
private String rep2; // 치환문자2
|
||||||
|
private String rep3; // 치환문자3
|
||||||
|
private String rep4; // 치환문자4
|
||||||
|
|
||||||
|
// 메시지 관련
|
||||||
|
private String msgId; // 메시지 ID
|
||||||
|
private String msgGroupId; // 메시지 그룹 ID
|
||||||
|
private String userId; // 사용자 ID
|
||||||
|
private String callFrom; // 발신번호
|
||||||
|
private String callTo; // 수신번호 (phone과 동일)
|
||||||
|
private String reqDate; // 요청일시
|
||||||
|
private String agentCode; // 에이전트 코드
|
||||||
|
private String subject; // 제목
|
||||||
|
private String smsTxt; // SMS 내용
|
||||||
|
private String msgType; // 메시지 타입
|
||||||
|
|
||||||
|
// 파일 관련
|
||||||
|
private String fileCnt; // 파일 개수
|
||||||
|
private String filePath1; // 파일경로1
|
||||||
|
private String filePath2; // 파일경로2
|
||||||
|
private String filePath3; // 파일경로3
|
||||||
|
|
||||||
|
// 기타
|
||||||
|
// @Builder.Default
|
||||||
|
// private String eventYn = "N"; // 이벤트 여부 (기본: N)
|
||||||
|
private String eachPrice; // 개별 가격
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* packageName : com.itn.mjonApi.cmn.msg
|
||||||
|
* fileName : mjonResponse
|
||||||
|
* author : hylee
|
||||||
|
* date : 2023-05-12
|
||||||
|
* description : 문자온 프로젝트에서 받은 리턴값
|
||||||
|
* ===========================================================
|
||||||
|
* DATE AUTHOR NOTE
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* 2023-05-12 hylee 최초 생성
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true) // JSON에 있지만 VO에 없는 필드를 무시하고 무사히 역직렬화해 줌
|
||||||
|
@ToString
|
||||||
|
public class MjonFtResponseVO {
|
||||||
|
|
||||||
|
private String result;
|
||||||
|
private String message;
|
||||||
|
private String resultSts; // 전송결과 갯수
|
||||||
|
private String resultBlockSts; // 수신거부 갯수
|
||||||
|
private String msgGroupId;
|
||||||
|
private String afterCash;
|
||||||
|
private String msgType;
|
||||||
|
private String statCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param apiReturnNode
|
||||||
|
* @return ResponseEntity vo convert
|
||||||
|
* @throws JsonProcessingException
|
||||||
|
*/
|
||||||
|
// public static MjonAtResponseVO getMjonResponse(JsonNode apiReturnNode) throws JsonProcessingException {
|
||||||
|
// ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
// return objectMapper.treeToValue(apiReturnNode, MjonAtResponseVO.class);
|
||||||
|
// }
|
||||||
|
}
|
||||||
@ -0,0 +1,109 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import lombok.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fileName : MsgAtRequestVO.java
|
||||||
|
* author : hylee
|
||||||
|
* date : 2025-07-29
|
||||||
|
* description : 알림톡
|
||||||
|
* ===========================================================
|
||||||
|
* DATE AUTHOR NOTE
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* 2025-07-29 hylee 최초 생성
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@ToString
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class MsgFtRequestVO implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String sendKind = "A";
|
||||||
|
|
||||||
|
private String mberId; // value = "사용자 ID", example = "goodgkdus"
|
||||||
|
|
||||||
|
private String accessKey; // value = "Api Key", example = "0367a25ec370d1141898a0b9767103"
|
||||||
|
|
||||||
|
private String senderKey; // 카카오 알림톡 채널ID
|
||||||
|
|
||||||
|
private String templateCode; // 카카오 알림톡 템플릿 코드
|
||||||
|
|
||||||
|
private String callFrom; // value = "발신번호 :: 정책이 필요함", example = "01011112222"
|
||||||
|
|
||||||
|
// 대체문자 여부
|
||||||
|
private String subMsgSendYn;
|
||||||
|
|
||||||
|
// 광고 여부
|
||||||
|
private String adFlag;
|
||||||
|
|
||||||
|
private String test_yn;
|
||||||
|
|
||||||
|
|
||||||
|
// 실제 업로드 파일(로그/직렬화 제외)
|
||||||
|
@JsonIgnore
|
||||||
|
@ToString.Exclude
|
||||||
|
private MultipartFile templateImage;
|
||||||
|
|
||||||
|
|
||||||
|
// ====== ⬇️ AOP/DB 저장용(문자열/숫자만) 메타데이터 필드들 ======
|
||||||
|
// template
|
||||||
|
private String templateImageName;
|
||||||
|
private String templateImageContentType;
|
||||||
|
private Long templateImageSize; // bytes
|
||||||
|
private Integer templateImageWidth; // px
|
||||||
|
private Integer templateImageHeight; // px
|
||||||
|
private String templateImageSha256; // hexdigest
|
||||||
|
private String templateImageSavedPath; // 서버 저장 경로(선택)
|
||||||
|
private String templateAtchFileId; // 내부 첨부ID(선택)
|
||||||
|
private String templateMsgType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : 친구톡 이미지 등록된 URL
|
||||||
|
*/
|
||||||
|
private String templateImageUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : 치환문자 이미지
|
||||||
|
* 이미지 문자가 있고 대체문자가 있으면(subMsgSendYn="Y") filepath에 atchFileId 있어야함
|
||||||
|
*/
|
||||||
|
private String filePath1;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : 버튼 사용
|
||||||
|
*/
|
||||||
|
private List<FtButtonVO> buttons = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
// sub
|
||||||
|
|
||||||
|
// @JsonIgnore
|
||||||
|
// @ToString.Exclude
|
||||||
|
// private MultipartFile subImage;
|
||||||
|
|
||||||
|
// private String subImageName;
|
||||||
|
// private String subImageContentType;
|
||||||
|
// private Long subImageSize;
|
||||||
|
// private Integer subImageWidth;
|
||||||
|
// private Integer subImageHeight;
|
||||||
|
// private String subImageSha256;
|
||||||
|
// private String subImageSavedPath;
|
||||||
|
// private String subAtchFileId;
|
||||||
|
// private String subMsgType;
|
||||||
|
|
||||||
|
private List<VarFtListMapVO> varListMap = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
public class VarFtListMapVO {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : 수신자번호
|
||||||
|
*/
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : 친구톡 내용
|
||||||
|
*/
|
||||||
|
private String templateContent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : 치환문자
|
||||||
|
*/
|
||||||
|
private String subMsgTxt;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @description : [*3*] - 치환문자
|
||||||
|
// */
|
||||||
|
// private String rep3;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @description : [*4*] - 치환문자
|
||||||
|
// */
|
||||||
|
// private String rep4;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @description : 제목
|
||||||
|
// */
|
||||||
|
// private String subject;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * @description : 내용
|
||||||
|
// */
|
||||||
|
// private String message;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,145 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.ft.send.service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.FtButtonVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.MsgFtRequestVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.VarFtListMapVO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fileName : IndexedParameterParserService.java
|
||||||
|
* author : hylee
|
||||||
|
* date : 2025-08-18
|
||||||
|
* description : 알림톡 인덱스된 파라미터 파싱 서비스
|
||||||
|
* parseIndexedParametersFromRequest 메서드의 아키텍처 분리를 위해 생성
|
||||||
|
* ===========================================================
|
||||||
|
* DATE AUTHOR NOTE
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* 2025-08-18 hylee 최초 생성
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class FtIndexedParameterParserService {
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
// 정규식 패턴을 static final로 캐싱하여 성능 최적화
|
||||||
|
private static final Pattern INDEX_PATTERN =
|
||||||
|
Pattern.compile("^(callTo|templateContent|subMsgTxt|button)_(\\d+)$");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HttpServletRequest에서 동적으로 인덱스된 파라미터들을 파싱하여 VarListMapVO 리스트로 변환
|
||||||
|
* callTo_1~100, templateContent_1~100, templateTitle_1~100, subMsgTxt_1~100 등을 동적 처리
|
||||||
|
*
|
||||||
|
* @param request HTTP 요청 객체
|
||||||
|
* @return 파싱된 VarListMapVO 리스트
|
||||||
|
*/
|
||||||
|
public List<VarFtListMapVO> parseIndexedParameters(MsgFtRequestVO msgFtRequestVO, HttpServletRequest request) {
|
||||||
|
List<VarFtListMapVO> varListMap = new ArrayList<>();
|
||||||
|
|
||||||
|
// 모든 파라미터 맵 가져오기
|
||||||
|
Map<String, String[]> parameterMap = request.getParameterMap();
|
||||||
|
|
||||||
|
// 인덱스별 데이터를 저장할 맵
|
||||||
|
Map<Integer, Map<String, String>> indexedDataMap = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
String subMsgSendYn = msgFtRequestVO.getSubMsgSendYn();
|
||||||
|
|
||||||
|
// 모든 파라미터를 순회하며 인덱스된 파라미터 찾기
|
||||||
|
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
|
||||||
|
String paramName = entry.getKey();
|
||||||
|
String[] paramValues = entry.getValue();
|
||||||
|
|
||||||
|
Matcher matcher = INDEX_PATTERN.matcher(paramName);
|
||||||
|
if (matcher.matches() && paramValues.length > 0) {
|
||||||
|
String fieldName = matcher.group(1); // callTo, templateContent 등
|
||||||
|
int index = Integer.parseInt(matcher.group(2)); // 1, 2, 3 등
|
||||||
|
String value = paramValues[0]; // 파라미터 값
|
||||||
|
|
||||||
|
// 인덱스별 데이터 맵에 저장
|
||||||
|
indexedDataMap.computeIfAbsent(index, k -> new HashMap<>()).put(fieldName, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 인덱스 순서대로 VarListMapVO 생성
|
||||||
|
List<Integer> sortedIndexes = new ArrayList<>(indexedDataMap.keySet());
|
||||||
|
Collections.sort(sortedIndexes);
|
||||||
|
|
||||||
|
for (Integer index : sortedIndexes) {
|
||||||
|
Map<String, String> dataMap = indexedDataMap.get(index);
|
||||||
|
|
||||||
|
VarFtListMapVO vo = new VarFtListMapVO();
|
||||||
|
vo.setPhone(dataMap.get("callTo"));
|
||||||
|
vo.setTemplateContent(dataMap.get("templateContent"));
|
||||||
|
|
||||||
|
// 치환 데이터는 subMsgSendYn 이 Y일때
|
||||||
|
if("Y".equals(subMsgSendYn)){
|
||||||
|
vo.setSubMsgTxt(dataMap.get("subMsgTxt"));
|
||||||
|
}
|
||||||
|
// 필수 필드 중 하나라도 있으면 리스트에 추가
|
||||||
|
if (vo.getPhone() != null || vo.getTemplateContent() != null) {
|
||||||
|
varListMap.add(vo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 버튼 파라미터를 요청 레벨에서 한 번만 파싱
|
||||||
|
String buttonData = request.getParameter("button");
|
||||||
|
|
||||||
|
if (buttonData != null && !buttonData.trim().isEmpty()) {
|
||||||
|
try {
|
||||||
|
JsonNode buttonJson = objectMapper.readTree(buttonData);
|
||||||
|
JsonNode buttonArray = buttonJson.get("button");
|
||||||
|
|
||||||
|
List<FtButtonVO> buttonList = new ArrayList<>();
|
||||||
|
if (buttonArray != null && buttonArray.isArray()) {
|
||||||
|
for (JsonNode button : buttonArray) {
|
||||||
|
FtButtonVO ftButton = FtButtonVO.builder()
|
||||||
|
.name(getJsonText(button, "name"))
|
||||||
|
.linkType(getJsonText(button, "linkType"))
|
||||||
|
.linkTypeName(getJsonText(button, "linkTypeName"))
|
||||||
|
.linkMo(getJsonText(button, "linkMo"))
|
||||||
|
.linkPc(getJsonText(button, "linkPc"))
|
||||||
|
.linkIos(getJsonText(button, "linkIos"))
|
||||||
|
.linkAnd(getJsonText(button, "linkAnd"))
|
||||||
|
.build();
|
||||||
|
buttonList.add(ftButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ✅ MsgFtRequestVO에 버튼 설정 (모든 수신자 공통)
|
||||||
|
msgFtRequestVO.setButtons(buttonList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("버튼 JSON 파싱 실패: {}", buttonData, e);
|
||||||
|
msgFtRequestVO.setButtons(new ArrayList<>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return varListMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JsonNode에서 안전하게 텍스트 값을 추출하는 헬퍼 메서드
|
||||||
|
*
|
||||||
|
* @param node JSON 노드
|
||||||
|
* @param fieldName 필드명
|
||||||
|
* @return 텍스트 값 (null 또는 빈 값일 경우 null 반환)
|
||||||
|
*/
|
||||||
|
private String getJsonText(JsonNode node, String fieldName) {
|
||||||
|
if (node != null && node.has(fieldName)) {
|
||||||
|
JsonNode fieldNode = node.get(fieldName);
|
||||||
|
if (!fieldNode.isNull()) {
|
||||||
|
String text = fieldNode.asText();
|
||||||
|
return text.isEmpty() ? null : text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,141 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.ft.send.service;
|
||||||
|
|
||||||
|
import com.itn.mjonApi.cmn.apiServer.ApiService;
|
||||||
|
import com.itn.mjonApi.cmn.domain.StatusResponse;
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.BizTemplateRequest;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.domain.MjKakaoProfileInfoVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.inqry.service.InqryService;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.MsgFtRequestVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.VarFtListMapVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.utils.FtFileMetaUtil;
|
||||||
|
import com.itn.mjonApi.util.MunjaUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.catalina.connector.Response;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fileName : AtParameterProcessingService.java
|
||||||
|
* author : hylee
|
||||||
|
* date : 2025-08-18
|
||||||
|
* description : 알림톡 파라미터 처리 서비스
|
||||||
|
* MsgAtRequestVO의 비즈니스 로직을 담당
|
||||||
|
* ===========================================================
|
||||||
|
* DATE AUTHOR NOTE
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* 2025-08-18 hylee 최초 생성
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class FtParameterProcessingService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FtIndexedParameterParserService indexedParameterParserService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InqryService inqryService;
|
||||||
|
|
||||||
|
private ApiService<Response> apiService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public FtParameterProcessingService(ApiService<Response> apiService) {
|
||||||
|
this.apiService = apiService;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* HttpServletRequest에서 동적으로 인덱스된 파라미터들을 파싱하고 검증하여
|
||||||
|
* MsgAtRequestVO의 varListMap에 설정
|
||||||
|
*
|
||||||
|
* @param msgFtRequestVO 요청 VO 객체
|
||||||
|
* @param request HTTP 요청 객체
|
||||||
|
* @return 검증 실패 시 오류 코드, 성공 시 null
|
||||||
|
*/
|
||||||
|
public String processIndexedParameters(MsgFtRequestVO msgFtRequestVO, HttpServletRequest request) {
|
||||||
|
|
||||||
|
// 기존 varListMap 초기화
|
||||||
|
msgFtRequestVO.setVarListMap(new ArrayList<>());
|
||||||
|
|
||||||
|
|
||||||
|
// 채널ID 확인
|
||||||
|
String STAT_2010 = this.validateSenderKey(msgFtRequestVO.getMberId(), msgFtRequestVO.getSenderKey());
|
||||||
|
if (STAT_2010 != null) return STAT_2010;
|
||||||
|
|
||||||
|
// 템플릿 코드 확인
|
||||||
|
// String STAT_2030 = this.validateTemplateCode(msgFtRequestVO.getMberId(), msgFtRequestVO.getSenderKey(), msgFtRequestVO.getTemplateCode());
|
||||||
|
// if (STAT_2030 != null) return STAT_2030;
|
||||||
|
|
||||||
|
// 파싱 로직을 IndexedParameterParserService에 위임
|
||||||
|
List<VarFtListMapVO> parsedList = indexedParameterParserService.parseIndexedParameters(msgFtRequestVO, request);
|
||||||
|
|
||||||
|
// 파싱된 각 VO에 대해 검증 수행
|
||||||
|
for (VarFtListMapVO vo : parsedList) {
|
||||||
|
String validationError = MunjaUtil.kakaoFtValidate(vo, msgFtRequestVO);
|
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(validationError)) {
|
||||||
|
return validationError; // 검증 실패 시 오류 코드 반환
|
||||||
|
}
|
||||||
|
|
||||||
|
// 검증 통과한 VO를 리스트에 추가
|
||||||
|
msgFtRequestVO.getVarListMap().add(vo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null; // 모든 검증 통과
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String validateSenderKey(String mberId, String senderKey) {
|
||||||
|
if (StringUtils.isEmpty(senderKey)) {
|
||||||
|
return "STAT_2010";
|
||||||
|
}
|
||||||
|
|
||||||
|
List<MjKakaoProfileInfoVO> resultList = (List<MjKakaoProfileInfoVO>) inqryService.getChnlId(BizTemplateRequest.builder().mberId(mberId).build()).getData();
|
||||||
|
boolean ok = resultList.stream().anyMatch(p -> senderKey.equals(p.getSenderKey()));
|
||||||
|
return ok ? null : "STAT_2010";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getImagesInfo(MsgFtRequestVO msgFtRequestVO) throws IOException, NoSuchAlgorithmException {
|
||||||
|
|
||||||
|
log.info("msgFtRequestVO.getTemplateImage() : [{}]", msgFtRequestVO.getTemplateImage());
|
||||||
|
if (FtFileMetaUtil.hasFile(msgFtRequestVO.getTemplateImage())) {
|
||||||
|
String code = FtFileMetaUtil.fillTemplateMeta(msgFtRequestVO);
|
||||||
|
if (StringUtils.isNotEmpty(code)) return code;
|
||||||
|
|
||||||
|
// 메타데이터 처리 성공 후 업로드 API 호출
|
||||||
|
try {
|
||||||
|
// Option 1: ApiService에 multipart 메소드 추가
|
||||||
|
StatusResponse uploadResponse = apiService.postMultipartForEntity(
|
||||||
|
"/web/mjon/kakao/template/sendKakaoFriendsTemplateImageUploadAjax_advc.do",
|
||||||
|
msgFtRequestVO,
|
||||||
|
msgFtRequestVO.getTemplateImage()
|
||||||
|
);
|
||||||
|
// .is2xxSuccessful() 상태코드가 200번대(200 ~ 299)인지 확인
|
||||||
|
if (uploadResponse != null && uploadResponse.getStatus().is2xxSuccessful()) {
|
||||||
|
Map<String, Object> obj = (Map<String, Object>) uploadResponse.getObject();
|
||||||
|
String imgUrl = (String) obj.get("imgUrl");
|
||||||
|
String atchFileId = (String) obj.get("atchFileId");
|
||||||
|
|
||||||
|
log.info("imgUrl: {}, atchFileId: {}", imgUrl, atchFileId);
|
||||||
|
msgFtRequestVO.setTemplateImageUrl(imgUrl);
|
||||||
|
msgFtRequestVO.setFilePath1(atchFileId);
|
||||||
|
}else{
|
||||||
|
// return new RestResponse(new FailRestResponse("STAT_2099", ""));
|
||||||
|
return "STAT_2099";
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("템플릿 이미지 업로드 실패", e);
|
||||||
|
return "STAT_2099";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.ft.send.service;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.MsgFtRequestVO;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
public interface SendFtService {
|
||||||
|
|
||||||
|
|
||||||
|
// RestResponse sendMsgData(MsgRequestVO msgRequestVO) throws Exception;
|
||||||
|
//
|
||||||
|
// RestResponse sendMsgData_advc(MsgRequestVO msgRequestVO) throws Exception;
|
||||||
|
//
|
||||||
|
// RestResponse sendMsgsData(MsgsRequestVO msgsRequestVO) throws Exception;
|
||||||
|
//
|
||||||
|
// RestResponse sendMsgsData_advc(MsgsRequestVO msgsRequestVO) throws Exception;
|
||||||
|
|
||||||
|
RestResponse sendFtData(MsgFtRequestVO msgFtRequestVO, HttpServletRequest request) throws IOException, NoSuchAlgorithmException;
|
||||||
|
}
|
||||||
@ -0,0 +1,197 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.ft.send.service.impl;
|
||||||
|
|
||||||
|
import com.itn.mjonApi.cmn.apiServer.ApiService;
|
||||||
|
import com.itn.mjonApi.cmn.msg.FailRestResponse;
|
||||||
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.*;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.service.FtParameterProcessingService;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.service.SendFtService;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.PriceMapper;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.SendMapper;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.MjonResponseVO;
|
||||||
|
import com.itn.mjonApi.util.TestDataUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.catalina.connector.Response;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class SendFtServiceImpl implements SendFtService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FtParameterProcessingService ftParameterProcessingService;
|
||||||
|
|
||||||
|
private ApiService<Response> apiService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
SendMapper sendMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
PriceMapper priceMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public SendFtServiceImpl(ApiService<Response> apiService) {
|
||||||
|
this.apiService = apiService;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String replaseStrList = "[*이름*],[*1*],[*2*],[*3*],[*4*]";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param
|
||||||
|
* @return
|
||||||
|
* @throws Exception 처리 중 예외 발생 가능
|
||||||
|
* @date 2025-07-29
|
||||||
|
* @Discription 치환없는 알림톡 데이터
|
||||||
|
* @author hylee
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public RestResponse sendFtData(MsgFtRequestVO msgFtRequestVO, HttpServletRequest request) throws IOException, NoSuchAlgorithmException {
|
||||||
|
|
||||||
|
if(StringUtils.isNotEmpty(msgFtRequestVO.getTest_yn())){
|
||||||
|
// YF => 실패 테스트 데이터, YS => 성공 테스트 데이터 (친구톡 전용)
|
||||||
|
return TestDataUtil.getTestFtSendReturnData(msgFtRequestVO.getTest_yn());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 데이터
|
||||||
|
// Form-data의 인덱스된 파라미터들을 VarListMapVO 리스트로 변환 (동적 처리 _1~_100)
|
||||||
|
String falseCode = ftParameterProcessingService.processIndexedParameters(msgFtRequestVO, request);
|
||||||
|
if(StringUtils.isNotEmpty(falseCode)){
|
||||||
|
log.info("falseCode :: [{}]", falseCode);
|
||||||
|
return new RestResponse(new FailRestResponse(falseCode,""));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 이미지 정제
|
||||||
|
String falseImageCode = ftParameterProcessingService.getImagesInfo(msgFtRequestVO);
|
||||||
|
if(StringUtils.isNotEmpty(falseImageCode)) return new RestResponse(new FailRestResponse(falseImageCode,""));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ========== 새로운 개별 발송 코드 ==========
|
||||||
|
List<MjonResponseVO> responses = new ArrayList<>();
|
||||||
|
List<String> successList = new ArrayList<>();
|
||||||
|
List<String> failList = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
log.info("msgFtRequestVO.toString() :: [{}]", msgFtRequestVO.toString());
|
||||||
|
// 각 수신자별로 개별 발송 처리
|
||||||
|
// List<KakaoFTSendVO> individualRequestList = new ArrayList<>();
|
||||||
|
for (VarFtListMapVO recipient : msgFtRequestVO.getVarListMap()) {
|
||||||
|
try {
|
||||||
|
// 개별 수신자용 KakaoFTSendVO 생성
|
||||||
|
KakaoFTSendVO individualRequest = createKakaoFTSendVO(msgFtRequestVO, recipient);
|
||||||
|
// individualRequestList.add(individualRequest);
|
||||||
|
|
||||||
|
log.info("individualRequest: {}", individualRequest);
|
||||||
|
|
||||||
|
// 개별 API 호출
|
||||||
|
MjonResponseVO response = apiService.postForEntity(
|
||||||
|
"/web/mjon/kakao/friendstalk/kakaoFriendsTalkMsgSendAjax_advc.do",
|
||||||
|
individualRequest,
|
||||||
|
String.class
|
||||||
|
);
|
||||||
|
log.info("response: {}", response);
|
||||||
|
|
||||||
|
responses.add(response);
|
||||||
|
successList.add(recipient.getPhone());
|
||||||
|
|
||||||
|
log.info("개별 발송 성공 - 수신번호: {}", recipient.getPhone());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("개별 발송 실패 - 수신번호: {}, 오류: {}", recipient.getPhone(), e.getMessage());
|
||||||
|
failList.add(recipient.getPhone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SMS API 형태의 응답 생성
|
||||||
|
FtSendSuccessResponse ftResponse = FtSendSuccessResponse.createFtResponse(
|
||||||
|
msgFtRequestVO.getVarListMap().size(),
|
||||||
|
successList.size(),
|
||||||
|
failList.size(),
|
||||||
|
successList
|
||||||
|
);
|
||||||
|
|
||||||
|
return new RestResponse(ftResponse);
|
||||||
|
// return new RestResponse(individualRequestList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MsgFtRequestVO + VarFtListMapVO를 KakaoFTSendVO로 변환
|
||||||
|
* (개별 수신자용 객체 생성)
|
||||||
|
*/
|
||||||
|
private KakaoFTSendVO createKakaoFTSendVO(MsgFtRequestVO source, VarFtListMapVO recipient) {
|
||||||
|
|
||||||
|
// 버튼 변환 (FtButtonVO → KakaoButtonVO)
|
||||||
|
List<KakaoButtonVO> kakaoButtons = source.getButtons().stream()
|
||||||
|
.map(this::convertToKakaoButton)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 개별 수신자 객체 생성
|
||||||
|
MjonFTSendVO mjonFTSend = MjonFTSendVO.builder()
|
||||||
|
.phone(recipient.getPhone()) // 핵심: 수신번호
|
||||||
|
// .callTo(recipient.getPhone()) // 동일값
|
||||||
|
// .eventYn("N") // 기본값
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// KakaoFTSendVO 생성
|
||||||
|
return KakaoFTSendVO.builder()
|
||||||
|
// 공통 정보 (모든 요청에 동일)
|
||||||
|
|
||||||
|
.mberId(source.getMberId())
|
||||||
|
.sendKind(source.getSendKind())
|
||||||
|
.reserveYn("N")
|
||||||
|
.adFlag(source.getAdFlag())
|
||||||
|
|
||||||
|
.senderKey(source.getSenderKey())
|
||||||
|
.callFrom(source.getCallFrom())
|
||||||
|
.buttonVOList(kakaoButtons)
|
||||||
|
|
||||||
|
// 이미지 관련
|
||||||
|
.templateImageUrl(source.getTemplateImageUrl())
|
||||||
|
.atchFileId(source.getFilePath1())
|
||||||
|
.imageType(source.getTemplateImageUrl() != null ? source.getTemplateMsgType() : null)
|
||||||
|
// .imageFileName(extractFileName(source.getTemplateImageUrl()))
|
||||||
|
.imageFileName(source.getTemplateImageName())
|
||||||
|
|
||||||
|
// 개별 수신자 정보
|
||||||
|
.templateContent(recipient.getTemplateContent()) // 개별 내용
|
||||||
|
.subMsgSendYn(source.getSubMsgSendYn()) // 개별 대체문자
|
||||||
|
.subMsgTxt(recipient.getSubMsgTxt()) // 개별 대체문자
|
||||||
|
.mjonFTSendVOList(Arrays.asList(mjonFTSend)) // 단일 수신자만
|
||||||
|
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FtButtonVO를 KakaoButtonVO로 변환
|
||||||
|
*/
|
||||||
|
private KakaoButtonVO convertToKakaoButton(FtButtonVO source) {
|
||||||
|
return KakaoButtonVO.builder()
|
||||||
|
.name(source.getName())
|
||||||
|
.linkType(source.getLinkType())
|
||||||
|
.linkTypeName(source.getLinkTypeName())
|
||||||
|
.linkMo(source.getLinkMo())
|
||||||
|
.linkPc(source.getLinkPc())
|
||||||
|
.linkIos(source.getLinkIos())
|
||||||
|
.linkAnd(source.getLinkAnd())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 이미지 URL에서 파일명 추출
|
||||||
|
*/
|
||||||
|
private String extractFileName(String imageUrl) {
|
||||||
|
if (imageUrl == null) return null;
|
||||||
|
return imageUrl.substring(imageUrl.lastIndexOf('/') + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.ft.send.web;
|
||||||
|
|
||||||
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.MsgFtRequestVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.service.SendFtService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* packageName : com.itn.mjonApi.mjon.send.web
|
||||||
|
* fileName : SendRestController
|
||||||
|
* author : hylee
|
||||||
|
* date : 2023-02-15
|
||||||
|
* description :
|
||||||
|
* ===========================================================
|
||||||
|
* DATE AUTHOR NOTE
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* 2023-02-15 hylee 최초 생성
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 치환문자가 있으면 , => §로 치환
|
||||||
|
|
||||||
|
@CrossOrigin("*") // 모든 요청에 접근 허용
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
public class SendFtRestController {
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SendFtService sendFtService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param msgFtRequestVO
|
||||||
|
* @param request
|
||||||
|
* @Discription [문자 발송] 같은 내용으로 여려명에게 보냄
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/api/kakao/ft/sendMsg",
|
||||||
|
consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
|
public ResponseEntity<RestResponse> sendMsg(
|
||||||
|
@ModelAttribute MsgFtRequestVO msgFtRequestVO // 폼 텍스트들 바인딩
|
||||||
|
, HttpServletRequest request) throws Exception {
|
||||||
|
|
||||||
|
// https://smartsms.aligo.in/friendapi.html
|
||||||
|
|
||||||
|
return ResponseEntity.ok().body(sendFtService.sendFtData(msgFtRequestVO, request));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,279 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.kakao.utils;
|
||||||
|
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.MsgFtRequestVO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kakao FT 이미지 메타데이터 유틸리티.
|
||||||
|
* - 템플릿/서브 이미지의 파일명, 용량, 폭/높이, SHA-256 해시 세팅
|
||||||
|
* - 템플릿: I/W 타입 판정(2:1, 4:3, 가로≥500) 및 검증
|
||||||
|
* - 서브(MMS): jpg/jpeg/png/gif, ≤10MB만 검증(권장 640×960은 안내 수준)
|
||||||
|
* - 실패 시 코드 문자열 반환(성공 시 null)
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class FtFileMetaUtil {
|
||||||
|
|
||||||
|
// ===== 실패코드 상수 정의 =====
|
||||||
|
private static final String OK = null; // 성공 시 null 반환
|
||||||
|
private static final String FT_E_EMPTY = "STAT_2055"; // 파일이 비어있음
|
||||||
|
private static final String FT_E_IMG_READ_FAIL = "STAT_2052"; // 이미지 읽기 실패
|
||||||
|
private static final String FT_E_WIDTH_LT_500 = "STAT_2054"; // 가로폭 500px 미만
|
||||||
|
private static final String FT_E_RATIO_OUT_OF_RANGE = "STAT_2056"; // 비율이 2:1~4:3 범위 밖
|
||||||
|
private static final String FT_E_SIZE_GT_5MB = "STAT_2051"; // 파일 크기 초과(5MB 이상)
|
||||||
|
private static final String FT_E_CONTENT_TYPE = "STAT_2050"; // 허용되지 않는 콘텐츠 타입// 추가
|
||||||
|
private static final String FT_E_SIZE_GT_10MB = "STAT_2057"; // 대체문자(MMS) 이미지는 10MB를 초과할 수 없습니다.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 템플릿 이미지의 메타데이터(파일명, 용량, 폭/높이, 해시, 타입)를 MsgFtRequestVO에 채움
|
||||||
|
* @param vo 메타데이터를 세팅할 VO
|
||||||
|
* @throws IOException
|
||||||
|
* @throws NoSuchAlgorithmException
|
||||||
|
*/
|
||||||
|
public static String fillTemplateMeta(MsgFtRequestVO vo) throws IOException, NoSuchAlgorithmException {
|
||||||
|
return fillMeta(vo.getTemplateImage(),
|
||||||
|
(name) -> vo.setTemplateImageName(name),
|
||||||
|
(ct) -> vo.setTemplateImageContentType(ct),
|
||||||
|
(size) -> vo.setTemplateImageSize(size),
|
||||||
|
(w) -> vo.setTemplateImageWidth(w),
|
||||||
|
(h) -> vo.setTemplateImageHeight(h),
|
||||||
|
(hash) -> vo.setTemplateImageSha256(hash),
|
||||||
|
(type) -> vo.setTemplateMsgType(type) // I/W 세팅
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 서브(와이드) 이미지의 메타데이터를 MsgFtRequestVO에 채움
|
||||||
|
* - MMS 규격 검증(타입/10MB)만 수행, I/W 판정 없음
|
||||||
|
* @param vo 메타데이터를 세팅할 VO
|
||||||
|
* @throws IOException
|
||||||
|
* @throws NoSuchAlgorithmException
|
||||||
|
*/
|
||||||
|
// public static String fillSubMeta(MsgFtRequestVO vo) throws IOException, NoSuchAlgorithmException {
|
||||||
|
// return fillMetaForSubImage(vo.getSubImage(),
|
||||||
|
// (name) -> vo.setSubImageName(name),
|
||||||
|
// (ct) -> vo.setSubImageContentType(ct),
|
||||||
|
// (size) -> vo.setSubImageSize(size),
|
||||||
|
// (w) -> vo.setSubImageWidth(w),
|
||||||
|
// (h) -> vo.setSubImageHeight(h),
|
||||||
|
// (hash) -> vo.setSubImageSha256(hash)
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* subImage(MMS) 전용 메타데이터 수집/검증 메서드
|
||||||
|
* - 검증: 파일 존재 여부, 용량(≤10MB), Content-Type(jpg/jpeg/png/gif)
|
||||||
|
* - 세팅: 파일명, Content-Type, 파일 크기, width/height, SHA-256
|
||||||
|
* - 비율/가로 500px 검증은 하지 않음 (권장 640×960은 안내 수준)
|
||||||
|
*
|
||||||
|
* @param f 업로드된 서브 이미지 파일
|
||||||
|
* @param nameC 파일명 setter
|
||||||
|
* @param ctC Content-Type setter
|
||||||
|
* @param sizeC 파일 크기 setter
|
||||||
|
* @param wC width setter
|
||||||
|
* @param hC height setter
|
||||||
|
* @param hashC SHA-256 setter
|
||||||
|
* @return 실패코드(String), 성공 시 null(OK)
|
||||||
|
* @throws IOException
|
||||||
|
* @throws NoSuchAlgorithmException
|
||||||
|
*/
|
||||||
|
private static String fillMetaForSubImage(
|
||||||
|
MultipartFile f,
|
||||||
|
Consumer<String> nameC,
|
||||||
|
Consumer<String> ctC,
|
||||||
|
Consumer<Long> sizeC,
|
||||||
|
Consumer<Integer> wC,
|
||||||
|
Consumer<Integer> hC,
|
||||||
|
Consumer<String> hashC
|
||||||
|
) throws IOException, NoSuchAlgorithmException {
|
||||||
|
// 1) 파일 존재/빈 파일 체크
|
||||||
|
if (f == null || f.isEmpty()) return FT_E_EMPTY;
|
||||||
|
|
||||||
|
// 2) 용량(10MB) 제한
|
||||||
|
if (f.getSize() > 10L * 1024 * 1024) return FT_E_SIZE_GT_10MB;
|
||||||
|
|
||||||
|
// 3) 허용 Content-Type 확인 (jpg/jpeg/png/gif)
|
||||||
|
String ct = f.getContentType();
|
||||||
|
if (!isAllowedSubCt(ct)) return FT_E_CONTENT_TYPE;
|
||||||
|
|
||||||
|
// 4) 기본 메타 세팅
|
||||||
|
nameC.accept(f.getOriginalFilename());
|
||||||
|
ctC.accept(ct);
|
||||||
|
sizeC.accept(f.getSize());
|
||||||
|
|
||||||
|
// 5) 이미지 읽기 → width/height 세팅 (비율 제한 없음)
|
||||||
|
int w = 0, h = 0;
|
||||||
|
try (InputStream is = f.getInputStream()) {
|
||||||
|
BufferedImage img = ImageIO.read(is);
|
||||||
|
if (img == null) return FT_E_IMG_READ_FAIL;
|
||||||
|
w = img.getWidth();
|
||||||
|
h = img.getHeight();
|
||||||
|
wC.accept(w);
|
||||||
|
hC.accept(h);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return FT_E_IMG_READ_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sha-256
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||||
|
md.update(f.getBytes());
|
||||||
|
hashC.accept(bytesToHex(md.digest()));
|
||||||
|
|
||||||
|
// 권장 사이즈(640×960)는 안내사항이므로 실패코드 미반환
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 공통 메타데이터 채우기 유틸
|
||||||
|
* - 파일명, Content-Type, 파일 크기
|
||||||
|
* - 이미지 폭/높이
|
||||||
|
* - 파일 SHA-256 해시
|
||||||
|
* - 가로/세로 비율 기반의 메시지 타입(I/W) 판정
|
||||||
|
*
|
||||||
|
* @param f MultipartFile (이미지 파일)
|
||||||
|
* @param nameC 파일명 setter
|
||||||
|
* @param ctC ContentType setter
|
||||||
|
* @param sizeC 파일 크기 setter
|
||||||
|
* @param wC width setter
|
||||||
|
* @param hC height setter
|
||||||
|
* @param hashC SHA-256 setter
|
||||||
|
* @param typeC 이미지 타입(I/W) setter
|
||||||
|
* @return 실패코드(String), 성공 시 null 반환
|
||||||
|
*/
|
||||||
|
private static String fillMeta(MultipartFile f,
|
||||||
|
Consumer<String> nameC,
|
||||||
|
Consumer<String> ctC,
|
||||||
|
Consumer<Long> sizeC,
|
||||||
|
Consumer<Integer> wC,
|
||||||
|
Consumer<Integer> hC,
|
||||||
|
Consumer<String> hashC,
|
||||||
|
Consumer<String> typeC
|
||||||
|
) throws IOException, NoSuchAlgorithmException {
|
||||||
|
if (f == null || f.isEmpty()) return FT_E_EMPTY;
|
||||||
|
|
||||||
|
// 용량/콘텐츠타입 1차 검증
|
||||||
|
if (f.getSize() > 5L * 1024 * 1024) return FT_E_SIZE_GT_5MB;
|
||||||
|
|
||||||
|
String ct = f.getContentType();
|
||||||
|
log.info(" + ct :: [{}]", ct);
|
||||||
|
|
||||||
|
// MIME 타입이 application/octet-stream이면 파일명으로 추정
|
||||||
|
if ("application/octet-stream".equalsIgnoreCase(ct)) {
|
||||||
|
String filename = f.getOriginalFilename();
|
||||||
|
if (filename != null) {
|
||||||
|
String ext = filename.toLowerCase();
|
||||||
|
if (ext.endsWith(".jpg") || ext.endsWith(".jpeg")) {
|
||||||
|
ct = "image/jpeg";
|
||||||
|
} else if (ext.endsWith(".png")) {
|
||||||
|
ct = "image/png";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ct == null || !(ct.equalsIgnoreCase("image/jpeg")
|
||||||
|
|| ct.equalsIgnoreCase("image/png"))) {
|
||||||
|
return FT_E_CONTENT_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nameC.accept(f.getOriginalFilename());
|
||||||
|
ctC.accept(ct);
|
||||||
|
sizeC.accept(f.getSize());
|
||||||
|
|
||||||
|
int w = 0, h = 0;
|
||||||
|
try (InputStream is = f.getInputStream()) {
|
||||||
|
BufferedImage img = ImageIO.read(is);
|
||||||
|
if (img == null) return FT_E_IMG_READ_FAIL;
|
||||||
|
w = img.getWidth();
|
||||||
|
h = img.getHeight();
|
||||||
|
wC.accept(w);
|
||||||
|
hC.accept(h);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return FT_E_IMG_READ_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sha-256
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||||
|
md.update(f.getBytes());
|
||||||
|
hashC.accept(bytesToHex(md.digest()));
|
||||||
|
|
||||||
|
// 규칙 검증 + 타입(I/W) 판정
|
||||||
|
String typeOrCode = calcFtMsgTypeOrCode(w, h);
|
||||||
|
if (typeOrCode.length() == 1) { // "I" or "W"
|
||||||
|
typeC.accept(typeOrCode);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
return typeOrCode; // 실패코드 리턴
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* byte[] → 16진수 문자열 변환
|
||||||
|
* @param bytes SHA-256 결과 바이트 배열
|
||||||
|
* @return Hex 문자열
|
||||||
|
*/
|
||||||
|
private static String bytesToHex(byte[] bytes) {
|
||||||
|
StringBuilder sb = new StringBuilder(bytes.length * 2);
|
||||||
|
for (byte b : bytes) sb.append(String.format("%02x", b));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 가로/세로 크기를 기반으로 이미지 타입 판정
|
||||||
|
* - 폭 < 500px → 오류코드 반환
|
||||||
|
* - 비율이 2:1(약 2.0) ±10% → "I"
|
||||||
|
* - 비율이 4:3(약 1.333) ±10% → "W"
|
||||||
|
* - 그 외 → 오류코드 반환
|
||||||
|
*
|
||||||
|
* @param width 이미지 가로 폭
|
||||||
|
* @param height 이미지 세로 높이
|
||||||
|
* @return "I" 또는 "W" / 실패코드
|
||||||
|
*/
|
||||||
|
public static String calcFtMsgTypeOrCode(int width, int height) {
|
||||||
|
if (width < 500 || height <= 0) return FT_E_WIDTH_LT_500;
|
||||||
|
|
||||||
|
double r = (double) width / (double) height;
|
||||||
|
// 2:1 ~= 2.0, 4:3 ~= 1.333... (±10%)
|
||||||
|
boolean isI = (r >= 1.8 && r <= 2.2);
|
||||||
|
boolean isW = (r >= 1.28 && r <= 1.36);
|
||||||
|
|
||||||
|
if (isI) return "I";
|
||||||
|
if (isW) return "W";
|
||||||
|
return FT_E_RATIO_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MultipartFile 존재 여부 헬퍼
|
||||||
|
* @param f 업로드 파일
|
||||||
|
* @return 파일이 null이 아니고 비어있지 않으면 true
|
||||||
|
*/
|
||||||
|
public static boolean hasFile(MultipartFile f){ return f != null && !f.isEmpty(); }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 서브(MMS) 허용 Content-Type 검사
|
||||||
|
* 허용: image/jpeg, image/jpg, image/png, image/gif
|
||||||
|
* @param ct 요청의 Content-Type
|
||||||
|
* @return 허용 타입이면 true
|
||||||
|
*/
|
||||||
|
private static boolean isAllowedSubCt(String ct) {
|
||||||
|
return ct != null && (
|
||||||
|
ct.equalsIgnoreCase("image/jpeg") ||
|
||||||
|
ct.equalsIgnoreCase("image/jpg") || // 일부 클라이언트 대비
|
||||||
|
ct.equalsIgnoreCase("image/png") ||
|
||||||
|
ct.equalsIgnoreCase("image/gif")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,14 +1,14 @@
|
|||||||
package com.itn.mjonApi.mjon.api.inqry.mapper;
|
package com.itn.mjonApi.mjon.api.msg.inqry.mapper;
|
||||||
|
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.mapper.domain.HstryDetailVO;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.HstryDetailVO;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.mapper.domain.HstryVO;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.HstryVO;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.mapper.domain.MjonResponseVO;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.MjonResponseVO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @packageName : com.itn.mjonApi.mjon.api.inqry.service.mapper
|
* @packageName : com.itn.mjonApi.mjon.api.msg.inqry.service.mapper
|
||||||
* @fileName : PriceMapper.java
|
* @fileName : PriceMapper.java
|
||||||
* @author : JunHo Lee
|
* @author : JunHo Lee
|
||||||
* @date : 2023.05.15
|
* @date : 2023.05.15
|
||||||
@ -1,11 +1,11 @@
|
|||||||
package com.itn.mjonApi.mjon.api.inqry.mapper;
|
package com.itn.mjonApi.mjon.api.msg.inqry.mapper;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @packageName : com.itn.mjonApi.mjon.api.inqry.service.mapper
|
* @packageName : com.itn.mjonApi.mjon.api.msg.inqry.service.mapper
|
||||||
* @fileName : PriceMapper.java
|
* @fileName : PriceMapper.java
|
||||||
* @author : JunHo Lee
|
* @author : JunHo Lee
|
||||||
* @date : 2023.05.15
|
* @date : 2023.05.15
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.itn.mjonApi.mjon.api.inqry.service.mapper.domain;
|
package com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.itn.mjonApi.mjon.api.inqry.service.mapper.domain;
|
package com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain;
|
||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.itn.mjonApi.mjon.api.inqry.service.mapper.domain;
|
package com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.itn.mjonApi.mjon.api.inqry.service.mapper.domain;
|
package com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain;
|
||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
@ -1,14 +1,9 @@
|
|||||||
package com.itn.mjonApi.mjon.api.inqry.mapper.domain;
|
package com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import java.time.LocalDateTime;
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
@Getter
|
@Getter
|
||||||
@ -27,13 +22,23 @@ public class PriceResponse {
|
|||||||
private double shortPrice; // 단문 이용단가
|
private double shortPrice; // 단문 이용단가
|
||||||
private double longPrice; // 장문 이용단가
|
private double longPrice; // 장문 이용단가
|
||||||
private double picturePrice; // 그림 이용단가
|
private double picturePrice; // 그림 이용단가
|
||||||
|
|
||||||
|
private double kakaoAtPrice; // 그림 이용단가
|
||||||
|
private double kakaoFtPrice; // 그림 이용단가
|
||||||
|
private double kakaoFtImgPrice; // 그림 이용단가
|
||||||
|
private double kakaoFtWideImgPrice; // 그림 이용단가
|
||||||
|
|
||||||
private double mberMoney; // 잔액
|
private double mberMoney; // 잔액
|
||||||
|
|
||||||
private int shortSendPsbltEa; // 단문 발송 가능건 수
|
private int shortSendPsbltEa; // 단문 발송 가능건 수
|
||||||
private int longSendPsbltEa; // 장문 발송 가능건 수
|
private int longSendPsbltEa; // 장문 발송 가능건 수
|
||||||
private int pictureSendPsbltEa; // 그림 발송 가능건 수
|
private int pictureSendPsbltEa; // 그림 발송 가능건 수
|
||||||
|
|
||||||
|
private int kakaoAtSendPsbltEa; // 그림 발송 가능건 수
|
||||||
|
private int kakaoFtSendPsbltEa; // 그림 발송 가능건 수
|
||||||
|
private int kakaoFtImgSendPsbltEa; // 그림 발송 가능건 수
|
||||||
|
private int kakaoFtWideImgSendPsbltEa; // 그림 발송 가능건 수
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 200-OK : 정상접속
|
* 200-OK : 정상접속
|
||||||
* 401-Unauthorized : 인증실패
|
* 401-Unauthorized : 인증실패
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PriceVO implements Serializable{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -7865729705175845268L;
|
||||||
|
|
||||||
|
private String mberId; // 사용자 ID
|
||||||
|
|
||||||
|
private double shortPrice; // 단문 이용단가
|
||||||
|
private double longPrice; // 장문 이용단가
|
||||||
|
private double picturePrice; // 그림 이용단가
|
||||||
|
|
||||||
|
private double kakaoAtPrice; // 알림톡 이용단가
|
||||||
|
private double kakaoFtPrice; // 친구톡 이용단가
|
||||||
|
private double kakaoFtImgPrice; // 친구톡 그림 이용단가
|
||||||
|
private double kakaoFtWideImgPrice; // 친구톡 와이드 그림 이용단가
|
||||||
|
|
||||||
|
private double mberMoney; // 잔액
|
||||||
|
|
||||||
|
private int shortSendPsbltEa; // 단문 발송 가능건 수
|
||||||
|
private int longSendPsbltEa; // 장문 발송 가능건 수
|
||||||
|
private int pictureSendPsbltEa; // 그림 발송 가능건 수
|
||||||
|
|
||||||
|
private int kakaoAtSendPsbltEa; // 알림톡 발송 가능건 수
|
||||||
|
private int kakaoFtSendPsbltEa; // 친구톡 발송 가능건 수
|
||||||
|
private int kakaoFtImgSendPsbltEa; // 친구톡 그림 발송 가능건 수
|
||||||
|
private int kakaoFtWideImgSendPsbltEa; // 친구톡 와이드 그림 발송 가능건 수
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,8 +1,8 @@
|
|||||||
package com.itn.mjonApi.mjon.api.inqry.service;
|
package com.itn.mjonApi.mjon.api.msg.inqry.service;
|
||||||
|
|
||||||
import com.itn.mjonApi.cmn.msg.RestResponse;
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.mapper.domain.HstryDetailVO;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.HstryDetailVO;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.mapper.domain.HstryVO;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.HstryVO;
|
||||||
|
|
||||||
public interface HstryService {
|
public interface HstryService {
|
||||||
|
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package com.itn.mjonApi.mjon.api.inqry.service;
|
package com.itn.mjonApi.mjon.api.msg.inqry.service;
|
||||||
|
|
||||||
import com.itn.mjonApi.cmn.msg.RestResponse;
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @packageName : com.itn.mjonApi.mjon.api.inqry.service
|
* @packageName : com.itn.mjonApi.mjon.api.msg.inqry.service
|
||||||
* @fileName : PriceService.java
|
* @fileName : PriceService.java
|
||||||
* @author : JunHo Lee
|
* @author : JunHo Lee
|
||||||
* @date : 2023.05.15
|
* @date : 2023.05.15
|
||||||
@ -1,15 +1,15 @@
|
|||||||
package com.itn.mjonApi.mjon.api.inqry.service.impl;
|
package com.itn.mjonApi.mjon.api.msg.inqry.service.impl;
|
||||||
|
|
||||||
import com.itn.mjonApi.cmn.apiServer.ApiService;
|
import com.itn.mjonApi.cmn.apiServer.ApiService;
|
||||||
import com.itn.mjonApi.cmn.msg.RestResponse;
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
import com.itn.mjonApi.cmn.msg.FailRestResponse;
|
import com.itn.mjonApi.cmn.msg.FailRestResponse;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.mapper.HstryMapper;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.HstryMapper;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.HstryService;
|
import com.itn.mjonApi.mjon.api.msg.inqry.service.HstryService;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.mapper.domain.HstryDetailVO;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.HstryDetailVO;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.mapper.domain.HstryResponse;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.HstryResponse;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.mapper.domain.HstryVO;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.HstryVO;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.mapper.domain.MjonResponseVO;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.MjonResponseVO;
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.SendMapper;
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.SendMapper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.catalina.connector.Response;
|
import org.apache.catalina.connector.Response;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -28,9 +28,7 @@ public class HstryServiceImpl implements HstryService {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HstryMapper hstryMapper;
|
HstryMapper hstryMapper;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
SendMapper sendMapper;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public HstryServiceImpl(ApiService<Response> apiService) {
|
public HstryServiceImpl(ApiService<Response> apiService) {
|
||||||
@ -1,13 +1,13 @@
|
|||||||
package com.itn.mjonApi.mjon.api.inqry.service.impl;
|
package com.itn.mjonApi.mjon.api.msg.inqry.service.impl;
|
||||||
|
|
||||||
import com.itn.mjonApi.cmn.model.Price;
|
import com.itn.mjonApi.cmn.model.Price;
|
||||||
import com.itn.mjonApi.cmn.msg.FailRestResponse;
|
import com.itn.mjonApi.cmn.msg.FailRestResponse;
|
||||||
import com.itn.mjonApi.cmn.msg.RestResponse;
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
import com.itn.mjonApi.cmn.msg.StatMsg;
|
import com.itn.mjonApi.cmn.msg.StatMsg;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.mapper.PriceMapper;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.PriceMapper;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.mapper.domain.PriceResponse;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.PriceResponse;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.mapper.domain.PriceVO;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.PriceVO;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.PriceService;
|
import com.itn.mjonApi.mjon.api.msg.inqry.service.PriceService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@ -16,7 +16,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @packageName : com.itn.mjonApi.mjon.api.inqry.service.impl
|
* @packageName : com.itn.mjonApi.mjon.api.msg.inqry.service.impl
|
||||||
* @fileName : PriceServiceImpl.java
|
* @fileName : PriceServiceImpl.java
|
||||||
* @author : JunHo Lee
|
* @author : JunHo Lee
|
||||||
* @date : 2023.05.15
|
* @date : 2023.05.15
|
||||||
@ -59,10 +59,20 @@ public class PriceServiceImpl implements PriceService {
|
|||||||
.shortPrice(priceVO.getShortPrice())
|
.shortPrice(priceVO.getShortPrice())
|
||||||
.longPrice(priceVO.getLongPrice())
|
.longPrice(priceVO.getLongPrice())
|
||||||
.picturePrice(priceVO.getPicturePrice())
|
.picturePrice(priceVO.getPicturePrice())
|
||||||
|
|
||||||
|
.kakaoAtPrice(priceVO.getKakaoAtPrice())
|
||||||
|
.kakaoFtPrice(priceVO.getKakaoFtPrice())
|
||||||
|
.kakaoFtImgPrice(priceVO.getKakaoFtImgPrice())
|
||||||
|
.kakaoFtWideImgPrice(priceVO.getKakaoFtWideImgPrice())
|
||||||
//3. 발송가능건수
|
//3. 발송가능건수
|
||||||
.shortSendPsbltEa(priceVO.getShortSendPsbltEa())
|
.shortSendPsbltEa(priceVO.getShortSendPsbltEa())
|
||||||
.longSendPsbltEa(priceVO.getLongSendPsbltEa())
|
.longSendPsbltEa(priceVO.getLongSendPsbltEa())
|
||||||
.pictureSendPsbltEa(priceVO.getPictureSendPsbltEa())
|
.pictureSendPsbltEa(priceVO.getPictureSendPsbltEa())
|
||||||
|
|
||||||
|
.kakaoAtSendPsbltEa(priceVO.getKakaoAtSendPsbltEa())
|
||||||
|
.kakaoFtSendPsbltEa(priceVO.getKakaoFtSendPsbltEa())
|
||||||
|
.kakaoFtImgSendPsbltEa(priceVO.getKakaoFtImgSendPsbltEa())
|
||||||
|
.kakaoFtWideImgSendPsbltEa(priceVO.getKakaoFtWideImgSendPsbltEa())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -1,9 +1,9 @@
|
|||||||
package com.itn.mjonApi.mjon.api.inqry.web;
|
package com.itn.mjonApi.mjon.api.msg.inqry.web;
|
||||||
|
|
||||||
import com.itn.mjonApi.cmn.msg.RestResponse;
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.HstryService;
|
import com.itn.mjonApi.mjon.api.msg.inqry.service.HstryService;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.mapper.domain.HstryDetailVO;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.HstryDetailVO;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.mapper.domain.HstryVO;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.HstryVO;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@ -24,7 +24,6 @@ import org.springframework.web.client.RestTemplate;
|
|||||||
* 2023-02-15 hylee 최초 생성
|
* 2023-02-15 hylee 최초 생성
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// 치환문자가 있으면 , => §로 치환
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.itn.mjonApi.mjon.api.inqry.web;
|
package com.itn.mjonApi.mjon.api.msg.inqry.web;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@ -6,11 +6,11 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import com.itn.mjonApi.cmn.msg.RestResponse;
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.mapper.domain.PriceVO;
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.PriceVO;
|
||||||
import com.itn.mjonApi.mjon.api.inqry.service.PriceService;
|
import com.itn.mjonApi.mjon.api.msg.inqry.service.PriceService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @packageName : com.itn.mjonApi.mjon.api.inqry.web
|
* @packageName : com.itn.mjonApi.mjon.api.msg.inqry.web
|
||||||
* @fileName : PriceRestController.java
|
* @fileName : PriceRestController.java
|
||||||
* @author : JunHo Lee
|
* @author : JunHo Lee
|
||||||
* @date : 2023.05.15
|
* @date : 2023.05.15
|
||||||
@ -1,10 +1,10 @@
|
|||||||
package com.itn.mjonApi.mjon.api.send.mapper;
|
package com.itn.mjonApi.mjon.api.msg.send.mapper;
|
||||||
|
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.MsgRequestVO;
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.MsgRequestVO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* packageName : com.itn.mjonApi.mjon.api.send.mapper.domain
|
* packageName : com.itn.mjonApi.mjon.api.msg.send.mapper.domain
|
||||||
* fileName : SendMapper
|
* fileName : SendMapper
|
||||||
* author : hylee
|
* author : hylee
|
||||||
* date : 2023-05-19
|
* date : 2023-05-19
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.msg.send.mapper.domain;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
public class MjonMsgSendVO{
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : 수신자번호
|
||||||
|
*/
|
||||||
|
private String phone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : [*이름*] - 치환문자
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : [*1*] - 치환문자
|
||||||
|
*/
|
||||||
|
private String rep1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : [*2*] - 치환문자
|
||||||
|
*/
|
||||||
|
private String rep2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : [*3*] - 치환문자
|
||||||
|
*/
|
||||||
|
private String rep3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description : [*4*] - 치환문자
|
||||||
|
*/
|
||||||
|
private String rep4;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.msg.send.mapper.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* packageName : com.itn.mjonApi.cmn.msg
|
||||||
|
* fileName : mjonResponse
|
||||||
|
* author : hylee
|
||||||
|
* date : 2023-05-12
|
||||||
|
* description : 문자온 프로젝트에서 받은 리턴값
|
||||||
|
* ===========================================================
|
||||||
|
* DATE AUTHOR NOTE
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* 2023-05-12 hylee 최초 생성
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true) // JSON에 있지만 VO에 없는 필드를 무시하고 무사히 역직렬화해 줌
|
||||||
|
@ToString
|
||||||
|
public class MjonResponseVO {
|
||||||
|
|
||||||
|
private String result;
|
||||||
|
private String message;
|
||||||
|
private String resultSts; // 전송결과 갯수
|
||||||
|
private String resultBlockSts; // 수신거부 갯수
|
||||||
|
private String msgGroupId;
|
||||||
|
private String afterCash;
|
||||||
|
private String msgType;
|
||||||
|
private String statCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param apiReturnNode
|
||||||
|
* @return ResponseEntity vo convert
|
||||||
|
* @throws JsonProcessingException
|
||||||
|
*/
|
||||||
|
public static MjonResponseVO getMjonResponse(JsonNode apiReturnNode) throws JsonProcessingException {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
return objectMapper.treeToValue(apiReturnNode, MjonResponseVO.class);
|
||||||
|
}
|
||||||
|
// public static MjonResponseVO getMjonResponse(ResponseEntity<String> stringResponseEntity) throws JsonProcessingException {
|
||||||
|
// ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
// return objectMapper.readValue(stringResponseEntity.getBody(), MjonResponseVO.class);
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,11 +1,12 @@
|
|||||||
package com.itn.mjonApi.mjon.api.send.mapper.domain;
|
package com.itn.mjonApi.mjon.api.msg.send.mapper.domain;
|
||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* packageName : com.itn.mjonApi.mjon.api.send.mapper.domain
|
* packageName : com.itn.mjonApi.mjon.api.msg.send.mapper.domain
|
||||||
* fileName : MjonMsgVO
|
* fileName : MjonMsgVO
|
||||||
* author : hylee
|
* author : hylee
|
||||||
* date : 2023-05-09
|
* date : 2023-05-09
|
||||||
@ -18,6 +19,7 @@ import java.io.Serializable;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Builder
|
@Builder
|
||||||
|
@ToString
|
||||||
public class MsgRequestVO implements Serializable {
|
public class MsgRequestVO implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,6 +35,8 @@ public class MsgRequestVO implements Serializable {
|
|||||||
|
|
||||||
private String smsTxt; // value = "SMS용 메시지본문", example = "문자 메세지 본문"
|
private String smsTxt; // value = "SMS용 메시지본문", example = "문자 메세지 본문"
|
||||||
|
|
||||||
|
private String smsTxtArea;//문자 작성 화면 본문 내용
|
||||||
|
|
||||||
private String[] callToList; // value = "수신번호리스트", dataType = "[Ljava.lang.String;", example = "01011112222,01022223333"
|
private String[] callToList; // value = "수신번호리스트", dataType = "[Ljava.lang.String;", example = "01011112222,01022223333"
|
||||||
|
|
||||||
private String callFrom; // value = "발신번호 :: 정책이 필요함", example = "01011112222"
|
private String callFrom; // value = "발신번호 :: 정책이 필요함", example = "01011112222"
|
||||||
@ -98,6 +102,10 @@ public class MsgRequestVO implements Serializable {
|
|||||||
|
|
||||||
private String test_yn; // 테스트 여부
|
private String test_yn; // 테스트 여부
|
||||||
|
|
||||||
|
private String sendKind; // 문자종류
|
||||||
|
|
||||||
|
|
||||||
|
List<MjonMsgSendVO> mjonMsgSendVOList;
|
||||||
|
|
||||||
// private String msgId ;// '문자ID',
|
// private String msgId ;// '문자ID',
|
||||||
// private String userId ; // '문자온 일반회원ID',
|
// private String userId ; // '문자온 일반회원ID',
|
||||||
@ -113,7 +121,6 @@ public class MsgRequestVO implements Serializable {
|
|||||||
// private String rsltCode2; // '결과처리 상세코드',
|
// private String rsltCode2; // '결과처리 상세코드',
|
||||||
// private String rsltNet; // '결과처리 통신사',
|
// private String rsltNet; // '결과처리 통신사',
|
||||||
// private String subject; // 'MMS용 메시지제목',
|
// private String subject; // 'MMS용 메시지제목',
|
||||||
// private String smsTxtArea;//문자 작성 화면 본문 내용
|
|
||||||
// private String msgPayCode; // '재전송 기능에 의한 최종전송콘텐트 종류 저장',
|
// private String msgPayCode; // '재전송 기능에 의한 최종전송콘텐트 종류 저장',
|
||||||
// private String contSeq; // COMMENT 'MMS의 콘텐츠 Key(MMS_CONTENTS_INFO의 CONT_SEQ)',
|
// private String contSeq; // COMMENT 'MMS의 콘텐츠 Key(MMS_CONTENTS_INFO의 CONT_SEQ)',
|
||||||
// private String msgTypeResend; // '재전송할 문자 타입. 값이 있으면 재전송. 없으면 단 건 전송',
|
// private String msgTypeResend; // '재전송할 문자 타입. 값이 있으면 재전송. 없으면 단 건 전송',
|
||||||
@ -228,6 +235,14 @@ public class MsgRequestVO implements Serializable {
|
|||||||
this.smsTxt = smsTxt;
|
this.smsTxt = smsTxt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSmsTxtArea() {
|
||||||
|
return smsTxtArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSmsTxtArea(String smsTxtArea) {
|
||||||
|
this.smsTxtArea = smsTxtArea;
|
||||||
|
}
|
||||||
|
|
||||||
public String[] getCallToList() {
|
public String[] getCallToList() {
|
||||||
return callToList;
|
return callToList;
|
||||||
}
|
}
|
||||||
@ -475,4 +490,20 @@ public class MsgRequestVO implements Serializable {
|
|||||||
public void setTest_yn(String test_yn) {
|
public void setTest_yn(String test_yn) {
|
||||||
this.test_yn = test_yn;
|
this.test_yn = test_yn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSendKind() {
|
||||||
|
return sendKind;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSendKind(String sendKind) {
|
||||||
|
this.sendKind = sendKind;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<MjonMsgSendVO> getMjonMsgSendVOList() {
|
||||||
|
return mjonMsgSendVOList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMjonMsgSendVOList(List<MjonMsgSendVO> mjonMsgSendVOList) {
|
||||||
|
this.mjonMsgSendVOList = mjonMsgSendVOList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,106 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.msg.send.mapper.domain;
|
||||||
|
|
||||||
|
import com.itn.mjonApi.cmn.domain.SendRequestCmnVO;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* packageName : com.itn.mjonApi.mjon.api.msg.send.mapper.domain
|
||||||
|
* fileName : MjonMsgVO
|
||||||
|
* author : hylee
|
||||||
|
* date : 2023-05-23
|
||||||
|
* description : 문자 발송에 필요한 값들을 받는 vo
|
||||||
|
* 1건~500건 대량 문자 개인별로 발송
|
||||||
|
* ===========================================================
|
||||||
|
* DATE AUTHOR NOTE
|
||||||
|
* -----------------------------------------------------------
|
||||||
|
* 2023-05-09 hylee 최초 생성
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MsgsRequestVO extends SendRequestCmnVO implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 값이 있는 경우
|
||||||
|
* 문자온 프로젝트에서 처리해줌
|
||||||
|
* null이면 에러
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String mberId; // 사용자 ID
|
||||||
|
|
||||||
|
private String accessKey; // Api Key
|
||||||
|
|
||||||
|
private String smsTxt; // SMS용 메시지본문
|
||||||
|
|
||||||
|
private String[] callToList; // 수신번호리스트
|
||||||
|
|
||||||
|
private String callFrom; // 발신번호 :: 정책이 필요함
|
||||||
|
|
||||||
|
private String eachPrice = "0"; // 전송문자 개별가격
|
||||||
|
private String sPrice = "0"; // 임시
|
||||||
|
|
||||||
|
private String totPrice = "0"; // 전송문자 토탈가격
|
||||||
|
|
||||||
|
private String fileCnt = "0"; // 첨부파일 갯수
|
||||||
|
|
||||||
|
private String msgType = "4"; // 메시지의 (4: SMS 전송, 5: URL 전송, 6: MMS전송, 7: BARCODE전송, 8: 카카오 알림톡 전송)
|
||||||
|
|
||||||
|
// ==== 단가 ====
|
||||||
|
private float smsPrice = 0; // sms 단가 null 이면 에러
|
||||||
|
|
||||||
|
private float mmsPrice = 0; // mms 단가 null 이면 에러
|
||||||
|
// private float kakaoAtPrice; // 카카오 알림톡 단가
|
||||||
|
// private float kakaoFtPrice; // 카카오 친구톡 단가
|
||||||
|
// private float kakaoFtImgPrice;// 카카오 이미지 단가
|
||||||
|
// private float kakaoFtWideImgPrice; // 카카오 와이드 이미지 단가
|
||||||
|
|
||||||
|
private String[] imgFilePath = new String[0]; // 그림 이미지 경로
|
||||||
|
|
||||||
|
|
||||||
|
private String spamStatus; // 스팸문자 유무 (Y/N) - 서비스단에서 처리 함
|
||||||
|
|
||||||
|
private String txtReplYn = "N"; // 변환문자 유무 (Y/N) - 서비스단에서 처리 함
|
||||||
|
|
||||||
|
// private String nameStr; // value = "치환 이름 리스트 |로 구분", example = "홍길동1|홍길동2|홍길동3"
|
||||||
|
|
||||||
|
// private String rep1Str; // value = "치환 문자1 리스트 |로 구분", example = ""
|
||||||
|
|
||||||
|
// private String rep2Str; // value = "치환 문자2 리스트 |로 구분", example = ""
|
||||||
|
|
||||||
|
// private String rep3Str; // value = "치환 문자3 리스트 |로 구분", example = ""
|
||||||
|
|
||||||
|
// private String rep4Str; // value = "치환 문자4 리스트 |로 구분", example = ""
|
||||||
|
|
||||||
|
// private String[] nameList= new String[0]; // value = "nameStr 을 |로 split 후 담는 변수", example = ""
|
||||||
|
|
||||||
|
// private String[] rep1List= new String[0]; // value = "rep1Str 을 |로 split 후 담는 변수", example = ""
|
||||||
|
|
||||||
|
// private String[] rep2List= new String[0]; // value = "rep2Str 을 |로 split 후 담는 변수", example = ""
|
||||||
|
|
||||||
|
// private String[] rep3List= new String[0]; // value = "rep3Str 을 |로 split 후 담는 변수", example = ""
|
||||||
|
|
||||||
|
// private String[] rep4List= new String[0]; // value = "rep4Str 을 |로 split 후 담는 변수", example = ""
|
||||||
|
|
||||||
|
private String reserveYn = "N"; // value = "예약 유무 (Y/N)", example = "N"
|
||||||
|
|
||||||
|
// 치환 있을 경우 사용
|
||||||
|
// private String shortMsgCnt; // value = "치환 후 단문 건수", example = ""
|
||||||
|
|
||||||
|
// private String longMsgCnt; // value = "치환 후 장문 건수", example = ""
|
||||||
|
|
||||||
|
|
||||||
|
// @ApiModelProperty(value = "문자 종류 일반:N, 광고:A, 선거:C", example = "N", hidden = true)
|
||||||
|
private String msgKind = "N"; // '문자 종류 일반:N, 광고:A, 선거:C',
|
||||||
|
|
||||||
|
private String test_yn; // 테스트 여부
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.itn.mjonApi.mjon.api.send.mapper.domain;
|
package com.itn.mjonApi.mjon.api.msg.send.mapper.domain;
|
||||||
|
|
||||||
import com.itn.mjonApi.cmn.msg.StatMsg;
|
import com.itn.mjonApi.cmn.msg.StatMsg;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
@ -67,13 +67,31 @@ public class SendSucRestResponse {
|
|||||||
private static List<String> getMsgType(String msgType) {
|
private static List<String> getMsgType(String msgType) {
|
||||||
List<String> result = new ArrayList<>();
|
List<String> result = new ArrayList<>();
|
||||||
|
|
||||||
|
// msgType이 null이거나 빈 문자열인 경우 빈 리스트 반환
|
||||||
|
if (msgType == null || msgType.trim().isEmpty()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if(msgType.indexOf(",") > 0)
|
if(msgType.indexOf(",") > 0)
|
||||||
{
|
{
|
||||||
result = Arrays.stream(msgType.split(","))
|
result = Arrays.stream(msgType.split(","))
|
||||||
.map(s -> StatMsg.valueOf("msgType"+s).getMsg())
|
.filter(s -> s != null && !s.trim().isEmpty()) // 빈 문자열 필터링
|
||||||
|
.map(s -> {
|
||||||
|
try {
|
||||||
|
return StatMsg.valueOf("msgType" + s.trim()).getMsg();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
log.warn("Unknown msgType: {}, skipping", s.trim());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(s -> s != null) // null 값 제거
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}else{
|
}else{
|
||||||
result.add(StatMsg.valueOf("msgType"+ msgType).getMsg());
|
try {
|
||||||
|
result.add(StatMsg.valueOf("msgType" + msgType.trim()).getMsg());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
log.warn("Unknown msgType: {}, returning empty list", msgType.trim());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -85,31 +103,41 @@ public class SendSucRestResponse {
|
|||||||
*/
|
*/
|
||||||
public static SendSucRestResponse SendSuccessMsgsRestResponse(List<MjonResponseVO> mjonResponseVOList) {
|
public static SendSucRestResponse SendSuccessMsgsRestResponse(List<MjonResponseVO> mjonResponseVOList) {
|
||||||
|
|
||||||
|
mjonResponseVOList.forEach(t->log.info(t.toString()));
|
||||||
|
|
||||||
// 실패 카운트
|
// 실패 카운트
|
||||||
int failCnt = (int) mjonResponseVOList.stream()
|
int failCnt = (int) mjonResponseVOList.stream()
|
||||||
.filter(s->"fail".equals(s.getResult()))
|
.filter(s->!"OK".equals(s.getResult()))
|
||||||
.count();
|
.count();
|
||||||
// 성공 카운트
|
// 성공 카운트
|
||||||
int successCnt = mjonResponseVOList.parallelStream()
|
int successCnt = (int) mjonResponseVOList.parallelStream()
|
||||||
.filter(s->!"fail".equals(s.getResult()))
|
.filter(s->"OK".equals(s.getResult()))
|
||||||
.mapToInt(s -> Integer.parseInt(s.getResultSts()))
|
.count();
|
||||||
.sum();
|
|
||||||
// 수신거부 카운트
|
// 수신거부 카운트
|
||||||
int blockCnt = mjonResponseVOList.parallelStream()
|
// int blockCnt = mjonResponseVOList.parallelStream()
|
||||||
.filter(s->!"fail".equals(s.getResult()))
|
// .filter(s->!"OK".equals(s.getResult()))
|
||||||
.mapToInt(s -> Integer.parseInt(s.getResultBlockSts()))
|
// .mapToInt(s -> Integer.parseInt(s.getResultBlockSts()))
|
||||||
.sum();
|
// .sum();
|
||||||
|
|
||||||
// 성공한 메세지 그룹 아이디
|
// 성공한 메세지 그룹 아이디
|
||||||
List<String> msgGroupIdList = mjonResponseVOList.stream()
|
List<String> msgGroupIdList = mjonResponseVOList.stream()
|
||||||
.filter(s->!"fail".equals(s.getResult()))
|
.filter(s->"OK".equals(s.getResult()))
|
||||||
.map(s -> s.getMsgGroupId())
|
.map(s -> s.getMsgGroupId())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// 성공한 메세지 그룹 아이디
|
// 메세지 타입
|
||||||
List<String> msgTypeList = mjonResponseVOList.stream()
|
List<String> msgTypeList = mjonResponseVOList.stream()
|
||||||
.map(s -> StatMsg.valueOf("msgType"+s.getMsgType()).getMsg())
|
.filter(s -> s.getMsgType() != null && !s.getMsgType().trim().isEmpty())
|
||||||
.collect(Collectors.toList());
|
.map(s -> {
|
||||||
|
try {
|
||||||
|
return StatMsg.valueOf("msgType" + s.getMsgType().trim()).getMsg();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
log.warn("Unknown msgType in list: {}, skipping", s.getMsgType().trim());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(s -> s != null)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -118,8 +146,8 @@ public class SendSucRestResponse {
|
|||||||
.resultCode(StatMsg.valueOf("STAT_0").getCode()) // 성공 코드 0 - StatMsg 참고
|
.resultCode(StatMsg.valueOf("STAT_0").getCode()) // 성공 코드 0 - StatMsg 참고
|
||||||
.msgGroupIdList(msgGroupIdList) // 전송 메세지 그룹 ID
|
.msgGroupIdList(msgGroupIdList) // 전송 메세지 그룹 ID
|
||||||
.successCnt(Integer.toString(successCnt)) // 성공 건수
|
.successCnt(Integer.toString(successCnt)) // 성공 건수
|
||||||
.blockCnt(Integer.toString(blockCnt)) // 수신거부 건수
|
// .blockCnt(Integer.toString(blockCnt)) // 수신거부 건수
|
||||||
.failCnt(Integer.toString(failCnt)) // 수신거부 건수
|
.failCnt(Integer.toString(failCnt)) // 실패 건수
|
||||||
.msgTypeList(msgTypeList) // msgType List
|
.msgTypeList(msgTypeList) // msgType List
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.msg.send.service;
|
||||||
|
|
||||||
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.MsgRequestVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.MsgsRequestVO;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface SendService {
|
||||||
|
|
||||||
|
|
||||||
|
// RestResponse sendMsgData(MsgRequestVO msgRequestVO) throws Exception;
|
||||||
|
|
||||||
|
RestResponse sendMsgData_advc(MsgRequestVO msgRequestVO) throws Exception;
|
||||||
|
|
||||||
|
// RestResponse sendMsgsData(MsgsRequestVO msgsRequestVO) throws Exception;
|
||||||
|
|
||||||
|
RestResponse sendMsgsData_advc(MsgsRequestVO msgsRequestVO) throws Exception;
|
||||||
|
|
||||||
|
RestResponse sendMsgsData_advc(MsgsRequestVO msgsRequestVO, Map<String, String> allParams) throws Exception;
|
||||||
|
}
|
||||||
@ -0,0 +1,367 @@
|
|||||||
|
package com.itn.mjonApi.mjon.api.msg.send.service.impl;
|
||||||
|
|
||||||
|
import com.itn.mjonApi.cmn.apiServer.ApiService;
|
||||||
|
import com.itn.mjonApi.cmn.msg.FailRestResponse;
|
||||||
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.inqry.mapper.PriceMapper;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.SendMapper;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.*;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.send.service.SendService;
|
||||||
|
import com.itn.mjonApi.util.MunjaUtil;
|
||||||
|
import com.itn.mjonApi.util.TestDataUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class SendServiceImpl implements SendService {
|
||||||
|
|
||||||
|
private ApiService apiService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
SendMapper sendMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
PriceMapper priceMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public SendServiceImpl(ApiService apiService) {
|
||||||
|
this.apiService = apiService;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String replaseStrList = "[*이름*],[*1*],[*2*],[*3*],[*4*]";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RestResponse sendMsgData_advc(MsgRequestVO msgRequestVO) throws Exception {
|
||||||
|
log.info(" :: sendMsgData_advc ::");
|
||||||
|
|
||||||
|
msgRequestVO.setSendKind("A");
|
||||||
|
|
||||||
|
if(StringUtils.isNotEmpty(msgRequestVO.getTest_yn())){
|
||||||
|
// YF => 실패 테스트 데이터
|
||||||
|
return TestDataUtil._getTestMsgReturnData(msgRequestVO.getTest_yn());
|
||||||
|
}
|
||||||
|
|
||||||
|
// step2.수신자 전화번호 정상 여부 체크(정상 번호에 대해서만 발송 가능)
|
||||||
|
// 1020
|
||||||
|
// 폰번호 확인 - 빈 값 -> 유효성 정규식
|
||||||
|
if(MunjaUtil.getCallToListChk(msgRequestVO.getCallToList())){
|
||||||
|
return new RestResponse(new FailRestResponse("STAT_1020",""));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 치환 데이터 및 수신자 번호 VO 생성
|
||||||
|
msgRequestVO.setMjonMsgSendVOList(this.buildMsgSendVOList(msgRequestVO));
|
||||||
|
|
||||||
|
// sms 변수 변경
|
||||||
|
msgRequestVO.setSmsTxtArea(msgRequestVO.getSmsTxt());
|
||||||
|
|
||||||
|
|
||||||
|
MjonResponseVO munjaSendResponse = apiService.postForEntity(
|
||||||
|
"/web/mjon/msgdata/sendMsgDataAjax_advc.do"
|
||||||
|
, msgRequestVO
|
||||||
|
, String.class
|
||||||
|
);
|
||||||
|
|
||||||
|
// convertMjonDataToApiResponse => MjonResponseVO 데이터를 ApiResponse 데이터로 변환하는 메소드
|
||||||
|
log.info(" + munjaSendResponse :: [{}]", munjaSendResponse.toString());
|
||||||
|
if("OK".equals(munjaSendResponse.getResult())){ // 성공
|
||||||
|
return new RestResponse(SendSucRestResponse.convertMjonDataToApiResponse(munjaSendResponse));
|
||||||
|
}else{ // 실패
|
||||||
|
return new RestResponse(new FailRestResponse(munjaSendResponse.getStatCode(),""));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MsgRequestVO 내 nameStr, rep1Str~rep4Str, callToList 를 기반으로
|
||||||
|
* 각 항목을 MjonMsgSendVO 리스트로 매핑한다.
|
||||||
|
*
|
||||||
|
* @param msgRequestVO 메시지 요청 VO
|
||||||
|
* @return 수신자별 메시지 전송 VO 리스트
|
||||||
|
*/
|
||||||
|
public List<MjonMsgSendVO> buildMsgSendVOList(MsgRequestVO msgRequestVO) {
|
||||||
|
|
||||||
|
// 수신자 이름 및 치환 문자들 파싱 (null-safe 처리)
|
||||||
|
String[] nameArr = Optional.ofNullable(msgRequestVO.getNameStr()).orElse("").split("\\|");
|
||||||
|
String[] rep1Arr = Optional.ofNullable(msgRequestVO.getRep1Str()).orElse("").split("\\|");
|
||||||
|
String[] rep2Arr = Optional.ofNullable(msgRequestVO.getRep2Str()).orElse("").split("\\|");
|
||||||
|
String[] rep3Arr = Optional.ofNullable(msgRequestVO.getRep3Str()).orElse("").split("\\|");
|
||||||
|
String[] rep4Arr = Optional.ofNullable(msgRequestVO.getRep4Str()).orElse("").split("\\|");
|
||||||
|
|
||||||
|
// 콤마(,) 기준으로 수신 번호 문자열을 파싱
|
||||||
|
String[] phoneArr = Optional.ofNullable(msgRequestVO.getCallToList())
|
||||||
|
.orElse(new String[0]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
List<MjonMsgSendVO> mjonMsgSendVOList = new ArrayList<>();
|
||||||
|
|
||||||
|
// 수신 번호 개수만큼 반복
|
||||||
|
for (int i = 0; i < phoneArr.length; i++) {
|
||||||
|
MjonMsgSendVO vo = new MjonMsgSendVO();
|
||||||
|
|
||||||
|
// 1. 수신 번호 세팅
|
||||||
|
vo.setPhone(phoneArr[i].trim());
|
||||||
|
|
||||||
|
// 2. 이름/치환문자 세팅
|
||||||
|
if (i < nameArr.length) vo.setName(nameArr[i].trim());
|
||||||
|
if (i < rep1Arr.length) vo.setRep1(rep1Arr[i].trim());
|
||||||
|
if (i < rep2Arr.length) vo.setRep2(rep2Arr[i].trim());
|
||||||
|
if (i < rep3Arr.length) vo.setRep3(rep3Arr[i].trim());
|
||||||
|
if (i < rep4Arr.length) vo.setRep4(rep4Arr[i].trim());
|
||||||
|
|
||||||
|
mjonMsgSendVOList.add(vo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mjonMsgSendVOList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RestResponse sendMsgsData_advc(MsgsRequestVO msgsRequestVO) throws Exception {
|
||||||
|
|
||||||
|
|
||||||
|
log.info(" :: sendMsgData_advc ::");
|
||||||
|
|
||||||
|
|
||||||
|
if(StringUtils.isNotEmpty(msgsRequestVO.getTest_yn())){
|
||||||
|
return TestDataUtil._getTestMsgsReturnData(msgsRequestVO.getTest_yn());
|
||||||
|
}
|
||||||
|
|
||||||
|
// msgsVO -> msgVO List로 변환
|
||||||
|
List<MsgRequestVO> msgRequestVOList = this.getDataCleaning_advc(msgsRequestVO);
|
||||||
|
msgRequestVOList.forEach(t->log.info(" + t.toString() :: [{}]", t.toString()));
|
||||||
|
|
||||||
|
log.info("msgRequestVOList :: [{}]", msgRequestVOList.size());
|
||||||
|
|
||||||
|
|
||||||
|
List<MjonResponseVO> mjonResponseVOList = new ArrayList<MjonResponseVO>();
|
||||||
|
for(MsgRequestVO aa : msgRequestVOList){
|
||||||
|
|
||||||
|
aa.setSmsTxtArea(aa.getSmsTxt());
|
||||||
|
aa.setSendKind("A");
|
||||||
|
|
||||||
|
MjonResponseVO munjaSendResponse = apiService.postForEntity(
|
||||||
|
"/web/mjon/msgdata/sendMsgDataAjax_advc.do"
|
||||||
|
, aa
|
||||||
|
, String.class
|
||||||
|
);
|
||||||
|
|
||||||
|
log.info("munjaSendResponse :: [{}]", munjaSendResponse.toString());
|
||||||
|
mjonResponseVOList.add(munjaSendResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return new RestResponse(SendSucRestResponse.SendSuccessMsgsRestResponse(mjonResponseVOList));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RestResponse sendMsgsData_advc(MsgsRequestVO msgsRequestVO, Map<String, String> allParams) throws Exception {
|
||||||
|
|
||||||
|
|
||||||
|
log.info(" :: sendMsgData_advc with Map params ::");
|
||||||
|
|
||||||
|
|
||||||
|
if(StringUtils.isNotEmpty(msgsRequestVO.getTest_yn())){
|
||||||
|
return TestDataUtil._getTestMsgsReturnData(msgsRequestVO.getTest_yn());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map 기반 동적 파라미터 처리
|
||||||
|
List<MsgRequestVO> msgRequestVOList = this.getDataCleaning_advc_withMap(msgsRequestVO, allParams);
|
||||||
|
|
||||||
|
log.info("msgRequestVOList :: [{}]", msgRequestVOList.size());
|
||||||
|
|
||||||
|
|
||||||
|
List<MjonResponseVO> mjonResponseVOList = new ArrayList<MjonResponseVO>();
|
||||||
|
for(MsgRequestVO aa : msgRequestVOList){
|
||||||
|
|
||||||
|
aa.setSmsTxtArea(aa.getSmsTxt());
|
||||||
|
aa.setSendKind("A");
|
||||||
|
|
||||||
|
MjonResponseVO munjaSendResponse = apiService.postForEntity(
|
||||||
|
"/web/mjon/msgdata/sendMsgDataAjax_advc.do"
|
||||||
|
, aa
|
||||||
|
, String.class
|
||||||
|
);
|
||||||
|
|
||||||
|
log.info("munjaSendResponse :: [{}]", munjaSendResponse.toString());
|
||||||
|
mjonResponseVOList.add(munjaSendResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return new RestResponse(SendSucRestResponse.SendSuccessMsgsRestResponse(mjonResponseVOList));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RestResponse callToErrorReturnData(MsgRequestVO msgRequestVO) {
|
||||||
|
|
||||||
|
FailRestResponse stat1020 = new FailRestResponse("STAT_1020","");
|
||||||
|
String errorMsg = stat1020.getMsg();
|
||||||
|
errorMsg.replace("수신자", "수신자(" + msgRequestVO.getCallToList()[0] + ")");
|
||||||
|
stat1020.setMsg(errorMsg);
|
||||||
|
|
||||||
|
return new RestResponse(stat1020);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static List<MsgRequestVO> getDataCleaning_advc(MsgsRequestVO msgsRequestVO) {
|
||||||
|
|
||||||
|
|
||||||
|
List<MsgRequestVO> msgRequestVOList = new ArrayList<>();
|
||||||
|
|
||||||
|
// Reflection으로 Object Field에 접근한다.
|
||||||
|
Field[] declaredFields = msgsRequestVO.getClass().getDeclaredFields();
|
||||||
|
|
||||||
|
String mberId = msgsRequestVO.getMberId(); // 사용자 ID
|
||||||
|
String accessKey = msgsRequestVO.getAccessKey(); // accessKey
|
||||||
|
String callFrom = msgsRequestVO.getCallFrom(); // 발신자 번호
|
||||||
|
String callTo = null; // 수신자 번호
|
||||||
|
|
||||||
|
List<MjonMsgSendVO> mjonMsgSendVOList = new ArrayList<>();
|
||||||
|
for (Field field : declaredFields) {
|
||||||
|
|
||||||
|
Object value = null;
|
||||||
|
// private Field일 경우 접근을 허용한다.
|
||||||
|
field.setAccessible(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Field Value를 참조한다.
|
||||||
|
value = field.get(msgsRequestVO);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
log.info("Reflection Error. {}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// nullPointException 방지
|
||||||
|
if(value != null)
|
||||||
|
{
|
||||||
|
log.info("field.getName() : [{}]", field.getName());
|
||||||
|
log.info("value.toString() : [{}]", value.toString());
|
||||||
|
/**
|
||||||
|
* 필드 이름으로 분기하여
|
||||||
|
* 각각에 맞는 위치에 값을 넣어준다.
|
||||||
|
*/
|
||||||
|
if(field.getName().startsWith("callTo")){ // 수신자 번호
|
||||||
|
callTo = value.toString();
|
||||||
|
}else if(field.getName().startsWith("smsTxt")){ // 문자 내용
|
||||||
|
|
||||||
|
// 값이 비여 있으면 다음 반복문으로 넘어간다.
|
||||||
|
if(StringUtils.isEmpty(value.toString())){
|
||||||
|
callTo = "";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MjonMsgSendVO vo = new MjonMsgSendVO();
|
||||||
|
vo.setPhone(callTo);
|
||||||
|
mjonMsgSendVOList.add(vo);
|
||||||
|
|
||||||
|
msgRequestVOList.add(
|
||||||
|
MsgRequestVO.builder()
|
||||||
|
.mberId(mberId)
|
||||||
|
.accessKey(accessKey)
|
||||||
|
.callFrom(callFrom)
|
||||||
|
.smsTxt(value.toString())
|
||||||
|
.mjonMsgSendVOList(mjonMsgSendVOList)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
// 초기화
|
||||||
|
callTo = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return msgRequestVOList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map 기반 동적 파라미터 처리를 위한 새로운 메소드
|
||||||
|
* callTo_1, smsTxt_1, callTo_2, smsTxt_2 등의 동적 파라미터를 처리
|
||||||
|
*/
|
||||||
|
private List<MsgRequestVO> getDataCleaning_advc_withMap(MsgsRequestVO msgsRequestVO, Map<String, String> allParams) {
|
||||||
|
|
||||||
|
List<MsgRequestVO> msgRequestVOList = new ArrayList<>();
|
||||||
|
|
||||||
|
String mberId = msgsRequestVO.getMberId();
|
||||||
|
String accessKey = msgsRequestVO.getAccessKey();
|
||||||
|
String callFrom = msgsRequestVO.getCallFrom();
|
||||||
|
|
||||||
|
// 동적 파라미터를 순서대로 처리하기 위해 인덱스 기반으로 처리
|
||||||
|
Map<Integer, String> callToMap = new HashMap<>();
|
||||||
|
Map<Integer, String> smsTxtMap = new HashMap<>();
|
||||||
|
|
||||||
|
// 파라미터를 분석하여 인덱스별로 분류
|
||||||
|
for (Map.Entry<String, String> entry : allParams.entrySet()) {
|
||||||
|
String paramName = entry.getKey();
|
||||||
|
String paramValue = entry.getValue();
|
||||||
|
|
||||||
|
log.info("Processing param: [{}] = [{}]", paramName, paramValue);
|
||||||
|
|
||||||
|
if (paramName.startsWith("callTo_")) {
|
||||||
|
try {
|
||||||
|
int index = Integer.parseInt(paramName.substring(7)); // "callTo_" 이후 숫자
|
||||||
|
callToMap.put(index, paramValue);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.warn("Invalid callTo parameter format: [{}]", paramName);
|
||||||
|
}
|
||||||
|
} else if (paramName.startsWith("smsTxt_")) {
|
||||||
|
try {
|
||||||
|
int index = Integer.parseInt(paramName.substring(7)); // "smsTxt_" 이후 숫자
|
||||||
|
if (StringUtils.isNotEmpty(paramValue)) {
|
||||||
|
smsTxtMap.put(index, paramValue);
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.warn("Invalid smsTxt parameter format: [{}]", paramName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 인덱스별로 메시지 요청 VO 생성
|
||||||
|
for (Integer index : smsTxtMap.keySet()) {
|
||||||
|
String callTo = callToMap.get(index);
|
||||||
|
String smsTxt = smsTxtMap.get(index);
|
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(callTo) && StringUtils.isNotEmpty(smsTxt)) {
|
||||||
|
List<MjonMsgSendVO> mjonMsgSendVOList = new ArrayList<>();
|
||||||
|
MjonMsgSendVO vo = new MjonMsgSendVO();
|
||||||
|
vo.setPhone(callTo);
|
||||||
|
mjonMsgSendVOList.add(vo);
|
||||||
|
|
||||||
|
msgRequestVOList.add(
|
||||||
|
MsgRequestVO.builder()
|
||||||
|
.mberId(mberId)
|
||||||
|
.accessKey(accessKey)
|
||||||
|
.callFrom(callFrom)
|
||||||
|
.smsTxt(smsTxt)
|
||||||
|
.reserveYn("N")
|
||||||
|
.mjonMsgSendVOList(mjonMsgSendVOList)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
|
||||||
|
log.info("Created MsgRequestVO for index [{}]: callTo=[{}], smsTxt=[{}]",
|
||||||
|
index, callTo, smsTxt);
|
||||||
|
}
|
||||||
|
// else {
|
||||||
|
// log.warn("Skipping index [{}]: callTo=[{}], smsTxt=[{}]", index, callTo, smsTxt);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
msgRequestVOList.forEach(t->log.info("+ t.getReserveYn() :: [{}]", t.getReserveYn()));
|
||||||
|
|
||||||
|
return msgRequestVOList;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,16 +1,18 @@
|
|||||||
package com.itn.mjonApi.mjon.api.send.web;
|
package com.itn.mjonApi.mjon.api.msg.send.web;
|
||||||
|
|
||||||
import com.itn.mjonApi.cmn.msg.RestResponse;
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.MsgRequestVO;
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.MsgRequestVO;
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.MsgsRequestVO;
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.MsgsRequestVO;
|
||||||
import com.itn.mjonApi.mjon.api.send.service.SendService;
|
import com.itn.mjonApi.mjon.api.msg.send.service.SendService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* packageName : com.itn.mjonApi.mjon.send.web
|
* packageName : com.itn.mjonApi.mjon.send.web
|
||||||
@ -24,18 +26,11 @@ import org.springframework.web.client.RestTemplate;
|
|||||||
* 2023-02-15 hylee 최초 생성
|
* 2023-02-15 hylee 최초 생성
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// 치환문자가 있으면 , => §로 치환
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
public class SendRestController {
|
public class SendRestController {
|
||||||
|
|
||||||
private final RestTemplate restTemplate;
|
|
||||||
|
|
||||||
public SendRestController(RestTemplate restTemplate) {
|
|
||||||
this.restTemplate = restTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SendService sendService;
|
private SendService sendService;
|
||||||
|
|
||||||
@ -49,20 +44,24 @@ public class SendRestController {
|
|||||||
@CrossOrigin("*") // 모든 요청에 접근 허용
|
@CrossOrigin("*") // 모든 요청에 접근 허용
|
||||||
@PostMapping("/api/send/sendMsg")
|
@PostMapping("/api/send/sendMsg")
|
||||||
public ResponseEntity<RestResponse> sendMsg(MsgRequestVO msgRequestVO) throws Exception {
|
public ResponseEntity<RestResponse> sendMsg(MsgRequestVO msgRequestVO) throws Exception {
|
||||||
return ResponseEntity.ok().body(sendService.sendMsgData(msgRequestVO));
|
return ResponseEntity.ok().body(sendService.sendMsgData_advc(msgRequestVO));
|
||||||
|
// return ResponseEntity.ok().body(sendService.sendMsgData(msgRequestVO));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param msgsRequestVO
|
* @param msgsRequestVO
|
||||||
* @description [문자 발송] 다른 내용으로 여려명에게 보냄
|
* @param allParams
|
||||||
|
* @description [문자 발송] 다른 내용으로 여려명에게 보냄 - Map 기반 동적 파라미터 처리
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@CrossOrigin("*") // 모든 요청에 접근 허용
|
@CrossOrigin("*") // 모든 요청에 접근 허용
|
||||||
@PostMapping("/api/send/sendMsgs")
|
@PostMapping("/api/send/sendMsgs")
|
||||||
public ResponseEntity<RestResponse> sendMsgs(MsgsRequestVO msgsRequestVO) throws Exception {
|
public ResponseEntity<RestResponse> sendMsgs(MsgsRequestVO msgsRequestVO,
|
||||||
return ResponseEntity.ok().body(sendService.sendMsgsData(msgsRequestVO));
|
@RequestParam Map<String, String> allParams) throws Exception {
|
||||||
|
return ResponseEntity.ok().body(sendService.sendMsgsData_advc(msgsRequestVO, allParams));
|
||||||
|
// return ResponseEntity.ok().body(sendService.sendMsgsData(msgsRequestVO));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package com.itn.mjonApi.mjon.api.send.service;
|
|
||||||
|
|
||||||
import com.itn.mjonApi.cmn.msg.RestResponse;
|
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.MsgRequestVO;
|
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.MsgsRequestVO;
|
|
||||||
|
|
||||||
public interface SendService {
|
|
||||||
|
|
||||||
|
|
||||||
RestResponse sendMsgData(MsgRequestVO msgRequestVO) throws Exception;
|
|
||||||
|
|
||||||
RestResponse sendMsgsData(MsgsRequestVO msgsRequestVO) throws Exception;
|
|
||||||
}
|
|
||||||
@ -1,625 +0,0 @@
|
|||||||
package com.itn.mjonApi.mjon.api.send.service.impl;
|
|
||||||
|
|
||||||
import com.itn.mjonApi.cmn.apiServer.ApiService;
|
|
||||||
import com.itn.mjonApi.cmn.model.Price;
|
|
||||||
import com.itn.mjonApi.cmn.msg.FailRestResponse;
|
|
||||||
import com.itn.mjonApi.cmn.msg.RestResponse;
|
|
||||||
import com.itn.mjonApi.cmn.msg.StatMsg;
|
|
||||||
import com.itn.mjonApi.mjon.api.inqry.mapper.PriceMapper;
|
|
||||||
import com.itn.mjonApi.mjon.api.inqry.mapper.domain.PriceVO;
|
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.SendMapper;
|
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.MjonResponseVO;
|
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.MsgRequestVO;
|
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.MsgsRequestVO;
|
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.SendSucRestResponse;
|
|
||||||
import com.itn.mjonApi.mjon.api.send.service.SendService;
|
|
||||||
import com.itn.mjonApi.util.MunjaUtil;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.catalina.connector.Response;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
public class SendServiceImpl implements SendService {
|
|
||||||
|
|
||||||
private ApiService<Response> apiService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
SendMapper sendMapper;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
PriceMapper priceMapper;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public SendServiceImpl(ApiService<Response> apiService) {
|
|
||||||
this.apiService = apiService;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String replaseStrList = "[*이름*],[*1*],[*2*],[*3*],[*4*]";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RestResponse sendMsgData(MsgRequestVO msgRequestVO) throws Exception {
|
|
||||||
|
|
||||||
if(StringUtils.isNotEmpty(msgRequestVO.getTest_yn())){
|
|
||||||
// YF => 실패 테스트 데이터
|
|
||||||
return this._getTestMsgReturnData(msgRequestVO.getTest_yn());
|
|
||||||
}
|
|
||||||
//sendMsg 문자 발송 전 체크 사항
|
|
||||||
|
|
||||||
//step1.발신자 전화번호 사용 가능 여부 체크(해당 사용자의 기 등록된 번호만 발송 가능)
|
|
||||||
// 1010
|
|
||||||
msgRequestVO.setCallFrom(MunjaUtil.removeCharactersWithRegex(msgRequestVO.getCallFrom()));
|
|
||||||
if(!sendMapper.findByCallFrom(msgRequestVO)){
|
|
||||||
return new RestResponse(new FailRestResponse("STAT_1010",""));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// step2.수신자 전화번호 정상 여부 체크(정상 번호에 대해서만 발송 가능)
|
|
||||||
// 1020
|
|
||||||
// 폰번호 확인 - 빈 값 -> 유효성 정규식
|
|
||||||
if(this.getCallToListChk(msgRequestVO)){
|
|
||||||
return new RestResponse(new FailRestResponse("STAT_1020",""));
|
|
||||||
}
|
|
||||||
|
|
||||||
//step3.문자 내용 정상 여부 확인 - 스미싱 문구는 발송 30분 지연으로 처리됨
|
|
||||||
// 1030 => 현재 사용안함
|
|
||||||
// 스팸체크 하는 부분
|
|
||||||
// apiService.postForEntity => restTemplate.postForEntity 호출 후 MjonResponseVO에 맞게 데이터 정제하는 메소드
|
|
||||||
MjonResponseVO spamChkEntity = apiService.postForEntity(
|
|
||||||
"/web/user/login/selectSpamTxtChkAjax.do"
|
|
||||||
, msgRequestVO
|
|
||||||
, String.class
|
|
||||||
);
|
|
||||||
// 스팸체크 결과값이 spams 이면 스팸문자로 처리
|
|
||||||
if("spams".equals(spamChkEntity.getResult())){
|
|
||||||
msgRequestVO.setSpamStatus("Y");
|
|
||||||
};
|
|
||||||
|
|
||||||
//step4.치환명 정상 여부 확인
|
|
||||||
// 1040
|
|
||||||
msgRequestVO.setTxtReplYn(this.getTxtReplYn(msgRequestVO));
|
|
||||||
// 치환데이터가 있을 경우
|
|
||||||
if("Y".equals(msgRequestVO.getTxtReplYn())){
|
|
||||||
//일괄변환 문자에 콤마(,)가 들어가있으면 배열로 넘길때 문제가 발생하여 특수문자(§)로 치환하여 넘겨주도록 한다.
|
|
||||||
msgRequestVO = this.getReplaceCommaToStrSymbol(msgRequestVO);
|
|
||||||
// 치환 후 단문 장문 개수 구하기
|
|
||||||
msgRequestVO = this.getLengthOfShortAndLongMsg(msgRequestVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PriceVO priceVO = Price.priceRefine(msgRequestVO.getMberId(), priceMapper);
|
|
||||||
|
|
||||||
|
|
||||||
// +""; => Double to String 와 같은 기능
|
|
||||||
msgRequestVO.setsPrice(priceVO.getShortPrice()+"");
|
|
||||||
msgRequestVO.setmPrice(priceVO.getLongPrice()+"");
|
|
||||||
msgRequestVO.setpPrice(priceVO.getPicturePrice()+"");
|
|
||||||
|
|
||||||
|
|
||||||
//문자열 길이 체크 해주기
|
|
||||||
// 문자 바이트 계산에 필요한 캐릭터 셋 : 한글 2Byte로 계산
|
|
||||||
int FrBytes = getFrBytes(msgRequestVO);
|
|
||||||
// 단문 장문 단가과 타입 지정
|
|
||||||
if(FrBytes > 90){
|
|
||||||
msgRequestVO.setEachPrice(msgRequestVO.getsPrice());
|
|
||||||
msgRequestVO.setMsgType("6");
|
|
||||||
}else {
|
|
||||||
msgRequestVO.setEachPrice(msgRequestVO.getmPrice());
|
|
||||||
msgRequestVO.setMsgType("4");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 문자 전송하는 부분
|
|
||||||
// apiService.postForEntity => restTemplate.postForEntity 호출 후 MjonResponseVO에 맞게 데이터 정제하는 메소드
|
|
||||||
MjonResponseVO munjaSendResponse = apiService.postForEntity(
|
|
||||||
"/web/user/login/sendMsgDataAjax.do"
|
|
||||||
, msgRequestVO
|
|
||||||
, String.class
|
|
||||||
);
|
|
||||||
log.info("munjaSendResponse : [{}]", munjaSendResponse.toString());
|
|
||||||
log.info("munjaSendResponse : [{}]", munjaSendResponse.getResult());
|
|
||||||
|
|
||||||
// convertMjonDataToApiResponse => MjonResponseVO 데이터를 ApiResponse 데이터로 변환하는 메소드
|
|
||||||
if(!munjaSendResponse.getResult().equals("fail")){ // 성공
|
|
||||||
return new RestResponse(SendSucRestResponse.convertMjonDataToApiResponse(munjaSendResponse));
|
|
||||||
}else{ // 실패
|
|
||||||
return new RestResponse(new FailRestResponse(StatMsg.randomErrorStatCode(),""));
|
|
||||||
}
|
|
||||||
|
|
||||||
//step5.발송일시 정상여부 확인
|
|
||||||
// 1050
|
|
||||||
//step6.문자 타입에 따른 비용 처리 가능 여부 확인
|
|
||||||
// 1060
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getFrBytes(MsgRequestVO msgRequestVO) throws UnsupportedEncodingException {
|
|
||||||
String smsCont = msgRequestVO.getSmsTxt().replace("\r\n", "\n");
|
|
||||||
int FrBytes = smsCont.getBytes("euc-kr").length;
|
|
||||||
return FrBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private RestResponse _getTestMsgReturnData(String testYn)
|
|
||||||
{
|
|
||||||
// YF => 실패 테스트 데이터
|
|
||||||
if("YF".equals(testYn))
|
|
||||||
{
|
|
||||||
// 실패 코드 중 랜덤으로 리턴
|
|
||||||
return new RestResponse(new FailRestResponse(StatMsg.randomErrorStatCode(),"YF"));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}else{
|
|
||||||
return new RestResponse(
|
|
||||||
SendSucRestResponse.builder()
|
|
||||||
.resultCode("0")
|
|
||||||
.msgGroupId("MSGGID_0000000000000") // 전송 메세지 그룹 ID
|
|
||||||
.successCnt("5") // 성공 건수
|
|
||||||
.blockCnt("2") // 수신거부 건수
|
|
||||||
.msgType("LMS")
|
|
||||||
.failCnt("0")
|
|
||||||
.test_yn("YS")
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private RestResponse _getTestMsgsReturnData(String testYn)
|
|
||||||
{
|
|
||||||
// YF => 실패 테스트 데이터
|
|
||||||
if("YF".equals(testYn))
|
|
||||||
{
|
|
||||||
return new RestResponse(new FailRestResponse(StatMsg.randomErrorStatCode(),"YF"));
|
|
||||||
}else{ // YS => 성공 테스트 데이터
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
List<String> gIdList = new ArrayList<>();
|
|
||||||
gIdList.add("MSGGID_0000000000000");
|
|
||||||
gIdList.add("MSGGID_0000000000001");
|
|
||||||
gIdList.add("MSGGID_0000000000002");
|
|
||||||
|
|
||||||
List<String> msgTypeList = new ArrayList<>();
|
|
||||||
msgTypeList.add("SMS");
|
|
||||||
msgTypeList.add("LMS");
|
|
||||||
msgTypeList.add("LMS");
|
|
||||||
return new RestResponse(
|
|
||||||
SendSucRestResponse.builder()
|
|
||||||
.resultCode("0")
|
|
||||||
.msgGroupIdList(gIdList) // 전송 메세지 그룹 ID
|
|
||||||
.successCnt("2") // 성공 건수
|
|
||||||
.blockCnt("1") // 수신거부 건수
|
|
||||||
.msgTypeList(msgTypeList)
|
|
||||||
.failCnt("0")
|
|
||||||
.test_yn("YS")
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public RestResponse sendMsgsData(MsgsRequestVO msgsRequestVO) throws Exception {
|
|
||||||
|
|
||||||
if(StringUtils.isNotEmpty(msgsRequestVO.getTest_yn())){
|
|
||||||
return this._getTestMsgsReturnData(msgsRequestVO.getTest_yn());
|
|
||||||
}
|
|
||||||
|
|
||||||
// msgsVO -> msgVO List로 변환
|
|
||||||
List<MsgRequestVO> msgRequestVOList = this.getDataCleaning(msgsRequestVO);
|
|
||||||
|
|
||||||
|
|
||||||
//step1.발신자 전화번호 사용 가능 여부 체크(해당 사용자의 기 등록된 번호만 발송 가능)
|
|
||||||
// 1010
|
|
||||||
if(!sendMapper.findByCallFrom(msgRequestVOList.get(0))){
|
|
||||||
return new RestResponse(new FailRestResponse("STAT_1010",""));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// step2.수신자 전화번호 정상 여부 체크(정상 번호에 대해서만 발송 가능)
|
|
||||||
// 1020
|
|
||||||
// 폰번호 확인 - 빈 값 -> 유효성 정규식
|
|
||||||
for(MsgRequestVO msgRequestVO : msgRequestVOList){
|
|
||||||
if(this.getCallToListChk(msgRequestVO)){
|
|
||||||
// if(StringUtils.isNotEmpty(this.getCallToListChk(msgRequestVO))){
|
|
||||||
return this.callToErrorReturnData(msgRequestVO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//사용자 잔액
|
|
||||||
// double mberMoney = priceMapper.selectMberMoney(mberId);
|
|
||||||
// 이용단가, 발송가능 건수
|
|
||||||
// PriceVO priceVO = this.price_refine(mberId, mberMoney, priceMapper);
|
|
||||||
|
|
||||||
|
|
||||||
PriceVO priceVO = Price.priceRefine(msgsRequestVO.getMberId(), priceMapper);
|
|
||||||
|
|
||||||
// +""; => Double to String 와 같은 기능
|
|
||||||
String sPrice = priceVO.getShortPrice()+"";
|
|
||||||
String mPrice = priceVO.getLongPrice()+"";
|
|
||||||
String pPrice = priceVO.getPicturePrice()+"";
|
|
||||||
List<MjonResponseVO> mjonResponseVOList = new ArrayList<MjonResponseVO>();
|
|
||||||
for(MsgRequestVO msgRequestVO : msgRequestVOList){
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//문자열 길이 체크 해주기
|
|
||||||
// 문자 바이트 계산에 필요한 캐릭터 셋 : 한글 2Byte로 계산
|
|
||||||
int FrBytes = getFrBytes(msgRequestVO);
|
|
||||||
// 단문 장문 단가과 타입 지정
|
|
||||||
if(FrBytes > 90){
|
|
||||||
msgRequestVO.setEachPrice(sPrice);
|
|
||||||
msgRequestVO.setMsgType("6");
|
|
||||||
}else {
|
|
||||||
msgRequestVO.setEachPrice(mPrice);
|
|
||||||
msgRequestVO.setMsgType("4");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 단가 셋팅
|
|
||||||
msgRequestVO.setsPrice(sPrice); // 단문
|
|
||||||
msgRequestVO.setmPrice(mPrice); // 장문
|
|
||||||
msgRequestVO.setpPrice(pPrice); // 사진
|
|
||||||
|
|
||||||
|
|
||||||
//step3.문자 내용 정상 여부 확인 - 스미싱 문구는 발송 30분 지연으로 처리됨
|
|
||||||
// 1030 => 현재 사용안함
|
|
||||||
// 스팸체크 하는 부분
|
|
||||||
MjonResponseVO spamChkEntity = apiService.postForEntity(
|
|
||||||
"/web/user/login/selectSpamTxtChkAjax.do"
|
|
||||||
, msgRequestVO
|
|
||||||
, String.class
|
|
||||||
);
|
|
||||||
// 스팸체크 결과값이 spams 이면 스팸문자로 처리
|
|
||||||
if("spams".equals(spamChkEntity.getResult())){
|
|
||||||
msgRequestVO.setSpamStatus("Y");
|
|
||||||
};
|
|
||||||
|
|
||||||
// 문자 전송하는 부분
|
|
||||||
// apiService.postForEntity => restTemplate.postForEntity 호출 후 MjonResponseVO에 맞게 데이터 정제하는 메소드
|
|
||||||
MjonResponseVO munjaSendResponse = apiService.postForEntity(
|
|
||||||
"/web/user/login/sendMsgDataAjax.do"
|
|
||||||
, msgRequestVO
|
|
||||||
, String.class
|
|
||||||
);
|
|
||||||
//
|
|
||||||
mjonResponseVOList.add(munjaSendResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return new RestResponse(SendSucRestResponse.SendSuccessMsgsRestResponse(mjonResponseVOList));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static RestResponse callToErrorReturnData(MsgRequestVO msgRequestVO) {
|
|
||||||
|
|
||||||
FailRestResponse stat1020 = new FailRestResponse("STAT_1020","");
|
|
||||||
String errorMsg = stat1020.getMsg();
|
|
||||||
errorMsg.replace("수신자", "수신자(" + msgRequestVO.getCallToList()[0] + ")");
|
|
||||||
stat1020.setMsg(errorMsg);
|
|
||||||
|
|
||||||
return new RestResponse(stat1020);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 최대 1~100개의 수신번호와 메세지를 MsgRequestVO로 정재하는 메소드.
|
|
||||||
* @param msgsRequestVO
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static List<MsgRequestVO> getDataCleaning(MsgsRequestVO msgsRequestVO) {
|
|
||||||
|
|
||||||
|
|
||||||
List<MsgRequestVO> msgRequestVOList = new ArrayList<>();
|
|
||||||
|
|
||||||
// Reflection으로 Object Field에 접근한다.
|
|
||||||
Field[] declaredFields = msgsRequestVO.getClass().getDeclaredFields();
|
|
||||||
|
|
||||||
String mberId = null; // 사용자 ID
|
|
||||||
String accessKey = null; // accessKey
|
|
||||||
String callFrom = null; // 발신자 번호
|
|
||||||
String callTo = null; // 수신자 번호
|
|
||||||
|
|
||||||
for (Field field : declaredFields) {
|
|
||||||
|
|
||||||
Object value = null;
|
|
||||||
// private Field일 경우 접근을 허용한다.
|
|
||||||
field.setAccessible(true);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Field Value를 참조한다.
|
|
||||||
value = field.get(msgsRequestVO);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
log.info("Reflection Error. {}", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// nullPointException 방지
|
|
||||||
if(value != null)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 필드 이름으로 분기하여
|
|
||||||
* 각각에 맞는 위치에 값을 넣어준다.
|
|
||||||
*/
|
|
||||||
if("mberId".equals(field.getName())){ // 사용자 ID
|
|
||||||
mberId = value.toString();
|
|
||||||
}else if("accessKey".equals(field.getName())){ // accessKey
|
|
||||||
accessKey = value.toString();
|
|
||||||
}else if("callFrom".equals(field.getName())){ // 발신자 번호
|
|
||||||
callFrom = value.toString();
|
|
||||||
}else if(field.getName().startsWith("callTo")){ // 수신자 번호
|
|
||||||
callTo = value.toString();
|
|
||||||
}else if(field.getName().startsWith("smsTxt")){ // 문자 내용
|
|
||||||
|
|
||||||
// 값이 비여 있으면 다음 반복문으로 넘어간다.
|
|
||||||
if(StringUtils.isEmpty(value.toString())){
|
|
||||||
callTo = "";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
msgRequestVOList.add(
|
|
||||||
MsgRequestVO.builder()
|
|
||||||
.mberId(mberId)
|
|
||||||
.accessKey(accessKey)
|
|
||||||
.callFrom(callFrom)
|
|
||||||
.callToList(new String[]{callTo})
|
|
||||||
.smsTxt(value.toString())
|
|
||||||
.eachPrice("0") // 디폴트
|
|
||||||
.sPrice("0") // 디폴트
|
|
||||||
.totPrice("0") // 디폴트
|
|
||||||
.fileCnt("0") // 디폴트
|
|
||||||
.msgType("4") // 디폴트
|
|
||||||
.smsPrice(0) // 디폴트
|
|
||||||
.mmsPrice(0) // 디폴트
|
|
||||||
.imgFilePath(new String[0]) // 디폴트
|
|
||||||
.txtReplYn("N") // 디폴트
|
|
||||||
.reserveYn("N") // 디폴트
|
|
||||||
.msgKind("N") // 디폴트
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
// 초기화
|
|
||||||
callTo = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return msgRequestVOList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 치환 후 단문 장문 msg 개수 구하기
|
|
||||||
* @param msgRequestVO
|
|
||||||
* @return msgRequestVO
|
|
||||||
* @throws UnsupportedEncodingException
|
|
||||||
*/
|
|
||||||
private static MsgRequestVO getLengthOfShortAndLongMsg(MsgRequestVO msgRequestVO) throws UnsupportedEncodingException {
|
|
||||||
String charset = "euc-kr";
|
|
||||||
int totListCnt = msgRequestVO.getCallToList().length;
|
|
||||||
|
|
||||||
int shortMsgCnt=0; // 치환 후 단문 개수
|
|
||||||
int longMsgCnt=0; // 치환 후 장문 개수
|
|
||||||
for(int i=0; i < totListCnt; i ++) {
|
|
||||||
String smsTxt = msgRequestVO.getSmsTxt().replaceAll(String.valueOf((char)13), ""); //발송 문자 내용
|
|
||||||
|
|
||||||
String[] nameList = msgRequestVO.getNameList(); //치환 이름 리스트
|
|
||||||
String[] phone = msgRequestVO.getCallToList(); //수신자 휴대폰 번호
|
|
||||||
String[] rep1 = msgRequestVO.getRep1List(); //치환 문자1 리스트
|
|
||||||
String[] rep2 = msgRequestVO.getRep2List(); //치환 문자2 리스트
|
|
||||||
String[] rep3 = msgRequestVO.getRep3List(); //치환 문자3 리스트
|
|
||||||
String[] rep4 = msgRequestVO.getRep4List(); //치환 문자4 리스트
|
|
||||||
|
|
||||||
if (smsTxt.indexOf("[*이름*]") > -1) {
|
|
||||||
if(nameList.length > i && StringUtils.isNotEmpty(nameList[i])) {
|
|
||||||
smsTxt = smsTxt.replaceAll("\\[\\*이름\\*\\]", MunjaUtil.getString(nameList[i].replaceAll("§", ",")));
|
|
||||||
}else {
|
|
||||||
smsTxt = smsTxt.replaceAll("\\[\\*이름\\*\\]", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (smsTxt.indexOf("[*1*]") > -1) {
|
|
||||||
if(rep1.length > i && StringUtils.isNotEmpty(rep1[i])) {
|
|
||||||
smsTxt = smsTxt.replaceAll("\\[\\*1\\*\\]", MunjaUtil.getString(rep1[i].replaceAll("§", ",")));
|
|
||||||
}else {
|
|
||||||
smsTxt = smsTxt.replaceAll("\\[\\*1\\*\\]", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (smsTxt.indexOf("[*2*]") > -1) {
|
|
||||||
if(rep2.length > i && StringUtils.isNotEmpty(rep2[i])) {
|
|
||||||
smsTxt = smsTxt.replaceAll("\\[\\*2\\*\\]", MunjaUtil.getString(rep2[i].replaceAll("§", ",")));
|
|
||||||
}else {
|
|
||||||
smsTxt = smsTxt.replaceAll("\\[\\*2\\*\\]", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (smsTxt.indexOf("[*3*]") > -1) {
|
|
||||||
if(rep3.length > i && StringUtils.isNotEmpty(rep3[i])) {
|
|
||||||
smsTxt = smsTxt.replaceAll("\\[\\*3\\*\\]", MunjaUtil.getString(rep3[i].replaceAll("§", ",")));
|
|
||||||
}else {
|
|
||||||
smsTxt = smsTxt.replaceAll("\\[\\*3\\*\\]", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (smsTxt.indexOf("[*4*]") > -1) {
|
|
||||||
if(rep4.length > i && StringUtils.isNotEmpty(rep4[i])) {
|
|
||||||
smsTxt = smsTxt.replaceAll("\\[\\*4\\*\\]", MunjaUtil.getString(rep4[i].replaceAll("§", ",")));
|
|
||||||
}else {
|
|
||||||
smsTxt = smsTxt.replaceAll("\\[\\*4\\*\\]", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int bytes = smsTxt.getBytes(charset).length;
|
|
||||||
|
|
||||||
if(bytes > 90) {//장문문자 리스트 만들기
|
|
||||||
longMsgCnt++;
|
|
||||||
}else {//단문문자 리스트 만들기
|
|
||||||
shortMsgCnt++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
msgRequestVO.setLongMsgCnt(Integer.toString(longMsgCnt));
|
|
||||||
msgRequestVO.setShortMsgCnt(Integer.toString(shortMsgCnt));
|
|
||||||
|
|
||||||
return msgRequestVO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 치환문자가 있으면 , => §로 치환
|
|
||||||
* @param msgRequestVO
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static MsgRequestVO getReplaceCommaToStrSymbol(MsgRequestVO msgRequestVO) {
|
|
||||||
|
|
||||||
AtomicInteger index = new AtomicInteger();
|
|
||||||
|
|
||||||
// 이름 배열
|
|
||||||
if(StringUtils.isNotEmpty(msgRequestVO.getNameStr()))
|
|
||||||
{
|
|
||||||
msgRequestVO.setNameList(msgRequestVO.getNameStr().split("\\|"));
|
|
||||||
String[] nameList = new String[msgRequestVO.getNameList().length];
|
|
||||||
Arrays.stream(msgRequestVO.getNameList()).forEach(name -> {
|
|
||||||
nameList[index.getAndIncrement()] = MunjaUtil.replaceCommaToStrSymbol(name);
|
|
||||||
});
|
|
||||||
msgRequestVO.setNameList(nameList);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rep1 배열
|
|
||||||
if(StringUtils.isNotEmpty(msgRequestVO.getRep1Str()))
|
|
||||||
{
|
|
||||||
index.set(0);
|
|
||||||
msgRequestVO.setRep1List(msgRequestVO.getRep1Str().split("\\|"));
|
|
||||||
String[] rep1List = new String[msgRequestVO.getRep1List().length];
|
|
||||||
Arrays.stream(msgRequestVO.getRep1List()).forEach(str -> {
|
|
||||||
rep1List[index.getAndIncrement()] = MunjaUtil.replaceCommaToStrSymbol(str);
|
|
||||||
});
|
|
||||||
msgRequestVO.setRep1List(rep1List);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rep2 배열
|
|
||||||
if(StringUtils.isNotEmpty(msgRequestVO.getRep2Str()))
|
|
||||||
{
|
|
||||||
index.set(0);
|
|
||||||
msgRequestVO.setRep2List(msgRequestVO.getRep2Str().split("\\|"));
|
|
||||||
String[] rep2List = new String[msgRequestVO.getRep2List().length];
|
|
||||||
Arrays.stream(msgRequestVO.getRep2List()).forEach(str -> {
|
|
||||||
rep2List[index.getAndIncrement()] = MunjaUtil.replaceCommaToStrSymbol(str);
|
|
||||||
});
|
|
||||||
msgRequestVO.setRep2List(rep2List);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rep3 배열
|
|
||||||
if(StringUtils.isNotEmpty(msgRequestVO.getRep3Str()))
|
|
||||||
{
|
|
||||||
index.set(0);
|
|
||||||
msgRequestVO.setRep3List(msgRequestVO.getRep3Str().split("\\|"));
|
|
||||||
String[] rep3List = new String[msgRequestVO.getRep3List().length];
|
|
||||||
Arrays.stream(msgRequestVO.getRep3List()).forEach(str -> {
|
|
||||||
rep3List[index.getAndIncrement()] = MunjaUtil.replaceCommaToStrSymbol(str);
|
|
||||||
});
|
|
||||||
msgRequestVO.setRep3List(rep3List);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rep4 배열
|
|
||||||
if(StringUtils.isNotEmpty(msgRequestVO.getRep4Str()))
|
|
||||||
{
|
|
||||||
index.set(0);
|
|
||||||
msgRequestVO.setRep4List(msgRequestVO.getRep4Str().split("\\|"));
|
|
||||||
String[] rep4List = new String[msgRequestVO.getRep4List().length];
|
|
||||||
Arrays.stream(msgRequestVO.getRep4List()).forEach(str -> {
|
|
||||||
rep4List[index.getAndIncrement()] = MunjaUtil.replaceCommaToStrSymbol(str);
|
|
||||||
});
|
|
||||||
msgRequestVO.setRep4List(rep4List);
|
|
||||||
}
|
|
||||||
return msgRequestVO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 치환 문자 여부 확인
|
|
||||||
* @param msgRequestVO
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static String getTxtReplYn(MsgRequestVO msgRequestVO) {
|
|
||||||
|
|
||||||
int callLen = msgRequestVO.getCallToList().length;
|
|
||||||
// 치환 데이터 확인
|
|
||||||
Arrays.stream(replaseStrList.split(",")).forEach(
|
|
||||||
str -> {
|
|
||||||
if(msgRequestVO.getSmsTxt().indexOf(str) > -1){
|
|
||||||
msgRequestVO.setTxtReplYn("Y");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return msgRequestVO.getTxtReplYn();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 수신자 목록 번호 검증
|
|
||||||
* message가 없으면 정상
|
|
||||||
* @param msgRequestVO
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
private static Boolean getCallToListChk(MsgRequestVO msgRequestVO) {
|
|
||||||
Boolean returnData = false;
|
|
||||||
for(String callTo : msgRequestVO.getCallToList()){
|
|
||||||
/*
|
|
||||||
if(!MunjaUtil.checkPhoneNumberEmpty(callTo)){
|
|
||||||
message = "수신 목록에 핸드폰 번호가 없는 항목이 있습니다."; break;};
|
|
||||||
if(!MunjaUtil.validatePNumWithRegex(callTo)){
|
|
||||||
message = "휴대폰 번호가 올바르지 않습니다. : " + callTo; break;};
|
|
||||||
*/
|
|
||||||
if(!MunjaUtil.validatePNumWithRegex(callTo) // 비여있는지 체크
|
|
||||||
|| !MunjaUtil.validatePNumWithRegex(callTo) // 정규식으로 번호 체크
|
|
||||||
)
|
|
||||||
{
|
|
||||||
returnData = true;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
return returnData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MjonResponseVO -> 변환 -> SendFailRestResponse
|
|
||||||
* @param mjonResponseVO
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String convertMjonDataToApiResponse(MjonResponseVO mjonResponseVO) {
|
|
||||||
String result = mjonResponseVO.getResult();
|
|
||||||
log.info("convertMjonDataToApiResponse : [{}]", result);
|
|
||||||
|
|
||||||
String message = mjonResponseVO.getMessage();
|
|
||||||
log.info("convertMjonDataToApiResponse : [{}]", message);
|
|
||||||
|
|
||||||
String statCode = "";
|
|
||||||
switch (result) {
|
|
||||||
case "statusFail" : statCode = "1070"; // 회원 정지
|
|
||||||
break;
|
|
||||||
case "smsLengFail" : statCode = "1080"; // 문자 길이 초과
|
|
||||||
break;
|
|
||||||
case "fail" : // 문자온 프로젝트에서 result가 fail로 다양한 에러가 리턴하여 분기처리함
|
|
||||||
if(message.indexOf("문자 치환 후 전송 문자 길이를 초과하였습니다.")>-1)
|
|
||||||
statCode = "1050"; // 치환 후 문자 길이 초과
|
|
||||||
else if(message.indexOf("치환문자 데이터가 없습니다")>-1)
|
|
||||||
statCode = "1040"; // 치환 데이터 오류
|
|
||||||
else if(message.indexOf("치환 후 전송 문자 길이를 초과")>-1)
|
|
||||||
statCode = "1050"; // 치환 데이터 오류
|
|
||||||
else
|
|
||||||
statCode = "1099"; // 기타 시스템 오류
|
|
||||||
break;
|
|
||||||
default: statCode = "1099"; // 기타 시스템 오류
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "STAT_"+statCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -3,10 +3,6 @@ package com.itn.mjonApi.util;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import com.itn.mjonApi.cmn.msg.RestResponse;
|
|
||||||
import com.itn.mjonApi.mjon.api.access.mapper.domain.AccessKeyVO;
|
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.MsgRequestVO;
|
|
||||||
import com.itn.mjonApi.mjon.api.send.mapper.domain.MsgsRequestVO;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* packageName : com.itn.mjonApi.util
|
* packageName : com.itn.mjonApi.util
|
||||||
@ -21,45 +17,10 @@ import com.itn.mjonApi.mjon.api.send.mapper.domain.MsgsRequestVO;
|
|||||||
*/
|
*/
|
||||||
public class ApiObjectUtil {
|
public class ApiObjectUtil {
|
||||||
|
|
||||||
|
private static final ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
|
||||||
|
|
||||||
|
public static String toJson(Object obj) throws JsonProcessingException {
|
||||||
|
if (obj == null) return null;
|
||||||
|
return objectMapper.writeValueAsString(obj);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description : VO를 json으로 변환
|
|
||||||
* @param restResponse
|
|
||||||
* @return String
|
|
||||||
* @throws JsonProcessingException
|
|
||||||
*/
|
|
||||||
public static String getRestResponseToJsonString(RestResponse restResponse) throws JsonProcessingException {
|
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
// .registerModule(new JavaTimeModule()) : LocalDateTime을 json으로 변환하기 위함
|
|
||||||
return objectMapper.registerModule(new JavaTimeModule()).writeValueAsString(restResponse);
|
|
||||||
}
|
}
|
||||||
public static String getMsgsRequestVOToJsonString(MsgsRequestVO msgsRequestVO) throws JsonProcessingException {
|
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
// .registerModule(new JavaTimeModule()) : LocalDateTime을 json으로 변환하기 위함
|
|
||||||
return objectMapper.registerModule(new JavaTimeModule()).writeValueAsString(msgsRequestVO);
|
|
||||||
}
|
|
||||||
public static String getMsgRequestVOToJsonString(MsgRequestVO msgRequestVO) throws JsonProcessingException {
|
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
// .registerModule(new JavaTimeModule()) : LocalDateTime을 json으로 변환하기 위함
|
|
||||||
return objectMapper.registerModule(new JavaTimeModule()).writeValueAsString(msgRequestVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description : VO를 json으로 변환
|
|
||||||
* @param accessKeyVO
|
|
||||||
* @return String
|
|
||||||
* @throws JsonProcessingException
|
|
||||||
*/
|
|
||||||
public static String getAccessKeyVOToJsonString(AccessKeyVO accessKeyVO) throws JsonProcessingException {
|
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
// .registerModule(new JavaTimeModule()) : LocalDateTime을 json으로 변환하기 위함
|
|
||||||
return objectMapper.registerModule(new JavaTimeModule()).writeValueAsString(accessKeyVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,11 @@
|
|||||||
package com.itn.mjonApi.util;
|
package com.itn.mjonApi.util;
|
||||||
|
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain.MsgAtRequestVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.send.mapper.domain.VarAtListMapVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.MsgFtRequestVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.ft.send.mapper.domain.VarFtListMapVO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,19 +19,10 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
* -----------------------------------------------------------
|
* -----------------------------------------------------------
|
||||||
* 2023-05-17 hylee 최초 생성
|
* 2023-05-17 hylee 최초 생성
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class MunjaUtil {
|
public class MunjaUtil {
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 폰번호 유효성 검사
|
|
||||||
* @param callTo
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static Boolean validatePNumWithRegex(String callTo){
|
|
||||||
// 핸드폰 정규식
|
|
||||||
String regex = "^01(?:0|1|[6-9])(?:\\d{3}|\\d{4})\\d{4}$";
|
|
||||||
return callTo.matches(regex) ? true : false;
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 폰번호 빈값 검사
|
* 폰번호 빈값 검사
|
||||||
* @param str
|
* @param str
|
||||||
@ -49,7 +46,7 @@ public class MunjaUtil {
|
|||||||
* 파라미터를 String 타입으로 가져옵니다.<br>
|
* 파라미터를 String 타입으로 가져옵니다.<br>
|
||||||
* - null일 경우 빈 문자열을 가져옵니다.<br>
|
* - null일 경우 빈 문자열을 가져옵니다.<br>
|
||||||
* Get String(if object is null, return empty string).
|
* Get String(if object is null, return empty string).
|
||||||
* @param Object
|
* @param obj
|
||||||
* @return String
|
* @return String
|
||||||
*/
|
*/
|
||||||
public static String getString(Object obj) {
|
public static String getString(Object obj) {
|
||||||
@ -59,5 +56,128 @@ public class MunjaUtil {
|
|||||||
return String.valueOf(obj);
|
return String.valueOf(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 수신자 목록 번호 검증
|
||||||
|
* message가 없으면 정상
|
||||||
|
* @param callToList
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public static Boolean getCallToListChk(String[] callToList) {
|
||||||
|
Boolean returnData = false;
|
||||||
|
|
||||||
|
|
||||||
|
if (ArrayUtils.isEmpty(callToList)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(String callTo : callToList){
|
||||||
|
if(!MunjaUtil.checkPhoneNumberEmpty(callTo) // 비여있는지 체크
|
||||||
|
|| !MunjaUtil.validatePNumWithRegex(callTo) // 정규식으로 번호 체크
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
return returnData;
|
||||||
|
}
|
||||||
|
public static Boolean getCallToChk(String callTo) {
|
||||||
|
Boolean returnData = false;
|
||||||
|
|
||||||
|
if(!MunjaUtil.checkPhoneNumberEmpty(callTo) // 비여있는지 체크
|
||||||
|
|| !MunjaUtil.validatePNumWithRegex(callTo) // 정규식으로 번호 체크
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
return returnData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 기존 정규식 검사 메서드 (변경 없음)
|
||||||
|
public static boolean validatePNumWithRegex(String pNum) {
|
||||||
|
return pNum != null && pNum.matches("^\\d{10,11}$");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VarListMapVO의 필드들을 검증
|
||||||
|
*
|
||||||
|
* @param vo 검증할 VarListMapVO 객체
|
||||||
|
* @param msgAtRequestVO
|
||||||
|
* @return 검증 실패 시 오류 코드, 성공 시 null
|
||||||
|
*/
|
||||||
|
public static String kakaoAtValidate(VarAtListMapVO vo, MsgAtRequestVO msgAtRequestVO) {
|
||||||
|
|
||||||
|
|
||||||
|
String subMsgSendYn = msgAtRequestVO.getSubMsgSendYn();
|
||||||
|
Boolean hasTemplateTitle = msgAtRequestVO.getHasTemplateTitle();
|
||||||
|
// 수신번호 검증
|
||||||
|
String callTo = vo.getCallToList();
|
||||||
|
if (MunjaUtil.getCallToChk(callTo)) {
|
||||||
|
return "STAT_1020"; // 수신자 전화번호 오류
|
||||||
|
}
|
||||||
|
|
||||||
|
// 본문 데이터 검증
|
||||||
|
String templateContent = vo.getTemplateContent();
|
||||||
|
if (StringUtils.isEmpty(templateContent)) {
|
||||||
|
return "STAT_2040"; // 본문 데이터 오류
|
||||||
|
}
|
||||||
|
|
||||||
|
// 템플릿에 타이틀이 있으면 값 확인
|
||||||
|
if (hasTemplateTitle && StringUtils.isEmpty(vo.getTemplateTitle())) {
|
||||||
|
return "STAT_2041"; // 타이틀 데이터 오류
|
||||||
|
}
|
||||||
|
|
||||||
|
// 대체문자 검증 (대체문자 발송이 활성화된 경우에만)
|
||||||
|
if ("Y".equals(subMsgSendYn)) {
|
||||||
|
String subMsgTxt = vo.getSubMsgTxt();
|
||||||
|
if (StringUtils.isEmpty(subMsgTxt)) {
|
||||||
|
return "STAT_2042"; // 대체문자 데이터 오류
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 모든 검증 통과
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String kakaoFtValidate(VarFtListMapVO vo, MsgFtRequestVO msgFtRequestVO) {
|
||||||
|
|
||||||
|
log.info(" vo.toString() [{}]", vo.toString());
|
||||||
|
String ok = null;
|
||||||
|
// 수신번호 검증
|
||||||
|
String callTo = vo.getPhone();
|
||||||
|
if (MunjaUtil.getCallToChk(callTo)) {
|
||||||
|
return "STAT_1020"; // 수신자 전화번호 오류
|
||||||
|
}
|
||||||
|
|
||||||
|
// 본문 데이터 검증
|
||||||
|
String smsTxt = vo.getTemplateContent();
|
||||||
|
if (StringUtils.isEmpty(smsTxt)) {
|
||||||
|
return "STAT_2040"; // 본문 데이터 오류
|
||||||
|
}
|
||||||
|
|
||||||
|
// 대체문자 검증 (대체문자 발송이 활성화된 경우에만)
|
||||||
|
if ("Y".equals(msgFtRequestVO.getSubMsgSendYn())) {
|
||||||
|
String subMsgTxt = vo.getSubMsgTxt();
|
||||||
|
if (StringUtils.isEmpty(subMsgTxt)) {
|
||||||
|
return "STAT_2042"; // 대체문자 데이터 오류
|
||||||
|
}
|
||||||
|
|
||||||
|
String callFrom = msgFtRequestVO.getCallFrom();
|
||||||
|
if (StringUtils.isEmpty(callFrom)) {
|
||||||
|
return "STAT_2043"; // 대체문자 발송 시 발신번호 필요
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 모든 검증 통과
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
299
src/main/java/com/itn/mjonApi/util/TestDataUtil.java
Normal file
299
src/main/java/com/itn/mjonApi/util/TestDataUtil.java
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
package com.itn.mjonApi.util;
|
||||||
|
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.detail.TemplateComments;
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.detail.TemplateDetail;
|
||||||
|
import com.itn.mjonApi.cmn.domain.biz.template.list.TemplateInfo;
|
||||||
|
import com.itn.mjonApi.cmn.msg.FailRestResponse;
|
||||||
|
import com.itn.mjonApi.cmn.msg.RestResponse;
|
||||||
|
import com.itn.mjonApi.cmn.msg.StatMsg;
|
||||||
|
import com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.domain.MjKakaoProfileInfoVO;
|
||||||
|
import com.itn.mjonApi.mjon.api.msg.send.mapper.domain.SendSucRestResponse;
|
||||||
|
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 카카오 조회 API 테스트 데이터 유틸리티 클래스
|
||||||
|
* 기존 SMS/LMS 테스트 패턴을 재사용하여 일관성 유지
|
||||||
|
*
|
||||||
|
* @author system
|
||||||
|
* @date 2025-01-09
|
||||||
|
*/
|
||||||
|
public class TestDataUtil {
|
||||||
|
|
||||||
|
|
||||||
|
private static FailRestResponse randomFail(){
|
||||||
|
|
||||||
|
return new FailRestResponse(StatMsg.randomErrorStatCode(),"YF");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RestResponse _getTestMsgReturnData(String testYn)
|
||||||
|
{
|
||||||
|
// YF => 실패 테스트 데이터
|
||||||
|
|
||||||
|
if("YF".equals(testYn))
|
||||||
|
{
|
||||||
|
// 실패 코드 중 랜덤으로 리턴
|
||||||
|
return new RestResponse(randomFail());
|
||||||
|
}else{
|
||||||
|
return new RestResponse(
|
||||||
|
SendSucRestResponse.builder()
|
||||||
|
.resultCode("0")
|
||||||
|
.msgGroupId("MSGGID_0000000000000") // 전송 메세지 그룹 ID
|
||||||
|
.successCnt("5") // 성공 건수
|
||||||
|
.blockCnt("2") // 수신거부 건수
|
||||||
|
.msgType("LMS")
|
||||||
|
.failCnt("0")
|
||||||
|
.test_yn("YS")
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 다중문자발송
|
||||||
|
*
|
||||||
|
* @param testYn 테스트 모드 (YS: 성공, YF: 실패)
|
||||||
|
* @return RestResponse 래핑된 테스트 데이터
|
||||||
|
*/
|
||||||
|
public static RestResponse _getTestMsgsReturnData(String testYn)
|
||||||
|
{
|
||||||
|
// YF => 실패 테스트 데이터
|
||||||
|
if("YF".equals(testYn))
|
||||||
|
{
|
||||||
|
return new RestResponse(randomFail());
|
||||||
|
}else{ // YS => 성공 테스트 데이터
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
List<String> gIdList = new ArrayList<>();
|
||||||
|
gIdList.add("MSGGID_0000000000000");
|
||||||
|
gIdList.add("MSGGID_0000000000001");
|
||||||
|
gIdList.add("MSGGID_0000000000002");
|
||||||
|
|
||||||
|
List<String> msgTypeList = new ArrayList<>();
|
||||||
|
msgTypeList.add("SMS");
|
||||||
|
msgTypeList.add("LMS");
|
||||||
|
msgTypeList.add("LMS");
|
||||||
|
return new RestResponse(
|
||||||
|
SendSucRestResponse.builder()
|
||||||
|
.resultCode("0")
|
||||||
|
.msgGroupIdList(gIdList) // 전송 메세지 그룹 ID
|
||||||
|
.successCnt("2") // 성공 건수
|
||||||
|
.blockCnt("1") // 수신거부 건수
|
||||||
|
.msgTypeList(msgTypeList)
|
||||||
|
.failCnt("0")
|
||||||
|
.test_yn("YS")
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 알림톡 발송 테스트 데이터 생성
|
||||||
|
* @param testYn 테스트 모드 (YS: 성공, YF: 실패)
|
||||||
|
* @return RestResponse 래핑된 테스트 데이터
|
||||||
|
*/
|
||||||
|
public static RestResponse getTestAtSendReturnData(String testYn) {
|
||||||
|
if("YF".equals(testYn)) {
|
||||||
|
// 실패 테스트 데이터
|
||||||
|
return new RestResponse(randomFail());
|
||||||
|
} else {
|
||||||
|
// 성공 테스트: 알림톡 발송 성공 응답
|
||||||
|
return new RestResponse(
|
||||||
|
SendSucRestResponse.builder()
|
||||||
|
.resultCode("0")
|
||||||
|
.msgGroupId("MSGGID_AT_" + System.currentTimeMillis()) // 알림톡 전용 그룹 ID
|
||||||
|
.successCnt("2") // 성공 건수
|
||||||
|
.blockCnt("0") // 수신거부 건수
|
||||||
|
.msgType("AT") // 알림톡 타입
|
||||||
|
.failCnt("0")
|
||||||
|
.test_yn("YS")
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 친구톡 발송 테스트 데이터 생성
|
||||||
|
* @param testYn 테스트 모드 (YS: 성공, YF: 실패)
|
||||||
|
* @return RestResponse 래핑된 테스트 데이터
|
||||||
|
*/
|
||||||
|
public static RestResponse getTestFtSendReturnData(String testYn) {
|
||||||
|
if("YF".equals(testYn)) {
|
||||||
|
// 실패 테스트 데이터
|
||||||
|
return new RestResponse(randomFail());
|
||||||
|
} else {
|
||||||
|
// 친구톡용 msgGroupIdList 생성
|
||||||
|
List<String> msgGroupIdList = new ArrayList<>();
|
||||||
|
long timestamp = System.currentTimeMillis();
|
||||||
|
msgGroupIdList.add("MSGGID_" + timestamp);
|
||||||
|
msgGroupIdList.add("MSGGID_" + timestamp);
|
||||||
|
|
||||||
|
// 성공 테스트: 친구톡 발송 성공 응답
|
||||||
|
return new RestResponse(
|
||||||
|
SendSucRestResponse.builder()
|
||||||
|
.resultCode("0")
|
||||||
|
.msgType("FT") // 친구톡 타입
|
||||||
|
.msgGroupIdList(msgGroupIdList) // 친구톡은 msgGroupIdList 사용
|
||||||
|
.successCnt("2") // 성공 건수
|
||||||
|
.failCnt("0")
|
||||||
|
.test_yn("YS")
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 채널 ID 조회 테스트 데이터 생성
|
||||||
|
*
|
||||||
|
* @param testYn 테스트 모드 (YS: 성공, YF: 실패)
|
||||||
|
* @return RestResponse 래핑된 테스트 데이터
|
||||||
|
*/
|
||||||
|
public static RestResponse getChnlIdTestData(String testYn) {
|
||||||
|
if ("YF".equals(testYn)) {
|
||||||
|
return new RestResponse(randomFail());
|
||||||
|
} else {
|
||||||
|
|
||||||
|
|
||||||
|
Date now = new Date();
|
||||||
|
// 원하는 포맷
|
||||||
|
String nowDate = DateFormatUtils.format(now, "yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
// 성공 테스트: 모킹된 채널 정보 반환
|
||||||
|
List<MjKakaoProfileInfoVO> mockData = new ArrayList<>();
|
||||||
|
|
||||||
|
MjKakaoProfileInfoVO channel1 = new MjKakaoProfileInfoVO();
|
||||||
|
channel1.setSenderKey("test_sender_key_001");
|
||||||
|
channel1.setPhoneNumber("02-1234-0000");
|
||||||
|
channel1.setYellowId("@test_channel_001");
|
||||||
|
channel1.setFrstRegisterId("test_id_one");
|
||||||
|
channel1.setFrstRegistPnttm(nowDate);
|
||||||
|
|
||||||
|
MjKakaoProfileInfoVO channel2 = new MjKakaoProfileInfoVO();
|
||||||
|
channel2.setSenderKey("test_sender_key_002");
|
||||||
|
channel2.setPhoneNumber("02-1234-0001");
|
||||||
|
channel2.setYellowId("@test_channel_002");
|
||||||
|
channel2.setFrstRegisterId("test_id_tow");
|
||||||
|
channel2.setFrstRegistPnttm(nowDate);
|
||||||
|
|
||||||
|
mockData.add(channel1);
|
||||||
|
mockData.add(channel2);
|
||||||
|
|
||||||
|
return new RestResponse(mockData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 템플릿 목록 조회 테스트 데이터 생성
|
||||||
|
*
|
||||||
|
* @param testYn 테스트 모드 (YS: 성공, YF: 실패)
|
||||||
|
* @return RestResponse 래핑된 테스트 데이터
|
||||||
|
*/
|
||||||
|
public static RestResponse getTemplateListTestData(String testYn) {
|
||||||
|
if ("YF".equals(testYn)) {
|
||||||
|
return new RestResponse(randomFail());
|
||||||
|
} else {
|
||||||
|
// 성공 테스트: 모킹된 템플릿 목록 반환
|
||||||
|
List<TemplateInfo> mockData = new ArrayList<>();
|
||||||
|
|
||||||
|
TemplateInfo template1 = new TemplateInfo();
|
||||||
|
template1.setSenderKey("test_sender_key_001");
|
||||||
|
template1.setTemplateCode("TEST_TEMPLATE_001");
|
||||||
|
template1.setTemplateName("테스트 템플릿 001");
|
||||||
|
template1.setCreatedAt("2025-01-01 10:00:00");
|
||||||
|
template1.setModifiedAt("2025-01-01 10:00:00");
|
||||||
|
template1.setServiceStatus("REG(등록완료)");
|
||||||
|
|
||||||
|
TemplateInfo template2 = new TemplateInfo();
|
||||||
|
template2.setSenderKey("test_sender_key_001");
|
||||||
|
template2.setTemplateCode("TEST_TEMPLATE_002");
|
||||||
|
template2.setTemplateName("테스트 템플릿 002");
|
||||||
|
template2.setCreatedAt("2025-01-01 11:00:00");
|
||||||
|
template2.setModifiedAt("2025-01-01 11:00:00");
|
||||||
|
template2.setServiceStatus("REG(등록완료)");
|
||||||
|
|
||||||
|
TemplateInfo template3 = new TemplateInfo();
|
||||||
|
template3.setSenderKey("test_sender_key_002");
|
||||||
|
template3.setTemplateCode("TEST_TEMPLATE_003");
|
||||||
|
template3.setTemplateName("테스트 템플릿 003");
|
||||||
|
template3.setCreatedAt("2025-01-01 12:00:00");
|
||||||
|
template3.setModifiedAt("2025-01-01 12:00:00");
|
||||||
|
template3.setServiceStatus("REJ(반려)");
|
||||||
|
|
||||||
|
|
||||||
|
mockData.add(template1);
|
||||||
|
mockData.add(template2);
|
||||||
|
mockData.add(template3);
|
||||||
|
|
||||||
|
return new RestResponse(mockData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 템플릿 상세 조회 테스트 데이터 생성
|
||||||
|
*
|
||||||
|
* @param testYn 테스트 모드 (YS: 성공, YF: 실패)
|
||||||
|
* @return RestResponse 래핑된 테스트 데이터
|
||||||
|
*/
|
||||||
|
public static RestResponse getTemplateDetailTestData(String testYn) {
|
||||||
|
if ("YF".equals(testYn)) {
|
||||||
|
return new RestResponse(randomFail());
|
||||||
|
} else {
|
||||||
|
// 성공 테스트: 실제 API 응답 구조를 반영한 템플릿 상세 반환
|
||||||
|
TemplateDetail templateDetail = TemplateDetail.builder()
|
||||||
|
.block("false")
|
||||||
|
.categoryCode("0000000")
|
||||||
|
.createdAt("2024-08-29 10:10:06")
|
||||||
|
.dormant("false")
|
||||||
|
.inspectionStatus("APR")
|
||||||
|
.modifiedAt("2025-03-27 15:41:57")
|
||||||
|
.securityFlag("false")
|
||||||
|
.senderKey("test_sender_key_1215123251234234234")
|
||||||
|
.senderKeyType("S")
|
||||||
|
.status("A")
|
||||||
|
.templateCode("bizp_test_template_0000000000000000")
|
||||||
|
.templateContent("[테스트]\\n안녕하세요 #{이름}님\\n테스트 물건1 #{물건1}\\n테스트 물건2 #{물건2}\\n테스트 물건3 #{물건3}\\n테스트 물건4 #{물건4}\\n테스트 물건5 #{물건5}\\n테스트 물건6 #{물건6}\\n입니다.")
|
||||||
|
.templateEmphasizeType("NONE")
|
||||||
|
.templateExtra("")
|
||||||
|
.templateHeader("")
|
||||||
|
.templateImageName("")
|
||||||
|
.templateImageUrl("")
|
||||||
|
.templateMessageType("BA")
|
||||||
|
.templateName("테스트 변수 템플릿")
|
||||||
|
.templateSubtitle("")
|
||||||
|
.templateTitle("")
|
||||||
|
.templateItemHighlight(null)
|
||||||
|
.templateItem(null)
|
||||||
|
.buttons(new ArrayList<>())
|
||||||
|
.comments(createMockComments())
|
||||||
|
.quickReplies(new ArrayList<>())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return new RestResponse(templateDetail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 테스트용 Mock Comments 생성 헬퍼 메서드
|
||||||
|
* 실제 API 응답의 comments 구조를 반영
|
||||||
|
*/
|
||||||
|
private static List<TemplateComments> createMockComments() {
|
||||||
|
List<TemplateComments> comments = new ArrayList<>();
|
||||||
|
|
||||||
|
// 실제 API 응답과 유사한 comment 구조
|
||||||
|
TemplateComments comment = new TemplateComments();
|
||||||
|
comment.setContent("안녕하세요. 카카오톡 알림톡 검수 담당자입니다.\\r\\n\\r\\n테스트 템플릿으로 확인되어 승인합니다.\\r\\n\\r\\n감사합니다.");
|
||||||
|
comment.setCreatedAt("2024-08-29 13:44:13");
|
||||||
|
comment.setStatus("APR");
|
||||||
|
comment.setAttachment(new ArrayList<>());
|
||||||
|
|
||||||
|
comments.add(comment);
|
||||||
|
return comments;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# DB INFO
|
# DB INFO
|
||||||
spring.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
|
spring.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
|
||||||
spring.datasource.url=jdbc:log4jdbc:mysql://192.168.0.125:3306/mjon?serverTimezone=Asia/Seoul
|
spring.datasource.url=jdbc:log4jdbc:mysql://192.168.0.60:3308/mjon_advc?serverTimezone=Asia/Seoul
|
||||||
#spring.datasource.url=jdbc:log4jdbc:mysql://139.150.72.157:3306/mjon?serverTimezone=Asia/Seoul
|
#spring.datasource.url=jdbc:log4jdbc:mysql://139.150.72.157:3306/mjon?serverTimezone=Asia/Seoul
|
||||||
|
|
||||||
spring.datasource.username=mjonUr
|
spring.datasource.username=mjonUr
|
||||||
@ -10,11 +10,17 @@ spring.datasource.password=mjon!@#$
|
|||||||
|
|
||||||
server.port=8088
|
server.port=8088
|
||||||
|
|
||||||
#logging.level.root=info
|
# Logging Configuration
|
||||||
|
logging.level.root=info
|
||||||
|
logging.level.jdbc.sqltiming=info
|
||||||
|
logging.level.jdbc.resultset=info
|
||||||
|
logging.level.jdbc.resultsettable=info
|
||||||
|
logging.level.jdbc.sqlonly=debug
|
||||||
|
logging.level.jdbc.audit=warn
|
||||||
|
logging.level.jdbc.connection=warn
|
||||||
|
|
||||||
#??? ?? ??
|
#??? ?? ??
|
||||||
api.root.url=http://192.168.0.60:8085/
|
api.root.url=http://192.168.0.176:9080/
|
||||||
#api.root.url=https://www.munjaon.co.kr/
|
|
||||||
|
|
||||||
Ganpandaup.receiver.email=hylee250@kakao.com
|
Ganpandaup.receiver.email=hylee250@kakao.com
|
||||||
|
|
||||||
|
|||||||
30
src/main/resources/application-local.properties
Normal file
30
src/main/resources/application-local.properties
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
|
||||||
|
# DB INFO
|
||||||
|
spring.datasource.driverClassName=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
|
||||||
|
spring.datasource.url=jdbc:log4jdbc:mysql://192.168.0.60:3308/mjon_advc?serverTimezone=Asia/Seoul
|
||||||
|
#spring.datasource.url=jdbc:log4jdbc:mysql://139.150.72.157:3306/mjon?serverTimezone=Asia/Seoul
|
||||||
|
|
||||||
|
spring.datasource.username=mjonUr
|
||||||
|
spring.datasource.password=mjon!@#$
|
||||||
|
|
||||||
|
server.port=8088
|
||||||
|
|
||||||
|
# Logging Configuration
|
||||||
|
logging.level.root=info
|
||||||
|
logging.level.jdbc.sqltiming=info
|
||||||
|
logging.level.jdbc.resultset=info
|
||||||
|
logging.level.jdbc.resultsettable=info
|
||||||
|
logging.level.jdbc.sqlonly=debug
|
||||||
|
logging.level.jdbc.audit=warn
|
||||||
|
logging.level.jdbc.connection=warn
|
||||||
|
|
||||||
|
#??? ?? ??
|
||||||
|
api.root.url=http://localhost:8080/
|
||||||
|
#api.root.url=http://192.168.0.60:8085/
|
||||||
|
#api.root.url=https://www.munjaon.co.kr/
|
||||||
|
|
||||||
|
Ganpandaup.receiver.email=hylee250@kakao.com
|
||||||
|
|
||||||
|
|
||||||
|
server.tomcat.ajp.port=8009
|
||||||
@ -1,12 +1,14 @@
|
|||||||
|
|
||||||
|
|
||||||
spring.profiles.active=dev
|
spring.profiles.active=local
|
||||||
|
|
||||||
|
|
||||||
# mybatis setting
|
# mybatis setting
|
||||||
|
mybatis.config-location=classpath:mybatis-config.xml
|
||||||
mybatis.mapper-locations=classpath:mapper/**/*.xml
|
mybatis.mapper-locations=classpath:mapper/**/*.xml
|
||||||
# model camel case set
|
|
||||||
mybatis.configuration.map-underscore-to-camel-case=true
|
spring.jackson.default-property-inclusion=non_null
|
||||||
|
|
||||||
|
|
||||||
#sql \ucd9c\ub825 log \uc124\uc815
|
#sql \ucd9c\ub825 log \uc124\uc815
|
||||||
logging.level.jdbc.sqlonly=off
|
logging.level.jdbc.sqlonly=off
|
||||||
@ -34,4 +36,21 @@ spring.servlet.multipart.max-request-size=20MB
|
|||||||
#management.endpoints.web.exposure.include=*
|
#management.endpoints.web.exposure.include=*
|
||||||
#management.endpoint.health.show-details=always
|
#management.endpoint.health.show-details=always
|
||||||
#
|
#
|
||||||
Ganpandaup.estimate.template.url=https://www.munjaon.co.kr/publish/email_form_ganpandaum_contact.html
|
Ganpandaup.estimate.template.url=https://www.munjaon.co.kr/publish/email_form_ganpandaum_contact.html
|
||||||
|
|
||||||
|
|
||||||
|
biz.root.url=https://kapi.ppurio.com
|
||||||
|
biz.api.key=dheBWCONP6J5
|
||||||
|
biz.id=itn0202
|
||||||
|
|
||||||
|
|
||||||
|
# ?? ?? actuator ?? ???? ?? ?
|
||||||
|
# management.server.port=8081
|
||||||
|
|
||||||
|
# actuator base path ?? (???: /actuator)
|
||||||
|
# management.endpoints.web.base-path=/manage
|
||||||
|
|
||||||
|
# health ?? ?? ??
|
||||||
|
management.endpoint.health.show-details=always
|
||||||
|
# actuator endpoint ?? ??
|
||||||
|
management.endpoints.web.exposure.include=health,info,metrics
|
||||||
|
|||||||
@ -1,2 +1,20 @@
|
|||||||
|
# log4jdbc 설정
|
||||||
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
|
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
|
||||||
log4jdbc.dump.sql.maxlinelength=0
|
|
||||||
|
# SQL 출력 설정
|
||||||
|
log4jdbc.dump.sql.maxlinelength=0
|
||||||
|
log4jdbc.trim.sql=true
|
||||||
|
log4jdbc.trim.sql.extrablanklines=false
|
||||||
|
|
||||||
|
# ResultSet 출력 활성화 (가장 중요한 설정)
|
||||||
|
log4jdbc.dump.sql.select=true
|
||||||
|
log4jdbc.dump.sql.insert=true
|
||||||
|
log4jdbc.dump.sql.update=true
|
||||||
|
log4jdbc.dump.sql.delete=true
|
||||||
|
|
||||||
|
# ResultSet 테이블 형태 출력을 위한 추가 설정
|
||||||
|
log4jdbc.dump.fulldebugstacktrace=false
|
||||||
|
log4jdbc.suppress.generated.keys.exception=false
|
||||||
|
|
||||||
|
# 에러 억제 설정
|
||||||
|
log4jdbc.auto.load.popular.drivers=false
|
||||||
@ -81,6 +81,23 @@
|
|||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!-- Loggers -->
|
<!-- Loggers -->
|
||||||
|
|
||||||
|
<!-- log4jdbc 로거 설정 - SQL 쿼리와 결과값 출력 -->
|
||||||
|
<logger name="jdbc.sqltiming" level="INFO" additivity="false">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</logger>
|
||||||
|
<logger name="jdbc.sqlonly" level="DEBUG" additivity="false">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</logger>
|
||||||
|
<logger name="jdbc.audit" level="WARN" />
|
||||||
|
<logger name="jdbc.resultset" level="DEBUG" additivity="false">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</logger>
|
||||||
|
<logger name="jdbc.resultsettable" level="DEBUG" additivity="false">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</logger>
|
||||||
|
<logger name="jdbc.connection" level="WARN" />
|
||||||
|
|
||||||
<!-- <logger name="org.apache.catalina" level="ERROR">
|
<!-- <logger name="org.apache.catalina" level="ERROR">
|
||||||
</logger>
|
</logger>
|
||||||
|
|
||||||
|
|||||||
@ -1,38 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
|
|
||||||
<mapper namespace="com.itn.mjonApi.mjon.api.inqry.mapper.PriceMapper">
|
|
||||||
|
|
||||||
<select id="selectMberMoney"
|
|
||||||
resultType="double"
|
|
||||||
>
|
|
||||||
|
|
||||||
SELECT a.USER_MONEY AS mberMoney
|
|
||||||
FROM lettngnrlmber a
|
|
||||||
WHERE a.MBER_ID = #{mberId}
|
|
||||||
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<select id="selectMberPriceInfo"
|
|
||||||
resultType="hashmap"
|
|
||||||
>
|
|
||||||
|
|
||||||
SELECT a.SHORT_PRICE AS sysShortPrice,
|
|
||||||
a.LONG_PRICE AS sysLongPrice,
|
|
||||||
a.PICTURE_PRICE AS sysPicturePrice,
|
|
||||||
a.PICTURE2_PRICE AS sysPicturePrice2,
|
|
||||||
a.PICTURE3_PRICE AS sysPicturePrice3,
|
|
||||||
b.SHORT_PRICE AS shortPrice,
|
|
||||||
b.LONG_PRICE AS longPrice,
|
|
||||||
b.PICTURE_PRICE AS picturePrice,
|
|
||||||
b.PICTURE2_PRICE AS picturePrice2,
|
|
||||||
b.PICTURE3_PRICE AS picturePrice3
|
|
||||||
FROM mj_mber_setting a ,
|
|
||||||
lettngnrlmber b
|
|
||||||
WHERE b.mber_id = #{mberId}
|
|
||||||
|
|
||||||
</select>
|
|
||||||
|
|
||||||
</mapper>
|
|
||||||
43
src/main/resources/mapper/api/kakao/inqry/InqryMapper.xml
Normal file
43
src/main/resources/mapper/api/kakao/inqry/InqryMapper.xml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
|
<mapper namespace="com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.InqryMapper">
|
||||||
|
|
||||||
|
<select id="getChnlIds" resultType="com.itn.mjonApi.mjon.api.kakao.at.inqry.mapper.domain.MjKakaoProfileInfoVO">
|
||||||
|
/* kakao at getChnlIds */
|
||||||
|
SELECT
|
||||||
|
-- USER_ID
|
||||||
|
-- , PROFILE_ID
|
||||||
|
SENDER_KEY
|
||||||
|
-- , TOKEN
|
||||||
|
, PHONE_NUMBER
|
||||||
|
, YELLOW_ID
|
||||||
|
-- , CATEGORY_CODE
|
||||||
|
-- , CATEGORY_NAME
|
||||||
|
, FRST_REGIST_PNTTM
|
||||||
|
, FRST_REGISTER_ID
|
||||||
|
-- , LAST_UPDT_PNTTM
|
||||||
|
-- , LAST_UPDUSR_ID
|
||||||
|
-- , DELETE_YN
|
||||||
|
FROM mj_kakao_profile_info
|
||||||
|
WHERE DELETE_YN = 'N'
|
||||||
|
AND USER_ID = #{mberId}
|
||||||
|
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="isTemplateExist" parameterType="map" resultType="int">
|
||||||
|
/* kakao at isTemplateExist */
|
||||||
|
SELECT
|
||||||
|
COUNT(*)
|
||||||
|
FROM
|
||||||
|
mj_kakao_profile_info
|
||||||
|
WHERE
|
||||||
|
SENDER_KEY = #{senderKey}
|
||||||
|
AND TEMPLATE_CODE = #{templateCode}
|
||||||
|
AND DELETE_YN = 'N'
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -3,9 +3,9 @@
|
|||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
<mapper namespace="com.itn.mjonApi.mjon.api.inqry.mapper.HstryMapper">
|
<mapper namespace="com.itn.mjonApi.mjon.api.msg.inqry.mapper.HstryMapper">
|
||||||
|
|
||||||
<select id="selectApiInqryHstry" resultType="com.itn.mjonApi.mjon.api.inqry.service.mapper.domain.MjonResponseVO">
|
<select id="selectApiInqryHstry" resultType="com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.MjonResponseVO">
|
||||||
|
|
||||||
/* 문자온 발송결과 페이지 쿼리를 그대로 사용함 - http://localhost:9080/web/mjon/msgsent/selectMsgSentView.do */
|
/* 문자온 발송결과 페이지 쿼리를 그대로 사용함 - http://localhost:9080/web/mjon/msgsent/selectMsgSentView.do */
|
||||||
SELECT
|
SELECT
|
||||||
@ -102,23 +102,21 @@
|
|||||||
A.RSLT_CODE ,
|
A.RSLT_CODE ,
|
||||||
A.RSLT_CODE2 ,
|
A.RSLT_CODE2 ,
|
||||||
CASE
|
CASE
|
||||||
WHEN B.MSG_TYPE = '6'
|
WHEN B.MSG_TYPE = '6' AND B.FILE_CNT > 0 THEN '그림(MMS)'
|
||||||
AND B.FILE_CNT > 0
|
WHEN B.MSG_TYPE = '6' AND B.FILE_CNT = 0 THEN '장문(LMS)'
|
||||||
THEN '그림(MMS)'
|
WHEN B.MSG_TYPE = '4' THEN '단문(SMS)'
|
||||||
WHEN B.MSG_TYPE = '6'
|
WHEN B.MSG_TYPE = '8' THEN '알림톡(AT)'
|
||||||
AND B.FILE_CNT = 0
|
WHEN B.MSG_TYPE = '9' THEN '친구톡(FT)'
|
||||||
THEN '장문(LMS)'
|
ELSE '기타'
|
||||||
ELSE '단문(SMS)'
|
END msgTypeName ,
|
||||||
END msgTypeName ,
|
|
||||||
CASE
|
CASE
|
||||||
WHEN B.MSG_TYPE = '6'
|
WHEN B.MSG_TYPE = '6' AND B.FILE_CNT > 0 THEN '3'
|
||||||
AND B.FILE_CNT > 0
|
WHEN B.MSG_TYPE = '6' AND B.FILE_CNT = 0 THEN '2'
|
||||||
THEN '3'
|
WHEN B.MSG_TYPE = '4' THEN '1'
|
||||||
WHEN B.MSG_TYPE = '6'
|
WHEN B.MSG_TYPE = '8' THEN '4'
|
||||||
AND B.FILE_CNT = 0
|
WHEN B.MSG_TYPE = '9' THEN '5'
|
||||||
THEN '2'
|
ELSE '9'
|
||||||
ELSE '1'
|
END orderByCode ,(
|
||||||
END orderByCode , (
|
|
||||||
CASE
|
CASE
|
||||||
WHEN A.AGENT_CODE = '01'
|
WHEN A.AGENT_CODE = '01'
|
||||||
AND
|
AND
|
||||||
@ -182,14 +180,23 @@
|
|||||||
AND DATE_ADD(NOW(), INTERVAL 60 MINUTE) >= B.REQ_DATE
|
AND DATE_ADD(NOW(), INTERVAL 60 MINUTE) >= B.REQ_DATE
|
||||||
|
|
||||||
<if test="startDate != null and startDate != ''">
|
<if test="startDate != null and startDate != ''">
|
||||||
AND b.regdate >= STR_TO_DATE(CONCAT(#{startDate}, '000000'), '%Y%m%d%H%i%s')
|
AND (
|
||||||
|
(b.regdate <![CDATA[ >= ]]> STR_TO_DATE(CONCAT(#{startDate}, '000000'), '%Y%m%d%H%i%s'))
|
||||||
|
OR
|
||||||
|
(b.req_date <![CDATA[ >= ]]> STR_TO_DATE(CONCAT(#{startDate}, '000000'), '%Y%m%d%H%i%s'))
|
||||||
|
)
|
||||||
</if>
|
</if>
|
||||||
<if test="startDate == null or startDate == ''">
|
<if test="startDate == null or startDate == ''">
|
||||||
AND b.regdate >= STR_TO_DATE(date_format(now(),'%Y%m%d000000'), '%Y%m%d%H%i%s')
|
<!-- AND b.regdate >= STR_TO_DATE(date_format(now(),'%Y%m%d000000'), '%Y%m%d%H%i%s')-->
|
||||||
|
AND b.regdate <![CDATA[ < ]]> DATE_ADD(CURDATE(), INTERVAL 1 DAY)
|
||||||
</if>
|
</if>
|
||||||
|
|
||||||
<if test="endDate != null and endDate != ''">
|
<if test="endDate != null and endDate != ''">
|
||||||
AND STR_TO_DATE(CONCAT(#{endDate}, '235959'), '%Y%m%d%H%i%s') >= b.regdate
|
AND (
|
||||||
|
(b.regdate <![CDATA[ <= ]]> STR_TO_DATE(CONCAT(#{endDate}, '235959'), '%Y%m%d%H%i%s'))
|
||||||
|
OR
|
||||||
|
(b.req_date <![CDATA[ <= ]]> STR_TO_DATE(CONCAT(#{endDate}, '235959'), '%Y%m%d%H%i%s'))
|
||||||
|
)
|
||||||
</if>
|
</if>
|
||||||
<if test="startDate == null or startDate == ''">
|
<if test="startDate == null or startDate == ''">
|
||||||
AND STR_TO_DATE(date_format(DATE_ADD(NOW(), INTERVAL 1 day),'%Y%m%d000000'), '%Y%m%d%H%i%s') >= b.regdate
|
AND STR_TO_DATE(date_format(DATE_ADD(NOW(), INTERVAL 1 day),'%Y%m%d000000'), '%Y%m%d%H%i%s') >= b.regdate
|
||||||
@ -214,7 +221,10 @@
|
|||||||
'2',
|
'2',
|
||||||
'3')
|
'3')
|
||||||
AND MSG_TYPE IN ('4',
|
AND MSG_TYPE IN ('4',
|
||||||
'6')
|
'6',
|
||||||
|
'8',
|
||||||
|
'9'
|
||||||
|
)
|
||||||
GROUP BY MSG_GROUP_ID
|
GROUP BY MSG_GROUP_ID
|
||||||
/*
|
/*
|
||||||
ORDER BY 1=1,
|
ORDER BY 1=1,
|
||||||
@ -301,7 +311,10 @@
|
|||||||
WHERE 1 =1
|
WHERE 1 =1
|
||||||
AND MD.DEL_FLAG = 'N'
|
AND MD.DEL_FLAG = 'N'
|
||||||
AND MD.MSG_TYPE IN ('4',
|
AND MD.MSG_TYPE IN ('4',
|
||||||
'6')
|
'6',
|
||||||
|
'8',
|
||||||
|
'9'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
A
|
A
|
||||||
GROUP BY A.MSG_GROUP_ID,
|
GROUP BY A.MSG_GROUP_ID,
|
||||||
@ -336,7 +349,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<select id="selectApiInqryHstryDetail"
|
<select id="selectApiInqryHstryDetail"
|
||||||
resultType="com.itn.mjonApi.mjon.api.inqry.service.mapper.domain.MjonResponseVO"
|
resultType="com.itn.mjonApi.mjon.api.msg.inqry.mapper.domain.MjonResponseVO"
|
||||||
>
|
>
|
||||||
|
|
||||||
/* 문자온 발송결과 페이지 실패 건수 팝업을 변형해서 사용함 - http://localhost:9080/web/mjon/msgsent/selectMsgSFDetailListAjax.do */
|
/* 문자온 발송결과 페이지 실패 건수 팝업을 변형해서 사용함 - http://localhost:9080/web/mjon/msgsent/selectMsgSFDetailListAjax.do */
|
||||||
@ -366,24 +379,23 @@
|
|||||||
DEL_FLAG AS delFlag ,
|
DEL_FLAG AS delFlag ,
|
||||||
*/
|
*/
|
||||||
MSG_TYPE AS msgType ,
|
MSG_TYPE AS msgType ,
|
||||||
|
|
||||||
|
|
||||||
|
CASE
|
||||||
|
WHEN MSG_TYPE = '6' AND FILE_CNT > 0 THEN '그림(MMS)'
|
||||||
|
WHEN MSG_TYPE = '6' AND FILE_CNT = 0 THEN '장문(LMS)'
|
||||||
|
WHEN MSG_TYPE = '4' THEN '단문(SMS)'
|
||||||
|
WHEN MSG_TYPE = '8' THEN '알림톡(AT)'
|
||||||
|
WHEN MSG_TYPE = '9' THEN '친구톡(FT)'
|
||||||
|
ELSE '기타'
|
||||||
|
END msgTypeName ,
|
||||||
CASE
|
CASE
|
||||||
WHEN MSG_TYPE = '6'
|
WHEN MSG_TYPE = '6' AND FILE_CNT > 0 THEN '3'
|
||||||
AND FILE_CNT > 0
|
WHEN MSG_TYPE = '6' AND FILE_CNT = 0 THEN '2'
|
||||||
THEN '그림(MMS)'
|
WHEN MSG_TYPE = '4' THEN '1'
|
||||||
WHEN MSG_TYPE = '6'
|
WHEN MSG_TYPE = '8' THEN '4'
|
||||||
AND FILE_CNT = 0
|
WHEN MSG_TYPE = '9' THEN '5'
|
||||||
THEN '장문(LMS)'
|
ELSE '9'
|
||||||
ELSE '단문(SMS)'
|
|
||||||
END msgTypeName ,
|
|
||||||
CASE
|
|
||||||
WHEN MSG_TYPE = '6'
|
|
||||||
AND FILE_CNT > 0
|
|
||||||
THEN '3'
|
|
||||||
WHEN MSG_TYPE = '6'
|
|
||||||
AND FILE_CNT = 0
|
|
||||||
THEN '2'
|
|
||||||
ELSE '1'
|
|
||||||
END orderByCode ,
|
END orderByCode ,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
46
src/main/resources/mapper/api/msg/inqry/PriceMapper.xml
Normal file
46
src/main/resources/mapper/api/msg/inqry/PriceMapper.xml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
|
<mapper namespace="com.itn.mjonApi.mjon.api.msg.inqry.mapper.PriceMapper">
|
||||||
|
|
||||||
|
<select id="selectMberMoney"
|
||||||
|
resultType="double"
|
||||||
|
>
|
||||||
|
|
||||||
|
SELECT a.USER_MONEY AS mberMoney
|
||||||
|
FROM lettngnrlmber a
|
||||||
|
WHERE a.MBER_ID = #{mberId}
|
||||||
|
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectMberPriceInfo"
|
||||||
|
resultType="hashmap"
|
||||||
|
>
|
||||||
|
|
||||||
|
SELECT a.SHORT_PRICE AS sysShortPrice
|
||||||
|
, a.LONG_PRICE AS sysLongPrice
|
||||||
|
, a.PICTURE_PRICE AS sysPicturePrice
|
||||||
|
, a.PICTURE2_PRICE AS sysPicturePrice2
|
||||||
|
, a.PICTURE3_PRICE AS sysPicturePrice3
|
||||||
|
, a.KAKAO_AT_PRICE AS sysKakaoAtPrice
|
||||||
|
, a.KAKAO_FT_PRICE AS sysKakaoFtPrice
|
||||||
|
, a.KAKAO_FT_IMG_PRICE AS sysKakaoFtImgPrice
|
||||||
|
, a.KAKAO_FT_WIDE_IMG_PRICE AS sysKakaoFtWideImgPrice
|
||||||
|
, b.SHORT_PRICE AS shortPrice
|
||||||
|
, b.LONG_PRICE AS longPrice
|
||||||
|
, b.PICTURE_PRICE AS picturePrice
|
||||||
|
, b.PICTURE2_PRICE AS picturePrice2
|
||||||
|
, b.PICTURE3_PRICE AS picturePrice3
|
||||||
|
, b.KAKAO_AT_PRICE AS kakaoAtPrice
|
||||||
|
, b.KAKAO_FT_PRICE AS kakaoFtPrice
|
||||||
|
, b.KAKAO_FT_IMG_PRICE AS kakaoFtImgPrice
|
||||||
|
, b.KAKAO_FT_WIDE_IMG_PRICE AS kakaoFtWideImgPrice
|
||||||
|
FROM mj_mber_setting a ,
|
||||||
|
lettngnrlmber b
|
||||||
|
WHERE b.mber_id = #{mberId}
|
||||||
|
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@ -3,7 +3,7 @@
|
|||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
|
||||||
<mapper namespace="com.itn.mjonApi.mjon.api.send.mapper.SendMapper">
|
<mapper namespace="com.itn.mjonApi.mjon.api.msg.send.mapper.SendMapper">
|
||||||
|
|
||||||
<select id="findByCallFrom" resultType="boolean">
|
<select id="findByCallFrom" resultType="boolean">
|
||||||
SELECT IF(COUNT(*), 1, 0)
|
SELECT IF(COUNT(*), 1, 0)
|
||||||
14
src/main/resources/mybatis-config.xml
Normal file
14
src/main/resources/mybatis-config.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE configuration
|
||||||
|
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||||
|
|
||||||
|
<configuration>
|
||||||
|
<settings>
|
||||||
|
<setting name="mapUnderscoreToCamelCase" value="true"/>
|
||||||
|
</settings>
|
||||||
|
|
||||||
|
<typeAliases>
|
||||||
|
<package name="com.itn.mjonApi.mjon.api.kakao.inqry.mapper.domain"/>
|
||||||
|
</typeAliases>
|
||||||
|
</configuration>
|
||||||
Loading…
Reference in New Issue
Block a user