add content api

This commit is contained in:
박서은 2025-06-17 15:08:46 +09:00
parent b34277c9bd
commit d77f6843ff
12 changed files with 38 additions and 143 deletions

View File

@ -60,18 +60,16 @@ public class ContentQueryService implements ContentQueryUseCase {
/**
* 콘텐츠 목록 조회
*
* @param contentType 콘텐츠 타입
* @param storeId 가게 ID
* @param platform 플랫폼
* @param period 기간
* @param sortBy 정렬 기준
* @return 콘텐츠 목록
*/
@Override
public List<ContentResponse> getContents(String contentType, String platform, String period, String sortBy) {
ContentType type = contentType != null ? ContentType.fromString(contentType) : null;
public List<ContentResponse> getContents(Long storeId, String platform) {
Platform platformEnum = platform != null ? Platform.fromString(platform) : null;
List<Content> contents = contentRepository.findByFilters(type, platformEnum, period, sortBy);
List<Content> contents = contentRepository.findByFilters(storeId, platformEnum);
return contents.stream()
.map(this::toContentResponse)

View File

@ -74,6 +74,7 @@ public class SnsContentService implements SnsContentUseCase {
.platform(Platform.fromString(request.getPlatform()))
.title(request.getTitle())
.content(request.getContent())
.contentType(request.getContentType())
.hashtags(request.getHashtags())
.images(request.getImages())
.status(ContentStatus.PUBLISHED)

View File

@ -22,13 +22,12 @@ public interface ContentQueryUseCase {
/**
* 콘텐츠 목록 조회
*
* @param contentType 콘텐츠 타입
* @param storeId 콘텐츠 타입
* @param platform 플랫폼
* @param period 기간
* @param sortBy 정렬 기준
* @return 콘텐츠 목록
*/
List<ContentResponse> getContents(String contentType, String platform, String period, String sortBy);
List<ContentResponse> getContents(Long storeId, String platform);
/**
* 진행 중인 콘텐츠 목록 조회

View File

@ -31,13 +31,12 @@ public interface ContentRepository {
/**
* 필터 조건으로 콘텐츠 목록 조회
* @param contentType 콘텐츠 타입
* @param storeId 콘텐츠 타입
* @param platform 플랫폼
* @param period 기간
* @param sortBy 정렬 기준
* @return 콘텐츠 목록
*/
List<Content> findByFilters(ContentType contentType, Platform platform, String period, String sortBy);
List<Content> findByFilters(Long storeId, Platform platform);
/**
* 진행 중인 콘텐츠 목록 조회

View File

@ -1,38 +0,0 @@
package com.won.smarketing.content.domain.repository;
import com.won.smarketing.content.infrastructure.entity.ContentEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* Spring Data JPA ContentRepository
* JPA 기반 콘텐츠 데이터 접근
*/
@Repository
public interface SpringDataContentRepository extends JpaRepository<ContentEntity, Long> {
/**
* 매장별 콘텐츠 조회
*
* @param storeId 매장 ID
* @return 콘텐츠 목록
*/
List<ContentEntity> findByStoreId(Long storeId);
/**
* 콘텐츠 타입별 조회
*
* @param contentType 콘텐츠 타입
* @return 콘텐츠 목록
*/
List<ContentEntity> findByContentType(String contentType);
/**
* 플랫폼별 조회
*
* @param platform 플랫폼
* @return 콘텐츠 목록
*/
List<ContentEntity> findByPlatform(String platform);
}

View File

@ -1,60 +0,0 @@
package com.won.smarketing.content.infrastructure.entity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.time.LocalDateTime;
/**
* 콘텐츠 엔티티
* 콘텐츠 정보를 데이터베이스에 저장하기 위한 JPA 엔티티
*/
@Entity
@Table(name = "contents")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public class ContentEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "content_type", nullable = false)
private String contentType;
@Column(name = "platform", nullable = false)
private String platform;
@Column(name = "title", nullable = false)
private String title;
@Column(name = "content", columnDefinition = "TEXT")
private String content;
@Column(name = "hashtags")
private String hashtags;
@Column(name = "images", columnDefinition = "TEXT")
private String images;
@Column(name = "status", nullable = false)
private String status;
@Column(name = "store_id", nullable = false)
private Long storeId;
@CreatedDate
@Column(name = "created_at", updatable = false)
private LocalDateTime createdAt;
@LastModifiedDate
@Column(name = "updated_at")
private LocalDateTime updatedAt;
}

View File

@ -23,6 +23,7 @@ import java.util.Date;
public class ContentJpaEntity {
@Id
@Column(name = "content_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

View File

@ -41,9 +41,9 @@ public class ContentMapper {
ContentJpaEntity entity = new ContentJpaEntity();
// 기본 필드 매핑
if (content.getId() != null) {
entity.setId(content.getId());
}
// if (content.getId() != null) {
// entity.setId(content.getId());
// }
entity.setStoreId(content.getStoreId());
entity.setContentType(content.getContentType() != null ? content.getContentType().name() : null);
entity.setPlatform(content.getPlatform() != null ? content.getPlatform().name() : null);

View File

@ -66,20 +66,18 @@ public class JpaContentRepository implements ContentRepository {
/**
* 필터 조건으로 콘텐츠 목록 조회
* @param contentType 콘텐츠 타입
* @param storeId 콘텐츠 타입
* @param platform 플랫폼
* @param period 기간 (현재는 사용하지 않음)
* @param sortBy 정렬 기준 (현재는 사용하지 않음)
*
* @return 도메인 콘텐츠 목록
*/
@Override
public List<Content> findByFilters(ContentType contentType, Platform platform, String period, String sortBy) {
log.debug("Finding contents with filters - contentType: {}, platform: {}", contentType, platform);
public List<Content> findByFilters(Long storeId, Platform platform) {
log.debug("Finding contents with filters - platform: {}", platform);
String contentTypeStr = contentType != null ? contentType.name() : null;
String platformStr = platform != null ? platform.name() : null;
List<ContentJpaEntity> entities = jpaRepository.findByFilters(contentTypeStr, platformStr, null);
List<ContentJpaEntity> entities = jpaRepository.findByFilters(storeId, platformStr);
return entities.stream()
.map(contentMapper::toDomain)

View File

@ -45,19 +45,16 @@ public interface JpaContentRepositoryInterface extends JpaRepository<ContentJpaE
/**
* 필터 조건으로 콘텐츠 목록 조회
* @param contentType 콘텐츠 타입 (null 가능)
* @param storeId 콘텐츠 타입
* @param platform 플랫폼 (null 가능)
* @param status 상태 (null 가능)
* @return 콘텐츠 엔티티 목록
*/
@Query("SELECT c FROM ContentJpaEntity c WHERE " +
"(:contentType IS NULL OR c.contentType = :contentType) AND " +
"(:platform IS NULL OR c.platform = :platform) AND " +
"(:status IS NULL OR c.status = :status) " +
"(c.storeId = :storeId) AND " +
"(:platform IS NULL OR c.platform = :platform)" +
"ORDER BY c.createdAt DESC")
List<ContentJpaEntity> findByFilters(@Param("contentType") String contentType,
@Param("platform") String platform,
@Param("status") String status);
List<ContentJpaEntity> findByFilters(@Param("storeId") Long storeId,
@Param("platform") String platform);
/**
* 진행 중인 콘텐츠 목록 조회 (발행된 상태의 콘텐츠)

View File

@ -101,24 +101,19 @@ public class ContentController {
/**
* 콘텐츠 목록 조회
*
* @param contentType 콘텐츠 타입 필터
* @param storeId 콘텐츠 타입 필터
* @param platform 플랫폼 필터
* @param period 기간 필터
* @param sortBy 정렬 기준
*
* @return 콘텐츠 목록
*/
@Operation(summary = "콘텐츠 목록 조회", description = "다양한 필터와 정렬 옵션으로 콘텐츠 목록을 조회합니다.")
@GetMapping
public ResponseEntity<ApiResponse<List<ContentResponse>>> getContents(
@Parameter(description = "콘텐츠 타입")
@RequestParam(required = false) String contentType,
@Parameter(description = "플랫폼")
@RequestParam(required = false) String platform,
@Parameter(description = "기간")
@RequestParam(required = false) String period,
@Parameter(description = "정렬 기준")
@RequestParam(required = false) String sortBy) {
List<ContentResponse> response = contentQueryUseCase.getContents(contentType, platform, period, sortBy);
@Parameter(description = "가게 ID")
@RequestParam Long storeId) {
List<ContentResponse> response = contentQueryUseCase.getContents(storeId, platform);
return ResponseEntity.ok(ApiResponse.success(response));
}

View File

@ -1,6 +1,7 @@
// smarketing-java/marketing-content/src/main/java/com/won/smarketing/content/presentation/dto/SnsContentSaveRequest.java
package com.won.smarketing.content.presentation.dto;
import com.won.smarketing.content.domain.model.ContentType;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@ -22,14 +23,18 @@ import java.util.List;
@Schema(description = "SNS 콘텐츠 저장 요청")
public class SnsContentSaveRequest {
@Schema(description = "콘텐츠 ID", example = "1", required = true)
@NotNull(message = "콘텐츠 ID는 필수입니다")
private Long contentId;
// @Schema(description = "콘텐츠 ID", example = "1", required = true)
// @NotNull(message = "콘텐츠 ID는 필수입니다")
// private Long contentId;
@Schema(description = "매장 ID", example = "1", required = true)
@NotNull(message = "매장 ID는 필수입니다")
private Long storeId;
@Schema(description = "콘텐트 타입", example = "1", required = true)
@NotNull(message = "콘텐트 타입은 필수입니다")
private ContentType contentType;
@Schema(description = "플랫폼", example = "INSTAGRAM", required = true)
@NotBlank(message = "플랫폼은 필수입니다")
private String platform;