支持段落删除与移动排序,修复导出残留与外键约束
- 前端:段落列表/配置区/手动编辑区新增上移、下移、删除按钮,hover 显示 - 前端:移动和删除操作后自动保存到后端,修正 canDeleteBlock 判定逻辑 - 后端:保存段落时级联删除关联的 generation_logs 再删段落 - 后端:导出时清理未被引用的标题段落及其内容,避免已删段落残留在 Word 中 - 后端:删除模板时级联清理 generation_logs/documents/paragraphs
This commit is contained in:
@@ -6,11 +6,13 @@ from datetime import datetime
|
||||
from io import BytesIO
|
||||
|
||||
from fastapi import APIRouter, Depends, File, HTTPException, Query, UploadFile
|
||||
from sqlalchemy import func, select
|
||||
from sqlalchemy import delete, func, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from config import settings
|
||||
from database import get_db
|
||||
from models.document import Document
|
||||
from models.generation_log import GenerationLog
|
||||
from models.paragraph import Paragraph
|
||||
from models.template import Template
|
||||
from schemas.schemas import Response, TemplateSave
|
||||
@@ -194,8 +196,14 @@ async def save_template_paragraphs(
|
||||
paragraph_map = {item.id: item for item in existing_paragraphs}
|
||||
incoming_ids = {config.id for config in body.paragraphs if config.id}
|
||||
|
||||
print(f"[SAVE] template_id={template_id}, incoming_ids={incoming_ids}, existing_ids={[p.id for p in existing_paragraphs]}")
|
||||
|
||||
for paragraph in existing_paragraphs:
|
||||
if paragraph.id not in incoming_ids:
|
||||
print(f"[SAVE] Deleting paragraph id={paragraph.id} title={paragraph.title}")
|
||||
await db.execute(
|
||||
delete(GenerationLog).where(GenerationLog.paragraph_id == paragraph.id)
|
||||
)
|
||||
await db.delete(paragraph)
|
||||
|
||||
for index, config in enumerate(body.paragraphs, start=1):
|
||||
@@ -229,7 +237,23 @@ async def delete_template(template_id: int, db: AsyncSession = Depends(get_db)):
|
||||
raise HTTPException(status_code=404, detail="模板不存在")
|
||||
|
||||
result = await db.execute(select(Paragraph).where(Paragraph.template_id == template_id))
|
||||
for paragraph in result.scalars().all():
|
||||
paragraphs_to_delete = result.scalars().all()
|
||||
paragraph_ids = [p.id for p in paragraphs_to_delete]
|
||||
|
||||
doc_result = await db.execute(select(Document).where(Document.template_id == template_id))
|
||||
documents_to_delete = doc_result.scalars().all()
|
||||
|
||||
if paragraph_ids:
|
||||
await db.execute(
|
||||
delete(GenerationLog).where(GenerationLog.paragraph_id.in_(paragraph_ids))
|
||||
)
|
||||
for document in documents_to_delete:
|
||||
await db.execute(
|
||||
delete(GenerationLog).where(GenerationLog.document_id == document.id)
|
||||
)
|
||||
await db.delete(document)
|
||||
|
||||
for paragraph in paragraphs_to_delete:
|
||||
await db.delete(paragraph)
|
||||
|
||||
file_path = template.file_path or ""
|
||||
|
||||
Reference in New Issue
Block a user