repair-agent 88b8f023f4
Some checks failed
Build and Deploy Backend / build-and-deploy (push) Failing after 1m36s
Fix app api
2026-02-09 15:35:33 +08:00

143 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
故事模块视图 - App端
"""
from django.db.models import Count
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from drf_spectacular.utils import extend_schema
from utils.response import success, error
from utils.exceptions import ErrorCode
from apps.admins.authentication import AppJWTAuthentication
from .models import StoryShelf, Story
from .serializers import (
StoryShelfSerializer,
CreateShelfSerializer,
StoryListSerializer,
GenerateStorySerializer,
)
@extend_schema(tags=['故事'])
class StoryViewSet(viewsets.ViewSet):
"""故事视图集App端"""
authentication_classes = [AppJWTAuthentication]
permission_classes = [IsAuthenticated]
def list(self, request):
"""
获取故事列表
GET /api/v1/stories/?shelf_id=1&page=1&page_size=20
"""
queryset = Story.objects.filter(user=request.user)
shelf_id = request.query_params.get('shelf_id')
if shelf_id:
queryset = queryset.filter(shelf_id=shelf_id)
# 分页
page = int(request.query_params.get('page', 1))
page_size = int(request.query_params.get('page_size', 20))
start = (page - 1) * page_size
total = queryset.count()
items = queryset[start:start + page_size]
return success(data={
'total': total,
'items': StoryListSerializer(items, many=True).data,
})
def destroy(self, request, pk=None):
"""
删除故事
DELETE /api/v1/stories/{id}/
"""
try:
story = Story.objects.get(id=pk, user=request.user)
except Story.DoesNotExist:
return error(code=ErrorCode.STORY_NOT_FOUND, message='故事不存在')
story.delete()
return success(message='删除成功')
@action(detail=False, methods=['post'], url_path='generate')
def generate(self, request):
"""
生成故事 (SSE 流式 - 占位)
POST /api/v1/stories/generate/
"""
serializer = GenerateStorySerializer(data=request.data)
if not serializer.is_valid():
return error(message=str(serializer.errors))
# TODO: 接入 LLM API 实现 SSE 流式生成
shelf_id = serializer.validated_data.get('shelf_id')
shelf = None
if shelf_id:
try:
shelf = StoryShelf.objects.get(id=shelf_id, user=request.user)
except StoryShelf.DoesNotExist:
return error(code=ErrorCode.SHELF_NOT_FOUND, message='书架不存在')
story = Story.objects.create(
user=request.user,
shelf=shelf,
title='生成中...',
content='',
generation_mode=serializer.validated_data.get('mode', 'random'),
prompt=serializer.validated_data.get('prompt', ''),
)
return success(data={
'id': story.id,
'message': '故事生成功能待接入 LLM API',
})
@extend_schema(tags=['故事'])
class ShelfViewSet(viewsets.ViewSet):
"""书架视图集App端"""
authentication_classes = [AppJWTAuthentication]
permission_classes = [IsAuthenticated]
def list(self, request):
"""
书架列表
GET /api/v1/stories/shelves/
"""
shelves = StoryShelf.objects.filter(
user=request.user
).annotate(story_count=Count('stories'))
return success(data=StoryShelfSerializer(shelves, many=True).data)
def create(self, request):
"""
创建书架
POST /api/v1/stories/shelves/
"""
serializer = CreateShelfSerializer(data=request.data)
if not serializer.is_valid():
return error(message=str(serializer.errors))
shelf = StoryShelf.objects.create(
user=request.user,
name=serializer.validated_data['name'],
)
return success(data=StoryShelfSerializer(shelf).data, message='创建成功')
def destroy(self, request, pk=None):
"""
删除书架故事保留shelf_id 置 null
DELETE /api/v1/stories/shelves/{id}/
"""
try:
shelf = StoryShelf.objects.get(id=pk, user=request.user)
except StoryShelf.DoesNotExist:
return error(code=ErrorCode.SHELF_NOT_FOUND, message='书架不存在')
Story.objects.filter(shelf=shelf).update(shelf=None)
shelf.delete()
return success(message='删除成功')