mirror of
https://github.com/KingHWJ/WeReadBoard.git
synced 2026-11-03 18:24:58 +08:00
feat: collapsible hierarchical category tags + category sort for shelf
- Backend: add parent_category param (matches '历史-*' sub-categories), sort=category mode (ORDER BY category ASC), return category_tree with parent→sub→count hierarchy - Frontend: replace flat 63-tag list with collapsible parent tags showing book counts, click parent to expand sub-category pills with fade-in animation, click sub to filter to exact category - Add '分类排序' toggle button: when active, books are grouped by category with colored section headers showing category name + count - Clicking same parent again collapses it; '全部' resets everything - Mobile responsive: smaller tag sizes, reduced indent on narrow screens
This commit is contained in:
1 parent
ec88707e6b
commit
e578a90543
4 files changed
+312
-41
No files matched your search
@@ -504,17 +504,21 @@ def api_shelf(conn):
|
||||
page (int): 页码,默认 1
|
||||
per_page (int): 每页数量,默认 60
|
||||
keyword (str): 书名或作者搜索(模糊匹配)
|
||||
category (str): 分类筛选(精确匹配分类名)
|
||||
category (str): 分类筛选(精确匹配完整分类名,如 "历史-中国古代")
|
||||
parent_category (str): 父分类筛选(如 "历史" 匹配所有 "历史-*" 子分类)
|
||||
finished (str): "1" 表示只看已读完
|
||||
sort (str): "category" 表示按分类排序,其他默认按置顶+阅读时间
|
||||
|
||||
Returns:
|
||||
JSON: {books: [...], total, page, per_page, total_pages, categories: [...]}
|
||||
JSON: {books: [...], total, page, per_page, total_pages, categories: [...], category_tree: {...}}
|
||||
"""
|
||||
page = int(request.args.get("page", 1))
|
||||
per_page = int(request.args.get("per_page", 60))
|
||||
keyword = request.args.get("keyword", "").strip()
|
||||
category = request.args.get("category", "").strip()
|
||||
parent_category = request.args.get("parent_category", "").strip()
|
||||
finished_only = request.args.get("finished", "0") == "1"
|
||||
sort_mode = request.args.get("sort", "").strip()
|
||||
|
||||
offset = (page - 1) * per_page
|
||||
cursor = conn.cursor()
|
||||
@@ -528,6 +532,9 @@ def api_shelf(conn):
|
||||
if category:
|
||||
where_clauses.append("category = %s")
|
||||
params.append(category)
|
||||
if parent_category:
|
||||
where_clauses.append("(category = %s OR category LIKE %s)")
|
||||
params.extend([parent_category, f"{parent_category}-%"])
|
||||
if finished_only:
|
||||
where_clauses.append("finish_reading=1")
|
||||
|
||||
@@ -537,16 +544,40 @@ def api_shelf(conn):
|
||||
cursor.execute(f"SELECT COUNT(*) AS cnt FROM books{where_sql}", params)
|
||||
total = cursor.fetchone()["cnt"]
|
||||
|
||||
# 查询当前页数据(置顶优先,最近阅读时间倒序)
|
||||
# 排序
|
||||
if sort_mode == "category":
|
||||
order_sql = " ORDER BY category ASC, is_top DESC, read_update_time DESC"
|
||||
else:
|
||||
order_sql = " ORDER BY is_top DESC, read_update_time DESC"
|
||||
|
||||
# 查询当前页数据
|
||||
cursor.execute(
|
||||
f"SELECT * FROM books{where_sql} ORDER BY is_top DESC, read_update_time DESC LIMIT %s OFFSET %s",
|
||||
f"SELECT * FROM books{where_sql}{order_sql} LIMIT %s OFFSET %s",
|
||||
params + [per_page, offset],
|
||||
)
|
||||
rows = cursor.fetchall()
|
||||
|
||||
# 获取所有分类列表(用于前端筛选下拉框)
|
||||
cursor.execute("SELECT DISTINCT category FROM books WHERE category != '' ORDER BY category")
|
||||
categories = [r["category"] for r in cursor.fetchall()]
|
||||
# 获取所有分类列表及层级树
|
||||
cursor.execute(
|
||||
"SELECT category, COUNT(*) AS cnt FROM books "
|
||||
"WHERE category IS NOT NULL AND category != '' "
|
||||
"GROUP BY category ORDER BY category"
|
||||
)
|
||||
cat_rows = cursor.fetchall()
|
||||
|
||||
# 构建层级树: { "历史": {"count": 114, "subs": {"世界史": 5, "中国古代": 10, ...}}, ... }
|
||||
category_tree = {}
|
||||
for r in cat_rows:
|
||||
parts = r["category"].split("-", 1)
|
||||
parent = parts[0]
|
||||
sub = parts[1] if len(parts) > 1 else ""
|
||||
if parent not in category_tree:
|
||||
category_tree[parent] = {"count": 0, "subs": {}}
|
||||
category_tree[parent]["count"] += r["cnt"]
|
||||
if sub:
|
||||
category_tree[parent]["subs"][sub] = r["cnt"]
|
||||
|
||||
categories = [r["category"] for r in cat_rows]
|
||||
|
||||
books = []
|
||||
for row in rows:
|
||||
@@ -570,6 +601,7 @@ def api_shelf(conn):
|
||||
"per_page": per_page,
|
||||
"total_pages": (total + per_page - 1) // per_page,
|
||||
"categories": categories,
|
||||
"category_tree": category_tree,
|
||||
})
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user