This commit is contained in:
2025-09-04 16:09:11 +08:00
parent 8996b508a3
commit 4c1065bceb
4 changed files with 382 additions and 14 deletions

View File

@@ -0,0 +1,178 @@
import json
import logging
from fastapi import APIRouter, Request, HTTPException
from fastapi.responses import StreamingResponse
from TeacherHelper.Kit.TeacherHelper import (
generate_lesson_plan,
generate_courseware,
generate_homework
)
# 创建路由器
router = APIRouter(prefix="/api", tags=["教师辅助工具"])
# 配置日志
logger = logging.getLogger(__name__)
@router.post("/teacher/daoXueAn")
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")
# 生成导学案
content_generator = await generate_lesson_plan(system_prompt, user_prompt)
# 定义SSE响应生成器
async def generate_sse_response():
try:
yield "data: 开始生成导学案...\n\n"
async for chunk in content_generator:
yield f"data: {chunk}\n\n"
yield "data: [DONE]\n\n"
except Exception as e:
logger.error(f"生成导学案时发生异常: {str(e)}")
yield f"data: 生成导学案时发生异常: {str(e)}\n\n"
# 返回SSE响应
return StreamingResponse(
generate_sse_response(),
media_type="text/event-stream",
headers={"Cache-Control": "no-cache", "Connection": "keep-alive"}
)
except json.JSONDecodeError:
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)}")
@router.post("/teacher/jiaoAn")
async def generate_jiao_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")
# 生成教案
content_generator = await generate_lesson_plan(system_prompt, user_prompt)
# 定义SSE响应生成器
async def generate_sse_response():
try:
yield "data: 开始生成教案...\n\n"
async for chunk in content_generator:
yield f"data: {chunk}\n\n"
yield "data: [DONE]\n\n"
except Exception as e:
logger.error(f"生成教案时发生异常: {str(e)}")
yield f"data: 生成教案时发生异常: {str(e)}\n\n"
# 返回SSE响应
return StreamingResponse(
generate_sse_response(),
media_type="text/event-stream",
headers={"Cache-Control": "no-cache", "Connection": "keep-alive"}
)
except json.JSONDecodeError:
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)}")
@router.post("/teacher/keJian")
async def generate_ke_jian(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")
# 生成课件
content_generator = await generate_courseware(system_prompt, user_prompt)
# 定义SSE响应生成器
async def generate_sse_response():
try:
yield "data: 开始生成课件...\n\n"
async for chunk in content_generator:
yield f"data: {chunk}\n\n"
yield "data: [DONE]\n\n"
except Exception as e:
logger.error(f"生成课件时发生异常: {str(e)}")
yield f"data: 生成课件时发生异常: {str(e)}\n\n"
# 返回SSE响应
return StreamingResponse(
generate_sse_response(),
media_type="text/event-stream",
headers={"Cache-Control": "no-cache", "Connection": "keep-alive"}
)
except json.JSONDecodeError:
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)}")
@router.post("/teacher/zuoYe")
async def generate_zuo_ye(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")
material_path = data.get("material_path")
# 生成作业
content_generator = await generate_homework(system_prompt, user_prompt, material_path)
# 定义SSE响应生成器
async def generate_sse_response():
try:
yield "data: 开始生成作业...\n\n"
async for chunk in content_generator:
yield f"data: {chunk}\n\n"
yield "data: [DONE]\n\n"
except Exception as e:
logger.error(f"生成作业时发生异常: {str(e)}")
yield f"data: 生成作业时发生异常: {str(e)}\n\n"
# 返回SSE响应
return StreamingResponse(
generate_sse_response(),
media_type="text/event-stream",
headers={"Cache-Control": "no-cache", "Connection": "keep-alive"}
)
except json.JSONDecodeError:
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)}")

View File

@@ -31,7 +31,7 @@ from Routes.VideoRetalkRoute import router as videoRetalk_router
from Routes.ttsRoute import router as tts_router
from Routes.CopyFaceRoute import router as copyFace_router
from Routes.WenShengTu import router as wenshengtu_router
from Routes.TeacherHelperRoute import router as teacherHelper_router
# 控制日志输出
logger = logging.getLogger('lightrag')
logger.setLevel(logging.INFO)
@@ -89,6 +89,7 @@ app.include_router(tts_router) # 文本转语音
app.include_router(copyFace_router) # 抄脸
app.include_router(wenshengtu_router) # 文生图
app.include_router(teacherHelper_router) # 教师助手
# Teaching Model 相关路由
# 登录相关(不用登录)

View File

@@ -78,17 +78,20 @@ async def save_lesson_plan(content_chunks, output_file, stream_print=False):
return None, False
async def generate_gravitation_lesson_plan():
"""生成万有引力教案的异步函数"""
system_prompt = """你是市级骨干教师撰写教案时严格对标“核心素养四维度物理观念、科学思维、探究能力、态度责任并采用“目标—评价—活动”逆向设计模板UbD。活动设计需包含“教师行为+期望的学生行为+评价要点”三列表格。"""
llm_client = LLMClient(system_prompt=system_prompt)
prompt = """请输出“万有引力”第1课时的详案要求
1. 教学重难点用“行为动词+知识内容”表述;
2. 至少1个“演示实验”+1个“小组探究”+1个“即时反馈”技术如Padlet
async def generate_lesson_plan(system_prompt=None, user_prompt=None):
"""生成教案的异步函数,支持动态传入提示词"""
# 默认系统提示词
default_system_prompt = """你是市级骨干教师,撰写教案时严格对标"核心素养四维度(物理观念、科学思维、探究能力、态度责任)",并采用"目标—评价—活动"逆向设计模板UbD。活动设计需包含"教师行为+期望的学生行为+评价要点"三列表格。"""
# 使用传入的系统提示词或默认值
system_prompt = system_prompt or default_system_prompt
# 默认用户提示词
default_user_prompt = """请输出"万有引力"第1课时的详案要求
1. 教学重难点用"行为动词+知识内容"表述;
2. 至少1个"演示实验"+1个"小组探究"+1个"即时反馈"技术如Padlet
3. 时间轴精确到分钟;
4. 课后教学反思提示留3条空白供教师手写。
4. 课后"教学反思提示"留3条空白供教师手写。
【格式要求】
### 1. 教材与学情分析
@@ -104,9 +107,121 @@ async def generate_gravitation_lesson_plan():
教材版本:{人教版八年级下第十章第2节}
学生基础:{已学过重力、匀速圆周运动}
课时长度:{45分钟}"""
# 使用传入的用户提示词或默认值
user_prompt = user_prompt or default_user_prompt
llm_client = LLMClient(system_prompt=system_prompt)
async def get_lesson_plan():
async for chunk in llm_client.get_response(prompt, stream=True):
async for chunk in llm_client.get_response(user_prompt, stream=True):
yield chunk
return get_lesson_plan()
return get_lesson_plan()
async def generate_courseware(system_prompt=None, user_prompt=None):
"""生成课件大纲的异步函数,支持动态传入提示词"""
# 默认系统提示词
default_system_prompt = """你是PPT视觉设计教练遵循"6×6原则"每页≤6行每行≤6词字体≥28pt主色调#005BAC教育蓝强调色#FFB703暖黄。所有动画≤0.5s,禁止花哨。需要给出演示者备注栏(<备注>)。"""
# 使用传入的系统提示词或默认值
system_prompt = system_prompt or default_system_prompt
# 默认用户提示词
default_user_prompt = """"万有引力"生成可直接导入PowerPoint的Markdown大纲共12页
1. 封面(课程名+章节+教师姓名留白)
2. 情境导入1个30s短视频建议+2张图片提示
3. 概念建构(苹果落地+月亮绕地对比图)
4. 规律探究卡文迪许实验GIF占位
5. 公式推导F=G·m₁m₂/r²分三步行
6. 例题精讲2道step-by-step动画
7. 当堂检测Padlet二维码占位
8. 小结思维导图可一键转SmartArt
9. 作业二维码(链接到在线表单)
10. 结束页("思考:如果没有万有引力?"留白)
【格式要求】
每页用三级标题###表示,下方用<ul>列要点;如需图片,用! `https://via.placeholder.com/800x450?text=Image` 占位并给出版权提示;在要点后另起一行写<备注>演示者话术。"""
# 使用传入的用户提示词或默认值
user_prompt = user_prompt or default_user_prompt
llm_client = LLMClient(system_prompt=system_prompt)
async def get_courseware():
async for chunk in llm_client.get_response(user_prompt, stream=True):
yield chunk
return get_courseware()
async def generate_homework(system_prompt=None, user_prompt=None, material_path=None):
"""生成课后作业的异步函数,支持动态传入提示词和材料路径"""
# 默认系统提示词
default_system_prompt = "你是命题专家,熟悉布鲁姆认知分类和'双减'政策。你需要根据用户提供的题目材料来生成作业,而不是自己创造题目。客观题采用'四选一'单选,难度比例易:中:难=6:3:1主观题设置2小问第1问'解释现象'对应'理解'第2问'方案设计'对应'创新'。题量控制为20分钟完成。"
# 使用传入的系统提示词或默认值
system_prompt = system_prompt or default_system_prompt
# 默认材料路径
default_material_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "static", "YunXiao.txt")
material_path = material_path or default_material_path
# 读取题目材料
try:
with open(material_path, "r", encoding="utf-8") as f:
question_material = f.read()
except Exception as e:
logger.error(f"读取题目材料失败: {str(e)}")
question_material = ""
# 默认用户提示词
default_user_prompt = f"""请根据以下'万有引力'相关题目材料输出课后作业满分100分
A. 客观题8题×5分=40分
- 从提供的材料中选择题目,并按要求重新组织
- 前3题考'史实&概念'识记
- 中间3题考'公式变形&比例'理解
- 后2题考'情境估算'应用
B. 主观题2题30+30分
- 题1结合'天问一号'发射新闻,解释地球与火星之间的引力如何变化
- 题2设计一个实验用智能手机+免费APP估算地球质量写出步骤与所需测量量
C. 评分标准主观题分点给分每点10分
D. 参考答案与解析(客观题给出选项+一句话解析;主观题给出关键公式与评分关键词)
以下是题目材料:
{question_material}
【格式要求】
### A. 客观题
<ul>
<li>1. ……</li>
……
</ul>
### B. 主观题
#### 1. ……
#### 2. ………
### C. 评分标准
……
### D. 参考答案与解析
……"""
# 使用传入的用户提示词或默认值
user_prompt = user_prompt or default_user_prompt
llm_client = LLMClient(system_prompt=system_prompt)
async def get_homework():
async for chunk in llm_client.get_response(user_prompt, stream=True):
yield chunk
return get_homework()
# 保持向后兼容性的函数别名
async def generate_gravitation_lesson_plan():
"""生成万有引力教案的异步函数(向后兼容)"""
return await generate_lesson_plan()

View File

@@ -51,4 +51,78 @@ D![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/WToM/images/da
<li>8. 嫦娥五号返回器从A点到E点无动力飞行下列说法正确的是
A在A点动能等于在C点动能
B在A点动能大于在C点动能
C在A、C、E三点加速度大小
C在A、C、E三点加速度大小相同
D在A、C、E三点加速度方向相同
</li>
</ul>
---
## B. 主观题2题每题30分
### 1. 结合“天问一号”发射新闻,解释地球与火星之间的引力如何变化。
### 2. 设计一个实验,用智能手机+免费APP估算地球质量写出步骤与所需测量量。
---
## C. 评分标准
**主观题130分**
- 正确说明引力与距离平方成反比关系10分
- 能结合“天问一号”轨道变化分析引力变化趋势10分
- 语言表达清晰、逻辑合理10分
**主观题230分**
- 明确实验原理如利用重力加速度公式10分
- 合理设计实验步骤10分
- 列出所需测量量如高度、时间10分
---
## D. 参考答案与解析
### 客观题答案
1. **C**
解析:地球对物体的引力是向心力来源,向心力不是独立存在的力。
2. **D**
解析根据F=GmM/r²当r增加为2R时F变为原来的1/2。
3. **D**
解析轨道半径分别为2R和3R根据F=GmM/r²得比值为9:4。
4. **C**
解析:椭圆轨道远地点速度小于圆轨道速度,近地点速度可能大于第一宇宙速度。
5. **C**
解析由开普勒第三定律r增大为2倍周期增大为2√2倍。
6. **C**
解析根据T²∝r³/MM=ρVρ相同则T与r^(3/2)成反比。
7. **A**
解析由v=2πr/T和F=mv²/r=GmM/r²可推导出M=4π²r³/(GT²)。
8. **B**
解析:空气阻力做负功,动能减小;加速度大小相同但方向不同。
---
### 主观题答案
**主观题1**
- 地球与火星之间的万有引力随距离变化而变化遵循F=Gm₁m₂/r²
- “天问一号”在发射初期距离地球较近,引力较大;随着远离地球,引力逐渐减小
- 到达火星附近时,受火星引力主导,地球引力可忽略
- 引力变化体现为探测器加速度的变化,影响其轨道设计与控制
**主观题2**
- **实验原理**利用自由落体运动测重力加速度g再由g=GM/R²计算地球质量M
- **步骤**
1. 在智能手机上安装加速度计APP如phyphox
2. 将手机固定在稳定支架上,记录自由落体过程中的加速度数据
3. 测量下落高度h和落地时间t计算g=2h/t²
- **所需测量量**下落高度h、落地时间t
- **公式**M = gR²/G其中R为地球半径G为引力常量6.67×10⁻¹¹ N·m²/kg²