-
Notifications
You must be signed in to change notification settings - Fork 0
Feature comments #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 11 commits
d551e6e
c7ceb2e
49e4f02
6b79c5e
a550ce9
a31c02d
b49f3c3
0a07c55
5bf2732
d04c6ae
58a1e15
7440203
3208b6e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,4 @@ | ||
| # java-explore-with-me | ||
| Template repository for ExploreWithMe project. | ||
| --- | ||
| https://github.com/SugarFoxy/java-explore-with-me/pull/3 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| package ru.practicum.events.comments.controller; | ||
|
|
||
| import org.springframework.beans.factory.annotation.Autowired; | ||
| import org.springframework.http.HttpStatus; | ||
| import org.springframework.web.bind.annotation.*; | ||
| import ru.practicum.events.comments.dto.InputCommentDto; | ||
| import ru.practicum.events.comments.dto.OutCommentDto; | ||
| import ru.practicum.events.comments.service.CommentPrivateService; | ||
| import ru.practicum.util.exception.handler.CustomExceptionHandler; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/users/{userId}/comments") | ||
| @CustomExceptionHandler | ||
| public class ControllerPrivateComment { | ||
| private final CommentPrivateService service; | ||
|
|
||
| @Autowired | ||
| public ControllerPrivateComment(CommentPrivateService service) { | ||
| this.service = service; | ||
| } | ||
|
|
||
| @PostMapping | ||
| @ResponseStatus(HttpStatus.CREATED) | ||
| public OutCommentDto createComment(@PathVariable Long userId, | ||
| @RequestBody InputCommentDto dto) { | ||
| return service.createComment(userId, dto); | ||
| } | ||
|
|
||
| @PatchMapping("/{commId}") | ||
| public OutCommentDto updateComment(@PathVariable Long userId, | ||
| @PathVariable Long commId, | ||
| @RequestBody InputCommentDto dto) { | ||
| return service.updateComment(userId, commId, dto); | ||
| } | ||
|
|
||
| @DeleteMapping("/{commId}") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Может на |
||
| @ResponseStatus(HttpStatus.NO_CONTENT) | ||
| public void deleteComment(@PathVariable Long userId, | ||
| @PathVariable Long commId) { | ||
| service.deleteComment(userId, commId); | ||
| } | ||
|
|
||
| @PostMapping("/{commId}/like") | ||
| @ResponseStatus(HttpStatus.CREATED) | ||
| public OutCommentDto leaveRating(@PathVariable Long userId, | ||
| @PathVariable Long commId, | ||
| @RequestParam Boolean grade) { | ||
| return service.leaveRating(userId, commId, grade); | ||
| } | ||
|
|
||
| @DeleteMapping("/{commId}/like") | ||
| @ResponseStatus(HttpStatus.NO_CONTENT) | ||
| public void deleteRating(@PathVariable Long userId, | ||
| @PathVariable Long commId) { | ||
| service.deleteRating(userId, commId); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| package ru.practicum.events.comments.controller; | ||
|
|
||
| import org.springframework.beans.factory.annotation.Autowired; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RequestParam; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
| import ru.practicum.events.comments.dto.OutCommentDto; | ||
| import ru.practicum.events.comments.service.CommentPublicService; | ||
| import ru.practicum.util.exception.handler.CustomExceptionHandler; | ||
|
|
||
| import javax.validation.constraints.NotNull; | ||
| import javax.validation.constraints.Positive; | ||
| import javax.validation.constraints.PositiveOrZero; | ||
| import java.util.List; | ||
|
|
||
| @RestController | ||
| @RequestMapping("/comment") | ||
| @CustomExceptionHandler | ||
| public class ControllerPublicComment { | ||
| private final CommentPublicService service; | ||
|
|
||
| @Autowired | ||
| public ControllerPublicComment(CommentPublicService service) { | ||
| this.service = service; | ||
| } | ||
|
|
||
| @GetMapping | ||
| public List<OutCommentDto> getCommentByEvent(@NotNull @RequestParam Long eventId, | ||
| @RequestParam(defaultValue = "false") Boolean rating, | ||
| @PositiveOrZero @RequestParam(defaultValue = "0") int from, | ||
| @Positive @RequestParam(defaultValue = "10") int size) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Почему какие-то поля объектные, а какие-то примитивные, тем более если |
||
| return service.getCommentByEvent(eventId, rating, from, size); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package ru.practicum.events.comments.dto; | ||
|
|
||
| import lombok.*; | ||
|
|
||
| import javax.validation.constraints.NotBlank; | ||
| import javax.validation.constraints.NotNull; | ||
|
|
||
| @Setter | ||
| @Getter | ||
| @NoArgsConstructor | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Вот это ты где-то используешь? Если нет, то лучше удалить это из всех классов
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Когда дто приходи и десериализуется требует конструкторы. Неужели это так нагружает систему? Могу удалить билдер он тут не нужен. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. На самом деле систему это не нагружает, тут проблема в том, что такой доступный зоопарк возможностей по конструированию объекта приводит к тому, что каждый разработчик создает объекты по своему и это больно потом одному человеку сводить, когда надо довести горящий релиз до логического завершения. А так в целом билдер это отличный шаблон, очень удобно с ним работать, и вообще это довольно интересная концепция. |
||
| @AllArgsConstructor | ||
| @Builder | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. И
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. только от билдера. Хотя для написания тестов он был бы удобен. (очень он мне полюбился) |
||
| public class InputCommentDto { | ||
| @NotNull | ||
| @NotBlank | ||
| private String text; | ||
| private Long eventId; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package ru.practicum.events.comments.dto; | ||
|
|
||
| import lombok.*; | ||
| import ru.practicum.users.dto.UserShortDto; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| @Setter | ||
| @Getter | ||
| @AllArgsConstructor | ||
| @NoArgsConstructor | ||
| @Builder | ||
| public class OutCommentDto { | ||
| private Long id; | ||
| private UserShortDto commentator; | ||
| private String text; | ||
| private LocalDateTime commentTime; | ||
| private Long rating; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| package ru.practicum.events.comments.mapper; | ||
|
|
||
| import ru.practicum.events.comments.dto.InputCommentDto; | ||
| import ru.practicum.events.comments.dto.OutCommentDto; | ||
| import ru.practicum.events.comments.model.Comment; | ||
| import ru.practicum.events.event.model.Event; | ||
| import ru.practicum.users.mapper.UserMapper; | ||
| import ru.practicum.users.model.User; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| public class CommentMapper { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Если все методы статические, то лучше сделать пустой конструктор этого класса приватным, чтобы везде гарантированно использовать его, как синглтон: https://en.wikipedia.org/wiki/Singleton_pattern Либо можно вместо класса использовать https://www.geeksforgeeks.org/advantages-and-disadvantages-of-using-enum-as-singleton-in-java/ |
||
| public static OutCommentDto toDto(Comment comment) { | ||
| return OutCommentDto.builder() | ||
| .commentator(UserMapper.toShortDto(comment.getCommentator())) | ||
| .commentTime(comment.getCommentTime()) | ||
| .id(comment.getId()) | ||
| .text(comment.getText()) | ||
| .build(); | ||
| } | ||
|
|
||
| public static OutCommentDto toDto(Comment comment, Long rating) { | ||
| return OutCommentDto.builder() | ||
| .commentator(UserMapper.toShortDto(comment.getCommentator())) | ||
| .commentTime(comment.getCommentTime()) | ||
| .id(comment.getId()) | ||
| .text(comment.getText()) | ||
| .rating(rating) | ||
| .build(); | ||
| } | ||
|
|
||
| public static Comment toComment(InputCommentDto dto, LocalDateTime time, User commentator, Event event) { | ||
| return Comment.builder() | ||
| .commentator(commentator) | ||
| .text(dto.getText()) | ||
| .commentTime(time) | ||
| .event(event) | ||
| .build(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package ru.practicum.events.comments.model; | ||
|
|
||
| import lombok.*; | ||
| import ru.practicum.events.event.model.Event; | ||
| import ru.practicum.users.model.User; | ||
|
|
||
| import javax.persistence.*; | ||
| import java.time.LocalDateTime; | ||
|
|
||
| @Setter | ||
| @Getter | ||
| @Builder | ||
| @AllArgsConstructor | ||
| @NoArgsConstructor | ||
| @Entity | ||
| @Table(name = "comments") | ||
| public class Comment { | ||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| private Long id; | ||
| @Column(name = "comment_text") | ||
| private String text; | ||
| @ManyToOne() | ||
| @JoinColumn(name = "user_id") | ||
| private User commentator; | ||
| @ManyToOne() | ||
| @JoinColumn(name = "event_id") | ||
| private Event event; | ||
| @Column(name = "comment_time") | ||
| private LocalDateTime commentTime; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| package ru.practicum.events.comments.rating.model; | ||
|
|
||
| import lombok.*; | ||
| import ru.practicum.events.comments.model.Comment; | ||
| import ru.practicum.users.model.User; | ||
|
|
||
| import javax.persistence.*; | ||
|
|
||
| @Setter | ||
| @Getter | ||
| @Builder | ||
| @AllArgsConstructor | ||
| @NoArgsConstructor | ||
| @Entity | ||
| @Table(name = "rating") | ||
| public class Grade { | ||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| private Long id; | ||
| @ManyToOne() | ||
| @JoinColumn(name = "user_id") | ||
| private User rater; | ||
| @ManyToOne() | ||
| @JoinColumn(name = "comment_id") | ||
| private Comment comment; | ||
| private Boolean grade; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package ru.practicum.events.comments.rating.storage; | ||
|
|
||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
| import ru.practicum.events.comments.model.Comment; | ||
| import ru.practicum.events.comments.rating.model.Grade; | ||
| import ru.practicum.users.model.User; | ||
|
|
||
| public interface RatingRepository extends JpaRepository<Grade, Long> { | ||
| Long countGradeByCommentAndGrade(Comment comment, Boolean grade); | ||
|
|
||
| Boolean existsByCommentAndRater(Comment comment, User rater); | ||
|
|
||
| void deleteByCommentAndRater(Comment comment, User user); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package ru.practicum.events.comments.service; | ||
|
|
||
| import ru.practicum.events.comments.dto.InputCommentDto; | ||
| import ru.practicum.events.comments.dto.OutCommentDto; | ||
|
|
||
| public interface CommentPrivateService { | ||
| OutCommentDto createComment(Long userId, InputCommentDto dto); | ||
|
|
||
| OutCommentDto updateComment(Long userId, Long commentId, InputCommentDto dto); | ||
|
|
||
| void deleteComment(Long userId, Long commentId); | ||
|
|
||
| OutCommentDto leaveRating(Long userId, Long commentId, Boolean grade); | ||
|
|
||
| void deleteRating(Long userId, Long commentId); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| package ru.practicum.events.comments.service; | ||
|
|
||
| import org.springframework.beans.factory.annotation.Autowired; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
| import ru.practicum.events.comments.dto.InputCommentDto; | ||
| import ru.practicum.events.comments.dto.OutCommentDto; | ||
| import ru.practicum.events.comments.mapper.CommentMapper; | ||
| import ru.practicum.events.comments.model.Comment; | ||
| import ru.practicum.events.comments.rating.model.Grade; | ||
| import ru.practicum.events.comments.rating.storage.RatingRepository; | ||
| import ru.practicum.events.comments.storage.CommentRepository; | ||
| import ru.practicum.events.event.model.Event; | ||
| import ru.practicum.users.model.User; | ||
| import ru.practicum.util.RepositoryObjectCreator; | ||
| import ru.practicum.util.exception.BadRequestException; | ||
| import ru.practicum.util.exception.ConflictException; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| @Service | ||
| public class CommentPrivateServiceImpl implements CommentPrivateService { | ||
| private final CommentRepository commentRepository; | ||
| private final RepositoryObjectCreator objectCreator; | ||
| private final RatingRepository ratingRepository; | ||
|
|
||
| @Autowired | ||
| public CommentPrivateServiceImpl(CommentRepository commentRepository, | ||
| RepositoryObjectCreator objectCreator, | ||
| RatingRepository ratingRepository) { | ||
| this.commentRepository = commentRepository; | ||
| this.objectCreator = objectCreator; | ||
| this.ratingRepository = ratingRepository; | ||
| } | ||
|
|
||
| @Override | ||
| public OutCommentDto createComment(Long userId, InputCommentDto dto) { | ||
| Event event = objectCreator.getEventById(dto.getEventId()); | ||
| if (!event.getCommentSwitch()) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Наверное лучше
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Это не я, это гугл переводчик тебя испугал))))). Я буду скучать по твоим ревью :`( |
||
| throw new ConflictException("Невозможно добавить комментарий! У события отключены комментарии!"); | ||
| } | ||
| return CommentMapper.toDto(commentRepository.save(CommentMapper.toComment( | ||
| dto, | ||
| LocalDateTime.now(), | ||
| objectCreator.getUserById(userId), | ||
| event) | ||
| )); | ||
| } | ||
|
|
||
| @Override | ||
| public OutCommentDto updateComment(Long userId, Long commentId, InputCommentDto dto) { | ||
| Comment comment = objectCreator.getCommentById(commentId); | ||
|
|
||
| if (!comment.getCommentator().getId().equals(userId)) { | ||
| throw new BadRequestException(String | ||
| .format("Только комментатор может изменить коментарий id = %d ", commentId)); | ||
| } | ||
| if (!comment.getEvent().getId().equals(dto.getEventId())) { | ||
| throw new BadRequestException(String | ||
| .format("У события id = %d отсутствует коментарий id = %d", userId, commentId)); | ||
| } | ||
|
|
||
| comment.setText(dto.getText()); | ||
| return CommentMapper.toDto(commentRepository.save(comment)); | ||
| } | ||
|
|
||
| @Override | ||
| public void deleteComment(Long userId, Long commId) { | ||
| Comment comment = objectCreator.getCommentById(commId); | ||
|
|
||
| if (!comment.getCommentator().getId().equals(userId)) { | ||
| throw new BadRequestException(String | ||
| .format("Только комментатор может удалить коментарий id = %d ", commId)); | ||
| } | ||
| commentRepository.deleteById(commId); | ||
| } | ||
|
|
||
| @Override | ||
| public OutCommentDto leaveRating(Long userId, Long commentId, Boolean grade) { | ||
| if (ratingRepository | ||
| .existsByCommentAndRater(objectCreator.getCommentById(commentId), objectCreator.getUserById(userId))) { | ||
| throw new ConflictException("Отавить оценку комментарию можно один раз"); | ||
| } | ||
| ratingRepository.save(Grade.builder() | ||
| .comment(objectCreator.getCommentById(commentId)) | ||
| .rater(objectCreator.getUserById(userId)) | ||
| .grade(grade) | ||
| .build()); | ||
| Comment comment = objectCreator.getCommentById(commentId); | ||
| return CommentMapper.toDto(comment, ratingRepository.countGradeByCommentAndGrade(comment, true) | ||
| - ratingRepository.countGradeByCommentAndGrade(comment, false)); | ||
| } | ||
|
|
||
| @Override | ||
| @Transactional | ||
| public void deleteRating(Long userId, Long commentId) { | ||
| Comment comment = objectCreator.getCommentById(commentId); | ||
| User user = objectCreator.getUserById(userId); | ||
| if (!ratingRepository.existsByCommentAndRater(comment, user)) { | ||
| throw new BadRequestException(String.format("Невозможно удалеть лайк! " + | ||
| "Пользователь id = %d не ставил оценку комментарию id = %d", userId, commentId)); | ||
| } | ||
| ratingRepository | ||
| .deleteByCommentAndRater(comment, user); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| package ru.practicum.events.comments.service; | ||
|
|
||
| import ru.practicum.events.comments.dto.OutCommentDto; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public interface CommentPublicService { | ||
| List<OutCommentDto> getCommentByEvent(Long eventId, Boolean rating, int from, int size); | ||
| } |
This comment was marked as resolved.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Спасибо что подсказал. Не дружу с английским. Поэтому и названия кривые