-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/weekly/11' into feat/#142-mypage
- Loading branch information
Showing
32 changed files
with
1,142 additions
and
302 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,78 +1,166 @@ | ||
# Project : Inplace ( Team7_BE ) | ||
# Inplace ( Team7_BE ) | ||
|
||
## 배포 링크 | ||
> [**BackEnd**](https://api.inplace.my) : _api.inplace.my_ | ||
> | ||
> [**FrontEnd**](https://inplace.my) : _inplace.my_ | ||
<p align="center"> | ||
<img src="https://i.ibb.co/CVBQHPg/image-2.png" alt="메인 이미지" style="border: 2px solid black;"> | ||
</p> | ||
|
||
## 개발 Repository 정보 | ||
## Project Purpose | ||
> 저희의 아이디어는 **데이트 코스의 단조로움**을 어떻게 하면 해소할 수 있을까? 라는 생각에서 시작했습니다. | ||
> | ||
> 아이디어를 구체화하는 과정에서 저희는 **장소**에 관련된 소재로 인스타, 유튜브 등의 SNS 및 동영상 플랫폼의 성장과 함께 등장한 **인플루언서** 라는 개념에 집중하게 되었습니다. | ||
> | ||
> 이는 **인플루언서가 방문한 장소에 대한 정보를 서비스 해보자!** 라는 생각으로 이어졌습니다. | ||
> | ||
> 이를 관심있는 **인플루언서를 등록하고, 이에 따른 장소 추천 및, 장소에 대한 리뷰 기능**을 통해 풀어내어 **Inplace** 라는 저희만의 웹 애플리케이션으로 구현해보았습니다. | ||
## Main Function | ||
> 프로그램 시나리오 | ||
- 사용자 회원가입 | ||
- 사용자 로그인 | ||
- 관심있는 인플루언서 선택 ( 초기 한정 ) | ||
- 사용자 별 맞춤 페이지 제공 ( 좋아요 한 인플루언서의 영상, 내 주변 인플루언서 방문 장소에 대한 영상 ) | ||
- 인플루언서, 장소, 동영상 통합 검색 기능 | ||
- 인플루언서 검색 기능 | ||
- 인플루언서 좋아요 기능 | ||
- 지도를 통한 장소 검색 기능 ( 위치 정보, 인플루언서 정보, 장소 태그 별 검색 ) | ||
- 장소에 대한 상세 페이지 제공 기능 ( 장소 정보, 리뷰 정보 ) | ||
- 방문 예정 기능 ( 나에게 카카오 메세지 전송 ) | ||
- 방문 예정 이후 3일 뒤, 리뷰 기능 ( 나에게 카카오 메세지 전송 ) | ||
- 마이페이지 기능 ( 유저 별 좋아요 한 인플루언서, 장소와 리뷰 조회, 닉네임 변경 가능 ) | ||
|
||
## Repository Info | ||
![GitHub language count](https://img.shields.io/github/languages/count/kakao-tech-campus-2nd-step3/Team7_BE) | ||
![GitHub top language](https://img.shields.io/github/languages/top/kakao-tech-campus-2nd-step3/Team7_BE) | ||
![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/kakao-tech-campus-2nd-step3/Team7_BE) | ||
![GitHub repo size](https://img.shields.io/github/repo-size/kakao-tech-campus-2nd-step3/Team7_BE) | ||
![GitHub open issues](https://img.shields.io/github/issues/kakao-tech-campus-2nd-step3/Team7_BE) | ||
![GitHub closed issues](https://img.shields.io/github/issues-closed/kakao-tech-campus-2nd-step3/Team7_BE) | ||
![GitHub commit activity](https://img.shields.io/github/commit-activity/w/kakao-tech-campus-2nd-step3/Team7_BE) | ||
![GitHub last commit](https://img.shields.io/github/last-commit/kakao-tech-campus-2nd-step3/Team7_BE) | ||
|
||
## 참여자 | ||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> | ||
[![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors-) | ||
<!-- ALL-CONTRIBUTORS-BADGE:END --> | ||
## Deploy Link | ||
> [**BackEnd**](https://api.inplace.my) : _api.inplace.my_ | ||
> | ||
> [**API Spec**](https://api.inplace.my/swagger-ui/index.html) : _api.inplace.my/swagger-ui/index.html_ | ||
> | ||
> [**FrontEnd**](https://inplace.my) : _inplace.my_ | ||
## Contributor | ||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> | ||
<table> | ||
<tr> | ||
<td align="center"><a href="https://github.com/sanghee0820"><img src="https://avatars.githubusercontent.com/u/102018082?v=4" width="100px;" alt=""/><br /><sub><b>이상희</b></sub></a><br /><a href="https://github.com/sanghee0820" title="Code">💻</a></td> | ||
<td align="center"><a href="https://github.com/dong-yxxn"><img src="https://avatars.githubusercontent.com/u/129285999?v=4" width="100px;" alt=""/><br /><sub><b>김동윤</b></sub></a><br /><a href="https://github.com/dong-yxxn" title="Code">💻</a></td> | ||
<td align="center"><a href="https://github.com/suhyeon7497"><img src="https://avatars.githubusercontent.com/u/137245467?v=4" width="100px;" alt=""/><br /><sub><b>정수현</b></sub></a><br /><a href="https://github.com/suhyeon7497" title="Code">💻</a></td> | ||
<td align="center"><a href="https://github.com/wndlthsk"><img src="https://avatars.githubusercontent.com/u/80496766?v=4" width="100px;" alt=""/><br /><sub><b>우현서</b></sub></a><br /><a href="https://github.com/wndlthsk" title="Code">💻</a></td> | ||
<td align="center"><a href="https://github.com/BaeJunH0"><img src="https://avatars.githubusercontent.com/u/114082026?v=4" width="100px;" alt=""/><br /><sub><b>배준호</b></sub></a><br /><a href="https://github.com/BaeJunH0" title="Code">💻</a></td> | ||
<!-- Add more contributors here --> | ||
<td align="center"> | ||
<b>Frontend</b><br /> | ||
</td> | ||
<td align="center"> | ||
<b>Frontend</b><br /> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td align="center"> | ||
<a href="https://github.com/userjmmm"><img src="https://avatars.githubusercontent.com/u/141299582?v=4" width="80px;" alt=""/><br /><sub><b>이정민</b></sub></a> | ||
</td> | ||
<td align="center"> | ||
<a href="https://github.com/Hyoeunkh"><img src="https://avatars.githubusercontent.com/u/102338613?v=4" width="80px;" alt=""/><br /><sub><b>이효은</b></sub></a> | ||
</td> | ||
</tr> | ||
</table> | ||
<table> | ||
<tr> | ||
<td align="center"> | ||
<b>Backend</b><br /> | ||
</td> | ||
<td align="center"> | ||
<b>Backend</b><br /> | ||
</td> | ||
<td align="center"> | ||
<b>Backend</b><br /> | ||
</td> | ||
<td align="center"> | ||
<b>Backend</b><br /> | ||
</td> | ||
<td align="center"> | ||
<b>Backend</b><br /> | ||
</td> | ||
</tr> | ||
<tr> | ||
<td align="center"> | ||
<a href="https://github.com/sanghee0820"><img src="https://avatars.githubusercontent.com/u/102018082?v=4" width="80px;" alt=""/><br /><sub><b>이상희</b></sub></a> | ||
</td> | ||
<td align="center"> | ||
<a href="https://github.com/dong-yxxn"><img src="https://avatars.githubusercontent.com/u/129285999?v=4" width="80px;" alt=""/><br /><sub><b>김동윤</b></sub></a> | ||
</td> | ||
<td align="center"> | ||
<a href="https://github.com/suhyeon7497"><img src="https://avatars.githubusercontent.com/u/137245467?v=4" width="80px;" alt=""/><br /><sub><b>정수현</b></sub></a> | ||
</td> | ||
<td align="center"> | ||
<a href="https://github.com/wndlthsk"><img src="https://avatars.githubusercontent.com/u/80496766?v=4" width="80px;" alt=""/><br /><sub><b>우현서</b></sub></a> | ||
</td> | ||
<td align="center"> | ||
<a href="https://github.com/BaeJunH0"><img src="https://avatars.githubusercontent.com/u/114082026?v=4" width="80px;" alt=""/><br /><sub><b>배준호</b></sub></a> | ||
</td> | ||
</tr> | ||
</table> | ||
<!-- ALL-CONTRIBUTORS-LIST:END --> | ||
|
||
## 기획 의도 | ||
> **데이트 코스의 단조로움** 이라는 생각에서 시작한 저희의 아이디어는 인스타, 유튜브 등의 SNS 플랫폼의 성장과 함께 등장한 '인플루언서' 라는 개념에 집중하여, **인플루언서가 방문한 주변 장소에 대한 정보를 서비스 해보자!** 라는 생각으로 이어졌고, 이를 개인별 맞춤 장소 추천, 방문시 정보 발송 및 알림, 리뷰와 같은 기능으로 풀어내어 **Inplace** 라는 저희만의 웹 어플리케이션으로 구현해보았습니다. | ||
## 주요 기능 | ||
|
||
## 프로그램 구조 | ||
## Program Architecture | ||
- **ERD** | ||
|
||
<img src="https://file.notion.so/f/f/3ef8dbd9-414c-4cf5-813d-32ecb943cc67/125d6695-92d4-438c-8bc8-bee423d36257/image.png?table=block&id=8410a24e-b147-4649-9b77-304c9fd6599a&spaceId=3ef8dbd9-414c-4cf5-813d-32ecb943cc67&expirationTimestamp=1731585600000&signature=nfFPKXrEnsF9lTp65eWkTl9Gjhs_r8Yqf2qG4nAAmTw&downloadName=image.png" alt="ERD" width="600"/> | ||
|
||
- | ||
|
||
## 주요 종속성 버전 | ||
- Spring Boots 3.3.3 | ||
- Java 17 LTS | ||
## Main Dependency Version | ||
> **Spring Boots 3.3.3** | ||
> | ||
> **Java 17 LTS** | ||
## 기술 스택 | ||
## Tech Stack | ||
> **Backend** | ||
> | ||
![Spring Boot](https://img.shields.io/badge/Spring%20Boot-6DB33F?style=flat-square&logo=springboot&logoColor=white) | ||
![Lombok](https://img.shields.io/badge/Lombok-DC382D?style=flat-square&logo=lombok&logoColor=white) | ||
|
||
> **Security** | ||
> | ||
![Spring Security](https://img.shields.io/badge/Spring%20Security-6DB33F?style=flat-square&logo=springsecurity&logoColor=white) | ||
![JWT](https://img.shields.io/badge/JWT-000000?style=flat-square&logo=jsonwebtokens&logoColor=white) | ||
|
||
> **DB** | ||
> | ||
![Spring Data JPA](https://img.shields.io/badge/Spring%20Data%20JPA-6DB33F?style=flat-square&logo=spring&logoColor=white) | ||
![QueryDSL](https://img.shields.io/badge/QueryDSL-0055a2?style=flat-square&logo=appveyor&logoColor=white) | ||
![MySQL](https://img.shields.io/badge/MySQL-4479A1?style=flat-square&logo=mysql&logoColor=white) | ||
![Redis](https://img.shields.io/badge/Redis-DC382D?style=flat-square&logo=redis&logoColor=white) | ||
|
||
> **Web** | ||
> | ||
![Spring WebFlux](https://img.shields.io/badge/Spring%20WebFlux-6DB33F?style=flat-square&logo=spring&logoColor=white) | ||
![Thymeleaf](https://img.shields.io/badge/Thymeleaf-005F0F?style=flat-square&logo=thymeleaf&logoColor=white) | ||
|
||
> **Deployment** | ||
> | ||
![AWS EC2](https://img.shields.io/badge/AWS%20EC2-FF9900?style=flat-square&logo=amazonaws&logoColor=white) | ||
![Docker](https://img.shields.io/badge/Docker-2496ED?style=flat-square&logo=docker&logoColor=white) | ||
|
||
> **Admin Page** | ||
> | ||
![jQuery](https://img.shields.io/badge/jQuery-0769AD?style=flat-square&logo=jquery&logoColor=white) | ||
![Thymeleaf](https://img.shields.io/badge/Thymeleaf-005F0F?style=flat-square&logo=thymeleaf&logoColor=white) | ||
![AJAX](https://img.shields.io/badge/AJAX-005571?style=flat-square&logo=ajax&logoColor=white) | ||
|
||
> **Test** | ||
> | ||
![JMeter](https://img.shields.io/badge/JMeter-D22128?style=flat-square&logo=apachejmeter&logoColor=white) | ||
![JUnit](https://img.shields.io/badge/JUnit-25A162?style=flat-square&logo=junit5&logoColor=white) | ||
![Mockito](https://img.shields.io/badge/Mockito-FFCA28?style=flat-square&logo=mockito&logoColor=white) | ||
|
||
> **Code Maintenance** | ||
> | ||
![Git](https://img.shields.io/badge/Git-F05032?style=flat-square&logo=git&logoColor=white) | ||
![GitHub](https://img.shields.io/badge/GitHub-181717?style=flat-square&logo=github&logoColor=white) | ||
![GitHub Actions](https://img.shields.io/badge/GitHub%20Actions-2088FF?style=flat-square&logo=githubactions&logoColor=white) | ||
|
||
## 사용 예시 | ||
> **Collaboration Tool** | ||
> | ||
![Discord](https://img.shields.io/badge/Discord-5865F2?style=flat-square&logo=discord&logoColor=white) | ||
![Slack](https://img.shields.io/badge/Slack-4A154B?style=flat-square&logo=slack&logoColor=white) | ||
|
||
## Example Usage | ||
> 나중에 시연 영상 첨부하기 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
src/main/java/team7/inplace/admin/application/BannerService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/team7/inplace/admin/application/command/BannerCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
14
src/main/java/team7/inplace/admin/application/dto/BannerInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/team7/inplace/admin/persistence/BannerRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
31 changes: 31 additions & 0 deletions
31
src/main/java/team7/inplace/admin/persistence/BannerS3Repository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
} |
Oops, something went wrong.