store update
This commit is contained in:
parent
fc43d07e47
commit
cb1ab34a39
@ -0,0 +1,251 @@
|
||||
package com.ktds.hi.store.biz.service;
|
||||
|
||||
import com.ktds.hi.store.biz.usecase.in.ExternalIntegrationUseCase;
|
||||
import com.ktds.hi.store.biz.usecase.out.ExternalPlatformPort;
|
||||
import com.ktds.hi.store.biz.usecase.out.EventPort;
|
||||
import com.ktds.hi.store.infra.dto.ExternalSyncRequest;
|
||||
import com.ktds.hi.store.infra.dto.ExternalSyncResponse;
|
||||
import com.ktds.hi.store.infra.dto.ExternalConnectRequest;
|
||||
import com.ktds.hi.store.infra.dto.ExternalConnectResponse;
|
||||
import com.ktds.hi.common.exception.BusinessException;
|
||||
import com.ktds.hi.common.exception.ExternalServiceException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 외부 연동 인터랙터 클래스
|
||||
* 외부 플랫폼 연동 비즈니스 로직을 구현
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@Transactional
|
||||
public class ExternalIntegrationInteractor implements ExternalIntegrationUseCase {
|
||||
|
||||
private final ExternalPlatformPort externalPlatformPort;
|
||||
private final EventPort eventPort;
|
||||
|
||||
@Override
|
||||
public ExternalSyncResponse syncReviews(Long storeId, ExternalSyncRequest request) {
|
||||
log.info("외부 플랫폼 리뷰 동기화 시작: storeId={}, platform={}", storeId, request.getPlatform());
|
||||
|
||||
try {
|
||||
validateSyncRequest(storeId, request);
|
||||
|
||||
int syncedCount = 0;
|
||||
|
||||
// 플랫폼별 리뷰 동기화
|
||||
switch (request.getPlatform().toUpperCase()) {
|
||||
case "NAVER":
|
||||
syncedCount = externalPlatformPort.syncNaverReviews(storeId, request.getExternalStoreId());
|
||||
break;
|
||||
case "KAKAO":
|
||||
syncedCount = externalPlatformPort.syncKakaoReviews(storeId, request.getExternalStoreId());
|
||||
break;
|
||||
case "GOOGLE":
|
||||
syncedCount = externalPlatformPort.syncGoogleReviews(storeId, request.getExternalStoreId());
|
||||
break;
|
||||
case "HIORDER":
|
||||
syncedCount = externalPlatformPort.syncHiorderReviews(storeId, request.getExternalStoreId());
|
||||
break;
|
||||
default:
|
||||
throw new BusinessException("지원하지 않는 플랫폼입니다: " + request.getPlatform());
|
||||
}
|
||||
|
||||
// 동기화 이벤트 발행
|
||||
publishSyncEvent(storeId, request.getPlatform(), syncedCount);
|
||||
|
||||
log.info("외부 플랫폼 리뷰 동기화 완료: storeId={}, platform={}, syncedCount={}",
|
||||
storeId, request.getPlatform(), syncedCount);
|
||||
|
||||
return ExternalSyncResponse.builder()
|
||||
.success(true)
|
||||
.message(String.format("%s 플랫폼에서 %d개의 리뷰를 성공적으로 동기화했습니다",
|
||||
request.getPlatform(), syncedCount))
|
||||
.syncedCount(syncedCount)
|
||||
.build();
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("외부 플랫폼 리뷰 동기화 실패: storeId={}, platform={}, error={}",
|
||||
storeId, request.getPlatform(), e.getMessage(), e);
|
||||
|
||||
throw new ExternalServiceException(request.getPlatform(),
|
||||
"리뷰 동기화 중 오류가 발생했습니다: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExternalConnectResponse connectPlatform(Long storeId, ExternalConnectRequest request) {
|
||||
log.info("외부 플랫폼 계정 연동 시작: storeId={}, platform={}", storeId, request.getPlatform());
|
||||
|
||||
try {
|
||||
validateConnectRequest(storeId, request);
|
||||
|
||||
boolean connected = false;
|
||||
|
||||
// 플랫폼별 계정 연동
|
||||
switch (request.getPlatform().toUpperCase()) {
|
||||
case "NAVER":
|
||||
connected = externalPlatformPort.connectNaverAccount(storeId,
|
||||
request.getUsername(), request.getPassword());
|
||||
break;
|
||||
case "KAKAO":
|
||||
connected = externalPlatformPort.connectKakaoAccount(storeId,
|
||||
request.getUsername(), request.getPassword());
|
||||
break;
|
||||
case "GOOGLE":
|
||||
connected = externalPlatformPort.connectGoogleAccount(storeId,
|
||||
request.getUsername(), request.getPassword());
|
||||
break;
|
||||
case "HIORDER":
|
||||
connected = externalPlatformPort.connectHiorderAccount(storeId,
|
||||
request.getUsername(), request.getPassword());
|
||||
break;
|
||||
default:
|
||||
throw new BusinessException("지원하지 않는 플랫폼입니다: " + request.getPlatform());
|
||||
}
|
||||
|
||||
if (connected) {
|
||||
// 연동 성공 이벤트 발행
|
||||
publishConnectEvent(storeId, request.getPlatform());
|
||||
|
||||
log.info("외부 플랫폼 계정 연동 완료: storeId={}, platform={}", storeId, request.getPlatform());
|
||||
|
||||
return ExternalConnectResponse.builder()
|
||||
.success(true)
|
||||
.message(request.getPlatform() + " 계정이 성공적으로 연동되었습니다")
|
||||
.build();
|
||||
} else {
|
||||
throw new ExternalServiceException(request.getPlatform(), "계정 인증에 실패했습니다");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("외부 플랫폼 계정 연동 실패: storeId={}, platform={}, error={}",
|
||||
storeId, request.getPlatform(), e.getMessage(), e);
|
||||
|
||||
return ExternalConnectResponse.builder()
|
||||
.success(false)
|
||||
.message("계정 연동에 실패했습니다: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExternalConnectResponse disconnectPlatform(Long storeId, String platform) {
|
||||
log.info("외부 플랫폼 연동 해제: storeId={}, platform={}", storeId, platform);
|
||||
|
||||
try {
|
||||
// 연동 해제 로직 구현
|
||||
boolean disconnected = externalPlatformPort.disconnectPlatform(storeId, platform);
|
||||
|
||||
if (disconnected) {
|
||||
// 연동 해제 이벤트 발행
|
||||
publishDisconnectEvent(storeId, platform);
|
||||
|
||||
return ExternalConnectResponse.builder()
|
||||
.success(true)
|
||||
.message(platform + " 플랫폼 연동이 해제되었습니다")
|
||||
.build();
|
||||
} else {
|
||||
throw new ExternalServiceException(platform, "연동 해제에 실패했습니다");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("외부 플랫폼 연동 해제 실패: storeId={}, platform={}, error={}",
|
||||
storeId, platform, e.getMessage(), e);
|
||||
|
||||
return ExternalConnectResponse.builder()
|
||||
.success(false)
|
||||
.message("연동 해제에 실패했습니다: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ExternalConnectResponse getConnectedPlatforms(Long storeId) {
|
||||
log.info("연동된 플랫폼 목록 조회: storeId={}", storeId);
|
||||
|
||||
try {
|
||||
// 연동된 플랫폼 목록 조회 로직
|
||||
// 실제로는 ExternalPlatformEntity에서 조회
|
||||
|
||||
return ExternalConnectResponse.builder()
|
||||
.success(true)
|
||||
.message("연동된 플랫폼 목록을 조회했습니다")
|
||||
.build();
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("연동된 플랫폼 목록 조회 실패: storeId={}, error={}", storeId, e.getMessage(), e);
|
||||
|
||||
return ExternalConnectResponse.builder()
|
||||
.success(false)
|
||||
.message("플랫폼 목록 조회에 실패했습니다: " + e.getMessage())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// Private helper methods
|
||||
|
||||
private void validateSyncRequest(Long storeId, ExternalSyncRequest request) {
|
||||
if (storeId == null) {
|
||||
throw new BusinessException("매장 ID는 필수입니다");
|
||||
}
|
||||
|
||||
if (request.getPlatform() == null || request.getPlatform().trim().isEmpty()) {
|
||||
throw new BusinessException("플랫폼 정보는 필수입니다");
|
||||
}
|
||||
|
||||
if (request.getExternalStoreId() == null || request.getExternalStoreId().trim().isEmpty()) {
|
||||
throw new BusinessException("외부 매장 ID는 필수입니다");
|
||||
}
|
||||
}
|
||||
|
||||
private void validateConnectRequest(Long storeId, ExternalConnectRequest request) {
|
||||
if (storeId == null) {
|
||||
throw new BusinessException("매장 ID는 필수입니다");
|
||||
}
|
||||
|
||||
if (request.getPlatform() == null || request.getPlatform().trim().isEmpty()) {
|
||||
throw new BusinessException("플랫폼 정보는 필수입니다");
|
||||
}
|
||||
|
||||
if (request.getUsername() == null || request.getUsername().trim().isEmpty()) {
|
||||
throw new BusinessException("사용자명은 필수입니다");
|
||||
}
|
||||
|
||||
if (request.getPassword() == null || request.getPassword().trim().isEmpty()) {
|
||||
throw new BusinessException("비밀번호는 필수입니다");
|
||||
}
|
||||
}
|
||||
|
||||
private void publishSyncEvent(Long storeId, String platform, int syncedCount) {
|
||||
try {
|
||||
// 동기화 이벤트 발행 로직
|
||||
log.info("동기화 이벤트 발행: storeId={}, platform={}, syncedCount={}",
|
||||
storeId, platform, syncedCount);
|
||||
} catch (Exception e) {
|
||||
log.warn("동기화 이벤트 발행 실패: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void publishConnectEvent(Long storeId, String platform) {
|
||||
try {
|
||||
// 연동 이벤트 발행 로직
|
||||
log.info("연동 이벤트 발행: storeId={}, platform={}", storeId, platform);
|
||||
} catch (Exception e) {
|
||||
log.warn("연동 이벤트 발행 실패: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void publishDisconnectEvent(Long storeId, String platform) {
|
||||
try {
|
||||
// 연동 해제 이벤트 발행 로직
|
||||
log.info("연동 해제 이벤트 발행: storeId={}, platform={}", storeId, platform);
|
||||
} catch (Exception e) {
|
||||
log.warn("연동 해제 이벤트 발행 실패: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
package com.ktds.hi.store.biz.service;
|
||||
|
||||
public class ExternalIntegrationUseCase {
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package com.ktds.hi.store.biz.usecase.in;
|
||||
|
||||
import com.ktds.hi.store.infra.dto.ExternalSyncRequest;
|
||||
import com.ktds.hi.store.infra.dto.ExternalSyncResponse;
|
||||
import com.ktds.hi.store.infra.dto.ExternalConnectRequest;
|
||||
import com.ktds.hi.store.infra.dto.ExternalConnectResponse;
|
||||
|
||||
/**
|
||||
* 외부 연동 유스케이스 인터페이스
|
||||
* 외부 플랫폼 연동 관련 비즈니스 로직을 정의
|
||||
*/
|
||||
public interface ExternalIntegrationUseCase {
|
||||
|
||||
/**
|
||||
* 외부 플랫폼 리뷰 동기화
|
||||
*/
|
||||
ExternalSyncResponse syncReviews(Long storeId, ExternalSyncRequest request);
|
||||
|
||||
/**
|
||||
* 외부 플랫폼 계정 연동
|
||||
*/
|
||||
ExternalConnectResponse connectPlatform(Long storeId, ExternalConnectRequest request);
|
||||
|
||||
/**
|
||||
* 외부 플랫폼 연동 해제
|
||||
*/
|
||||
ExternalConnectResponse disconnectPlatform(Long storeId, String platform);
|
||||
|
||||
/**
|
||||
* 연동된 플랫폼 목록 조회
|
||||
*/
|
||||
ExternalConnectResponse getConnectedPlatforms(Long storeId);
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
package com.ktds.hi.store.biz.usecase.out;
|
||||
|
||||
/**
|
||||
* 외부 플랫폼 포트 인터페이스
|
||||
* 외부 플랫폼 연동 기능을 정의
|
||||
*
|
||||
* @author 하이오더 개발팀
|
||||
* @version 1.0.0
|
||||
*/
|
||||
public interface ExternalPlatformPort {
|
||||
|
||||
/**
|
||||
* 네이버 리뷰 동기화
|
||||
*
|
||||
* @param storeId 매장 ID
|
||||
* @param externalStoreId 외부 매장 ID
|
||||
* @return 동기화된 리뷰 수
|
||||
*/
|
||||
int syncNaverReviews(Long storeId, String externalStoreId);
|
||||
|
||||
/**
|
||||
* 카카오 리뷰 동기화
|
||||
*
|
||||
* @param storeId 매장 ID
|
||||
* @param externalStoreId 외부 매장 ID
|
||||
* @return 동기화된 리뷰 수
|
||||
*/
|
||||
int syncKakaoReviews(Long storeId, String externalStoreId);
|
||||
|
||||
/**
|
||||
* 구글 리뷰 동기화
|
||||
*
|
||||
* @param storeId 매장 ID
|
||||
* @param externalStoreId 외부 매장 ID
|
||||
* @return 동기화된 리뷰 수
|
||||
*/
|
||||
int syncGoogleReviews(Long storeId, String externalStoreId);
|
||||
|
||||
/**
|
||||
* 하이오더 리뷰 동기화
|
||||
*
|
||||
* @param storeId 매장 ID
|
||||
* @param externalStoreId 외부 매장 ID
|
||||
* @return 동기화된 리뷰 수
|
||||
*/
|
||||
int syncHiorderReviews(Long storeId, String externalStoreId);
|
||||
|
||||
/**
|
||||
* 네이버 계정 연동
|
||||
*
|
||||
* @param storeId 매장 ID
|
||||
* @param username 사용자명
|
||||
* @param password 비밀번호
|
||||
* @return 연동 성공 여부
|
||||
*/
|
||||
boolean connectNaverAccount(Long storeId, String username, String password);
|
||||
|
||||
/**
|
||||
* 카카오 계정 연동
|
||||
*
|
||||
* @param storeId 매장 ID
|
||||
* @param username 사용자명
|
||||
* @param password 비밀번호
|
||||
* @return 연동 성공 여부
|
||||
*/
|
||||
boolean connectKakaoAccount(Long storeId, String username, String password);
|
||||
|
||||
/**
|
||||
* 구글 계정 연동
|
||||
*
|
||||
* @param storeId 매장 ID
|
||||
* @param username 사용자명
|
||||
* @param password 비밀번호
|
||||
* @return 연동 성공 여부
|
||||
*/
|
||||
boolean connectGoogleAccount(Long storeId, String username, String password);
|
||||
|
||||
/**
|
||||
* 하이오더 계정 연동
|
||||
*
|
||||
* @param storeId 매장 ID
|
||||
* @param username 사용자명
|
||||
* @param password 비밀번호
|
||||
* @return 연동 성공 여부
|
||||
*/
|
||||
boolean connectHiorderAccount(Long storeId, String username, String password);
|
||||
|
||||
/**
|
||||
* 외부 플랫폼 연동 해제
|
||||
*
|
||||
* @param storeId 매장 ID
|
||||
* @param platform 플랫폼명 (NAVER, KAKAO, GOOGLE, HIORDER)
|
||||
* @return 연동 해제 성공 여부
|
||||
*/
|
||||
boolean disconnectPlatform(Long storeId, String platform);
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.ktds.hi.store.infra.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 외부 플랫폼 계정 연동 요청 DTO
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@Schema(description = "외부 플랫폼 계정 연동 요청")
|
||||
public class ExternalConnectRequest {
|
||||
|
||||
@NotBlank(message = "플랫폼 정보는 필수입니다")
|
||||
@Schema(description = "플랫폼 타입", example = "NAVER", allowableValues = {"NAVER", "KAKAO", "GOOGLE", "HIORDER"})
|
||||
private String platform;
|
||||
|
||||
@NotBlank(message = "사용자명은 필수입니다")
|
||||
@Schema(description = "외부 플랫폼 사용자명", example = "store_owner@example.com")
|
||||
private String username;
|
||||
|
||||
@NotBlank(message = "비밀번호는 필수입니다")
|
||||
@Schema(description = "외부 플랫폼 비밀번호", example = "password123")
|
||||
private String password;
|
||||
|
||||
@Schema(description = "추가 인증 정보", example = "api_key_or_token")
|
||||
private String additionalAuth;
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.ktds.hi.store.infra.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 외부 플랫폼 동기화 요청 DTO
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@Schema(description = "외부 플랫폼 동기화 요청")
|
||||
public class ExternalSyncRequest {
|
||||
|
||||
@NotBlank(message = "플랫폼 정보는 필수입니다")
|
||||
@Schema(description = "플랫폼 타입", example = "NAVER", allowableValues = {"NAVER", "KAKAO", "GOOGLE", "HIORDER"})
|
||||
private String platform;
|
||||
|
||||
@NotBlank(message = "외부 매장 ID는 필수입니다")
|
||||
@Schema(description = "외부 플랫폼의 매장 ID", example = "naver_store_12345")
|
||||
private String externalStoreId;
|
||||
|
||||
@Schema(description = "동기화 옵션", example = "FULL")
|
||||
private String syncOption = "FULL"; // FULL, INCREMENTAL
|
||||
|
||||
@Schema(description = "시작 날짜", example = "2024-01-01")
|
||||
private String startDate;
|
||||
|
||||
@Schema(description = "종료 날짜", example = "2024-12-31")
|
||||
private String endDate;
|
||||
}
|
||||
@ -4,15 +4,10 @@ import com.ktds.hi.store.biz.usecase.out.ExternalPlatformPort;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 외부 플랫폼 어댑터 클래스
|
||||
* External Platform Port를 구현하여 외부 API 연동 기능을 제공
|
||||
@ -215,6 +210,79 @@ public class ExternalPlatformAdapter implements ExternalPlatformPort {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean disconnectPlatform(Long storeId, String platform) {
|
||||
log.info("외부 플랫폼 연동 해제 시작: storeId={}, platform={}", storeId, platform);
|
||||
|
||||
try {
|
||||
// 플랫폼별 연동 해제 로직
|
||||
boolean disconnected = false;
|
||||
|
||||
switch (platform.toUpperCase()) {
|
||||
case "NAVER":
|
||||
disconnected = disconnectNaverAccount(storeId);
|
||||
break;
|
||||
case "KAKAO":
|
||||
disconnected = disconnectKakaoAccount(storeId);
|
||||
break;
|
||||
case "GOOGLE":
|
||||
disconnected = disconnectGoogleAccount(storeId);
|
||||
break;
|
||||
case "HIORDER":
|
||||
disconnected = disconnectHiorderAccount(storeId);
|
||||
break;
|
||||
default:
|
||||
log.warn("지원하지 않는 플랫폼: {}", platform);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (disconnected) {
|
||||
removeExternalConnection(storeId, platform);
|
||||
}
|
||||
|
||||
log.info("외부 플랫폼 연동 해제 완료: storeId={}, platform={}, disconnected={}",
|
||||
storeId, platform, disconnected);
|
||||
return disconnected;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("외부 플랫폼 연동 해제 실패: storeId={}, platform={}, error={}",
|
||||
storeId, platform, e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 네이버 계정 연동 해제
|
||||
*/
|
||||
private boolean disconnectNaverAccount(Long storeId) {
|
||||
// 네이버 연동 해제 로직 (Mock)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 카카오 계정 연동 해제
|
||||
*/
|
||||
private boolean disconnectKakaoAccount(Long storeId) {
|
||||
// 카카오 연동 해제 로직 (Mock)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 구글 계정 연동 해제
|
||||
*/
|
||||
private boolean disconnectGoogleAccount(Long storeId) {
|
||||
// 구글 연동 해제 로직 (Mock)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 하이오더 계정 연동 해제
|
||||
*/
|
||||
private boolean disconnectHiorderAccount(Long storeId) {
|
||||
// 하이오더 연동 해제 로직 (Mock)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 외부 연동 정보 저장
|
||||
*/
|
||||
@ -222,5 +290,12 @@ public class ExternalPlatformAdapter implements ExternalPlatformPort {
|
||||
// 실제로는 ExternalPlatformEntity에 연동 정보 저장
|
||||
log.info("외부 연동 정보 저장: storeId={}, platform={}, username={}", storeId, platform, username);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 외부 연동 정보 제거
|
||||
*/
|
||||
private void removeExternalConnection(Long storeId, String platform) {
|
||||
// 실제로는 ExternalPlatformEntity에서 연동 정보 제거
|
||||
log.info("외부 연동 정보 제거: storeId={}, platform={}", storeId, platform);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user