Добавлен фильтр по удаленным
This commit is contained in:
@@ -126,12 +126,6 @@
|
|||||||
<q-icon class="la la-meh q-mr-xs" size="28px" />
|
<q-icon class="la la-meh q-mr-xs" size="28px" />
|
||||||
Поиск не дал результатов
|
Поиск не дал результатов
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-show="hiddenCount" class="row">
|
|
||||||
<div class="q-ml-lg q-py-sm clickable2 text-red" style="font-size: 120%" @click="showHiddenHelp">
|
|
||||||
{{ hiddenResultsMessage }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -150,7 +144,6 @@ import _ from 'lodash';
|
|||||||
|
|
||||||
class AuthorList extends BaseList {
|
class AuthorList extends BaseList {
|
||||||
cachedAuthors = {};
|
cachedAuthors = {};
|
||||||
hiddenCount = 0;
|
|
||||||
|
|
||||||
showHiddenHelp() {
|
showHiddenHelp() {
|
||||||
this.$root.stdDialog.alert(`
|
this.$root.stdDialog.alert(`
|
||||||
@@ -158,10 +151,6 @@ class AuthorList extends BaseList {
|
|||||||
`, 'Пояснение', {iconName: 'la la-info-circle'});
|
`, 'Пояснение', {iconName: 'la la-info-circle'});
|
||||||
}
|
}
|
||||||
|
|
||||||
get hiddenResultsMessage() {
|
|
||||||
return `+${this.hiddenCount} результат${utils.wordEnding(this.hiddenCount)} скрыт${utils.wordEnding(this.hiddenCount, 2)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
get foundCountMessage() {
|
get foundCountMessage() {
|
||||||
return `Найден${utils.wordEnding(this.list.totalFound, 2)} ${this.list.totalFound} автор${utils.wordEnding(this.list.totalFound)}`;
|
return `Найден${utils.wordEnding(this.list.totalFound, 2)} ${this.list.totalFound} автор${utils.wordEnding(this.list.totalFound)}`;
|
||||||
}
|
}
|
||||||
@@ -333,15 +322,10 @@ class AuthorList extends BaseList {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
let num = 0;
|
let num = 0;
|
||||||
this.hiddenCount = 0;
|
|
||||||
for (const rec of authors) {
|
for (const rec of authors) {
|
||||||
this.cachedAuthors[rec.author] = rec;
|
this.cachedAuthors[rec.author] = rec;
|
||||||
|
|
||||||
const count = (this.showDeleted ? rec.bookCount + rec.bookDelCount : rec.bookCount);
|
const count = (this.showDeleted ? rec.bookCount + rec.bookDelCount : rec.bookCount);
|
||||||
if (!count) {
|
|
||||||
this.hiddenCount++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const item = reactive({
|
const item = reactive({
|
||||||
key: rec.id,
|
key: rec.id,
|
||||||
@@ -379,6 +363,8 @@ class AuthorList extends BaseList {
|
|||||||
newQuery = newQuery.setDefaults(newQuery);
|
newQuery = newQuery.setDefaults(newQuery);
|
||||||
delete newQuery.setDefaults;
|
delete newQuery.setDefaults;
|
||||||
newQuery.offset = (newQuery.page - 1)*newQuery.limit;
|
newQuery.offset = (newQuery.page - 1)*newQuery.limit;
|
||||||
|
if (!this.showDeleted)
|
||||||
|
newQuery.del = 0;
|
||||||
|
|
||||||
if (_.isEqual(newQuery, this.prevQuery))
|
if (_.isEqual(newQuery, this.prevQuery))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ const componentOptions = {
|
|||||||
deep: true,
|
deep: true,
|
||||||
},
|
},
|
||||||
showDeleted() {
|
showDeleted() {
|
||||||
this.updateTableData();
|
this.refresh();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -54,10 +54,10 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="!item.showAllBooks && isExpandedSeries(item) && item.books && !item.books.length" class="book-row row items-center">
|
<!--div v-if="!item.showAllBooks && isExpandedSeries(item) && item.books && !item.books.length" class="book-row row items-center">
|
||||||
<q-icon class="la la-meh q-mr-xs" size="24px" />
|
<q-icon class="la la-meh q-mr-xs" size="24px" />
|
||||||
Возможно у этой серии были найдены книги, помеченные как удаленные, но подходящие по критериям
|
Возможно у этой серии были найдены книги, помеченные как удаленные, но подходящие по критериям
|
||||||
</div>
|
</div-->
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="item.allBooksLoaded && item.allBooksLoaded.length != item.booksLoaded.length"
|
v-if="item.allBooksLoaded && item.allBooksLoaded.length != item.booksLoaded.length"
|
||||||
@@ -230,6 +230,8 @@ class SeriesList extends BaseList {
|
|||||||
newQuery = newQuery.setDefaults(newQuery);
|
newQuery = newQuery.setDefaults(newQuery);
|
||||||
delete newQuery.setDefaults;
|
delete newQuery.setDefaults;
|
||||||
newQuery.offset = (newQuery.page - 1)*newQuery.limit;
|
newQuery.offset = (newQuery.page - 1)*newQuery.limit;
|
||||||
|
if (!this.showDeleted)
|
||||||
|
newQuery.del = 0;
|
||||||
|
|
||||||
if (_.isEqual(newQuery, this.prevQuery))
|
if (_.isEqual(newQuery, this.prevQuery))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ class TitleList extends BaseList {
|
|||||||
newQuery = newQuery.setDefaults(newQuery);
|
newQuery = newQuery.setDefaults(newQuery);
|
||||||
delete newQuery.setDefaults;
|
delete newQuery.setDefaults;
|
||||||
newQuery.offset = (newQuery.page - 1)*newQuery.limit;
|
newQuery.offset = (newQuery.page - 1)*newQuery.limit;
|
||||||
|
if (!this.showDeleted)
|
||||||
|
newQuery.del = 0;
|
||||||
|
|
||||||
if (_.isEqual(newQuery, this.prevQuery))
|
if (_.isEqual(newQuery, this.prevQuery))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ class DbCreator {
|
|||||||
let genreArr = [];
|
let genreArr = [];
|
||||||
let langMap = new Map();//языки
|
let langMap = new Map();//языки
|
||||||
let langArr = [];
|
let langArr = [];
|
||||||
|
let delMap = new Map();//удаленные
|
||||||
|
let delArr = [];
|
||||||
|
|
||||||
//stats
|
//stats
|
||||||
let authorCount = 0;
|
let authorCount = 0;
|
||||||
@@ -314,12 +316,16 @@ class DbCreator {
|
|||||||
//парсинг 2, подготовка
|
//парсинг 2, подготовка
|
||||||
const parseField = (fieldValue, fieldMap, fieldArr, authorIds, bookId) => {
|
const parseField = (fieldValue, fieldMap, fieldArr, authorIds, bookId) => {
|
||||||
let addBookId = bookId;
|
let addBookId = bookId;
|
||||||
if (!fieldValue) {
|
let value = fieldValue;
|
||||||
fieldValue = emptyFieldValue;
|
|
||||||
addBookId = 0;//!!!
|
|
||||||
}
|
|
||||||
|
|
||||||
const value = fieldValue.toLowerCase();
|
if (typeof(fieldValue) == 'string') {
|
||||||
|
if (!fieldValue) {
|
||||||
|
fieldValue = emptyFieldValue;
|
||||||
|
addBookId = 0;//!!!
|
||||||
|
}
|
||||||
|
|
||||||
|
value = fieldValue.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
let fieldRec;
|
let fieldRec;
|
||||||
if (fieldMap.has(value)) {
|
if (fieldMap.has(value)) {
|
||||||
@@ -384,6 +390,9 @@ class DbCreator {
|
|||||||
|
|
||||||
//языки
|
//языки
|
||||||
parseField(rec.lang, langMap, langArr, authorIds);
|
parseField(rec.lang, langMap, langArr, authorIds);
|
||||||
|
|
||||||
|
//удаленные
|
||||||
|
parseField(rec.del, delMap, delArr, authorIds);
|
||||||
};
|
};
|
||||||
|
|
||||||
callback({job: 'search tables create', jobMessage: 'Создание поисковых таблиц', jobStep: 4, progress: 0});
|
callback({job: 'search tables create', jobMessage: 'Создание поисковых таблиц', jobStep: 4, progress: 0});
|
||||||
@@ -437,6 +446,8 @@ class DbCreator {
|
|||||||
seriesMap = null;
|
seriesMap = null;
|
||||||
titleMap = null;
|
titleMap = null;
|
||||||
genreMap = null;
|
genreMap = null;
|
||||||
|
langMap = null;
|
||||||
|
delMap = null;
|
||||||
|
|
||||||
utils.freeMemory();
|
utils.freeMemory();
|
||||||
|
|
||||||
@@ -484,13 +495,16 @@ class DbCreator {
|
|||||||
//сохраним поисковые таблицы
|
//сохраним поисковые таблицы
|
||||||
const chunkSize = 10000;
|
const chunkSize = 10000;
|
||||||
|
|
||||||
const saveTable = async(table, arr, nullArr, authorIdToArray = false, bookIdToArray = false) => {
|
const saveTable = async(table, arr, nullArr, authorIdToArray = false, bookIdToArray = false, indexType = 'string') => {
|
||||||
|
|
||||||
arr.sort((a, b) => a.value.localeCompare(b.value));
|
if (indexType == 'string')
|
||||||
|
arr.sort((a, b) => a.value.localeCompare(b.value));
|
||||||
|
else
|
||||||
|
arr.sort((a, b) => a.value - b.value);
|
||||||
|
|
||||||
await db.create({
|
await db.create({
|
||||||
table,
|
table,
|
||||||
index: {field: 'value', unique: true, depth: 1000000},
|
index: {field: 'value', unique: true, type: indexType, depth: 1000000},
|
||||||
});
|
});
|
||||||
|
|
||||||
//вставка в БД по кусочкам, экономим память
|
//вставка в БД по кусочкам, экономим память
|
||||||
@@ -543,6 +557,9 @@ class DbCreator {
|
|||||||
callback({job: 'lang save', jobMessage: 'Сохранение индекса языков', jobStep: 10, progress: 0});
|
callback({job: 'lang save', jobMessage: 'Сохранение индекса языков', jobStep: 10, progress: 0});
|
||||||
await saveTable('lang', langArr, () => {langArr = null}, true);
|
await saveTable('lang', langArr, () => {langArr = null}, true);
|
||||||
|
|
||||||
|
//del
|
||||||
|
await saveTable('del', delArr, () => {delArr = null}, true, false, 'number');
|
||||||
|
|
||||||
//кэш-таблицы запросов
|
//кэш-таблицы запросов
|
||||||
await db.create({table: 'query_cache'});
|
await db.create({table: 'query_cache'});
|
||||||
await db.create({table: 'query_time'});
|
await db.create({table: 'query_time'});
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ class DbSearcher {
|
|||||||
this.periodicCleanCache();//no await
|
this.periodicCleanCache();//no await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
queryKey(q) {
|
||||||
|
return JSON.stringify([q.author, q.series, q.title, q.genre, q.lang, q.del]);
|
||||||
|
}
|
||||||
|
|
||||||
getWhere(a) {
|
getWhere(a) {
|
||||||
const db = this.db;
|
const db = this.db;
|
||||||
|
|
||||||
@@ -226,6 +230,35 @@ class DbSearcher {
|
|||||||
idsArr.push(langIds);
|
idsArr.push(langIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//удаленные
|
||||||
|
if (query.del !== undefined) {
|
||||||
|
const delKey = `author-ids-del-${query.del}`;
|
||||||
|
let delIds = await this.getCached(delKey);
|
||||||
|
|
||||||
|
if (delIds === null) {
|
||||||
|
const delRows = await db.select({
|
||||||
|
table: 'del',
|
||||||
|
rawResult: true,
|
||||||
|
where: `
|
||||||
|
const ids = @indexLR('value', ${db.esc(query.del)}, ${db.esc(query.del)});
|
||||||
|
|
||||||
|
const result = new Set();
|
||||||
|
for (const id of ids) {
|
||||||
|
const row = @unsafeRow(id);
|
||||||
|
for (const authorId of row.authorId)
|
||||||
|
result.add(authorId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(result);
|
||||||
|
`
|
||||||
|
});
|
||||||
|
|
||||||
|
delIds = delRows[0].rawResult;
|
||||||
|
await this.putCached(delKey, delIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
idsArr.push(delIds);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
//ищем пересечение множеств
|
//ищем пересечение множеств
|
||||||
idsArr.push(authorIds);
|
idsArr.push(authorIds);
|
||||||
@@ -300,6 +333,14 @@ class DbSearcher {
|
|||||||
|
|
||||||
//порядок важен, более простые проверки вперед
|
//порядок важен, более простые проверки вперед
|
||||||
|
|
||||||
|
//удаленные
|
||||||
|
if (query.del !== undefined) {
|
||||||
|
filter += `
|
||||||
|
if (book.del !== ${db.esc(query.del)})
|
||||||
|
return false;
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
//серии
|
//серии
|
||||||
if (exclude !== 'series' && query.series && query.series !== '*') {
|
if (exclude !== 'series' && query.series && query.series !== '*') {
|
||||||
closures += `
|
closures += `
|
||||||
@@ -569,10 +610,6 @@ class DbSearcher {
|
|||||||
return titleIds;
|
return titleIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
queryKey(q) {
|
|
||||||
return JSON.stringify([q.author, q.series, q.title, q.genre, q.lang]);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getCached(key) {
|
async getCached(key) {
|
||||||
if (!this.config.queryCacheEnabled)
|
if (!this.config.queryCacheEnabled)
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user