init
This commit is contained in:
136
backend/app/api/files.py
Normal file
136
backend/app/api/files.py
Normal file
@@ -0,0 +1,136 @@
|
||||
import os
|
||||
import uuid
|
||||
from typing import Annotated
|
||||
from fastapi import APIRouter, UploadFile, File, HTTPException, Depends
|
||||
from fastapi.responses import FileResponse
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, delete
|
||||
|
||||
from app.database import get_db
|
||||
from app.models.transcript import Transcript
|
||||
from app.models.person import Person
|
||||
from app.schemas.schemas import TranscriptOut, PersonOut
|
||||
from app.services.file_service import file_service
|
||||
from app.services.docx_parser import parse_transcript, parse_person_info
|
||||
|
||||
router = APIRouter(prefix="/files", tags=["文件管理"])
|
||||
|
||||
|
||||
# ===== 文字稿 =====
|
||||
|
||||
@router.post("/transcripts", response_model=list[TranscriptOut])
|
||||
async def upload_transcripts(files: list[UploadFile], db: Annotated[AsyncSession, Depends(get_db)]):
|
||||
"""批量上传文字稿"""
|
||||
results = []
|
||||
for file in files:
|
||||
if not file.filename.endswith(".docx"):
|
||||
raise HTTPException(400, f"仅支持 .docx 格式: {file.filename}")
|
||||
|
||||
saved = await file_service.save_transcript(file)
|
||||
|
||||
# 解析行数
|
||||
paragraphs = parse_transcript(saved["file_path"])
|
||||
line_count = len(paragraphs)
|
||||
|
||||
record = Transcript(
|
||||
id=saved["id"],
|
||||
filename=saved["filename"],
|
||||
file_path=saved["file_path"],
|
||||
line_count=line_count,
|
||||
file_size=saved["file_size"],
|
||||
status="pending",
|
||||
)
|
||||
db.add(record)
|
||||
results.append(record)
|
||||
|
||||
await db.commit()
|
||||
for r in results:
|
||||
await db.refresh(r)
|
||||
return results
|
||||
|
||||
|
||||
@router.get("/transcripts", response_model=list[TranscriptOut])
|
||||
async def list_transcripts(db: Annotated[AsyncSession, Depends(get_db)]):
|
||||
"""获取文字稿列表"""
|
||||
result = await db.execute(select(Transcript).order_by(Transcript.uploaded_at.desc()))
|
||||
return result.scalars().all()
|
||||
|
||||
|
||||
@router.delete("/transcripts/{transcript_id}")
|
||||
async def delete_transcript(transcript_id: str, db: Annotated[AsyncSession, Depends(get_db)]):
|
||||
"""删除文字稿"""
|
||||
record = await db.get(Transcript, transcript_id)
|
||||
if not record:
|
||||
raise HTTPException(404, "文字稿不存在")
|
||||
file_service.delete_file(record.file_path)
|
||||
await db.delete(record)
|
||||
await db.commit()
|
||||
return {"message": "已删除"}
|
||||
|
||||
|
||||
# ===== 讲述者信息 =====
|
||||
|
||||
@router.post("/persons", response_model=list[PersonOut])
|
||||
async def upload_persons(files: list[UploadFile], db: Annotated[AsyncSession, Depends(get_db)]):
|
||||
"""批量上传讲述者信息"""
|
||||
results = []
|
||||
for file in files:
|
||||
if not file.filename.endswith(".docx"):
|
||||
raise HTTPException(400, f"仅支持 .docx 格式: {file.filename}")
|
||||
|
||||
saved = await file_service.save_person(file)
|
||||
|
||||
# 解析个人信息
|
||||
info = parse_person_info(saved["file_path"])
|
||||
|
||||
record = Person(
|
||||
id=saved["id"],
|
||||
name=info["name"],
|
||||
filename=saved["filename"],
|
||||
file_path=saved["file_path"],
|
||||
photo_path=info["photos"][0] if info["photos"] else "",
|
||||
info=info["info_text"],
|
||||
)
|
||||
db.add(record)
|
||||
results.append(record)
|
||||
|
||||
await db.commit()
|
||||
for r in results:
|
||||
await db.refresh(r)
|
||||
return results
|
||||
|
||||
|
||||
@router.get("/persons", response_model=list[PersonOut])
|
||||
async def list_persons(db: Annotated[AsyncSession, Depends(get_db)]):
|
||||
"""获取讲述者列表"""
|
||||
result = await db.execute(select(Person).order_by(Person.uploaded_at.desc()))
|
||||
return result.scalars().all()
|
||||
|
||||
|
||||
@router.delete("/persons/{person_id}")
|
||||
async def delete_person(person_id: str, db: Annotated[AsyncSession, Depends(get_db)]):
|
||||
"""删除讲述者信息"""
|
||||
record = await db.get(Person, person_id)
|
||||
if not record:
|
||||
raise HTTPException(404, "讲述者不存在")
|
||||
file_service.delete_file(record.file_path)
|
||||
if record.photo_path:
|
||||
file_service.delete_file(record.photo_path)
|
||||
await db.delete(record)
|
||||
await db.commit()
|
||||
return {"message": "已删除"}
|
||||
|
||||
|
||||
@router.get("/persons/{person_id}/preview")
|
||||
async def preview_person(person_id: str, db: Annotated[AsyncSession, Depends(get_db)]):
|
||||
"""预览讲述者信息"""
|
||||
record = await db.get(Person, person_id)
|
||||
if not record:
|
||||
raise HTTPException(404, "讲述者不存在")
|
||||
return {
|
||||
"id": record.id,
|
||||
"name": record.name,
|
||||
"nickname": record.nickname,
|
||||
"info": record.info,
|
||||
"photo_path": record.photo_path,
|
||||
}
|
||||
Reference in New Issue
Block a user