diff --git a/backend/app/api/projects.py b/backend/app/api/projects.py index 5e35280..3fc5848 100644 --- a/backend/app/api/projects.py +++ b/backend/app/api/projects.py @@ -14,6 +14,10 @@ from app.models.chapter import Chapter from app.models.generation_history import GenerationHistory from app.models.relationship import CharacterRelationship, Organization, OrganizationMember from app.models.memory import StoryMemory, PlotAnalysis +from app.models.foreshadow import Foreshadow +from app.models.career import Career, CharacterCareer +from app.models.analysis_task import AnalysisTask +from app.models.batch_generation_task import BatchGenerationTask from app.schemas.project import ( ProjectCreate, ProjectUpdate, @@ -234,11 +238,15 @@ async def delete_project( else: logger.warning(f"⚠️ 未找到用户ID,跳过向量数据库清理") + # === 删除所有关联数据(SQLite默认不启用外键约束,需要显式删除)=== + + # 1. 删除角色关系 relationships_result = await db.execute( delete(CharacterRelationship).where(CharacterRelationship.project_id == project_id) ) logger.debug(f"删除角色关系数: {relationships_result.rowcount}") + # 2. 删除组织成员和组织 orgs_result = await db.execute( select(Organization).where(Organization.project_id == project_id) ) @@ -256,29 +264,73 @@ async def delete_project( ) logger.debug(f"删除组织数: {organizations_result.rowcount}") + # 3. 删除生成历史 history_result = await db.execute( delete(GenerationHistory).where(GenerationHistory.project_id == project_id) ) logger.debug(f"删除生成历史数: {history_result.rowcount}") + # 4. 删除分析任务 + analysis_tasks_result = await db.execute( + delete(AnalysisTask).where(AnalysisTask.project_id == project_id) + ) + logger.debug(f"删除分析任务数: {analysis_tasks_result.rowcount}") + + # 5. 删除批量生成任务 + batch_tasks_result = await db.execute( + delete(BatchGenerationTask).where(BatchGenerationTask.project_id == project_id) + ) + logger.debug(f"删除批量生成任务数: {batch_tasks_result.rowcount}") + + # 6. 删除角色职业关联(先获取角色ID列表) + characters_query = await db.execute( + select(Character.id).where(Character.project_id == project_id) + ) + character_ids = [row[0] for row in characters_query.fetchall()] + + if character_ids: + character_careers_result = await db.execute( + delete(CharacterCareer).where(CharacterCareer.character_id.in_(character_ids)) + ) + logger.debug(f"删除角色职业关联数: {character_careers_result.rowcount}") + + # 7. 删除职业体系 + careers_result = await db.execute( + delete(Career).where(Career.project_id == project_id) + ) + logger.debug(f"删除职业体系数: {careers_result.rowcount}") + + # 8. 删除故事记忆 + story_memories_result = await db.execute( + delete(StoryMemory).where(StoryMemory.project_id == project_id) + ) + logger.debug(f"删除故事记忆数: {story_memories_result.rowcount}") + + # 9. 删除章节(会级联删除 PlotAnalysis) chapters_result = await db.execute( delete(Chapter).where(Chapter.project_id == project_id) ) logger.debug(f"删除章节数: {chapters_result.rowcount}") + # 10. 删除大纲 outlines_result = await db.execute( delete(Outline).where(Outline.project_id == project_id) ) logger.debug(f"删除大纲数: {outlines_result.rowcount}") + # 11. 删除角色 characters_result = await db.execute( delete(Character).where(Character.project_id == project_id) ) logger.debug(f"删除角色数: {characters_result.rowcount}") - # 注意:StoryMemory和PlotAnalysis会通过数据库级联删除自动清理 - # 但向量数据库已在上面手动清理 + # 12. 删除伏笔 + foreshadows_result = await db.execute( + delete(Foreshadow).where(Foreshadow.project_id == project_id) + ) + logger.debug(f"删除伏笔数: {foreshadows_result.rowcount}") + # 最后删除项目本身 await db.delete(project) await db.commit()