From 80b21371a44a476971fb41f0ce41819d1e359bce Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Mon, 28 Nov 2022 16:58:32 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=B1=D1=89=D0=B5=D0=B3=D0=BE=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BB=D0=B8=D1=87=D0=B5=D1=81=D1=82=D0=B2=D0=B0=20?= =?UTF-8?q?=D0=BA=D0=BD=D0=B8=D0=B3=20=D0=B2=20=D1=81=D0=B5=D1=80=D0=B8?= =?UTF-8?q?=D0=B8,=20=D0=B1=D0=B5=D0=B7=20=D0=B5=D0=B5=20=D1=80=D0=B0?= =?UTF-8?q?=D1=81=D0=BA=D1=80=D1=8B=D1=82=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/components/Api/Api.vue | 4 ++ .../Search/AuthorList/AuthorList.vue | 25 ++++++++-- client/components/Search/BaseList.js | 23 +++++++++ server/controllers/WebSocketController.js | 8 +++ server/core/DbSearcher.js | 50 ++++++++++++++++++- server/core/WebWorker.js | 6 +++ 6 files changed, 110 insertions(+), 6 deletions(-) diff --git a/client/components/Api/Api.vue b/client/components/Api/Api.vue index e3e597a..7b34ed3 100644 --- a/client/components/Api/Api.vue +++ b/client/components/Api/Api.vue @@ -239,6 +239,10 @@ class Api { return await this.request({action: 'get-author-book-list', authorId}); } + async getAuthorSeriesList(authorId) { + return await this.request({action: 'get-author-series-list', authorId}); + } + async getSeriesBookList(series) { return await this.request({action: 'get-series-book-list', series}); } diff --git a/client/components/Search/AuthorList/AuthorList.vue b/client/components/Search/AuthorList/AuthorList.vue index bc7718f..2f5892a 100644 --- a/client/components/Search/AuthorList/AuthorList.vue +++ b/client/components/Search/AuthorList/AuthorList.vue @@ -56,7 +56,7 @@
- {{ getSeriesBookCount(book) }} + {{ getSeriesBookCount(item, book) }}
@@ -188,15 +188,17 @@ class AuthorList extends BaseList { return `(${result})`; } - getSeriesBookCount(book) { + getSeriesBookCount(item, book) { let result = ''; if (!this.showCounts || book.type != 'series') return result; let count = book.seriesBooks.length; result = `${count}`; - if (book.allBooksLoaded) { - result += `/${book.allBooksLoaded.length}`; + if (item.seriesLoaded) { + const rec = item.seriesLoaded[book.series]; + const totalCount = (this.showDeleted ? rec.bookCount + rec.bookDelCount : rec.bookCount); + result += `/${totalCount}`; } return `(${result})`; @@ -227,6 +229,19 @@ class AuthorList extends BaseList { } } + async getAuthorSeries(item) { + if (item.seriesLoaded) + return; + + const series = await this.loadAuthorSeries(item.key); + const loaded = {}; + for (const s of series) { + loaded[s.series] = {bookCount: s.bookCount, bookDelCount: s.bookDelCount}; + } + + item.seriesLoaded = loaded; + } + async getAuthorBooks(item) { if (item.books) { if (item.count > this.maxItemCount) { @@ -328,6 +343,7 @@ class AuthorList extends BaseList { } item.booksLoaded = books; + this.getAuthorSeries(item);//no await this.showMore(item); await this.$nextTick(); @@ -360,6 +376,7 @@ class AuthorList extends BaseList { name: rec.author.replace(/,/g, ', '), count, booksLoaded: false, + seriesLoaded: false, books: false, bookLoading: false, showMore: false, diff --git a/client/components/Search/BaseList.js b/client/components/Search/BaseList.js index 180d556..0082d58 100644 --- a/client/components/Search/BaseList.js +++ b/client/components/Search/BaseList.js @@ -259,6 +259,29 @@ export default class BaseList { } } + async loadAuthorSeries(authorId) { + try { + let result; + + if (this.abCacheEnabled) { + const key = `author-${authorId}-series-${this.list.inpxHash}`; + const data = await authorBooksStorage.getData(key); + if (data) { + result = JSON.parse(data); + } else { + result = await this.api.getAuthorSeriesList(authorId); + await authorBooksStorage.setData(key, JSON.stringify(result)); + } + } else { + result = await this.api.getAuthorSeriesList(authorId); + } + + return result.series; + } catch (e) { + this.$root.stdDialog.alert(e.message, 'Ошибка'); + } + } + async loadSeriesBooks(series) { try { let result; diff --git a/server/controllers/WebSocketController.js b/server/controllers/WebSocketController.js index eea3c01..73344b4 100644 --- a/server/controllers/WebSocketController.js +++ b/server/controllers/WebSocketController.js @@ -89,6 +89,8 @@ class WebSocketController { await this.search(req, ws); break; case 'get-author-book-list': await this.getAuthorBookList(req, ws); break; + case 'get-author-series-list': + await this.getAuthorSeriesList(req, ws); break; case 'get-series-book-list': await this.getSeriesBookList(req, ws); break; case 'get-genre-tree': @@ -169,6 +171,12 @@ class WebSocketController { this.send(result, req, ws); } + async getAuthorSeriesList(req, ws) { + const result = await this.webWorker.getAuthorSeriesList(req.authorId); + + this.send(result, req, ws); + } + async getSeriesBookList(req, ws) { const result = await this.webWorker.getSeriesBookList(req.series); diff --git a/server/core/DbSearcher.js b/server/core/DbSearcher.js index 8ee01ce..fe3012f 100644 --- a/server/core/DbSearcher.js +++ b/server/core/DbSearcher.js @@ -599,7 +599,7 @@ class DbSearcher { throw new Error('DbSearcher closed'); if (!authorId && !author) - return {author: '', books: ''}; + return {author: '', books: []}; this.searchFlag++; @@ -638,12 +638,58 @@ class DbSearcher { } } + async getAuthorSeriesList(authorId) { + if (this.closed) + throw new Error('DbSearcher closed'); + + if (!authorId) + return {author: '', series: []}; + + this.searchFlag++; + + try { + const db = this.db; + + //выборка книг автора по authorId + const bookList = await this.getAuthorBookList(authorId); + const books = bookList.books; + const seriesSet = new Set(); + for (const book of books) { + if (book.series) + seriesSet.add(book.series.toLowerCase()); + } + + let series = []; + if (seriesSet.size) { + //выборка серий по названиям + series = await db.select({ + table: 'series', + map: `(r) => ({id: r.id, series: r.name, bookCount: r.bookCount, bookDelCount: r.bookDelCount})`, + where: ` + const seriesArr = ${db.esc(Array.from(seriesSet))}; + const ids = new Set(); + for (const value of seriesArr) { + for (const id of @dirtyIndexLR('value', value, value)) + ids.add(id); + } + + return ids; + ` + }); + } + + return {author: bookList.author, series}; + } finally { + this.searchFlag--; + } + } + async getSeriesBookList(series) { if (this.closed) throw new Error('DbSearcher closed'); if (!series) - return {books: ''}; + return {books: []}; this.searchFlag++; diff --git a/server/core/WebWorker.js b/server/core/WebWorker.js index 7a1e6c9..50a89e4 100644 --- a/server/core/WebWorker.js +++ b/server/core/WebWorker.js @@ -279,6 +279,12 @@ class WebWorker { return await this.dbSearcher.getAuthorBookList(authorId, author); } + async getAuthorSeriesList(authorId) { + this.checkMyState(); + + return await this.dbSearcher.getAuthorSeriesList(authorId); + } + async getSeriesBookList(series) { this.checkMyState();