Добавлено кеширование запросов на клиенте
This commit is contained in:
@@ -151,6 +151,7 @@
|
||||
|
||||
<q-checkbox v-model="showCounts" size="36px" label="Показывать количество" />
|
||||
<q-checkbox v-model="showDeleted" size="36px" label="Показывать удаленные" />
|
||||
<q-checkbox v-model="abCacheEnabled" size="36px" label="Кешировать запросы" />
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
@@ -168,6 +169,7 @@ import vueComponent from '../vueComponent.js';
|
||||
import { reactive } from 'vue';
|
||||
|
||||
import PageScroller from './PageScroller/PageScroller.vue';
|
||||
import authorBooksStorage from './authorBooksStorage';
|
||||
import DivBtn from '../share/DivBtn.vue';
|
||||
import Dialog from '../share/Dialog.vue';
|
||||
|
||||
@@ -218,6 +220,9 @@ const componentOptions = {
|
||||
showDeleted(newValue) {
|
||||
this.setSetting('showDeleted', newValue);
|
||||
},
|
||||
abCacheEnabled(newValue) {
|
||||
this.setSetting('abCacheEnabled', newValue);
|
||||
},
|
||||
totalFound() {
|
||||
this.updatePageCount();
|
||||
},
|
||||
@@ -250,11 +255,13 @@ class Search {
|
||||
expanded = [];
|
||||
showCounts = true;
|
||||
showDeleted = false;
|
||||
abCacheEnabled = true;
|
||||
|
||||
//stuff
|
||||
queryFound = -1;
|
||||
totalFound = 0;
|
||||
bookRowsOnPage = 100;
|
||||
inpxHash = '';
|
||||
|
||||
limitOptions = [
|
||||
{label: '10', value: 10},
|
||||
@@ -276,6 +283,9 @@ class Search {
|
||||
}
|
||||
|
||||
mounted() {
|
||||
(async() => {
|
||||
await authorBooksStorage.init();
|
||||
|
||||
this.api = this.$root.api;
|
||||
|
||||
if (!this.$root.isMobileDevice)
|
||||
@@ -283,6 +293,7 @@ class Search {
|
||||
|
||||
this.ready = true;
|
||||
this.refresh();//no await
|
||||
})();
|
||||
}
|
||||
|
||||
loadSettings() {
|
||||
@@ -290,7 +301,9 @@ class Search {
|
||||
|
||||
this.limit = settings.limit;
|
||||
this.expanded = _.cloneDeep(settings.expanded);
|
||||
this.showCounts = settings.showCounts;
|
||||
this.showDeleted = settings.showDeleted;
|
||||
this.abCacheEnabled = settings.abCacheEnabled;
|
||||
}
|
||||
|
||||
get config() {
|
||||
@@ -438,9 +451,23 @@ class Search {
|
||||
return `(${result})`;
|
||||
}
|
||||
|
||||
async loadBooks(author, authorId) {
|
||||
async loadBooks(authorId) {
|
||||
try {
|
||||
const result = await this.api.getBookList(authorId);
|
||||
let result;
|
||||
|
||||
const key = `${authorId}-${this.inpxHash}`;
|
||||
|
||||
if (this.abCacheEnabled) {
|
||||
const data = await authorBooksStorage.getData(key);
|
||||
if (data) {
|
||||
result = JSON.parse(data);
|
||||
} else {
|
||||
result = await this.api.getBookList(authorId);
|
||||
await authorBooksStorage.setData(key, JSON.stringify(result));
|
||||
}
|
||||
} else {
|
||||
result = await this.api.getBookList(authorId);
|
||||
}
|
||||
|
||||
return JSON.parse(result.books);
|
||||
} catch (e) {
|
||||
@@ -470,7 +497,7 @@ class Search {
|
||||
})();
|
||||
}
|
||||
|
||||
const loadedBooks = await this.loadBooks(item.author, item.key);
|
||||
const loadedBooks = await this.loadBooks(item.key);
|
||||
|
||||
const filtered = this.filterBooks(loadedBooks);
|
||||
|
||||
@@ -561,6 +588,7 @@ class Search {
|
||||
|
||||
this.queryFound = result.author.length;
|
||||
this.totalFound = result.totalFound;
|
||||
this.inpxHash = result.inpxHash;
|
||||
|
||||
this.searchResult = result;
|
||||
await this.updateTableData();
|
||||
|
||||
74
client/components/Search/authorBooksStorage.js
Normal file
74
client/components/Search/authorBooksStorage.js
Normal file
@@ -0,0 +1,74 @@
|
||||
import localForage from 'localforage';
|
||||
//import _ from 'lodash';
|
||||
import * as utils from '../../share/utils';
|
||||
|
||||
const maxDataSize = 100*1024*1024;
|
||||
|
||||
const abStore = localForage.createInstance({
|
||||
name: 'authorBooksStorage'
|
||||
});
|
||||
|
||||
class AuthorBooksStorage {
|
||||
constructor() {
|
||||
}
|
||||
|
||||
async init() {
|
||||
this.cleanStorage(); //no await
|
||||
}
|
||||
|
||||
async setData(key, data) {
|
||||
if (typeof data !== 'string')
|
||||
throw new Error('AuthorBooksStorage: data must be a string');
|
||||
|
||||
await abStore.setItem(key, data);
|
||||
await abStore.setItem(`addTime-${key}`, Date.now());
|
||||
}
|
||||
|
||||
async getData(key) {
|
||||
const item = await abStore.getItem(key);
|
||||
|
||||
//обновим addTime
|
||||
if (item !== undefined)
|
||||
abStore.setItem(`addTime-${key}`, Date.now());//no await
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
async removeData(key) {
|
||||
await abStore.removeItem(key);
|
||||
await abStore.removeItem(`addTime-${key}`);
|
||||
}
|
||||
|
||||
async cleanStorage() {
|
||||
await utils.sleep(5000);
|
||||
|
||||
while (1) {// eslint-disable-line no-constant-condition
|
||||
let size = 0;
|
||||
let min = Date.now();
|
||||
let toDel = null;
|
||||
for (const key of (await abStore.keys())) {
|
||||
if (key.indexOf('addTime-') == 0)
|
||||
continue;
|
||||
|
||||
const item = await abStore.getItem(key);
|
||||
const addTime = await abStore.getItem(`addTime-${key}`);
|
||||
|
||||
size += item.length;
|
||||
|
||||
if (addTime < min) {
|
||||
toDel = key;
|
||||
min = addTime;
|
||||
}
|
||||
}
|
||||
|
||||
if (size > maxDataSize && toDel) {
|
||||
await this.removeData(toDel);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default new AuthorBooksStorage();
|
||||
@@ -6,6 +6,7 @@ const state = {
|
||||
expanded: [],
|
||||
showCounts: true,
|
||||
showDeleted: false,
|
||||
abCacheEnabled: true,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user