feat(auto): 按作者筛选小说
This commit is contained in:
parent
db1208b981
commit
49bb95604b
@ -467,6 +467,22 @@ body:has(.reader-mode) #toast {
|
|||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.clickable-author {
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--primary);
|
||||||
|
transition: color var(--transition-fast);
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
padding: 2px 4px;
|
||||||
|
margin: -2px -4px;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.clickable-author:active {
|
||||||
|
color: var(--primary-dark);
|
||||||
|
background: var(--bg-hover);
|
||||||
|
}
|
||||||
|
|
||||||
.novel-synopsis {
|
.novel-synopsis {
|
||||||
font-size: var(--font-size-sm);
|
font-size: var(--font-size-sm);
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
|
|||||||
@ -169,6 +169,49 @@
|
|||||||
color: var(--bg-primary);
|
color: var(--bg-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 筛选信息 */
|
||||||
|
.filter-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--spacing-sm);
|
||||||
|
padding: var(--spacing-sm) var(--spacing-md);
|
||||||
|
margin-bottom: var(--spacing-md);
|
||||||
|
background: var(--bg-hover);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-label {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-value {
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-filter-btn {
|
||||||
|
margin-left: auto;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: var(--radius-full);
|
||||||
|
transition: all var(--transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-filter-btn:active {
|
||||||
|
background: var(--bg-card);
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
/* 小说列表 */
|
/* 小说列表 */
|
||||||
.novel-list {
|
.novel-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -465,6 +508,11 @@
|
|||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.detail-author.clickable-author {
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
.detail-stats {
|
.detail-stats {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--spacing-lg);
|
gap: var(--spacing-lg);
|
||||||
|
|||||||
@ -231,7 +231,7 @@ const App = (function() {
|
|||||||
$('.tag-btn').removeClass('active');
|
$('.tag-btn').removeClass('active');
|
||||||
$(this).addClass('active');
|
$(this).addClass('active');
|
||||||
const tag = $(this).data('tag');
|
const tag = $(this).data('tag');
|
||||||
Pages.loadNovels(0, tag);
|
Pages.loadNovels(0, tag, null); // 清除作者筛选,只按标签筛选
|
||||||
});
|
});
|
||||||
|
|
||||||
// 加载更多(追加模式,保持当前筛选条件)
|
// 加载更多(追加模式,保持当前筛选条件)
|
||||||
@ -255,10 +255,22 @@ const App = (function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 点击作者名字,筛选该作者的作品
|
||||||
|
$(document).on('click', '.clickable-author', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
const author = $(this).data('author');
|
||||||
|
if (author) {
|
||||||
|
Pages.searchByAuthor(author);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 其他页面的小说卡片点击
|
// 其他页面的小说卡片点击
|
||||||
$(document).on('click', '.novel-card, .novel-grid-card, .shelf-item', function(e) {
|
$(document).on('click', '.novel-card, .novel-grid-card, .shelf-item', function(e) {
|
||||||
// 如果是搜索结果中的,上面的事件已处理,这里跳过
|
// 如果是搜索结果中的,上面的事件已处理,这里跳过
|
||||||
if ($(this).closest('#search-results').length) return;
|
if ($(this).closest('#search-results').length) return;
|
||||||
|
// 如果点击的是作者名字,跳过(上面的事件已处理)
|
||||||
|
if ($(e.target).hasClass('clickable-author') || $(e.target).closest('.clickable-author').length) return;
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if ($(e.target).closest('button').length) return;
|
if ($(e.target).closest('button').length) return;
|
||||||
@ -386,6 +398,13 @@ const App = (function() {
|
|||||||
$text.toggleClass('text-clamp-3');
|
$text.toggleClass('text-clamp-3');
|
||||||
$(this).text($text.hasClass('text-clamp-3') ? '展开' : '收起');
|
$(this).text($text.hasClass('text-clamp-3') ? '展开' : '收起');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 加载更多按钮(使用事件委托,在pages.js中也有绑定,这里作为备用)
|
||||||
|
$(document).on('click', '.load-more-btn', function() {
|
||||||
|
if (Pages.hasMore()) {
|
||||||
|
Pages.loadNovels(Pages.currentPage() + 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 搜索功能 ==========
|
// ========== 搜索功能 ==========
|
||||||
|
|||||||
@ -208,7 +208,7 @@ const Pages = (function() {
|
|||||||
</div>
|
</div>
|
||||||
<div class="novel-info">
|
<div class="novel-info">
|
||||||
<div class="novel-title text-ellipsis">${novel.name}</div>
|
<div class="novel-title text-ellipsis">${novel.name}</div>
|
||||||
<div class="novel-author text-ellipsis">${novel.author}</div>
|
<div class="novel-author text-ellipsis clickable-author" data-author="${novel.author || ''}">${novel.author || '未知'}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@ -262,31 +262,42 @@ const Pages = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadNovels(page, tag = null, append = false) {
|
let currentAuthor = null; // 保存当前选择的作者
|
||||||
|
|
||||||
|
async function loadNovels(page, tag = null, author = null, append = false) {
|
||||||
if (isLoadingMore) return;
|
if (isLoadingMore) return;
|
||||||
isLoadingMore = true;
|
isLoadingMore = true;
|
||||||
|
|
||||||
// 如果不是追加加载,保存当前标签
|
// 如果不是追加加载,保存当前筛选条件
|
||||||
if (!append) {
|
if (!append) {
|
||||||
currentPage = 0;
|
currentPage = 0;
|
||||||
hasMore = true;
|
hasMore = true;
|
||||||
currentTag = tag; // 保存当前选择的标签
|
currentTag = tag; // 保存当前选择的标签
|
||||||
|
currentAuthor = author; // 保存当前选择的作者
|
||||||
$('#novel-list').html(renderSkeletonList(5));
|
$('#novel-list').html(renderSkeletonList(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 追加加载时使用已保存的标签
|
// 追加加载时使用已保存的筛选条件
|
||||||
const useTag = append ? currentTag : tag;
|
const useTag = append ? currentTag : tag;
|
||||||
|
const useAuthor = append ? currentAuthor : author;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const params = { page, size: 20 };
|
const params = { page, size: 20 };
|
||||||
if (useTag) params.tag = useTag;
|
if (useTag) params.tag = useTag;
|
||||||
|
if (useAuthor) params.keyword = useAuthor; // 使用keyword参数搜索作者
|
||||||
|
|
||||||
const data = await API.searchNovels(params);
|
const data = await API.searchNovels(params);
|
||||||
const novels = data.content || [];
|
const novels = data.content || [];
|
||||||
hasMore = !data.last;
|
hasMore = !data.last;
|
||||||
|
|
||||||
|
// 如果有作者筛选,只保留该作者的作品
|
||||||
|
let filteredNovels = novels;
|
||||||
|
if (useAuthor) {
|
||||||
|
filteredNovels = novels.filter(novel => novel.author === useAuthor);
|
||||||
|
}
|
||||||
|
|
||||||
let html = '';
|
let html = '';
|
||||||
novels.forEach(novel => {
|
filteredNovels.forEach(novel => {
|
||||||
const isInShelf = Store.isInShelfCache(novel.id);
|
const isInShelf = Store.isInShelfCache(novel.id);
|
||||||
html += renderNovelCard(novel, isInShelf);
|
html += renderNovelCard(novel, isInShelf);
|
||||||
});
|
});
|
||||||
@ -294,11 +305,19 @@ const Pages = (function() {
|
|||||||
if (append) {
|
if (append) {
|
||||||
$('#novel-list').append(html);
|
$('#novel-list').append(html);
|
||||||
} else {
|
} else {
|
||||||
$('#novel-list').html(html || '<div class="empty-state"><p>暂无小说</p></div>');
|
// 显示筛选信息
|
||||||
|
let filterInfo = '';
|
||||||
|
if (useAuthor) {
|
||||||
|
filterInfo = `<div class="filter-info"><span class="filter-label">作者:</span><span class="filter-value">${useAuthor}</span><button class="clear-filter-btn" data-type="author">×</button></div>`;
|
||||||
|
} else if (useTag) {
|
||||||
|
filterInfo = `<div class="filter-info"><span class="filter-label">标签:</span><span class="filter-value">${useTag}</span><button class="clear-filter-btn" data-type="tag">×</button></div>`;
|
||||||
|
}
|
||||||
|
const listHtml = html || '<div class="empty-state"><p>暂无小说</p></div>';
|
||||||
|
$('#novel-list').html(filterInfo ? (filterInfo + listHtml) : listHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新加载更多按钮
|
// 更新加载更多按钮
|
||||||
if (hasMore) {
|
if (hasMore && filteredNovels.length > 0) {
|
||||||
$('#load-more').html('<button class="load-more-btn">加载更多</button>');
|
$('#load-more').html('<button class="load-more-btn">加载更多</button>');
|
||||||
} else {
|
} else {
|
||||||
$('#load-more').html('<span style="color:var(--text-muted);font-size:14px;">没有更多了</span>');
|
$('#load-more').html('<span style="color:var(--text-muted);font-size:14px;">没有更多了</span>');
|
||||||
@ -311,6 +330,23 @@ const Pages = (function() {
|
|||||||
handleCoverError(this);
|
handleCoverError(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 重新绑定清除筛选按钮事件(只在非追加模式下绑定,避免重复绑定)
|
||||||
|
if (!append) {
|
||||||
|
$(document).off('click', '.clear-filter-btn').on('click', '.clear-filter-btn', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
const filterType = $(this).data('type');
|
||||||
|
if (filterType === 'author') {
|
||||||
|
currentAuthor = null;
|
||||||
|
loadNovels(0, currentTag, null);
|
||||||
|
} else if (filterType === 'tag') {
|
||||||
|
currentTag = null;
|
||||||
|
$('.tag-btn').removeClass('active');
|
||||||
|
loadNovels(0, null, currentAuthor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载小说失败:', error);
|
console.error('加载小说失败:', error);
|
||||||
Toast.show('加载失败,请重试');
|
Toast.show('加载失败,请重试');
|
||||||
@ -332,7 +368,7 @@ const Pages = (function() {
|
|||||||
</div>
|
</div>
|
||||||
<div class="novel-info">
|
<div class="novel-info">
|
||||||
<div class="novel-title text-ellipsis">${novel.name}</div>
|
<div class="novel-title text-ellipsis">${novel.name}</div>
|
||||||
<div class="novel-author">${novel.author}</div>
|
<div class="novel-author clickable-author" data-author="${novel.author || ''}">${novel.author || '未知'}</div>
|
||||||
<div class="novel-synopsis text-clamp-2">${synopsis}...</div>
|
<div class="novel-synopsis text-clamp-2">${synopsis}...</div>
|
||||||
<div class="novel-tags">
|
<div class="novel-tags">
|
||||||
${tags.map(t => `<span class="tag">${t}</span>`).join('')}
|
${tags.map(t => `<span class="tag">${t}</span>`).join('')}
|
||||||
@ -569,7 +605,7 @@ const Pages = (function() {
|
|||||||
</div>
|
</div>
|
||||||
<div class="detail-meta">
|
<div class="detail-meta">
|
||||||
<h1 class="detail-title">${novel.name}</h1>
|
<h1 class="detail-title">${novel.name}</h1>
|
||||||
<div class="detail-author">${novel.author}</div>
|
<div class="detail-author clickable-author" data-author="${novel.author || ''}">${novel.author || '未知'}</div>
|
||||||
<div class="detail-stats">
|
<div class="detail-stats">
|
||||||
<div class="detail-stat">
|
<div class="detail-stat">
|
||||||
<div class="detail-stat-value">${novel.chapterCount || 0}</div>
|
<div class="detail-stat-value">${novel.chapterCount || 0}</div>
|
||||||
@ -750,6 +786,22 @@ const Pages = (function() {
|
|||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 按作者搜索(公开函数)
|
||||||
|
function searchByAuthor(author) {
|
||||||
|
if (!author) return;
|
||||||
|
// 切换到发现页面
|
||||||
|
if (window.location.hash !== '#/explore') {
|
||||||
|
window.location.hash = '#/explore';
|
||||||
|
// 等待页面渲染完成后加载该作者的作品
|
||||||
|
setTimeout(() => {
|
||||||
|
loadNovels(0, null, author);
|
||||||
|
}, 300);
|
||||||
|
} else {
|
||||||
|
// 如果已经在发现页面,直接加载
|
||||||
|
loadNovels(0, null, author);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 公开API
|
// 公开API
|
||||||
return {
|
return {
|
||||||
renderShelf,
|
renderShelf,
|
||||||
@ -760,6 +812,7 @@ const Pages = (function() {
|
|||||||
renderSearchResults,
|
renderSearchResults,
|
||||||
renderSearchByTag,
|
renderSearchByTag,
|
||||||
loadNovels,
|
loadNovels,
|
||||||
|
searchByAuthor,
|
||||||
currentPage: () => currentPage,
|
currentPage: () => currentPage,
|
||||||
hasMore: () => hasMore
|
hasMore: () => hasMore
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user