refactor-architecture #31
@ -8,10 +8,10 @@ import com.magamochi.catalog.model.dto.MangaListFilterDTO;
|
|||||||
import com.magamochi.catalog.model.entity.Manga;
|
import com.magamochi.catalog.model.entity.Manga;
|
||||||
import com.magamochi.catalog.model.repository.MangaRepository;
|
import com.magamochi.catalog.model.repository.MangaRepository;
|
||||||
import com.magamochi.common.exception.NotFoundException;
|
import com.magamochi.common.exception.NotFoundException;
|
||||||
import com.magamochi.model.repository.UserMangaFollowRepository;
|
|
||||||
import com.magamochi.model.specification.MangaSpecification;
|
import com.magamochi.model.specification.MangaSpecification;
|
||||||
import com.magamochi.user.service.UserService;
|
import com.magamochi.user.service.UserService;
|
||||||
import com.magamochi.userinteraction.model.repository.UserFavoriteMangaRepository;
|
import com.magamochi.userinteraction.model.repository.UserFavoriteMangaRepository;
|
||||||
|
import com.magamochi.userinteraction.model.repository.UserMangaFollowRepository;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|||||||
@ -23,28 +23,4 @@ public class MangaController {
|
|||||||
|
|
||||||
return DefaultResponseDTO.ok().build();
|
return DefaultResponseDTO.ok().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(
|
|
||||||
summary = "Follow the manga specified by its ID",
|
|
||||||
description = "Follow the manga specified by its ID.",
|
|
||||||
tags = {"Manga"},
|
|
||||||
operationId = "followManga")
|
|
||||||
@PostMapping("/{mangaId}/followManga")
|
|
||||||
public DefaultResponseDTO<Void> followManga(@PathVariable Long mangaId) {
|
|
||||||
oldMangaService.follow(mangaId);
|
|
||||||
|
|
||||||
return DefaultResponseDTO.ok().build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Operation(
|
|
||||||
summary = "Unfollow the manga specified by its ID",
|
|
||||||
description = "Unfollow the manga specified by its ID.",
|
|
||||||
tags = {"Manga"},
|
|
||||||
operationId = "unfollowManga")
|
|
||||||
@PostMapping("/{mangaId}/unfollowManga")
|
|
||||||
public DefaultResponseDTO<Void> unfollowManga(@PathVariable Long mangaId) {
|
|
||||||
oldMangaService.unfollow(mangaId);
|
|
||||||
|
|
||||||
return DefaultResponseDTO.ok().build();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,30 +1,23 @@
|
|||||||
package com.magamochi.service;
|
package com.magamochi.service;
|
||||||
|
|
||||||
import com.magamochi.catalog.model.entity.Manga;
|
|
||||||
import com.magamochi.catalog.model.repository.MangaContentProviderRepository;
|
import com.magamochi.catalog.model.repository.MangaContentProviderRepository;
|
||||||
import com.magamochi.catalog.model.repository.MangaRepository;
|
|
||||||
import com.magamochi.common.exception.NotFoundException;
|
import com.magamochi.common.exception.NotFoundException;
|
||||||
import com.magamochi.content.model.entity.MangaContent;
|
import com.magamochi.content.model.entity.MangaContent;
|
||||||
import com.magamochi.model.dto.*;
|
import com.magamochi.model.dto.*;
|
||||||
import com.magamochi.model.entity.UserMangaFollow;
|
|
||||||
import com.magamochi.model.repository.*;
|
|
||||||
import com.magamochi.queue.MangaChapterDownloadProducer;
|
import com.magamochi.queue.MangaChapterDownloadProducer;
|
||||||
import com.magamochi.user.service.UserService;
|
import com.magamochi.user.service.UserService;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
@Log4j2
|
@Log4j2
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class OldMangaService {
|
public class OldMangaService {
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
private final MangaRepository mangaRepository;
|
|
||||||
private final MangaContentProviderRepository mangaContentProviderRepository;
|
|
||||||
|
|
||||||
private final UserMangaFollowRepository userMangaFollowRepository;
|
private final MangaContentProviderRepository mangaContentProviderRepository;
|
||||||
|
|
||||||
private final MangaChapterDownloadProducer mangaChapterDownloadProducer;
|
private final MangaChapterDownloadProducer mangaChapterDownloadProducer;
|
||||||
|
|
||||||
@ -81,36 +74,4 @@ public class OldMangaService {
|
|||||||
// mangaProvider.getContentProvider().getName())));
|
// mangaProvider.getContentProvider().getName())));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public Manga findMangaByIdThrowIfNotFound(Long mangaId) {
|
|
||||||
return mangaRepository
|
|
||||||
.findById(mangaId)
|
|
||||||
.orElseThrow(() -> new NotFoundException("Manga not found for ID: " + mangaId));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public void follow(Long mangaId) {
|
|
||||||
var user = userService.getLoggedUserThrowIfNotFound();
|
|
||||||
|
|
||||||
var manga = findMangaByIdThrowIfNotFound(mangaId);
|
|
||||||
manga.setFollow(true);
|
|
||||||
|
|
||||||
if (userMangaFollowRepository.existsByUserAndManga(user, manga)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
userMangaFollowRepository.save(UserMangaFollow.builder().user(user).manga(manga).build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public void unfollow(Long mangaId) {
|
|
||||||
var user = userService.getLoggedUserThrowIfNotFound();
|
|
||||||
var manga = findMangaByIdThrowIfNotFound(mangaId);
|
|
||||||
|
|
||||||
var userMangaFollow = userMangaFollowRepository.findByUserAndManga(user, manga);
|
|
||||||
userMangaFollow.ifPresent(userMangaFollowRepository::delete);
|
|
||||||
|
|
||||||
if (!userMangaFollowRepository.existsByManga(manga)) {
|
|
||||||
manga.setFollow(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import com.magamochi.queue.UpdateMangaFollowChapterListProducer;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@ -22,7 +21,7 @@ public class MangaFollowUpdateTask {
|
|||||||
|
|
||||||
private final UpdateMangaFollowChapterListProducer producer;
|
private final UpdateMangaFollowChapterListProducer producer;
|
||||||
|
|
||||||
@Scheduled(cron = "${manga-follow.cron-expression}")
|
// @Scheduled(cron = "${manga-follow.cron-expression}")
|
||||||
@Transactional
|
@Transactional
|
||||||
public void updateMangaFollow() {
|
public void updateMangaFollow() {
|
||||||
if (!updateEnabled) {
|
if (!updateEnabled) {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package com.magamochi.userinteraction.controller;
|
|||||||
import com.magamochi.common.model.dto.DefaultResponseDTO;
|
import com.magamochi.common.model.dto.DefaultResponseDTO;
|
||||||
import com.magamochi.userinteraction.service.UserFavoriteMangaService;
|
import com.magamochi.userinteraction.service.UserFavoriteMangaService;
|
||||||
import com.magamochi.userinteraction.service.UserMangaContentReadService;
|
import com.magamochi.userinteraction.service.UserMangaContentReadService;
|
||||||
|
import com.magamochi.userinteraction.service.UserMangaFollowService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
@ -16,6 +17,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
public class UserInteractionController {
|
public class UserInteractionController {
|
||||||
private final UserFavoriteMangaService userFavoriteMangaService;
|
private final UserFavoriteMangaService userFavoriteMangaService;
|
||||||
private final UserMangaContentReadService userMangaContentReadService;
|
private final UserMangaContentReadService userMangaContentReadService;
|
||||||
|
private final UserMangaFollowService userMangaFollowService;
|
||||||
|
|
||||||
@Operation(
|
@Operation(
|
||||||
summary = "Favorite a manga",
|
summary = "Favorite a manga",
|
||||||
@ -52,4 +54,28 @@ public class UserInteractionController {
|
|||||||
|
|
||||||
return DefaultResponseDTO.ok().build();
|
return DefaultResponseDTO.ok().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "Follow the manga specified by its ID",
|
||||||
|
description = "Follow the manga specified by its ID.",
|
||||||
|
tags = {"User Interaction"},
|
||||||
|
operationId = "followManga")
|
||||||
|
@PostMapping("/manga/{mangaId}/follow")
|
||||||
|
public DefaultResponseDTO<Void> followManga(@PathVariable Long mangaId) {
|
||||||
|
userMangaFollowService.follow(mangaId);
|
||||||
|
|
||||||
|
return DefaultResponseDTO.ok().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "Unfollow the manga specified by its ID",
|
||||||
|
description = "Unfollow the manga specified by its ID.",
|
||||||
|
tags = {"User Interaction"},
|
||||||
|
operationId = "unfollowManga")
|
||||||
|
@PostMapping("/manga/{mangaId}/unfollow")
|
||||||
|
public DefaultResponseDTO<Void> unfollowManga(@PathVariable Long mangaId) {
|
||||||
|
userMangaFollowService.unfollow(mangaId);
|
||||||
|
|
||||||
|
return DefaultResponseDTO.ok().build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package com.magamochi.model.entity;
|
package com.magamochi.userinteraction.model.entity;
|
||||||
|
|
||||||
import com.magamochi.catalog.model.entity.Manga;
|
import com.magamochi.catalog.model.entity.Manga;
|
||||||
import com.magamochi.user.model.entity.User;
|
import com.magamochi.user.model.entity.User;
|
||||||
@ -1,8 +1,8 @@
|
|||||||
package com.magamochi.model.repository;
|
package com.magamochi.userinteraction.model.repository;
|
||||||
|
|
||||||
import com.magamochi.catalog.model.entity.Manga;
|
import com.magamochi.catalog.model.entity.Manga;
|
||||||
import com.magamochi.model.entity.UserMangaFollow;
|
|
||||||
import com.magamochi.user.model.entity.User;
|
import com.magamochi.user.model.entity.User;
|
||||||
|
import com.magamochi.userinteraction.model.entity.UserMangaFollow;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
package com.magamochi.userinteraction.service;
|
||||||
|
|
||||||
|
import com.magamochi.catalog.model.entity.Manga;
|
||||||
|
import com.magamochi.catalog.model.repository.MangaRepository;
|
||||||
|
import com.magamochi.common.exception.NotFoundException;
|
||||||
|
import com.magamochi.user.service.UserService;
|
||||||
|
import com.magamochi.userinteraction.model.entity.UserMangaFollow;
|
||||||
|
import com.magamochi.userinteraction.model.repository.UserMangaFollowRepository;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class UserMangaFollowService {
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
|
private final MangaRepository mangaRepository;
|
||||||
|
private final UserMangaFollowRepository userMangaFollowRepository;
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void follow(Long mangaId) {
|
||||||
|
var user = userService.getLoggedUserThrowIfNotFound();
|
||||||
|
|
||||||
|
var manga = findMangaByIdThrowIfNotFound(mangaId);
|
||||||
|
manga.setFollow(true);
|
||||||
|
|
||||||
|
if (userMangaFollowRepository.existsByUserAndManga(user, manga)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
userMangaFollowRepository.save(UserMangaFollow.builder().user(user).manga(manga).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void unfollow(Long mangaId) {
|
||||||
|
var user = userService.getLoggedUserThrowIfNotFound();
|
||||||
|
var manga = findMangaByIdThrowIfNotFound(mangaId);
|
||||||
|
|
||||||
|
var userMangaFollow = userMangaFollowRepository.findByUserAndManga(user, manga);
|
||||||
|
userMangaFollow.ifPresent(userMangaFollowRepository::delete);
|
||||||
|
|
||||||
|
if (!userMangaFollowRepository.existsByManga(manga)) {
|
||||||
|
manga.setFollow(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Manga findMangaByIdThrowIfNotFound(Long mangaId) {
|
||||||
|
return mangaRepository
|
||||||
|
.findById(mangaId)
|
||||||
|
.orElseThrow(() -> new NotFoundException("Manga not found for ID: " + mangaId));
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user