feat: 修正章节排序和分类逻辑

- 新增 SQL 脚本以修正章节排序索引,确保与 8 个分类体系对齐。
- 更新 API 章节获取逻辑,始终返回所有 8 个预定义类别,未填充内容的类别使用占位符。
- 引入章节分类功能,支持从 5-stage 关键词映射到 8 个章节类别,提升内容分类准确性。
- 更新 Android 客户端以适应新的章节定义和占位逻辑,确保用户界面一致性。
This commit is contained in:
penghanyuan
2026-03-01 10:50:58 +01:00
parent c1e2fb31a0
commit 5125ee1564
4 changed files with 131 additions and 40 deletions

View File

@@ -11,17 +11,36 @@ from database import get_async_db
from database.models import Chapter as ChapterModel
from database.models import User as UserModel
from middleware.auth import get_current_user
from agents.prompts.memory_prompts import CHAPTER_CATEGORIES, CHAPTER_ORDER, STAGE_TO_ORDER
router = APIRouter(prefix="/api/chapters", tags=["chapters"])
def _chapter_to_dict(ch: ChapterModel) -> dict:
return {
"id": ch.id,
"title": ch.title,
"content": ch.content,
"order_index": ch.order_index,
"status": ch.status,
"category": ch.category,
"images": ch.images or [],
"updated_at": ch.updated_at.isoformat() if ch.updated_at else None,
"is_new": ch.is_new,
"source_segments": ch.source_segments or [],
}
@router.get("", response_model=List[dict])
async def get_chapters(
current_user: UserModel = Depends(get_current_user),
is_new: Optional[bool] = Query(None, description="仅返回未读章节"),
db: AsyncSession = Depends(get_async_db)
):
"""获取用户所有章节(需要认证,仅返回 active 章节)"""
"""
获取用户所有章节(需要认证,仅返回 active 章节)。
始终返回全部 8 个预定义类别,没有内容的类别用占位符返回。
"""
stmt = select(ChapterModel).where(
ChapterModel.user_id == current_user.id,
ChapterModel.is_active == True
@@ -31,22 +50,37 @@ async def get_chapters(
stmt = stmt.order_by(ChapterModel.order_index)
result = await db.execute(stmt)
chapters = result.scalars().all()
return [
{
"id": ch.id,
"title": ch.title,
"content": ch.content,
"order_index": ch.order_index,
"status": ch.status,
"category": ch.category,
"images": ch.images or [],
"updated_at": ch.updated_at.isoformat() if ch.updated_at else None,
"is_new": ch.is_new,
"source_segments": ch.source_segments or [],
}
for ch in chapters
]
chapter_by_category: dict[str, ChapterModel] = {}
for ch in chapters:
if ch.category and ch.category not in chapter_by_category:
chapter_by_category[ch.category] = ch
all_chapters: List[dict] = []
for category in CHAPTER_ORDER:
ch = chapter_by_category.pop(category, None)
if ch:
all_chapters.append(_chapter_to_dict(ch))
else:
if is_new is True:
continue
all_chapters.append({
"id": f"placeholder_{category}",
"title": CHAPTER_CATEGORIES[category],
"content": "",
"order_index": STAGE_TO_ORDER.get(category, 999),
"status": "empty",
"category": category,
"images": [],
"updated_at": None,
"is_new": False,
"source_segments": [],
})
for ch in chapter_by_category.values():
all_chapters.append(_chapter_to_dict(ch))
return all_chapters
@router.get("/{chapter_id}", response_model=dict)