Skip to content

Commit

Permalink
Merge branch 'main' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
stopmin committed Jul 19, 2024
2 parents 8ca1802 + 45157f6 commit 75c485f
Show file tree
Hide file tree
Showing 15 changed files with 255 additions and 98 deletions.
24 changes: 12 additions & 12 deletions src/main/java/gyeongdan/article/controller/ArticleController.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class ArticleController {
// 단, 유저가 보면 조회기록 저장하고, 유저가 아닌 경우 조회수만 증가시키기.
@GetMapping("/detail")
public ResponseEntity<?> getArticle(@RequestParam Long id,
@RequestHeader @Nullable String accessToken) { // id : 기사id, access token : 유저의 접근 권한
@RequestHeader @Nullable String accessToken) { // id : 기사id, access token : 유저의 접근 권한
Optional<Long> userId = Optional.empty();
if (accessToken != null && !accessToken.isEmpty()) {
userId = jwtUtil.getUserId(jwtUtil.resolveToken(accessToken));
Expand Down Expand Up @@ -63,21 +63,21 @@ public ResponseEntity<?> getRecentViewedArticles(@RequestHeader @Nullable String
List<Article> recentViewedArticles = articleService.getRecentViewedArticles(userId.orElse(null));

List<ArticleAllResponse> finalResponse = recentViewedArticles.stream()
.map(article -> new ArticleAllResponse(
article.getId(),
article.getSimpleTitle(),
article.getSimpleContent(),
article.getViewCount(),
article.getCategory(),
Optional.ofNullable(article.getImageUrl()),
article.getPublishedAt()
))
.collect(Collectors.toList());
.map(article -> new ArticleAllResponse(
article.getId(),
article.getSimpleTitle(),
article.getSimpleContent(),
article.getViewCount(),
article.getCategory(),
Optional.ofNullable(article.getImageUrl()),
article.getPublishedAt()
))
.collect(Collectors.toList());

return ResponseEntity.ok(new CommonResponse<>(finalResponse, "가장 최근에 조회한 게시글 3개 조회 성공", true));
}

// 오늘 가장 인기 있는 기사 5개 조회 (조회수 기준)
// 이번주 가장 인기 있는 기사 10개 조회 (조회수 기준)
@GetMapping("/popular")
public ResponseEntity<?> getPopularArticles() {
List<PopularArticleResponse> popularArticles = articleService.getPopularArticles();
Expand Down
33 changes: 0 additions & 33 deletions src/main/java/gyeongdan/article/controller/TypeTestController.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package gyeongdan.article.repository;

import gyeongdan.article.domain.Article;
import org.springframework.data.domain.Pageable;
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 java.time.LocalDateTime;
import java.util.List;

@Repository
public interface ArticleJpaRepository extends JpaRepository<Article, Long> {

List<Article> findTop10ByPublishedAtBetweenOrderByViewCountDesc(LocalDateTime startOfWeek, LocalDateTime endOfDay);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,4 @@

public interface ArticleViewHistoryJpaRepository extends JpaRepository<ArticleViewHistory, Long> {
List<ArticleViewHistory> findTop100ByUserIdOrderByViewedAtDesc(Long userId);

@Query("SELECT a.article FROM ArticleViewHistory a WHERE a.viewedAt >= :startOfDay AND a.viewedAt < :endOfDay GROUP BY a.article ORDER BY SUM(a.article.viewCount) DESC")
List<Article> findTopArticlesByViewedAtBetween(@Param("startOfDay") LocalDateTime startOfDay, @Param("endOfDay") LocalDateTime endOfDay);
}
49 changes: 27 additions & 22 deletions src/main/java/gyeongdan/article/service/ArticleService.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import gyeongdan.article.dto.ArticleAllResponse;
import gyeongdan.article.dto.ArticleUpdateRequest;
import gyeongdan.article.dto.PopularArticleResponse;
import gyeongdan.article.repository.ArticleJpaRepository;
import gyeongdan.article.repository.ArticleRepository;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
Expand All @@ -16,6 +18,7 @@
import gyeongdan.article.repository.ArticleViewHistoryJpaRepository;
import gyeongdan.user.service.UserManageService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

@Service
Expand All @@ -25,6 +28,7 @@ public class ArticleService {
private final ArticleRepository articleRepository;
private final ArticleViewHistoryJpaRepository articleViewHistoryJpaRepository;
private final UserManageService userManageService;
private final ArticleJpaRepository articleJpaRepository;

public Article getValidArticleById(Long id, Optional<Long> userId) {
Article article = articleRepository.findById(id);
Expand Down Expand Up @@ -68,17 +72,17 @@ public Long updateArticle(ArticleUpdateRequest articleUpdateRequest) {
public List<ArticleAllResponse> getValidArticles() {
List<Article> articles = articleRepository.findAll();
return articles.stream()
.filter(Article::isValid)
.map(article -> new ArticleAllResponse(
article.getId(),
article.getSimpleTitle(),
article.getSimpleContent(),
article.getViewCount(),
article.getCategory(),
Optional.ofNullable(article.getImageUrl()),
article.getPublishedAt()
))
.collect(Collectors.toList());
.filter(Article::isValid)
.map(article -> new ArticleAllResponse(
article.getId(),
article.getSimpleTitle(),
article.getSimpleContent(),
article.getViewCount(),
article.getCategory(),
Optional.ofNullable(article.getImageUrl()),
article.getPublishedAt()
))
.collect(Collectors.toList());
}

// 조회수 증가 메서드
Expand All @@ -97,24 +101,25 @@ public List<Article> getRecentViewedArticles(Long userId) {
userManageService.checkUserExist(userId);

List<ArticleViewHistory> recentViewedHistories = articleViewHistoryJpaRepository.findTop100ByUserIdOrderByViewedAtDesc(
userId);
userId);
return recentViewedHistories.stream()
.map(ArticleViewHistory::getArticle)
.distinct()
.limit(3)
.collect(Collectors.toList());
.map(ArticleViewHistory::getArticle)
.distinct()
.limit(3)
.collect(Collectors.toList());
}

// 오늘 가장 인기 있는 기사 5개 가져오는 메서드 (조회수 기준)
// 이번 주 가장 인기 있는 기사 5개 가져오는 메서드 (조회수 기준)
public List<PopularArticleResponse> getPopularArticles() {
// 오늘을 기준으로 이번 주의 시작과 끝을 구함 (월요일부터 일요일까지)
LocalDate today = LocalDate.now();
LocalDateTime startOfDay = today.atStartOfDay();
LocalDateTime endOfDay = today.plusDays(1).atStartOfDay();
LocalDateTime mondayDateTime = today.with(DayOfWeek.MONDAY).atStartOfDay();
LocalDateTime sundayDateTime = today.with(DayOfWeek.SUNDAY).plusDays(1).atStartOfDay();

List<Article> articles = articleViewHistoryJpaRepository.findTopArticlesByViewedAtBetween(startOfDay, endOfDay);
List<Article> articles = articleJpaRepository.findTop10ByPublishedAtBetweenOrderByViewCountDesc(mondayDateTime, sundayDateTime);

return articles.stream()
.map(article -> new PopularArticleResponse(article.getId(), article.getSimpleTitle(), article.getViewCount()))
.collect(Collectors.toList());
.map(article -> new PopularArticleResponse(article.getId(), article.getSimpleTitle(), article.getViewCount()))
.collect(Collectors.toList());
}
}
4 changes: 2 additions & 2 deletions src/main/java/gyeongdan/article/service/RecommendService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import gyeongdan.article.dto.ArticleAllResponse;
import gyeongdan.article.repository.ArticleJpaRepository;
import gyeongdan.article.domain.Recommends;
import gyeongdan.article.domain.UserType;
import gyeongdan.user.domain.UserType;
import gyeongdan.article.repository.RecommendJpaRepository;
import gyeongdan.article.repository.UserTypeJpaRepository;
import gyeongdan.user.repository.UserTypeJpaRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

Expand Down
49 changes: 49 additions & 0 deletions src/main/java/gyeongdan/user/controller/UserTypeController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package gyeongdan.user.controller;

import gyeongdan.user.domain.UserType;
import gyeongdan.user.dto.UserTypeRecord;
import gyeongdan.user.dto.UserTypeTestResult;
import gyeongdan.user.service.UserManageService;
import gyeongdan.util.CommonResponse;
import gyeongdan.util.annotation.LoginAuthenticated;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/usertype")
@RequiredArgsConstructor
public class UserTypeController {

private final UserManageService userManageService;



@LoginAuthenticated
@PostMapping("/save")
public ResponseEntity<?> saveUserTypeTestResult(
@RequestBody UserTypeTestResult userTypeTestResult
) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Long userId = Long.valueOf(authentication.getName());

userManageService.saveUserType(userId, userTypeTestResult);

return ResponseEntity.ok(new CommonResponse<>(null, "유저 타입 테스트 결과 저장 성공", true));
}

@LoginAuthenticated
@GetMapping
public ResponseEntity<?> getUserType() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Long userId = Long.valueOf(authentication.getName());
UserTypeRecord userType = userManageService.getUserType(userId);
return ResponseEntity.ok(new CommonResponse<>(userType, "유저 타입 테스트 결과 조회 성공", true));
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package gyeongdan.article.domain;
package gyeongdan.user.domain;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
Expand All @@ -18,12 +18,15 @@ public class UserType {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long userId;
private Long id;

private Long userId;
private Long userTypeIssueFinder;
private Long userTypeLifestyleConsumer;
private Long userTypeEntertainer;
private Long userTypeTechSpecialist;
private Long userTypeProfessionals;
private Long userType;

@Enumerated(EnumType.STRING)
private UserTypeEnum userType;
}
50 changes: 50 additions & 0 deletions src/main/java/gyeongdan/user/domain/UserTypeEnum.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package gyeongdan.user.domain;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum UserTypeEnum {
ISSUE_FINDER("이슈파인더"),
LIFESTYLE_CONSUMER("라이프스타일소비자"),
ENTERTAINER("엔터테이너"),
TECH_SPECIALIST("테크전문가"),
PROFESSIONALS("전문가");

private final String name;

public static UserTypeEnum from(String name) {
for (UserTypeEnum userType : UserTypeEnum.values()) {
if (userType.name.equals(name)) {
return userType;
}
}
throw new IllegalArgumentException("Invalid name: " + name);
}

public static UserTypeEnum fromWeights(Long issueFinder, Long lifestyleConsumer, Long entertainer,
Long techSpecialist, Long professionals) {
long maxWeight = issueFinder;
UserTypeEnum strongestUserType = ISSUE_FINDER;

if (lifestyleConsumer > maxWeight) {
maxWeight = lifestyleConsumer;
strongestUserType = LIFESTYLE_CONSUMER;
}
if (entertainer > maxWeight) {
maxWeight = entertainer;
strongestUserType = ENTERTAINER;
}
if (techSpecialist > maxWeight) {
maxWeight = techSpecialist;
strongestUserType = TECH_SPECIALIST;
}
if (professionals > maxWeight) {
maxWeight = professionals;
strongestUserType = PROFESSIONALS;
}

return strongestUserType;
}
}
19 changes: 19 additions & 0 deletions src/main/java/gyeongdan/user/dto/UserTypeRecord.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package gyeongdan.user.dto;

import gyeongdan.user.domain.UserTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
@AllArgsConstructor
public class UserTypeRecord {

private Long userTypeIssueFinder;
private Long userTypeLifestyleConsumer;
private Long userTypeEntertainer;
private Long userTypeTechSpecialist;
private Long userTypeProfessionals;
private UserTypeEnum userType;
}
17 changes: 17 additions & 0 deletions src/main/java/gyeongdan/user/dto/UserTypeTestResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package gyeongdan.user.dto;

import gyeongdan.user.domain.UserTypeEnum;
import lombok.Data;
import lombok.Getter;

@Data
@Getter
public class UserTypeTestResult {

private Long userTypeIssueFinder;
private Long userTypeLifestyleConsumer;
private Long userTypeEntertainer;
private Long userTypeTechSpecialist;
private Long userTypeProfessionals;
private UserTypeEnum userType;
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package gyeongdan.article.repository;
package gyeongdan.user.repository;

import gyeongdan.article.domain.UserType;
import gyeongdan.user.domain.UserType;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface UserTypeJpaRepository extends JpaRepository<UserType, Long> {

Optional<UserType> findByuserId(Long user_id);

Optional<List<UserType>> findByUserId(Long userId);
}
Loading

0 comments on commit 75c485f

Please sign in to comment.