Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,34 @@
# java-explore-with-me
Template repository for ExploreWithMe project.

#Ссылка на pull-request
https://github.com/KonneyJ/java-explore-with-me/pull/3

# Реализация дополнительной функциональности: likes
1) POST /users/{userId}/events/{eventId}/likes
- добавление лайка событию
2) DELETE /users/{userId}/events/{eventId}/likes/{likeId}
- удаление лайка
3) PATCH /users/{userId}/events/{eventId}/likes/{likeId}
- редактирование лайка
4) GET /users/{userId}/events/{eventId}/likes/{likeId}
- получение лайка по идентификатору
5) GET /users/{userId}/likes
- получение всех лайков пользователя
6) GET /users/{userId}/events/{eventId}/likes
- получение всех лайков события

## Интеграция

- Private API

## Логика

- Нельзя ставить лайк своему событию
- Лайк можно поставить только посещенному мероприятию
- Лайк можно поставить только через 3 часа после начала мероприятия
- Лайк можно поставить только опубликованному событию
- Удалять/обновлять лайки могут только пользователи, которые их поставили
- Нет ограничений на время редактирования лайка
- Лайк может посмотреть либо человек, который его поставил, либо владелец события
- Посмотреть все лайки может только владелец события
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import org.springframework.stereotype.Component;
import ru.practicum.ewm.compilation.Compilation;
import ru.practicum.ewm.event.dto.EventMapper;
import ru.practicum.ewm.event.mapper.EventMapper;

import java.util.stream.Collectors;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public class NewEventDto {
private String annotation;

@NotNull(message = "Поле category не может быть null")
//@NotBlank(message = "Поле category не может быть пустым")
private Integer category;

@NotNull(message = "Поле description не может быть null")
Expand All @@ -37,7 +36,6 @@ public class NewEventDto {
private LocalDateTime eventDate;

@NotNull(message = "Поле location не может быть null")
//@NotBlank(message = "Поле location не может быть пустым")
private Location location;

@Builder.Default
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package ru.practicum.ewm.event.dto;
package ru.practicum.ewm.event.mapper;

import org.springframework.stereotype.Component;
import ru.practicum.ewm.category.dto.CategoryMapper;
import ru.practicum.ewm.event.dto.*;
import ru.practicum.ewm.event.model.Event;
import ru.practicum.ewm.user.dto.UserMapper;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import ru.practicum.ewm.category.Category;
import ru.practicum.ewm.category.CategoryRepository;
import ru.practicum.ewm.event.dto.*;
import ru.practicum.ewm.event.mapper.EventMapper;
import ru.practicum.ewm.event.model.Event;
import ru.practicum.ewm.event.model.Location;
import ru.practicum.ewm.event.model.QEvent;
Expand Down Expand Up @@ -249,7 +250,6 @@ public EventFullDto createEvent(int userId, NewEventDto newEventDto) {
Event savedEvent = eventRepository.save(event);
log.info("Событие успешно сохранено с id {}", savedEvent.getId());
EventFullDto eventFullDto = eventMapper.toEventFullDto(savedEvent);
//eventFullDto.setViews(0);
return eventFullDto;
}

Expand Down
42 changes: 42 additions & 0 deletions main-service/src/main/java/ru/practicum/ewm/like/Like.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package ru.practicum.ewm.like;

import jakarta.persistence.*;
import lombok.*;
import ru.practicum.ewm.event.model.Event;
import ru.practicum.ewm.request.model.Request;
import ru.practicum.ewm.user.User;

import java.time.LocalDateTime;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "likes")
@Builder
@ToString
public class Like {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "like_id")
private Integer id;

@Column(name = "liked", nullable = false)
private Boolean liked;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private User user;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "event_id")
private Event event;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "request_id")
private Request request;

@Column(name = "created_date")
private LocalDateTime createdOn;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package ru.practicum.ewm.like;

import jakarta.validation.Valid;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.PositiveOrZero;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import ru.practicum.ewm.like.dto.LikeFullDto;
import ru.practicum.ewm.like.dto.LikeShortDto;
import ru.practicum.ewm.like.dto.NewLikeDto;
import ru.practicum.ewm.like.service.LikeService;

import java.util.Collection;

@Slf4j
@RestController
@RequestMapping(path = "/users/{userId}")
@RequiredArgsConstructor
public class LikePrivateController {
private final LikeService likeService;

@PostMapping("/events/{eventId}/likes")
@ResponseStatus(HttpStatus.CREATED)
public LikeFullDto createLike(@PathVariable("userId") int userId,
@PathVariable("eventId") int eventId,
@Valid @RequestBody NewLikeDto newLikeDto) {
log.info("PRIVATE POST /users/{userId}/events/{eventId}/likes запрос with userId {}, eventId {}, newLikeDto {}",
userId, eventId, newLikeDto);
return likeService.createLike(userId, eventId, newLikeDto);
}

@DeleteMapping("/events/{eventId}/likes/{likeId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteLike(@PathVariable("userId") int userId,
@PathVariable("eventId") int eventId,
@PathVariable("likeId") int likeId) {
log.info("PRIVATE DELETE /users/{userId}/events/{eventId}/likes/{likeId} запрос with userId {}, eventId {}," +
" likeId {}", userId, eventId, likeId);
likeService.deleteLike(userId, eventId, likeId);
}

@PatchMapping("/events/{eventId}/likes/{likeId}")
public LikeFullDto updateLike(@PathVariable("userId") int userId,
@PathVariable("eventId") int eventId,
@PathVariable("likeId") int likeId) {
log.info("PRIVATE PATCH /users/{userId}/events/{eventId}/likes/{likeId} запрос with userId {}, eventId {}," +
" likeId {}", userId, eventId, likeId);
return likeService.updateLike(userId, eventId, likeId);
}

@GetMapping("/events/{eventId}/likes/{likeId}")
public LikeFullDto getLikeById(@PathVariable("userId") int userId,
@PathVariable("eventId") int eventId,
@PathVariable("likeId") int likeId) {
log.info("PRIVATE GET /users/{userId}/events/{eventId}/likes/{likeId} запрос with userId {}, eventId {}," +
" likeId {}", userId, eventId, likeId);
return likeService.getLikeById(userId, eventId, likeId);
}

@GetMapping("/events/{eventId}/likes")
public Collection<LikeShortDto> getAllLikesByEvent(@PathVariable("userId") int userId,
@PathVariable("eventId") int eventId,
@RequestParam(defaultValue = "0") @PositiveOrZero int from,
@RequestParam(defaultValue = "10") @Positive int size) {
log.info("PRIVATE GET /users/{userId}/events/{eventId}/likes запрос with userId {}, eventId {}, from {}, " +
"size {}", userId, eventId, from, size);
return likeService.getAllLikesByEvent(userId, eventId, from, size);
}

@GetMapping("/likes")
public Collection<LikeShortDto> getAllLikesByUser(@PathVariable("userId") int userId,
@RequestParam(defaultValue = "0") @PositiveOrZero int from,
@RequestParam(defaultValue = "10") @Positive int size) {
log.info("PRIVATE GET /users/{userId}/likes запрос with userId {}, from {}, size {}", userId, from, size);
return likeService.getAllLikesByUser(userId, from, size);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ru.practicum.ewm.like;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface LikeRepository extends JpaRepository<Like, Integer> {

List<Like> findAllByEventId(int eventId, PageRequest page);

List<Like> findAllByUserId(int userId, PageRequest page);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package ru.practicum.ewm.like.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class LikeFullDto {
private Integer id;

@NotNull(message = "Поле liked не может быть null")
private Boolean liked;

private Integer user;

private Integer event;

private Integer request;

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime created;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package ru.practicum.ewm.like.dto;

import org.springframework.stereotype.Component;
import ru.practicum.ewm.like.Like;

@Component
public class LikeMapper {
public static LikeFullDto toFullDto(Like like) {
return LikeFullDto.builder()
.id(like.getId())
.liked(like.getLiked())
.user(like.getUser().getId())
.event(like.getEvent().getId())
.request(like.getRequest().getId())
.created(like.getCreatedOn())
.build();
}

public static LikeShortDto toShortDto(Like like) {
return LikeShortDto.builder()
.id(like.getId())
.liked(like.getLiked())
.created(like.getCreatedOn())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package ru.practicum.ewm.like.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class LikeShortDto {
private Integer id;

@NotNull(message = "Поле liked не может быть null")
private Boolean liked;

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime created;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ru.practicum.ewm.like.dto;

import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class NewLikeDto {
@NotNull(message = "Поле liked не может быть null")
private Boolean liked;

@NotNull(message = "Поле user не может быть null")
private Integer user;

@NotNull(message = "Поле event не может быть null")
private Integer event;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ru.practicum.ewm.like.service;

import ru.practicum.ewm.like.dto.LikeFullDto;
import ru.practicum.ewm.like.dto.LikeShortDto;
import ru.practicum.ewm.like.dto.NewLikeDto;

import java.util.Collection;

public interface LikeService {

LikeFullDto createLike(int userId, int eventId, NewLikeDto newLikeDto);

void deleteLike(int userId, int eventId, int likeId);

LikeFullDto updateLike(int userId, int eventId, int likeId);

LikeFullDto getLikeById(int userId, int eventId, int likeId);

Collection<LikeShortDto> getAllLikesByEvent(int userId, int eventId, int from, int size);

Collection<LikeShortDto> getAllLikesByUser(int userId, int from, int size);
}
Loading