feat: implement image management functionality; add ImageController, ImageService, ImageMapper, and related DTOs
This commit is contained in:
@@ -0,0 +1,63 @@
|
|||||||
|
package fr.gameovergne.api.controller.app;
|
||||||
|
|
||||||
|
import fr.gameovergne.api.dto.app.ImageDTO;
|
||||||
|
import fr.gameovergne.api.mapper.app.ImageMapper;
|
||||||
|
import fr.gameovergne.api.model.app.Image;
|
||||||
|
import fr.gameovergne.api.service.app.ImageService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/app/images")
|
||||||
|
public class ImageController {
|
||||||
|
|
||||||
|
private final ImageService imageService;
|
||||||
|
private final ImageMapper imageMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ImageController(ImageService imageService, ImageMapper imageMapper) {
|
||||||
|
this.imageService = imageService;
|
||||||
|
this.imageMapper = imageMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public List<ImageDTO> getAllImages() {
|
||||||
|
return imageService.getAllImages()
|
||||||
|
.stream()
|
||||||
|
.map(imageMapper::toDto)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ResponseEntity<Image> getImageById(@PathVariable Long id) {
|
||||||
|
return imageService.getImageById(id)
|
||||||
|
.map(ResponseEntity::ok)
|
||||||
|
.orElse(ResponseEntity.notFound().build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public void saveImage(@RequestBody ImageDTO imageDTO) {
|
||||||
|
imageService.saveImage(imageMapper.fromDto(imageDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public ResponseEntity<Image> updateImage(@PathVariable Long id, @RequestBody ImageDTO imageDTO) {
|
||||||
|
Image image = imageMapper.fromDto(imageDTO);
|
||||||
|
image.setId(id);
|
||||||
|
return imageService.getImageById(id)
|
||||||
|
.map(existingImage -> imageService.updateImage(image)
|
||||||
|
.map(ResponseEntity::ok)
|
||||||
|
.orElse(ResponseEntity.notFound().build()))
|
||||||
|
.orElse(ResponseEntity.notFound().build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public ResponseEntity<Image> deleteImageById(@PathVariable Long id) {
|
||||||
|
return imageService.deleteImageById(id)
|
||||||
|
.map(image -> ResponseEntity.ok().body(image))
|
||||||
|
.orElse(ResponseEntity.notFound().build());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package fr.gameovergne.api.controller.app;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/app/products_images")
|
||||||
|
public class ProductImageController {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
21
api/src/main/java/fr/gameovergne/api/dto/app/ImageDTO.java
Normal file
21
api/src/main/java/fr/gameovergne/api/dto/app/ImageDTO.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package fr.gameovergne.api.dto.app;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class ImageDTO {
|
||||||
|
|
||||||
|
@JsonProperty("id")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@JsonProperty("name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@JsonProperty("url")
|
||||||
|
private String url;
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package fr.gameovergne.api.mapper.app;
|
||||||
|
|
||||||
|
import fr.gameovergne.api.dto.app.ImageDTO;
|
||||||
|
import fr.gameovergne.api.model.app.Image;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ImageMapper {
|
||||||
|
|
||||||
|
public Image fromDto(ImageDTO imageDTO) {
|
||||||
|
if (imageDTO == null) return null;
|
||||||
|
Image image = new Image();
|
||||||
|
image.setId(imageDTO.getId());
|
||||||
|
image.setName(imageDTO.getName());
|
||||||
|
image.setUrl(imageDTO.getUrl());
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImageDTO toDto(Image image) {
|
||||||
|
if (image == null) return null;
|
||||||
|
ImageDTO imageDTO = new ImageDTO();
|
||||||
|
imageDTO.setId(image.getId());
|
||||||
|
imageDTO.setName(image.getName());
|
||||||
|
imageDTO.setUrl(image.getUrl());
|
||||||
|
return imageDTO;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package fr.gameovergne.api.model.app;
|
package fr.gameovergne.api.model.app;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonBackReference;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
|
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
|
||||||
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
|
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
|
||||||
import fr.gameovergne.api.model.user.User;
|
import fr.gameovergne.api.model.user.User;
|
||||||
@@ -26,7 +25,7 @@ public class Image {
|
|||||||
|
|
||||||
@Column(length = 120, unique = true, nullable = false)
|
@Column(length = 120, unique = true, nullable = false)
|
||||||
@NotBlank
|
@NotBlank
|
||||||
private String title;
|
private String name;
|
||||||
|
|
||||||
@Column(length = 255, unique = true, nullable = false)
|
@Column(length = 255, unique = true, nullable = false)
|
||||||
@NotBlank
|
@NotBlank
|
||||||
@@ -34,7 +33,7 @@ public class Image {
|
|||||||
|
|
||||||
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
|
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
|
||||||
@JoinTable(
|
@JoinTable(
|
||||||
name = "user_images",
|
name = "users_images",
|
||||||
joinColumns = @JoinColumn(name = "image_id"),
|
joinColumns = @JoinColumn(name = "image_id"),
|
||||||
inverseJoinColumns = @JoinColumn(name = "user_id")
|
inverseJoinColumns = @JoinColumn(name = "user_id")
|
||||||
)
|
)
|
||||||
@@ -42,7 +41,7 @@ public class Image {
|
|||||||
|
|
||||||
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
|
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
|
||||||
@JoinTable(
|
@JoinTable(
|
||||||
name = "product_images",
|
name = "products_images",
|
||||||
joinColumns = @JoinColumn(name = "image_id"),
|
joinColumns = @JoinColumn(name = "image_id"),
|
||||||
inverseJoinColumns = @JoinColumn(name = "product_id")
|
inverseJoinColumns = @JoinColumn(name = "product_id")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class Product {
|
|||||||
|
|
||||||
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
|
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
|
||||||
@JoinTable(
|
@JoinTable(
|
||||||
name = "product_images",
|
name = "products_images",
|
||||||
joinColumns = @JoinColumn(name = "image_id"),
|
joinColumns = @JoinColumn(name = "image_id"),
|
||||||
inverseJoinColumns = @JoinColumn(name = "product_id")
|
inverseJoinColumns = @JoinColumn(name = "product_id")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class User implements UserDetails {
|
|||||||
|
|
||||||
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
|
@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
|
||||||
@JoinTable(
|
@JoinTable(
|
||||||
name = "user_images",
|
name = "users_images",
|
||||||
joinColumns = @JoinColumn(name = "image_id"),
|
joinColumns = @JoinColumn(name = "image_id"),
|
||||||
inverseJoinColumns = @JoinColumn(name = "user_id")
|
inverseJoinColumns = @JoinColumn(name = "user_id")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package fr.gameovergne.api.repository.app;
|
||||||
|
|
||||||
|
import fr.gameovergne.api.model.app.Image;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface ImageRepository extends JpaRepository<Image, Long> {
|
||||||
|
Optional<Image> findByName(String name);
|
||||||
|
Optional<Image> findByUrl(String url);
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package fr.gameovergne.api.service.app;
|
||||||
|
|
||||||
|
import fr.gameovergne.api.model.app.Image;
|
||||||
|
import fr.gameovergne.api.repository.app.ImageRepository;
|
||||||
|
import jakarta.transaction.Transactional;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ImageService {
|
||||||
|
|
||||||
|
private final ImageRepository imageRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ImageService(ImageRepository imageRepository) {
|
||||||
|
this.imageRepository = imageRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void saveImage(Image image) {
|
||||||
|
if (image.getId() == null) {
|
||||||
|
imageRepository.save(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Image> getAllImages() {
|
||||||
|
return imageRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Image> getImageById(Long id) {
|
||||||
|
return imageRepository.findById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Image> getImageByName(String name) {
|
||||||
|
return imageRepository.findByName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Image> getImageByUrl(String url) {
|
||||||
|
return imageRepository.findByUrl(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Optional<Image> updateImage(Image image) {
|
||||||
|
return imageRepository.findById(image.getId()).map(existingImage -> {
|
||||||
|
existingImage.setName(image.getName());
|
||||||
|
existingImage.setUrl(image.getUrl());
|
||||||
|
return imageRepository.save(existingImage);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Optional<Image> deleteImageById(Long id) {
|
||||||
|
Optional<Image> image = imageRepository.findById(id);
|
||||||
|
image.ifPresent(imageRepository::delete);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user