added reviews
This commit is contained in:
@@ -8,6 +8,7 @@ import java.util.List;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
@@ -29,10 +30,7 @@ public class PostController {
|
|||||||
private final PostService service;
|
private final PostService service;
|
||||||
|
|
||||||
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
public PostRequest create(
|
public PostRequest create(@ModelAttribute PostRequest request, @RequestPart(value = "image", required = false) MultipartFile image) {
|
||||||
@ModelAttribute PostRequest request,
|
|
||||||
@RequestPart(value = "image", required = false) MultipartFile image
|
|
||||||
) {
|
|
||||||
log.info(request.toString());
|
log.info(request.toString());
|
||||||
return service.create(request, image);
|
return service.create(request, image);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.krylov.refound.controller;
|
||||||
|
|
||||||
|
import com.krylov.refound.dto.ReviewRequestDto;
|
||||||
|
import com.krylov.refound.dto.ReviewResponseDto;
|
||||||
|
import com.krylov.refound.service.ReviewService;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
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/v1/reviews")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
|
public class ReviewsController {
|
||||||
|
|
||||||
|
private final ReviewService reviewService;
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public List<ReviewResponseDto> getAllReviews() {
|
||||||
|
List<ReviewResponseDto> allReviews = reviewService.getAllReviews();
|
||||||
|
log.info("Got all reviews: {}", allReviews);
|
||||||
|
return allReviews;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
@PreAuthorize("isAuthenticated()")
|
||||||
|
public ReviewResponseDto createReview(@Valid @RequestBody ReviewRequestDto request, Authentication authentication) {
|
||||||
|
// Взять имя пользователя из authentication
|
||||||
|
return reviewService.createReview(request, authentication.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/main/java/com/krylov/refound/dto/ReviewRequestDto.java
Normal file
18
src/main/java/com/krylov/refound/dto/ReviewRequestDto.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package com.krylov.refound.dto;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Max;
|
||||||
|
import jakarta.validation.constraints.Min;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ReviewRequestDto {
|
||||||
|
@NotNull
|
||||||
|
@Min(1)
|
||||||
|
@Max(5)
|
||||||
|
private Integer rating;
|
||||||
|
|
||||||
|
@Size(max = 500)
|
||||||
|
private String text;
|
||||||
|
}
|
||||||
11
src/main/java/com/krylov/refound/dto/ReviewResponseDto.java
Normal file
11
src/main/java/com/krylov/refound/dto/ReviewResponseDto.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package com.krylov.refound.dto;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
public record ReviewResponseDto(
|
||||||
|
Long id,
|
||||||
|
String authorName,
|
||||||
|
Integer rating,
|
||||||
|
String text,
|
||||||
|
LocalDateTime createdAt) {
|
||||||
|
}
|
||||||
39
src/main/java/com/krylov/refound/entity/Review.java
Normal file
39
src/main/java/com/krylov/refound/entity/Review.java
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package com.krylov.refound.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.PrePersist;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "reviews")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class Review {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "author_name")
|
||||||
|
private String authorName;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private Integer rating; // 1-5
|
||||||
|
|
||||||
|
@Column(length = 500)
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
@Column(name = "created_at", nullable = false)
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@PrePersist
|
||||||
|
protected void onCreate() {
|
||||||
|
createdAt = LocalDateTime.now();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.krylov.refound.repository;
|
||||||
|
|
||||||
|
import com.krylov.refound.entity.Review;
|
||||||
|
import java.util.List;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface ReviewRepository extends JpaRepository<Review, Long> {
|
||||||
|
List<Review> findAllByOrderByCreatedAtDesc();
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ public class SecurityConfig {
|
|||||||
// Public endpoints
|
// Public endpoints
|
||||||
.requestMatchers("/api/v1/auth/**").permitAll()
|
.requestMatchers("/api/v1/auth/**").permitAll()
|
||||||
.requestMatchers(org.springframework.http.HttpMethod.GET, "/api/v1/posts/**").permitAll()
|
.requestMatchers(org.springframework.http.HttpMethod.GET, "/api/v1/posts/**").permitAll()
|
||||||
|
.requestMatchers("/api/v1/reviews/**").permitAll()
|
||||||
.requestMatchers("/files/**", "/uploads/**").permitAll()
|
.requestMatchers("/files/**", "/uploads/**").permitAll()
|
||||||
.requestMatchers("/ws/**").permitAll()
|
.requestMatchers("/ws/**").permitAll()
|
||||||
// All other endpoints require authentication
|
// All other endpoints require authentication
|
||||||
|
|||||||
@@ -35,12 +35,14 @@ public class PostService {
|
|||||||
private final PostMapper mapper;
|
private final PostMapper mapper;
|
||||||
private final ImageRepository imageRepository;
|
private final ImageRepository imageRepository;
|
||||||
private final NominatimService nominatimService;
|
private final NominatimService nominatimService;
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
public PostRequest create(PostRequest request, MultipartFile image) {
|
public PostRequest create(PostRequest request, MultipartFile image) {
|
||||||
|
|
||||||
Post post = mapper.toEntity(request);
|
Post post = mapper.toEntity(request);
|
||||||
post.setCreatedAt(LocalDateTime.now());
|
post.setCreatedAt(LocalDateTime.now());
|
||||||
post.setStatus(PostStatus.ACTIVE);
|
post.setStatus(PostStatus.ACTIVE);
|
||||||
|
post.setUser(userService.getCurrentUser()); // присваиваем текущего пользователя
|
||||||
repository.save(post); // сначала сохраняем post, чтобы получить id
|
repository.save(post); // сначала сохраняем post, чтобы получить id
|
||||||
|
|
||||||
if (image != null && !image.isEmpty()) {
|
if (image != null && !image.isEmpty()) {
|
||||||
|
|||||||
45
src/main/java/com/krylov/refound/service/ReviewService.java
Normal file
45
src/main/java/com/krylov/refound/service/ReviewService.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package com.krylov.refound.service;
|
||||||
|
|
||||||
|
import com.krylov.refound.dto.ReviewRequestDto;
|
||||||
|
import com.krylov.refound.dto.ReviewResponseDto;
|
||||||
|
import com.krylov.refound.entity.Review;
|
||||||
|
import com.krylov.refound.repository.ReviewRepository;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class ReviewService {
|
||||||
|
|
||||||
|
private final ReviewRepository reviewRepository;
|
||||||
|
|
||||||
|
public List<ReviewResponseDto> getAllReviews() {
|
||||||
|
return reviewRepository.findAllByOrderByCreatedAtDesc()
|
||||||
|
.stream()
|
||||||
|
.map(this::toResponse)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReviewResponseDto createReview(ReviewRequestDto request, String username) {
|
||||||
|
Review review = new Review();
|
||||||
|
review.setAuthorName(username); // или firstName из User
|
||||||
|
review.setRating(request.getRating());
|
||||||
|
review.setText(request.getText());
|
||||||
|
review.setCreatedAt(LocalDateTime.now());
|
||||||
|
|
||||||
|
Review saved = reviewRepository.save(review);
|
||||||
|
return toResponse(saved);
|
||||||
|
}
|
||||||
|
private ReviewResponseDto toResponse(Review r) {
|
||||||
|
return new ReviewResponseDto(
|
||||||
|
r.getId(),
|
||||||
|
r.getAuthorName(),
|
||||||
|
r.getRating(),
|
||||||
|
r.getText(),
|
||||||
|
r.getCreatedAt()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
databaseChangeLog:
|
||||||
|
- changeSet:
|
||||||
|
id: 008-create-reviews
|
||||||
|
author: you
|
||||||
|
changes:
|
||||||
|
- createTable:
|
||||||
|
tableName: reviews
|
||||||
|
columns:
|
||||||
|
- column: { name: id, type: BIGSERIAL, constraints: { primaryKey: true } }
|
||||||
|
- column: { name: author_name, type: VARCHAR(255) }
|
||||||
|
- column: { name: rating, type: INTEGER, constraints: { nullable: false } }
|
||||||
|
- column: { name: text, type: VARCHAR(500) }
|
||||||
|
- column: { name: created_at, type: TIMESTAMP, constraints: { nullable: false } }
|
||||||
@@ -14,3 +14,4 @@ databaseChangeLog:
|
|||||||
- include: { file: db/changelog/add/003-add-phone-posts.yaml }
|
- include: { file: db/changelog/add/003-add-phone-posts.yaml }
|
||||||
- include: { file: db/changelog/add/004-add-fields-user.yaml }
|
- include: { file: db/changelog/add/004-add-fields-user.yaml }
|
||||||
- include: { file: db/changelog/add/005-add-user-avatarUrl.yaml }
|
- include: { file: db/changelog/add/005-add-user-avatarUrl.yaml }
|
||||||
|
- include: { file: db/changelog/create/008-create-reviews.yaml }
|
||||||
Reference in New Issue
Block a user