done (not)
This commit is contained in:
parent
42800e0fbe
commit
361337b5d0
@ -51,7 +51,7 @@ public class SecurityConfiguration {
|
|||||||
.logout().permitAll()
|
.logout().permitAll()
|
||||||
.and()
|
.and()
|
||||||
.exceptionHandling().accessDeniedPage("/login");
|
.exceptionHandling().accessDeniedPage("/login");
|
||||||
http.formLogin().defaultSuccessUrl("/index", true);
|
http.formLogin().defaultSuccessUrl("/categories", true);
|
||||||
return http.userDetailsService(userService).build();
|
return http.userDetailsService(userService).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
package com.kalyshev.yan.cabinet.controller;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.WebConfiguration;
|
|
||||||
import com.kalyshev.yan.cabinet.service.CabinetService;
|
|
||||||
import com.kalyshev.yan.computer.controller.ComputerDto;
|
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping(WebConfiguration.REST_API + "/cabinet")
|
|
||||||
public class CabinetController {
|
|
||||||
private final CabinetService cabinetService;
|
|
||||||
public CabinetController(CabinetService cabinetService) {
|
|
||||||
this.cabinetService = cabinetService;
|
|
||||||
}
|
|
||||||
@GetMapping("/{id}")
|
|
||||||
public CabinetDto getCabinet(@PathVariable Long id) {
|
|
||||||
return new CabinetDto(cabinetService.findCabinet(id));
|
|
||||||
}
|
|
||||||
@GetMapping("/")
|
|
||||||
public List<CabinetDto> getCabinets() {
|
|
||||||
return cabinetService.findAllCabinets().stream()
|
|
||||||
.map(CabinetDto::new)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
@GetMapping("/{id}/computers")
|
|
||||||
public List<ComputerDto> getCabinetComputers(@PathVariable Long id) {
|
|
||||||
return cabinetService.listComputersFromCabinet(id).stream()
|
|
||||||
.map(ComputerDto::new)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
@GetMapping("/filter")
|
|
||||||
public List<CabinetDto> getFilteredCabinets(@RequestParam(value = "id", required = false) Long id,
|
|
||||||
@RequestParam(value = "number", required = false) String number) {
|
|
||||||
return cabinetService.findFilteredCabinets(id, number).stream()
|
|
||||||
.map(CabinetDto::new)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
@PostMapping("/")
|
|
||||||
public CabinetDto createCabinet(@RequestBody @Valid CabinetDto cabinetDto) {
|
|
||||||
return new CabinetDto(cabinetService.addCabinet(cabinetDto.getNumber()));
|
|
||||||
}
|
|
||||||
@PostMapping("/{id}/computer")
|
|
||||||
public void createCabinetComputer(@PathVariable Long id,
|
|
||||||
@RequestParam("computerId") Long computerId) {
|
|
||||||
cabinetService.addComputerToCabinet(computerId, id);
|
|
||||||
}
|
|
||||||
@PutMapping("/{id}")
|
|
||||||
public CabinetDto updateCabinet(@PathVariable Long id,
|
|
||||||
@RequestBody @Valid CabinetDto cabinetDto) {
|
|
||||||
return new CabinetDto(cabinetService.updateCabinet(id, cabinetDto.getNumber()));
|
|
||||||
}
|
|
||||||
@DeleteMapping("/{id}")
|
|
||||||
public CabinetDto deleteCabinet(@PathVariable Long id) {
|
|
||||||
return new CabinetDto(cabinetService.deleteCabinet(id));
|
|
||||||
}
|
|
||||||
@DeleteMapping("/{cabinetId}/computer")
|
|
||||||
public void deleteCabinetComputer(@PathVariable Long cabinetId,
|
|
||||||
@RequestParam("computerId") Long computerId) {
|
|
||||||
cabinetService.deleteComputerFromCabinet(computerId, cabinetId);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package com.kalyshev.yan.cabinet.controller;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.cabinet.model.Cabinet;
|
|
||||||
import com.kalyshev.yan.computer.model.Computer;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CabinetDto {
|
|
||||||
private Long id;
|
|
||||||
private String number;
|
|
||||||
private List<Long> computerIds;
|
|
||||||
public CabinetDto() {}
|
|
||||||
public CabinetDto(Cabinet cabinet) {
|
|
||||||
this.id = cabinet.getId();
|
|
||||||
this.number = cabinet.getNumber();
|
|
||||||
if (cabinet.getComputers() == null) {
|
|
||||||
this.computerIds = new ArrayList<>();
|
|
||||||
} else {
|
|
||||||
this.computerIds = new ArrayList<>();
|
|
||||||
List<Computer> computers = cabinet.getComputers();
|
|
||||||
for (Computer computer : computers) {
|
|
||||||
computerIds.add(computer.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public Long getId() { return this.id; }
|
|
||||||
public void setId(Long id) { this.id = id; }
|
|
||||||
public String getNumber() { return this.number; }
|
|
||||||
public void setNumber(String number) { this.number = number; }
|
|
||||||
public List<Long> getComputerIds() { return this.computerIds; }
|
|
||||||
public void setComputerIds(List<Long> computerIds) { this.computerIds = computerIds; }
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
package com.kalyshev.yan.cabinet.controller;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.cabinet.service.CabinetService;
|
|
||||||
import jakarta.validation.Valid;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.computer.controller.ComputerDto;
|
|
||||||
import com.kalyshev.yan.computer.service.ComputerService;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.validation.BindingResult;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/index")
|
|
||||||
public class CabinetMvcController {
|
|
||||||
private final CabinetService cabinetService;
|
|
||||||
private final ComputerService computerService;
|
|
||||||
public CabinetMvcController(CabinetService cabinetService,
|
|
||||||
ComputerService computerService) {
|
|
||||||
this.cabinetService = cabinetService;
|
|
||||||
this.computerService = computerService;
|
|
||||||
}
|
|
||||||
@GetMapping
|
|
||||||
public String getCabinets(Model model) {
|
|
||||||
model.addAttribute("cabinets",
|
|
||||||
cabinetService.findAllCabinets().stream()
|
|
||||||
.map(CabinetDto::new)
|
|
||||||
.toList());
|
|
||||||
return "index";
|
|
||||||
}
|
|
||||||
@GetMapping(value = {"/edit", "/edit/{id}"})
|
|
||||||
public String editCabinet(@PathVariable(required = false) Long id,
|
|
||||||
Model model) {
|
|
||||||
if (id == null || id <= 0) {
|
|
||||||
model.addAttribute("cabinetDto", new CabinetDto());
|
|
||||||
} else {
|
|
||||||
model.addAttribute("cabinetId", id);
|
|
||||||
model.addAttribute("cabinetDto", new CabinetDto(cabinetService.findCabinet(id)));
|
|
||||||
}
|
|
||||||
model.addAttribute("computers",
|
|
||||||
computerService.findFilteredComputers(null, null, null, null, id).stream()
|
|
||||||
.map(ComputerDto::new)
|
|
||||||
.toList());
|
|
||||||
model.addAttribute("allComputers",
|
|
||||||
computerService.findAllComputers().stream()
|
|
||||||
.map(ComputerDto::new)
|
|
||||||
.toList());
|
|
||||||
return "cabinet-edit";
|
|
||||||
}
|
|
||||||
@PostMapping(value = {"", "/{id}"})
|
|
||||||
public String saveCabinet(@PathVariable(required = false) Long id,
|
|
||||||
@ModelAttribute @Valid CabinetDto cabinetDto,
|
|
||||||
BindingResult bindingResult,
|
|
||||||
Model model) {
|
|
||||||
if (bindingResult.hasErrors()) {
|
|
||||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
|
||||||
return "cabinet-edit";
|
|
||||||
}
|
|
||||||
if (id == null || id <= 0) {
|
|
||||||
cabinetService.addCabinet(cabinetDto.getNumber());
|
|
||||||
} else {
|
|
||||||
cabinetService.updateCabinet(id, cabinetDto.getNumber());
|
|
||||||
}
|
|
||||||
return "redirect:/index";
|
|
||||||
}
|
|
||||||
@PostMapping(value = "/{id}/computer/{computerId}")
|
|
||||||
public String addCabinetComputer(@PathVariable(value = "id") Long id,
|
|
||||||
@PathVariable(value = "computerId") Long computerId) {
|
|
||||||
cabinetService.addComputerToCabinet(computerId, id);
|
|
||||||
return "redirect:/index";
|
|
||||||
}
|
|
||||||
@PostMapping(value = "/{id}/computerDelete/{computerId}")
|
|
||||||
public String deleteCabinetComputer(@PathVariable(value = "id") Long id,
|
|
||||||
@PathVariable(value = "computerId") Long computerId) {
|
|
||||||
cabinetService.deleteComputerFromCabinet(computerId, id);
|
|
||||||
return "redirect:/index";
|
|
||||||
}
|
|
||||||
@PostMapping("/delete/{id}")
|
|
||||||
public String deleteCabinet(@PathVariable Long id) {
|
|
||||||
cabinetService.deleteCabinet(id);
|
|
||||||
return "redirect:/index";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
package com.kalyshev.yan.cabinet.model;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.computer.model.Computer;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name = "cabinet")
|
|
||||||
public class Cabinet {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue
|
|
||||||
private Long id;
|
|
||||||
private String number;
|
|
||||||
@OneToMany(cascade = {CascadeType.MERGE})
|
|
||||||
private List<Computer> computers;
|
|
||||||
|
|
||||||
public Cabinet() {
|
|
||||||
}
|
|
||||||
public Cabinet(String number) {
|
|
||||||
this.number = number;
|
|
||||||
}
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public String getNumber() {
|
|
||||||
return number;
|
|
||||||
}
|
|
||||||
public void setNumber(String number) {
|
|
||||||
this.number = number;
|
|
||||||
}
|
|
||||||
public List<Computer> getComputers() {
|
|
||||||
return computers;
|
|
||||||
}
|
|
||||||
public void addComputer(Computer computer){
|
|
||||||
if (computers == null){
|
|
||||||
this.computers = new ArrayList<>();
|
|
||||||
}
|
|
||||||
if (!computers.contains(computer)) {
|
|
||||||
this.computers.add(computer);
|
|
||||||
computer.setCabinet(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void removeComputer(Computer computer){
|
|
||||||
if (computers.contains(computer))
|
|
||||||
this.computers.remove(computer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o)
|
|
||||||
return true;
|
|
||||||
if (!(o instanceof Cabinet cabinet))
|
|
||||||
return false;
|
|
||||||
return Objects.equals(id, cabinet.id);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(id);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Cabinet{" +
|
|
||||||
"id=" + id +
|
|
||||||
", number='" + number + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package com.kalyshev.yan.cabinet.repository;
|
|
||||||
|
|
||||||
public class CabinetNotFoundException extends RuntimeException {
|
|
||||||
public CabinetNotFoundException(Long id) {
|
|
||||||
super(String.format("Cabinet with id [%s] is not found", id));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package com.kalyshev.yan.cabinet.repository;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.cabinet.model.Cabinet;
|
|
||||||
import com.kalyshev.yan.monitor.model.Monitor;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
|
||||||
import org.springframework.data.repository.query.Param;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface CabinetRepository extends JpaRepository<Cabinet, Long> {
|
|
||||||
@Query(value = "select s from Cabinet s where (s.id = :id or :id is Null) and (s.number = :number or :number is Null)")
|
|
||||||
public List<Cabinet> findFilteredCabinets(@Param("id") Long id,
|
|
||||||
@Param("number") String number);
|
|
||||||
}
|
|
@ -1,105 +0,0 @@
|
|||||||
package com.kalyshev.yan.cabinet.service;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.cabinet.model.Cabinet;
|
|
||||||
import com.kalyshev.yan.cabinet.repository.CabinetNotFoundException;
|
|
||||||
import com.kalyshev.yan.cabinet.repository.CabinetRepository;
|
|
||||||
import com.kalyshev.yan.computer.model.Computer;
|
|
||||||
import com.kalyshev.yan.computer.service.ComputerService;
|
|
||||||
import com.kalyshev.yan.util.validation.ValidatorUtil;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class CabinetService {
|
|
||||||
private final CabinetRepository cabinetRepository;
|
|
||||||
private final ComputerService computerService;
|
|
||||||
private final ValidatorUtil validatorUtil;
|
|
||||||
public CabinetService(CabinetRepository cabinetRepository,
|
|
||||||
ComputerService computerService,
|
|
||||||
ValidatorUtil validatorUtil) {
|
|
||||||
this.cabinetRepository = cabinetRepository;
|
|
||||||
this.computerService = computerService;
|
|
||||||
this.validatorUtil = validatorUtil;
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public Cabinet addCabinet(String number) {
|
|
||||||
if (!StringUtils.hasText(number)) {
|
|
||||||
throw new IllegalArgumentException("Cabinet number is null or empty");
|
|
||||||
}
|
|
||||||
final Cabinet cabinet = new Cabinet(number);
|
|
||||||
validatorUtil.validate(cabinet);
|
|
||||||
return cabinetRepository.save(cabinet);
|
|
||||||
}
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
public Cabinet findCabinet(Long id) {
|
|
||||||
final Optional<Cabinet> cabinet = cabinetRepository.findById(id);
|
|
||||||
return cabinet.orElseThrow(() -> new CabinetNotFoundException(id));
|
|
||||||
}
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
public List<Cabinet> findFilteredCabinets(Long id, String number) {
|
|
||||||
return cabinetRepository.findFilteredCabinets(id, number);
|
|
||||||
}
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
public List<Cabinet> findAllCabinets() {
|
|
||||||
return cabinetRepository.findAll();
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public Cabinet updateCabinet(Long id, String number) {
|
|
||||||
if (!StringUtils.hasText(number)) {
|
|
||||||
throw new IllegalArgumentException("Cabinet number is null or empty");
|
|
||||||
}
|
|
||||||
final Cabinet currentCabinet = findCabinet(id);
|
|
||||||
currentCabinet.setNumber(number);
|
|
||||||
validatorUtil.validate(currentCabinet);
|
|
||||||
return cabinetRepository.save(currentCabinet);
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public Cabinet deleteCabinet(Long id) {
|
|
||||||
final Cabinet currentCabinet = findCabinet(id);
|
|
||||||
computerService.deleteRelationsWithCabinets(currentCabinet.getComputers());
|
|
||||||
cabinetRepository.delete(currentCabinet);
|
|
||||||
return currentCabinet;
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public void deleteAllCabinets() {
|
|
||||||
cabinetRepository.deleteAll();
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public List<Computer> listComputersFromCabinet(Long id) {
|
|
||||||
if ((Object)id == null) {
|
|
||||||
throw new IllegalArgumentException("Cabinet id is null or empty");
|
|
||||||
}
|
|
||||||
return findCabinet(id).getComputers();
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public void addComputerToCabinet(Long computerId, Long cabinetId) {
|
|
||||||
if ((Object)computerId == null) {
|
|
||||||
throw new IllegalArgumentException("Computer id is null or empty");
|
|
||||||
}
|
|
||||||
if ((Object)cabinetId == null) {
|
|
||||||
throw new IllegalArgumentException("Cabinet id is null or empty");
|
|
||||||
}
|
|
||||||
final Computer computer = computerService.findComputer(computerId);
|
|
||||||
final Cabinet cabinet = findCabinet(cabinetId);
|
|
||||||
cabinet.addComputer(computer);
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public void deleteComputerFromCabinet(Long computerId, Long cabinetId) {
|
|
||||||
if ((Object) computerId == null) {
|
|
||||||
throw new IllegalArgumentException("Computer id is null or empty");
|
|
||||||
}
|
|
||||||
if ((Object) cabinetId == null) {
|
|
||||||
throw new IllegalArgumentException("Cabinet id is null or empty");
|
|
||||||
}
|
|
||||||
final Computer computer = computerService.findComputer(computerId);
|
|
||||||
final Cabinet cabinet = findCabinet(cabinetId);
|
|
||||||
cabinet.removeComputer(computer);
|
|
||||||
computer.setCabinet(null);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.kalyshev.yan.category.controller;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.WebConfiguration;
|
||||||
|
import com.kalyshev.yan.category.service.CategoryService;
|
||||||
|
import com.kalyshev.yan.video.service.VideoService;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(WebConfiguration.REST_API + "/category")
|
||||||
|
public class CategoryController {
|
||||||
|
private final CategoryService categoryService;
|
||||||
|
private final VideoService videoService;
|
||||||
|
public CategoryController(CategoryService categoryService,
|
||||||
|
VideoService videoService) {
|
||||||
|
this.categoryService = categoryService;
|
||||||
|
this.videoService = videoService;
|
||||||
|
}
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public CategoryDto getCategory(@PathVariable Long id) {
|
||||||
|
return new CategoryDto(categoryService.findCategory(id));
|
||||||
|
}
|
||||||
|
@GetMapping("/")
|
||||||
|
public List<CategoryDto> getCategories() {
|
||||||
|
return categoryService.findAllCategories().stream()
|
||||||
|
.map(CategoryDto::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
@GetMapping("/filter")
|
||||||
|
public List<CategoryDto> getFilteredCategories(@RequestParam(value = "id", required = false) Long id,
|
||||||
|
@RequestParam(value = "name", required = false) String name) {
|
||||||
|
return categoryService.findFilteredCategories(id, name).stream()
|
||||||
|
.map(CategoryDto::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
@PostMapping("/")
|
||||||
|
public CategoryDto createMonitor(@RequestBody @Valid CategoryDto categoryDto) {
|
||||||
|
return new CategoryDto(categoryService.addCategory(categoryDto.getName()));
|
||||||
|
}
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public CategoryDto updateMonitor(@PathVariable Long id,
|
||||||
|
@RequestBody @Valid CategoryDto categoryDto) {
|
||||||
|
return new CategoryDto(categoryService.updateCategory(id, categoryDto.getName()));
|
||||||
|
}
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public CategoryDto deleteMonitor(@PathVariable Long id) {
|
||||||
|
return new CategoryDto(categoryService.deleteCategory(id));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.kalyshev.yan.category.controller;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.cabinet.model.Cabinet;
|
||||||
|
import com.kalyshev.yan.category.model.Category;
|
||||||
|
import com.kalyshev.yan.computer.model.Computer;
|
||||||
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CategoryDto {
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private List<Long> videoIds;
|
||||||
|
public CategoryDto() {}
|
||||||
|
public CategoryDto(Category category) {
|
||||||
|
this.id = category.getId();
|
||||||
|
this.name = category.getName();
|
||||||
|
if (category.getVideos() == null) {
|
||||||
|
this.videoIds = new ArrayList<>();
|
||||||
|
} else {
|
||||||
|
this.videoIds = new ArrayList<>();
|
||||||
|
List<Video> videos = category.getVideos();
|
||||||
|
for (Video video : videos) {
|
||||||
|
videoIds.add(video.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Long getId() { return this.id; }
|
||||||
|
public void setId(Long id) { this.id = id; }
|
||||||
|
public String getName() { return this.name; }
|
||||||
|
public void setName(String name) { this.name = name; }
|
||||||
|
public List<Long> getVideoIds() { return this.videoIds; }
|
||||||
|
public void setVideoIds(List<Long> videoIds) { this.videoIds = videoIds; }
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
package com.kalyshev.yan.category.controller;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.category.model.Category;
|
||||||
|
import com.kalyshev.yan.category.service.CategoryService;
|
||||||
|
import com.kalyshev.yan.video.controller.VideoDto;
|
||||||
|
import com.kalyshev.yan.video.service.VideoService;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/categories")
|
||||||
|
public class CategoryMvcController {
|
||||||
|
private final CategoryService categoryService;
|
||||||
|
private final VideoService videoService;
|
||||||
|
public CategoryMvcController(CategoryService categoryService,
|
||||||
|
VideoService videoService) {
|
||||||
|
this.categoryService = categoryService;
|
||||||
|
this.videoService = videoService;
|
||||||
|
}
|
||||||
|
@GetMapping(value = {"", "/"})
|
||||||
|
public String getCategories(Model model) {
|
||||||
|
model.addAttribute("categories",
|
||||||
|
categoryService.findAllCategories().stream()
|
||||||
|
.map(CategoryDto::new)
|
||||||
|
.toList());
|
||||||
|
return "categories";
|
||||||
|
}
|
||||||
|
@GetMapping(value = {"/filter/", "/filter"})
|
||||||
|
public String getFilteredCategories(@RequestParam(value = "id", required = false) Long id,
|
||||||
|
Model model) {
|
||||||
|
model.addAttribute("categories",
|
||||||
|
categoryService.findFilteredCategories().stream()
|
||||||
|
.map(CategoryDto::new)
|
||||||
|
.toList());
|
||||||
|
return "categories";
|
||||||
|
}
|
||||||
|
@GetMapping(value = {"/edit/", "/edit/{id}"})
|
||||||
|
public String editCategory(@PathVariable(required = false) Long id,
|
||||||
|
Model model) {
|
||||||
|
if (id == null || id <= 0) {
|
||||||
|
model.addAttribute("categoryDto", new CategoryDto());
|
||||||
|
} else {
|
||||||
|
model.addAttribute("categoryId", id);
|
||||||
|
model.addAttribute("categoryDto", new CategoryDto(categoryService.findCategory(id)));
|
||||||
|
model.addAttribute("videos",
|
||||||
|
categoryService.listVideosFromCategory(id).stream()
|
||||||
|
.map(VideoDto::new)
|
||||||
|
.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
model.addAttribute("allVideos",
|
||||||
|
videoService.findAllVideos().stream()
|
||||||
|
.map(VideoDto::new)
|
||||||
|
.toList());
|
||||||
|
return "category-edit";
|
||||||
|
}
|
||||||
|
@PostMapping(value = {"", "/", "/{id}"})
|
||||||
|
public String saveCategory(@PathVariable(required = false) Long id,
|
||||||
|
@ModelAttribute @Valid CategoryDto categoryDto,
|
||||||
|
BindingResult bindingResult,
|
||||||
|
Model model) {
|
||||||
|
if (bindingResult.hasErrors()) {
|
||||||
|
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||||
|
return "category-edit";
|
||||||
|
}
|
||||||
|
if (id == null || id <= 0) {
|
||||||
|
categoryService.addCategory(categoryDto.getName());
|
||||||
|
} else {
|
||||||
|
categoryService.updateCategory(id, categoryDto.getName());
|
||||||
|
}
|
||||||
|
return "redirect:/categories";
|
||||||
|
}
|
||||||
|
@PostMapping("/delete/{id}")
|
||||||
|
public String deleteCategory(@PathVariable Long id) {
|
||||||
|
categoryService.deleteCategory(id);
|
||||||
|
return "redirect:/categories";
|
||||||
|
}
|
||||||
|
@PostMapping(value = "/{id}/video/{videoId}")
|
||||||
|
public String addCategoryVideo(@PathVariable(value = "id") Long id,
|
||||||
|
@PathVariable(value = "videoId") Long videoId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
categoryService.addVideoToCategory(id, videoId);
|
||||||
|
String referer = request.getHeader("Referer");
|
||||||
|
return "redirect:"+ referer;
|
||||||
|
}
|
||||||
|
@GetMapping(value = "/{id}/videoDelete/{videoId}")
|
||||||
|
public String deleteCategoryVideo(@PathVariable(value = "id") Long id,
|
||||||
|
@PathVariable(value = "videoId") Long videoId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
categoryService.deleteVideoFromCategory(id, videoId);
|
||||||
|
String referer = request.getHeader("Referer");
|
||||||
|
return "redirect:"+ referer;
|
||||||
|
}
|
||||||
|
}
|
71
src/main/java/com/kalyshev/yan/category/model/Category.java
Normal file
71
src/main/java/com/kalyshev/yan/category/model/Category.java
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package com.kalyshev.yan.category.model;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "category")
|
||||||
|
public class Category {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
@ManyToMany(cascade = {CascadeType.MERGE})
|
||||||
|
private List<Video> videos;
|
||||||
|
|
||||||
|
public Category() {
|
||||||
|
}
|
||||||
|
public Category(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
public List<Video> getVideos() {
|
||||||
|
return videos;
|
||||||
|
}
|
||||||
|
public void addVideo(Video video){
|
||||||
|
if (videos == null){
|
||||||
|
this.videos = new ArrayList<>();
|
||||||
|
}
|
||||||
|
if (!videos.contains(video)) {
|
||||||
|
this.videos.add(video);
|
||||||
|
video.addCategory(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void removeVideo(Video video){
|
||||||
|
if (videos.contains(video))
|
||||||
|
this.videos.remove(video);
|
||||||
|
video.removeCategory(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (!(o instanceof Category category))
|
||||||
|
return false;
|
||||||
|
return Objects.equals(id, category.id);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Video{" +
|
||||||
|
"id=" + id +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.kalyshev.yan.category.repository;
|
||||||
|
|
||||||
|
public class CategoryNotFoundException extends RuntimeException {
|
||||||
|
public CategoryNotFoundException(Long id) {
|
||||||
|
super(String.format("Category with id [%s] is not found", id));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.kalyshev.yan.category.repository;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.category.model.Category;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
|
import javax.management.monitor.Monitor;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface CategoryRepository extends JpaRepository<Category, Long> {
|
||||||
|
@Query(value = "select * from Category where (\"ID\" = :id or :id is Null) and " +
|
||||||
|
"(\"NAME\" = :name or :name is Null)", nativeQuery = true)
|
||||||
|
public List<Category> findFilteredCategories(@Param("id") Long id,
|
||||||
|
@Param("name") String name);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,136 @@
|
|||||||
|
package com.kalyshev.yan.category.service;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.category.repository.CategoryRepository;
|
||||||
|
import com.kalyshev.yan.category.model.Category;
|
||||||
|
import com.kalyshev.yan.category.repository.CategoryNotFoundException;
|
||||||
|
import com.kalyshev.yan.playlist.model.Playlist;
|
||||||
|
import com.kalyshev.yan.util.validation.ValidatorUtil;
|
||||||
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
import com.kalyshev.yan.video.service.VideoService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class CategoryService {
|
||||||
|
private final CategoryRepository categoryRepository;
|
||||||
|
private final VideoService videoService;
|
||||||
|
private final ValidatorUtil validatorUtil;
|
||||||
|
public CategoryService(CategoryRepository categoryRepository,
|
||||||
|
VideoService videoService,
|
||||||
|
ValidatorUtil validatorUtil) {
|
||||||
|
this.categoryRepository = categoryRepository;
|
||||||
|
this.videoService = videoService;
|
||||||
|
this.validatorUtil = validatorUtil;
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Category addCategory(String name) {
|
||||||
|
if (!StringUtils.hasText(name)) {
|
||||||
|
throw new IllegalArgumentException("Category model name is null or empty");
|
||||||
|
}
|
||||||
|
final Category category = new Category(name);
|
||||||
|
validatorUtil.validate(category);
|
||||||
|
return categoryRepository.save(category);
|
||||||
|
}
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public Category findCategory(Long id) {
|
||||||
|
final Optional<Category> category = categoryRepository.findById(id);
|
||||||
|
return category.orElseThrow(() -> new CategoryNotFoundException(id));
|
||||||
|
}
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public List<Category> findAllCategories() {
|
||||||
|
return categoryRepository.findAll();
|
||||||
|
}
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public List<Category> findFilteredCategories(Long id, String name) {
|
||||||
|
return categoryRepository.findFilteredCategories(id, name);
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Category updateCategory(Long id, String name) {
|
||||||
|
if (!StringUtils.hasText(name)) {
|
||||||
|
throw new IllegalArgumentException("Category name is null or empty");
|
||||||
|
}
|
||||||
|
final Category currentCategory = findCategory(id);
|
||||||
|
currentCategory.setName(name);
|
||||||
|
validatorUtil.validate(currentCategory);
|
||||||
|
return categoryRepository.save(currentCategory);
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Category deleteCategory(Long id) {
|
||||||
|
Category category = categoryRepository.findById(id).orElseThrow(() -> new CategoryNotFoundException(id));
|
||||||
|
categoryRepository.delete(category);
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public void deleteAllCategories() { categoryRepository.deleteAll(); }
|
||||||
|
@Transactional
|
||||||
|
public List<Video> listVideosFromCategory(Long id) {
|
||||||
|
if (id == null) {
|
||||||
|
throw new IllegalArgumentException("Category id is null or empty");
|
||||||
|
}
|
||||||
|
return findCategory(id).getVideos();
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Category addVideoToCategory(Long categoryId, Long videoId) {
|
||||||
|
if (videoId == null) {
|
||||||
|
throw new IllegalArgumentException("Video id is null or empty");
|
||||||
|
}
|
||||||
|
if (categoryId == null) {
|
||||||
|
throw new IllegalArgumentException("Category id is null or empty");
|
||||||
|
}
|
||||||
|
final Video video = videoService.findVideo(videoId);
|
||||||
|
final Category category = findCategory(categoryId);
|
||||||
|
category.addVideo(video);
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Category deleteVideoFromCategory(Long categoryId, Long videoId) {
|
||||||
|
if (videoId == null) {
|
||||||
|
throw new IllegalArgumentException("Video id is null or empty");
|
||||||
|
}
|
||||||
|
if (categoryId == null) {
|
||||||
|
throw new IllegalArgumentException("Category id is null or empty");
|
||||||
|
}
|
||||||
|
final Video video = videoService.findVideo(videoId);
|
||||||
|
final Category category = findCategory(categoryId);;
|
||||||
|
category.removeVideo(video);
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public List<Category> listCategoriesFromVideo(Long id) {
|
||||||
|
if (id == null) {
|
||||||
|
throw new IllegalArgumentException("Video id is null or empty");
|
||||||
|
}
|
||||||
|
return videoService.findVideo(id).getCategories();
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Video addCategoryToVideo(Long videoId, Long categoryId) {
|
||||||
|
if ((Object)videoId == null) {
|
||||||
|
throw new IllegalArgumentException("Video id is null or empty");
|
||||||
|
}
|
||||||
|
if ((Object)categoryId == null) {
|
||||||
|
throw new IllegalArgumentException("Category id is null or empty");
|
||||||
|
}
|
||||||
|
final Video video = videoService.findVideo(videoId);
|
||||||
|
final Category category = findCategory(categoryId);
|
||||||
|
video.addCategory(category);
|
||||||
|
return video;
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Video deleteCategoryFromVideo(Long videoId, Long categoryId) {
|
||||||
|
if (videoId == null) {
|
||||||
|
throw new IllegalArgumentException("Video id is null or empty");
|
||||||
|
}
|
||||||
|
if (categoryId == null) {
|
||||||
|
throw new IllegalArgumentException("Category id is null or empty");
|
||||||
|
}
|
||||||
|
final Video video = videoService.findVideo(videoId);
|
||||||
|
final Category category = findCategory(categoryId);
|
||||||
|
video.removeCategory(category);
|
||||||
|
return video;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package com.kalyshev.yan.comment.controller;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.WebConfiguration;
|
||||||
|
import com.kalyshev.yan.category.controller.CategoryDto;
|
||||||
|
import com.kalyshev.yan.category.model.Category;
|
||||||
|
import com.kalyshev.yan.category.service.CategoryService;
|
||||||
|
import com.kalyshev.yan.comment.service.CommentService;
|
||||||
|
import com.kalyshev.yan.playlist.controller.PlaylistDto;
|
||||||
|
import com.kalyshev.yan.playlist.model.Playlist;
|
||||||
|
import com.kalyshev.yan.playlist.service.PlaylistService;
|
||||||
|
import com.kalyshev.yan.user.model.User;
|
||||||
|
import com.kalyshev.yan.user.service.UserService;
|
||||||
|
import com.kalyshev.yan.util.validation.ValidatorUtil;
|
||||||
|
import com.kalyshev.yan.video.controller.VideoDto;
|
||||||
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
import com.kalyshev.yan.video.repository.VideoNotFoundException;
|
||||||
|
import com.kalyshev.yan.video.repository.VideoRepository;
|
||||||
|
import com.kalyshev.yan.video.service.VideoService;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(WebConfiguration.REST_API + "/comment")
|
||||||
|
public class CommentController {
|
||||||
|
private final CommentService commentService;
|
||||||
|
public CommentController(CommentService commentService) {
|
||||||
|
this.commentService = commentService;
|
||||||
|
}
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public CommentDto getComment(@PathVariable Long id) {
|
||||||
|
return new CommentDto(commentService.findComment(id));
|
||||||
|
}
|
||||||
|
@GetMapping("/")
|
||||||
|
public List<CommentDto> getComments() {
|
||||||
|
return commentService.findAllComments().stream()
|
||||||
|
.map(CommentDto::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
// @GetMapping("/filter")
|
||||||
|
// public List<VideoDto> getFilteredVideos(@RequestParam(value = "id", required = false) Long id,
|
||||||
|
// @RequestParam(value = "name", required = false) String name,
|
||||||
|
// @RequestParam(value = "date", required = false) LocalDate date,
|
||||||
|
// @RequestParam(value = "userId", required = false) Long monitorId) {
|
||||||
|
// return videoService.findFilteredVideos(id, name, date, monitorId).stream()
|
||||||
|
// .map(VideoDto::new)
|
||||||
|
// .toList();
|
||||||
|
// }
|
||||||
|
@PostMapping("/")
|
||||||
|
public CommentDto createPlaylist(@RequestBody @Valid CommentDto commentDto) {
|
||||||
|
return new CommentDto(commentService.addComment(commentDto.getComment(), commentDto.getUserId(), commentDto.getVideoId()));
|
||||||
|
}
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public CommentDto updateComment(@PathVariable Long id,
|
||||||
|
@RequestBody @Valid CommentDto commentDto) {
|
||||||
|
return new CommentDto(commentService.updateComment(id, commentDto.getComment()));
|
||||||
|
}
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public CommentDto deleteComment(@PathVariable Long id) {
|
||||||
|
return new CommentDto(commentService.deleteComment(id));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.kalyshev.yan.comment.controller;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.category.model.Category;
|
||||||
|
import com.kalyshev.yan.comment.model.Comment;
|
||||||
|
import com.kalyshev.yan.comment.service.CommentService;
|
||||||
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CommentDto {
|
||||||
|
private Long id;
|
||||||
|
private String comment;
|
||||||
|
private Long videoId;
|
||||||
|
private Long userId;
|
||||||
|
public CommentDto() {}
|
||||||
|
public CommentDto(Comment comment) {
|
||||||
|
this.id = comment.getId();
|
||||||
|
this.comment = comment.getComment();
|
||||||
|
this.videoId = comment.getVideo().getId();
|
||||||
|
this.userId = comment.getUser().getId();
|
||||||
|
}
|
||||||
|
public Long getId() { return this.id; }
|
||||||
|
public void setId(Long id) { this.id = id; }
|
||||||
|
public String getComment() { return this.comment; }
|
||||||
|
public void setComment(String comment) { this.comment = comment; }
|
||||||
|
public Long getVideoId() { return this.videoId; }
|
||||||
|
public void setVideoId(Long videoId) { this.videoId = videoId; }
|
||||||
|
public Long getUserId() { return this.userId; }
|
||||||
|
public void setUserId(Long userId) { this.userId = userId; }
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.kalyshev.yan.comment.controller;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.category.controller.CategoryDto;
|
||||||
|
import com.kalyshev.yan.category.service.CategoryService;
|
||||||
|
import com.kalyshev.yan.comment.service.CommentService;
|
||||||
|
import com.kalyshev.yan.user.model.User;
|
||||||
|
import com.kalyshev.yan.user.service.UserService;
|
||||||
|
import com.kalyshev.yan.video.controller.VideoDto;
|
||||||
|
import com.kalyshev.yan.video.service.VideoService;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/comments")
|
||||||
|
public class CommentMvcService {
|
||||||
|
private final CommentService commentService;
|
||||||
|
private final UserService userService;
|
||||||
|
private final VideoService videoService;
|
||||||
|
public CommentMvcService(CommentService commentService,
|
||||||
|
VideoService videoService,
|
||||||
|
UserService userService) {
|
||||||
|
this.commentService = commentService;
|
||||||
|
this.userService = userService;
|
||||||
|
this.videoService = videoService;
|
||||||
|
}
|
||||||
|
@GetMapping(value = {"", "/"})
|
||||||
|
public String getComments(Model model) {
|
||||||
|
model.addAttribute("comments",
|
||||||
|
commentService.findAllComments().stream()
|
||||||
|
.map(CommentDto::new)
|
||||||
|
.toList());
|
||||||
|
return "comments";
|
||||||
|
}
|
||||||
|
@GetMapping(value = {"/edit/", "/edit/{id}"})
|
||||||
|
public String editComment(@PathVariable(required = false) Long id,
|
||||||
|
Model model) {
|
||||||
|
if (id == null || id <= 0) {
|
||||||
|
model.addAttribute("commentDto", new CommentDto());
|
||||||
|
} else {
|
||||||
|
model.addAttribute("commentId", id);
|
||||||
|
model.addAttribute("commentDto", new CommentDto(commentService.findComment(id)));
|
||||||
|
}
|
||||||
|
return "comment-edit";
|
||||||
|
}
|
||||||
|
@PostMapping(value = {"", "/", "/{id}"})
|
||||||
|
public String saveComment(@PathVariable(required = false) Long id,
|
||||||
|
@ModelAttribute @Valid CommentDto commentDto,
|
||||||
|
BindingResult bindingResult,
|
||||||
|
Model model) {
|
||||||
|
if (bindingResult.hasErrors()) {
|
||||||
|
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||||
|
return "comment-edit";
|
||||||
|
}
|
||||||
|
User user = userService.findByLogin(SecurityContextHolder.getContext().getAuthentication().getName());
|
||||||
|
if (id == null || id <= 0) {
|
||||||
|
commentService.addComment(commentDto.getComment(), user.getId(), commentDto.getVideoId());
|
||||||
|
} else {
|
||||||
|
commentService.updateComment(id, commentDto.getComment());
|
||||||
|
}
|
||||||
|
return "redirect:/comments";
|
||||||
|
}
|
||||||
|
@PostMapping("/delete/{id}")
|
||||||
|
public String deleteComment(@PathVariable Long id) {
|
||||||
|
commentService.deleteComment(id);
|
||||||
|
return "redirect:/comments";
|
||||||
|
}
|
||||||
|
}
|
75
src/main/java/com/kalyshev/yan/comment/model/Comment.java
Normal file
75
src/main/java/com/kalyshev/yan/comment/model/Comment.java
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
package com.kalyshev.yan.comment.model;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.user.model.User;
|
||||||
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "comment")
|
||||||
|
public class Comment {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
@NotNull
|
||||||
|
private String comment;
|
||||||
|
@NotNull
|
||||||
|
@ManyToOne(cascade = {CascadeType.MERGE})
|
||||||
|
private User user;
|
||||||
|
@NotNull
|
||||||
|
@ManyToOne(cascade = {CascadeType.REMOVE})
|
||||||
|
private Video video;
|
||||||
|
public Comment() {
|
||||||
|
}
|
||||||
|
public Comment(String comment, User user, Video video) {
|
||||||
|
this.comment = comment;
|
||||||
|
this.user = user;
|
||||||
|
this.video = video;
|
||||||
|
}
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public String getComment() {
|
||||||
|
return comment;
|
||||||
|
}
|
||||||
|
public void setComment(String comment) {
|
||||||
|
this.comment = comment;
|
||||||
|
}
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
public Video getVideo() {
|
||||||
|
return video;
|
||||||
|
}
|
||||||
|
public void setVideo(Video video) {
|
||||||
|
this.video = video;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (!(o instanceof Comment comment))
|
||||||
|
return false;
|
||||||
|
return Objects.equals(id, comment.id);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Comment{" +
|
||||||
|
"id=" + id +
|
||||||
|
", comment='" + comment + '\'' +
|
||||||
|
", user='" + user + '\'' +
|
||||||
|
", video='" + video + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.kalyshev.yan.comment.repository;
|
||||||
|
|
||||||
|
public class CommentNotFoundException extends RuntimeException {
|
||||||
|
public CommentNotFoundException(Long id) {
|
||||||
|
super(String.format("Comment with id [%s] is not found", id));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.kalyshev.yan.comment.repository;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.comment.model.Comment;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface CommentRepository extends JpaRepository<Comment, Long> {
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
package com.kalyshev.yan.comment.service;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.playlist.model.Playlist;
|
||||||
|
import com.kalyshev.yan.user.model.User;
|
||||||
|
import com.kalyshev.yan.user.service.UserService;
|
||||||
|
import com.kalyshev.yan.util.validation.ValidatorUtil;
|
||||||
|
import com.kalyshev.yan.comment.model.Comment;
|
||||||
|
import com.kalyshev.yan.comment.repository.CommentNotFoundException;
|
||||||
|
import com.kalyshev.yan.comment.repository.CommentRepository;
|
||||||
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
import com.kalyshev.yan.video.service.VideoService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class CommentService {
|
||||||
|
private final CommentRepository commentRepository;
|
||||||
|
private final UserService userService;
|
||||||
|
private final VideoService videoService;
|
||||||
|
private final ValidatorUtil validatorUtil;
|
||||||
|
public CommentService(CommentRepository commentRepository,
|
||||||
|
VideoService videoService,
|
||||||
|
UserService userService,
|
||||||
|
ValidatorUtil validatorUtil) {
|
||||||
|
this.commentRepository = commentRepository;
|
||||||
|
this.userService = userService;
|
||||||
|
this.videoService = videoService;
|
||||||
|
this.validatorUtil = validatorUtil;
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Comment addComment(String comment, Long userId, Long videoId) {
|
||||||
|
if (!StringUtils.hasText(comment)) {
|
||||||
|
throw new IllegalArgumentException("Comment comment is null or empty");
|
||||||
|
}
|
||||||
|
if (userId == null) {
|
||||||
|
throw new IllegalArgumentException("Comment userId is null or empty");
|
||||||
|
}
|
||||||
|
if (videoId == null) {
|
||||||
|
throw new IllegalArgumentException("Comment videoId is null or empty");
|
||||||
|
}
|
||||||
|
User user = userService.findUser(userId);
|
||||||
|
Video video = videoService.findVideo(videoId);
|
||||||
|
final Comment curcomment = new Comment(comment, user, video);
|
||||||
|
validatorUtil.validate(curcomment);
|
||||||
|
return commentRepository.save(curcomment);
|
||||||
|
}
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public Comment findComment(Long id) {
|
||||||
|
final Optional<Comment> comment = commentRepository.findById(id);
|
||||||
|
return comment.orElseThrow(() -> new CommentNotFoundException(id));
|
||||||
|
}
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public List<Comment> findAllComments() {
|
||||||
|
return commentRepository.findAll();
|
||||||
|
}
|
||||||
|
// @Transactional(readOnly = true)
|
||||||
|
// public List<Comment> findFilteredComments(Long id, String modelName, String serialNum, Long monitorId, Long cabinetId) {
|
||||||
|
// return commentRepository.findFilteredComments(id, modelName, serialNum, monitorId, cabinetId);
|
||||||
|
// }
|
||||||
|
@Transactional
|
||||||
|
public Comment updateComment(Long id, String comment) {
|
||||||
|
if (!StringUtils.hasText(comment)) {
|
||||||
|
throw new IllegalArgumentException("Comment value is null or empty");
|
||||||
|
}
|
||||||
|
final Comment currentComment = findComment(id);
|
||||||
|
currentComment.setComment(comment);
|
||||||
|
validatorUtil.validate(currentComment);
|
||||||
|
return commentRepository.save(currentComment);
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Comment deleteComment(Long id) {
|
||||||
|
final Comment currentComment = findComment(id);
|
||||||
|
commentRepository.delete(currentComment);
|
||||||
|
return currentComment;
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public void deleteAllComments() {
|
||||||
|
commentRepository.deleteAll();
|
||||||
|
}
|
||||||
|
}
|
@ -1,56 +0,0 @@
|
|||||||
package com.kalyshev.yan.computer.controller;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.WebConfiguration;
|
|
||||||
import com.kalyshev.yan.computer.service.ComputerService;
|
|
||||||
import com.kalyshev.yan.monitor.controller.MonitorDto;
|
|
||||||
import jakarta.validation.Valid;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping(WebConfiguration.REST_API + "/computer")
|
|
||||||
public class ComputerController {
|
|
||||||
private final ComputerService computerService;
|
|
||||||
public ComputerController(ComputerService computerService) {
|
|
||||||
this.computerService = computerService;
|
|
||||||
}
|
|
||||||
@GetMapping("/{id}")
|
|
||||||
public ComputerDto getStudent(@PathVariable Long id) {
|
|
||||||
return new ComputerDto(computerService.findComputer(id));
|
|
||||||
}
|
|
||||||
@GetMapping("/")
|
|
||||||
public List<ComputerDto> getComputers() {
|
|
||||||
return computerService.findAllComputers().stream()
|
|
||||||
.map(ComputerDto::new)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
@GetMapping("/filter")
|
|
||||||
public List<ComputerDto> getFilteredComputers(@RequestParam(value = "id", required = false) Long id,
|
|
||||||
@RequestParam(value = "modelName", required = false) String modelName,
|
|
||||||
@RequestParam(value = "serialNum", required = false) String serialNum,
|
|
||||||
@RequestParam(value = "monitorId", required = false) Long monitorId,
|
|
||||||
@RequestParam(value = "cabinetId", required = false) Long cabinetId) {
|
|
||||||
return computerService.findFilteredComputers(id, modelName, serialNum, monitorId, cabinetId).stream()
|
|
||||||
.map(ComputerDto::new)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
@PostMapping("/")
|
|
||||||
public ComputerDto createComputer(@RequestBody @Valid ComputerDto computerDto) {
|
|
||||||
return new ComputerDto(computerService.addComputer(computerDto.getModelName(), computerDto.getSerialNum(), computerDto.getMonitorId()));
|
|
||||||
}
|
|
||||||
@PostMapping("/{id}/monitor")
|
|
||||||
public MonitorDto setMonitorComputer(@PathVariable Long id,
|
|
||||||
@RequestParam("monitorId") Long monitorId) {
|
|
||||||
return new MonitorDto(computerService.setMonitor(monitorId, id));
|
|
||||||
}
|
|
||||||
@PutMapping("/{id}")
|
|
||||||
public ComputerDto updateComputer(@PathVariable Long id,
|
|
||||||
@RequestBody @Valid ComputerDto computerDto) {
|
|
||||||
return new ComputerDto(computerService.updateComputer(id, computerDto.getModelName(), computerDto.getSerialNum(), computerDto.getMonitorId(), computerDto.getCabinetId()));
|
|
||||||
}
|
|
||||||
@DeleteMapping("/{id}")
|
|
||||||
public ComputerDto deleteComputer(@PathVariable Long id) {
|
|
||||||
return new ComputerDto(computerService.deleteComputer(id));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
package com.kalyshev.yan.computer.controller;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.computer.model.Computer;
|
|
||||||
|
|
||||||
public class ComputerDto {
|
|
||||||
private Long id;
|
|
||||||
private String modelName;
|
|
||||||
private String serialNum;
|
|
||||||
private Long monitorId;
|
|
||||||
private String monitorModelName;
|
|
||||||
private Long cabinetId;
|
|
||||||
private String cabinetNumber;
|
|
||||||
public ComputerDto() {}
|
|
||||||
public ComputerDto(Computer computer) {
|
|
||||||
this.id = computer.getId();
|
|
||||||
this.modelName = computer.getModelName();
|
|
||||||
this.serialNum = computer.getSerialNum();
|
|
||||||
if (computer.getMonitor() == null) {
|
|
||||||
this.monitorId = null;
|
|
||||||
this.monitorModelName = "";
|
|
||||||
} else {
|
|
||||||
this.monitorId = computer.getMonitor().getId();
|
|
||||||
this.monitorModelName = computer.getMonitor().getModelName();
|
|
||||||
}
|
|
||||||
if (computer.getCabinet() == null) {
|
|
||||||
this.cabinetId = null;
|
|
||||||
this.cabinetNumber = "";
|
|
||||||
} else {
|
|
||||||
this.cabinetId = computer.getCabinet().getId();
|
|
||||||
this.cabinetNumber = computer.getCabinet().getNumber();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public Long getId() { return this.id; }
|
|
||||||
public String getModelName() { return this.modelName; }
|
|
||||||
public void setModelName(String modelName) { this.modelName = modelName; }
|
|
||||||
public String getSerialNum() { return this.serialNum; }
|
|
||||||
public void setSerialNum(String serialNum) { this.serialNum = serialNum; }
|
|
||||||
public Long getMonitorId() { return this.monitorId; }
|
|
||||||
public void setMonitorId(Long monitorId) { this.monitorId = monitorId; }
|
|
||||||
public Long getCabinetId() { return this.cabinetId; }
|
|
||||||
public void setCabinetId(Long cabinetId) { this.cabinetId = cabinetId; }
|
|
||||||
public String getMonitorModelName() { return this.monitorModelName; }
|
|
||||||
public String getCabinetNumber() { return this.cabinetNumber; }
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
package com.kalyshev.yan.computer.controller;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.cabinet.controller.CabinetDto;
|
|
||||||
import com.kalyshev.yan.cabinet.service.CabinetService;
|
|
||||||
import com.kalyshev.yan.computer.service.ComputerService;
|
|
||||||
import com.kalyshev.yan.monitor.service.MonitorService;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.validation.BindingResult;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/computers")
|
|
||||||
public class ComputerMvcController {
|
|
||||||
private final ComputerService computerService;
|
|
||||||
private final MonitorService monitorService;
|
|
||||||
public ComputerMvcController(ComputerService computerService,
|
|
||||||
MonitorService monitorService) {
|
|
||||||
this.computerService = computerService;
|
|
||||||
this.monitorService = monitorService;
|
|
||||||
}
|
|
||||||
@GetMapping
|
|
||||||
public String getComputers(Model model) {
|
|
||||||
model.addAttribute("computers",
|
|
||||||
computerService.findAllComputers().stream()
|
|
||||||
.map(ComputerDto::new)
|
|
||||||
.toList());
|
|
||||||
return "computers";
|
|
||||||
}
|
|
||||||
@GetMapping(value = {"/edit", "/edit/{id}"})
|
|
||||||
public String editComputer(@PathVariable(required = false) Long id,
|
|
||||||
Model model) {
|
|
||||||
if (id == null || id <= 0) {
|
|
||||||
model.addAttribute("computerDto", new ComputerDto());
|
|
||||||
} else {
|
|
||||||
model.addAttribute("computerId", id);
|
|
||||||
model.addAttribute("computerDto", new ComputerDto(computerService.findComputer(id)));
|
|
||||||
}
|
|
||||||
model.addAttribute("monitors",
|
|
||||||
monitorService.findAllMonitors());
|
|
||||||
return "computer-edit";
|
|
||||||
}
|
|
||||||
@PostMapping(value = {"", "/{id}"})
|
|
||||||
public String saveComputer(@PathVariable(required = false) Long id,
|
|
||||||
@ModelAttribute @Valid ComputerDto computerDto,
|
|
||||||
BindingResult bindingResult,
|
|
||||||
Model model) {
|
|
||||||
if (bindingResult.hasErrors()) {
|
|
||||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
|
||||||
return "computer-edit";
|
|
||||||
}
|
|
||||||
if (id == null || id <= 0) {
|
|
||||||
computerService.addComputer(computerDto.getModelName(), computerDto.getSerialNum(), computerDto.getMonitorId());
|
|
||||||
} else {
|
|
||||||
computerService.updateComputer(id, computerDto.getModelName(), computerDto.getSerialNum(), computerDto.getMonitorId(), computerDto.getCabinetId());
|
|
||||||
}
|
|
||||||
return "redirect:/computers";
|
|
||||||
}
|
|
||||||
@PostMapping("/delete/{id}")
|
|
||||||
public String deleteComputer(@PathVariable Long id) {
|
|
||||||
computerService.deleteComputer(id);
|
|
||||||
return "redirect:/computers";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
package com.kalyshev.yan.computer.model;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.cabinet.model.Cabinet;
|
|
||||||
import com.kalyshev.yan.monitor.model.Monitor;
|
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name = "computer")
|
|
||||||
public class Computer {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue
|
|
||||||
private Long id;
|
|
||||||
private String modelName;
|
|
||||||
private String serialNum;
|
|
||||||
@ManyToOne( cascade = {CascadeType.MERGE}, fetch = FetchType.EAGER)
|
|
||||||
@JoinColumn(name = "cabinet", nullable = true)
|
|
||||||
private Cabinet cabinet;
|
|
||||||
@OneToOne(cascade = {CascadeType.MERGE})
|
|
||||||
@JoinColumn(name = "monitor_id")
|
|
||||||
private Monitor monitor;
|
|
||||||
|
|
||||||
public Computer() {
|
|
||||||
}
|
|
||||||
public Computer(String modelName, String serialNum) {
|
|
||||||
this.modelName = modelName;
|
|
||||||
this.serialNum = serialNum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public String getModelName() {
|
|
||||||
return modelName;
|
|
||||||
}
|
|
||||||
public void setModelName(String modelName) {
|
|
||||||
this.modelName = modelName;
|
|
||||||
}
|
|
||||||
public String getSerialNum() {
|
|
||||||
return serialNum;
|
|
||||||
}
|
|
||||||
public void setSerialNum(String serialNum) { this.serialNum = serialNum; }
|
|
||||||
public Cabinet getCabinet() {
|
|
||||||
return cabinet;
|
|
||||||
}
|
|
||||||
public void setCabinet(Cabinet cabinet) { this.cabinet = cabinet; }
|
|
||||||
|
|
||||||
public Monitor getMonitor() {
|
|
||||||
return monitor;
|
|
||||||
}
|
|
||||||
public void setMonitor(Monitor monitor) {
|
|
||||||
this.monitor = monitor;
|
|
||||||
}
|
|
||||||
public Monitor removeMonitor() {
|
|
||||||
Monitor temp = this.monitor;
|
|
||||||
this.monitor = null;
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o)
|
|
||||||
return true;
|
|
||||||
if (!(o instanceof Computer computer))
|
|
||||||
return false;
|
|
||||||
return Objects.equals(id, computer.id);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(id);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Computer{" +
|
|
||||||
"id=" + id +
|
|
||||||
", modelName='" + modelName + '\'' +
|
|
||||||
", serialNum='" + serialNum + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package com.kalyshev.yan.computer.repository;
|
|
||||||
|
|
||||||
public class ComputerNotFoundException extends RuntimeException {
|
|
||||||
public ComputerNotFoundException(Long id) {
|
|
||||||
super(String.format("Computer with id [%s] is not found", id));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package com.kalyshev.yan.computer.repository;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.computer.model.Computer;
|
|
||||||
import com.kalyshev.yan.monitor.model.Monitor;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
|
||||||
import org.springframework.data.repository.query.Param;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface ComputerRepository extends JpaRepository<Computer, Long> {
|
|
||||||
@Query(value = "select * from Computer where (\"ID\" = :id or :id is Null) and " +
|
|
||||||
"(\"MODEL_NAME\" = :modelName or :modelName is Null) and " +
|
|
||||||
"(\"SERIAL_NUM\" = :serialNum or :serialNum is Null) and " +
|
|
||||||
"(\"MONITOR_ID\" = :monitorId or :monitorId is Null) and " +
|
|
||||||
"(\"CABINET\" = :cabinetId or :cabinetId is Null)", nativeQuery = true)
|
|
||||||
public List<Computer> findFilteredComputers(@Param("id") Long id,
|
|
||||||
@Param("modelName") String modelName,
|
|
||||||
@Param("serialNum") String serialNum,
|
|
||||||
@Param("monitorId") Long monitorId,
|
|
||||||
@Param("cabinetId") Long cabinetId);
|
|
||||||
|
|
||||||
@Query(value = "select * from Computer where \"MONITOR_ID\" = :monitorId", nativeQuery = true)
|
|
||||||
public Computer findComputerByMonitor(@Param("monitorId") Long monitorId);
|
|
||||||
|
|
||||||
@Modifying
|
|
||||||
@Query(value = "update Computer set \"MONITOR_ID\" = null", nativeQuery = true)
|
|
||||||
public void removeAllComputerMonitorRelations();
|
|
||||||
|
|
||||||
// @Query(value = "update Computer where id in :computerIds set cabinet_id = null")
|
|
||||||
// public void deleteRelationsWithCabinets(@Param("computerIds") Collection<Long> computerIds);
|
|
||||||
}
|
|
@ -1,135 +0,0 @@
|
|||||||
package com.kalyshev.yan.computer.service;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.cabinet.model.Cabinet;
|
|
||||||
import com.kalyshev.yan.computer.model.Computer;
|
|
||||||
import com.kalyshev.yan.computer.repository.ComputerNotFoundException;
|
|
||||||
import com.kalyshev.yan.computer.repository.ComputerRepository;
|
|
||||||
import com.kalyshev.yan.monitor.model.Monitor;
|
|
||||||
import com.kalyshev.yan.monitor.service.MonitorService;
|
|
||||||
import com.kalyshev.yan.util.validation.ValidatorUtil;
|
|
||||||
import jakarta.validation.constraints.Null;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class ComputerService {
|
|
||||||
private final ComputerRepository computerRepository;
|
|
||||||
private final MonitorService monitorService;
|
|
||||||
private final ValidatorUtil validatorUtil;
|
|
||||||
public ComputerService(ComputerRepository computerRepository,
|
|
||||||
MonitorService monitorService,
|
|
||||||
ValidatorUtil validatorUtil) {
|
|
||||||
this.computerRepository = computerRepository;
|
|
||||||
this.monitorService = monitorService;
|
|
||||||
this.validatorUtil = validatorUtil;
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public Computer addComputer(String modelName, String serialNum, @Null Long monitorId) {
|
|
||||||
if (!StringUtils.hasText(modelName)) {
|
|
||||||
throw new IllegalArgumentException("Computer model name is null or empty");
|
|
||||||
}
|
|
||||||
if (!StringUtils.hasText(serialNum)) {
|
|
||||||
throw new IllegalArgumentException("Computer serial number is null or empty");
|
|
||||||
}
|
|
||||||
final Computer computer = new Computer(modelName, serialNum);
|
|
||||||
if (monitorId != null) {
|
|
||||||
final Monitor monitor = monitorService.findMonitor(monitorId);
|
|
||||||
computer.setMonitor(monitor);
|
|
||||||
}
|
|
||||||
validatorUtil.validate(computer);
|
|
||||||
return computerRepository.save(computer);
|
|
||||||
}
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
public Computer findComputer(Long id) {
|
|
||||||
final Optional<Computer> computer = computerRepository.findById(id);
|
|
||||||
return computer.orElseThrow(() -> new ComputerNotFoundException(id));
|
|
||||||
}
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
public List<Computer> findAllComputers() {
|
|
||||||
return computerRepository.findAll();
|
|
||||||
}
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
public List<Computer> findFilteredComputers(Long id, String modelName, String serialNum, Long monitorId, Long cabinetId) {
|
|
||||||
return computerRepository.findFilteredComputers(id, modelName, serialNum, monitorId, cabinetId);
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public Computer updateComputer(Long id, String modelName, String serialNum, Long monitorId, Long cabinetId) {
|
|
||||||
if (!(StringUtils.hasText(modelName) || StringUtils.hasText(serialNum))) {
|
|
||||||
throw new IllegalArgumentException("Need at least one argument");
|
|
||||||
}
|
|
||||||
final Computer currentComputer = findComputer(id);
|
|
||||||
if (modelName != null) {
|
|
||||||
currentComputer.setModelName(modelName);
|
|
||||||
}
|
|
||||||
if (serialNum != null) {
|
|
||||||
currentComputer.setSerialNum(serialNum);
|
|
||||||
}
|
|
||||||
if (monitorId != null) {
|
|
||||||
final Monitor monitor = monitorService.findMonitor(monitorId);
|
|
||||||
currentComputer.setMonitor(monitor);
|
|
||||||
}
|
|
||||||
validatorUtil.validate(currentComputer);
|
|
||||||
return computerRepository.save(currentComputer);
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public Computer deleteComputer(Long id) {
|
|
||||||
final Computer currentComputer = findComputer(id);
|
|
||||||
Cabinet currentComputerCabinet = currentComputer.getCabinet();
|
|
||||||
if (currentComputerCabinet != null) {
|
|
||||||
currentComputerCabinet.removeComputer(currentComputer);
|
|
||||||
}
|
|
||||||
computerRepository.delete(currentComputer);
|
|
||||||
return currentComputer;
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public void deleteAllComputers() {
|
|
||||||
List<Computer> computers = findAllComputers();
|
|
||||||
for (Computer computer : computers) {
|
|
||||||
deleteComputer(computer.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public Monitor setMonitor(Long monitorId, Long computerId) {
|
|
||||||
if ((Object)computerId == null) {
|
|
||||||
throw new IllegalArgumentException("Computer id is null or empty");
|
|
||||||
}
|
|
||||||
if ((Object)monitorId == null) {
|
|
||||||
throw new IllegalArgumentException("Monitor id is null or empty");
|
|
||||||
}
|
|
||||||
final Computer computer = findComputer(computerId);
|
|
||||||
final Monitor monitor = monitorService.findMonitor(monitorId);
|
|
||||||
computer.setMonitor(monitor);
|
|
||||||
return monitor;
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public void deleteRelationsWithCabinets(List<Computer> computers) {
|
|
||||||
for (Computer computer: computers) {
|
|
||||||
computer.setCabinet(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public Computer findComputerByMonitor(Monitor monitor) {
|
|
||||||
if (monitor.getId() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return computerRepository.findComputerByMonitor(monitor.getId());
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public Monitor deleteMonitorWithRelation(Long id) {
|
|
||||||
final Monitor currentMonitor = monitorService.findMonitor(id);
|
|
||||||
Computer computer = findComputerByMonitor(currentMonitor);
|
|
||||||
if (computer != null) {
|
|
||||||
computer.removeMonitor();
|
|
||||||
}
|
|
||||||
monitorService.deleteMonitor(currentMonitor);
|
|
||||||
return currentMonitor;
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public void deleteAllMonitorsWithRelations() {
|
|
||||||
computerRepository.removeAllComputerMonitorRelations();
|
|
||||||
monitorService.deleteAllMonitors();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
package com.kalyshev.yan.monitor.controller;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.WebConfiguration;
|
|
||||||
import com.kalyshev.yan.computer.service.ComputerService;
|
|
||||||
import com.kalyshev.yan.monitor.service.MonitorService;
|
|
||||||
import jakarta.validation.Valid;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping(WebConfiguration.REST_API + "/monitor")
|
|
||||||
public class MonitorController {
|
|
||||||
private final MonitorService monitorService;
|
|
||||||
private final ComputerService computerService;
|
|
||||||
public MonitorController(MonitorService monitorService,
|
|
||||||
ComputerService computerService) {
|
|
||||||
this.monitorService = monitorService;
|
|
||||||
this.computerService = computerService;
|
|
||||||
}
|
|
||||||
@GetMapping("/{id}")
|
|
||||||
public MonitorDto getMonitor(@PathVariable Long id) {
|
|
||||||
return new MonitorDto(monitorService.findMonitor(id));
|
|
||||||
}
|
|
||||||
@GetMapping("/")
|
|
||||||
public List<MonitorDto> getMonitors() {
|
|
||||||
return monitorService.findAllMonitors().stream()
|
|
||||||
.map(MonitorDto::new)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
@GetMapping("/filter")
|
|
||||||
public List<MonitorDto> getFilteredmonitors(@RequestParam(value = "id", required = false) Long id,
|
|
||||||
@RequestParam(value = "modelName", required = false) String modelName) {
|
|
||||||
return monitorService.findFilteredMonitors(id, modelName).stream()
|
|
||||||
.map(MonitorDto::new)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
@PostMapping("/")
|
|
||||||
public MonitorDto createMonitor(@RequestBody @Valid MonitorDto monitorDto) {
|
|
||||||
return new MonitorDto(monitorService.addMonitor(monitorDto.getModelName()));
|
|
||||||
}
|
|
||||||
@PutMapping("/{id}")
|
|
||||||
public MonitorDto updateMonitor(@PathVariable Long id,
|
|
||||||
@RequestBody @Valid MonitorDto monitorDto) {
|
|
||||||
return new MonitorDto(monitorService.updateMonitor(id, monitorDto.getModelName()));
|
|
||||||
}
|
|
||||||
@DeleteMapping("/{id}")
|
|
||||||
public MonitorDto deleteMonitor(@PathVariable Long id) {
|
|
||||||
return new MonitorDto(computerService.deleteMonitorWithRelation(id));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
package com.kalyshev.yan.monitor.controller;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.monitor.model.Monitor;
|
|
||||||
|
|
||||||
public class MonitorDto {
|
|
||||||
private Long id;
|
|
||||||
private String modelName;
|
|
||||||
public MonitorDto() {
|
|
||||||
}
|
|
||||||
public MonitorDto(Monitor monitor) {
|
|
||||||
this.id = monitor.getId();
|
|
||||||
this.modelName = monitor.getModelName();
|
|
||||||
}
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public String getModelName() {
|
|
||||||
return modelName;
|
|
||||||
}
|
|
||||||
public void setModelName(String modelName) {
|
|
||||||
this.modelName = modelName;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
package com.kalyshev.yan.monitor.controller;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.cabinet.controller.CabinetDto;
|
|
||||||
import com.kalyshev.yan.cabinet.service.CabinetService;
|
|
||||||
import com.kalyshev.yan.computer.service.ComputerService;
|
|
||||||
import com.kalyshev.yan.monitor.model.Monitor;
|
|
||||||
import com.kalyshev.yan.monitor.service.MonitorService;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.validation.BindingResult;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/monitors")
|
|
||||||
public class MonitorMvcController {
|
|
||||||
private final MonitorService monitorService;
|
|
||||||
public MonitorMvcController(MonitorService monitorService) {
|
|
||||||
this.monitorService = monitorService;
|
|
||||||
}
|
|
||||||
@GetMapping
|
|
||||||
public String getMonitors(Model model) {
|
|
||||||
model.addAttribute("monitors",
|
|
||||||
monitorService.findAllMonitors().stream()
|
|
||||||
.map(MonitorDto::new)
|
|
||||||
.toList());
|
|
||||||
return "monitors";
|
|
||||||
}
|
|
||||||
@GetMapping(value = {"/edit", "/edit/{id}"})
|
|
||||||
public String editMonitor(@PathVariable(required = false) Long id,
|
|
||||||
Model model) {
|
|
||||||
if (id == null || id <= 0) {
|
|
||||||
model.addAttribute("monitorDto", new MonitorDto());
|
|
||||||
} else {
|
|
||||||
model.addAttribute("monitorId", id);
|
|
||||||
model.addAttribute("monitorDto", new MonitorDto(monitorService.findMonitor(id)));
|
|
||||||
}
|
|
||||||
return "monitor-edit";
|
|
||||||
}
|
|
||||||
@PostMapping(value = {"", "/{id}"})
|
|
||||||
public String saveComputer(@PathVariable(required = false) Long id,
|
|
||||||
@ModelAttribute @Valid MonitorDto monitorDto,
|
|
||||||
BindingResult bindingResult,
|
|
||||||
Model model) {
|
|
||||||
if (bindingResult.hasErrors()) {
|
|
||||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
|
||||||
return "monitor-edit";
|
|
||||||
}
|
|
||||||
if (id == null || id <= 0) {
|
|
||||||
monitorService.addMonitor(monitorDto.getModelName());
|
|
||||||
} else {
|
|
||||||
monitorService.updateMonitor(id, monitorDto.getModelName());
|
|
||||||
}
|
|
||||||
return "redirect:/monitors";
|
|
||||||
}
|
|
||||||
@PostMapping("/delete/{id}")
|
|
||||||
public String deleteComputer(@PathVariable Long id) {
|
|
||||||
monitorService.deleteMonitor(monitorService.findMonitor(id));
|
|
||||||
return "redirect:/monitors";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
package com.kalyshev.yan.monitor.model;
|
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name = "monitor")
|
|
||||||
public class Monitor {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue
|
|
||||||
private Long id;
|
|
||||||
private String modelName;
|
|
||||||
public Monitor() {
|
|
||||||
}
|
|
||||||
public Monitor(String modelName) {
|
|
||||||
this.modelName = modelName;
|
|
||||||
}
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public String getModelName() {
|
|
||||||
return modelName;
|
|
||||||
}
|
|
||||||
public void setModelName(String modelName) {
|
|
||||||
this.modelName = modelName;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o)
|
|
||||||
return true;
|
|
||||||
if (!(o instanceof Monitor monitor))
|
|
||||||
return false;
|
|
||||||
return Objects.equals(id, monitor.id);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(id);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Monitor{" +
|
|
||||||
"id=" + id +
|
|
||||||
", modelName='" + modelName + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package com.kalyshev.yan.monitor.repository;
|
|
||||||
|
|
||||||
public class MonitorNotFoundException extends RuntimeException {
|
|
||||||
public MonitorNotFoundException(Long id) {
|
|
||||||
super(String.format("Monitor with id [%s] is not found", id));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package com.kalyshev.yan.monitor.repository;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.monitor.model.Monitor;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.jpa.repository.Query;
|
|
||||||
import org.springframework.data.repository.query.Param;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface MonitorRepository extends JpaRepository<Monitor, Long> {
|
|
||||||
@Query(value = "select * from Monitor where (\"ID\" = :id or :id is Null) and " +
|
|
||||||
"(\"MODEL_NAME\" = :modelName or :modelName is Null)", nativeQuery = true)
|
|
||||||
public List<Monitor> findFilteredMonitors(@Param("id") Long id,
|
|
||||||
@Param("modelName") String modelName);
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
package com.kalyshev.yan.monitor.service;
|
|
||||||
|
|
||||||
import com.kalyshev.yan.monitor.model.Monitor;
|
|
||||||
import com.kalyshev.yan.monitor.repository.MonitorNotFoundException;
|
|
||||||
import com.kalyshev.yan.monitor.repository.MonitorRepository;
|
|
||||||
import com.kalyshev.yan.util.validation.ValidatorUtil;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class MonitorService {
|
|
||||||
private final MonitorRepository monitorRepository;
|
|
||||||
private final ValidatorUtil validatorUtil;
|
|
||||||
public MonitorService(MonitorRepository monitorRepository,
|
|
||||||
ValidatorUtil validatorUtil) {
|
|
||||||
this.monitorRepository = monitorRepository;
|
|
||||||
this.validatorUtil = validatorUtil;
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public Monitor addMonitor(String modelName) {
|
|
||||||
if (!StringUtils.hasText(modelName)) {
|
|
||||||
throw new IllegalArgumentException("Monitor model name is null or empty");
|
|
||||||
}
|
|
||||||
final Monitor monitor = new Monitor(modelName);
|
|
||||||
validatorUtil.validate(monitor);
|
|
||||||
return monitorRepository.save(monitor);
|
|
||||||
}
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
public Monitor findMonitor(Long id) {
|
|
||||||
final Optional<Monitor> monitor = monitorRepository.findById(id);
|
|
||||||
return monitor.orElseThrow(() -> new MonitorNotFoundException(id));
|
|
||||||
}
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
public List<Monitor> findAllMonitors() {
|
|
||||||
return monitorRepository.findAll();
|
|
||||||
}
|
|
||||||
@Transactional(readOnly = true)
|
|
||||||
public List<Monitor> findFilteredMonitors(Long id, String modelName) {
|
|
||||||
return monitorRepository.findFilteredMonitors(id, modelName);
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public Monitor updateMonitor(Long id, String modelName) {
|
|
||||||
if (!StringUtils.hasText(modelName)) {
|
|
||||||
throw new IllegalArgumentException("Monitor model name is null or empty");
|
|
||||||
}
|
|
||||||
final Monitor currentMonitor = findMonitor(id);
|
|
||||||
currentMonitor.setModelName(modelName);
|
|
||||||
validatorUtil.validate(currentMonitor);
|
|
||||||
return monitorRepository.save(currentMonitor);
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public void deleteMonitor(Monitor monitor) {
|
|
||||||
monitorRepository.delete(monitor);
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public void deleteAllMonitors() { monitorRepository.deleteAll(); }
|
|
||||||
}
|
|
@ -0,0 +1,80 @@
|
|||||||
|
package com.kalyshev.yan.playlist.controller;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.WebConfiguration;
|
||||||
|
import com.kalyshev.yan.category.controller.CategoryDto;
|
||||||
|
import com.kalyshev.yan.category.model.Category;
|
||||||
|
import com.kalyshev.yan.category.service.CategoryService;
|
||||||
|
import com.kalyshev.yan.playlist.model.Playlist;
|
||||||
|
import com.kalyshev.yan.playlist.service.PlaylistService;
|
||||||
|
import com.kalyshev.yan.user.model.User;
|
||||||
|
import com.kalyshev.yan.user.service.UserService;
|
||||||
|
import com.kalyshev.yan.util.validation.ValidatorUtil;
|
||||||
|
import com.kalyshev.yan.video.controller.VideoDto;
|
||||||
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
import com.kalyshev.yan.video.repository.VideoNotFoundException;
|
||||||
|
import com.kalyshev.yan.video.repository.VideoRepository;
|
||||||
|
import com.kalyshev.yan.video.service.VideoService;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(WebConfiguration.REST_API + "/playlist")
|
||||||
|
public class PlaylistController {
|
||||||
|
private final PlaylistService playlistService;
|
||||||
|
public PlaylistController(PlaylistService playlistService) {
|
||||||
|
this.playlistService = playlistService;
|
||||||
|
}
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public PlaylistDto getPlaylist(@PathVariable Long id) {
|
||||||
|
return new PlaylistDto(playlistService.findPlaylist(id));
|
||||||
|
}
|
||||||
|
@GetMapping("/")
|
||||||
|
public List<PlaylistDto> getVideos() {
|
||||||
|
return playlistService.findAllPlaylists().stream()
|
||||||
|
.map(PlaylistDto::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
// @GetMapping("/filter")
|
||||||
|
// public List<VideoDto> getFilteredVideos(@RequestParam(value = "id", required = false) Long id,
|
||||||
|
// @RequestParam(value = "name", required = false) String name,
|
||||||
|
// @RequestParam(value = "date", required = false) LocalDate date,
|
||||||
|
// @RequestParam(value = "userId", required = false) Long monitorId) {
|
||||||
|
// return videoService.findFilteredVideos(id, name, date, monitorId).stream()
|
||||||
|
// .map(VideoDto::new)
|
||||||
|
// .toList();
|
||||||
|
// }
|
||||||
|
@PostMapping("/")
|
||||||
|
public PlaylistDto createPlaylist(@RequestBody @Valid PlaylistDto playlistDto) {
|
||||||
|
return new PlaylistDto(playlistService.addPlaylist(playlistDto.getName(), playlistDto.getUserId()));
|
||||||
|
}
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public PlaylistDto updatePlaylist(@PathVariable Long id,
|
||||||
|
@RequestBody @Valid PlaylistDto playlistDto) {
|
||||||
|
return new PlaylistDto(playlistService.updatePlaylist(id, playlistDto.getName()));
|
||||||
|
}
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public PlaylistDto deletePlaylist(@PathVariable Long id) {
|
||||||
|
return new PlaylistDto(playlistService.deletePlaylist(id));
|
||||||
|
}
|
||||||
|
@GetMapping("/{id}/videos")
|
||||||
|
public List<VideoDto> getPlaylistVideos(@PathVariable Long id) {
|
||||||
|
return playlistService.listVideosFromPlaylist(id).stream()
|
||||||
|
.map(VideoDto::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
@PostMapping("/{id}/video")
|
||||||
|
public PlaylistDto addPlaylistVideo(@PathVariable Long id,
|
||||||
|
@RequestParam("videoId") Long videoId) {
|
||||||
|
return new PlaylistDto(playlistService.addVideoToPlaylist(id, videoId));
|
||||||
|
}
|
||||||
|
@DeleteMapping("/{id}/video/{videoId}")
|
||||||
|
public PlaylistDto deletePlaylistVideo(@PathVariable Long id, @PathVariable Long videoId) {
|
||||||
|
return new PlaylistDto(playlistService.deleteVideoFromPlaylist(id, videoId));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.kalyshev.yan.playlist.controller;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.comment.model.Comment;
|
||||||
|
import com.kalyshev.yan.playlist.model.Playlist;
|
||||||
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PlaylistDto {
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private Long userId;
|
||||||
|
private List<Long> videoIds;
|
||||||
|
public PlaylistDto() {}
|
||||||
|
public PlaylistDto(Playlist playlist) {
|
||||||
|
this.id = playlist.getId();
|
||||||
|
this.name = playlist.getName();
|
||||||
|
if (playlist.getVideos() == null) {
|
||||||
|
this.videoIds = new ArrayList<>();
|
||||||
|
} else {
|
||||||
|
this.videoIds = new ArrayList<>();
|
||||||
|
List<Video> videos = playlist.getVideos();
|
||||||
|
for (Video video : videos) {
|
||||||
|
videoIds.add(video.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Long getId() { return this.id; }
|
||||||
|
public void setId(Long id) { this.id = id; }
|
||||||
|
public String getName() { return this.name; }
|
||||||
|
public void setName(String name) { this.name = name; }
|
||||||
|
public List<Long> getVideoIds() { return this.videoIds; }
|
||||||
|
public void setVideoIds(List<Long> videoIds) { this.videoIds = videoIds; }
|
||||||
|
public Long getUserId() { return this.userId; }
|
||||||
|
public void setUserId(Long userId) { this.userId = userId; }
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
package com.kalyshev.yan.playlist.controller;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.category.controller.CategoryDto;
|
||||||
|
import com.kalyshev.yan.category.service.CategoryService;
|
||||||
|
import com.kalyshev.yan.playlist.controller.PlaylistDto;
|
||||||
|
import com.kalyshev.yan.playlist.service.PlaylistService;
|
||||||
|
import com.kalyshev.yan.user.model.User;
|
||||||
|
import com.kalyshev.yan.user.service.UserService;
|
||||||
|
import com.kalyshev.yan.video.controller.VideoDto;
|
||||||
|
import com.kalyshev.yan.video.service.VideoService;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/playlists")
|
||||||
|
public class PlaylistMvcController {
|
||||||
|
private final PlaylistService playlistService;
|
||||||
|
private final UserService userService;
|
||||||
|
private final VideoService videoService;
|
||||||
|
public PlaylistMvcController(VideoService videoService,
|
||||||
|
UserService userService,
|
||||||
|
PlaylistService playlistService) {
|
||||||
|
this.playlistService = playlistService;
|
||||||
|
this.videoService = videoService;
|
||||||
|
this.userService = userService;
|
||||||
|
}
|
||||||
|
@GetMapping(value = {"", "/"})
|
||||||
|
public String getPlaylists(Model model) {
|
||||||
|
model.addAttribute("playlists",
|
||||||
|
playlistService.findAllPlaylists().stream()
|
||||||
|
.map(PlaylistDto::new)
|
||||||
|
.toList());
|
||||||
|
return "playlists";
|
||||||
|
}
|
||||||
|
@GetMapping(value = {"/edit/", "/edit/{id}"})
|
||||||
|
public String editPlaylist(@PathVariable(required = false) Long id,
|
||||||
|
Model model) {
|
||||||
|
if (id == null || id <= 0) {
|
||||||
|
model.addAttribute("playlistDto", new PlaylistDto());
|
||||||
|
} else {
|
||||||
|
model.addAttribute("playlistId", id);
|
||||||
|
model.addAttribute("playlistDto", new PlaylistDto(playlistService.findPlaylist(id)));
|
||||||
|
model.addAttribute("videos",
|
||||||
|
playlistService.listVideosFromPlaylist(id).stream()
|
||||||
|
.map(VideoDto::new)
|
||||||
|
.toList());
|
||||||
|
}
|
||||||
|
model.addAttribute("allVideos",
|
||||||
|
videoService.findAllVideos().stream()
|
||||||
|
.map(VideoDto::new)
|
||||||
|
.toList());
|
||||||
|
return "playlist-edit";
|
||||||
|
}
|
||||||
|
@PostMapping(value = {"", "/", "/{id}"})
|
||||||
|
public String savePlaylist(@PathVariable(required = false) Long id,
|
||||||
|
@ModelAttribute @Valid PlaylistDto playlistDto,
|
||||||
|
BindingResult bindingResult,
|
||||||
|
Model model) {
|
||||||
|
if (bindingResult.hasErrors()) {
|
||||||
|
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||||
|
return "playlist-edit";
|
||||||
|
}
|
||||||
|
User user = userService.findByLogin(SecurityContextHolder.getContext().getAuthentication().getName());
|
||||||
|
if (id == null || id <= 0) {
|
||||||
|
playlistService.addPlaylist(playlistDto.getName(), user.getId());
|
||||||
|
} else {
|
||||||
|
playlistService.updatePlaylist(id, playlistDto.getName());
|
||||||
|
}
|
||||||
|
return "redirect:/playlists";
|
||||||
|
}
|
||||||
|
@PostMapping("/delete/{id}")
|
||||||
|
public String deleteVideo(@PathVariable Long id) {
|
||||||
|
videoService.deleteVideo(id);
|
||||||
|
return "redirect:/videos";
|
||||||
|
}
|
||||||
|
@PostMapping(value = "/{id}/video/{videoId}")
|
||||||
|
public String addPlaylistVideo(@PathVariable(value = "id") Long id,
|
||||||
|
@PathVariable(value = "videoId") Long videoId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
playlistService.addVideoToPlaylist(id, videoId);
|
||||||
|
String referer = request.getHeader("Referer");
|
||||||
|
return "redirect:"+ referer;
|
||||||
|
}
|
||||||
|
@GetMapping(value = "/{id}/videoDelete/{videoId}")
|
||||||
|
public String deletePlaylistVideo(@PathVariable(value = "id") Long id,
|
||||||
|
@PathVariable(value = "videoId") Long videoId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
playlistService.deleteVideoFromPlaylist(id, videoId);
|
||||||
|
String referer = request.getHeader("Referer");
|
||||||
|
return "redirect:"+ referer;
|
||||||
|
}
|
||||||
|
}
|
81
src/main/java/com/kalyshev/yan/playlist/model/Playlist.java
Normal file
81
src/main/java/com/kalyshev/yan/playlist/model/Playlist.java
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package com.kalyshev.yan.playlist.model;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.user.model.User;
|
||||||
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "playlist")
|
||||||
|
public class Playlist {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
@ManyToOne(cascade = {CascadeType.MERGE})
|
||||||
|
private User user;
|
||||||
|
@ManyToMany(cascade = {CascadeType.MERGE})
|
||||||
|
private List<Video> videos;
|
||||||
|
public Playlist() {
|
||||||
|
}
|
||||||
|
public Playlist(String name, User user) {
|
||||||
|
this.name = name;
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
public List<Video> getVideos() {
|
||||||
|
return videos;
|
||||||
|
}
|
||||||
|
public void addVideo(Video video){
|
||||||
|
if (videos == null){
|
||||||
|
this.videos = new ArrayList<>();
|
||||||
|
}
|
||||||
|
if (!videos.contains(video)) {
|
||||||
|
this.videos.add(video);
|
||||||
|
video.addPlaylist(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void removeVideo(Video video){
|
||||||
|
if (videos.contains(video)) {
|
||||||
|
this.videos.remove(video);
|
||||||
|
video.removePlaylist(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (!(o instanceof Playlist playlist))
|
||||||
|
return false;
|
||||||
|
return Objects.equals(id, playlist.id);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Playlist{" +
|
||||||
|
"id=" + id +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.kalyshev.yan.playlist.repository;
|
||||||
|
|
||||||
|
public class PlaylistNotFoundException extends RuntimeException {
|
||||||
|
public PlaylistNotFoundException(Long id) {
|
||||||
|
super(String.format("Playlist with id [%s] is not found", id));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.kalyshev.yan.playlist.repository;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.playlist.model.Playlist;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
|
||||||
|
public interface PlaylistRepository extends JpaRepository<Playlist, Long> {
|
||||||
|
}
|
@ -0,0 +1,158 @@
|
|||||||
|
package com.kalyshev.yan.playlist.service;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.category.model.Category;
|
||||||
|
import com.kalyshev.yan.playlist.model.Playlist;
|
||||||
|
import com.kalyshev.yan.playlist.repository.PlaylistNotFoundException;
|
||||||
|
import com.kalyshev.yan.playlist.repository.PlaylistRepository;
|
||||||
|
import com.kalyshev.yan.user.model.User;
|
||||||
|
import com.kalyshev.yan.user.service.UserService;
|
||||||
|
import com.kalyshev.yan.util.validation.ValidatorUtil;
|
||||||
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
import com.kalyshev.yan.video.repository.VideoNotFoundException;
|
||||||
|
import com.kalyshev.yan.video.repository.VideoRepository;
|
||||||
|
import com.kalyshev.yan.video.service.VideoService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class PlaylistService {
|
||||||
|
private final PlaylistRepository playlistRepository;
|
||||||
|
private final VideoService videoService;
|
||||||
|
private final UserService userService;
|
||||||
|
private final ValidatorUtil validatorUtil;
|
||||||
|
public PlaylistService(PlaylistRepository playlistRepository,
|
||||||
|
VideoService videoService,
|
||||||
|
UserService userService,
|
||||||
|
ValidatorUtil validatorUtil) {
|
||||||
|
this.playlistRepository = playlistRepository;
|
||||||
|
this.videoService = videoService;
|
||||||
|
this.userService = userService;
|
||||||
|
this.validatorUtil = validatorUtil;
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Playlist addPlaylist(String name, Long userId) {
|
||||||
|
if (!StringUtils.hasText(name)) {
|
||||||
|
throw new IllegalArgumentException("Playlist name is null or empty");
|
||||||
|
}
|
||||||
|
if (userId == null) {
|
||||||
|
throw new IllegalArgumentException("Playlist userId is null or empty");
|
||||||
|
}
|
||||||
|
User user = userService.findUser(userId);
|
||||||
|
final Playlist playlist = new Playlist(name, user);
|
||||||
|
validatorUtil.validate(playlist);
|
||||||
|
return playlistRepository.save(playlist);
|
||||||
|
}
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public Playlist findPlaylist(Long id) {
|
||||||
|
final Optional<Playlist> playlist = playlistRepository.findById(id);
|
||||||
|
return playlist.orElseThrow(() -> new PlaylistNotFoundException(id));
|
||||||
|
}
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public List<Playlist> findAllPlaylists() {
|
||||||
|
return playlistRepository.findAll();
|
||||||
|
}
|
||||||
|
// @Transactional(readOnly = true)
|
||||||
|
// public List<Video> findFilteredVideos(Long id, String modelName, String serialNum, Long monitorId, Long cabinetId) {
|
||||||
|
// return videoRepository.findFilteredVideos(id, modelName, serialNum, monitorId, cabinetId);
|
||||||
|
// }
|
||||||
|
@Transactional
|
||||||
|
public Playlist updatePlaylist(Long id, String name) {
|
||||||
|
if (!StringUtils.hasText(name)) {
|
||||||
|
throw new IllegalArgumentException("Video name is null or empty");
|
||||||
|
}
|
||||||
|
final Playlist currentPlaylist = findPlaylist(id);
|
||||||
|
currentPlaylist.setName(name);
|
||||||
|
validatorUtil.validate(currentPlaylist);
|
||||||
|
return playlistRepository.save(currentPlaylist);
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Playlist deletePlaylist(Long id) {
|
||||||
|
final Playlist currentPlaylist = findPlaylist(id);
|
||||||
|
List<Video> currentPlaylistVideos = currentPlaylist.getVideos();
|
||||||
|
if (currentPlaylistVideos != null && currentPlaylistVideos.size() > 0) {
|
||||||
|
for (Video currentPlaylistVideo: currentPlaylistVideos) {
|
||||||
|
currentPlaylistVideo.removePlaylist(currentPlaylist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
playlistRepository.delete(currentPlaylist);
|
||||||
|
return currentPlaylist;
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public void deleteAllVideos() {
|
||||||
|
List<Playlist> playlists = findAllPlaylists();
|
||||||
|
for (Playlist playlist : playlists) {
|
||||||
|
deletePlaylist(playlist.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public List<Video> listVideosFromPlaylist(Long id) {
|
||||||
|
if (id == null) {
|
||||||
|
throw new IllegalArgumentException("Playlist id is null or empty");
|
||||||
|
}
|
||||||
|
return findPlaylist(id).getVideos();
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Playlist addVideoToPlaylist(Long playlistId, Long videoId) {
|
||||||
|
if (videoId == null) {
|
||||||
|
throw new IllegalArgumentException("Video id is null or empty");
|
||||||
|
}
|
||||||
|
if (playlistId == null) {
|
||||||
|
throw new IllegalArgumentException("Playlist id is null or empty");
|
||||||
|
}
|
||||||
|
final Video video = videoService.findVideo(videoId);
|
||||||
|
final Playlist playlist = findPlaylist(playlistId);
|
||||||
|
playlist.addVideo(video);
|
||||||
|
return playlist;
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Playlist deleteVideoFromPlaylist(Long playlistId, Long videoId) {
|
||||||
|
if (videoId == null) {
|
||||||
|
throw new IllegalArgumentException("Video id is null or empty");
|
||||||
|
}
|
||||||
|
if (playlistId == null) {
|
||||||
|
throw new IllegalArgumentException("Playlist id is null or empty");
|
||||||
|
}
|
||||||
|
final Video video = videoService.findVideo(videoId);
|
||||||
|
final Playlist playlist = findPlaylist(playlistId);;
|
||||||
|
playlist.removeVideo(video);
|
||||||
|
return playlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public List<Playlist> listPlaylistsFromVideo(Long id) {
|
||||||
|
if (id == null) {
|
||||||
|
throw new IllegalArgumentException("Video id is null or empty");
|
||||||
|
}
|
||||||
|
return videoService.findVideo(id).getPlaylists();
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Video addPlaylistToVideo(Long videoId, Long playlistId) {
|
||||||
|
if (videoId == null) {
|
||||||
|
throw new IllegalArgumentException("Video id is null or empty");
|
||||||
|
}
|
||||||
|
if (playlistId == null) {
|
||||||
|
throw new IllegalArgumentException("Playlist id is null or empty");
|
||||||
|
}
|
||||||
|
final Video video = videoService.findVideo(videoId);
|
||||||
|
final Playlist playlist = findPlaylist(playlistId);
|
||||||
|
video.addPlaylist(playlist);
|
||||||
|
return video;
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Video deletePlaylistFromVideo(Long videoId, Long playlistId) {
|
||||||
|
if (videoId == null) {
|
||||||
|
throw new IllegalArgumentException("Video id is null or empty");
|
||||||
|
}
|
||||||
|
if (playlistId == null) {
|
||||||
|
throw new IllegalArgumentException("Playlist id is null or empty");
|
||||||
|
}
|
||||||
|
final Video video = videoService.findVideo(videoId);
|
||||||
|
final Playlist playlist = findPlaylist(playlistId);
|
||||||
|
video.removePlaylist(playlist);
|
||||||
|
return video;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.kalyshev.yan.user.repository;
|
||||||
|
|
||||||
|
public class UserNotFoundException extends RuntimeException {
|
||||||
|
public UserNotFoundException(Long id) {
|
||||||
|
super(String.format("User with id [%s] is not found", id));
|
||||||
|
}
|
||||||
|
}
|
@ -2,10 +2,12 @@ package com.kalyshev.yan.user.service;
|
|||||||
|
|
||||||
import com.kalyshev.yan.user.model.User;
|
import com.kalyshev.yan.user.model.User;
|
||||||
import com.kalyshev.yan.user.model.UserRole;
|
import com.kalyshev.yan.user.model.UserRole;
|
||||||
|
import com.kalyshev.yan.user.repository.UserNotFoundException;
|
||||||
import com.kalyshev.yan.user.repository.UserRepository;
|
import com.kalyshev.yan.user.repository.UserRepository;
|
||||||
import com.kalyshev.yan.util.validation.ValidationException;
|
import com.kalyshev.yan.util.validation.ValidationException;
|
||||||
import com.kalyshev.yan.util.validation.ValidatorUtil;
|
import com.kalyshev.yan.util.validation.ValidatorUtil;
|
||||||
import jakarta.transaction.Transactional;
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
import com.kalyshev.yan.video.repository.VideoNotFoundException;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
@ -14,9 +16,11 @@ import org.springframework.security.core.userdetails.UserDetailsService;
|
|||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class UserService implements UserDetailsService {
|
public class UserService implements UserDetailsService {
|
||||||
@ -33,6 +37,11 @@ public class UserService implements UserDetailsService {
|
|||||||
public Page<User> findAllPages(int page, int size) {
|
public Page<User> findAllPages(int page, int size) {
|
||||||
return userRepository.findAll(PageRequest.of(page - 1, size, Sort.by("id").ascending()));
|
return userRepository.findAll(PageRequest.of(page - 1, size, Sort.by("id").ascending()));
|
||||||
}
|
}
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public User findUser(Long id) {
|
||||||
|
final Optional<User> user = userRepository.findById(id);
|
||||||
|
return user.orElseThrow(() -> new UserNotFoundException(id));
|
||||||
|
}
|
||||||
public User findByLogin(String login) {
|
public User findByLogin(String login) {
|
||||||
return userRepository.findOneByLoginIgnoreCase(login);
|
return userRepository.findOneByLoginIgnoreCase(login);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package com.kalyshev.yan.util.error;
|
package com.kalyshev.yan.util.error;
|
||||||
|
|
||||||
import com.kalyshev.yan.cabinet.repository.CabinetNotFoundException;
|
import com.kalyshev.yan.category.repository.CategoryNotFoundException;
|
||||||
|
import com.kalyshev.yan.comment.repository.CommentNotFoundException;
|
||||||
|
import com.kalyshev.yan.playlist.repository.PlaylistNotFoundException;
|
||||||
|
import com.kalyshev.yan.user.repository.UserNotFoundException;
|
||||||
import com.kalyshev.yan.util.validation.ValidationException;
|
import com.kalyshev.yan.util.validation.ValidationException;
|
||||||
|
import com.kalyshev.yan.video.repository.VideoNotFoundException;
|
||||||
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@ -15,7 +19,11 @@ import java.util.stream.Collectors;
|
|||||||
@ControllerAdvice(annotations = RestController.class)
|
@ControllerAdvice(annotations = RestController.class)
|
||||||
public class AdviceController {
|
public class AdviceController {
|
||||||
@ExceptionHandler({
|
@ExceptionHandler({
|
||||||
CabinetNotFoundException.class,
|
VideoNotFoundException.class,
|
||||||
|
PlaylistNotFoundException.class,
|
||||||
|
CategoryNotFoundException.class,
|
||||||
|
CommentNotFoundException.class,
|
||||||
|
UserNotFoundException.class,
|
||||||
ValidationException.class
|
ValidationException.class
|
||||||
})
|
})
|
||||||
public ResponseEntity<Object> handleException(Throwable e) {
|
public ResponseEntity<Object> handleException(Throwable e) {
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
package com.kalyshev.yan.video.controller;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.WebConfiguration;
|
||||||
|
import com.kalyshev.yan.category.controller.CategoryDto;
|
||||||
|
import com.kalyshev.yan.category.service.CategoryService;
|
||||||
|
import com.kalyshev.yan.computer.controller.ComputerDto;
|
||||||
|
import com.kalyshev.yan.computer.service.ComputerService;
|
||||||
|
import com.kalyshev.yan.monitor.controller.MonitorDto;
|
||||||
|
import com.kalyshev.yan.playlist.controller.PlaylistDto;
|
||||||
|
import com.kalyshev.yan.playlist.service.PlaylistService;
|
||||||
|
import com.kalyshev.yan.video.service.VideoService;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(WebConfiguration.REST_API + "/video")
|
||||||
|
public class VideoController {
|
||||||
|
private final VideoService videoService;
|
||||||
|
private final PlaylistService playlistService;
|
||||||
|
private final CategoryService categoryService;
|
||||||
|
public VideoController(VideoService videoService,
|
||||||
|
PlaylistService playlistService,
|
||||||
|
CategoryService categoryService) {
|
||||||
|
this.videoService = videoService;
|
||||||
|
this.playlistService = playlistService;
|
||||||
|
this.categoryService = categoryService;
|
||||||
|
}
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public VideoDto getVideo(@PathVariable Long id) {
|
||||||
|
return new VideoDto(videoService.findVideo(id));
|
||||||
|
}
|
||||||
|
@GetMapping("/")
|
||||||
|
public List<VideoDto> getVideos() {
|
||||||
|
return videoService.findAllVideos().stream()
|
||||||
|
.map(VideoDto::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
// @GetMapping("/filter")
|
||||||
|
// public List<VideoDto> getFilteredVideos(@RequestParam(value = "id", required = false) Long id,
|
||||||
|
// @RequestParam(value = "name", required = false) String name,
|
||||||
|
// @RequestParam(value = "date", required = false) LocalDate date,
|
||||||
|
// @RequestParam(value = "userId", required = false) Long monitorId) {
|
||||||
|
// return videoService.findFilteredVideos(id, name, date, monitorId).stream()
|
||||||
|
// .map(VideoDto::new)
|
||||||
|
// .toList();
|
||||||
|
// }
|
||||||
|
@PostMapping("/")
|
||||||
|
public VideoDto createVideo(@RequestBody @Valid VideoDto videoDto) {
|
||||||
|
return new VideoDto(videoService.addVideo(videoDto.getName(), videoDto.getUserId()));
|
||||||
|
}
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public VideoDto updateVideo(@PathVariable Long id,
|
||||||
|
@RequestBody @Valid VideoDto updateVideo) {
|
||||||
|
return new VideoDto(videoService.updateVideo(id, updateVideo.getName()));
|
||||||
|
}
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public VideoDto deleteVideo(@PathVariable Long id) {
|
||||||
|
return new VideoDto(videoService.deleteVideo(id));
|
||||||
|
}
|
||||||
|
@GetMapping("/{id}/playlists")
|
||||||
|
public List<PlaylistDto> getVideoPlaylists(@PathVariable Long id) {
|
||||||
|
return playlistService.listPlaylistsFromVideo(id).stream()
|
||||||
|
.map(PlaylistDto::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
@PostMapping("/{id}/playlist")
|
||||||
|
public VideoDto addVideoPlaylist(@PathVariable Long id,
|
||||||
|
@RequestParam("playlistId") Long playlistId) {
|
||||||
|
return new VideoDto(playlistService.addPlaylistToVideo(id, playlistId));
|
||||||
|
}
|
||||||
|
@DeleteMapping("/{id}/playlist/{playlistId}")
|
||||||
|
public VideoDto deleteVideoPlaylist(@PathVariable Long id, @PathVariable Long playlistId) {
|
||||||
|
return new VideoDto(playlistService.deletePlaylistFromVideo(id, playlistId));
|
||||||
|
}
|
||||||
|
@GetMapping("/{id}/categories")
|
||||||
|
public List<CategoryDto> getVideoCategories(@PathVariable Long id) {
|
||||||
|
return categoryService.listCategoriesFromVideo(id).stream()
|
||||||
|
.map(CategoryDto::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
@PostMapping("/{id}/category")
|
||||||
|
public VideoDto addVideoCategory(@PathVariable Long id,
|
||||||
|
@RequestParam("categoryId") Long categoryId) {
|
||||||
|
return new VideoDto(categoryService.addCategoryToVideo(id, categoryId));
|
||||||
|
}
|
||||||
|
@DeleteMapping("/{id}/category/{categoryId}")
|
||||||
|
public VideoDto deleteVideoCategory(@PathVariable Long id, @PathVariable Long categoryId) {
|
||||||
|
return new VideoDto(categoryService.deleteCategoryFromVideo(id, categoryId));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.kalyshev.yan.video.controller;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.category.model.Category;
|
||||||
|
import com.kalyshev.yan.playlist.model.Playlist;
|
||||||
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class VideoDto {
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private Long userId;
|
||||||
|
private LocalDate date;
|
||||||
|
private List<Long> categoryIds;
|
||||||
|
private List<Long> playlistIds;
|
||||||
|
public VideoDto() {}
|
||||||
|
public VideoDto(Video video) {
|
||||||
|
this.id = video.getId();
|
||||||
|
this.name = video.getName();
|
||||||
|
this.date = video.getDate();
|
||||||
|
this.userId = video.getUser().getId();
|
||||||
|
if (video.getCategories() == null) {
|
||||||
|
this.categoryIds = new ArrayList<>();
|
||||||
|
} else {
|
||||||
|
this.categoryIds = new ArrayList<>();
|
||||||
|
List<Category> categories = video.getCategories();
|
||||||
|
for (Category category : categories) {
|
||||||
|
categoryIds.add(category.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (video.getPlaylists() == null) {
|
||||||
|
this.playlistIds = new ArrayList<>();
|
||||||
|
} else {
|
||||||
|
this.playlistIds = new ArrayList<>();
|
||||||
|
List<Playlist> playlists = video.getPlaylists();
|
||||||
|
for (Playlist playlist : playlists) {
|
||||||
|
playlistIds.add(playlist.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Long getId() { return this.id; }
|
||||||
|
public void setId(Long id) { this.id = id; }
|
||||||
|
public String getName() { return this.name; }
|
||||||
|
public void setName(String name) { this.name = name; }
|
||||||
|
public Long getUserId() { return this.userId; }
|
||||||
|
public void setUserId(Long userId) { this.userId = userId; }
|
||||||
|
public String getDate() { return this.date.toString(); }
|
||||||
|
public List<Long> getCategoryIds() { return this.categoryIds; }
|
||||||
|
public void setCategoryIds(List<Long> categoryIds) { this.categoryIds = categoryIds; }
|
||||||
|
public List<Long> getPlaylistIds() { return this.playlistIds; }
|
||||||
|
public void setPlaylistIds(List<Long> playlistIds) { this.playlistIds = playlistIds; }
|
||||||
|
public void setDate(LocalDate date) { this.date = date; }
|
||||||
|
}
|
@ -0,0 +1,124 @@
|
|||||||
|
package com.kalyshev.yan.video.controller;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.category.controller.CategoryDto;
|
||||||
|
import com.kalyshev.yan.category.service.CategoryService;
|
||||||
|
import com.kalyshev.yan.playlist.controller.PlaylistDto;
|
||||||
|
import com.kalyshev.yan.playlist.service.PlaylistService;
|
||||||
|
import com.kalyshev.yan.user.model.User;
|
||||||
|
import com.kalyshev.yan.user.service.UserService;
|
||||||
|
import com.kalyshev.yan.video.service.VideoService;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/videos")
|
||||||
|
public class VideoMvcController {
|
||||||
|
private final CategoryService categoryService;
|
||||||
|
private final PlaylistService playlistService;
|
||||||
|
private final UserService userService;
|
||||||
|
private final VideoService videoService;
|
||||||
|
public VideoMvcController(CategoryService categoryService,
|
||||||
|
VideoService videoService,
|
||||||
|
UserService userService,
|
||||||
|
PlaylistService playlistService) {
|
||||||
|
this.categoryService = categoryService;
|
||||||
|
this.playlistService = playlistService;
|
||||||
|
this.videoService = videoService;
|
||||||
|
this.userService = userService;
|
||||||
|
}
|
||||||
|
@GetMapping(value = {"", "/"})
|
||||||
|
public String getVideos(Model model) {
|
||||||
|
model.addAttribute("videos",
|
||||||
|
videoService.findAllVideos().stream()
|
||||||
|
.map(VideoDto::new)
|
||||||
|
.toList());
|
||||||
|
return "videos";
|
||||||
|
}
|
||||||
|
@GetMapping(value = {"/edit/", "/edit/{id}"})
|
||||||
|
public String editVideo(@PathVariable(required = false) Long id,
|
||||||
|
Model model) {
|
||||||
|
if (id == null || id <= 0) {
|
||||||
|
model.addAttribute("videoDto", new VideoDto());
|
||||||
|
} else {
|
||||||
|
model.addAttribute("videoId", id);
|
||||||
|
model.addAttribute("videoDto", new VideoDto(videoService.findVideo(id)));
|
||||||
|
model.addAttribute("categories",
|
||||||
|
categoryService.listCategoriesFromVideo(id).stream()
|
||||||
|
.map(CategoryDto::new)
|
||||||
|
.toList());
|
||||||
|
model.addAttribute("playlists",
|
||||||
|
playlistService.listPlaylistsFromVideo(id).stream()
|
||||||
|
.map(PlaylistDto::new)
|
||||||
|
.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
model.addAttribute("allCategories",
|
||||||
|
categoryService.findAllCategories().stream()
|
||||||
|
.map(CategoryDto::new)
|
||||||
|
.toList());
|
||||||
|
model.addAttribute("allPlaylists",
|
||||||
|
playlistService.findAllPlaylists().stream()
|
||||||
|
.map(PlaylistDto::new)
|
||||||
|
.toList());
|
||||||
|
return "video-edit";
|
||||||
|
}
|
||||||
|
@PostMapping(value = {"", "/", "/{id}"})
|
||||||
|
public String saveVideo(@PathVariable(required = false) Long id,
|
||||||
|
@ModelAttribute @Valid VideoDto videoDto,
|
||||||
|
BindingResult bindingResult,
|
||||||
|
Model model) {
|
||||||
|
if (bindingResult.hasErrors()) {
|
||||||
|
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||||
|
return "video-edit";
|
||||||
|
}
|
||||||
|
User user = userService.findByLogin(SecurityContextHolder.getContext().getAuthentication().getName());
|
||||||
|
if (id == null || id <= 0) {
|
||||||
|
videoService.addVideo(videoDto.getName(), user.getId());
|
||||||
|
} else {
|
||||||
|
videoService.updateVideo(id, videoDto.getName());
|
||||||
|
}
|
||||||
|
return "redirect:/videos";
|
||||||
|
}
|
||||||
|
@PostMapping("/delete/{id}")
|
||||||
|
public String deleteVideo(@PathVariable Long id) {
|
||||||
|
videoService.deleteVideo(id);
|
||||||
|
return "redirect:/videos";
|
||||||
|
}
|
||||||
|
@PostMapping(value = "/{id}/category/{categoryId}")
|
||||||
|
public String addVideoCategory(@PathVariable(value = "id") Long id,
|
||||||
|
@PathVariable(value = "categoryId") Long categoryId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
categoryService.addCategoryToVideo(id, categoryId);
|
||||||
|
String referer = request.getHeader("Referer");
|
||||||
|
return "redirect:"+ referer;
|
||||||
|
}
|
||||||
|
@GetMapping(value = "/{id}/categoryDelete/{categoryId}")
|
||||||
|
public String deleteVideoCategory(@PathVariable(value = "id") Long id,
|
||||||
|
@PathVariable(value = "categoryId") Long categoryId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
categoryService.deleteCategoryFromVideo(id, categoryId);
|
||||||
|
String referer = request.getHeader("Referer");
|
||||||
|
return "redirect:"+ referer;
|
||||||
|
}
|
||||||
|
@PostMapping(value = "/{id}/playlist/{playlistId}")
|
||||||
|
public String addVideoPlaylist(@PathVariable(value = "id") Long id,
|
||||||
|
@PathVariable(value = "playlistId") Long playlistId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
playlistService.addPlaylistToVideo(id, playlistId);
|
||||||
|
String referer = request.getHeader("Referer");
|
||||||
|
return "redirect:"+ referer;
|
||||||
|
}
|
||||||
|
@GetMapping(value = "/{id}/playlistDelete/{playlistId}")
|
||||||
|
public String deleteVideoPlaylist(@PathVariable(value = "id") Long id,
|
||||||
|
@PathVariable(value = "playlistId") Long playlistId,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
playlistService.deletePlaylistFromVideo(id, playlistId);
|
||||||
|
String referer = request.getHeader("Referer");
|
||||||
|
return "redirect:"+ referer;
|
||||||
|
}
|
||||||
|
}
|
112
src/main/java/com/kalyshev/yan/video/model/Video.java
Normal file
112
src/main/java/com/kalyshev/yan/video/model/Video.java
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
package com.kalyshev.yan.video.model;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.category.model.Category;
|
||||||
|
import com.kalyshev.yan.playlist.model.Playlist;
|
||||||
|
import com.kalyshev.yan.user.model.User;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "video")
|
||||||
|
public class Video {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private LocalDate date;
|
||||||
|
@ManyToMany(cascade = {CascadeType.MERGE})
|
||||||
|
private List<Category> categories;
|
||||||
|
@ManyToMany(cascade = {CascadeType.MERGE})
|
||||||
|
private List<Playlist> playlists;
|
||||||
|
@ManyToOne(cascade = {CascadeType.MERGE})
|
||||||
|
private User user;
|
||||||
|
public Video() {
|
||||||
|
}
|
||||||
|
public Video(String name, User user) {
|
||||||
|
this.name = name;
|
||||||
|
this.user = user;
|
||||||
|
this.date = LocalDate.now();
|
||||||
|
}
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
public LocalDate getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
public void setDate(LocalDate date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
public List<Category> getCategories() {
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
public void addCategory(Category category){
|
||||||
|
if (categories == null){
|
||||||
|
this.categories = new ArrayList<>();
|
||||||
|
}
|
||||||
|
if (!categories.contains(category)) {
|
||||||
|
this.categories.add(category);
|
||||||
|
category.addVideo(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void removeCategory(Category category){
|
||||||
|
if (categories.contains(category)) {
|
||||||
|
this.categories.remove(category);
|
||||||
|
category.removeVideo(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public List<Playlist> getPlaylists() {
|
||||||
|
return playlists;
|
||||||
|
}
|
||||||
|
public void addPlaylist(Playlist playlist){
|
||||||
|
if (playlists == null){
|
||||||
|
this.playlists = new ArrayList<>();
|
||||||
|
}
|
||||||
|
if (!playlists.contains(playlist)) {
|
||||||
|
this.playlists.add(playlist);
|
||||||
|
playlist.addVideo(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void removePlaylist(Playlist playlist){
|
||||||
|
if (playlists.contains(playlist)) {
|
||||||
|
this.playlists.remove(playlist);
|
||||||
|
playlist.removeVideo(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o)
|
||||||
|
return true;
|
||||||
|
if (!(o instanceof Video video))
|
||||||
|
return false;
|
||||||
|
return Objects.equals(id, video.id);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(id);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Video{" +
|
||||||
|
"id=" + id +
|
||||||
|
", name='" + name + '\'' +
|
||||||
|
", date='" + date + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.kalyshev.yan.video.repository;
|
||||||
|
|
||||||
|
public class VideoNotFoundException extends RuntimeException {
|
||||||
|
public VideoNotFoundException(Long id) {
|
||||||
|
super(String.format("Video with id [%s] is not found", id));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.kalyshev.yan.video.repository;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface VideoRepository extends JpaRepository<Video, Long> {
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
package com.kalyshev.yan.video.service;
|
||||||
|
|
||||||
|
import com.kalyshev.yan.category.model.Category;
|
||||||
|
import com.kalyshev.yan.category.service.CategoryService;
|
||||||
|
import com.kalyshev.yan.playlist.model.Playlist;
|
||||||
|
import com.kalyshev.yan.playlist.repository.PlaylistRepository;
|
||||||
|
import com.kalyshev.yan.playlist.service.PlaylistService;
|
||||||
|
import com.kalyshev.yan.user.model.User;
|
||||||
|
import com.kalyshev.yan.user.service.UserService;
|
||||||
|
import com.kalyshev.yan.video.model.Video;
|
||||||
|
import com.kalyshev.yan.video.repository.VideoNotFoundException;
|
||||||
|
import com.kalyshev.yan.video.repository.VideoRepository;
|
||||||
|
import com.kalyshev.yan.util.validation.ValidatorUtil;
|
||||||
|
import jakarta.validation.constraints.Null;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class VideoService {
|
||||||
|
private final VideoRepository videoRepository;
|
||||||
|
private final UserService userService;
|
||||||
|
private final ValidatorUtil validatorUtil;
|
||||||
|
public VideoService(VideoRepository videoRepository,
|
||||||
|
UserService userService,
|
||||||
|
ValidatorUtil validatorUtil) {
|
||||||
|
this.videoRepository = videoRepository;
|
||||||
|
this.userService = userService;
|
||||||
|
this.validatorUtil = validatorUtil;
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Video addVideo(String name, Long userId) {
|
||||||
|
if (!StringUtils.hasText(name)) {
|
||||||
|
throw new IllegalArgumentException("Video name is null or empty");
|
||||||
|
}
|
||||||
|
if (userId == null) {
|
||||||
|
throw new IllegalArgumentException("Video userId is null or empty");
|
||||||
|
}
|
||||||
|
User user = userService.findUser(userId);
|
||||||
|
final Video video = new Video(name, user);
|
||||||
|
validatorUtil.validate(video);
|
||||||
|
return videoRepository.save(video);
|
||||||
|
}
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public Video findVideo(Long id) {
|
||||||
|
final Optional<Video> video = videoRepository.findById(id);
|
||||||
|
return video.orElseThrow(() -> new VideoNotFoundException(id));
|
||||||
|
}
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public List<Video> findAllVideos() {
|
||||||
|
return videoRepository.findAll();
|
||||||
|
}
|
||||||
|
// @Transactional(readOnly = true)
|
||||||
|
// public List<Video> findFilteredVideos(Long id, String modelName, String serialNum, Long monitorId, Long cabinetId) {
|
||||||
|
// return videoRepository.findFilteredVideos(id, modelName, serialNum, monitorId, cabinetId);
|
||||||
|
// }
|
||||||
|
@Transactional
|
||||||
|
public Video updateVideo(Long id, String name) {
|
||||||
|
if (!StringUtils.hasText(name)) {
|
||||||
|
throw new IllegalArgumentException("Video name is null or empty");
|
||||||
|
}
|
||||||
|
final Video currentVideo = findVideo(id);
|
||||||
|
currentVideo.setName(name);
|
||||||
|
validatorUtil.validate(currentVideo);
|
||||||
|
return videoRepository.save(currentVideo);
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public Video deleteVideo(Long id) {
|
||||||
|
final Video currentVideo = findVideo(id);
|
||||||
|
List<Playlist> currentVideoPlaylists = currentVideo.getPlaylists();
|
||||||
|
if (currentVideoPlaylists != null && currentVideoPlaylists.size() > 0) {
|
||||||
|
for (Playlist currentVideoPlaylist: currentVideoPlaylists) {
|
||||||
|
currentVideoPlaylist.removeVideo(currentVideo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
videoRepository.delete(currentVideo);
|
||||||
|
return currentVideo;
|
||||||
|
}
|
||||||
|
@Transactional
|
||||||
|
public void deleteAllVideos() {
|
||||||
|
List<Video> videos = findAllVideos();
|
||||||
|
for (Video video : videos) {
|
||||||
|
deleteVideo(video.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,72 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="content">
|
|
||||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
|
||||||
<form action="#" th:action="@{/index/{id}(id=${id})}" th:object="${cabinetDto}" method="post">
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="number" class="form-label">Номер кабинета</label>
|
|
||||||
<input type="text" class="form-control" id="number" th:field="${cabinetDto.number}" required="true">
|
|
||||||
</div>
|
|
||||||
<div th:if="${id != null}" class="table-responsive">
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">#</th>
|
|
||||||
<th scope="col">Название</th>
|
|
||||||
<th scope="col">Серийный номер</th>
|
|
||||||
<th scope="col">Монитор</th>
|
|
||||||
<th scope="col">Кабинет</th>
|
|
||||||
<th scope="col"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr th:each="computer, iterator: ${computers}">
|
|
||||||
<th scope="row" th:text="${iterator.index} + 1"/>
|
|
||||||
<td th:text="${computer.modelName}" style="width: 60%"/>
|
|
||||||
<td th:text="${computer.serialNum}" style="width: 60%"/>
|
|
||||||
<td th:text="${computer.monitorModelName}" style="width: 60%"/>
|
|
||||||
<td style="width: 10%">
|
|
||||||
<div class="btn-group" role="group" aria-label="Basic example">
|
|
||||||
<button type="button" class="btn btn-danger button-fixed button-sm"
|
|
||||||
th:attr="onclick=|confirm('Удалить?') && document.getElementById('remove-${computer.id}').click()|">
|
|
||||||
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<form th:action="@{/index/{id}/computerDelete/{computerId}(id=${id}, computerId=${computer.id})}" method="post">
|
|
||||||
<button th:id="'remove-' + ${computer.id}" type="submit" style="display: none">
|
|
||||||
Удалить
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<button type="submit" class="btn btn-primary button-fixed">
|
|
||||||
<span th:if="${id == null}">Добавить</span>
|
|
||||||
<span th:if="${id != null}">Обновить</span>
|
|
||||||
</button>
|
|
||||||
<a class="btn btn-secondary button-fixed" th:href="@{/index}">
|
|
||||||
Назад
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<form th:if="${id != null}" th:action="@{/index/{id}/computer(id=${id})}" id="addComputerForm" method="post">
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="computers" class="form-label">Добавить компьютер</label>
|
|
||||||
<select class="form-select" id="computers" required>
|
|
||||||
<option disabled value="">Выберите компьютер</option>
|
|
||||||
<option th:each="computer, iterator: ${allComputers}" th:text="${computer.modelName}" th:value="${computer.id}">
|
|
||||||
</select>
|
|
||||||
<button class="btn btn-outline-secondary" id="addComputerButton" th:attr="onclick=|document.getElementById('addComputerForm').action = document.getElementById('addComputerForm').action + '/' + document.getElementById('computers').value ; document.getElementById('addComputerForm}').submit()|">Добавить</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -8,7 +8,7 @@
|
|||||||
<div layout:fragment="content">
|
<div layout:fragment="content">
|
||||||
<div>
|
<div>
|
||||||
<a class="btn btn-success button-fixed"
|
<a class="btn btn-success button-fixed"
|
||||||
th:href="@{/monitors/edit/}">
|
th:href="@{/categories/edit/}">
|
||||||
<i class="fa-solid fa-plus"></i> Добавить
|
<i class="fa-solid fa-plus"></i> Добавить
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -22,22 +22,22 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr th:each="monitor, iterator: ${monitors}">
|
<tr th:each="category, iterator: ${categories}">
|
||||||
<th scope="row" th:text="${iterator.index} + 1"/>
|
<th scope="row" th:text="${iterator.index} + 1"/>
|
||||||
<td th:text="${monitor.modelName}" style="width: 60%"/>
|
<td th:text="${category.name}" style="width: 60%"/>
|
||||||
<td style="width: 10%">
|
<td style="width: 10%">
|
||||||
<div class="btn-group" role="group" aria-label="Basic example">
|
<div class="btn-group" role="group" aria-label="Basic example">
|
||||||
<a class="btn btn-warning button-fixed button-sm"
|
<a class="btn btn-warning button-fixed button-sm"
|
||||||
th:href="@{/monitors/edit/{id}(id=${monitor.id})}">
|
th:href="@{/categories/edit/{id}(id=${category.id})}">
|
||||||
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
|
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
|
||||||
</a>
|
</a>
|
||||||
<button type="button" class="btn btn-danger button-fixed button-sm"
|
<button type="button" class="btn btn-danger button-fixed button-sm"
|
||||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${monitor.id}').click()|">
|
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${category.id}').click()|">
|
||||||
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<form th:action="@{/monitors/delete/{id}(id=${monitor.id})}" method="post">
|
<form th:action="@{/categories/delete/{id}(id=${category.id})}" method="post">
|
||||||
<button th:id="'remove-' + ${monitor.id}" type="submit" style="display: none">
|
<button th:id="'remove-' + ${category.id}" type="submit" style="display: none">
|
||||||
Удалить
|
Удалить
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
66
src/main/resources/templates/category-edit.html
Normal file
66
src/main/resources/templates/category-edit.html
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorate="~{default}">
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div layout:fragment="content">
|
||||||
|
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||||
|
<form action="#" th:action="@{/categories/{id}(id=${id})}" th:object="${categoryDto}" method="post">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="number" class="form-label">Название</label>
|
||||||
|
<input type="text" class="form-control" id="number" th:field="${categoryDto.name}" required="true">
|
||||||
|
</div>
|
||||||
|
<div th:if="${id != null}" class="table-responsive">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">Название</th>
|
||||||
|
<th scope="col">Дата</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr th:each="video, iterator: ${videos}">
|
||||||
|
<th scope="row" th:text="${iterator.index} + 1"/>
|
||||||
|
<td th:text="${video.name}" style="width: 60%"/>
|
||||||
|
<td th:text="${video.date}" style="width: 60%"/>
|
||||||
|
<td style="width: 10%">
|
||||||
|
<div class="btn-group" role="group" aria-label="Basic example">
|
||||||
|
<a th:href="@{/categories/{id}/videoDelete/{videoId}(id=${id}, videoId=${video.id})}" class="btn btn-danger button-fixed button-sm">Удалить</a>
|
||||||
|
</div>
|
||||||
|
<!-- <form th:action="@{/categories/{id}/videoDelete/{videoId}(id=${id}, videoId=${video.id})}" method="post">-->
|
||||||
|
<!-- <button th:id="'remove-' + ${video.id}" type="submit" style="display: none">-->
|
||||||
|
<!-- Удалить-->
|
||||||
|
<!-- </button>-->
|
||||||
|
<!-- </form>-->
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<button type="submit" class="btn btn-primary button-fixed">
|
||||||
|
<span th:if="${id == null}">Добавить</span>
|
||||||
|
<span th:if="${id != null}">Обновить</span>
|
||||||
|
</button>
|
||||||
|
<a class="btn btn-secondary button-fixed" th:href="@{/categories}">
|
||||||
|
Назад
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<form th:if="${id != null}" th:action="@{/categories/{id}/video(id=${id})}" id="addVideoForm" method="post">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="videos" class="form-label">Добавить видео</label>
|
||||||
|
<select class="form-select" id="videos" required>
|
||||||
|
<option disabled value="">Выберите видео</option>
|
||||||
|
<option th:each="video, iterator: ${allVideos}" th:text="${video.name}" th:value="${video.id}">
|
||||||
|
</select>
|
||||||
|
<button class="btn btn-outline-secondary" id="addVideoButton" th:attr="onclick=|document.getElementById('addVideoForm').action = document.getElementById('addVideoForm').action + '/' + document.getElementById('videos').value ; document.getElementById('addVideoForm}').submit()|">Добавить</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -7,17 +7,21 @@
|
|||||||
<body>
|
<body>
|
||||||
<div layout:fragment="content">
|
<div layout:fragment="content">
|
||||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||||
<form action="#" th:action="@{/monitors/{id}(id=${id})}" th:object="${monitorDto}" method="post">
|
<form action="#" th:action="@{/comments/{id}(id=${id})}" th:object="${commentDto}" method="post">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="modelName" class="form-label">Название</label>
|
<label for="number" class="form-label">Комментарий</label>
|
||||||
<input type="text" class="form-control" id="modelName" th:field="${monitorDto.modelName}" required="true">
|
<input type="text" class="form-control" id="number" th:field="${commentDto.comment}" required="true">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="video" class="form-label">Видео</label>
|
||||||
|
<input type="text" class="form-control" id="video" th:field="${commentDto.videoId}" required="true">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<button type="submit" class="btn btn-primary button-fixed">
|
<button type="submit" class="btn btn-primary button-fixed">
|
||||||
<span th:if="${id == null}">Добавить</span>
|
<span th:if="${id == null}">Добавить</span>
|
||||||
<span th:if="${id != null}">Обновить</span>
|
<span th:if="${id != null}">Обновить</span>
|
||||||
</button>
|
</button>
|
||||||
<a class="btn btn-secondary button-fixed" th:href="@{/monitors}">
|
<a class="btn btn-secondary button-fixed" th:href="@{/comments}">
|
||||||
Назад
|
Назад
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
53
src/main/resources/templates/comments.html
Normal file
53
src/main/resources/templates/comments.html
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorate="~{default}">
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div layout:fragment="content">
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-success button-fixed"
|
||||||
|
th:href="@{/comments/edit/}">
|
||||||
|
<i class="fa-solid fa-plus"></i> Добавить
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">Комментарий</th>
|
||||||
|
<th scope="col">Видео</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr th:each="comment, iterator: ${comments}">
|
||||||
|
<th scope="row" th:text="${iterator.index} + 1"/>
|
||||||
|
<td th:text="${comment.comment}" style="width: 60%"/>
|
||||||
|
<td th:text="${comment.videoId}" style="width: 60%"/>
|
||||||
|
<td style="width: 10%">
|
||||||
|
<div class="btn-group" role="group" aria-label="Basic example">
|
||||||
|
<a class="btn btn-warning button-fixed button-sm"
|
||||||
|
th:href="@{/comments/edit/{id}(id=${comment.id})}">
|
||||||
|
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
|
||||||
|
</a>
|
||||||
|
<button type="button" class="btn btn-danger button-fixed button-sm"
|
||||||
|
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${comment.id}').click()|">
|
||||||
|
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<form th:action="@{/comments/delete/{id}(id=${comment.id})}" method="post">
|
||||||
|
<button th:id="'remove-' + ${comment.id}" type="submit" style="display: none">
|
||||||
|
Удалить
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,38 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="content">
|
|
||||||
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
|
||||||
<form action="#" th:action="@{/computers/{id}(id=${id})}" th:object="${computerDto}" method="post">
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="modelName" class="form-label">Название</label>
|
|
||||||
<input type="text" class="form-control" id="modelName" th:field="${computerDto.modelName}" required="true">
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="serialNum" class="form-label">Серийный номер</label>
|
|
||||||
<input type="text" class="form-control" id="serialNum" th:field="${computerDto.serialNum}" required="true">
|
|
||||||
</div>
|
|
||||||
<label for="monitor" class="form-label">Монитор</label>
|
|
||||||
<select class="form-select" id="monitor" th:field="${computerDto.monitorId}">
|
|
||||||
<option value="">Выберите монитор</option>
|
|
||||||
<option th:each="monitor, iterator: ${monitors}" th:text="${monitor.modelName}" th:value="${monitor.id}"
|
|
||||||
th:selected="${monitor.id==computerDto.monitorId}">
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<div class="mb-3">
|
|
||||||
<button type="submit" class="btn btn-primary button-fixed">
|
|
||||||
<span th:if="${id == null}">Добавить</span>
|
|
||||||
<span th:if="${id != null}">Обновить</span>
|
|
||||||
</button>
|
|
||||||
<a class="btn btn-secondary button-fixed" th:href="@{/computers}">
|
|
||||||
Назад
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,57 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="content">
|
|
||||||
<div>
|
|
||||||
<a class="btn btn-success button-fixed"
|
|
||||||
th:href="@{/computers/edit/}">
|
|
||||||
<i class="fa-solid fa-plus"></i> Добавить
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">#</th>
|
|
||||||
<th scope="col">Название</th>
|
|
||||||
<th scope="col">Серийный номер</th>
|
|
||||||
<th scope="col">Монитор</th>
|
|
||||||
<th scope="col">Кабинет</th>
|
|
||||||
<th scope="col"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr th:each="computer, iterator: ${computers}">
|
|
||||||
<th scope="row" th:text="${iterator.index} + 1"/>
|
|
||||||
<td th:text="${computer.modelName}" style="width: 60%"/>
|
|
||||||
<td th:text="${computer.serialNum}" style="width: 60%"/>
|
|
||||||
<td th:text="${computer.monitorModelName}" style="width: 60%"/>
|
|
||||||
<td th:text="${computer.cabinetNumber}" style="width: 60%"/>
|
|
||||||
<td style="width: 10%">
|
|
||||||
<div class="btn-group" role="group" aria-label="Basic example">
|
|
||||||
<a class="btn btn-warning button-fixed button-sm"
|
|
||||||
th:href="@{/computers/edit/{id}(id=${computer.id})}">
|
|
||||||
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
|
|
||||||
</a>
|
|
||||||
<button type="button" class="btn btn-danger button-fixed button-sm"
|
|
||||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${computer.id}').click()|">
|
|
||||||
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<form th:action="@{/computers/delete/{id}(id=${computer.id})}" method="post">
|
|
||||||
<button th:id="'remove-' + ${computer.id}" type="submit" style="display: none">
|
|
||||||
Удалить
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -27,12 +27,12 @@
|
|||||||
</button>
|
</button>
|
||||||
<div class="collapse navbar-collapse" id="navbarNav" sec:authorize="isAuthenticated()">
|
<div class="collapse navbar-collapse" id="navbarNav" sec:authorize="isAuthenticated()">
|
||||||
<ul class="navbar-nav" th:with="activeLink=${#ctx.springRequestContext.requestUri}">
|
<ul class="navbar-nav" th:with="activeLink=${#ctx.springRequestContext.requestUri}">
|
||||||
<a class="nav-link" href="/index"
|
<a class="nav-link" href="/categories"
|
||||||
th:classappend="${#strings.equals(activeLink, '/index')} ? 'active' : ''">Кабинеты</a>
|
th:classappend="${#strings.equals(activeLink, '/categories')} ? 'active' : ''">Категории</a>
|
||||||
<a class="nav-link" href="/computers"
|
<a class="nav-link" href="/videos"
|
||||||
th:classappend="${#strings.equals(activeLink, '/computers')} ? 'active' : ''">Компьютеры</a>
|
th:classappend="${#strings.equals(activeLink, '/videos')} ? 'active' : ''">Видео</a>
|
||||||
<a class="nav-link" href="/monitors"
|
<a class="nav-link" href="/playlists"
|
||||||
th:classappend="${#strings.equals(activeLink, '/monitors')} ? 'active' : ''">Мониторы</a>
|
th:classappend="${#strings.equals(activeLink, '/playlists')} ? 'active' : ''">Плейлисты</a>
|
||||||
<a class="nav-link" href="/users"
|
<a class="nav-link" href="/users"
|
||||||
th:classappend="${#strings.equals(activeLink, '/users')} ? 'active' : ''">Пользователи</a>
|
th:classappend="${#strings.equals(activeLink, '/users')} ? 'active' : ''">Пользователи</a>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<head>
|
|
||||||
<title>Сайт</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="content">
|
|
||||||
<div>
|
|
||||||
<a class="btn btn-success button-fixed"
|
|
||||||
th:href="@{/index/edit/}">
|
|
||||||
<i class="fa-solid fa-plus"></i> Добавить
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">#</th>
|
|
||||||
<th scope="col">Номер кабинета</th>
|
|
||||||
<th scope="col"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr th:each="cabinet, iterator: ${cabinets}">
|
|
||||||
<th scope="row" th:text="${iterator.index} + 1"/>
|
|
||||||
<td th:text="${cabinet.number}" style="width: 60%"/>
|
|
||||||
<td style="width: 10%">
|
|
||||||
<div class="btn-group" role="group" aria-label="Basic example">
|
|
||||||
<a class="btn btn-warning button-fixed button-sm"
|
|
||||||
th:href="@{/index/edit/{id}(id=${cabinet.id})}">
|
|
||||||
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
|
|
||||||
</a>
|
|
||||||
<button type="button" class="btn btn-danger button-fixed button-sm"
|
|
||||||
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${cabinet.id}').click()|">
|
|
||||||
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<form th:action="@{/index/delete/{id}(id=${cabinet.id})}" method="post">
|
|
||||||
<button th:id="'remove-' + ${cabinet.id}" type="submit" style="display: none">
|
|
||||||
Удалить
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
66
src/main/resources/templates/playlist-edit.html
Normal file
66
src/main/resources/templates/playlist-edit.html
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorate="~{default}">
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div layout:fragment="content">
|
||||||
|
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||||
|
<form action="#" th:action="@{/playlists/{id}(id=${id})}" th:object="${playlistDto}" method="post">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="name" class="form-label">Название</label>
|
||||||
|
<input type="text" class="form-control" id="name" th:field="${playlistDto.name}" required="true">
|
||||||
|
</div>
|
||||||
|
<div th:if="${id != null}" class="table-responsive">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">Название</th>
|
||||||
|
<th scope="col">Дата</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr th:each="video, iterator: ${videos}">
|
||||||
|
<th scope="row" th:text="${iterator.index} + 1"/>
|
||||||
|
<td th:text="${video.name}" style="width: 60%"/>
|
||||||
|
<td th:text="${video.date}" style="width: 60%"/>
|
||||||
|
<td style="width: 10%">
|
||||||
|
<div class="btn-group" role="group" aria-label="Basic example">
|
||||||
|
<a th:href="@{/playlists/{id}/videoDelete/{videoId}(id=${id}, videoId=${video.id})}" class="btn btn-danger button-fixed button-sm">Удалить</a>
|
||||||
|
</div>
|
||||||
|
<!-- <form th:action="@{/categories/{id}/videoDelete/{videoId}(id=${id}, videoId=${video.id})}" method="post">-->
|
||||||
|
<!-- <button th:id="'remove-' + ${video.id}" type="submit" style="display: none">-->
|
||||||
|
<!-- Удалить-->
|
||||||
|
<!-- </button>-->
|
||||||
|
<!-- </form>-->
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<button type="submit" class="btn btn-primary button-fixed">
|
||||||
|
<span th:if="${id == null}">Добавить</span>
|
||||||
|
<span th:if="${id != null}">Обновить</span>
|
||||||
|
</button>
|
||||||
|
<a class="btn btn-secondary button-fixed" th:href="@{/playlists}">
|
||||||
|
Назад
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<form th:if="${id != null}" th:action="@{/playlists/{id}/video(id=${id})}" id="addVideoForm" method="post">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="videos" class="form-label">Добавить видео</label>
|
||||||
|
<select class="form-select" id="videos" required>
|
||||||
|
<option disabled value="">Выберите видео</option>
|
||||||
|
<option th:each="video, iterator: ${allVideos}" th:text="${video.name}" th:value="${video.id}">
|
||||||
|
</select>
|
||||||
|
<button class="btn btn-outline-secondary" id="addVideoButton" th:attr="onclick=|document.getElementById('addVideoForm').action = document.getElementById('addVideoForm').action + '/' + document.getElementById('videos').value ; document.getElementById('addVideoForm}').submit()|">Добавить</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
51
src/main/resources/templates/playlists.html
Normal file
51
src/main/resources/templates/playlists.html
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorate="~{default}">
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div layout:fragment="content">
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-success button-fixed"
|
||||||
|
th:href="@{/playlists/edit/}">
|
||||||
|
<i class="fa-solid fa-plus"></i> Добавить
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">Название</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr th:each="playlist, iterator: ${playlists}">
|
||||||
|
<th scope="row" th:text="${iterator.index} + 1"/>
|
||||||
|
<td th:text="${playlist.name}" style="width: 60%"/>
|
||||||
|
<td style="width: 10%">
|
||||||
|
<div class="btn-group" role="group" aria-label="Basic example">
|
||||||
|
<a class="btn btn-warning button-fixed button-sm"
|
||||||
|
th:href="@{/playlists/edit/{id}(id=${playlist.id})}">
|
||||||
|
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
|
||||||
|
</a>
|
||||||
|
<button type="button" class="btn btn-danger button-fixed button-sm"
|
||||||
|
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${playlist.id}').click()|">
|
||||||
|
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<form th:action="@{/playlists/delete/{id}(id=${playlist.id})}" method="post">
|
||||||
|
<button th:id="'remove-' + ${playlist.id}" type="submit" style="display: none">
|
||||||
|
Удалить
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
105
src/main/resources/templates/video-edit.html
Normal file
105
src/main/resources/templates/video-edit.html
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorate="~{default}">
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div layout:fragment="content">
|
||||||
|
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
|
||||||
|
<form action="#" th:action="@{/videos/{id}(id=${id})}" th:object="${videoDto}" method="post">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="number" class="form-label">Название</label>
|
||||||
|
<input type="text" class="form-control" id="number" th:field="${videoDto.name}" required="true">
|
||||||
|
</div>
|
||||||
|
<div th:if="${id != null}" class="table-responsive">
|
||||||
|
<p>Категории</p>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">Название</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr th:each="category, iterator: ${categories}">
|
||||||
|
<th scope="row" th:text="${iterator.index} + 1"/>
|
||||||
|
<td th:text="${category.name}" style="width: 60%"/>
|
||||||
|
<td style="width: 10%">
|
||||||
|
<div class="btn-group" role="group" aria-label="Basic example">
|
||||||
|
<a th:href="@{/videos/{id}/categoryDelete/{categoryId}(id=${id}, categoryId=${category.id})}" class="btn btn-danger button-fixed button-sm">Удалить</a>
|
||||||
|
</div>
|
||||||
|
<!-- <form th:action="@{/videos/{id}/categoryDelete/{categoryId}(id=${id}, categoryId=${category.id})}" method="post">-->
|
||||||
|
<!-- <button th:id="'remove-' + ${category.id}" type="submit" style="display: none">-->
|
||||||
|
<!-- Удалить-->
|
||||||
|
<!-- </button>-->
|
||||||
|
<!-- </form>-->
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div th:if="${id != null}" class="table-responsive">
|
||||||
|
<p>Плейлисты</p>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">Название</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr th:each="playlist, iterator: ${playlists}">
|
||||||
|
<th scope="row" th:text="${iterator.index} + 1"/>
|
||||||
|
<td th:text="${playlist.name}" style="width: 60%"/>
|
||||||
|
<td style="width: 10%">
|
||||||
|
<div class="btn-group" role="group" aria-label="Basic example">
|
||||||
|
<a th:href="@{/videos/{id}/playlistDelete/{playlistId}(id=${id}, playlistId=${playlist.id})}" class="btn btn-danger button-fixed button-sm">Удалить</a>
|
||||||
|
</div>
|
||||||
|
<!-- <form th:action="@{/videos/{id}/playlistDelete/{playlistId}(id=${id}, playlistId=${playlist.id})}" method="post">-->
|
||||||
|
<!-- <button th:id="'remove-' + ${playlist.id}" type="submit" style="display: none">-->
|
||||||
|
<!-- Удалить-->
|
||||||
|
<!-- </button>-->
|
||||||
|
<!-- </form>-->
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<button type="submit" class="btn btn-primary button-fixed">
|
||||||
|
<span th:if="${id == null}">Добавить</span>
|
||||||
|
<span th:if="${id != null}">Обновить</span>
|
||||||
|
</button>
|
||||||
|
<a class="btn btn-secondary button-fixed" th:href="@{/videos}">
|
||||||
|
Назад
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<form th:if="${id != null}" th:action="@{/videos/{id}/category(id=${id})}" id="addCategoryForm" method="post">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="categories" class="form-label">Добавить категорию</label>
|
||||||
|
<select class="form-select" id="categories" required>
|
||||||
|
<option disabled value="">Выберите категорию</option>
|
||||||
|
<option th:each="category, iterator: ${allCategories}" th:text="${category.name}" th:value="${category.id}">
|
||||||
|
</select>
|
||||||
|
<button class="btn btn-outline-secondary" id="addCategoryButton" th:attr="onclick=|document.getElementById('addCategoryForm').action = document.getElementById('addCategoryForm').action + '/' + document.getElementById('categories').value ; document.getElementById('addCategoryForm}').submit()|">Добавить</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
<form th:if="${id != null}" th:action="@{/videos/{id}/playlist(id=${id})}" id="addPlaylistForm" method="post">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="playlists" class="form-label">Добавить плейлист</label>
|
||||||
|
<select class="form-select" id="playlists" required>
|
||||||
|
<option disabled value="">Выберите плейлист</option>
|
||||||
|
<option th:each="playlist, iterator: ${allPlaylists}" th:text="${playlist.name}" th:value="${playlist.id}">
|
||||||
|
</select>
|
||||||
|
<button class="btn btn-outline-secondary" id="addPlaylistButton" th:attr="onclick=|document.getElementById('addPlaylistForm').action = document.getElementById('addPlaylistForm').action + '/' + document.getElementById('playlists').value ; document.getElementById('addPlaylistForm}').submit()|">Добавить</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
53
src/main/resources/templates/videos.html
Normal file
53
src/main/resources/templates/videos.html
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorate="~{default}">
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div layout:fragment="content">
|
||||||
|
<div>
|
||||||
|
<a class="btn btn-success button-fixed"
|
||||||
|
th:href="@{/videos/edit/}">
|
||||||
|
<i class="fa-solid fa-plus"></i> Добавить
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">Название</th>
|
||||||
|
<th scope="col">Дата</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr th:each="video, iterator: ${videos}">
|
||||||
|
<th scope="row" th:text="${iterator.index} + 1"/>
|
||||||
|
<td th:text="${video.name}" style="width: 60%"/>
|
||||||
|
<td th:text="${video.date}" style="width: 60%"/>
|
||||||
|
<td style="width: 10%">
|
||||||
|
<div class="btn-group" role="group" aria-label="Basic example">
|
||||||
|
<a class="btn btn-warning button-fixed button-sm"
|
||||||
|
th:href="@{/videos/edit/{id}(id=${video.id})}">
|
||||||
|
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
|
||||||
|
</a>
|
||||||
|
<button type="button" class="btn btn-danger button-fixed button-sm"
|
||||||
|
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${video.id}').click()|">
|
||||||
|
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<form th:action="@{/videos/delete/{id}(id=${video.id})}" method="post">
|
||||||
|
<button th:id="'remove-' + ${video.id}" type="submit" style="display: none">
|
||||||
|
Удалить
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user