From 49b8125146a25a8b6eafdfe3c88e14d83a553330 Mon Sep 17 00:00:00 2001 From: "ityurner02@mail.ru" Date: Tue, 25 Apr 2023 13:06:29 +0400 Subject: [PATCH] =?UTF-8?q?=D0=9B=D0=A04=20=D0=B1=D0=B5=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B1=D1=8D=D0=BA=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/CatalogGenres.vue | 46 ++++++++ .../vue-project/src/components/Catalogs.vue | 23 ++++ .../vue-project/src/components/DataTable.vue | 70 ++++++++++++ .../vue-project/src/components/Header.vue | 3 + Frontend/vue-project/src/components/Modal.vue | 63 +++++++++++ Frontend/vue-project/src/components/Table.vue | 9 ++ .../vue-project/src/components/ToolBar.vue | 46 ++++++++ Frontend/vue-project/src/main.js | 10 +- .../vue-project/src/mixins/CatalogMixins.js | 102 ++++++++++++++++++ Frontend/vue-project/src/models/Collection.js | 26 +++++ Frontend/vue-project/src/models/Film.js | 26 +++++ Frontend/vue-project/src/models/Genre.js | 21 ++++ .../vue-project/src/services/DataService.js | 42 ++++++++ data.mv.db | Bin 40960 -> 40960 bytes .../DataBase/controller/GenreController.java | 1 - .../DataBase/service/CollectionService.java | 1 - 16 files changed, 485 insertions(+), 4 deletions(-) create mode 100644 Frontend/vue-project/src/components/CatalogGenres.vue create mode 100644 Frontend/vue-project/src/components/Catalogs.vue create mode 100644 Frontend/vue-project/src/components/DataTable.vue create mode 100644 Frontend/vue-project/src/components/Modal.vue create mode 100644 Frontend/vue-project/src/components/Table.vue create mode 100644 Frontend/vue-project/src/components/ToolBar.vue create mode 100644 Frontend/vue-project/src/mixins/CatalogMixins.js create mode 100644 Frontend/vue-project/src/models/Collection.js create mode 100644 Frontend/vue-project/src/models/Film.js create mode 100644 Frontend/vue-project/src/models/Genre.js create mode 100644 Frontend/vue-project/src/services/DataService.js diff --git a/Frontend/vue-project/src/components/CatalogGenres.vue b/Frontend/vue-project/src/components/CatalogGenres.vue new file mode 100644 index 0000000..f29daf6 --- /dev/null +++ b/Frontend/vue-project/src/components/CatalogGenres.vue @@ -0,0 +1,46 @@ + + + \ No newline at end of file diff --git a/Frontend/vue-project/src/components/Catalogs.vue b/Frontend/vue-project/src/components/Catalogs.vue new file mode 100644 index 0000000..b95dcad --- /dev/null +++ b/Frontend/vue-project/src/components/Catalogs.vue @@ -0,0 +1,23 @@ + + + \ No newline at end of file diff --git a/Frontend/vue-project/src/components/DataTable.vue b/Frontend/vue-project/src/components/DataTable.vue new file mode 100644 index 0000000..036f145 --- /dev/null +++ b/Frontend/vue-project/src/components/DataTable.vue @@ -0,0 +1,70 @@ + + + + + \ No newline at end of file diff --git a/Frontend/vue-project/src/components/Header.vue b/Frontend/vue-project/src/components/Header.vue index 225f150..01a052a 100644 --- a/Frontend/vue-project/src/components/Header.vue +++ b/Frontend/vue-project/src/components/Header.vue @@ -23,6 +23,9 @@ + diff --git a/Frontend/vue-project/src/components/Modal.vue b/Frontend/vue-project/src/components/Modal.vue new file mode 100644 index 0000000..f12c004 --- /dev/null +++ b/Frontend/vue-project/src/components/Modal.vue @@ -0,0 +1,63 @@ + + + + + \ No newline at end of file diff --git a/Frontend/vue-project/src/components/Table.vue b/Frontend/vue-project/src/components/Table.vue new file mode 100644 index 0000000..732105b --- /dev/null +++ b/Frontend/vue-project/src/components/Table.vue @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/Frontend/vue-project/src/components/ToolBar.vue b/Frontend/vue-project/src/components/ToolBar.vue new file mode 100644 index 0000000..0a21290 --- /dev/null +++ b/Frontend/vue-project/src/components/ToolBar.vue @@ -0,0 +1,46 @@ + + + + + \ No newline at end of file diff --git a/Frontend/vue-project/src/main.js b/Frontend/vue-project/src/main.js index 2281dd6..75e6397 100644 --- a/Frontend/vue-project/src/main.js +++ b/Frontend/vue-project/src/main.js @@ -6,15 +6,21 @@ import Player from './components/Player.vue' import Films from './components/Films.vue' import About_us from './components/About_us.vue' import Form from './components/Form.vue' +import Table from './components/Table.vue' +import Catalogs from './components/Catalogs.vue' +import CatalogGenres from './components/CatalogGenres.vue' const routes = [ { path: '/', redirect: '/index' }, - { path: '/index', component: Index }, + { path: '/index', component: Index}, { path: '/player', component: Player}, { path: '/films', component: Films}, { path: '/about_us', component: About_us}, - { path: '/form', component: Form} + { path: '/form', component: Form}, + { path: '/table', component: Table}, + { path: '/catalogs', component: Catalogs}, + { path: '/catalogs/genres', component: CatalogGenres} ] const router = createRouter({ diff --git a/Frontend/vue-project/src/mixins/CatalogMixins.js b/Frontend/vue-project/src/mixins/CatalogMixins.js new file mode 100644 index 0000000..4b493d2 --- /dev/null +++ b/Frontend/vue-project/src/mixins/CatalogMixins.js @@ -0,0 +1,102 @@ +import ToolBar from '../components/ToolBar.vue'; +import DataTable from '../components/DataTable.vue'; +import Modal from '../components/Modal.vue'; +import DataService from '../services/DataService'; + +const CatalogMixin = { + components: { + ToolBar, DataTable, Modal + }, + data() { + return { + getAllUrl: undefined, + dataUrl: undefined, + transformer: undefined, + headers: [], + items: [], + selectedItems: [], + modal: { + header: undefined, + confirm: undefined, + }, + modalShow: false, + data: undefined, + isEdit: false + } + }, + created() { + this.loadItems(); + }, + methods: { + loadItems() { + this.getItems(); + this.data = this.transformer(); + }, + getItems() { + DataService.readAll(this.getAllUrl, this.transformer) + .then(data => { + this.items = data; + }); + }, + showAddModal() { + this.isEdit = false; + this.data = this.transformer(); + this.modal.header = 'Добавление элемента'; + this.modal.confirm = 'Добавить'; + this.modalShow = true; + }, + showEditModal() { + if (this.selectedItems.length === 0) { + return; + } + this.showEditModalDblClick(this.selectedItems[0]); + }, + showEditModalDblClick(editId) { + DataService.read(this.dataUrl + "/" + editId, this.transformer) + .then(data => { + this.data = data; + this.isEdit = true; + this.modal.header = 'Редактирование элемента'; + this.modal.confirm = 'Сохранить'; + this.modalShow = true; + }); + }, + saveItem() { + if (!this.isEdit) { + DataService.create(this.dataUrl + "/", this.data) + .then(() => { + this.getItems(); + }); + } else { + DataService.update(this.dataUrl + "/" + this.data.id, this.data) + .then(() => { + this.getItems(); + }); + } + }, + removeSelectedItems() { + if (this.selectedItems.length === 0) { + return; + } + if (confirm('Удалить выбранные элементы?')) { + const promises = []; + const self = this; + this.selectedItems.forEach(item => { + promises.push(DataService.delete(this.dataUrl + item)); + }); + Promise.all(promises).then((results) => { + results.forEach(function (id) { + const index = self.selectedItems.indexOf(id); + if (index === - 1) { + return; + } + self.selectedItems.splice(index, 1); + }); + this.getItems(); + }); + } + } + } +} + +export default CatalogMixin; \ No newline at end of file diff --git a/Frontend/vue-project/src/models/Collection.js b/Frontend/vue-project/src/models/Collection.js new file mode 100644 index 0000000..dbef5df --- /dev/null +++ b/Frontend/vue-project/src/models/Collection.js @@ -0,0 +1,26 @@ +export default class Collection { + constructor(data) { + this._id = data?.id; + this._name = data?.name; + this._filmIds = data?.filmIds; + } + + get id() { + return this._id; + } + + get name() { + return this._name; + } + + set name(value) { + if (typeof value !== 'string' || value === null || value.length == 0) { + throw 'New name value ' + value + ' is not a string or empty'; + } + this._name = value; + } + + get filmIds() { + return this.filmIds; + } +} \ No newline at end of file diff --git a/Frontend/vue-project/src/models/Film.js b/Frontend/vue-project/src/models/Film.js new file mode 100644 index 0000000..aa7c7d0 --- /dev/null +++ b/Frontend/vue-project/src/models/Film.js @@ -0,0 +1,26 @@ +export default class Film { + constructor(data) { + this._id = data?.id; + this._name = data?.name; + this._genreIds = data?.genreIds; + } + + get id() { + return this._id; + } + + get name() { + return this._name; + } + + set name(value) { + if (typeof value !== 'string' || value === null || value.length == 0) { + throw 'New name value ' + value + ' is not a string or empty'; + } + this._name = value; + } + + get genreIds() { + return this._genreIds; + } +} \ No newline at end of file diff --git a/Frontend/vue-project/src/models/Genre.js b/Frontend/vue-project/src/models/Genre.js new file mode 100644 index 0000000..80b53da --- /dev/null +++ b/Frontend/vue-project/src/models/Genre.js @@ -0,0 +1,21 @@ +export default class Genre { + constructor(data) { + this._id = data?.id; + this._name = data?.name; + } + + get id() { + return this._id; + } + + get name() { + return this._name; + } + + set name(value) { + if (typeof value !== 'string' || value === null || value.length == 0) { + throw 'New name value ' + value + ' is not a string or empty'; + } + this._name = value; + } +} \ No newline at end of file diff --git a/Frontend/vue-project/src/services/DataService.js b/Frontend/vue-project/src/services/DataService.js new file mode 100644 index 0000000..54810c9 --- /dev/null +++ b/Frontend/vue-project/src/services/DataService.js @@ -0,0 +1,42 @@ +import axios from 'axios'; + +function toJSON(data) { + const jsonObj = {}; + const fields = Object.getOwnPropertyNames(data); + for (const field of fields) { + if (data[field] === undefined) { + continue; + } + jsonObj[field.substring(1)] = data[field]; + } + return jsonObj; +} + +export default class DataService { + static dataUrlPrefix = 'http://localhost:8080/'; + + static async readAll(url, transformer) { + const response = await axios.get(this.dataUrlPrefix + url); + return response.data.map(item => transformer(item)); + } + + static async read(url, transformer) { + const response = await axios.get(this.dataUrlPrefix + url); + return transformer(response.data); + } + + static async create(url, data) { + const response = await axios.post(this.dataUrlPrefix + url, toJSON(data)); + return true; + } + + static async update(url, data) { + const response = await axios.put(this.dataUrlPrefix + url, toJSON(data)); + return true; + } + + static async delete(url) { + const response = await axios.delete(this.dataUrlPrefix + url); + return response.data.id; + } +} \ No newline at end of file diff --git a/data.mv.db b/data.mv.db index 9be51e6d37474808a18771e30f163191b076dcaf..39ecef297863bc91c813c2a06954aaeb84d72935 100644 GIT binary patch delta 2915 zcmeH}U27aw7{|{{*4^!fnv|>?HEG>6$;#3(IWKc&&P=gU!4gzrrB(!?&CKkq2~BoG zvXQnRUA^gbbFdVo7B74OdlNTa2nzAm3)%Vs1g}K!#t&fYnX~h@jS&p$Rrg}f49w1X z&hz~K|L1A%s_k8Ma^A+8yVCS7M(f$-E53~&gqpXs*|=yUdVTWgBGu|Ee#=|(*KO=$ z7cCEF1ZH2g~~n`mp!+x~`# zZ@t-U*;E&?K}0P}*ILV~zO6HzSUPbq}Iw^&tijUR=_eDA^N%o?iclxdrd%?-aMq9rvK`y_mRzV${FHAxOY!UG_! z>3N%LPQ$xwLvmXQE28r=H%1l4o%N9huFGs89Hq+%(?!B`1@S=aTPRM~egWu70ODPd z!Mfq612AqWTkR4*VO~?eP`1h?zQo4(FXr6%-yMo0c8vda;}Cz7eLC8!9mJkx3{n|b zaL+pD=a;j*J(sH_Jfw;llV|DJWOc_BWnJLya)#fZ&6kW2A)=)aBE0*-QH`=-j{p@M zp~5VSLN7U}ArET0ZVHuQiONVC72HFm^E(`mNuiPy8j^xlLI6Piny|_-G#zRjtu;mwvq&ph!i6r z7 zUBe}OcH(FL=;Tyq`1mISygc<9FTcK%$?T|S_-aMV`?3|`dgtTHgepfCA{!C;vig`> z_ElUL^nIVdqNWBG9GMFV1{R)!!@Nt!_&8**LTDwA|ZK2njVto!M-;~5Edik%#V8Xq=_Ll5A2_C7^ RCZh=D+HB@K3d_c2WQU delta 1554 zcmb`HPiPcZ7{K3~>_0bEqfHb4ZFZWFwb7}0@9pgDyg@WVp`s;iQW1i>asDlath-@% zBh-Ve?WL!ZH8F$6)Rm;K%@?EBvL z`+eWnSQQ$p!oXpTNk*w+PHR~|em!;G)+ixFGSAGGr!~sv2X=qRq+-dgn`i8*W-)_h zO+D$%Pu|?T(3RZ&et#5Wo2?)-lS+13qmU{b+;YyY)}|_D&64UBQ?nU`<>4dABtp@< z(IgUjVCAa}JZ|iS=vW>;xwr!+$Nq$SwNGK`+l;d~KHdRh{Z2IUtMCxR?YVS!^sGL! zkHx%C;s@$Hn%f~HVrBiTtxfj97ZWML?1R!o3Y*S;=oWS}A~1?jM{29@b4v-%gqhSmH-9EHuTmW$ z)Idn;apMTWm+!j~A>prM%lhYdL5vNCghDQD5k}5pS)-VD35`NSjKQnnL{DhbV=B3Y zYs`S>gMD!L%$iT>%%twQKIy_UB@KtzmDh;Qr-Oyhc=?q_J!G%H}R^VFU=U!R$G&7U0 zu@ArGcRFlnGzKrz8#1A-c4co&8mGikO+6O~j(CD;Ff_71G`?W3(!Fo3w0(J4#`18> zdhdGcs&Ac#)`@4Gc-FTuRbbq;9*NbkJ030BWS#6U|7Y3n4&P7wR`~NXzb%OIOvv&L zLhbqDgmBeZgFg;Ws$HW?fUq03!WDR))vf^B01ah+HO zRSAq-ywX}%usHscBYs!Hj#xk42|vvBio(&24+Io%Z5$=oH2EN^fDfgde`lUzI9D6` vsNt^;?5+;^inlsCo{TT+-*0TL4j%MLuHD2u+~Kxu5nC-Pt<~YYs$lXO48G$Z diff --git a/src/main/java/ru/ulstu/is/lab1/DataBase/controller/GenreController.java b/src/main/java/ru/ulstu/is/lab1/DataBase/controller/GenreController.java index 3453274..d0db0aa 100644 --- a/src/main/java/ru/ulstu/is/lab1/DataBase/controller/GenreController.java +++ b/src/main/java/ru/ulstu/is/lab1/DataBase/controller/GenreController.java @@ -9,7 +9,6 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import ru.ulstu.is.lab1.DataBase.model.Genre; import ru.ulstu.is.lab1.DataBase.service.GenreService; import java.util.List; diff --git a/src/main/java/ru/ulstu/is/lab1/DataBase/service/CollectionService.java b/src/main/java/ru/ulstu/is/lab1/DataBase/service/CollectionService.java index 6dc63cd..14bac03 100644 --- a/src/main/java/ru/ulstu/is/lab1/DataBase/service/CollectionService.java +++ b/src/main/java/ru/ulstu/is/lab1/DataBase/service/CollectionService.java @@ -3,7 +3,6 @@ package ru.ulstu.is.lab1.DataBase.service; import ru.ulstu.is.lab1.DataBase.model.Film; import ru.ulstu.is.lab1.DataBase.model.Collection; import ru.ulstu.is.lab1.DataBase.Repository.ICollectionRepository; -import ru.ulstu.is.lab1.DataBase.model.Genre; import ru.ulstu.is.lab1.util.validation.ValidatorUtil; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional;