diff --git a/dsLightRag/Routes/TeacherHelperRoute.py b/dsLightRag/Routes/TeacherHelperRoute.py index 7678a4d5..208255f3 100644 --- a/dsLightRag/Routes/TeacherHelperRoute.py +++ b/dsLightRag/Routes/TeacherHelperRoute.py @@ -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)}") \ No newline at end of file + 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" + ) \ No newline at end of file diff --git a/dsLightRag/Routes/__pycache__/TeacherHelperRoute.cpython-310.pyc b/dsLightRag/Routes/__pycache__/TeacherHelperRoute.cpython-310.pyc index b0a50483..b136148e 100644 Binary files a/dsLightRag/Routes/__pycache__/TeacherHelperRoute.cpython-310.pyc and b/dsLightRag/Routes/__pycache__/TeacherHelperRoute.cpython-310.pyc differ diff --git a/dsLightRag/generated_files/导学案_20250904165056.md b/dsLightRag/generated_files/导学案_20250904165056.md new file mode 100644 index 00000000..d5614f8f --- /dev/null +++ b/dsLightRag/generated_files/导学案_20250904165056.md @@ -0,0 +1,87 @@ +### 1. 教材与学情分析 + +本节课选自人教版八年级下册第十章第2节《万有引力》。学生在前期已学习了重力、匀速圆周运动等知识,具备一定的力学基础和科学探究意识。本节内容是牛顿力学体系中的重要组成部分,通过引导学生理解万有引力的提出背景、基本概念及其在天体运动中的应用,有助于培养其物理观念、科学思维和探究能力。 + +--- + +### 2. 四维目标(对应核心素养) + +| 核心素养维度 | 学习目标 | +|--------------|----------| +| 物理观念 | 通过观察和分析,理解万有引力的基本概念及其作用规律。 | +| 科学思维 | 能够运用归纳推理和类比思维,理解牛顿提出万有引力的过程。 | +| 探究能力 | 通过小组合作探究,设计实验验证万有引力与质量、距离的关系(定性)。 | +| 态度责任 | 培与科学探索的兴趣,体会科学家探索自然规律的坚持与智慧。 | + +--- + +### 3. 重难点 + +| 类型 | 内容(行为动词+知识内容) | +|------|-----------------------------| +| 教学重点 | 分析牛顿提出万有引力的思想过程;理解万有引力的定义与表达式。 | +| 教学难点 | 推理万有引力与质量、距离之间的定性关系;理解万有引力在天体运动中的作用。 | + +--- + +### 4. 教学准备 + +| 类型 | 内容 | +|------|------| +| 实验器材 | 演示实验:弹簧秤、质量块若干、天体模型(地球与月球) | +| 数字资源 | Padlet在线协作平台、PPT课件、视频片段《牛顿发现万有引力》 | + +--- + +### 5. 教学过程(时间轴表格) + +| 时间 | 教师行为 | 期望的学生行为 | 评价要点 | +|------|----------|------------------|-----------| +| 0-5分钟 | 情境导入:播放牛顿发现苹果落地的视频,提问“为什么苹果会落地?” | 学生观看视频,思考问题,尝试回答 | 观察学生是否能联系重力知识进行初步解释 | +| 5-10分钟 | 演示实验:用弹簧秤测量不同质量物体的重力,引导学生观察数据变化 | 学生观察实验,记录数据,思考质量与重力的关系 | 评价学生是否理解质量与引力的关系 | +| 10-15分钟 | 讲解牛顿提出万有引力的过程,结合地球绕太阳运动进行类比说明 | 学生倾听,记录关键点,尝试用自己的语言复述 | 评价学生是否能理解“类比思维”在科学发现中的作用 | +| 15-25分钟 | 小组探究:每组设计一个实验(定性)验证万有引力与质量、距离的关系(可用天体模型模拟) | 学生分组讨论,设计实验方案,进行模拟演示 | 评价学生是否能运用控制变量法进行探究设计 | +| 25-30分钟 | Padlet即时反馈:学生将探究结果上传至Padlet平台,教师选取典型方案进行展示与点评 | 学生上传探究结果,浏览他人方案,参与互评 | 评价学生是否能清晰表达探究过程与结论 | +| 30-40分钟 | 总结提升:教师引导学生归纳万有引力的基本概念与表达式(F=Gm₁m₂/r²),并解释其在宇宙中的应用 | 学生整理笔记,参与互动问答,尝试解释天体运动现象 | 评价学生是否掌握万有引力的基本表达与应用 | +| 40-45分钟 | 课堂小结与作业布置:回顾本节课重点,布置分层作业 | 学生记录作业内容,提出疑问 | 评价学生是否理解学习目标与任务 | + +--- + +### 6. 板书设计(ASCII示意图) + +``` + 万有引力 +┌───────────────┐ +│ 一、牛顿的发现过程 │ +│ - 苹果落地与月球绕地 │ +│ - 类比思维的应用 │ +├───────────────┤ +│ 二、万有引力概念 │ +│ - 定义:任何两个物体之间都存在引力 │ +│ - 表达式:F = Gm₁m₂ / r² │ +├───────────────┤ +│ 三、探究活动 │ +│ - 探究目的:质量、距离对引力的影响 │ +│ - 探究方法:控制变量法 + 模拟实验 │ +└───────────────┘ +``` + +--- + +### 7. 作业布置(与导学案分层衔接) + +| 层次 | 内容 | +|------|------| +| 基础层 | 教材P58练习题1-3题,完成导学案“基础巩固”部分 | +| 提高层 | 设计一个实验方案,验证“两个物体之间的引力与它们的距离平方成反比”(可用文字+图示表达) | +| 拓展层 | 查阅资料,简述“万有引力定律”对现代航天技术的影响(200字左右) | + +--- + +### 8. 教学反思提示(空白) + +1. ___________________________________________________________ + +2. ___________________________________________________________ + +3. ___________________________________________________________ \ No newline at end of file diff --git a/dsLightRag/generated_files/导学案_20250904170005.docx b/dsLightRag/generated_files/导学案_20250904170005.docx new file mode 100644 index 00000000..6dee321e Binary files /dev/null and b/dsLightRag/generated_files/导学案_20250904170005.docx differ diff --git a/dsLightRag/static/teacherHelper/index.html b/dsLightRag/static/teacherHelper/index.html index f1055126..67f4ccdf 100644 --- a/dsLightRag/static/teacherHelper/index.html +++ b/dsLightRag/static/teacherHelper/index.html @@ -4,8 +4,11 @@ 教师辅助工具 - 教学资源生成 - - + + + + + - -
-
-
-
-
- 教学资源生成工具 -
-
-

使用此工具生成万有引力相关的导学案、教案、课件和作业。您可以自定义提示词以获得更符合需求的内容。

- - - -
- -
-
-
- - -
-
- - -
- -
-
-
- 加载中... -
-

正在生成导学案,请稍候...

+
+ +
+
+
+ +
- -
- - -
- -
- - -
-
- - -
- - -
-
- 加载中... -
-

正在生成教案,请稍候...

+
+ +
- -
- - -
-
-
- - -
-
- - -
- -
-
-
- 加载中... -
-

正在生成课件,请稍候...

+ +
+
+
+ +
- -
- - -
- -
- - -
-
- - -
- - -
-
- 加载中... -
-

正在生成作业,请稍候...

+
+ +
- -
+ + +
+
+
+ + +
+
+
+ + +
+
+ + +
+ +
+
+
+
+ + +
+
+
+ + +
+
+ + +
+ +
+
+
+
-
-
-

© 2023 教师辅助工具 - 万有引力教学资源生成

-
-
+ + + // 验证输入 + if (!userPrompt.trim()) { + alert('请输入用户提示词'); + return; + } + + // 重置状态 + resultContainer.innerHTML = ''; + resultContainer.style.display = 'block'; + loadingElement.style.display = 'flex'; + + // 禁用按钮 + generateButton.disabled = true; + generateButton.classList.add('btn-disabled'); + generateButton.innerHTML = '生成中...'; + + try { + // 发送请求 + const response = await fetch(`/api/teacher/${resourceType}`, { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({ + system_prompt: systemPrompt, + user_prompt: userPrompt + }) + }); + + if (!response.ok) throw new Error(`HTTP错误: ${response.status}`); + + // 处理流式响应 + const reader = response.body.getReader(); + const decoder = new TextDecoder(); + let done = false; + + while (!done) { + const { value, done: doneReading } = await reader.read(); + done = doneReading; + const chunk = decoder.decode(value, { stream: true }); + if (chunk) handleStreamData(chunk, resourceType, resultContainer, loadingElement, generateButton); + } + } catch (error) { + console.error('生成资源失败:', error); + resultContainer.innerHTML = `
生成失败: ${error.message}
`; + resetState(loadingElement, generateButton); + } + } + + // 处理流数据 + function handleStreamData(data, resourceType, resultContainer, loadingElement, generateButton) { + const lines = data.split('\n').filter(line => line.trim()); + let shouldHideLoading = false; - - + } + + // 重置状态 + function resetState(loadingElement, generateButton) { + loadingElement.style.display = 'none'; + generateButton.disabled = false; + generateButton.classList.remove('btn-disabled'); + generateButton.innerHTML = `生成${getResourceName(resourceType).replace(/^./, c => c.toLowerCase())}`; + } + \ No newline at end of file diff --git a/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904170732.docx b/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904170732.docx new file mode 100644 index 00000000..3be2e9fd Binary files /dev/null and b/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904170732.docx differ diff --git a/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904171033.docx b/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904171033.docx new file mode 100644 index 00000000..9148cd09 Binary files /dev/null and b/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904171033.docx differ diff --git a/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904171748.docx b/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904171748.docx new file mode 100644 index 00000000..017f92ea Binary files /dev/null and b/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904171748.docx differ diff --git a/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904172412.docx b/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904172412.docx new file mode 100644 index 00000000..f9aea615 Binary files /dev/null and b/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904172412.docx differ diff --git a/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904172633.docx b/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904172633.docx new file mode 100644 index 00000000..9b695ba8 Binary files /dev/null and b/dsLightRag/static/teacherHelpergenerated_files/导学案_20250904172633.docx differ