Работа над проектом

This commit is contained in:
Book Pauk
2022-08-21 21:10:56 +07:00
parent c7073635e3
commit 705fce73f7
7 changed files with 172 additions and 28 deletions

View File

@@ -54,6 +54,16 @@ class Api {
return response; return response;
} }
async getBookList(authorId) {
const response = await this.request({action: 'get-book-list', authorId});
if (response.error) {
throw new Error(response.error);
}
return response;
}
async getConfig() { async getConfig() {
const response = await this.request({action: 'get-config'}); const response = await this.request({action: 'get-config'});

View File

@@ -83,23 +83,30 @@
<!-- Формирование списка ------------------------------------------------------------------------> <!-- Формирование списка ------------------------------------------------------------------------>
<div v-for="item in tableData" :key="item.key" class="column" :class="{'odd-author': item.num % 2}" style="font-size: 120%"> <div v-for="item in tableData" :key="item.key" class="column" :class="{'odd-author': item.num % 2}" style="font-size: 120%">
<div class="row items-center q-ml-md q-my-xs no-wrap"> <div class="row items-center q-ml-md q-mr-xs no-wrap">
<div class="clickable q-mr-sm q-pa-xs"> <div style="width: 30px">
<div v-if="!isExpanded(item)" @click="expandAuthor(item, true)"> <DivBtn v-if="tableData.length > 1" :icon-size="24" icon="la la-check-circle" @click="selectAuthor(item.author)">
<q-icon name="la la-plus-square" size="24px" /> <q-tooltip :delay="1500" anchor="bottom right" content-style="font-size: 80%">
</div> Только этот автор
<div v-else @click="expandAuthor(item, false)"> </q-tooltip>
<q-icon name="la la-minus-square" size="24px" /> </DivBtn>
</div>
</div> </div>
<div class="clickable" style="font-weight: bold" @click="authorClick(item.author)"> <div class="row items-center clickable q-mr-sm q-pa-xs" @click="expandAuthor(item)">
{{ item.name }} <div v-if="!isExpanded(item)">
<q-icon name="la la-plus-square" size="28px" />
</div>
<div v-else>
<q-icon name="la la-minus-square" size="28px" />
</div>
<div class="q-ml-xs" style="font-weight: bold">
{{ item.name }}
</div>
</div> </div>
</div> </div>
<div v-if="isExpanded(item) && item.books"> <div v-if="isExpanded(item) && item.books">
{{ item.books[0] }} {{ item.books }}
</div> </div>
</div> </div>
<!-- Формирование списка конец ------------------------------------------------------------------> <!-- Формирование списка конец ------------------------------------------------------------------>
@@ -118,6 +125,8 @@ import vueComponent from '../vueComponent.js';
const { reactive } = require('@vue/reactivity'); const { reactive } = require('@vue/reactivity');
import PageScroller from './PageScroller/PageScroller.vue'; import PageScroller from './PageScroller/PageScroller.vue';
import DivBtn from '../share/DivBtn.vue';
import * as utils from '../../share/utils'; import * as utils from '../../share/utils';
import _ from 'lodash'; import _ from 'lodash';
@@ -125,6 +134,7 @@ import _ from 'lodash';
const componentOptions = { const componentOptions = {
components: { components: {
PageScroller, PageScroller,
DivBtn
}, },
watch: { watch: {
config() { config() {
@@ -301,7 +311,7 @@ class Search {
this.page = 1; this.page = 1;
} }
authorClick(author) { selectAuthor(author) {
this.author = `=${author}`; this.author = `=${author}`;
} }
@@ -309,11 +319,11 @@ class Search {
return this.expanded.indexOf(item.author) >= 0; return this.expanded.indexOf(item.author) >= 0;
} }
expandAuthor(item, expand = true) { expandAuthor(item) {
const expanded = _.cloneDeep(this.expanded); const expanded = _.cloneDeep(this.expanded);
const author = item.author; const author = item.author;
if (expand) { if (!this.isExpanded(item)) {
if (expanded.indexOf(author) < 0) { if (expanded.indexOf(author) < 0) {
expanded.push(author); expanded.push(author);
@@ -334,26 +344,39 @@ class Search {
} }
} }
async loadBooks() { async loadBooks(authorId) {
let inSearch = true;
(async() => {
await utils.sleep(500);
if (inSearch)
this.loadingMessage = 'Загрузка списка книг...';
})();
try {
const result = await this.api.getBookList(authorId);
return result;
} catch (e) {
this.$root.stdDialog.alert(e.message, 'Ошибка');
return;
} finally {
inSearch = false;
this.loadingMessage = '';
}
} }
async getBooks(item) { async getBooks(item) {
if (item.books) if (item.books)
return; return;
await utils.sleep(1000); item.books = await this.loadBooks(item.key);
item.books = [{name: 'book1'}];
} }
async updateTableData() { async updateTableData() {
let result = []; let result = [];
const authors = this.searchResult.author;
if (authors.length == 1) {
this.expandAuthor(authors[0]);
}
const expandedSet = new Set(this.expanded); const expandedSet = new Set(this.expanded);
const authors = this.searchResult.author;
let num = 0; let num = 0;
for (const rec of authors) { for (const rec of authors) {
@@ -373,6 +396,10 @@ class Search {
result.push(item); result.push(item);
} }
if (result.length == 1 && !this.isExpanded(result[0])) {
this.expandAuthor(result[0]);
}
this.tableData = result; this.tableData = result;
} }

View File

@@ -0,0 +1,54 @@
<template>
<div ref="btn" class="clickable row justify-center items-center">
<q-icon :name="icon" :size="`${iconSize}px`" />
<slot></slot>
</div>
</template>
<script>
//-----------------------------------------------------------------------------
import vueComponent from '../vueComponent.js';
//import * as utils from '../../share/utils';
const componentOptions = {
watch: {
size() {
this.updateSizes();
},
}
};
class DivBtn {
_options = componentOptions;
_props = {
size: { type: Number, default: 24 },
icon: { type: String, default: '' },
iconSize: { type: Number, default: 14 },
round: { type: Boolean },
};
created() {
}
mounted() {
this.updateSizes();
}
updateSizes() {
this.$refs.btn.style.width = `${this.size}px`;
this.$refs.btn.style.height = `${this.size}px`;
if (this.round)
this.$refs.btn.style.borderRadius = `${this.size}px`;
}
}
export default vueComponent(DivBtn);
//-----------------------------------------------------------------------------
</script>
<style scoped>
.clickable-icon {
cursor: pointer;
}
</style>

View File

@@ -21,7 +21,7 @@ import {QIcon} from 'quasar/src/components/icon';
//import {QSeparator} from 'quasar/src/components/separator'; //import {QSeparator} from 'quasar/src/components/separator';
//import {QList} from 'quasar/src/components/item'; //import {QList} from 'quasar/src/components/item';
//import {QItem, QItemSection, QItemLabel} from 'quasar/src/components/item'; //import {QItem, QItemSection, QItemLabel} from 'quasar/src/components/item';
//import {QTooltip} from 'quasar/src/components/tooltip'; import {QTooltip} from 'quasar/src/components/tooltip';
import {QSpinner} from 'quasar/src/components/spinner'; import {QSpinner} from 'quasar/src/components/spinner';
//import {QTable, QTh, QTr, QTd} from 'quasar/src/components/table'; //import {QTable, QTh, QTr, QTd} from 'quasar/src/components/table';
//import {QCheckbox} from 'quasar/src/components/checkbox'; //import {QCheckbox} from 'quasar/src/components/checkbox';
@@ -52,7 +52,7 @@ const components = {
//QSeparator, //QSeparator,
//QList, //QList,
//QItem, QItemSection, QItemLabel, //QItem, QItemSection, QItemLabel,
//QTooltip, QTooltip,
QSpinner, QSpinner,
//QTable, QTh, QTr, QTd, //QTable, QTh, QTr, QTd,
//QCheckbox, //QCheckbox,

View File

@@ -4,7 +4,7 @@ const _ = require('lodash');
const WorkerState = require('../core/WorkerState');//singleton const WorkerState = require('../core/WorkerState');//singleton
const WebWorker = require('../core/WebWorker');//singleton const WebWorker = require('../core/WebWorker');//singleton
const log = new (require('../core/AppLogger'))().log;//singleton const log = new (require('../core/AppLogger'))().log;//singleton
//const utils = require('../core/utils'); const utils = require('../core/utils');
const cleanPeriod = 1*60*1000;//1 минута const cleanPeriod = 1*60*1000;//1 минута
const closeSocketOnIdle = 5*60*1000;//5 минут const closeSocketOnIdle = 5*60*1000;//5 минут
@@ -68,6 +68,8 @@ class WebSocketController {
await this.getWorkerState(req, ws); break; await this.getWorkerState(req, ws); break;
case 'search': case 'search':
await this.search(req, ws); break; await this.search(req, ws); break;
case 'get-book-list':
await this.getBookList(req, ws); break;
default: default:
throw new Error(`Action not found: ${req.action}`); throw new Error(`Action not found: ${req.action}`);
@@ -122,6 +124,15 @@ class WebSocketController {
this.send(result, req, ws); this.send(result, req, ws);
} }
async getBookList(req, ws) {
if (!utils.hasProp(req, 'authorId'))
throw new Error(`authorId is empty`);
const result = await this.webWorker.getBookList(req.authorId);
this.send(result, req, ws);
}
} }
module.exports = WebSocketController; module.exports = WebSocketController;

View File

@@ -193,7 +193,7 @@ class DbSearcher {
//сначала попробуем найти в кеше //сначала попробуем найти в кеше
const q = query; const q = query;
const keyArr = [q.author, q.series, q.title, q.genre, q.lang]; const keyArr = [q.author, q.series, q.title, q.genre, q.lang];
const keyStr = keyArr.join(''); const keyStr = `query-${keyArr.join('')}`;
if (!keyStr) {//пустой запрос if (!keyStr) {//пустой запрос
if (db.searchCache.authorIdsAll) if (db.searchCache.authorIdsAll)
@@ -262,6 +262,42 @@ class DbSearcher {
} }
} }
async getBookList(authorId) {
if (this.closed)
throw new Error('DbSearcher closed');
this.searchFlag++;
try {
const db = this.db;
//выборка автора по authorId
const rows = await db.select({
table: 'author',
map: `(r) => ({author: r.author, bookId: r.bookId})`,
where: `@@id(${db.esc(authorId)})`
});
let author = '';
let result = [];
if (rows.length) {
author = rows[0].author;
//выборка книг по bookId
result = await db.select({
table: 'book',
//map: `(r) => ({})`,
where: `@@id(${db.esc(rows[0].bookId)})`,
});
}
return {author, books: result};
} finally {
this.searchFlag--;
}
}
async periodicCleanCache() { async periodicCleanCache() {
this.timer = null; this.timer = null;
const cleanInterval = 5*1000;//this.config.cacheCleanInterval*60*1000; const cleanInterval = 5*1000;//this.config.cacheCleanInterval*60*1000;

View File

@@ -195,7 +195,13 @@ class WebWorker {
totalFound: result.totalFound, totalFound: result.totalFound,
inpxHash: (config.inpxHash ? config.inpxHash : ''), inpxHash: (config.inpxHash ? config.inpxHash : ''),
}; };
} }
async getBookList(authorId) {
this.checkMyState();
return await this.dbSearcher.getBookList(authorId);
}
async logServerStats() { async logServerStats() {
while (1) {// eslint-disable-line while (1) {// eslint-disable-line