Преглед изворни кода

Добавлен фильтр по удаленным

Book Pauk пре 2 година
родитељ
комит
87fc08e3bc

+ 2 - 16
client/components/Search/AuthorList/AuthorList.vue

@@ -126,12 +126,6 @@
             <q-icon class="la la-meh q-mr-xs" size="28px" />
             Поиск не дал результатов
         </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>
 </template>
 
@@ -150,7 +144,6 @@ import _ from 'lodash';
 
 class AuthorList extends BaseList {
     cachedAuthors = {};
-    hiddenCount = 0;
 
     showHiddenHelp() {
         this.$root.stdDialog.alert(`
@@ -158,10 +151,6 @@ class AuthorList extends BaseList {
         `, 'Пояснение', {iconName: 'la la-info-circle'});
     }
 
-    get hiddenResultsMessage() {
-        return `+${this.hiddenCount} результат${utils.wordEnding(this.hiddenCount)} скрыт${utils.wordEnding(this.hiddenCount, 2)}`;
-    }
-
     get foundCountMessage() {
         return `Найден${utils.wordEnding(this.list.totalFound, 2)} ${this.list.totalFound} автор${utils.wordEnding(this.list.totalFound)}`;
     }    
@@ -333,15 +322,10 @@ class AuthorList extends BaseList {
             return;
 
         let num = 0;
-        this.hiddenCount = 0;
         for (const rec of authors) {
             this.cachedAuthors[rec.author] = rec;
 
             const count = (this.showDeleted ? rec.bookCount + rec.bookDelCount : rec.bookCount);
-            if (!count) {
-                this.hiddenCount++;
-                continue;
-            }
 
             const item = reactive({
                 key: rec.id,
@@ -379,6 +363,8 @@ class AuthorList extends BaseList {
         newQuery = newQuery.setDefaults(newQuery);
         delete newQuery.setDefaults;
         newQuery.offset = (newQuery.page - 1)*newQuery.limit;
+        if (!this.showDeleted)
+            newQuery.del = 0;
 
         if (_.isEqual(newQuery, this.prevQuery))
             return;

+ 1 - 1
client/components/Search/BaseList.js

@@ -30,7 +30,7 @@ const componentOptions = {
             deep: true,
         },
         showDeleted() {
-            this.updateTableData();
+            this.refresh();
         },
     },
 };

+ 4 - 2
client/components/Search/SeriesList/SeriesList.vue

@@ -54,10 +54,10 @@
                     />
                 </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" />
                     Возможно у этой серии были найдены книги, помеченные как удаленные, но подходящие по критериям
-                </div>
+                </div-->
 
                 <div
                     v-if="item.allBooksLoaded && item.allBooksLoaded.length != item.booksLoaded.length"
@@ -230,6 +230,8 @@ class SeriesList extends BaseList {
         newQuery = newQuery.setDefaults(newQuery);
         delete newQuery.setDefaults;
         newQuery.offset = (newQuery.page - 1)*newQuery.limit;
+        if (!this.showDeleted)
+            newQuery.del = 0;
 
         if (_.isEqual(newQuery, this.prevQuery))
             return;

+ 2 - 0
client/components/Search/TitleList/TitleList.vue

@@ -90,6 +90,8 @@ class TitleList extends BaseList {
         newQuery = newQuery.setDefaults(newQuery);
         delete newQuery.setDefaults;
         newQuery.offset = (newQuery.page - 1)*newQuery.limit;
+        if (!this.showDeleted)
+            newQuery.del = 0;
 
         if (_.isEqual(newQuery, this.prevQuery))
             return;

+ 25 - 8
server/core/DbCreator.js

@@ -58,6 +58,8 @@ class DbCreator {
         let genreArr = [];
         let langMap = new Map();//языки
         let langArr = [];
+        let delMap = new Map();//удаленные
+        let delArr = [];
 
         //stats
         let authorCount = 0;
@@ -314,12 +316,16 @@ class DbCreator {
         //парсинг 2, подготовка
         const parseField = (fieldValue, fieldMap, fieldArr, authorIds, bookId) => {
             let addBookId = bookId;
-            if (!fieldValue) {
-                fieldValue = emptyFieldValue;
-                addBookId = 0;//!!!
-            }
+            let value = fieldValue;
+
+            if (typeof(fieldValue) == 'string') {
+                if (!fieldValue) {
+                    fieldValue = emptyFieldValue;
+                    addBookId = 0;//!!!
+                }
 
-            const value = fieldValue.toLowerCase();
+                value = fieldValue.toLowerCase();
+            }
 
             let fieldRec;
             if (fieldMap.has(value)) {
@@ -384,6 +390,9 @@ class DbCreator {
 
             //языки
             parseField(rec.lang, langMap, langArr, authorIds);
+            
+            //удаленные
+            parseField(rec.del, delMap, delArr, authorIds);
         };
 
         callback({job: 'search tables create', jobMessage: 'Создание поисковых таблиц', jobStep: 4, progress: 0});
@@ -437,6 +446,8 @@ class DbCreator {
         seriesMap = null;
         titleMap = null;
         genreMap = null;
+        langMap = null;
+        delMap = null;
 
         utils.freeMemory();
 
@@ -484,13 +495,16 @@ class DbCreator {
         //сохраним поисковые таблицы
         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({
                 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});
         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_time'});

+ 41 - 4
server/core/DbSearcher.js

@@ -24,6 +24,10 @@ class DbSearcher {
         this.periodicCleanCache();//no await
     }
 
+    queryKey(q) {
+        return JSON.stringify([q.author, q.series, q.title, q.genre, q.lang, q.del]);
+    }
+
     getWhere(a) {
         const db = this.db;
 
@@ -226,6 +230,35 @@ class DbSearcher {
             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);
@@ -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 !== '*') {
             closures += `
@@ -569,10 +610,6 @@ class DbSearcher {
         return titleIds;
     }
 
-    queryKey(q) {
-        return JSON.stringify([q.author, q.series, q.title, q.genre, q.lang]);
-    }
-
     async getCached(key) {
         if (!this.config.queryCacheEnabled)
             return null;