Skip to content

Commit

Permalink
Merge branch 'dev' into test
Browse files Browse the repository at this point in the history
  • Loading branch information
gouyeonch committed Sep 14, 2024
2 parents 495efe0 + 362916e commit 1e342b5
Show file tree
Hide file tree
Showing 19 changed files with 317 additions and 74 deletions.
Binary file modified .DS_Store
Binary file not shown.
5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ dependencies {

// Mail
implementation 'org.springframework.boot:spring-boot-starter-mail'

// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.data:spring-data-redis:3.0.1'

}

tasks.named('test') {
Expand Down
Binary file modified src/.DS_Store
Binary file not shown.
Binary file modified src/main/.DS_Store
Binary file not shown.
17 changes: 17 additions & 0 deletions src/main/java/com/kkokkomu/short_news/core/config/RedisConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.kkokkomu.short_news.core.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

@Configuration
public class RedisConfig {

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.kkokkomu.short_news.core.config.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Set;
import java.util.stream.Collectors;

@Service
public class RedisService {

@Autowired
private RedisTemplate<String, String> redisTemplate;

// 뉴스 조회수
private static final String NEWS_VIEW_COUNT_PREFIX = "news:viewCount:";

public void incrementViewCount(Long newsId) {
String key = NEWS_VIEW_COUNT_PREFIX + newsId;
redisTemplate.opsForValue().increment(key);
}

public Integer getViewCount(Long newsId) {
String key = NEWS_VIEW_COUNT_PREFIX + newsId;
String count = redisTemplate.opsForValue().get(key);
return count != null ? Integer.parseInt(count) : 0;
}

// 뉴스 시청기록
private static final String VIEW_HISTORY_PREFIX = "news:viewHistory:";

public void saveNewsViewHistory(Long userId, Long newsId) {
String key = VIEW_HISTORY_PREFIX + userId;
redisTemplate.opsForSet().add(key, String.valueOf(newsId));
}

public Set<Long> getNewsViewHistory(Long userId) {
String key = VIEW_HISTORY_PREFIX + userId;
Set<String> stringSet = redisTemplate.opsForSet().members(key); // Set<String> 반환

// Set<String>을 Set<Long>으로 변환
return stringSet.stream()
.map(Long::valueOf) // String -> Long 변환
.collect(Collectors.toSet());
}

public void deleteNewsViewHistory(Long userId) {
String key = VIEW_HISTORY_PREFIX + userId;
redisTemplate.delete(key);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package com.kkokkomu.short_news.core.scheduler;

import com.kkokkomu.short_news.core.config.service.RedisService;
import com.kkokkomu.short_news.news.domain.News;
import com.kkokkomu.short_news.news.dto.news.request.CreateGenerateNewsDto;
import com.kkokkomu.short_news.news.dto.news.response.GenerateNewsDto;
import com.kkokkomu.short_news.core.config.service.MailService;
import com.kkokkomu.short_news.news.service.AdminNewsService;
import com.kkokkomu.short_news.news.service.HomeNewsService;
import com.kkokkomu.short_news.news.service.NewsViewHistService;
import com.kkokkomu.short_news.user.domain.User;
import com.kkokkomu.short_news.user.service.UserLookupService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
Expand All @@ -17,7 +23,10 @@
@RequiredArgsConstructor
public class NewsScheduler {
private final AdminNewsService adminNewsService;
private final HomeNewsService homeNewsService;
private final MailService mailService;
private final UserLookupService userLookupService;
private final NewsViewHistService newsViewHistService;

@Scheduled(cron = "0 0 8 * * *") // 매일 아침 8시
public void generateNewsAt8AM() {
Expand Down Expand Up @@ -59,5 +68,20 @@ public void generateNewsAt8AM() {
log.info("send [email protected]");
mailService.sendEmail("[email protected]", LocalDate.now().toString() + " kkm 뉴스", content.toString());

}
} // 뉴스 생성

@Scheduled(fixedRate = 600000) // 10분 마다
public void syncViewCountToDatabase() {
log.info("syncViewCountToDatabase");
homeNewsService.updateViewCnt();
} // 뉴스 조회수 동기화

@Scheduled(cron = "0 0 4 * * ?") // 매일 새벽 4시에 실행
public void syncAllUsersViewHistory() {
log.info("syncAllUsersViewHistory");
List<User> users = userLookupService.findAll();
for (User user : users) {
newsViewHistService.updateNewsHist(user.getId());
}
} // 모든 유저에 대해 시청기록 동기화
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,30 @@ public class HomeNewsController {
@Operation(summary = "뉴스 리스트 조회")
@GetMapping("/list")
public ResponseDto<PagingResponseDto<List<NewsInfoDto>>> readNewsList(@Parameter(hidden = true) @UserId Long userId,
@Parameter(description = "politics, economy, social, entertain, sports, living, world, it를 , 로 구분", example = "social,world") @RequestParam String category,
@RequestParam(required = false) Long cursorId,
@RequestParam EHomeFilter filter,
@RequestParam int page, @RequestParam int size) {
@RequestParam int size) {
log.info("readNewsList controller");
return ResponseDto.ok(homeNewsService.readNewsList(userId, category, filter, page, size));

if (filter.equals(EHomeFilter.RECOMMEND)) {
return ResponseDto.ok(homeNewsService.readNewsList(userId, cursorId, size));
} else {
return ResponseDto.ok(homeNewsService.readNewsList(userId, cursorId, size));
}
}

@Operation(summary = "비로그인 뉴스 리스트 조회")
@GetMapping("/list/guest")
public ResponseDto<PagingResponseDto<List<GuestNewsInfoDto>>> guestReadNewsList(@RequestParam int page, @RequestParam int size) {
public ResponseDto<PagingResponseDto<List<GuestNewsInfoDto>>> guestReadNewsList(@RequestParam(required = false) Long cursorId,
@RequestParam int size) {
log.info("guestReadNewsList controller");
return ResponseDto.ok(homeNewsService.guestReadNewsList(page, size));

return ResponseDto.ok(homeNewsService.guestReadNewsList(cursorId, size));
}



@Operation(summary = "뉴스 공유 수 증가")
@Operation(summary = "뉴스 공유수 증가")
@PostMapping("/shared")
public ResponseDto<NewsDto> updateSharedCnt(@RequestBody SharedCntDto sharedCntDto) {
log.info("updateSharedCnt controller");
Expand All @@ -58,4 +65,12 @@ public ResponseDto<NewsDto> updateNotInterested(@RequestBody SharedCntDto shared
log.info("updateNotInterested controller");
return ResponseDto.ok(homeNewsService.updateNotInterested(sharedCntDto));
}

@Operation(summary = "뉴스 조회수 증가")
@PostMapping("/view")
public ResponseDto<String> increaseViewCnt(@RequestBody SharedCntDto sharedCntDto,
@Parameter(hidden = true) @UserId Long userId) {
log.info("increaseViewCnt controller");
return ResponseDto.ok(homeNewsService.increaseNewsView(sharedCntDto, userId));
}
}
4 changes: 4 additions & 0 deletions src/main/java/com/kkokkomu/short_news/news/domain/News.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,8 @@ public void incrementViewCnt() {
public void updateSharedCnt() {
this.sharedCnt++;
}

public void updateViewCnt(int viewCnt) {
this.viewCnt += viewCnt;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.kkokkomu.short_news.news.domain;

import com.kkokkomu.short_news.core.event.NewsViewHistListener;
import com.kkokkomu.short_news.user.domain.User;
import jakarta.persistence.*;
import lombok.*;
Expand All @@ -12,7 +11,6 @@
@Table(name = "news_view_hist", indexes = {
@Index(name = "idx_user_id", columnList = "user_id")
})
@EntityListeners(NewsViewHistListener.class)
public class NewsViewHist {

@Id
Expand All @@ -31,9 +29,9 @@ public class NewsViewHist {
private LocalDateTime viewDate; // 시청 일자

@Builder
public NewsViewHist(User user, News news, LocalDateTime viewDate) {
public NewsViewHist(User user, News news) {
this.user = user;
this.news = news;
this.viewDate = viewDate;
this.viewDate = LocalDateTime.now();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,49 @@

@Repository
public interface NewsRepository extends JpaRepository<News, Long> {
@Query("select n from News n order by n.createdAt desc ")
Page<News> findAllCreatedAtDesc(Pageable pageable);
/****************** 뉴스 홈화면 *************************/
// @Query("select n from News n order by n.createdAt desc ")
// Page<News> findAllCreatedAtDesc(Pageable pageable);

// 카테고리별 최신순 홈화면 뉴스 조회
@Query("SELECT n FROM News n " +
"WHERE n.category IN :categories " +
"AND n.id < :cursorId " +
"AND n.id NOT IN (SELECT h.news.id FROM NewsViewHist h WHERE h.user.id = :userId) " +
"ORDER BY n.id DESC")
Page<News> findByCategoryAndIdLessThanAndNotViewedByUser(
@Param("categories") List<ECategory> category,
@Param("cursorId") Long cursorId,
@Param("userId") Long userId,
Pageable pageable
);

// 카테고리별 최신순 홈화면 뉴스 초기 페이지 조회
@Query("SELECT n FROM News n " +
"WHERE n.category IN :categories " +
"AND n.id NOT IN (SELECT h.news.id FROM NewsViewHist h WHERE h.user.id = :userId) " +
"ORDER BY n.id DESC")
Page<News> findFirstPageByCategoryAndNotViewedByUser(
@Param("categories") List<ECategory> category,
@Param("userId") Long userId,
Pageable pageable
);

// 비로그인 카테고리별 최신순 홈화면 뉴스 조회
@Query("SELECT n FROM News n " +
"WHERE n.id < :cursorId " +
"ORDER BY n.id DESC")
Page<News> guestFindByCategoryAndIdLessThanAndNotViewedByUser(
@Param("cursorId") Long cursorId,
Pageable pageable
);

// 비로그인 카테고리별 최신순 홈화면 뉴스 초기 페이지 조회
@Query("SELECT n FROM News n " +
"ORDER BY n.id DESC")
Page<News> guestFindFirstPageByCategoryAndNotViewedByUser(
Pageable pageable
);

/****************** 뉴스 시청 기록 *************************/

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@
@Repository
public interface NewsViewHistRepository extends JpaRepository<NewsViewHist, Long> {
void deleteAllByUser(User user);

// 중복 체크를 위한 쿼리
boolean existsByUserIdAndNewsId(Long userId, Long newsId);
}
Loading

0 comments on commit 1e342b5

Please sign in to comment.