Добавлена возможность отображения всех книг серии
This commit is contained in:
@@ -221,8 +221,8 @@ class Api {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSeriesBookList(seriesId) {
|
async getSeriesBookList(series) {
|
||||||
const response = await this.request({action: 'get-series-book-list', seriesId});
|
const response = await this.request({action: 'get-series-book-list', series});
|
||||||
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
throw new Error(response.error);
|
throw new Error(response.error);
|
||||||
|
|||||||
@@ -1,38 +1,40 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="row items-center q-my-sm">
|
<div class="row items-center q-my-sm">
|
||||||
<div v-if="showRate || showDeleted">
|
<div class="row no-wrap">
|
||||||
<div v-if="showRate && !book.del">
|
<div v-if="showRate || showDeleted">
|
||||||
<div v-if="book.librate">
|
<div v-if="showRate && !book.del">
|
||||||
<q-knob
|
<div v-if="book.librate">
|
||||||
:model-value="book.librate"
|
<q-knob
|
||||||
:min="0"
|
:model-value="book.librate"
|
||||||
:max="5"
|
:min="0"
|
||||||
size="18px"
|
:max="5"
|
||||||
font-size="12px"
|
size="18px"
|
||||||
:thickness="1"
|
font-size="12px"
|
||||||
:color="rateColor"
|
:thickness="1"
|
||||||
track-color="grey-4"
|
:color="rateColor"
|
||||||
readonly
|
track-color="grey-4"
|
||||||
/>
|
readonly
|
||||||
|
/>
|
||||||
|
|
||||||
<q-tooltip :delay="500" anchor="top middle" content-style="font-size: 80%" max-width="400px">
|
<q-tooltip :delay="500" anchor="top middle" content-style="font-size: 80%" max-width="400px">
|
||||||
Оценка {{ book.librate }}
|
Оценка {{ book.librate }}
|
||||||
</q-tooltip>
|
</q-tooltip>
|
||||||
|
</div>
|
||||||
|
<div v-else style="width: 18px" />
|
||||||
|
</div>
|
||||||
|
<div v-else class="row justify-center" style="width: 18px">
|
||||||
|
<q-icon v-if="book.del" class="la la-trash text-bold text-red" size="18px">
|
||||||
|
<q-tooltip :delay="500" anchor="top middle" content-style="font-size: 80%" max-width="400px">
|
||||||
|
Удалено
|
||||||
|
</q-tooltip>
|
||||||
|
</q-icon>
|
||||||
</div>
|
</div>
|
||||||
<div v-else style="width: 18px" />
|
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="row justify-center" style="width: 18px">
|
|
||||||
<q-icon v-if="book.del" class="la la-trash text-bold text-red" size="18px">
|
|
||||||
<q-tooltip :delay="500" anchor="top middle" content-style="font-size: 80%" max-width="400px">
|
|
||||||
Удалено
|
|
||||||
</q-tooltip>
|
|
||||||
</q-icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="q-ml-sm clickable2" @click="selectTitle">
|
<div class="q-ml-sm clickable2" @click="selectTitle">
|
||||||
{{ book.serno ? `${book.serno}. ` : '' }}
|
{{ book.serno ? `${book.serno}. ` : '' }}
|
||||||
<span class="text-blue-10">{{ book.title }}</span>
|
<span class="text-blue-10">{{ bookTitle }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="q-ml-sm">
|
<div class="q-ml-sm">
|
||||||
@@ -79,6 +81,7 @@ class BookView {
|
|||||||
_props = {
|
_props = {
|
||||||
book: Object,
|
book: Object,
|
||||||
genreTree: Array,
|
genreTree: Array,
|
||||||
|
showAuthor: Boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
showRate = true;
|
showRate = true;
|
||||||
@@ -105,6 +108,17 @@ class BookView {
|
|||||||
return this.$store.state.settings;
|
return this.$store.state.settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get bookTitle() {
|
||||||
|
if (this.showAuthor && this.book.author) {
|
||||||
|
let a = this.book.author.split(',');
|
||||||
|
const author = a.slice(0, 2).join(', ') + (a.length > 2 ? ' и др.' : '');
|
||||||
|
|
||||||
|
return `${author} - ${this.book.title}`;
|
||||||
|
} else {
|
||||||
|
return this.book.title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get bookSize() {
|
get bookSize() {
|
||||||
let size = this.book.size/1024;
|
let size = this.book.size/1024;
|
||||||
let unit = 'KB';
|
let unit = 'KB';
|
||||||
|
|||||||
@@ -172,8 +172,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="isExpandedSeries(book) && book.books" class="book-row column">
|
<div v-if="isExpandedSeries(book) && book.books">
|
||||||
<BookView v-for="subbook in book.books" :key="subbook.key" :book="subbook" :genre-tree="genreTree" @book-event="bookEvent" />
|
<div v-if="book.showAllBooks" class="book-row column">
|
||||||
|
<BookView v-for="subbook in book.allBooks" :key="subbook.key" :book="subbook" show-author :genre-tree="genreTree" @book-event="bookEvent" />
|
||||||
|
</div>
|
||||||
|
<div v-else class="book-row column">
|
||||||
|
<BookView v-for="subbook in book.books" :key="subbook.key" :book="subbook" :genre-tree="genreTree" @book-event="bookEvent" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="book.allBooks" class="q-my-sm clickable" style="margin-left: 100px" @click="book.showAllBooks = !book.showAllBooks">
|
||||||
|
<div v-if="book.showAllBooks">
|
||||||
|
Показать только найденные
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
Показать все книги серии
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<BookView v-else :book="book" :genre-tree="genreTree" @book-event="bookEvent" />
|
<BookView v-else :book="book" :genre-tree="genreTree" @book-event="bookEvent" />
|
||||||
@@ -191,7 +205,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Формирование списка конец ------------------------------------------------------------------>
|
<!-- Формирование списка конец ------------------------------------------------------------------>
|
||||||
|
|
||||||
<div v-if="ready && !refreshing && !tableData.length" class="q-ml-md" style="font-size: 120%">
|
<div v-if="ready && !refreshing && !tableData.length" class="q-ml-md" style="font-size: 120%">
|
||||||
Поиск не дал результатов
|
Поиск не дал результатов
|
||||||
</div>
|
</div>
|
||||||
@@ -851,6 +865,8 @@ class Search {
|
|||||||
expandedSeries.shift();
|
expandedSeries.shift();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.getSeriesBooks(seriesItem); //no await
|
||||||
|
|
||||||
this.setSetting('expandedSeries', expandedSeries);
|
this.setSetting('expandedSeries', expandedSeries);
|
||||||
this.ignoreScroll();
|
this.ignoreScroll();
|
||||||
} else {
|
} else {
|
||||||
@@ -879,35 +895,52 @@ class Search {
|
|||||||
result = await this.api.getBookList(authorId);
|
result = await this.api.getBookList(authorId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return JSON.parse(result.books);
|
return (result.books ? JSON.parse(result.books) : []);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.$root.stdDialog.alert(e.message, 'Ошибка');
|
this.$root.stdDialog.alert(e.message, 'Ошибка');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadSeriesBooks(seriesId) {
|
async loadSeriesBooks(series) {
|
||||||
try {
|
try {
|
||||||
let result;
|
let result;
|
||||||
|
|
||||||
if (this.abCacheEnabled) {
|
if (this.abCacheEnabled) {
|
||||||
const key = `series-${seriesId}-${this.inpxHash}`;
|
const key = `series-${series}-${this.inpxHash}`;
|
||||||
const data = await authorBooksStorage.getData(key);
|
const data = await authorBooksStorage.getData(key);
|
||||||
if (data) {
|
if (data) {
|
||||||
result = JSON.parse(data);
|
result = JSON.parse(data);
|
||||||
} else {
|
} else {
|
||||||
result = await this.api.getBookList(seriesId);
|
result = await this.api.getSeriesBookList(series);
|
||||||
await authorBooksStorage.setData(key, JSON.stringify(result));
|
await authorBooksStorage.setData(key, JSON.stringify(result));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = await this.api.getBookList(seriesId);
|
result = await this.api.getSeriesBookList(series);
|
||||||
}
|
}
|
||||||
|
|
||||||
return JSON.parse(result.books);
|
return (result.books ? JSON.parse(result.books) : []);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.$root.stdDialog.alert(e.message, 'Ошибка');
|
this.$root.stdDialog.alert(e.message, 'Ошибка');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getSeriesBooks(seriesItem) {
|
||||||
|
//асинхронно подгружаем все книги серии, блокируем повторный вызов
|
||||||
|
if (seriesItem.allBooks === null) {
|
||||||
|
seriesItem.allBooks = undefined;
|
||||||
|
(async() => {
|
||||||
|
seriesItem.allBooks = await this.loadSeriesBooks(seriesItem.series);
|
||||||
|
|
||||||
|
if (seriesItem.allBooks) {
|
||||||
|
seriesItem.allBooks = seriesItem.allBooks.filter(book => (this.showDeleted || !book.del));
|
||||||
|
this.sortSeriesBooks(seriesItem.allBooks);
|
||||||
|
} else {
|
||||||
|
seriesItem.allBooks = null;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
filterBooks(loadedBooks) {
|
filterBooks(loadedBooks) {
|
||||||
const s = this.search;
|
const s = this.search;
|
||||||
|
|
||||||
@@ -1016,6 +1049,15 @@ class Search {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sortSeriesBooks(books) {
|
||||||
|
books.sort((a, b) => {
|
||||||
|
const dserno = (a.serno || Number.MAX_VALUE) - (b.serno || Number.MAX_VALUE);
|
||||||
|
const dtitle = a.title.localeCompare(b.title);
|
||||||
|
const dext = a.ext.localeCompare(b.ext);
|
||||||
|
return (dserno ? dserno : (dtitle ? dtitle : dext));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async getBooks(item) {
|
async getBooks(item) {
|
||||||
if (item.books) {
|
if (item.books) {
|
||||||
if (item.count > maxItemCount) {
|
if (item.count > maxItemCount) {
|
||||||
@@ -1064,13 +1106,15 @@ class Search {
|
|||||||
let index = seriesIndex[book.series];
|
let index = seriesIndex[book.series];
|
||||||
if (index === undefined) {
|
if (index === undefined) {
|
||||||
index = books.length;
|
index = books.length;
|
||||||
books.push({
|
books.push(reactive({
|
||||||
key: `${item.author}-${book.series}`,
|
key: `${item.author}-${book.series}`,
|
||||||
type: 'series',
|
type: 'series',
|
||||||
series: book.series,
|
series: book.series,
|
||||||
|
allBooks: null,
|
||||||
|
showAllBooks: false,
|
||||||
|
|
||||||
books: [],
|
books: [],
|
||||||
});
|
}));
|
||||||
|
|
||||||
seriesIndex[book.series] = index;
|
seriesIndex[book.series] = index;
|
||||||
}
|
}
|
||||||
@@ -1093,12 +1137,12 @@ class Search {
|
|||||||
//сортировка внутри серий
|
//сортировка внутри серий
|
||||||
for (const book of books) {
|
for (const book of books) {
|
||||||
if (book.type == 'series') {
|
if (book.type == 'series') {
|
||||||
book.books.sort((a, b) => {
|
this.sortSeriesBooks(book.books);
|
||||||
const dserno = (a.serno || Number.MAX_VALUE) - (b.serno || Number.MAX_VALUE);
|
|
||||||
const dtitle = a.title.localeCompare(b.title);
|
//асинхронно подгрузим все книги серии, если она раскрыта
|
||||||
const dext = a.ext.localeCompare(b.ext);
|
if (this.isExpandedSeries(book)) {
|
||||||
return (dserno ? dserno : (dtitle ? dtitle : dext));
|
this.getSeriesBooks(book);//no await
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -153,10 +153,10 @@ class WebSocketController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getSeriesBookList(req, ws) {
|
async getSeriesBookList(req, ws) {
|
||||||
if (!utils.hasProp(req, 'seriesId'))
|
if (!utils.hasProp(req, 'series'))
|
||||||
throw new Error(`seriesId is empty`);
|
throw new Error(`series is empty`);
|
||||||
|
|
||||||
const result = await this.webWorker.getSeriesBookList(req.seriesId);
|
const result = await this.webWorker.getSeriesBookList(req.series);
|
||||||
|
|
||||||
this.send(result, req, ws);
|
this.send(result, req, ws);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ class DbSearcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSeriesBookList(seriesId) {
|
async getSeriesBookList(series) {
|
||||||
if (this.closed)
|
if (this.closed)
|
||||||
throw new Error('DbSearcher closed');
|
throw new Error('DbSearcher closed');
|
||||||
|
|
||||||
@@ -301,10 +301,11 @@ class DbSearcher {
|
|||||||
try {
|
try {
|
||||||
const db = this.db;
|
const db = this.db;
|
||||||
|
|
||||||
//выборка серии по seriesId
|
series = series.toLowerCase();
|
||||||
|
//выборка серии по названию серии
|
||||||
const rows = await db.select({
|
const rows = await db.select({
|
||||||
table: 'series',
|
table: 'series',
|
||||||
where: `@@id(${db.esc(seriesId)})`
|
where: `@@dirtyIndexLR('value', ${db.esc(series)}, ${db.esc(series)})`
|
||||||
});
|
});
|
||||||
|
|
||||||
return {books: (rows.length ? rows[0].books : '')};
|
return {books: (rows.length ? rows[0].books : '')};
|
||||||
|
|||||||
Reference in New Issue
Block a user