diff --git a/data.mv.db b/data.mv.db index 30e75a1..5496080 100644 Binary files a/data.mv.db and b/data.mv.db differ diff --git a/frontend/Mangs.html b/frontend/Mangs.html new file mode 100644 index 0000000..cdabd1c --- /dev/null +++ b/frontend/Mangs.html @@ -0,0 +1,71 @@ + + + + + + + + + Mangs + + +
+ +
+

Manga

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + +
#mangaNamechapterCountcreatorIdreaders
+
+
+
+ + + diff --git a/frontend/Readers.html b/frontend/Readers.html new file mode 100644 index 0000000..0b8ce25 --- /dev/null +++ b/frontend/Readers.html @@ -0,0 +1,76 @@ + + + + + + + + + Readers + + +
+ +
+

Reader

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ + + + + + + + + + + +
#readerNamehashedPasswordmangs
+
+
+
+ + + diff --git a/frontend/build.gradle b/frontend/build.gradle new file mode 100644 index 0000000..5af1aa0 --- /dev/null +++ b/frontend/build.gradle @@ -0,0 +1,58 @@ +import com.github.gradle.node.util.PlatformHelper +import groovy.text.SimpleTemplateEngine + +plugins { + id 'java' + id 'com.github.node-gradle.node' version '3.5.1' + id "de.undercouch.download" version '5.3.1' +} + +node { + version = '18.15.0' + download = true +} + +jar.dependsOn 'npmBuild' + +clean.dependsOn 'npmClean' + +nodeSetup.dependsOn 'downloadNode' + +jar { + from 'dist' + into 'static' + final devHost = 'http://localhost:8080' + final prodHost = '' + filesMatching('index.html') { + filter { line -> line.replaceAll(devHost, prodHost) } + } +} + +task downloadNode(type: Download) { + final helper = new PlatformHelper() + final templateData = [ + "url" : node.distBaseUrl.get(), + "version": node.version.get(), + "os" : helper.osName, + "arch" : helper.osArch, + "ext" : helper.windows ? 'zip' : 'tar.gz' + ] + final urlTemplate = '${url}/v${version}/node-v${version}-${os}-${arch}.${ext}' + final engine = new SimpleTemplateEngine() + final url = engine.createTemplate(urlTemplate).make(templateData).toString() + final String destDir = '.gradle/' + file(destDir).mkdirs() + src url + dest destDir + overwrite false +} + +tasks.register('npmBuild', NpmTask) { + dependsOn npmInstall + args = ['run-script', 'build'] +} + +tasks.register('npmClean', NpmTask) { + dependsOn npmInstall + args = ['run-script', 'clean'] +} diff --git a/frontend/index.html b/frontend/index.html index 62358bb..c598b55 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,27 +1,24 @@ - - - - - - - + + + + + Main -
-
-
- Creator - Manga - Reader -
-
+
+

Creator

-
+
@@ -37,29 +34,32 @@
- -
- + +
-
- - - -
+
+
+ +
+
+ +
+
+ +
+
+ +
+
- - + + + @@ -68,6 +68,6 @@ - + diff --git a/frontend/scriptCreator.js b/frontend/scriptCreator.js new file mode 100644 index 0000000..f300c89 --- /dev/null +++ b/frontend/scriptCreator.js @@ -0,0 +1,127 @@ +"use strict"; + +window.addEventListener('DOMContentLoaded', function () { + const host = "http://localhost:8080"; + const table = document.getElementById("tbody"); + const form = document.getElementById("form"); + const creatorIdInput = document.getElementById("creatorId"); + const mangaIdInput = document.getElementById("mangaId"); + const creatorNameInput = document.getElementById("creatorName"); + const passwordInput = document.getElementById("password"); + const buttonRemove = document.getElementById("btnRemove"); + const buttonUpdate = document.getElementById("btnUpdate");btnRemoveAll + const buttonRemoveAll = document.getElementById("btnRemoveAll"); + const getData = async function () { + table.innerHTML = ""; + const response = await fetch(host + "/creator"); + const data = await response.json(); + console.log(data); + data.forEach(Creator => { + let temp = "" + table.innerHTML += + ` + + + + + `; + }) + } + + const create = async function (creatorName, password) { + const requestParams = { + method: "POST", + headers: { + "Content-Type": "application/json", + } + }; + const response = await fetch(host + `/creator?creatorName=${creatorName}&password=${password}`, requestParams); + return await response.json(); + } + + const remove = async function (){ + console.info('Try to remove item'); + if (creatorIdInput.value !== 0) { + if (!confirm('Do you really want to remove this item?')) { + console.info('Canceled'); + return; + } + } + const requestParams = { + method: "DELETE", + headers: { + "Content-Type": "application/json", + } + }; + const response = await fetch(host + `/creator/` + creatorIdInput.value, requestParams); + return await response.json(); + } + + const removeAll = async function (){ + console.info('Try to remove item'); + if (!confirm('Do you really want to remove this item?')) { + console.info('Canceled'); + return; + } + const requestParams = { + method: "DELETE", + }; + await fetch(host + `/creator/`, requestParams); + } + + const update = async function (){ + console.info('Try to update item'); + if (creatorIdInput.value === 0 || creatorNameInput.value == null || passwordInput.value === 0) { + return; + } + const requestParams = { + method: "PUT", + headers: { + "Content-Type": "application/json", + } + }; + const response = await fetch(host + `/creator/${creatorIdInput.value}?creatorName=${creatorNameInput.value}&password=${passwordInput.value}`, requestParams); + return await response.json(); + } + + buttonRemove.addEventListener('click', function (event){ + event.preventDefault(); + remove().then((result) => { + getData() + creatorIdInput.value = ""; + }); + }); + buttonRemoveAll.addEventListener('click', function (event){ + event.preventDefault(); + removeAll().then(() => { + getData() + }); + }); + + buttonUpdate.addEventListener('click', function (event){ + event.preventDefault(); + update().then((result) => { + getData() + creatorIdInput.value = ""; + passwordInput.value = ""; + creatorNameInput.value = ""; + }); + }); + + form.addEventListener("submit", function (event) { + event.preventDefault(); + create(creatorNameInput.value, passwordInput.value).then((result) => { + getData(); + creatorNameInput.value = ""; + passwordInput.value = ""; + console.log(result); + alert(`Creator[id=${result.id}, creatorNameInput=${result.creatorName}, passwordInput=${result.hashedPassword}]`); + }); + }); + + getData(); +}); \ No newline at end of file diff --git a/frontend/scriptManga.js b/frontend/scriptManga.js new file mode 100644 index 0000000..125c774 --- /dev/null +++ b/frontend/scriptManga.js @@ -0,0 +1,112 @@ +"use strict"; + +window.addEventListener('DOMContentLoaded', function () { + const host = "http://localhost:8080"; + const table = document.getElementById("tbody"); + const form = document.getElementById("form"); + const creatorIdInput = document.getElementById("creatorId"); + const mangaIdInput = document.getElementById("mangaId"); + const mangaNameInput = document.getElementById("mangaName"); + const chapterCountInput = document.getElementById("chapterCount"); + const buttonRemove = document.getElementById("btnRemove"); + const buttonUpdate = document.getElementById("btnUpdate"); + const getData = async function () { + table.innerHTML = ""; + const response = await fetch(host + "/manga"); + const data = await response.json(); + console.log(data); + data.forEach(Manga => { + let temp = "" + table.innerHTML += + ` + + + + + + `; + }) + } + + const create = async function (creatorId, chapterCount, mangaName) { + const requestParams = { + method: "POST", + headers: { + "Content-Type": "application/json", + } + }; + console.log(creatorId); + console.log(chapterCount); + console.log(mangaName); + const response = await fetch(host + `/manga?creatorId=${creatorId}&chapterCount=${chapterCount}&mangaName=${mangaName}`, requestParams); + return await response.json(); + } + + const remove = async function (){ + console.info('Try to remove item'); + if (mangaIdInput.value !== 0) { + if (!confirm('Do you really want to remove this item?')) { + console.info('Canceled'); + return; + } + } + const requestParams = { + method: "DELETE", + headers: { + "Content-Type": "application/json", + } + }; + const response = await fetch(host + `/manga/` + mangaIdInput.value, requestParams); + return await response.json(); + } + + const update = async function (){ + console.info('Try to update item'); + if (mangaIdInput.value === 0 || chapterCountInput.value === null) { + return; + } + const requestParams = { + method: "PUT", + headers: { + "Content-Type": "application/json", + } + }; + const response = await fetch(host + `/manga/${mangaIdInput.value}?chapterCount=${chapterCountInput.value}`, requestParams); + return await response.json(); + } + + buttonRemove.addEventListener('click', function (event){ + event.preventDefault(); + remove().then((result) => { + getData() + mangaIdInput.value = ""; + }); + }); + + buttonUpdate.addEventListener('click', function (event){ + event.preventDefault(); + update().then((result) => { + getData() + mangaIdInput.value = ""; + chapterCountInput.value = ""; + }); + }); + + form.addEventListener("submit", function (event) { + event.preventDefault(); + create(creatorIdInput.value, chapterCountInput.value, mangaNameInput.value).then((result) => { + getData(); + mangaIdInput.value = ""; + creatorIdInput.value = ""; + chapterCountInput.value = ""; + mangaNameInput.value = ""; + alert(`Manga[id=${result.id}, mangaName=${result.mangaName}, chapterCount=${result.chapterCount}, chapterCount=${result.chapterCount}]`); + }); + }); + + getData(); +}); \ No newline at end of file diff --git a/frontend/scriptReader.js b/frontend/scriptReader.js new file mode 100644 index 0000000..845bf8c --- /dev/null +++ b/frontend/scriptReader.js @@ -0,0 +1,158 @@ +"use strict"; + +window.addEventListener('DOMContentLoaded', function () { + const host = "http://localhost:8080"; + const table = document.getElementById("tbody"); + const form = document.getElementById("form"); + const readerIdInput = document.getElementById("readerId"); + const mangaIdInput = document.getElementById("mangaId"); + const readerNameInput = document.getElementById("readerName"); + const hashedPasswordInput = document.getElementById("hashedPassword"); + const buttonRemove = document.getElementById("btnRemove"); + const buttonUpdate = document.getElementById("btnUpdate"); + const buttonRemoveManga = document.getElementById("btnRemoveManga"); + const buttonAddManga = document.getElementById("btnAddManga"); + const getData = async function () { + table.innerHTML = ""; + const response = await fetch(host + "/reader"); + const data = await response.json(); + console.log(data); + data.forEach(Reader => { + let temp = "" + table.innerHTML += + ` + + + + + `; + }) + } + + const create = async function (readerName, hashedPassword) { + const requestParams = { + method: "POST", + headers: { + "Content-Type": "application/json", + } + }; + console.log(host + `/reader?readerName=${readerName}&password=${hashedPassword}`, requestParams); + console.log(readerName); + const response = await fetch(host + `/reader?readerName=${readerName}&password=${hashedPassword}`, requestParams); + console.log(readerName); + return await response.json(); + } + + const addManga = async function () { + const requestParams = { + method: "PUT", + headers: { + "Content-Type": "application/json", + } + }; + console.log(host + `/reader/${readerIdInput.value}/addManga?mangaId=${mangaIdInput.value}`, requestParams); + const response = await fetch(host + `/reader/${readerIdInput.value}/addManga?mangaId=${mangaIdInput.value}`, requestParams); + return await response.json(); + } + + const remove = async function (){ + console.info('Try to remove item'); + if (readerIdInput.value !== 0) { + if (!confirm('Do you really want to remove this item?')) { + console.info('Canceled'); + return; + } + } + const requestParams = { + method: "DELETE", + headers: { + "Content-Type": "application/json", + } + }; + const response = await fetch(host + `/reader/` + readerIdInput.value, requestParams); + return await response.json(); + } + + const removeManga = async function (){ + console.info('Try to remove item'); + if (!confirm('Do you really want to remove this item?')) { + console.info('Canceled'); + return; + } + const requestParams = { + method: "PUT", + headers: { + "Content-Type": "application/json", + } + }; + console.log(host + `/reader/${readerIdInput.value}/removeManga?mangaId=${mangaIdInput.value}`, requestParams); + const response = await fetch(host + `/reader/${readerIdInput.value}/removeManga?mangaId=${mangaIdInput.value}`, requestParams); + return await response.json(); + } + + const update = async function (){ + console.info('Try to update item'); + if (readerIdInput.value === 0 || hashedPasswordInput.value === null) { + return; + } + const requestParams = { + method: "PUT", + headers: { + "Content-Type": "application/json", + } + }; + const response = await fetch(host + `/reader/${readerIdInput.value}?readerName=${readerNameInput.value}&password=${hashedPasswordInput.value}`, requestParams); + return await response.json(); + } + + buttonRemove.addEventListener('click', function (event){ + event.preventDefault(); + remove().then((result) => { + getData() + readerIdInput.value = ""; + }); + }); + + buttonRemoveManga.addEventListener('click', function (event){ + event.preventDefault(); + removeManga().then((result) => { + getData() + mangaIdInput.value = ""; + }); + }); + + buttonAddManga.addEventListener('click', function (event){ + event.preventDefault(); + addManga().then((result) => { + getData() + mangaIdInput.value = ""; + }); + }); + + buttonUpdate.addEventListener('click', function (event){ + event.preventDefault(); + update().then((result) => { + getData() + readerIdInput.value = ""; + hashedPasswordInput.value = ""; + }); + }); + + form.addEventListener("submit", function (event) { + event.preventDefault(); + console.log(readerNameInput.value); + create(readerNameInput.value, hashedPasswordInput.value).then((result) => { + console.log(readerNameInput.value); + getData(); + hashedPasswordInput.value = ""; + readerIdInput.value = ""; + alert(`Reader[id=${result.id}, readerName=${result.readerName}, password=${result.hashedPassword}]`); + }); + }); + + getData(); +}); \ No newline at end of file diff --git a/src/main/java/com/LabWork/app/MangaStore/controller/CreatorController.java b/src/main/java/com/LabWork/app/MangaStore/controller/CreatorController.java index 15b8aa1..2f6ed4b 100644 --- a/src/main/java/com/LabWork/app/MangaStore/controller/CreatorController.java +++ b/src/main/java/com/LabWork/app/MangaStore/controller/CreatorController.java @@ -42,6 +42,12 @@ public class CreatorController { @DeleteMapping("/{id}") public CreatorDto deleteCreator(@PathVariable Long id) { + //creatorService.deleteAllCreators(); return new CreatorDto(creatorService.deleteCreator(id)); } + + @DeleteMapping + public void deleteAllCreator() { + creatorService.deleteAllCreators(); + } } diff --git a/src/main/java/com/LabWork/app/MangaStore/controller/MangaController.java b/src/main/java/com/LabWork/app/MangaStore/controller/MangaController.java index fd146ae..815f378 100644 --- a/src/main/java/com/LabWork/app/MangaStore/controller/MangaController.java +++ b/src/main/java/com/LabWork/app/MangaStore/controller/MangaController.java @@ -38,7 +38,7 @@ public class MangaController { @PutMapping("/{id}") public MangaDto updateManga(@PathVariable Long id, - @RequestParam("chapterCount") Integer chapterCount) { + @RequestParam("chapterCount") Integer chapterCount) { return new MangaDto(mangaService.updateManga(id, chapterCount)); } diff --git a/src/main/java/com/LabWork/app/MangaStore/controller/ReaderController.java b/src/main/java/com/LabWork/app/MangaStore/controller/ReaderController.java index 73eb082..5b7a76f 100644 --- a/src/main/java/com/LabWork/app/MangaStore/controller/ReaderController.java +++ b/src/main/java/com/LabWork/app/MangaStore/controller/ReaderController.java @@ -41,15 +41,15 @@ public class ReaderController { return new ReaderDto(readerService.updateReader(id, readerName, password)); } - @PostMapping("/{id}/manga/{manga_id}") + @PutMapping("/{id}/addManga") public ReaderDto addManga(@PathVariable Long id, - @PathVariable Long mangaId) { + @RequestParam("mangaId") Long mangaId) { return new ReaderDto(readerService.addManga(mangaId, id)); } - @PutMapping("/{id}/manga/{manga_id}") + @PutMapping("/{id}/removeManga") public ReaderDto removeManga(@PathVariable Long id, - @PathVariable Long mangaId) { + @RequestParam("mangaId") Long mangaId) { return new ReaderDto(readerService.removeManga(mangaId, id)); } diff --git a/src/main/java/com/LabWork/app/MangaStore/model/Default/Manga.java b/src/main/java/com/LabWork/app/MangaStore/model/Default/Manga.java index c1423ab..4cdeb2b 100644 --- a/src/main/java/com/LabWork/app/MangaStore/model/Default/Manga.java +++ b/src/main/java/com/LabWork/app/MangaStore/model/Default/Manga.java @@ -42,6 +42,10 @@ public class Manga { return id; } + public Long getCreatorId() { + return creator.getId(); + } + public String getMangaName() { return mangaName; } diff --git a/src/main/java/com/LabWork/app/MangaStore/model/Dto/CreatorDto.java b/src/main/java/com/LabWork/app/MangaStore/model/Dto/CreatorDto.java index 625a3df..8b6436d 100644 --- a/src/main/java/com/LabWork/app/MangaStore/model/Dto/CreatorDto.java +++ b/src/main/java/com/LabWork/app/MangaStore/model/Dto/CreatorDto.java @@ -3,18 +3,21 @@ package com.LabWork.app.MangaStore.model.Dto; import com.LabWork.app.MangaStore.model.Default.Creator; import com.LabWork.app.MangaStore.model.Default.Manga; import java.util.List; +import java.util.Objects; public class CreatorDto { private final long id; private final String creatorName; private final String hashedPassword; - private final List mangas; + private final List mangas; public CreatorDto(Creator creator) { this.id = creator.getId(); this.creatorName = creator.getCreatorName(); this.hashedPassword = creator.getHashedPassword(); - this.mangas = creator.getMangas(); + this.mangas = creator.getMangas().stream() + .map(y -> new MangaDto(y)) + .toList(); } public long getId() { @@ -29,5 +32,5 @@ public class CreatorDto { return hashedPassword; } - public List getMangas() { return mangas; } + public List getMangas() { return mangas; } } diff --git a/src/main/java/com/LabWork/app/MangaStore/model/Dto/MangaDto.java b/src/main/java/com/LabWork/app/MangaStore/model/Dto/MangaDto.java index 959d867..fffdbe4 100644 --- a/src/main/java/com/LabWork/app/MangaStore/model/Dto/MangaDto.java +++ b/src/main/java/com/LabWork/app/MangaStore/model/Dto/MangaDto.java @@ -4,23 +4,26 @@ import com.LabWork.app.MangaStore.model.Default.Creator; import com.LabWork.app.MangaStore.model.Default.Manga; import com.LabWork.app.MangaStore.model.Default.Reader; import java.util.List; +import java.util.Objects; public class MangaDto { private final Long id; - private final Creator creator; + private final Long creatorId; private final String mangaName; private final Integer chapterCount; - private final List readers; + private final List readers; public MangaDto(Manga manga) { this.id = manga.getId(); - this.creator = manga.getCreator(); + this.creatorId = manga.getCreator().getId(); this.mangaName = manga.getMangaName(); this.chapterCount = manga.getChapterCount(); - this.readers = manga.getReaders(); + this.readers = manga.getReaders().stream() + .map(y -> new String(y.getReaderName())) + .toList(); } public Long getId() { @@ -35,11 +38,11 @@ public class MangaDto { return chapterCount; } - public Creator getCreator() { - return creator; + public Long getCreatorId() { + return creatorId; } - public List getReaders() { + public List getReaders() { return readers; } diff --git a/src/main/java/com/LabWork/app/MangaStore/model/Dto/ReaderDto.java b/src/main/java/com/LabWork/app/MangaStore/model/Dto/ReaderDto.java index 65e604b..a343a50 100644 --- a/src/main/java/com/LabWork/app/MangaStore/model/Dto/ReaderDto.java +++ b/src/main/java/com/LabWork/app/MangaStore/model/Dto/ReaderDto.java @@ -3,6 +3,7 @@ package com.LabWork.app.MangaStore.model.Dto; import com.LabWork.app.MangaStore.model.Default.Manga; import com.LabWork.app.MangaStore.model.Default.Reader; import java.util.List; +import java.util.Objects; public class ReaderDto { private Long id; @@ -11,13 +12,15 @@ public class ReaderDto { private String hashedPassword; - private List mangas; + private List mangas; public ReaderDto(Reader reader) { this.id = reader.getId(); this.readerName = reader.getReaderName(); this.hashedPassword = reader.getHashedPassword(); - this.mangas = reader.getMangas(); + this.mangas = reader.getMangas().stream() + .map(y -> new String(y.getMangaName())) + .toList(); } public Long getId() { @@ -28,6 +31,6 @@ public class ReaderDto { public String getHashedPassword() { return hashedPassword; } - public List getMangas() { return mangas; } + public List getMangas() { return mangas; } } diff --git a/src/test/java/com/LabWork/app/ReMangaTest.java b/src/test/java/com/LabWork/app/ReMangaTest.java index e122fcd..7af7b7c 100644 --- a/src/test/java/com/LabWork/app/ReMangaTest.java +++ b/src/test/java/com/LabWork/app/ReMangaTest.java @@ -41,6 +41,22 @@ public class ReMangaTest { creatorService.deleteAllCreators(); } + @Test + void test() { + readerService.deleteAllReaders(); + mangaService.deleteAllMangas(); + creatorService.deleteAllCreators(); + Creator c1 = creatorService.addCreator("first", "1"); + Manga m1 = mangaService.addManga(c1.getId(), 0, "Vagabond"); + Manga m2 = mangaService.addManga(c1.getId(), 10, "Berserk"); + Manga m3 = mangaService.addManga(c1.getId(), 0, "Manga_3"); + Creator c2 = creatorService.findCreator(c1.getId()); + Assertions.assertEquals(3, c2.getMangas().size()); + readerService.deleteAllReaders(); + mangaService.deleteAllMangas(); + creatorService.deleteAllCreators(); + } + /* @Test void testCreatorAddManga() { readerService.deleteAllReaders();
#creatorNamepasswordCreatorNamePasswordMangs
${Creator.id}${Creator.creatorName}${Creator.hashedPassword}${temp}
${Manga.id}${Manga.mangaName}${Manga.chapterCount}${Manga.creatorId}${temp}
${Reader.id}${Reader.readerName}${Reader.hashedPassword}${temp}