Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT/#293] 배너 수정 API 구현 #294

Merged
merged 9 commits into from
Jan 18, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import org.sopt.makers.operation.dto.BaseResponse;

import org.sopt.makers.operation.web.banner.dto.request.*;
import org.sopt.makers.operation.web.banner.dto.request.BannerRequest;
import org.springframework.http.ResponseEntity;

public interface BannerApi {
Expand Down Expand Up @@ -68,6 +68,24 @@ public interface BannerApi {
)
}
)
ResponseEntity<BaseResponse<?>> createBanner(BannerRequest.BannerCreate request);
ResponseEntity<BaseResponse<?>> createBanner(BannerRequest.BannerCreateOrModify request);

@Operation(
summary = "배너 생성 API",
responses = {
sung-silver marked this conversation as resolved.
Show resolved Hide resolved
@ApiResponse(
responseCode = "200",
description = "배너 수정 성공"
),
@ApiResponse(
responseCode = "400",
description = "잘못된 요청"
),
@ApiResponse(
responseCode = "500",
description = "서버 내부 오류"
)
}
)
ResponseEntity<BaseResponse<?>> updateBanner(Long bannerId, BannerRequest.BannerCreateOrModify request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import static org.sopt.makers.operation.code.success.web.BannerSuccessCode.SUCCESS_CREATE_BANNER;
import static org.sopt.makers.operation.code.success.web.BannerSuccessCode.SUCCESS_GET_BANNER_DETAIL;
import static org.sopt.makers.operation.code.success.web.BannerSuccessCode.SUCCESS_GET_BANNER_IMAGE_PRE_SIGNED_URL;
import static org.sopt.makers.operation.code.success.web.BannerSuccessCode.SUCCESS_UPDATE_BANNER;

@RestController
@RequestMapping("/api/v1/banners")
Expand All @@ -40,8 +41,15 @@ public ResponseEntity<BaseResponse<?>> getIssuedPreSignedUrlForPutImage(@Request

@PostMapping
@Override
public ResponseEntity<BaseResponse<?>> createBanner(@RequestBody BannerRequest.BannerCreate request) {
public ResponseEntity<BaseResponse<?>> createBanner(@RequestBody BannerRequest.BannerCreateOrModify request) {
val response = bannerService.createBanner(request);
return ApiResponseUtil.success(SUCCESS_CREATE_BANNER, response);
}

@PutMapping("/{bannerId}")
@Override
public ResponseEntity<BaseResponse<?>> updateBanner(@PathVariable("bannerId") Long bannerId, BannerRequest.BannerCreateOrModify request) {
val response = bannerService.updateBanner(bannerId, request);
return ApiResponseUtil.success(SUCCESS_UPDATE_BANNER, response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
@RequiredArgsConstructor(access = PRIVATE)
public class BannerRequest {

public record BannerCreate(
public record BannerCreateOrModify(
@JsonProperty("location") String bannerLocation,
@JsonProperty("content_type") String bannerType,
@JsonProperty("publisher") String publisher,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.sopt.makers.operation.web.banner.service;

import org.sopt.makers.operation.web.banner.dto.request.*;
import org.sopt.makers.operation.web.banner.dto.request.BannerRequest;
import org.sopt.makers.operation.web.banner.dto.response.BannerResponse;

public interface BannerService {
Expand All @@ -9,5 +9,7 @@ public interface BannerService {

BannerResponse.ImagePreSignedUrl getIssuedPreSignedUrlForPutImage(String contentName, String imageType, String imageExtension, String contentType);

BannerResponse.BannerDetail createBanner(BannerRequest.BannerCreate request);
BannerResponse.BannerDetail createBanner(BannerRequest.BannerCreateOrModify request);

BannerResponse.BannerDetail updateBanner(Long bannerId, BannerRequest.BannerCreateOrModify request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import org.sopt.makers.operation.code.failure.BannerFailureCode;
import org.sopt.makers.operation.config.ValueConfig;
import org.sopt.makers.operation.exception.BannerException;
import org.sopt.makers.operation.web.banner.dto.request.BannerRequest.*;
import org.sopt.makers.operation.web.banner.dto.request.*;
import org.sopt.makers.operation.web.banner.dto.response.BannerResponse;
import org.sopt.makers.operation.web.banner.dto.response.BannerResponse.*;
import org.springframework.stereotype.Service;
Expand All @@ -20,7 +20,9 @@
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class BannerServiceImpl implements BannerService {

private static final String SLASH = "/";
private static final String PROTOCOL_SEPARATOR = "//";
private static final int PROTOCOL_END_OFFSET = 2;
private final BannerRepository bannerRepository;
private final S3Service s3Service;
private final ValueConfig valueConfig;
Expand Down Expand Up @@ -57,7 +59,7 @@ private String getBannerImageName(String location, String contentName, String im

@Transactional
@Override
public BannerDetail createBanner(BannerCreate request) {
public BannerDetail createBanner(BannerRequest.BannerCreateOrModify request) {
val period = getPublishPeriod(request.startDate(), request.endDate());
val image = getBannerImage(request.pcImage(), request.mobileImage());
val newBanner = Banner.builder()
Expand All @@ -73,6 +75,31 @@ public BannerDetail createBanner(BannerCreate request) {
return BannerResponse.BannerDetail.fromEntity(banner);
}

@Transactional
@Override
public BannerDetail updateBanner(Long bannerId, BannerRequest.BannerCreateOrModify request) {
var banner = getBannerById(bannerId);
val period = getPublishPeriod(request.startDate(), request.endDate());
val image = getBannerImage(request.pcImage(), request.mobileImage());

deleteExistImage(banner.getImage().getPcImageUrl());
deleteExistImage(banner.getImage().getMobileImageUrl());
banner.updatePublisher(request.publisher());
banner.updateLink(request.link());
banner.updateContentType(ContentType.getByValue(request.bannerType()));
banner.updateLocation(PublishLocation.getByValue(request.bannerLocation()));
banner.updatePeriod(period);
banner.updateImage(image);
return BannerResponse.BannerDetail.fromEntity(banner);
}

private void deleteExistImage(String url) {
val protocolEndIndex = url.indexOf(PROTOCOL_SEPARATOR) + PROTOCOL_END_OFFSET;
val firstSlashIndex = url.indexOf(SLASH, protocolEndIndex);
val extractedPath = url.substring(firstSlashIndex);
s3Service.deleteFile(valueConfig.getBannerBucket(), extractedPath);
}

private PublishPeriod getPublishPeriod(LocalDate startDate, LocalDate endDate) {
return PublishPeriod.builder()
.startDate(startDate)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
public enum BannerSuccessCode implements SuccessCode {
SUCCESS_GET_BANNER_DETAIL(HttpStatus.OK, "배너 상세 정보 조회 성공"),
SUCCESS_GET_BANNER_IMAGE_PRE_SIGNED_URL(HttpStatus.OK, "이미지 업로드 pre signed url 조회에 성공했습니다"),
SUCCESS_UPDATE_BANNER(HttpStatus.OK, "배너 수정에 성공했습니다"),
SUCCESS_CREATE_BANNER(HttpStatus.CREATED, "배너 생성에 성공했습니다")
;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,10 @@ public void updateContentType(ContentType contentType) {
public void updatePublisher(String publisher) {
this.publisher = publisher;
}

public void updateLink(String link) { this.link = link;}

public void updatePeriod(PublishPeriod period) { this.period = period; }

public void updateImage(BannerImage image) { this.image = image; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ public interface S3Service {
String createPreSignedUrlForPutObject(String bucketName, String fileName);

String getUrl(String bucketName, String fileName);

void deleteFile(String bucketName, String fileName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public String getUrl(String bucketName, String fileName) {
}
}

public void deleteFile(String bucketName, String fileName){
@Override
public void deleteFile(String bucketName, String fileName) {
s3Client.deleteObject(b -> b.bucket(bucketName).key(fileName));
}
}