работает всё кроме смены пользователя и создателя. Также нужно пофиксить некоторые места, чтобы код был менее уродским

This commit is contained in:
Николай 2023-04-20 15:52:27 +04:00
parent f626c3a2f4
commit e4adadadd0
14 changed files with 278 additions and 75 deletions

Binary file not shown.

View File

@ -68,7 +68,6 @@ public class CreatorActionMvcController {
model.addAttribute("errors", bindingResult.getAllErrors()); model.addAttribute("errors", bindingResult.getAllErrors());
return "creatorAction-edit"; return "creatorAction-edit";
}*/ }*/
String fileName = StringUtils.cleanPath(multipartFile.getOriginalFilename());
MangaDto.setImage(Base64.getEncoder().encodeToString(multipartFile.getBytes())); MangaDto.setImage(Base64.getEncoder().encodeToString(multipartFile.getBytes()));
log.info(MangaDto.getMangaName()); log.info(MangaDto.getMangaName());
MangaDto.setCreatorId(creatorId); MangaDto.setCreatorId(creatorId);

View File

@ -0,0 +1,40 @@
package com.LabWork.app.MangaStore.controller;
import com.LabWork.app.MangaStore.model.Dto.MangaReaderDto;
import com.LabWork.app.MangaStore.model.Dto.ReaderMangaDto;
import com.LabWork.app.MangaStore.model.Dto.SupportDto.MangaDto;
import com.LabWork.app.MangaStore.service.MangaService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Controller
@RequestMapping("/manga")
public class MangaMvcController {
private final MangaService mangaService;
public MangaMvcController(MangaService mangaService) {
this.mangaService = mangaService;
}
@GetMapping()
public String getMangaAnfReaders(Model model) {
model.addAttribute("mangaList", mangaService.findAllMangas().stream()
.map(x -> new MangaDto(x))
.toList());
return "catalog";
}
@GetMapping("/{id}")
public String getMangaAnfReaders(@PathVariable Long id, Model model) {
model.addAttribute("manga", new MangaReaderDto(mangaService.findManga(id), mangaService.getReader(id)));
model.addAttribute("readers", mangaService.getReader(id).stream()
.map(x -> new ReaderMangaDto(x))
.toList());
return "mangaPage";
}
}

View File

@ -0,0 +1,68 @@
package com.LabWork.app.MangaStore.controller;
import com.LabWork.app.MangaStore.model.Dto.ReaderMangaDto;
import com.LabWork.app.MangaStore.model.Dto.SupportDto.MangaDto;
import com.LabWork.app.MangaStore.service.ReaderService;
import com.LabWork.app.MangaStore.service.MangaService;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Base64;
@Controller
@RequestMapping("/readerAction")
public class ReaderActionMvcController {
private final ReaderService readerService;
private static final Logger log = LoggerFactory.getLogger(ReaderActionMvcController.class);
private final MangaService mangaService;
public ReaderActionMvcController(ReaderService readerService, MangaService mangaService) {
this.readerService = readerService;
this.mangaService = mangaService;
}
@GetMapping
public String getReaders(Model model) {
model.addAttribute("readers",
readerService.findAllReaders().stream()
.map(ReaderMangaDto::new)
.toList());
model.addAttribute("readerId", 0);
return "readerAction";
}
@GetMapping("/{id}")
public String getReader(@PathVariable Long id, Model model) {
model.addAttribute("reader", new ReaderMangaDto(readerService.findReader(id)));
model.addAttribute("mangaId", id);
model.addAttribute("MangaDto", new MangaDto());
model.addAttribute("mangaList", mangaService.findAllMangas());
return "readerAction";
}
@PostMapping("/{readerId}/manga")
public String saveManga(@PathVariable Long readerId, @RequestParam("mangaId") Long mangaId,
@ModelAttribute @Valid MangaDto MangaDto,
BindingResult bindingResult,
Model model) throws IOException {
/* if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "readerAction-edit";
}*/
readerService.addManga(mangaId, readerId);
return "redirect:/readerAction/1";
}
@PostMapping("/{id}/removeManga/{mangaId}")
public String removeManga(@PathVariable Long id, @PathVariable Long mangaId) {
readerService.removeManga(mangaId, id);
return "redirect:/readerAction/1";
}
}

View File

@ -1,63 +0,0 @@
package com.LabWork.app.MangaStore.controller;
import com.LabWork.app.MangaStore.model.Dto.ReaderMangaDto;
import com.LabWork.app.MangaStore.service.ReaderService;
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("/reader")
public class ReaderMvcController {
private final ReaderService readerService;
public ReaderMvcController(ReaderService readerService) {
this.readerService = readerService;
}
@GetMapping
public String getReaders(Model model) {
model.addAttribute("readers",
readerService.findAllReaders().stream()
.map(ReaderMangaDto::new)
.toList());
return "reader";
}
@GetMapping(value = {"/edit", "/edit/{id}"})
public String editReader(@PathVariable(required = false) Long id,
Model model) {
if (id == null || id <= 0) {
model.addAttribute("ReaderMangaDto", new ReaderMangaDto());
} else {
model.addAttribute("readerId", id);
model.addAttribute("ReaderMangaDto", new ReaderMangaDto(readerService.findReader(id)));
}
return "reader-edit";
}
@PostMapping(value = {"", "/{id}"})
public String saveReader(@PathVariable(required = false) Long id,
@ModelAttribute @Valid ReaderMangaDto readerMangaDto,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "reader-edit";
}
if (id == null || id <= 0) {
readerService.addReader(readerMangaDto.getReaderName(), readerMangaDto.getHashedPassword());
} else {
readerService.updateReader(id, readerMangaDto.getReaderName(), readerMangaDto.getHashedPassword());
}
return "redirect:/reader";
}
@PostMapping("/delete/{id}")
public String deleteReader(@PathVariable Long id) {
readerService.deleteReader(id);
return "redirect:/reader";
}
}

View File

@ -54,10 +54,6 @@ public class ReaderService {
return currentReader; return currentReader;
} }
public void addManga(Long readerId, List<Manga> mangas) {
readerRepository.findById(readerId).get().setMangas(mangas);
}
@Transactional @Transactional
public Reader deleteReader(Long id) { public Reader deleteReader(Long id) {
final Reader currentReader = findReader(id); final Reader currentReader = findReader(id);

View File

@ -105,3 +105,7 @@ th {
max-width:180px; max-width:180px;
border-radius: 7%; border-radius: 7%;
} }
.table > :not(:first-child) {
border-top: 0;
}

View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<article class="p-2 catalog_article">
<div class = "catalog_wrapper">
<h1>Каталог</h1>
<div class="p-2 d-flex flex-wrap">
<a th:each="manga: ${mangaList}" th:href="@{/manga/{id}(id=${manga.id})}"><img th:src="@{'data:image/jpeg;base64,' + ${manga.image}}" class="slideshow"/></a>
</div>
</div>
</article>
</div>
</body>
</html>

View File

@ -24,7 +24,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr th:each="creator, iterator: ${creators}"> <tr th:each="creator: ${creators}">
<td th:text="${creator.id}"/> <td th:text="${creator.id}"/>
<td th:text="${creator.creatorName}"/> <td th:text="${creator.creatorName}"/>
<td th:text="${creator.hashedPassword}"/> <td th:text="${creator.hashedPassword}"/>

View File

@ -18,7 +18,7 @@
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="image" class="form-label">image</label> <label for="image" class="form-label">image</label>
<input type="file" id="image" name="image" accept="image/png, image/jpeg" /> <input type="file" id="image" name="image" accept="image/png, image/jpeg" class="form-control" th:value="@{'data:image/jpeg;base64,' + ${MangaDto.image}}"/>
<!--<input id="image" type="file" name="image" class="form-control text-white" accept="image/png, image/jpeg" th:field="${MangaDto.image}" required="true"/>--> <!--<input id="image" type="file" name="image" class="form-control text-white" accept="image/png, image/jpeg" th:field="${MangaDto.image}" required="true"/>-->
</div> </div>
<div class="mb-3"> <div class="mb-3">

View File

@ -22,7 +22,7 @@
<div class="row table-responsive text-white"> <div class="row table-responsive text-white">
<div th:each="manga, iterator: ${creator?.mangas}" class="d-flex flex-row flex-wrap flex-grow-1 align-items-center mt-3"> <div th:each="manga, iterator: ${creator?.mangas}" class="d-flex flex-row flex-wrap flex-grow-1 align-items-center mt-3">
<div class="me-3"> <div class="me-3">
<a th:href="@{/mangapage/{id}(id=${manga.id})}"><img th:src="@{'data:image/jpeg;base64,' + ${manga.image}}" th:alt="${manga.mangaName}" class="slideshow"/></a> <a th:href="@{/manga/{id}(id=${manga.id})}"><img th:src="@{'data:image/jpeg;base64,' + ${manga.image}}" th:alt="${manga.mangaName}" class="slideshow"/></a>
</div> </div>
<div> <div>
<div class="pt-3 description d-flex flex-column justify-content-start mb-3 fs-6 fw-bold"> <div class="pt-3 description d-flex flex-column justify-content-start mb-3 fs-6 fw-bold">
@ -37,8 +37,6 @@
<i class="fas fa-edit"></i> <i class="fas fa-edit"></i>
</a> </a>
</button> </button>
<button class="delete bg-danger p-2 px-2 mx-2 border border-0 rounded text-white fw-bold" type="button">Удалить</button>
<button type="button" class="delete bg-danger p-2 px-2 mx-2 border border-0 rounded text-white fw-bold" <button type="button" class="delete bg-danger p-2 px-2 mx-2 border border-0 rounded text-white fw-bold"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${manga.id}').click()|"> th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${manga.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить <i class="fa fa-trash" aria-hidden="true"></i> Удалить

View File

@ -30,8 +30,8 @@
<a class="nav-link" th:href="@{/creator}">Creator</a> <a class="nav-link" th:href="@{/creator}">Creator</a>
<a class="nav-link" href="/reader">Reader</a> <a class="nav-link" href="/reader">Reader</a>
<a class="nav-link" href="/creatorAction/1">CreatorAction</a> <a class="nav-link" href="/creatorAction/1">CreatorAction</a>
<a class="nav-link" href="/readerAction">ReaderAction</a> <a class="nav-link" href="/readerAction/1">ReaderAction</a>
<a class="nav-link" href="/catalog">Catalog</a> <a class="nav-link" href="/manga">Catalog</a>
<a class="nav-link" href="/mangaPage">MangaPage</a> <a class="nav-link" href="/mangaPage">MangaPage</a>
<a class="nav-link" href="/swagger-ui/index.html" target="_blank">Документация REST API</a> <a class="nav-link" href="/swagger-ui/index.html" target="_blank">Документация REST API</a>
<a class="nav-link" href="/h2-console/" target="_blank">Консоль H2</a> <a class="nav-link" href="/h2-console/" target="_blank">Консоль H2</a>

View File

@ -0,0 +1,57 @@
<!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 class="container d-flex" >
<div class="d-flex flex-column">
<img class="img_style01" style={{borderRadius:"3%"}} th:src="@{'data:image/jpeg;base64,' + ${manga.image}}" th:alt="${manga.mangaName}"/>
</div>
<div class="container table text-white fs-4 ms-4">
<div class="row text-white fw-bold fs-3">О манге</div>
<div class="row">
<div class="col-xs-6 col-sm-3">Год производства</div>
<div class="col-xs-6 col-sm-3">1000</div>
</div>
<div class="row">
<div class="col-xs-6 col-sm-3">Страна</div>
<div class="col-xs-6 col-sm-3">Россия</div>
</div>
<div class="row">
<div class="col-xs-6 col-sm-3">Жанр</div>
<div class="col-xs-6 col-sm-3">Драма</div>
</div>
<div class="row">
<div class="col-xs-6 col-sm-3">Количество глав</div>
<div class="col-xs-6 col-sm-3" th:text="${manga.chapterCount}"></div>
</div>
<div class="row">
<div class="col-xs-6 col-sm-3">Возраст</div>
<div class="col-xs-6 col-sm-3">16+</div>
</div>
<div class="row text-white fw-bold fs-3">Описание</div>
<div class="row">
<div class="col-xs-6 col-sm-12">
<p>Ким Кон Чжа спокойно живет в своей халупе, завидуя всем популярным охотникам. Однажды его желание быть лучше всех сбывается и он получает легендарный навык “Копирование способностей”... ценой своей жизни.</p>
<p>Прежде чем он успевает понять это, его убивает охотник №1, Летний дух! Но это активирует его навык, и теперь он скопировал новый, “Путешествие во времени после смерти”.</p>
<p>Как Ким Кон Чжа же будет использовать эти навыки, чтобы победить конкурентов и подняться на вершину?</p>
</div>
</div>
<div class="row table-responsive text-white">
<div th:each="reader: ${readers}" class="d-flex flex-row flex-wrap flex-grow-1 align-items-center mt-3">
<div>
<div class="pt-3 description mb-3 fs-6 fw-bold">
Имя пользователя:
<a th:href="@{/readerAction/{id}(id=${reader.id})}" th:text="${reader.readerName}"></a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,85 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
xmlns:th="http://www.thymeleaf.org"
layout:decorate="~{default}">
<head>
</head>
<body>
<div class="container" id="root-div" layout:fragment="content">
<div class="content">
<h1>Reader</h1>
<div class="d-flex mt-3">
<div class="d-grid col-sm-2">
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
<form action="#" th:action="@{/readerAction/1/manga}" enctype="multipart/form-data" method="post">
<div class="mb-3">
<label for="mangaId" class="form-label">Манга</label>
<select th:name="mangaId" id="mangaId" class="form-select">
<option th:each="manga: ${mangaList}" th:value="${manga.id}" th:text="${manga.mangaName}"/>
</select>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary button-fixed">
<i class="fa-solid fa-plus">Добавить</i>
</button>
</div>
</form>
</div>
</div>
<div class="row table-responsive text-white">
<div th:each="manga: ${reader?.mangas}" class="d-flex flex-row flex-wrap flex-grow-1 align-items-center mt-3">
<div class="me-3">
<a th:href="@{/manga/{id}(id=${manga.id})}"><img th:src="@{'data:image/jpeg;base64,' + ${manga.image}}" th:alt="${manga.mangaName}" class="slideshow"/></a>
</div>
<div>
<div class="pt-3 description d-flex flex-column justify-content-start mb-3 fs-6 fw-bold">
<h4>Название манги: <a class="text-white fs-5 unic_class fw-bold pt-3 mb-3" th:href="@{/mangapage/{id}(id=${manga.id})}" th:text="${manga.mangaName}"></a></h4>
<h4>
Количество глав:
<span th:text="${manga.chapterCount}"/>
</h4>
</div>
<div>
</button>
<button type="button" class="delete bg-danger p-2 px-2 mx-2 border border-0 rounded text-white fw-bold"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${manga.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
<form th:action="@{/readerAction/1/removeManga/{id}(id=${manga.id})}" method="post">
<button th:id="'remove-' + ${manga.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<!--<th:block layout:fragment="scripts">
<script>
let buttonAdd = document.getElementById("buttonAdd");
let selectReaderId = document.getElementById("readerId");
const host = "http://localhost:8080";
buttonAdd.addEventListener('click', function (event){
event.preventDefault();
create(selectReaderId.value);
});
const create = async function (readerId) {
const requestParams = {
method: "POST",
headers: {
"Content-Type": "application/json",
}
};
console.log(readerId);
const response = await fetch(host + `/readerAction?readerId=${readerId}`, requestParams);
return await response.json();
}
</script>
</th:block>-->
</html>