feat: 游玩记录支持区分原故事和AI草稿,已下架草稿显示标签

This commit is contained in:
wangwuww111
2026-03-13 12:28:42 +08:00
parent 411110ce0c
commit 4a69bf2711
8 changed files with 449 additions and 99 deletions

View File

@@ -52,6 +52,7 @@ class CollectRequest(BaseModel):
class PlayRecordRequest(BaseModel):
userId: int
storyId: int
draftId: Optional[int] = None # AI草稿ID原故事为空
endingName: str
endingType: str = ""
pathHistory: list
@@ -364,24 +365,79 @@ async def toggle_collect(request: CollectRequest, db: AsyncSession = Depends(get
@router.get("/collections")
async def get_collections(user_id: int = Query(..., alias="userId"), db: AsyncSession = Depends(get_db)):
"""获取收藏列表"""
result = await db.execute(
select(Story)
"""获取收藏列表包含原故事和AI改写草稿"""
from app.models.story import StoryDraft, DraftStatus
# 查询收藏的原故事
original_result = await db.execute(
select(Story, UserProgress.updated_at)
.join(UserProgress, Story.id == UserProgress.story_id)
.where(UserProgress.user_id == user_id, UserProgress.is_collected == True)
.order_by(UserProgress.updated_at.desc())
)
stories = result.scalars().all()
original_stories = original_result.all()
data = [{
"id": s.id,
"title": s.title,
"cover_url": s.cover_url,
"description": s.description,
"category": s.category,
"play_count": s.play_count,
"like_count": s.like_count
} for s in stories]
# 查询收藏的草稿
draft_result = await db.execute(
select(StoryDraft, Story.title.label('story_title'), Story.category, Story.cover_url)
.join(Story, StoryDraft.story_id == Story.id)
.where(
StoryDraft.user_id == user_id,
StoryDraft.is_collected == True,
StoryDraft.status == DraftStatus.completed
)
.order_by(StoryDraft.created_at.desc())
)
drafts = draft_result.all()
# 按 story_id 分组
collections = {}
# 处理原故事
for story, updated_at in original_stories:
story_id = story.id
if story_id not in collections:
collections[story_id] = {
"storyId": story_id,
"storyTitle": story.title,
"category": story.category,
"coverUrl": story.cover_url,
"versions": []
}
collections[story_id]["versions"].append({
"type": "original",
"id": story_id,
"title": story.title,
"draftId": None
})
# 处理草稿
for row in drafts:
draft = row[0]
story_title = row[1]
category = row[2]
cover_url = row[3]
story_id = draft.story_id
if story_id not in collections:
collections[story_id] = {
"storyId": story_id,
"storyTitle": story_title,
"category": category,
"coverUrl": cover_url,
"versions": []
}
collections[story_id]["versions"].append({
"type": draft.draft_type or "rewrite",
"id": draft.id,
"title": draft.title or f"{story_title}-{draft.draft_type}",
"draftId": draft.id
})
# 转换为列表,添加版本数量
data = []
for item in collections.values():
item["versionCount"] = len(item["versions"])
data.append(item)
return {"code": 0, "data": data}
@@ -511,11 +567,17 @@ async def save_play_record(request: PlayRecordRequest, db: AsyncSession = Depend
"""保存游玩记录(相同路径只保留最新)"""
import json
# 查找该用户该故事的所有记录
result = await db.execute(
select(PlayRecord)
.where(PlayRecord.user_id == request.userId, PlayRecord.story_id == request.storyId)
# 查找该用户该故事的所有记录(区分原故事和草稿)
query = select(PlayRecord).where(
PlayRecord.user_id == request.userId,
PlayRecord.story_id == request.storyId
)
if request.draftId:
query = query.where(PlayRecord.draft_id == request.draftId)
else:
query = query.where(PlayRecord.draft_id == None)
result = await db.execute(query)
existing_records = result.scalars().all()
# 检查是否有相同路径的记录
@@ -530,6 +592,7 @@ async def save_play_record(request: PlayRecordRequest, db: AsyncSession = Depend
record = PlayRecord(
user_id=request.userId,
story_id=request.storyId,
draft_id=request.draftId,
ending_name=request.endingName,
ending_type=request.endingType,
path_history=request.pathHistory
@@ -554,8 +617,10 @@ async def get_play_records(
db: AsyncSession = Depends(get_db)
):
"""获取游玩记录列表"""
from app.models.story import StoryDraft
if story_id:
# 获取指定故事的记录
# 获取指定故事的记录(包含草稿发布状态)
result = await db.execute(
select(PlayRecord)
.where(PlayRecord.user_id == user_id, PlayRecord.story_id == story_id)
@@ -563,12 +628,33 @@ async def get_play_records(
)
records = result.scalars().all()
data = [{
"id": r.id,
"endingName": r.ending_name,
"endingType": r.ending_type,
"createdAt": r.created_at.strftime("%Y-%m-%d %H:%M") if r.created_at else ""
} for r in records]
# 获取相关草稿的发布状态
draft_ids = [r.draft_id for r in records if r.draft_id]
draft_status = {}
if draft_ids:
draft_result = await db.execute(
select(StoryDraft.id, StoryDraft.published_to_center, StoryDraft.title)
.where(StoryDraft.id.in_(draft_ids))
)
for d in draft_result.all():
draft_status[d.id] = {"published": d.published_to_center, "title": d.title}
data = []
for r in records:
item = {
"id": r.id,
"draftId": r.draft_id,
"endingName": r.ending_name,
"endingType": r.ending_type,
"createdAt": r.created_at.strftime("%Y-%m-%d %H:%M") if r.created_at else ""
}
# 如果是草稿记录,添加发布状态
if r.draft_id and r.draft_id in draft_status:
item["isPublished"] = draft_status[r.draft_id]["published"]
item["draftTitle"] = draft_status[r.draft_id]["title"]
else:
item["isPublished"] = True # 原故事视为"已发布"
data.append(item)
else:
# 获取所有玩过的故事(按故事分组,取最新一条)
result = await db.execute(