Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bottlenote-admin-api/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.9
1.0.10
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class AdminBannerControllerDocsTest {
fieldWithPath("data[]").type(JsonFieldType.ARRAY).description("배너 목록"),
fieldWithPath("data[].id").type(JsonFieldType.NUMBER).description("배너 ID"),
fieldWithPath("data[].name").type(JsonFieldType.STRING).description("배너명"),
fieldWithPath("data[].mediaType").type(JsonFieldType.STRING).description("미디어 유형 (IMAGE, VIDEO). 프론트엔드에서 img/video 태그 분기용"),
fieldWithPath("data[].bannerType").type(JsonFieldType.STRING).description("배너 유형"),
fieldWithPath("data[].sortOrder").type(JsonFieldType.NUMBER).description("정렬 순서"),
fieldWithPath("data[].isActive").type(JsonFieldType.BOOLEAN).description("활성화 상태"),
Expand Down Expand Up @@ -147,6 +148,7 @@ class AdminBannerControllerDocsTest {
fieldWithPath("data.textPosition").type(JsonFieldType.STRING).description("텍스트 위치 (RT/CENTER/LB 등)"),
fieldWithPath("data.isExternalUrl").type(JsonFieldType.BOOLEAN).description("외부 URL 여부"),
fieldWithPath("data.targetUrl").type(JsonFieldType.VARIES).description("이동 URL. [주의] URL 형식 검증을 수행하지 않으므로 클라이언트에서 유효한 URL을 전달해야 합니다").optional(),
fieldWithPath("data.mediaType").type(JsonFieldType.STRING).description("미디어 유형 (IMAGE, VIDEO). 프론트엔드에서 img/video 태그 분기용"),
fieldWithPath("data.bannerType").type(JsonFieldType.STRING).description("배너 유형"),
fieldWithPath("data.sortOrder").type(JsonFieldType.NUMBER).description("정렬 순서"),
fieldWithPath("data.startDate").type(JsonFieldType.VARIES).description("시작일시").optional(),
Expand Down Expand Up @@ -202,6 +204,7 @@ class AdminBannerControllerDocsTest {
fieldWithPath("textPosition").type(JsonFieldType.STRING).description("텍스트 위치 (RT/CENTER/LB 등, 기본값: RT)").optional(),
fieldWithPath("isExternalUrl").type(JsonFieldType.BOOLEAN).description("외부 URL 여부 (기본값: false)").optional(),
fieldWithPath("targetUrl").type(JsonFieldType.VARIES).description("이동 URL (isExternalUrl=true 시 필수). [주의] URL 형식 검증을 수행하지 않으므로 클라이언트에서 유효한 URL을 전달해야 합니다").optional(),
fieldWithPath("mediaType").type(JsonFieldType.STRING).description("미디어 유형 (IMAGE/VIDEO, 기본값: IMAGE). 프론트엔드에서 img/video 태그 분기용").optional(),
fieldWithPath("bannerType").type(JsonFieldType.STRING).description("배너 유형 (필수: CURATION/AD/SURVEY/PARTNERSHIP/ETC)"),
fieldWithPath("sortOrder").type(JsonFieldType.NUMBER).description("정렬 순서 (0 이상, 기본값: 0)").optional(),
fieldWithPath("startDate").type(JsonFieldType.VARIES).description("시작일시").optional(),
Expand Down Expand Up @@ -266,6 +269,7 @@ class AdminBannerControllerDocsTest {
fieldWithPath("textPosition").type(JsonFieldType.STRING).description("텍스트 위치 (RT/CENTER/LB 등)"),
fieldWithPath("isExternalUrl").type(JsonFieldType.BOOLEAN).description("외부 URL 여부"),
fieldWithPath("targetUrl").type(JsonFieldType.VARIES).description("이동 URL (isExternalUrl=true 시 필수). [주의] URL 형식 검증을 수행하지 않으므로 클라이언트에서 유효한 URL을 전달해야 합니다").optional(),
fieldWithPath("mediaType").type(JsonFieldType.STRING).description("미디어 유형 (IMAGE/VIDEO, 미입력 시 기존 값 유지). 프론트엔드에서 img/video 태그 분기용").optional(),
fieldWithPath("bannerType").type(JsonFieldType.STRING).description("배너 유형 (필수: CURATION/AD/SURVEY/PARTNERSHIP/ETC)"),
fieldWithPath("sortOrder").type(JsonFieldType.NUMBER).description("정렬 순서 (0 이상, 필수)"),
fieldWithPath("startDate").type(JsonFieldType.VARIES).description("시작일시").optional(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class AdminImageUploadControllerDocsTest {
.header("Authorization", "Bearer test_access_token")
.param("rootPath", "admin/banner")
.param("uploadSize", "2")
.param("contentType", "image/jpeg")
)
.hasStatusOk()
.apply(
Expand All @@ -92,7 +93,8 @@ class AdminImageUploadControllerDocsTest {
),
queryParameters(
parameterWithName("rootPath").description("업로드 경로 (예: admin/banner, admin/alcohol)"),
parameterWithName("uploadSize").description("발급할 URL 개수")
parameterWithName("uploadSize").description("발급할 URL 개수"),
parameterWithName("contentType").description("업로드 파일의 Content-Type. 허용 목록: image/jpeg, image/png, image/webp, image/gif, image/svg+xml, video/mp4, application/pdf. 업로드(PUT) 요청 시 동일한 Content-Type 헤더 필요").optional()
),
responseFields(
fieldWithPath("success").type(JsonFieldType.BOOLEAN).description("응답 성공 여부"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app.helper.banner

import app.bottlenote.banner.constant.BannerType
import app.bottlenote.banner.constant.MediaType
import app.bottlenote.banner.constant.TextPosition
import app.bottlenote.banner.dto.response.AdminBannerDetailResponse
import app.bottlenote.banner.dto.response.AdminBannerListResponse
Expand All @@ -12,14 +13,15 @@ object BannerHelper {
fun createAdminBannerListResponse(
id: Long = 1L,
name: String = "테스트 배너",
mediaType: MediaType = MediaType.IMAGE,
bannerType: BannerType = BannerType.CURATION,
sortOrder: Int = 0,
isActive: Boolean = true,
startDate: LocalDateTime? = null,
endDate: LocalDateTime? = null,
createdAt: LocalDateTime = LocalDateTime.of(2024, 1, 1, 0, 0)
): AdminBannerListResponse = AdminBannerListResponse(
id, name, bannerType, sortOrder, isActive, startDate, endDate, createdAt
id, name, mediaType, bannerType, sortOrder, isActive, startDate, endDate, createdAt
)

fun createAdminBannerListResponses(count: Int = 3): List<AdminBannerListResponse> =
Expand All @@ -43,6 +45,7 @@ object BannerHelper {
textPosition: TextPosition = TextPosition.RT,
isExternalUrl: Boolean = false,
targetUrl: String? = null,
mediaType: MediaType = MediaType.IMAGE,
bannerType: BannerType = BannerType.CURATION,
sortOrder: Int = 0,
startDate: LocalDateTime? = null,
Expand All @@ -52,7 +55,7 @@ object BannerHelper {
modifiedAt: LocalDateTime = LocalDateTime.of(2024, 6, 1, 0, 0)
): AdminBannerDetailResponse = AdminBannerDetailResponse(
id, name, nameFontColor, descriptionA, descriptionB, descriptionFontColor,
imageUrl, textPosition, isExternalUrl, targetUrl, bannerType, sortOrder,
imageUrl, textPosition, isExternalUrl, targetUrl, mediaType, bannerType, sortOrder,
startDate, endDate, isActive, createdAt, modifiedAt
)

Expand All @@ -66,6 +69,7 @@ object BannerHelper {
textPosition: String = "RT",
isExternalUrl: Boolean = false,
targetUrl: String? = null,
mediaType: String = "IMAGE",
bannerType: String = "CURATION",
sortOrder: Int = 0,
startDate: String? = null,
Expand All @@ -80,6 +84,7 @@ object BannerHelper {
"textPosition" to textPosition,
"isExternalUrl" to isExternalUrl,
"targetUrl" to targetUrl,
"mediaType" to mediaType,
"bannerType" to bannerType,
"sortOrder" to sortOrder,
"startDate" to startDate,
Expand All @@ -96,6 +101,7 @@ object BannerHelper {
textPosition: String = "CENTER",
isExternalUrl: Boolean = false,
targetUrl: String? = null,
mediaType: String = "IMAGE",
bannerType: String = "CURATION",
sortOrder: Int = 1,
startDate: String? = null,
Expand All @@ -111,6 +117,7 @@ object BannerHelper {
"textPosition" to textPosition,
"isExternalUrl" to isExternalUrl,
"targetUrl" to targetUrl,
"mediaType" to mediaType,
"bannerType" to bannerType,
"sortOrder" to sortOrder,
"startDate" to startDate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ class AdminImageUploadIntegrationTest : IntegrationTestSupport() {
return try {
connection.doOutput = true
connection.requestMethod = "PUT"
connection.setRequestProperty("Content-Type", "application/octet-stream")
connection.setRequestProperty("Content-Type", "image/jpeg")

OutputStreamWriter(connection.outputStream).use { writer ->
writer.write(content)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package app.bottlenote.banner.constant;

import com.fasterxml.jackson.annotation.JsonCreator;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum MediaType {
IMAGE("이미지"),
VIDEO("동영상");

private final String description;

@JsonCreator
public static MediaType parsing(String source) {
if (source == null || source.isEmpty()) {
return null;
}
return MediaType.valueOf(source.toUpperCase());
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app.bottlenote.banner.domain;

import app.bottlenote.banner.constant.BannerType;
import app.bottlenote.banner.constant.MediaType;
import app.bottlenote.banner.constant.TextPosition;
import app.bottlenote.common.domain.BaseEntity;
import jakarta.persistence.Column;
Expand Down Expand Up @@ -73,6 +74,12 @@ public class Banner extends BaseEntity {
@Column(name = "target_url")
private String targetUrl;

@Comment("미디어 유형")
@Column(name = "media_type", nullable = false)
@Enumerated(EnumType.STRING)
@Builder.Default
private MediaType mediaType = MediaType.IMAGE;

@Comment("배너 유형")
@Column(name = "banner_type", nullable = false)
@Enumerated(EnumType.STRING)
Expand Down Expand Up @@ -106,6 +113,7 @@ public void update(
TextPosition textPosition,
Boolean isExternalUrl,
String targetUrl,
MediaType mediaType,
BannerType bannerType,
Integer sortOrder,
LocalDateTime startDate,
Expand All @@ -120,6 +128,7 @@ public void update(
this.textPosition = textPosition;
this.isExternalUrl = isExternalUrl;
this.targetUrl = targetUrl;
this.mediaType = mediaType != null ? mediaType : this.mediaType;
this.bannerType = bannerType;
this.sortOrder = sortOrder;
this.startDate = startDate;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app.bottlenote.banner.dto.request;

import app.bottlenote.banner.constant.BannerType;
import app.bottlenote.banner.constant.MediaType;
import app.bottlenote.banner.constant.TextPosition;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
Expand All @@ -22,6 +23,7 @@ public record AdminBannerCreateRequest(
TextPosition textPosition,
Boolean isExternalUrl,
String targetUrl,
MediaType mediaType,
@NotNull(message = "BANNER_TYPE_REQUIRED") BannerType bannerType,
@Min(value = 0, message = "BANNER_SORT_ORDER_MINIMUM") Integer sortOrder,
LocalDateTime startDate,
Expand All @@ -33,6 +35,7 @@ public record AdminBannerCreateRequest(
descriptionFontColor = descriptionFontColor != null ? descriptionFontColor : "#ffffff";
textPosition = textPosition != null ? textPosition : TextPosition.RT;
isExternalUrl = isExternalUrl != null ? isExternalUrl : false;
mediaType = mediaType != null ? mediaType : MediaType.IMAGE;
sortOrder = sortOrder != null ? sortOrder : 0;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app.bottlenote.banner.dto.request;

import app.bottlenote.banner.constant.BannerType;
import app.bottlenote.banner.constant.MediaType;
import app.bottlenote.banner.constant.TextPosition;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
Expand All @@ -21,6 +22,7 @@ public record AdminBannerUpdateRequest(
TextPosition textPosition,
Boolean isExternalUrl,
String targetUrl,
MediaType mediaType,
@NotNull(message = "BANNER_TYPE_REQUIRED") BannerType bannerType,
@NotNull(message = "BANNER_SORT_ORDER_REQUIRED")
@Min(value = 0, message = "BANNER_SORT_ORDER_MINIMUM")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app.bottlenote.banner.dto.response;

import app.bottlenote.banner.constant.BannerType;
import app.bottlenote.banner.constant.MediaType;
import app.bottlenote.banner.constant.TextPosition;
import java.time.LocalDateTime;

Expand All @@ -15,6 +16,7 @@ public record AdminBannerDetailResponse(
TextPosition textPosition,
Boolean isExternalUrl,
String targetUrl,
MediaType mediaType,
BannerType bannerType,
Integer sortOrder,
LocalDateTime startDate,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package app.bottlenote.banner.dto.response;

import app.bottlenote.banner.constant.BannerType;
import app.bottlenote.banner.constant.MediaType;
import java.time.LocalDateTime;

public record AdminBannerListResponse(
Long id,
String name,
MediaType mediaType,
BannerType bannerType,
Integer sortOrder,
Boolean isActive,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app.bottlenote.banner.dto.response;

import app.bottlenote.banner.constant.BannerType;
import app.bottlenote.banner.constant.MediaType;
import app.bottlenote.banner.constant.TextPosition;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
Expand All @@ -24,6 +25,7 @@ public class BannerResponse {
private TextPosition textPosition;
private String targetUrl;
private Boolean isExternalUrl;
private MediaType mediaType;
private BannerType bannerType;
private Integer sortOrder;
private LocalDateTime startDate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public Page<AdminBannerListResponse> searchForAdmin(
AdminBannerListResponse.class,
banner.id,
banner.name,
banner.mediaType,
banner.bannerType,
banner.sortOrder,
banner.isActive,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public AdminBannerDetailResponse getDetail(Long bannerId) {
banner.getTextPosition(),
banner.getIsExternalUrl(),
banner.getTargetUrl(),
banner.getMediaType(),
banner.getBannerType(),
banner.getSortOrder(),
banner.getStartDate(),
Expand Down Expand Up @@ -93,6 +94,7 @@ public AdminResultResponse create(AdminBannerCreateRequest request) {
.textPosition(request.textPosition())
.isExternalUrl(request.isExternalUrl())
.targetUrl(request.targetUrl())
.mediaType(request.mediaType())
.bannerType(request.bannerType())
.sortOrder(request.sortOrder())
.startDate(request.startDate())
Expand Down Expand Up @@ -130,6 +132,7 @@ public AdminResultResponse update(Long bannerId, AdminBannerUpdateRequest reques
request.textPosition(),
request.isExternalUrl(),
request.targetUrl(),
request.mediaType(),
request.bannerType(),
request.sortOrder(),
request.startDate(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public List<BannerResponse> getActiveBanners(Integer limit) {
.textPosition(banner.getTextPosition())
.targetUrl(banner.getTargetUrl())
.isExternalUrl(banner.getIsExternalUrl())
.mediaType(banner.getMediaType())
.bannerType(banner.getBannerType())
.sortOrder(banner.getSortOrder())
.startDate(banner.getStartDate())
Expand Down
Loading
Loading