From 11eb6238fa9cd3f3e34679be910e1c7cf58ad9fb Mon Sep 17 00:00:00 2001 From: "Jonguk. Lim" Date: Tue, 10 Sep 2024 17:50:32 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=B9=B4=EC=B9=B4=EC=98=A4=ED=86=A1=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=98=EC=98=81=20-=20send,=20status?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cokr/xit/ens/core/aop/EnsResponseVO.java | 18 +- .../xit/ens/modules/kkotalk/ApiConstants.java | 8 +- .../domain/SendDetailKkoTalkStatHist.java | 10 +- .../kkotalk/mapper/IKkoTalkMapper.java | 6 +- .../modules/kkotalk/model/KkotalkApiDTO.java | 10 +- .../ens/modules/kkotalk/model/KkotalkDTO.java | 6 +- .../kkotalk/service/KkoTalkService.java | 90 ++-- .../service/support/KkoTalkApiService.java | 172 ++---- .../service/support/KkoTalkRsltFetcher.java | 189 +++---- .../service/support/KkoTalkSender.java | 33 +- .../kkotalk/web/KkotalkApiController.java | 500 +++++++++--------- .../modules/iup-kkotalk-mapper.xml | 28 +- 12 files changed, 482 insertions(+), 588 deletions(-) diff --git a/src/main/java/cokr/xit/ens/core/aop/EnsResponseVO.java b/src/main/java/cokr/xit/ens/core/aop/EnsResponseVO.java index 5b5aebd..3081569 100644 --- a/src/main/java/cokr/xit/ens/core/aop/EnsResponseVO.java +++ b/src/main/java/cokr/xit/ens/core/aop/EnsResponseVO.java @@ -1,21 +1,17 @@ package cokr.xit.ens.core.aop; -import com.fasterxml.jackson.annotation.JsonAlias; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.gson.annotations.SerializedName; +import com.fasterxml.jackson.annotation.*; +import com.google.gson.annotations.*; -import cokr.xit.ens.core.exception.code.EnsErrCd; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.ToString; +import cokr.xit.ens.core.exception.code.*; +import io.swagger.v3.oas.annotations.media.*; +import lombok.*; @Getter @ToString @Schema(name = "EnsResponseVO") @NoArgsConstructor -public class EnsResponseVO implements IApiResponse { +public class EnsResponseVO { @Schema(required = true, title = "에러 코드", example = " ") @JsonProperty("errCode") @@ -34,7 +30,7 @@ public class EnsResponseVO implements IApiResponse { @JsonAlias({"result_info"}) @SerializedName(value = "resultInfo", alternate = {"result_info"}) private T resultInfo; - + @Builder(builderClassName = "okBuilder" ,builderMethodName = "okBuilder") EnsResponseVO(T resultInfo) { this.errCode = EnsErrCd.OK; diff --git a/src/main/java/cokr/xit/ens/modules/kkotalk/ApiConstants.java b/src/main/java/cokr/xit/ens/modules/kkotalk/ApiConstants.java index 726b412..b770edf 100644 --- a/src/main/java/cokr/xit/ens/modules/kkotalk/ApiConstants.java +++ b/src/main/java/cokr/xit/ens/modules/kkotalk/ApiConstants.java @@ -1,9 +1,9 @@ package cokr.xit.ens.modules.kkotalk; -import java.util.Arrays; +import java.util.*; -import cokr.xit.ens.core.exception.BizRuntimeException; -import lombok.Getter; +import cokr.xit.ens.core.exception.*; +import lombok.*; /** *
@@ -29,7 +29,7 @@ public class ApiConstants {
     /**
      * profile : local 여부
      */
-    public static final boolean IS_PROFILE_LOCAL = PROFILE.matches("local-.*");
+    public static final boolean IS_PROFILE_LOCAL = PROFILE.matches("local.*");
 
     /**
      * profile : 춘천 시스템 여부
diff --git a/src/main/java/cokr/xit/ens/modules/kkotalk/domain/SendDetailKkoTalkStatHist.java b/src/main/java/cokr/xit/ens/modules/kkotalk/domain/SendDetailKkoTalkStatHist.java
index 87b6f63..77b2486 100644
--- a/src/main/java/cokr/xit/ens/modules/kkotalk/domain/SendDetailKkoTalkStatHist.java
+++ b/src/main/java/cokr/xit/ens/modules/kkotalk/domain/SendDetailKkoTalkStatHist.java
@@ -66,20 +66,22 @@ public class SendDetailKkoTalkStatHist {
     private String authenticatedAt;
 
 
-    @Column(name = "token_used_at", nullable = true)
-    private Long tokenUsedAt;
+    @Column(name = "ott_verified_at", nullable = true)
+    private String ottVerifiedAt;
 
 
     @Column(name = "read_at", nullable = true)
     private String readAt;
 
+    @Column(name = "read_expired_at", nullable = true)
+    private String readExpiredAt;
 
     @Column(name = "user_notified_at", nullable = true)
-    private Long userNotifiedAt;
+    private String userNotifiedAt;
 
 
     @Column(name = "distribution_received_at", nullable = true)
-    private String docDistributionReceivedAt;//???
+    private String distributionReceivedAt;//???
 
 
     @Column(name = "payload", nullable = true)
diff --git a/src/main/java/cokr/xit/ens/modules/kkotalk/mapper/IKkoTalkMapper.java b/src/main/java/cokr/xit/ens/modules/kkotalk/mapper/IKkoTalkMapper.java
index ed03c4d..a16393e 100644
--- a/src/main/java/cokr/xit/ens/modules/kkotalk/mapper/IKkoTalkMapper.java
+++ b/src/main/java/cokr/xit/ens/modules/kkotalk/mapper/IKkoTalkMapper.java
@@ -5,7 +5,6 @@ import java.util.*;
 import org.apache.ibatis.annotations.*;
 
 import cokr.xit.ens.modules.common.domain.*;
-import cokr.xit.ens.modules.kkomydoc.domain.*;
 import cokr.xit.ens.modules.kkotalk.model.*;
 
 /**
@@ -29,6 +28,8 @@ public interface IKkoTalkMapper {
     void updateSndDtlKkoTalk(SendDetailKkoTalkDTO sendDetailKkoTalk);
     void updateKakaotalkSendBulksResult(SendDetailKkoTalkDTO sendDetailKkoTalk);
 
+    void updateKakaotalkStatusBulksResult(SendDetailKkoTalkDTO sendDetailKkoTalkDTO);
+
     List findAllBySendMastId(Long sendMastId);
 
 
@@ -37,5 +38,6 @@ public interface IKkoTalkMapper {
 
     List findAllBySendMastAndEnvlopeIdIsNotNull(SendMast sendMast);
 
-    Optional findByExternalId(String externalId);
+    //Optional findByExternalId(String externalId);
+
 }
diff --git a/src/main/java/cokr/xit/ens/modules/kkotalk/model/KkotalkApiDTO.java b/src/main/java/cokr/xit/ens/modules/kkotalk/model/KkotalkApiDTO.java
index 0d8718a..17a3c1a 100644
--- a/src/main/java/cokr/xit/ens/modules/kkotalk/model/KkotalkApiDTO.java
+++ b/src/main/java/cokr/xit/ens/modules/kkotalk/model/KkotalkApiDTO.java
@@ -7,7 +7,6 @@ import org.hibernate.validator.constraints.NotEmpty;
 
 import com.fasterxml.jackson.annotation.*;
 
-import cokr.xit.ens.core.aop.*;
 import cokr.xit.ens.modules.kkotalk.*;
 import io.swagger.v3.oas.annotations.media.*;
 import lombok.*;
@@ -190,7 +189,7 @@ public class KkotalkApiDTO {
     @NoArgsConstructor
     @AllArgsConstructor
     @EqualsAndHashCode(callSuper = false)
-    public static class ValidTokenRequest extends CmmEnsRequestDTO {
+    public static class ValidTokenRequest {
         /**
          * 문서 고유 ID, 34자로 고정
          */
@@ -212,7 +211,7 @@ public class KkotalkApiDTO {
     @NoArgsConstructor
     @AllArgsConstructor
     @EqualsAndHashCode(callSuper = true)
-    public static class ValidTokenResponse extends KkotalkErrorDTO implements IApiResponse {
+    public static class ValidTokenResponse extends KkotalkErrorDTO {
         /**
          * 문서 고유 ID, 34자로 고정
          */
@@ -231,7 +230,6 @@ public class KkotalkApiDTO {
          * 수신,미열람|열람|최초열람만료일시 또는 재열람 만료일시 초과
          * RECEIVE|READ|EXPIRED
          * 
- * @see ApiConstants.KkotalkDocStatus */ private ApiConstants.KkotalkDocStatus status; @@ -305,7 +303,7 @@ public class KkotalkApiDTO { @AllArgsConstructor @JsonInclude(JsonInclude.Include.NON_EMPTY) @EqualsAndHashCode(callSuper = true) - public static class EnvelopeStatusResponse extends ValidTokenResponse implements IApiResponse { + public static class EnvelopeStatusResponse extends ValidTokenResponse { /** /** *
          * 문서 열람 만료 일시
@@ -401,7 +399,7 @@ public class KkotalkApiDTO {
     @AllArgsConstructor
     @SuperBuilder
     @EqualsAndHashCode(callSuper = false)
-    public static class EnvelopeId extends CmmEnsRequestDTO{
+    public static class EnvelopeId {
         /**
          * 문서 고유 ID, 34자로 고정
          */
diff --git a/src/main/java/cokr/xit/ens/modules/kkotalk/model/KkotalkDTO.java b/src/main/java/cokr/xit/ens/modules/kkotalk/model/KkotalkDTO.java
index 029cf68..a52164b 100644
--- a/src/main/java/cokr/xit/ens/modules/kkotalk/model/KkotalkDTO.java
+++ b/src/main/java/cokr/xit/ens/modules/kkotalk/model/KkotalkDTO.java
@@ -36,7 +36,7 @@ public class KkotalkDTO extends KkotalkApiDTO {
     @AllArgsConstructor
     @SuperBuilder
     @EqualsAndHashCode(callSuper = false)
-    public static class SendRequest extends CmmEnsRequestDTO {
+    public static class SendRequest {
         /**
          * 
          * 상품 코드 - 필수
@@ -60,7 +60,7 @@ public class KkotalkDTO extends KkotalkApiDTO {
     @AllArgsConstructor
     @SuperBuilder
     @EqualsAndHashCode(callSuper = false)
-    public static class BulkSendRequest extends CmmEnsRequestDTO {
+    public static class BulkSendRequest {
         /**
          * 
          * 상품 코드 - 필수
@@ -92,7 +92,7 @@ public class KkotalkDTO extends KkotalkApiDTO {
     @AllArgsConstructor
     @SuperBuilder
     @EqualsAndHashCode(callSuper = false)
-    public static class BulkStatusRequest extends CmmEnsRequestDTO {
+    public static class BulkStatusRequest {
         @Schema(requiredMode = Schema.RequiredMode.REQUIRED)
         @Valid
         private List envelopes;
diff --git a/src/main/java/cokr/xit/ens/modules/kkotalk/service/KkoTalkService.java b/src/main/java/cokr/xit/ens/modules/kkotalk/service/KkoTalkService.java
index 5e71add..997e471 100644
--- a/src/main/java/cokr/xit/ens/modules/kkotalk/service/KkoTalkService.java
+++ b/src/main/java/cokr/xit/ens/modules/kkotalk/service/KkoTalkService.java
@@ -4,10 +4,12 @@ import java.time.*;
 import java.util.*;
 import java.util.stream.*;
 
-import org.apache.commons.lang.*;
+import org.springframework.http.*;
 import org.springframework.stereotype.*;
 import org.springframework.transaction.annotation.*;
 
+import com.google.gson.*;
+
 import cokr.xit.ens.core.aop.*;
 import cokr.xit.ens.core.exception.*;
 import cokr.xit.ens.core.exception.code.*;
@@ -305,54 +307,40 @@ public class KkoTalkService {
             OrgMng orgMng = orgMngService.find(orgCd).getResultInfo();
 
             // FIXME: 카카오톡 토큰검증 API 처리
-            KkotalkApiDTO.ValidTokenResponse resp = kkoTalkApi.validToken(
+            ResponseEntity resp = kkoTalkApi.validToken(
+                orgMng,
                 KkotalkApiDTO.ValidTokenRequest.builder()
-                    .signguCode(orgMng.getOrgCd())
-                    .ffnlgCode("11")
                     .envelopeId(envelopId)
                     .token(token)
                     .build()
             );
 
-            if (!StringUtils.isEmpty(resp.getErrorCode())){
-                responseVO = EnsResponseVO.errRsltBuilder()
-                    .errCode(EnsErrCd.ERR600)
-                    .errMsg(String.format("%s %s", resp.getErrorCode(), resp.getErrorMessage()))
-                    .resultInfo(resp)
-                    .build();
-            }else {
+            if (resp.getStatusCode() != HttpStatus.OK)
+                throw new EnsException(EnsErrCd.ERR620, String.format("토큰검증 실패. 실패사유: %s %s", resp.getStatusCode().toString(), resp.getBody()));
 
-                responseVO = EnsResponseVO.okBuilder()
-                    .resultInfo(resp)
-                    .build();
+            Map mResponse = null;
+            try {
+                Gson gson = new GsonBuilder().disableHtmlEscaping().registerTypeAdapter(Map.class, new MapDeserailizer()).serializeNulls().create();
+                mResponse = gson.fromJson(resp.getBody(), Map.class);
+            } catch (Exception e) {
+                throw new EnsException(EnsErrCd.ERR505, String.format("토큰검증 응답데이터 파싱 실패. %s", resp.getBody()));
             }
 
-            // ResponseEntity resp = kkoMydocApi.token(orgMng.getKkoMdAccessToken(), documentBinderUuid, token);
-            // if (resp.getStatusCode() != HttpStatus.OK)
-            //     throw new EnsException(EnsErrCd.ERR620, String.format("토큰검증 실패. 실패사유: %s %s", resp.getStatusCode().toString(), resp.getBody()));
-
-            // Map mResponse = null;
-            // try {
-            //     Gson gson = new GsonBuilder().disableHtmlEscaping().registerTypeAdapter(Map.class, new MapDeserailizer()).serializeNulls().create();
-            //     mResponse = gson.fromJson(resp.getBody(), Map.class);
-            // } catch (Exception e) {
-            //     throw new EnsException(EnsErrCd.ERR505, String.format("토큰검증 응답데이터 파싱 실패. %s", resp.getBody()));
-            // }
-
-            // String tokenUsedAt = (String) mResponse.get("token_status");
-            // if ("USED".equals(tokenUsedAt)) {
-            //     responseVO = EnsResponseVO.okBuilder()
-            //             .resultInfo(mResponse)
-            //             .build();
-            // } else {
-            //     String errorCode = (String) mResponse.get("error_code");
-            //     String errorMessage = (String) mResponse.get("error_message");
-            //     responseVO = EnsResponseVO.errRsltBuilder()
-            //             .errCode(EnsErrCd.ERR600)
-            //             .errMsg(String.format("%s %s", errorCode, errorMessage))
-            //             .resultInfo(mResponse)
-            //             .build();
-            // }
+            // FIXME: 카카오톡 적용 확인
+            String envelopeStatus = (String) mResponse.get("envelopeStatus");
+            if (!CmmnUtil.isEmpty(envelopeStatus)) {
+                responseVO = EnsResponseVO.okBuilder()
+                        .resultInfo(mResponse)
+                        .build();
+            } else {
+                String errorCode = (String) mResponse.get("errorCode");
+                String errorMessage = (String) mResponse.get("errorMessage");
+                responseVO = EnsResponseVO.errRsltBuilder()
+                        .errCode(EnsErrCd.ERR600)
+                        .errMsg(String.format("%s %s", errorCode, errorMessage))
+                        .resultInfo(mResponse)
+                        .build();
+            }
 
 
         } catch (EnsException e) {
@@ -368,6 +356,7 @@ public class KkoTalkService {
         } finally {
             if (EnsErrCd.OK.equals(responseVO.getErrCode())) {
                 Map resultInfo = (Map) responseVO.getResultInfo();
+                // FIXME: 카카오톡 적용 확인 필요??
                 sendDetailKkoTalkTokenHistRepository.save(SendDetailKkoTalkTokenHist.builder()
                         .envelopeId(envelopId)
                         .envelopeId(externalId)
@@ -417,21 +406,28 @@ public class KkoTalkService {
             OrgMng orgMng = orgMngService.find(orgCd).getResultInfo();
 
             // FIXME: 카카오툭 토큰 확인 API 호출 처리
-            KkotalkApiDTO.KkotalkErrorDTO resp = kkoTalkApi.modifyStatus(
+            ResponseEntity resp = kkoTalkApi.modifyStatus(
+                orgMng,
                 KkotalkDTO.EnvelopeId.builder()
                     .envelopeId(envelopeId)
-                    .signguCode(orgMng.getOrgCd())
-                    .ffnlgCode("11")
-
                     .build()
             );
 
-            if (StringUtils.isEmpty(resp.getErrorCode())){
+            if (resp.getStatusCode().equals(HttpStatus.NO_CONTENT)) {
                 responseVO = EnsResponseVO.okBuilder().build();
-            }else{
+            } else {
+                Map mResponse = null;
+                try {
+                    Gson gson = new GsonBuilder().disableHtmlEscaping().create();
+                    mResponse = gson.fromJson(resp.getBody(), Map.class);
+                } catch (Exception e) {
+                    throw new EnsException(EnsErrCd.ERR505, String.format("문서상태변경 응답데이터 파싱 실패. %s", resp.getBody()));
+                }
+                String errorCode = (String) mResponse.get("error_code");
+                String errorMessage = (String) mResponse.get("error_message");
                 responseVO = EnsResponseVO.errBuilder()
                     .errCode(EnsErrCd.ERR600)
-                    .errMsg(String.format("%s %s", resp.getErrorCode(), resp.getErrorMessage()))
+                    .errMsg(String.format("%s %s", errorCode, errorMessage))
                     .build();
             }
 
diff --git a/src/main/java/cokr/xit/ens/modules/kkotalk/service/support/KkoTalkApiService.java b/src/main/java/cokr/xit/ens/modules/kkotalk/service/support/KkoTalkApiService.java
index de8c650..354f462 100644
--- a/src/main/java/cokr/xit/ens/modules/kkotalk/service/support/KkoTalkApiService.java
+++ b/src/main/java/cokr/xit/ens/modules/kkotalk/service/support/KkoTalkApiService.java
@@ -18,6 +18,7 @@ import org.springframework.web.util.*;
 import cokr.xit.ens.core.exception.*;
 import cokr.xit.ens.core.exception.code.*;
 import cokr.xit.ens.core.utils.*;
+import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.*;
 import cokr.xit.ens.modules.kkotalk.model.*;
 import lombok.*;
 import lombok.extern.slf4j.*;
@@ -42,6 +43,14 @@ import lombok.extern.slf4j.*;
 @Component
 public class KkoTalkApiService {
 
+    private static final String PROFILE = System.getProperty("spring.profiles.active");
+    /**
+     * profile : local 여부
+     */
+    private static final boolean IS_PROFILE_LOCAL = PROFILE.matches("local.*");
+    private static final String PRODUCT_CD = IS_PROFILE_LOCAL ? "D10_1T" : "D10_2";
+
+
     @Value("${contract.kakao.talk.host}")
     private String HOST;
 
@@ -61,7 +70,6 @@ public class KkoTalkApiService {
     @Value("#{'${contract.kakao.talk.bulkstatus}'.split(';')}")
     private String[] API_BULKSTATUS;
 
-    private final ApiWebClientUtil webClient;
     private static final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
     private static final CharSequence ENVELOPE_ID = "{ENVELOPE_ID}";
 
@@ -74,10 +82,7 @@ public class KkoTalkApiService {
      * @param reqDTO KkoPayEltrDocDTO.RequestSendReq
      * @return KkotalkDTO.SendResponse
      */
-    public KkotalkDTO.SendResponse requestSend(final KkotalkDTO.SendRequest reqDTO) {
-        if(Checks.isEmpty(reqDTO.getProductCode())){
-            throw BizRuntimeException.create("상품 코드는 필수 입니다.");
-        }
+    public ResponseEntity requestSend(final OrgMng orgMng, final KkotalkDTO.SendRequest reqDTO) {
         List errors = new ArrayList<>();
         errors = validate(reqDTO.getEnvelope(), errors);
 
@@ -93,13 +98,15 @@ public class KkoTalkApiService {
             if(Checks.isEmpty(envelope.getPhoneNumber()))   Objects.requireNonNull(errors).add("phoneNumber=받는이 전화번호는 필수입니다.");
             if(Checks.isEmpty(envelope.getBirthday()))      Objects.requireNonNull(errors).add("birthday=받는이 생년월일은 필수입니다.");
         }
-        if(!Objects.requireNonNull(errors).isEmpty()) throw BizRuntimeException.create(errors.toString());
-        return webClient.exchangeKkotalk(
-            HOST + API_SEND[0].replace("{PRODUCT_CODE}", reqDTO.getProductCode()),
+        if(!Objects.requireNonNull(errors).isEmpty()){
+            return new ResponseEntity("{\""+EnsErrCd.SEND405.getCode() +"\":" + errors.toString() +"}", HttpStatus.BAD_REQUEST);
+        }
+
+        return callApi(
             HttpMethod.valueOf(API_SEND[1]),
+            HOST + API_SEND[0].replace("{PRODUCT_CODE}", reqDTO.getProductCode()),
             JsonUtils.toJson(envelope),
-            KkotalkDTO.SendResponse.class,
-            getRlaybsnmInfo(reqDTO));
+            getHeaders(orgMng));
     }
 
     /**
@@ -109,17 +116,14 @@ public class KkoTalkApiService {
      * @param reqDTO KkopayDocDTO.ValidTokenRequest
      * @return KkotalkApiDTO.ValidTokenResponse
      */
-    public KkotalkApiDTO.ValidTokenResponse validToken(final KkotalkApiDTO.ValidTokenRequest reqDTO) {
+    public ResponseEntity validToken(final OrgMng orgMng, final KkotalkApiDTO.ValidTokenRequest reqDTO) {
         validate(reqDTO, null);
 
-        return webClient.exchangeKkotalk(
-            HOST
-                + API_VALID_TOKEN[0].replace(ENVELOPE_ID, reqDTO.getEnvelopeId())
-                .replace("{TOKEN}", reqDTO.getToken()),
+        return callApi(
             HttpMethod.valueOf(API_VALID_TOKEN[1]),
+            HOST + API_VALID_TOKEN[0].replace(ENVELOPE_ID, reqDTO.getEnvelopeId()),
             null,
-            KkotalkApiDTO.ValidTokenResponse.class,
-            getRlaybsnmInfo(reqDTO));
+            getHeaders(orgMng));
     }
 
     /**
@@ -132,12 +136,16 @@ public class KkoTalkApiService {
      * 
* @param reqDTO KkopayDocAttrDTO.EnvelopeId */ - public KkotalkApiDTO.KkotalkErrorDTO modifyStatus(final KkotalkDTO.EnvelopeId reqDTO){ + public ResponseEntity modifyStatus(final OrgMng orgMng, final KkotalkDTO.EnvelopeId reqDTO){ validate(reqDTO.getEnvelopeId(), null); final String url = HOST + API_MODIFY_STATUS[0].replace(ENVELOPE_ID, reqDTO.getEnvelopeId()); - return webClient.exchangeKkotalk(url, HttpMethod.valueOf(API_MODIFY_STATUS[1]), null, KkotalkApiDTO.KkotalkErrorDTO.class, getRlaybsnmInfo(reqDTO)); + return callApi( + HttpMethod.valueOf(API_MODIFY_STATUS[1]), + url, + null, + getHeaders(orgMng)); } /** @@ -151,80 +159,24 @@ public class KkoTalkApiService { * @param reqDTO KkotalkDTO.EnvelopeId * @return KkotalkApiDTO.EnvelopeStatusResponse */ - public KkotalkApiDTO.EnvelopeStatusResponse findStatus(final KkotalkApiDTO.EnvelopeId reqDTO){ + public ResponseEntity findStatus(final OrgMng orgMng, final KkotalkApiDTO.EnvelopeId reqDTO){ validate(reqDTO, null); String param = "{\"envelopeIds\":" + JsonUtils.toJson(Collections.singletonList(reqDTO.getEnvelopeId())) + "}"; - KkotalkDTO.BulkStatusResponse res = webClient.exchangeKkotalk( - HOST + API_BULKSTATUS[0], - HttpMethod.valueOf(API_BULKSTATUS[1]), - param, - KkotalkDTO.BulkStatusResponse.class, - getRlaybsnmInfo(reqDTO)); - return res.getEnvelopeStatus().get(0); - } - /** - *
-     * 모바일웹 연계 문서발송 요청 : POST
-     * -.이용기관 서버에서 전자문서 서버로 문서발송 처리를 요청합니다.
-     * 
- * @param reqDTO KkotalkDTO.BulkSendRequest - * @return KkotalkDTO.BulkSendResponse - */ - public KkotalkDTO.BulkSendResponse requestSendBulk(final KkotalkDTO.BulkSendRequest reqDTO) { - if(Checks.isEmpty(reqDTO.getProductCode())){ - throw BizRuntimeException.create("상품 코드는 필수 입니다."); - } - - List errors = new ArrayList<>(); - - List envelopes = reqDTO.getEnvelopes(); - for(int idx = 0; idx < envelopes.size(); idx++) { - final Set> list = validator.validate(envelopes.get(idx)); - if (!list.isEmpty()) { - int finalIdx = idx; - errors.addAll(list.stream() - .map(row -> String.format("%s[%d]=%s", row.getPropertyPath(), finalIdx +1, row.getMessageTemplate())) - .collect(Collectors.toList()) - ); - } - } - - for(int idx = 0; idx < envelopes.size(); idx++) { - final KkotalkApiDTO.Envelope envelope = envelopes.get(idx); - - if(envelope.getReviewExpiresAt() != null){ - if(envelope.getReviewExpiresAt().compareTo(envelope.getReadExpiresAt()) < 0){ - errors.add("reviewExpiresAt=재열람 만료일시를 최조 열람 만료일시 보다 큰 날짜로 입력해주세요."); - } - } - - if (Checks.isEmpty(envelope.getCi())) { - if (Checks.isEmpty(envelope.getName())) errors.add(String.format("받는이 이름은 필수입니다(name[%d] 번째 오류)", idx+1)); - if (Checks.isEmpty(envelope.getPhoneNumber())) errors.add(String.format("받는이 전화번호는 필수입니다(phoneNumber[%d] 번째 오류)", idx+1)); - if (Checks.isEmpty(envelope.getBirthday())) errors.add(String.format("받는이 생년월일은 필수입니다(birthday[%d] 번째 오류)", idx+1)); - } else { - final StringBuilder sb = new StringBuilder() - .append(StringUtils.defaultString(envelope.getName(), StringUtils.EMPTY)) - .append(StringUtils.defaultString(envelope.getPhoneNumber(), StringUtils.EMPTY)) - .append(StringUtils.defaultString(envelope.getBirthday(), StringUtils.EMPTY)); - - if(Checks.isNotEmpty(sb.toString())){ - errors.add(String.format("CI가 지정 되었습니다(받는이 정보 불필요:[%d] 번째 오류) .", idx+1)); - } - } - } - if(!errors.isEmpty()){ - throw BizRuntimeException.create(errors.toString()); - } - String param = "{\"envelopes\":" + JsonUtils.toJson(envelopes) + "}"; - return webClient.exchangeKkotalk( - HOST + API_BULKSEND[0].replace("{PRODUCT_CODE}", reqDTO.getProductCode()), - HttpMethod.valueOf(API_BULKSEND[1]), + return callApi( + HttpMethod.valueOf(API_BULKSTATUS[1]), + HOST + API_BULKSTATUS[0], param, - KkotalkDTO.BulkSendResponse.class, - getRlaybsnmInfo(reqDTO)); + getHeaders(orgMng)); + + // KkotalkDTO.BulkStatusResponse res = webClient.exchangeKkotalk( + // HOST + API_BULKSTATUS[0], + // HttpMethod.valueOf(API_BULKSTATUS[1]), + // param, + // KkotalkDTO.BulkStatusResponse.class, + // getRlaybsnmInfo(reqDTO)); + // return res.getEnvelopeStatus().get(0); } /** @@ -235,12 +187,9 @@ public class KkoTalkApiService { * @param reqDTO KkotalkDTO.BulkSendRequest * @return KkotalkDTO.BulkSendResponse */ - public ResponseEntity requestSendBulk2(final KkotalkDTO.BulkSendRequest reqDTO) { + public ResponseEntity requestSendBulk(final OrgMng orgMng, final KkotalkDTO.BulkSendRequest reqDTO) { ResponseEntity resEntity = null; - - if(Checks.isEmpty(reqDTO.getProductCode())){ - return new ResponseEntity("{\""+EnsErrCd.SEND405.getCode() +"\":\"상품 코드는 필수 입니다\"}", HttpStatus.BAD_REQUEST); - } + reqDTO.setProductCode(PRODUCT_CD); List errors = new ArrayList<>(); @@ -289,7 +238,7 @@ public class KkoTalkApiService { HttpMethod.valueOf(API_BULKSEND[1]), HOST + API_BULKSEND[0].replace("{PRODUCT_CODE}", reqDTO.getProductCode()), param, - getHeaders()); + getHeaders(orgMng)); } /** @@ -303,7 +252,7 @@ public class KkoTalkApiService { * @param reqDTO KkotalkDTO.BulkStatusRequest * @return KkotalkDTO.BulkStatusResponse */ - public KkotalkDTO.BulkStatusResponse findBulkStatus(final KkotalkDTO.BulkStatusRequest reqDTO) { + public ResponseEntity findBulkStatus(final OrgMng orgMng, final KkotalkDTO.BulkStatusRequest reqDTO) { List errors = new ArrayList<>(); List envelopes = reqDTO.getEnvelopes(); @@ -314,15 +263,15 @@ public class KkoTalkApiService { } } if(!errors.isEmpty()) { - throw BizRuntimeException.create(errors.toString()); + return new ResponseEntity("{\""+EnsErrCd.SEND405.getCode() +"\":" + errors.toString() +"}", HttpStatus.BAD_REQUEST); } String param = "{\"envelopeIds\":" + JsonUtils.toJson(envelopes) + "}"; - return webClient.exchangeKkotalk( - HOST + API_BULKSTATUS[0], + + return callApi( HttpMethod.valueOf(API_BULKSTATUS[1]), + HOST + API_BULKSTATUS[0], param, - KkotalkDTO.BulkStatusResponse.class, - getRlaybsnmInfo(reqDTO)); + getHeaders(orgMng)); } //------------------------------------------------------------------------------------------------------------------- @@ -336,7 +285,9 @@ public class KkoTalkApiService { // 추가적인 유효성 검증이 필요 없는 경우 if(errList == null){ - if(!errors.isEmpty()) throw BizRuntimeException.create(errors.toString()); + if(!errors.isEmpty()){ + throw BizRuntimeException.create(errors.toString()); + } return null; } errList.addAll(errors); @@ -344,16 +295,6 @@ public class KkoTalkApiService { return errList; } - // FIXME: 카카오톡 API 호출 시 API 호출 정보 추가 필요 - private CmmEnsRlaybsnmDTO getRlaybsnmInfo(final CmmEnsRequestDTO request){ - //return null;//CmmEnsUtils.getRlaybsnmInfo(request.getSignguCode(), request.getFfnlgCode(), SndngSeCode.KAKAO); - return CmmEnsRlaybsnmDTO.builder() - .kakaoDealerRestApiKey("kakaoDealerRestApiKey") - .kakaoPartnerRestApiKey("kakaoPartnerRestApiKey") - .kakaoSettleId("kakaoSettleId") - .build(); - } - /** *
메소드 설명: API 호출
      * 
@@ -435,13 +376,12 @@ public class KkoTalkApiService { } // FIXME: 카카오톡 API 호출 시 API 호출 정보 추가 필요 - private HttpHeaders getHeaders(){ + private HttpHeaders getHeaders(final OrgMng orgMng){ HttpHeaders headers = new HttpHeaders(); - // headers.setContentType(MediaType.APPLICATION_JSON); headers.setContentType(new MediaType(MediaType.APPLICATION_JSON, Charset.forName("utf-8"))); - headers.set(HttpHeaders.AUTHORIZATION, String.format("KakaoAK %s", "KakaoDealerRestApiKey")); - headers.set("Target-Authorization", "KakaoPartnerRestApiKey"); - headers.set("settle-Id", "KakaoSettleId"); + headers.set(HttpHeaders.AUTHORIZATION, String.format("KakaoAK %s", orgMng.getKakaoDealerRestApiKey())); + headers.set("Target-Authorization", orgMng.getKakaoPartnerRestApiKey()); + headers.set("settle-Id", IS_PROFILE_LOCAL ? orgMng.getKakaoDevSettleId() : orgMng.getKakaoProdSettleId()); return headers; } diff --git a/src/main/java/cokr/xit/ens/modules/kkotalk/service/support/KkoTalkRsltFetcher.java b/src/main/java/cokr/xit/ens/modules/kkotalk/service/support/KkoTalkRsltFetcher.java index cf61362..20840ac 100644 --- a/src/main/java/cokr/xit/ens/modules/kkotalk/service/support/KkoTalkRsltFetcher.java +++ b/src/main/java/cokr/xit/ens/modules/kkotalk/service/support/KkoTalkRsltFetcher.java @@ -5,6 +5,7 @@ import java.util.stream.*; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.*; +import org.springframework.http.*; import org.springframework.stereotype.*; import org.springframework.transaction.annotation.*; @@ -23,9 +24,9 @@ import cokr.xit.ens.modules.common.domain.*; import cokr.xit.ens.modules.common.domain.repository.*; import cokr.xit.ens.modules.common.domain.support.*; import cokr.xit.ens.modules.common.event.*; -import cokr.xit.ens.modules.kkomydoc.domain.repository.*; import cokr.xit.ens.modules.kkotalk.code.*; import cokr.xit.ens.modules.kkotalk.domain.*; +import cokr.xit.ens.modules.kkotalk.domain.repository.*; import cokr.xit.ens.modules.kkotalk.mapper.*; import cokr.xit.ens.modules.kkotalk.model.*; import lombok.*; @@ -41,11 +42,10 @@ public class KkoTalkRsltFetcher extends ResultProcTemplate { private final SendMastRepository sendMastRepository; private final IKkoTalkMapper talkMapper; - private final SendDetailKkoMydocStatHistRepository sendDetailKkoMydocStatHistRepository; + private final SendDetailKkoTalkStatHistRepository sendDetailKkoTalkStatHistRepository; private final OrgMngService orgMngService; private final KkoTalkApiService kkoTalkApi; - //private final KkoMydocApiSpec kkoMydocApi; - @Value("${contract.kakao.pay.mydoc.api.bulksend-batch-unit}") + @Value("${contract.kakao.talk.bulksend-batch-unit}") private int SEND_BATCH_UNIT; @Override @@ -68,100 +68,61 @@ public class KkoTalkRsltFetcher extends ResultProcTemplate { Lists.partition(sendDetails, SEND_BATCH_UNIT).stream() .forEach(list -> { - + List envelopeIds = null; String sendRespBody = null; - String jsonStr = null; + try { - List envelopeIds = this.makeMessage(list); - KkotalkDTO.BulkStatusResponse resp = kkoTalkApi.findBulkStatus( + envelopeIds = this.makeMessage(list); + ResponseEntity resp = kkoTalkApi.findBulkStatus( + orgMng, KkotalkDTO.BulkStatusRequest.builder() .envelopes(envelopeIds) - .signguCode(orgMng.getOrgCd()) - .ffnlgCode("11") - .build() ); - - resp.getEnvelopeStatus().forEach(t -> {} - - ); - /* - list.stream().forEach(row -> - this.modifyStatInfoByDocumentBinderUuid(row, resp.getEnvelopeStatus()) - ); - List> documents = (List>) ((Map) mResponse.getResultInfo()).get("documents"); - - - - Map mApiRespVOByDocumentBinderUuid = documents.stream() - .map(row -> this.toApiRespVOMap(row)) - .collect(Collectors.toMap(m -> String.valueOf(m.get("key")), m -> (KkoMydocApiRespVO) m.get("value"), (k1, k2) -> k1)); - - list.stream().forEach(row -> this.modifyStatInfoByDocumentBinderUuid(row, mApiRespVOByDocumentBinderUuid)); - - */ -/* - EnsResponseVO message = this.makeMessage(list); - if (!(EnsErrCd.OK.equals(message.getErrCode()) || null == message.getErrCode())) - throw new EnsException(message.getErrCode(), message.getErrMsg()); - jsonStr = String.valueOf(message.getResultInfo()); - - ResponseEntity resp = kkoMydocApi.bulkStatus(orgMng.getKkoMdAccessToken(), orgMng.getKkoMdContractUuid(), jsonStr); - if (log.isDebugEnabled()) { - StringBuffer sb = new StringBuffer(); - sb.append("\n==============================================================================") - .append("\n[ Kakao Mydoc - StatFetch ]") - .append("\n### Request Info...") - .append("\n" + jsonStr) - .append("\n### Response Info...") - .append("\n" + resp.getBody()) - .append("\n=============================================================================="); - log.debug(sb.toString()); - } - sendRespBody = resp.getBody(); if (resp.getStatusCode() != HttpStatus.OK) - throw new EnsException(EnsErrCd.RSLT620, String.format("문서상태조회 중.. %s %s", resp.getStatusCode().toString(), resp.getBody())); - EnsResponseVO mResponse = this.respMsgToMap(resp.getBody()); + throw new EnsException(EnsErrCd.SEND620, String.format("카카오톡 상태 조회 중.. %s %s", resp.getStatusCode().toString(), resp.getBody())); + EnsResponseVO mResponse = this.respMsgToMap(sendRespBody); if (!EnsErrCd.OK.equals(mResponse.getErrCode())) throw new EnsException(mResponse.getErrCode(), mResponse.getErrMsg()); - List> documents = (List>) ((Map) mResponse.getResultInfo()).get("documents"); + List> envelopeStatus = (List>) ((Map) mResponse.getResultInfo()).get("envelopeStatus"); - Map mApiRespVOByDocumentBinderUuid = documents.stream() - .map(row -> this.toApiRespVOMap(row)) - .collect(Collectors.toMap(m -> String.valueOf(m.get("key")), m -> (KkoMydocApiRespVO) m.get("value"), (k1, k2) -> k1)); + Map mApiRespVO = envelopeStatus.stream() + .map(row -> this.toApiRespVOMap(row)) + .collect(Collectors.toMap(m -> String.valueOf(m.get("key")), m -> (KkoTalkApiRespVO) m.get("value"), (k1, k2) -> k1)); - list.stream().forEach(row -> this.modifyStatInfoByDocumentBinderUuid(row, mApiRespVOByDocumentBinderUuid)); + list.stream().forEach(row -> this.modifyStatInfoByEnvelopeId(row, mApiRespVO)); } catch (EnsException e) { - list.stream() - .forEach(row -> row.setError(FieldError.initBuilder() - .errorCode(e.getErrCd().getCode()) - .errorMessage(e.getMessage()) - .build()) - ); + list.forEach(row -> row.setError(FieldError.initBuilder() + .errorCode(e.getErrCd().getCode()) + .errorMessage(e.getMessage()) + .build()) + ); } catch (Exception e) { + list.forEach(row -> row.setError(FieldError.initBuilder() + .errorCode(EnsErrCd.RSLT500.getCode()) + .errorMessage(e.getMessage()) + .build()) + ); + } finally { + // FIXME: 카카오톡 추가 - 카카오톡 테이블 업데이트 list.stream() - .forEach(row -> row.setError(FieldError.initBuilder() - .errorCode(EnsErrCd.RSLT500.getCode()) - .errorMessage(e.getMessage()) - .build()) - ); + .forEach(talkMapper::updateKakaotalkStatusBulksResult); - */ - } finally { -// if (!CmmnUtil.isEmpty(jsonStr)) -// sendDetailKkoMydocStatHistRepository.saveAll(this.toSendDetailStatHist(list, sendRespBody)); + if (!CmmnUtil.isEmpty(envelopeIds)) + sendDetailKkoTalkStatHistRepository.saveAll(this.toSendDetailStatHist(list, sendRespBody)); } }); + respVO = EnsResponseVO.okBuilder().resultInfo(resultInfo).build(); } catch (EnsException e) { @@ -245,40 +206,46 @@ public class KkoTalkRsltFetcher extends ResultProcTemplate { * -. 성공/실패 여부에 따라 상태정보 및 Error 필드 갱신 * */ - private void modifyStatInfoByDocumentBinderUuid(SendDetailKkoTalkDTO row, List resList) { - /* - List resList = response.getEnvelopeStatus(); - if (CmmnUtil.isEmpty(envelopeStatus..getError_code())) { + private void modifyStatInfoByEnvelopeId(SendDetailKkoTalkDTO row, Map resMap) { + KkoTalkApiRespVO apiRespVO = resMap.get(row.getEnvelopeId()); + + if (CmmnUtil.isEmpty(apiRespVO.getErrorCode())) { Map statusData = (Map) apiRespVO.getData(); - String docBoxStatus = statusData.containsKey("doc_box_status") ? (String) statusData.get("doc_box_status") : null; - Long docBoxSentAt = statusData.containsKey("doc_box_sent_at") ? (Long) statusData.get("doc_box_sent_at") : null; - Long docBoxReceivedAt = statusData.containsKey("doc_box_received_at") ? (Long) statusData.get("doc_box_received_at") : null; - Long authenticatedAt = statusData.containsKey("authenticated_at") ? (Long) statusData.get("authenticated_at") : null; - Long tokenUsedAt = statusData.containsKey("token_used_at") ? (Long) statusData.get("token_used_at") : null; - Long docBoxReadAt = statusData.containsKey("doc_box_read_at") ? (Long) statusData.get("doc_box_read_at") : null; - Long userNotifiedAt = statusData.containsKey("user_notified_at") ? (Long) statusData.get("user_notified_at") : null; - - row.setKkoDocStat(CmmnUtil.isEmpty(docBoxStatus) ? row.getKkoDocStat() : KkoMydocStatusCd.valueOfEnum(docBoxStatus)); - row.setKkoDocSentDt(CmmnUtil.isEmpty(row.getKkoDocSentDt()) ? DateUtil.absTimeSecToDate(docBoxSentAt, "yyyyMMddHHmmss") : row.getKkoDocSentDt()); - row.setKkoDocReceivedDt(CmmnUtil.isEmpty(row.getKkoDocReceivedDt()) ? DateUtil.absTimeSecToDate(docBoxReceivedAt, "yyyyMMddHHmmss") : row.getKkoDocReceivedDt()); - row.setKkoDocAuthFrstDt(CmmnUtil.isEmpty(row.getKkoDocAuthFrstDt()) ? DateUtil.absTimeSecToDate(authenticatedAt, "yyyyMMddHHmmss") : row.getKkoDocAuthFrstDt()); - row.setKkoDocTokenVrfyFrstDt(CmmnUtil.isEmpty(row.getKkoDocTokenVrfyFrstDt()) ? DateUtil.absTimeSecToDate(tokenUsedAt, "yyyyMMddHHmmss") : row.getKkoDocTokenVrfyFrstDt()); - row.setKkoDocReadFrstDt(CmmnUtil.isEmpty(row.getKkoDocReadFrstDt()) ? DateUtil.absTimeSecToDate(docBoxReadAt, "yyyyMMddHHmmss") : row.getKkoDocReadFrstDt()); - row.setKkoDocUserNotiedDt(CmmnUtil.isEmpty(row.getKkoDocUserNotiedDt()) ? DateUtil.absTimeSecToDate(userNotifiedAt, "yyyyMMddHHmmss") : row.getKkoDocUserNotiedDt()); + String status = statusData.containsKey("status") ? (String) statusData.get("status") : null; + String sentAt = statusData.containsKey("sentAt") ? (String) statusData.get("sentAt") : null; + String receivedAt = statusData.containsKey("receivedAt") ? (String) statusData.get("receivedAt") : null; + String readAt = statusData.containsKey("readAt") ? (String) statusData.get("readAt") : null; + String readExpiredAt = statusData.containsKey("readExpiredAt") ? (String) statusData.get("readExpiredAt") : null; + String authenticatedAt = statusData.containsKey("authenticatedAt") ? (String) statusData.get("authenticatedAt") : null; + String ottVerifiedAt = statusData.containsKey("ottVerifiedAt") ? (String) statusData.get("ottVerifiedAt") : null; + String userNotifiedAt = statusData.containsKey("userNotifiedAt") ? (String) statusData.get("userNotifiedAt") : null; + String distributionReceivedAt = statusData.containsKey("distributionReceivedAt") ? (String) statusData.get("distributionReceivedAt") : null; + String payload = statusData.containsKey("payload") ? (String) statusData.get("payload") : null; + + row.setStatus(CmmnUtil.isEmpty(status) ? row.getStatus() : KkoTalkStatusCd.valueOfEnum(status)); + row.setSentAt(CmmnUtil.isEmpty(row.getSentAt()) ? sentAt : row.getSentAt()); + row.setReceivedAt(CmmnUtil.isEmpty(row.getReceivedAt()) ? receivedAt : row.getReceivedAt()); + row.setReadAt(CmmnUtil.isEmpty(row.getReadAt()) ? readAt : row.getReadAt()); + row.setReadExpiresAt(CmmnUtil.isEmpty(row.getReadExpiresAt()) ? readExpiredAt : row.getReadExpiresAt()); + row.setAuthenticatedAt(CmmnUtil.isEmpty(row.getAuthenticatedAt()) ? authenticatedAt : row.getAuthenticatedAt()); + row.setOttVerifiedAt(CmmnUtil.isEmpty(row.getOttVerifiedAt()) ? ottVerifiedAt : row.getOttVerifiedAt()); + row.setUserNotifiedAt(CmmnUtil.isEmpty(row.getUserNotifiedAt()) ? userNotifiedAt : row.getUserNotifiedAt()); + row.setDistributionReceivedAt(CmmnUtil.isEmpty(row.getDistributionReceivedAt()) ? distributionReceivedAt : row.getDistributionReceivedAt()); + row.setPayload(CmmnUtil.isEmpty(row.getPayload()) ? payload : row.getPayload()); row.setError(FieldError.initBuilder().build()); } else { - if ("NOT_FOUND".equals(apiRespVO.getError_code()) && "documentBinder를 찾을 수 없습니다.".equals(apiRespVO.getError_message())) - row.setKkoDocStat(KkoMydocStatusCd.INTERNAL_SENT_ERR); + if ("NOT_FOUND".equals(apiRespVO.getErrorCode()) && "envelopeStatus를 찾을 수 없습니다.".equals(apiRespVO.getErrorMessage())) + row.setStatus(KkoTalkStatusCd.INTERNAL_SENT_ERR); row.setError(FieldError.initBuilder() .errorCode(EnsErrCd.RSLT630.getCode()) - .errorMessage(String.format("%s %s", apiRespVO.getError_code(), apiRespVO.getError_message())) + .errorMessage(String.format("%s %s", apiRespVO.getErrorCode(), apiRespVO.getErrorMessage())) .build()); } - */ + } /** @@ -288,7 +255,7 @@ public class KkoTalkRsltFetcher extends ResultProcTemplate { * @param respMsg * @return */ - private List toSendDetailStatHist(List list, String respMsg) { + private List toSendDetailStatHist(List list, String respMsg) { // Map mMydocApiRespVOByExtDocUuid = @@ -297,8 +264,8 @@ public class KkoTalkRsltFetcher extends ResultProcTemplate { if (EnsErrCd.OK.equals(respVO.getErrCode())) { - List> documents = (List>) ((Map) respVO.getResultInfo()).get("envelopes"); - Map mRespVOByExtDocUuid = documents.stream() + List> envelopeStatus = (List>) ((Map) respVO.getResultInfo()).get("envelopeStatus"); + Map mRespVO = envelopeStatus.stream() .map(row -> this.toApiRespVOMap(row)) .collect(Collectors.toMap(m -> String.valueOf(m.get("key")), m -> (KkoTalkApiRespVO) m.get("value"), (k1, k2) -> k1)); @@ -306,21 +273,21 @@ public class KkoTalkRsltFetcher extends ResultProcTemplate { return list.stream() .map(row -> { - KkoTalkApiRespVO apiRespVO = mRespVOByExtDocUuid.get(row.getEnvelopeId()); + KkoTalkApiRespVO apiRespVO = mRespVO.get(row.getEnvelopeId()); Map statusData = (Map) apiRespVO.getData(); return SendDetailKkoTalkStatHist.builder() .sendDetailId(row.getSendDetailId()) .envelopeId(row.getEnvelopeId()) .externalId(row.getExternalId()) -// .respRawMsg(gson.toJson(statusData)) - .status(statusData.containsKey("doc_box_status") ? (String) statusData.get("doc_box_status") : null) -// .sentAt(statusData.containsKey("doc_box_sent_at") ? (Long) statusData.get("doc_box_sent_at") : null) -// .receivedAt(statusData.containsKey("doc_box_received_at") ? (Long) statusData.get("doc_box_received_at") : null) -// .authenticatedAt(statusData.containsKey("authenticated_at") ? (Long) statusData.get("authenticated_at") : null) -// .tokenUsedAt(statusData.containsKey("token_used_at") ? (Long) statusData.get("token_used_at") : null) -// .readAt(statusData.containsKey("doc_box_read_at") ? (Long) statusData.get("doc_box_read_at") : null) -// .userNotifiedAt(statusData.containsKey("user_notified_at") ? (Long) statusData.get("user_notified_at") : null) -// .docDistributionReceivedAt(statusData.containsKey("doc_distribution_received_at") ? (Long) statusData.get("doc_distribution_received_at") : null) + .status(statusData.containsKey("status") ? (String) statusData.get("status") : null) + .sentAt(statusData.containsKey("sentAt") ? (String) statusData.get("sentAt") : null) + .receivedAt(statusData.containsKey("receivedAt") ? (String) statusData.get("receivedAt") : null) + .readAt(statusData.containsKey("readAt") ? (String) statusData.get("readAt") : null) + .readExpiredAt(statusData.containsKey("readExpiredAt") ? (String) statusData.get("readExpiredAt") : null) + .authenticatedAt(statusData.containsKey("authenticatedAt") ? (String) statusData.get("authenticatedAt") : null) + .ottVerifiedAt(statusData.containsKey("ottVerifiedAt") ? (String) statusData.get("ottVerifiedAt") : null) + .userNotifiedAt(statusData.containsKey("userNotifiedAt") ? (String) statusData.get("userNotifiedAt") : null) + .distributionReceivedAt(statusData.containsKey("distributionReceivedAt") ? (String) statusData.get("distributionReceivedAt") : null) .payload(statusData.containsKey("payload") ? (String) statusData.get("payload") : null) .error(FieldError.initBuilder() .errorCode(apiRespVO.getErrorCode()) @@ -348,21 +315,21 @@ public class KkoTalkRsltFetcher extends ResultProcTemplate { } - private EnsResponseVO respMsgToMap(String respMsg) { + private EnsResponseVO respMsgToMap(String respMsg) { Gson gson = new GsonBuilder().registerTypeAdapter(Map.class, new MapDeserailizer()).serializeNulls().create(); EnsErrCd errCode = EnsErrCd.OK; String errMsg = EnsErrCd.OK.getCodeNm(); Map mResp = null; try { mResp = gson.fromJson(respMsg, Map.class); - if (CmmnUtil.isEmpty(mResp.get("documents"))) - throw new EnsException(EnsErrCd.RSLT620, String.format("문서상태조회API 오류. documents 키값이 없습니다. %s", respMsg)); + if (CmmnUtil.isEmpty(mResp.get("envelopeStatus"))) + throw new EnsException(EnsErrCd.RSLT620, String.format("카카오톡 상태조회API 오류. envelopeStatus 키값이 없습니다. %s", respMsg)); } catch (EnsException e) { errCode = e.getErrCd(); errMsg = e.getMessage(); } catch (Exception e) { errCode = EnsErrCd.RSLT511; - errMsg = String.format("문서상태조회API 응답 데이터 JSON 객체 변환 실패. %s", respMsg); + errMsg = String.format("카카오톡 상태조회API 응답 데이터 JSON 객체 변환 실패. %s", respMsg); } return EnsErrCd.OK.equals(errCode) ? EnsResponseVO.okBuilder().resultInfo(mResp).build() diff --git a/src/main/java/cokr/xit/ens/modules/kkotalk/service/support/KkoTalkSender.java b/src/main/java/cokr/xit/ens/modules/kkotalk/service/support/KkoTalkSender.java index 617b3e2..d981d83 100644 --- a/src/main/java/cokr/xit/ens/modules/kkotalk/service/support/KkoTalkSender.java +++ b/src/main/java/cokr/xit/ens/modules/kkotalk/service/support/KkoTalkSender.java @@ -77,38 +77,33 @@ public class KkoTalkSender extends SendProcTemplate { String sendRespBody = null; try { - envelopes = this.makeMessage(list); - ResponseEntity resp = kkoTalkApi.requestSendBulk2( + ResponseEntity resp = kkoTalkApi.requestSendBulk( + orgMng, KkotalkDTO.BulkSendRequest.builder() - // FIXME: 카카오톡 신규 추가 - 테스트를 위해 임시로 넣음 - .productCode("D10_2") .envelopes(envelopes) - .signguCode(orgMng.getOrgCd()) - .ffnlgCode("11") - .build() ); sendRespBody = resp.getBody(); if (resp.getStatusCode() != HttpStatus.OK) throw new EnsException(EnsErrCd.SEND620, String.format("전송요청 중.. %s %s", resp.getStatusCode().toString(), resp.getBody())); - EnsResponseVO mResponse = this.respMsgToMap(sendRespBody); + EnsResponseVO mResponse = this.respMsgToMap(sendRespBody); if (!EnsErrCd.OK.equals(mResponse.getErrCode())) throw new EnsException(mResponse.getErrCode(), mResponse.getErrMsg()); - List> documents = (List>)((Map)mResponse.getResultInfo()).get( + List> envelopeIds = (List>)((Map)mResponse.getResultInfo()).get( "envelopeIds"); - Map mApiResp = documents.stream() + Map mApiResp = envelopeIds.stream() .map(this::toApiRespVOMap) .collect(Collectors.toMap(m -> String.valueOf(m.get("key")), m -> (KkoTalkApiRespVO)m.get("value"), (k1, k2) -> k1)); list.stream() .forEach(row -> { - this.modifyTalkSendRsltByExtDocUuid(row, mApiResp); + this.modifyTalkSendRsltByExternalId(row, mApiResp); }); @@ -164,12 +159,6 @@ public class KkoTalkSender extends SendProcTemplate { else throw new EnsException(EnsErrCd.SEND500, String.format("전체건수 전송 실패(총 %d 건)", sendDetails.size())); - } catch (BizRuntimeException be){ - respVO = EnsResponseVO.errBuilder() - .errCode(EnsErrCd.SEND500) - .errMsg(be.getMessage()) - .build(); - } catch (EnsException e) { respVO = EnsResponseVO.errBuilder().errCode(e.getErrCd()).errMsg(e.getMessage()).build(); @@ -199,13 +188,7 @@ public class KkoTalkSender extends SendProcTemplate { .build()); } } - -// if (respVO != null && EnsErrCd.OK.equals(respVO.getErrCode())) { -// applicationEventPublisher.publishEvent(KkoMydocSentEvent.builder().sendMastId(sendMastId).build()); -// } else { applicationEventPublisher.publishEvent(SendMastStatUpdateEvent.builder().sendMastId(sendMastId).build()); -// } - } @@ -279,7 +262,7 @@ public class KkoTalkSender extends SendProcTemplate { * @param row SendDetailKkoTalkDTO * @param map Map */ - private void modifyTalkSendRsltByExtDocUuid(SendDetailKkoTalkDTO row, Map map) { + private void modifyTalkSendRsltByExternalId(SendDetailKkoTalkDTO row, Map map) { KkoTalkApiRespVO apiRespVO = map.get(row.getExternalId()); if (CmmnUtil.isEmpty(apiRespVO.getErrorCode())) { row.setStatus(KkoTalkStatusCd.SENT); @@ -421,7 +404,7 @@ public class KkoTalkSender extends SendProcTemplate { try { mResp = gson.fromJson(respMsg, Map.class); if (CmmnUtil.isEmpty(mResp.get("envelopeIds"))) - throw new EnsException(EnsErrCd.SEND620, String.format("전송요청API 오류. envelopeId 키값이 없습니다. %s", respMsg)); + throw new EnsException(EnsErrCd.SEND620, String.format("전송요청API 오류. envelopeIds 키값이 없습니다. %s", respMsg)); } catch (EnsException e) { errCode = e.getErrCd(); errMsg = e.getMessage(); diff --git a/src/main/java/cokr/xit/ens/modules/kkotalk/web/KkotalkApiController.java b/src/main/java/cokr/xit/ens/modules/kkotalk/web/KkotalkApiController.java index 02a4025..41c17d3 100644 --- a/src/main/java/cokr/xit/ens/modules/kkotalk/web/KkotalkApiController.java +++ b/src/main/java/cokr/xit/ens/modules/kkotalk/web/KkotalkApiController.java @@ -1,250 +1,250 @@ -package cokr.xit.ens.modules.kkotalk.web; - -import org.springframework.http.*; -import org.springframework.web.bind.annotation.*; - -import cokr.xit.ens.core.aop.*; -import cokr.xit.ens.modules.kkotalk.model.*; -import cokr.xit.ens.modules.kkotalk.service.support.*; -import io.swagger.v3.oas.annotations.*; -import io.swagger.v3.oas.annotations.media.*; -import io.swagger.v3.oas.annotations.tags.*; -import lombok.*; -import lombok.extern.slf4j.*; - -/** - *
- * description : 카카오톡 전자 문서 발송 controller
- * packageName : kr.xit.ens.kakao.talk.web
- * fileName    : KkotalkEltrcDocController
- * author      : julim
- * date        : 2024-08-12
- * ======================================================================
- * 변경일         변경자        변경 내용
- * ----------------------------------------------------------------------
- * 2024-08-12    julim       최초 생성
- *
- * 
- */ -@Tag(name = "KkotalkApiController", description = "카카오톡 인증톡 API") -@Slf4j -@RequiredArgsConstructor -@RestController -@RequestMapping(value = "/kko/talk/api") -public class KkotalkApiController { - private final KkoTalkApiService service; - - /** - *
-     * 모바일웹 연계 문서발송 요청
-     * -.이용기관 서버에서 전자문서 서버로 문서발송 처리를 요청합니다.
-     * 
- * @param reqDTO KkopayDocDTO.SendRequest - * @return ApiResponseDTO - */ - @Operation(summary = "문서발송 요청", description = "카카오톡 전자문서 서버로 문서발송 처리를 요청") - @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { - @Content(mediaType = "application/json", examples = { - @ExampleObject( - name = "D10", - value = "{\n" + - " \"productCode\": \"D10_1\",\n" + - " \"envelope\": {\n" + - " \"title\": \"전자문서\",\n" + - " \"content\": {\n" + - " \"link\": \"https://nps.or.kr\"\n" + - " },\n" + - " \"guide\": \"국민연금 공단에서 보내는 문서입니다.\",\n" + - " \"payload\": \"이용기관 페이로드\",\n" + - " \"readExpiresAt\": \"2023-12-31T10:00:00\",\n" + - " \"reviewExpiresAt\": \"2023-12-31T13:00:00\",\n" + - " \"useNonPersonalizedNotification\": true,\n" + - " \"phoneNumber\": \"01099999999\",\n" + - " \"name\": \"홍길동\",\n" + - " \"birthday\": \"20000303\",\n" + - " \"externalId\": \"external_id1\"\n" + - " },\n" + - " \"signguCode\": \"51110\",\n" + - " \"ffnlgCode\": \"11\"\n" + - "}" - ), - @ExampleObject( - name = "D11", - value = "{\n" + - " \"productCode\": \"D11_1\",\n" + - " \"envelope\": {\n" + - " \"title\": \"전자문서\",\n" + - " \"content\": {\n" + - " \"html\": \"

MyFirstHeading

Myfirstparagraph.

\"\n" + - " },\n" + - " \"guide\": \"국민연금 공단에서 보내는 문서입니다.\",\n" + - " \"readExpiresAt\": \"2023-12-31T10:00:00\",\n" + - " \"reviewExpiresAt\": \"2023-12-31T13:00:00\",\n" + - " \"ci\": \"${CI}\"\n" + - " },\n" + - " \"signguCode\": \"51110\",\n" + - " \"ffnlgCode\": \"11\"\n" + - "}" - ) - }) -}) @PostMapping(value = "/envelopes", produces = MediaType.APPLICATION_JSON_VALUE) - public IApiResponse requestSend( - @RequestBody final KkotalkDTO.SendRequest reqDTO - ) { - return ApiResponseDTO.success(service.requestSend(reqDTO)); - } - - /** - *
-     * 토큰 유효성 검증(Redirect URL  접속 허용/불허)
-     * 
- * @param reqDTO KkopayDocDTO.ValidTokenRequest - * @return ApiResponseDTO - */ - @Operation(summary = "토큰 유효성 검증", description = "Redirect URL 접속 허용/불허") - @PostMapping(value = "/validToken", produces = MediaType.APPLICATION_JSON_VALUE) - public IApiResponse validToken( - @RequestBody final KkotalkDTO.ValidTokenRequest reqDTO - ) { - return ApiResponseDTO.success(service.validToken(reqDTO)); - } - - /** - *
-     * 문서 열람처리 API
-     * -.문서에 대해서 열람 상태로 변경. 사용자가 문서열람 시(OTT 검증 완료 후 페이지 로딩 완료 시점) 반드시 문서 열람 상태 변경 API를 호출해야 함.
-     * -.미 호출 시 아래와 같은 문제 발생
-     * 1)유통증명시스템을 사용하는 경우 해당 API를 호출한 시점으로 열람정보가 등록되어 미 호출 시 열람정보가 등록 되지 않음.
-     * 2)문서상태조회 API(/v1/envelopes/${ENVELOPE_ID}/read) 호출 시 read_at최초 열람시간) 데이터가 내려가지 않음.
-     * 
- * @param reqDTO KkotalkApiDTO.EnvelopeStatusResponse - * @return ApiResponseDTO - */ - @Operation(summary = "문서열람처리(문서 상태 변경)", description = "문서열람처리(문서 상태 변경)") - @PostMapping(value = "/modifyStatus", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - public IApiResponse modifyStatus( - @RequestBody final KkotalkApiDTO.EnvelopeId reqDTO - ) { - service.modifyStatus(reqDTO); - return ApiResponseDTO.empty(); - } - - /** - *
-     * 문서 상태 조회 API
-     * -.이용기관 서버에서 카카오페이 전자문서 서버로 문서 상태에 대한 조회를 요청 합니다.
-     * : 발송된 문서의 진행상태를 알고 싶은 경우, flow와 상관없이 요청 가능
-     * : polling 방식으로 호출할 경우, 호출 간격은 5초를 권장.
-     * -.doc_box_status 상태변경순서
-     * : SENT(송신) > RECEIVED(수신) > READ(열람)/EXPIRED(미열람자료의 기한만료)
-     * 
- * @param reqDTO KkotalkDTO.EnvelopeId - * @return ApiResponseDTO - */ - @Operation(summary = "문서 상태 조회", description = "문서 상태 조회") - @PostMapping(value = "/findStatus", produces = MediaType.APPLICATION_JSON_VALUE) - public IApiResponse findStatus( - @RequestBody final KkotalkApiDTO.EnvelopeId reqDTO - ) { - return ApiResponseDTO.success(service.findStatus(reqDTO)); - } - - @Operation(summary = "대량 문서발송 요청 -> batch sendBulks 에서 호출", description = "카카오페이 전자문서 서버로 대량 문서발송 처리를 요청 -> batch sendBulks 에서 호출") - @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { - @Content(mediaType = "application/json", examples = { - @ExampleObject( - name = "D10", - value = "{\n" + - " \"productCode\": \"D10_1\",\n" + - " \"signguCode\": \"51110\",\n" + - " \"ffnlgCode\": \"11\",\n" + - " \"envelopes\": [\n" + - " {\n" + - " \"title\": \"전자문서\",\n" + - " \"content\": {\n" + - " \"html\": \"

MyFirstHeading

Myfirstparagraph.

\"\n" + - " },\n" + - " \"guide\": \"국민연금 공단에서 보내는 문서입니다.\",\n" + - " \"readExpiresAt\": \"2024-12-31T10:00:00\",\n" + - " \"reviewExpiresAt\": \"2025-03-31T13:00:00\",\n" + - " \"phoneNumber\": \"01099999999\",\n" + - " \"name\": \"홍길동\",\n" + - " \"birthday\": \"20000303\",\n" + - " \"externalId\": \"external_id1\"\n" + - " },\n" + - " {\n" + - " \"title\": \"전자문서\",\n" + - " \"content\": {\n" + - " \"html\": \"

MyFirstHeading

Myfirstparagraph.

\"\n" + - " },\n" + - " \"guide\": \"국민연금 공단에서 보내는 문서입니다.\",\n" + - " \"readExpiresAt\": \"2024-12-31T10:00:00\",\n" + - " \"reviewExpiresAt\": \"2025-03-31T13:00:00\",\n" + - " \"hash\": \"b0c34fdc5e2ecb0335919fdad3b2ada28fa3ab90ec16e9055c3e9e05c431c6e8\",\n" + - " \"ci\": \"vMtqVxJX56lBgbf9heK3QTc+jVndTfK77i/UJKAzPmBG4n9CazCdd/8YytlFZnN4qofIqgxHpSoiG0yYzgEpJg==\",\n" + - " \"externalId\": \"external_id2\"\n" + - " }\n" + - " ]\n" + - "}" - ), - @ExampleObject( - name = "D11", - value = "{\n" + - " \"productCode\": \"D11_1\",\n" + - " \"signguCode\": \"51110\",\n" + - " \"ffnlgCode\": \"11\",\n" + - " \"envelopes\": [\n" + - " {\n" + - " \"title\": \"전자문서\",\n" + - " \"content\": {\n" + - " \"link\": \"https://nps.or.kr\"\n" + - " },\n" + - " \"guide\": \"국민연금 공단에서 보내는 문서입니다.\",\n" + - " \"payload\": \"이용기관 페이로드\",\n" + - " \"readExpiresAt\": \"2024-12-31T10:00:00\",\n" + - " \"reviewExpiresAt\": \"2025-03-31T13:00:00\",\n" + - " \"phoneNumber\": \"01099999999\",\n" + - " \"name\": \"홍길동\",\n" + - " \"birthday\": \"20000303\",\n" + - " \"externalId\": \"external_id1\"\n" + - " },\n" + - " {\n" + - " \"title\": \"전자문서\",\n" + - " \"content\": {\n" + - " \"link\": \"https://nps.or.kr\"\n" + - " },\n" + - " \"guide\": \"국민연금 공단에서 보내는 문서입니다.\",\n" + - " \"payload\": \"이용기관 페이로드\",\n" + - " \"readExpiresAt\": \"2024-12-31T10:00:00\",\n" + - " \"reviewExpiresAt\": \"2025-03-31T13:00:00\",\n" + - " \"ci\": \"${CI}\",\n" + - " \"externalId\": \"external_id2\"\n" + - " }\n" + - " ]\n" + - "}" - ) - }) - }) - @PostMapping(value = "/envelopes/bulk", produces = MediaType.APPLICATION_JSON_VALUE) - public IApiResponse requestSendBulk( - @RequestBody final KkotalkDTO.BulkSendRequest reqDTO - ) { - return ApiResponseDTO.success(service.requestSendBulk(reqDTO)); - } - - /** - *
-     * 모바일웹 연계 문서발송 요청
-     * -.이용기관 서버에서 전자문서 서버로 문서발송 처리를 요청합니다.
-     * 
- * @param reqDTO KkotalkApiDTO.BulkStatusRequest - * @return KkotalkApiDTO.BulkStatusResponse - */ - @Operation(summary = "대량 문서 상태 조회 요청 -> batch statusBulks 에서 호출", description = "카카오페이 전자문서 서버로 대량 문서 상태 조회 요청 -> batch statusBulks 에서 호출") - @PostMapping(value = "/envelopes/bulk/status", produces = MediaType.APPLICATION_JSON_VALUE) - public IApiResponse findBulkStatus( - @RequestBody final KkotalkDTO.BulkStatusRequest reqDTO - ) { - return ApiResponseDTO.success(service.findBulkStatus(reqDTO)); - } -} +// package cokr.xit.ens.modules.kkotalk.web; +// +// import org.springframework.http.*; +// import org.springframework.web.bind.annotation.*; +// +// import cokr.xit.ens.core.aop.*; +// import cokr.xit.ens.modules.kkotalk.model.*; +// import cokr.xit.ens.modules.kkotalk.service.support.*; +// import io.swagger.v3.oas.annotations.*; +// import io.swagger.v3.oas.annotations.media.*; +// import io.swagger.v3.oas.annotations.tags.*; +// import lombok.*; +// import lombok.extern.slf4j.*; +// +// /** +// *
+//  * description : 카카오톡 전자 문서 발송 controller
+//  * packageName : kr.xit.ens.kakao.talk.web
+//  * fileName    : KkotalkEltrcDocController
+//  * author      : julim
+//  * date        : 2024-08-12
+//  * ======================================================================
+//  * 변경일         변경자        변경 내용
+//  * ----------------------------------------------------------------------
+//  * 2024-08-12    julim       최초 생성
+//  *
+//  * 
+// */ +// @Tag(name = "KkotalkApiController", description = "카카오톡 인증톡 API") +// @Slf4j +// @RequiredArgsConstructor +// @RestController +// @RequestMapping(value = "/kko/talk/api") +// public class KkotalkApiController { +// private final KkoTalkApiService service; +// +// /** +// *
+//      * 모바일웹 연계 문서발송 요청
+//      * -.이용기관 서버에서 전자문서 서버로 문서발송 처리를 요청합니다.
+//      * 
+// * @param reqDTO KkopayDocDTO.SendRequest +// * @return ApiResponseDTO +// */ +// @Operation(summary = "문서발송 요청", description = "카카오톡 전자문서 서버로 문서발송 처리를 요청") +// @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { +// @Content(mediaType = "application/json", examples = { +// @ExampleObject( +// name = "D10", +// value = "{\n" + +// " \"productCode\": \"D10_1\",\n" + +// " \"envelope\": {\n" + +// " \"title\": \"전자문서\",\n" + +// " \"content\": {\n" + +// " \"link\": \"https://nps.or.kr\"\n" + +// " },\n" + +// " \"guide\": \"국민연금 공단에서 보내는 문서입니다.\",\n" + +// " \"payload\": \"이용기관 페이로드\",\n" + +// " \"readExpiresAt\": \"2023-12-31T10:00:00\",\n" + +// " \"reviewExpiresAt\": \"2023-12-31T13:00:00\",\n" + +// " \"useNonPersonalizedNotification\": true,\n" + +// " \"phoneNumber\": \"01099999999\",\n" + +// " \"name\": \"홍길동\",\n" + +// " \"birthday\": \"20000303\",\n" + +// " \"externalId\": \"external_id1\"\n" + +// " },\n" + +// " \"signguCode\": \"51110\",\n" + +// " \"ffnlgCode\": \"11\"\n" + +// "}" +// ), +// @ExampleObject( +// name = "D11", +// value = "{\n" + +// " \"productCode\": \"D11_1\",\n" + +// " \"envelope\": {\n" + +// " \"title\": \"전자문서\",\n" + +// " \"content\": {\n" + +// " \"html\": \"

MyFirstHeading

Myfirstparagraph.

\"\n" + +// " },\n" + +// " \"guide\": \"국민연금 공단에서 보내는 문서입니다.\",\n" + +// " \"readExpiresAt\": \"2023-12-31T10:00:00\",\n" + +// " \"reviewExpiresAt\": \"2023-12-31T13:00:00\",\n" + +// " \"ci\": \"${CI}\"\n" + +// " },\n" + +// " \"signguCode\": \"51110\",\n" + +// " \"ffnlgCode\": \"11\"\n" + +// "}" +// ) +// }) +// }) @PostMapping(value = "/envelopes", produces = MediaType.APPLICATION_JSON_VALUE) +// public IApiResponse requestSend( +// @RequestBody final KkotalkDTO.SendRequest reqDTO +// ) { +// return ApiResponseDTO.success(service.requestSend(reqDTO)); +// } +// +// /** +// *
+//      * 토큰 유효성 검증(Redirect URL  접속 허용/불허)
+//      * 
+// * @param reqDTO KkopayDocDTO.ValidTokenRequest +// * @return ApiResponseDTO +// */ +// @Operation(summary = "토큰 유효성 검증", description = "Redirect URL 접속 허용/불허") +// @PostMapping(value = "/validToken", produces = MediaType.APPLICATION_JSON_VALUE) +// public IApiResponse validToken( +// @RequestBody final KkotalkDTO.ValidTokenRequest reqDTO +// ) { +// return ApiResponseDTO.success(service.validToken(reqDTO)); +// } +// +// /** +// *
+//      * 문서 열람처리 API
+//      * -.문서에 대해서 열람 상태로 변경. 사용자가 문서열람 시(OTT 검증 완료 후 페이지 로딩 완료 시점) 반드시 문서 열람 상태 변경 API를 호출해야 함.
+//      * -.미 호출 시 아래와 같은 문제 발생
+//      * 1)유통증명시스템을 사용하는 경우 해당 API를 호출한 시점으로 열람정보가 등록되어 미 호출 시 열람정보가 등록 되지 않음.
+//      * 2)문서상태조회 API(/v1/envelopes/${ENVELOPE_ID}/read) 호출 시 read_at최초 열람시간) 데이터가 내려가지 않음.
+//      * 
+// * @param reqDTO KkotalkApiDTO.EnvelopeStatusResponse +// * @return ApiResponseDTO +// */ +// @Operation(summary = "문서열람처리(문서 상태 변경)", description = "문서열람처리(문서 상태 변경)") +// @PostMapping(value = "/modifyStatus", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) +// public IApiResponse modifyStatus( +// @RequestBody final KkotalkApiDTO.EnvelopeId reqDTO +// ) { +// service.modifyStatus(reqDTO); +// return ApiResponseDTO.empty(); +// } +// +// /** +// *
+//      * 문서 상태 조회 API
+//      * -.이용기관 서버에서 카카오페이 전자문서 서버로 문서 상태에 대한 조회를 요청 합니다.
+//      * : 발송된 문서의 진행상태를 알고 싶은 경우, flow와 상관없이 요청 가능
+//      * : polling 방식으로 호출할 경우, 호출 간격은 5초를 권장.
+//      * -.doc_box_status 상태변경순서
+//      * : SENT(송신) > RECEIVED(수신) > READ(열람)/EXPIRED(미열람자료의 기한만료)
+//      * 
+// * @param reqDTO KkotalkDTO.EnvelopeId +// * @return ApiResponseDTO +// */ +// @Operation(summary = "문서 상태 조회", description = "문서 상태 조회") +// @PostMapping(value = "/findStatus", produces = MediaType.APPLICATION_JSON_VALUE) +// public IApiResponse findStatus( +// @RequestBody final KkotalkApiDTO.EnvelopeId reqDTO +// ) { +// return ApiResponseDTO.success(service.findStatus(reqDTO)); +// } +// +// @Operation(summary = "대량 문서발송 요청 -> batch sendBulks 에서 호출", description = "카카오페이 전자문서 서버로 대량 문서발송 처리를 요청 -> batch sendBulks 에서 호출") +// @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { +// @Content(mediaType = "application/json", examples = { +// @ExampleObject( +// name = "D10", +// value = "{\n" + +// " \"productCode\": \"D10_1\",\n" + +// " \"signguCode\": \"51110\",\n" + +// " \"ffnlgCode\": \"11\",\n" + +// " \"envelopes\": [\n" + +// " {\n" + +// " \"title\": \"전자문서\",\n" + +// " \"content\": {\n" + +// " \"html\": \"

MyFirstHeading

Myfirstparagraph.

\"\n" + +// " },\n" + +// " \"guide\": \"국민연금 공단에서 보내는 문서입니다.\",\n" + +// " \"readExpiresAt\": \"2024-12-31T10:00:00\",\n" + +// " \"reviewExpiresAt\": \"2025-03-31T13:00:00\",\n" + +// " \"phoneNumber\": \"01099999999\",\n" + +// " \"name\": \"홍길동\",\n" + +// " \"birthday\": \"20000303\",\n" + +// " \"externalId\": \"external_id1\"\n" + +// " },\n" + +// " {\n" + +// " \"title\": \"전자문서\",\n" + +// " \"content\": {\n" + +// " \"html\": \"

MyFirstHeading

Myfirstparagraph.

\"\n" + +// " },\n" + +// " \"guide\": \"국민연금 공단에서 보내는 문서입니다.\",\n" + +// " \"readExpiresAt\": \"2024-12-31T10:00:00\",\n" + +// " \"reviewExpiresAt\": \"2025-03-31T13:00:00\",\n" + +// " \"hash\": \"b0c34fdc5e2ecb0335919fdad3b2ada28fa3ab90ec16e9055c3e9e05c431c6e8\",\n" + +// " \"ci\": \"vMtqVxJX56lBgbf9heK3QTc+jVndTfK77i/UJKAzPmBG4n9CazCdd/8YytlFZnN4qofIqgxHpSoiG0yYzgEpJg==\",\n" + +// " \"externalId\": \"external_id2\"\n" + +// " }\n" + +// " ]\n" + +// "}" +// ), +// @ExampleObject( +// name = "D11", +// value = "{\n" + +// " \"productCode\": \"D11_1\",\n" + +// " \"signguCode\": \"51110\",\n" + +// " \"ffnlgCode\": \"11\",\n" + +// " \"envelopes\": [\n" + +// " {\n" + +// " \"title\": \"전자문서\",\n" + +// " \"content\": {\n" + +// " \"link\": \"https://nps.or.kr\"\n" + +// " },\n" + +// " \"guide\": \"국민연금 공단에서 보내는 문서입니다.\",\n" + +// " \"payload\": \"이용기관 페이로드\",\n" + +// " \"readExpiresAt\": \"2024-12-31T10:00:00\",\n" + +// " \"reviewExpiresAt\": \"2025-03-31T13:00:00\",\n" + +// " \"phoneNumber\": \"01099999999\",\n" + +// " \"name\": \"홍길동\",\n" + +// " \"birthday\": \"20000303\",\n" + +// " \"externalId\": \"external_id1\"\n" + +// " },\n" + +// " {\n" + +// " \"title\": \"전자문서\",\n" + +// " \"content\": {\n" + +// " \"link\": \"https://nps.or.kr\"\n" + +// " },\n" + +// " \"guide\": \"국민연금 공단에서 보내는 문서입니다.\",\n" + +// " \"payload\": \"이용기관 페이로드\",\n" + +// " \"readExpiresAt\": \"2024-12-31T10:00:00\",\n" + +// " \"reviewExpiresAt\": \"2025-03-31T13:00:00\",\n" + +// " \"ci\": \"${CI}\",\n" + +// " \"externalId\": \"external_id2\"\n" + +// " }\n" + +// " ]\n" + +// "}" +// ) +// }) +// }) +// @PostMapping(value = "/envelopes/bulk", produces = MediaType.APPLICATION_JSON_VALUE) +// public IApiResponse requestSendBulk( +// @RequestBody final KkotalkDTO.BulkSendRequest reqDTO +// ) { +// return ApiResponseDTO.success(service.requestSendBulk(reqDTO)); +// } +// +// /** +// *
+//      * 모바일웹 연계 문서발송 요청
+//      * -.이용기관 서버에서 전자문서 서버로 문서발송 처리를 요청합니다.
+//      * 
+// * @param reqDTO KkotalkApiDTO.BulkStatusRequest +// * @return KkotalkApiDTO.BulkStatusResponse +// */ +// @Operation(summary = "대량 문서 상태 조회 요청 -> batch statusBulks 에서 호출", description = "카카오페이 전자문서 서버로 대량 문서 상태 조회 요청 -> batch statusBulks 에서 호출") +// @PostMapping(value = "/envelopes/bulk/status", produces = MediaType.APPLICATION_JSON_VALUE) +// public IApiResponse findBulkStatus( +// @RequestBody final KkotalkDTO.BulkStatusRequest reqDTO +// ) { +// return ApiResponseDTO.success(service.findBulkStatus(reqDTO)); +// } +// } diff --git a/src/main/resources/mybatis-mapper/modules/iup-kkotalk-mapper.xml b/src/main/resources/mybatis-mapper/modules/iup-kkotalk-mapper.xml index f636d92..2bb978b 100644 --- a/src/main/resources/mybatis-mapper/modules/iup-kkotalk-mapper.xml +++ b/src/main/resources/mybatis-mapper/modules/iup-kkotalk-mapper.xml @@ -88,15 +88,25 @@ WHERE send_detail_id = #{sendDetailId} - + + /** iup-kkotalk-mapper|updateKakaotalkStatusBulksResult-카카오톡 문서 상태조회 결과 반영|limju */ + UPDATE ens_snd_dtl_kko_talk + SET status = #{status} + , sent_at = #{sentAt} + , received_at = #{receivedAt} + , read_at = #{readAt} + , read_expires_at = #{readExpiredAt} + , authenticated_at = #{authenticatedAt} + , ott_verified_at = #{ottVerifiedAt} + , user_notified_at = #{userNotifiedAt} + , distribution_received_at = #{distributionReceivedAt} + , payload = #{payload} + , error_code = #{errorCode} + , error_message = #{errorMessage} + , last_updt_dt = sysdate + WHERE send_detail_id = #{sendDetailId} + +