179 lines
5.9 KiB
Python
179 lines
5.9 KiB
Python
from fastapi import APIRouter, HTTPException, status
|
||
from pathlib import Path
|
||
|
||
try:
|
||
from backend.services.chat_service import ChatService
|
||
from backend.core.config import settings
|
||
except ImportError:
|
||
# Docker环境:直接从当前目录导入
|
||
from services.chat_service import ChatService
|
||
from core.config import settings
|
||
|
||
router = APIRouter(prefix="/chat", tags=["chat"])
|
||
|
||
# 初始化聊天服务
|
||
data_path = Path(settings.DATA_PATH) if hasattr(settings, 'DATA_PATH') else Path("data")
|
||
chat_service = ChatService(data_path)
|
||
|
||
|
||
@router.get("", response_model=dict)
|
||
async def list_all_chats():
|
||
"""获取所有角色的所有聊天列表"""
|
||
return chat_service.list_all_chats()
|
||
|
||
|
||
# 注意:路由定义顺序很重要!更具体的路由(更多参数)必须放在前面
|
||
@router.get("/{role_name}/{chat_name}")
|
||
async def get_chat(role_name: str, chat_name: str):
|
||
"""获取指定聊天的完整内容"""
|
||
try:
|
||
return chat_service.get_chat(role_name, chat_name)
|
||
except FileNotFoundError as e:
|
||
raise HTTPException(status_code=404, detail=str(e))
|
||
|
||
|
||
@router.get("/{role_name}")
|
||
async def list_role_chats(role_name: str):
|
||
"""获取指定角色的所有聊天列表"""
|
||
try:
|
||
all_chats = chat_service.list_all_chats()
|
||
# 从所有聊天中筛选出该角色的聊天
|
||
role_chats = all_chats.get(role_name, [])
|
||
return role_chats
|
||
except Exception as e:
|
||
raise HTTPException(status_code=500, detail=str(e))
|
||
|
||
|
||
@router.post("/{role_name}", status_code=status.HTTP_201_CREATED)
|
||
async def create_chat(role_name: str, chat_data: dict):
|
||
"""创建新聊天"""
|
||
try:
|
||
chat_name = chat_data.get("chat_name", "新聊天")
|
||
metadata = chat_data.get("metadata", {})
|
||
return chat_service.create_chat(role_name, chat_name, metadata)
|
||
except FileExistsError as e:
|
||
raise HTTPException(status_code=400, detail=str(e))
|
||
|
||
|
||
@router.put("/{role_name}/{chat_name}")
|
||
async def update_chat(role_name: str, chat_name: str, update_data: dict):
|
||
"""更新聊天元数据"""
|
||
# TODO: 实现更新聊天元数据功能
|
||
raise HTTPException(status_code=501, detail="Not Implemented")
|
||
|
||
|
||
@router.delete("/{role_name}/{chat_name}")
|
||
async def delete_chat(role_name: str, chat_name: str):
|
||
"""删除指定聊天"""
|
||
# TODO: 实现删除聊天功能
|
||
raise HTTPException(status_code=501, detail="Not Implemented")
|
||
|
||
|
||
@router.get("/{role_name}/{chat_name}/messages")
|
||
async def list_messages(role_name: str, chat_name: str):
|
||
"""获取聊天的所有消息"""
|
||
try:
|
||
chat_data = chat_service.get_chat(role_name, chat_name)
|
||
return {"messages": chat_data["messages"]}
|
||
except FileNotFoundError as e:
|
||
raise HTTPException(status_code=404, detail=str(e))
|
||
|
||
|
||
@router.get("/{role_name}/{chat_name}/messages/{floor}")
|
||
async def get_message(role_name: str, chat_name: str, floor: int):
|
||
"""获取指定楼层的消息"""
|
||
try:
|
||
chat_data = chat_service.get_chat(role_name, chat_name)
|
||
for msg in chat_data["messages"]:
|
||
if msg.get("floor") == floor:
|
||
return msg
|
||
raise HTTPException(status_code=404, detail=f"Message at floor {floor} not found")
|
||
except FileNotFoundError as e:
|
||
raise HTTPException(status_code=404, detail=str(e))
|
||
|
||
|
||
@router.post("/{role_name}/{chat_name}/messages", status_code=status.HTTP_201_CREATED)
|
||
async def add_message(role_name: str, chat_name: str, message_data: dict):
|
||
"""向聊天添加新消息"""
|
||
try:
|
||
return chat_service.add_message(role_name, chat_name, message_data)
|
||
except FileNotFoundError as e:
|
||
raise HTTPException(status_code=404, detail=str(e))
|
||
except ValueError as e:
|
||
raise HTTPException(status_code=400, detail=str(e))
|
||
|
||
|
||
@router.put("/{role_name}/{chat_name}/messages/{floor}")
|
||
async def update_message(role_name: str, chat_name: str, floor: int, update_data: dict):
|
||
"""更新指定楼层的消息"""
|
||
try:
|
||
return chat_service.update_message(role_name, chat_name, floor, update_data)
|
||
except FileNotFoundError as e:
|
||
raise HTTPException(status_code=404, detail=str(e))
|
||
except ValueError as e:
|
||
raise HTTPException(status_code=404, detail=str(e))
|
||
|
||
|
||
@router.delete("/{role_name}/{chat_name}/messages/{floor}")
|
||
async def delete_message(role_name: str, chat_name: str, floor: int):
|
||
"""删除指定楼层的消息"""
|
||
try:
|
||
return chat_service.delete_message(role_name, chat_name, floor)
|
||
except FileNotFoundError as e:
|
||
raise HTTPException(status_code=404, detail=str(e))
|
||
except ValueError as e:
|
||
raise HTTPException(status_code=404, detail=str(e))
|
||
|
||
|
||
@router.put("/{role_name}/{chat_name}/table")
|
||
async def update_table_data(role_name: str, chat_name: str, table_update: dict):
|
||
"""更新表格数据(带时间戳冲突解决)"""
|
||
try:
|
||
return chat_service.update_table_data(role_name, chat_name, table_update)
|
||
except FileNotFoundError as e:
|
||
raise HTTPException(status_code=404, detail=str(e))
|
||
except Exception as e:
|
||
raise HTTPException(status_code=500, detail=str(e))
|
||
|
||
|
||
@router.post("/{role_name}/{chat_name}/branch", status_code=status.HTTP_201_CREATED)
|
||
async def branch_chat(role_name: str, chat_name: str, branch_data: dict):
|
||
"""
|
||
创建聊天分支
|
||
|
||
复制当前楼层及之前的所有内容到一个新的聊天记录
|
||
|
||
Args:
|
||
role_name: 角色名称
|
||
chat_name: 原聊天名称
|
||
branch_data: {
|
||
"target_floor": int, # 目标楼层(包含该楼层及之前的内容)
|
||
"new_chat_name": str # 新聊天名称(可选,默认自动生成)
|
||
}
|
||
|
||
Returns:
|
||
{
|
||
"success": bool,
|
||
"new_chat_name": str,
|
||
"message_count": int
|
||
}
|
||
"""
|
||
try:
|
||
target_floor = branch_data.get("target_floor")
|
||
new_chat_name = branch_data.get("new_chat_name")
|
||
|
||
if target_floor is None:
|
||
raise HTTPException(status_code=400, detail="缺少 target_floor 参数")
|
||
|
||
# 调用服务层创建分支
|
||
result = chat_service.create_branch(role_name, chat_name, target_floor, new_chat_name)
|
||
|
||
return result
|
||
|
||
except FileNotFoundError as e:
|
||
raise HTTPException(status_code=404, detail=str(e))
|
||
except ValueError as e:
|
||
raise HTTPException(status_code=400, detail=str(e))
|
||
except Exception as e:
|
||
raise HTTPException(status_code=500, detail=f"创建分支失败: {str(e)}")
|