Skip to content

Commit

Permalink
Merge pull request #181 from kakao-tech-campus-2nd-step3/feat/#166-lo…
Browse files Browse the repository at this point in the history
…go-api

[Feat] 배너를 업로드하고 반환하는 기능을 추가했어요.
  • Loading branch information
sanghee0820 authored Nov 14, 2024
2 parents 1922bdc + 08e130a commit 82488ac
Show file tree
Hide file tree
Showing 20 changed files with 626 additions and 0 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ dependencies {
//Spring
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
testImplementation 'io.projectreactor:reactor-test'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/team7/inplace/admin/AdminPageController.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import team7.inplace.admin.persistence.BannerRepository;
import team7.inplace.global.exception.ErrorLog;
import team7.inplace.global.exception.ErrorLogRepository;
import team7.inplace.global.kakao.config.KakaoApiProperties;
Expand All @@ -23,6 +24,7 @@ public class AdminPageController {
private final KakaoApiProperties kakaoApiProperties;
private final VideoRepository videoRepository;
private final ErrorLogRepository errorLogRepository;
private final BannerRepository bannerRepository;

@GetMapping("/video")
public String getVideos(@PageableDefault Pageable pageable, Model model) {
Expand All @@ -42,4 +44,12 @@ public String getErrorLogs(Model model) {
model.addAttribute("errorLogs", errorLogs);
return "admin/error-logs.html";
}

@GetMapping("/banner")
public String getBanners(Model model) {
var banners = bannerRepository.findAll();

model.addAttribute("banners", banners);
return "admin/banner.html";
}
}
34 changes: 34 additions & 0 deletions src/main/java/team7/inplace/admin/application/BannerService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package team7.inplace.admin.application;

import java.time.LocalDateTime;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import team7.inplace.admin.application.command.BannerCommand;
import team7.inplace.admin.application.dto.BannerInfo;
import team7.inplace.admin.application.dto.BannerInfo.Detail;
import team7.inplace.admin.persistence.BannerRepository;
import team7.inplace.admin.persistence.BannerS3Repository;

@Service
@RequiredArgsConstructor
public class BannerService {
private final BannerS3Repository bannerS3Repository;
private final BannerRepository bannerRepository;

public void uploadBanner(BannerCommand.Create command) {
var imgPath = bannerS3Repository.uploadBanner(command.imgName(), command.imageFile());
var banner = command.toEntity(imgPath);
bannerRepository.save(banner);
}

public List<Detail> getBanners() {
var now = LocalDateTime.now();
var banners = bannerRepository.findActiveBanner(now);

return banners.stream()
.sorted((a, b) -> Boolean.compare(b.getIsFixed(), a.getIsFixed()))
.map(BannerInfo.Detail::from)
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package team7.inplace.admin.application.command;

import java.time.LocalDateTime;
import org.springframework.web.multipart.MultipartFile;
import team7.inplace.admin.domain.Banner;

public class BannerCommand {
public record Create(
String imgName,
MultipartFile imageFile,
LocalDateTime startDate,
LocalDateTime endDate,
Boolean isFixed
) {
public Banner toEntity(String imgPath) {
return Banner.of(imgName, imgPath, startDate, endDate, isFixed);
}
}
}
14 changes: 14 additions & 0 deletions src/main/java/team7/inplace/admin/application/dto/BannerInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package team7.inplace.admin.application.dto;

import team7.inplace.admin.domain.Banner;

public class BannerInfo {
public record Detail(
Long id,
String imageUrl
) {
public static Detail from(Banner banner) {
return new Detail(banner.getId(), banner.getImgPath());
}
}
}
38 changes: 38 additions & 0 deletions src/main/java/team7/inplace/admin/domain/Banner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package team7.inplace.admin.domain;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import java.time.LocalDateTime;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Banner {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String imgName;
private String imgPath;
private LocalDateTime startDate;
private LocalDateTime endDate;
private Boolean isFixed;

private Banner(String imgName, String imgPath, LocalDateTime startDate, LocalDateTime endDate, Boolean isFixed) {
this.imgName = imgName;
this.imgPath = imgPath;
this.startDate = startDate;
this.endDate = endDate;
this.isFixed = isFixed;
}

public static Banner of(String imgName, String imgPath, LocalDateTime startDate, LocalDateTime endDate,
Boolean isFixed) {
return new Banner(imgName, imgPath, startDate, endDate, isFixed);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package team7.inplace.admin.persistence;

import java.time.LocalDateTime;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import team7.inplace.admin.domain.Banner;

@Repository
public interface BannerRepository extends JpaRepository<Banner, Long> {
@Query("SELECT l FROM Banner l WHERE l.startDate <= :now AND l.endDate >= :now or l.isFixed = true")
List<Banner> findActiveBanner(@Param("now") LocalDateTime now);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package team7.inplace.admin.persistence;

import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.ObjectMetadata;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import org.springframework.web.multipart.MultipartFile;
import team7.inplace.infra.s3.AwsProperties;

@Repository
@RequiredArgsConstructor
public class BannerS3Repository {
private final AmazonS3Client amazonS3Client;
private final AwsProperties awsProperties;

public String uploadBanner(String bannerName, MultipartFile banner) {
var bucketName = awsProperties.bucketName();
var key = "banner/" + bannerName;

ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(banner.getSize());
metadata.setContentType(banner.getContentType());

try {
amazonS3Client.putObject(bucketName, key, banner.getInputStream(), metadata);
return amazonS3Client.getUrl(bucketName, key).toString();
} catch (Exception e) {
throw new RuntimeException("Failed to upload banner", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package team7.inplace.admin.presentation;

import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import team7.inplace.admin.application.BannerService;

@RestController
@Slf4j
@RequestMapping("/banner")
@RequiredArgsConstructor
public class BannerController {
private final BannerService bannerService;

@PostMapping()
public void saveBanner(BannerRequest.Create request) {

bannerService.uploadBanner(request.toCommand());
}

@GetMapping()
public ResponseEntity<List<BannerResponse.Info>> getBanners() {
var banners = bannerService.getBanners();

var response = banners.stream()
.map(BannerResponse.Info::from)
.toList();
return new ResponseEntity<>(response, HttpStatus.OK);
}
}
25 changes: 25 additions & 0 deletions src/main/java/team7/inplace/admin/presentation/BannerRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package team7.inplace.admin.presentation;

import java.time.LocalDate;
import org.springframework.web.multipart.MultipartFile;
import team7.inplace.admin.application.command.BannerCommand;

public class BannerRequest {
public record Create(
String imageName,
MultipartFile imageFile,
LocalDate startDate,
LocalDate endDate,
Boolean isFixed
) {
public BannerCommand.Create toCommand() {
return new BannerCommand.Create(
imageName,
imageFile,
startDate.atStartOfDay(),
endDate.atStartOfDay(),
isFixed
);
}
}
}
14 changes: 14 additions & 0 deletions src/main/java/team7/inplace/admin/presentation/BannerResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package team7.inplace.admin.presentation;

import team7.inplace.admin.application.dto.BannerInfo;

public class BannerResponse {
public record Info(
Long id,
String imageUrl
) {
public static Info from(BannerInfo.Detail banner) {
return new Info(banner.id(), banner.imageUrl().replace("https://", "http://"));
}
}
}
12 changes: 12 additions & 0 deletions src/main/java/team7/inplace/infra/s3/AwsProperties.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package team7.inplace.infra.s3;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "aws")
public record AwsProperties(
String accessKey,
String secretKey,
String region,
String bucketName
) {
}
26 changes: 26 additions & 0 deletions src/main/java/team7/inplace/infra/s3/S3Config.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package team7.inplace.infra.s3;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@RequiredArgsConstructor
public class S3Config {
private final AwsProperties awsProperties;

@Bean
public AmazonS3Client amazonS3Client() {
BasicAWSCredentials awsCredentials = new BasicAWSCredentials(awsProperties.accessKey(),
awsProperties.secretKey());

return (AmazonS3Client) AmazonS3ClientBuilder.standard()
.withRegion(awsProperties.region())
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.build();
}
}
5 changes: 5 additions & 0 deletions src/main/resources/application-s3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
aws:
accessKey: ${AWS_ACCESS_KEY}
secretKey: ${AWS_SECRET_KEY}
region: ${AWS_REGION}
bucket_name: ${AWS_BUCKET_NAME}
1 change: 1 addition & 0 deletions src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ spring:
- classpath:application-kakao.yaml
- classpath:application-db.yaml
- classpath:application-redis.yaml
- classpath:application-s3.yaml
- optional:file:.env[.properties]
11 changes: 11 additions & 0 deletions src/main/resources/sql/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,14 @@ create table liked_places
constraint FK7x24ubd2axm81hx0ggiy4l4ao
foreign key (place_id) references places (id)
);

create table banner
(
is_fixed bit null,
end_date datetime(6) null,
id bigint auto_increment
primary key,
start_date datetime(6) null,
img_name varchar(255) null,
img_path varchar(255) null
);
Loading

0 comments on commit 82488ac

Please sign in to comment.