This commit is contained in:
2025-09-04 17:27:42 +08:00
parent f219144328
commit f280923ce0
10 changed files with 459 additions and 391 deletions

View File

@@ -1,7 +1,13 @@
import json
import logging
import os
import json
import subprocess
import tempfile
from datetime import datetime
from fastapi.responses import FileResponse
from fastapi import APIRouter, Request, HTTPException
from fastapi import APIRouter, Request, HTTPException, Depends
from fastapi.responses import StreamingResponse
from TeacherHelper.Kit.TeacherHelper import (
@@ -17,17 +23,20 @@ router = APIRouter(prefix="/api", tags=["教师辅助工具"])
logger = logging.getLogger(__name__)
@router.post("/teacher/daoXueAn")
@router.api_route("/teacher/daoXueAn", methods=["GET", "POST"]) # 修改这里
async def generate_dao_xue_an(request: Request):
"""生成导学案接口"""
try:
# 解析请求体
body = await request.body()
data = json.loads(body) if body else {}
# 获取提示词参数,如果没有提供则使用默认值
system_prompt = data.get("system_prompt")
user_prompt = data.get("user_prompt")
# 获取请求参数兼容GET和POST
if request.method == "GET":
params = dict(request.query_params)
else:
body = await request.body()
params = json.loads(body) if body else {}
# 获取提示词参数
system_prompt = params.get("system_prompt")
user_prompt = params.get("user_prompt")
# 生成导学案
content_generator = await generate_lesson_plan(system_prompt, user_prompt)
@@ -35,9 +44,51 @@ async def generate_dao_xue_an(request: Request):
# 定义SSE响应生成器
async def generate_sse_response():
try:
buffer = [] # 用于收集完整内容
yield "data: 开始生成导学案...\n\n"
async for chunk in content_generator:
yield f"data: {chunk}\n\n"
buffer.append(chunk) # 仅收集内容,不实时发送
# 保存为Markdown并转换为Word
if buffer:
# 创建保存目录 - 修改保存路径到static下
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
save_dir = os.path.join(project_root, "static", "teacherHelpergenerated_files")
os.makedirs(save_dir, exist_ok=True)
# 生成唯一文件名
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
# 创建临时Markdown文件
with tempfile.NamedTemporaryFile(mode='w', encoding='utf-8', suffix='.md', delete=False) as temp_md:
temp_md.write(''.join(buffer))
temp_md_path = temp_md.name
# 使用Pandoc转换为Word
docx_filename = f"导学案_{timestamp}.docx"
docx_path = os.path.join(save_dir, docx_filename)
try:
yield "data: 正在转换为Word文档...\n\n"
# 执行Pandoc命令
result = subprocess.run(
["pandoc", temp_md_path, "-o", docx_path],
capture_output=True,
text=True,
check=True
)
# 清理临时文件
os.unlink(temp_md_path)
logger.info(f"导学案已转换为Word文档: {docx_path}")
# 修改下载链接为静态文件路径
yield f"data: [下载链接] /static/teacherHelpergenerated_files/{docx_filename}\n\n"
except subprocess.CalledProcessError as e:
yield f"data: [转换失败] Pandoc错误: {e.stderr}\n\n"
except Exception as e:
yield f"data: [转换失败] {str(e)}\n\n"
yield "data: [DONE]\n\n"
except Exception as e:
logger.error(f"生成导学案时发生异常: {str(e)}")
@@ -175,4 +226,21 @@ async def generate_zuo_ye(request: Request):
raise HTTPException(status_code=400, detail="无效的JSON格式")
except Exception as e:
logger.error(f"作业接口异常: {str(e)}")
raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}")
raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}")
@router.get("/teacher/download/{filename}")
async def download_word_file(filename: str):
"""下载生成的Word文件"""
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
save_dir = os.path.join(project_root, "static", "teacherHelpergenerated_files")
file_path = os.path.join(save_dir, filename)
if not os.path.exists(file_path):
raise HTTPException(status_code=404, detail="文件不存在")
return FileResponse(
path=file_path,
filename=filename,
media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
)