+
-
+
+{{ extendedParamsMessage }}
+
+
+
+
+
+
+
+
+ {{ extSearchNames }}
+
+
+
+
+
+
+
+ Клонировать поиск
+
+
+
+
@@ -202,7 +232,7 @@
@@ -224,6 +254,7 @@
+
@@ -234,6 +265,7 @@ import vueComponent from '../vueComponent.js';
import AuthorList from './AuthorList/AuthorList.vue';
import SeriesList from './SeriesList/SeriesList.vue';
import TitleList from './TitleList/TitleList.vue';
+import ExtendedList from './ExtendedList/ExtendedList.vue';
import PageScroller from './PageScroller/PageScroller.vue';
import SettingsDialog from './SettingsDialog/SettingsDialog.vue';
@@ -242,6 +274,7 @@ import SelectLangDialog from './SelectLangDialog/SelectLangDialog.vue';
import SelectLibRateDialog from './SelectLibRateDialog/SelectLibRateDialog.vue';
import SelectDateDialog from './SelectDateDialog/SelectDateDialog.vue';
import BookInfoDialog from './BookInfoDialog/BookInfoDialog.vue';
+import SelectExtSearchDialog from './SelectExtSearchDialog/SelectExtSearchDialog.vue';
import authorBooksStorage from './authorBooksStorage';
import DivBtn from '../share/DivBtn.vue';
@@ -252,11 +285,13 @@ import diffUtils from '../../share/diffUtils';
import _ from 'lodash';
+const maxLimit = 1000;
+
const route2component = {
'author': {component: 'AuthorList', label: 'Авторы'},
'series': {component: 'SeriesList', label: 'Серии'},
'title': {component: 'TitleList', label: 'Книги'},
- 'extended': {component: 'TitleList', label: 'Расширенный поиск'},
+ 'extended': {component: 'ExtendedList', label: 'Расширенный поиск'},
};
const componentOptions = {
@@ -264,6 +299,7 @@ const componentOptions = {
AuthorList,
SeriesList,
TitleList,
+ ExtendedList,
PageScroller,
SettingsDialog,
SelectGenreDialog,
@@ -271,6 +307,7 @@ const componentOptions = {
SelectLibRateDialog,
SelectDateDialog,
BookInfoDialog,
+ SelectExtSearchDialog,
Dialog,
DivBtn
},
@@ -293,6 +330,12 @@ const componentOptions = {
this.makeTitle();
this.updateRouteQueryFromSearch();
this.updateSearchDate(true);
+
+ //extSearch
+ if (this.isExtendedSearch) {
+ this.extSearch.page = newValue.page;
+ this.extSearch.limit = newValue.limit;
+ }
},
deep: true,
},
@@ -363,6 +406,7 @@ class Search {
selectLibRateDialogVisible = false;
selectDateDialogVisible = false;
bookInfoDialogVisible = false;
+ selectExtSearchDialogVisible = false;
pageCount = 1;
@@ -381,11 +425,21 @@ class Search {
lang: search.lang || '',
date: search.date || '',
librate: search.librate || '',
+
page: search.page || 1,
limit: search.limit || 50,
});
},
- };
+ };
+
+ extSearch = {
+ setDefaults(search) {
+ return Object.assign({}, search, {
+ page: search.page || 1,
+ limit: search.limit || 50,
+ });
+ },
+ };
searchDate = '';
prevManualDate = '';
@@ -429,6 +483,7 @@ class Search {
this.api = this.$root.api;
this.search = this.search.setDefaults(this.search);
+ this.extSearch = this.extSearch.setDefaults(this.extSearch);
this.search.lang = this.langDefault;
this.loadSettings();
@@ -550,6 +605,14 @@ class Search {
return result.filter(s => s).join(', ');
}
+ get isExtendedSearch() {
+ return this.selectedList === 'extended';
+ }
+
+ get extSearchNames() {
+ return '';
+ }
+
inputBgColor(inp) {
if (inp === this.selectedList)
return 'white';
@@ -750,6 +813,14 @@ class Search {
this.hideTooltip();
this.selectLibRateDialogVisible = true;
}
+
+ selectExtSearch() {
+ this.hideTooltip();
+ this.selectExtSearchDialogVisible = true;
+ }
+
+ clearExtSearch() {
+ }
onScroll() {
const curScrollTop = this.$refs.scroller.scrollTop;
@@ -862,22 +933,35 @@ class Search {
const query = to.query;
- this.search = this.search.setDefaults(
- Object.assign({}, this.search, {
- author: query.author,
- series: query.series,
- title: query.title,
- genre: query.genre,
- lang: (typeof(query.lang) == 'string' ? query.lang : this.langDefault),
- date: query.date,
- librate: query.librate,
- page: parseInt(query.page, 10),
- limit: parseInt(query.limit, 10) || this.search.limit,
- })
- );
+ if (!this.isExtendedSearch) {
+ this.search = this.search.setDefaults(
+ Object.assign({}, this.search, {
+ author: query.author,
+ series: query.series,
+ title: query.title,
+ genre: query.genre,
+ lang: (typeof(query.lang) == 'string' ? query.lang : this.langDefault),
+ date: query.date,
+ librate: query.librate,
- if (this.search.limit > 1000)
- this.search.limit = 1000;
+ page: parseInt(query.page, 10),
+ limit: parseInt(query.limit, 10) || this.search.limit,
+ })
+ );
+
+ if (this.search.limit > maxLimit)
+ this.search.limit = maxLimit;
+ } else {
+ this.extSearch = this.extSearch.setDefaults(
+ Object.assign({}, this.extSearch, {
+ page: parseInt(query.page, 10),
+ limit: parseInt(query.limit, 10) || this.search.limit,
+ })
+ );
+
+ if (this.extSearch.limit > maxLimit)
+ this.extSearch.limit = maxLimit;
+ }
}
updateRouteQueryFromSearch() {
@@ -887,16 +971,24 @@ class Search {
this.routeUpdating = true;
try {
const oldQuery = this.$route.query;
- const cloned = _.cloneDeep(this.search);
+ let query = {};
- delete cloned.setDefaults;
+ if (!this.isExtendedSearch) {
+ const cloned = _.cloneDeep(this.search);
- const query = _.pickBy(cloned);
+ delete cloned.setDefaults;
- if (this.search.lang == this.langDefault) {
- delete query.lang;
+ query = _.pickBy(cloned);
+
+ if (this.search.lang == this.langDefault) {
+ delete query.lang;
+ } else {
+ query.lang = this.search.lang;
+ }
} else {
- query.lang = this.search.lang;
+ const cloned = _.cloneDeep(this.extSearch);
+ delete cloned.setDefaults;
+ query = _.pickBy(cloned);
}
const diff = diffUtils.getObjDiff(oldQuery, query);
diff --git a/client/components/Search/SelectExtSearchDialog/SelectExtSearchDialog.vue b/client/components/Search/SelectExtSearchDialog/SelectExtSearchDialog.vue
new file mode 100644
index 0000000..5fb14fd
--- /dev/null
+++ b/client/components/Search/SelectExtSearchDialog/SelectExtSearchDialog.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/share/utils.js b/client/share/utils.js
index 3607954..2e7fe96 100644
--- a/client/share/utils.js
+++ b/client/share/utils.js
@@ -36,14 +36,14 @@ export function keyEventToCode(event) {
export function wordEnding(num, type = 0) {
const endings = [
- ['ов', '', 'а', 'а', 'а', 'ов', 'ов', 'ов', 'ов', 'ов'],
- ['й', 'я', 'и', 'и', 'и', 'й', 'й', 'й', 'й', 'й'],
- ['о', '', 'о', 'о', 'о', 'о', 'о', 'о', 'о', 'о'],
- ['ий', 'ие', 'ия', 'ия', 'ия', 'ий', 'ий', 'ий', 'ий', 'ий'],
- ['о', 'а', 'о', 'о', 'о', 'о', 'о', 'о', 'о', 'о'],
- ['ок', 'ка', 'ки', 'ки', 'ки', 'ок', 'ок', 'ок', 'ок', 'ок'],
- ['ых', 'ое', 'ых', 'ых', 'ых', 'ых', 'ых', 'ых', 'ых', 'ых'],
- ['о', 'о', 'о', 'о', 'о', 'о', 'о', 'о', 'о', 'о'],
+ ['ов', '', 'а', 'а', 'а', 'ов', 'ов', 'ов', 'ов', 'ов'],//0
+ ['й', 'я', 'и', 'и', 'и', 'й', 'й', 'й', 'й', 'й'],//1
+ ['о', '', 'о', 'о', 'о', 'о', 'о', 'о', 'о', 'о'],//2
+ ['ий', 'ие', 'ия', 'ия', 'ия', 'ий', 'ий', 'ий', 'ий', 'ий'],//3
+ ['о', 'а', 'о', 'о', 'о', 'о', 'о', 'о', 'о', 'о'],//4
+ ['ок', 'ка', 'ки', 'ки', 'ки', 'ок', 'ок', 'ок', 'ок', 'ок'],//5
+ ['ых', 'ое', 'ых', 'ых', 'ых', 'ых', 'ых', 'ых', 'ых', 'ых'],//6
+ ['о', 'о', 'о', 'о', 'о', 'о', 'о', 'о', 'о', 'о'],//7
];
const deci = num % 100;
if (deci > 10 && deci < 20) {
diff --git a/server/core/DbSearcher.js b/server/core/DbSearcher.js
index 0260ab9..c706331 100644
--- a/server/core/DbSearcher.js
+++ b/server/core/DbSearcher.js
@@ -571,6 +571,8 @@ class DbSearcher {
checks.push(filterBySearch(f.field, searchValue));
} if (f.type === 'N') {
searchValue = parseInt(searchValue, 10);
+ if (isNaN(searchValue))
+ throw new Error(`Wrong query param, ${f.field}=${searchValue}`);
checks.push(`row.${f.field} === ${searchValue}`);
}
}