This commit is contained in:
2025-09-04 16:30:24 +08:00
parent 4c1065bceb
commit f219144328
3 changed files with 486 additions and 0 deletions

View File

@@ -0,0 +1,486 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>教师辅助工具 - 教学资源生成</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css" rel="stylesheet">
<style>
:root {
--primary-color: #2c3e50;
--secondary-color: #3498db;
--accent-color: #e74c3c;
--light-color: #ecf0f1;
--dark-color: #34495e;
}
body {
font-family: 'Microsoft YaHei', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f8f9fa;
color: var(--dark-color);
padding-top: 20px;
}
.navbar {
background-color: var(--primary-color);
box-shadow: 0 2px 4px rgba(0,0,0,.1);
}
.navbar-brand {
font-weight: bold;
color: white !important;
}
.card {
border: none;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0,0,0,.1);
margin-bottom: 20px;
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
}
.card-header {
background-color: var(--primary-color);
color: white;
border-radius: 10px 10px 0 0 !important;
padding: 15px 20px;
font-weight: bold;
}
.btn-primary {
background-color: var(--secondary-color);
border-color: var(--secondary-color);
transition: all 0.3s ease;
}
.btn-primary:hover {
background-color: #2980b9;
border-color: #2980b9;
}
.form-control {
border-radius: 5px;
border: 1px solid #ddd;
padding: 10px;
}
.form-control:focus {
border-color: var(--secondary-color);
box-shadow: 0 0 0 0.25rem rgba(52, 152, 219, 0.25);
}
.result-container {
background-color: white;
border-radius: 10px;
padding: 20px;
margin-top: 20px;
box-shadow: 0 4px 6px rgba(0,0,0,.1);
min-height: 200px;
max-height: 500px;
overflow-y: auto;
}
.loading {
display: none;
text-align: center;
padding: 20px;
}
.spinner-border {
width: 3rem;
height: 3rem;
}
.nav-tabs .nav-link {
color: var(--dark-color);
font-weight: 500;
}
.nav-tabs .nav-link.active {
color: var(--secondary-color);
font-weight: bold;
}
.footer {
margin-top: 40px;
padding: 20px 0;
background-color: var(--primary-color);
color: white;
text-align: center;
}
.toast-container {
position: fixed;
top: 20px;
right: 20px;
z-index: 1050;
}
.tab-pane {
padding-top: 20px;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container">
<a class="navbar-brand" href="#">
<i class="bi bi-mortarboard-fill me-2"></i>教师辅助工具
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link active" href="#">教学资源生成</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container mt-4">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<i class="bi bi-book me-2"></i>教学资源生成工具
</div>
<div class="card-body">
<p class="text-muted">使用此工具生成万有引力相关的导学案、教案、课件和作业。您可以自定义提示词以获得更符合需求的内容。</p>
<ul class="nav nav-tabs" id="resourceTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="daoXueAn-tab" data-bs-toggle="tab" data-bs-target="#daoXueAn" type="button" role="tab">导学案</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="jiaoAn-tab" data-bs-toggle="tab" data-bs-target="#jiaoAn" type="button" role="tab">教案</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="keJian-tab" data-bs-toggle="tab" data-bs-target="#keJian" type="button" role="tab">课件</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="zuoYe-tab" data-bs-toggle="tab" data-bs-target="#zuoYe" type="button" role="tab">作业</button>
</li>
</ul>
<div class="tab-content" id="resourceTabsContent">
<!-- 导学案标签页 -->
<div class="tab-pane fade show active" id="daoXueAn" role="tabpanel">
<form id="daoXueAnForm">
<div class="mb-3">
<label for="daoXueAnSystemPrompt" class="form-label">系统提示词</label>
<textarea class="form-control" id="daoXueAnSystemPrompt" rows="3">你是市级骨干教师,撰写导学案时严格对标"核心素养四维度(物理观念、科学思维、探究能力、态度责任)",并采用"目标—评价—活动"逆向设计模板UbD。活动设计需包含"教师行为+期望的学生行为+评价要点"三列表格。</textarea>
</div>
<div class="mb-3">
<label for="daoXueAnUserPrompt" class="form-label">用户提示词</label>
<textarea class="form-control" id="daoXueAnUserPrompt" rows="6">请输出"万有引力"第1课时的导学案要求
1. 教学重难点用"行为动词+知识内容"表述;
2. 至少1个"演示实验"+1个"小组探究"+1个"即时反馈"技术如Padlet
3. 时间轴精确到分钟;
4. 课后"教学反思提示"留3条空白供教师手写。
【格式要求】
### 1. 教材与学情分析
### 2. 四维目标(对应核心素养)
### 3. 重难点
### 4. 教学准备(器材+数字资源)
### 5. 教学过程(时间轴表格)
### 6. 板书设计ASCII示意图
### 7. 作业布置(与导学案分层衔接)
### 8. 教学反思提示(空白)
【变量】
教材版本:{人教版八年级下第十章第2节}
学生基础:{已学过重力、匀速圆周运动}
课时长度:{45分钟}</textarea>
</div>
<button type="button" class="btn btn-primary" onclick="generateResource('daoXueAn')">
<i class="bi bi-magic me-2"></i>生成导学案
</button>
</form>
<div id="daoXueAnLoading" class="loading">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">加载中...</span>
</div>
<p class="mt-2">正在生成导学案,请稍候...</p>
</div>
<div id="daoXueAnResult" class="result-container" style="display: none;"></div>
</div>
<!-- 教案标签页 -->
<div class="tab-pane fade" id="jiaoAn" role="tabpanel">
<form id="jiaoAnForm">
<div class="mb-3">
<label for="jiaoAnSystemPrompt" class="form-label">系统提示词</label>
<textarea class="form-control" id="jiaoAnSystemPrompt" rows="3">你是市级骨干教师,撰写教案时严格对标"核心素养四维度(物理观念、科学思维、探究能力、态度责任)",并采用"目标—评价—活动"逆向设计模板UbD。活动设计需包含"教师行为+期望的学生行为+评价要点"三列表格。</textarea>
</div>
<div class="mb-3">
<label for="jiaoAnUserPrompt" class="form-label">用户提示词</label>
<textarea class="form-control" id="jiaoAnUserPrompt" rows="6">请输出"万有引力"第1课时的详案要求
1. 教学重难点用"行为动词+知识内容"表述;
2. 至少1个"演示实验"+1个"小组探究"+1个"即时反馈"技术如Padlet
3. 时间轴精确到分钟;
4. 课后"教学反思提示"留3条空白供教师手写。
【格式要求】
### 1. 教材与学情分析
### 2. 四维目标(对应核心素养)
### 3. 重难点
### 4. 教学准备(器材+数字资源)
### 5. 教学过程(时间轴表格)
### 6. 板书设计ASCII示意图
### 7. 作业布置(与导学案分层衔接)
### 8. 教学反思提示(空白)
【变量】
教材版本:{人教版八年级下第十章第2节}
学生基础:{已学过重力、匀速圆周运动}
课时长度:{45分钟}</textarea>
</div>
<button type="button" class="btn btn-primary" onclick="generateResource('jiaoAn')">
<i class="bi bi-magic me-2"></i>生成教案
</button>
</form>
<div id="jiaoAnLoading" class="loading">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">加载中...</span>
</div>
<p class="mt-2">正在生成教案,请稍候...</p>
</div>
<div id="jiaoAnResult" class="result-container" style="display: none;"></div>
</div>
<!-- 课件标签页 -->
<div class="tab-pane fade" id="keJian" role="tabpanel">
<form id="keJianForm">
<div class="mb-3">
<label for="keJianSystemPrompt" class="form-label">系统提示词</label>
<textarea class="form-control" id="keJianSystemPrompt" rows="3">你是PPT视觉设计教练遵循"6×6原则"每页≤6行每行≤6词字体≥28pt主色调#005BAC教育蓝强调色#FFB703暖黄。所有动画≤0.5s,禁止花哨。需要给出演示者备注栏(<备注>)。</textarea>
</div>
<div class="mb-3">
<label for="keJianUserPrompt" class="form-label">用户提示词</label>
<textarea class="form-control" id="keJianUserPrompt" rows="6">为"万有引力"生成可直接导入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` 占位并给出版权提示;在要点后另起一行写<备注>演示者话术。</textarea>
</div>
<button type="button" class="btn btn-primary" onclick="generateResource('keJian')">
<i class="bi bi-magic me-2"></i>生成课件
</button>
</form>
<div id="keJianLoading" class="loading">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">加载中...</span>
</div>
<p class="mt-2">正在生成课件,请稍候...</p>
</div>
<div id="keJianResult" class="result-container" style="display: none;"></div>
</div>
<!-- 作业标签页 -->
<div class="tab-pane fade" id="zuoYe" role="tabpanel">
<form id="zuoYeForm">
<div class="mb-3">
<label for="zuoYeSystemPrompt" class="form-label">系统提示词</label>
<textarea class="form-control" id="zuoYeSystemPrompt" rows="3">你是命题专家,熟悉布鲁姆认知分类和'双减'政策。你需要根据用户提供的题目材料来生成作业,而不是自己创造题目。客观题采用'四选一'单选,难度比例易:中:难=6:3:1主观题设置2小问第1问'解释现象'对应'理解'第2问'方案设计'对应'创新'。题量控制为20分钟完成。</textarea>
</div>
<div class="mb-3">
<label for="zuoYeUserPrompt" class="form-label">用户提示词</label>
<textarea class="form-control" id="zuoYeUserPrompt" rows="6">请根据以下'万有引力'相关题目材料输出课后作业满分100分
A. 客观题8题×5分=40分
- 从提供的材料中选择题目,并按要求重新组织
- 前3题考'史实&概念'识记
- 中间3题考'公式变形&比例'理解
- 后2题考'情境估算'应用
B. 主观题2题30+30分
- 题1结合'天问一号'发射新闻,解释地球与火星之间的引力如何变化
- 题2设计一个实验用智能手机+免费APP估算地球质量写出步骤与所需测量量
C. 评分标准主观题分点给分每点10分
D. 参考答案与解析(客观题给出选项+一句话解析;主观题给出关键公式与评分关键词)</textarea>
</div>
<button type="button" class="btn btn-primary" onclick="generateResource('zuoYe')">
<i class="bi bi-magic me-2"></i>生成作业
</button>
</form>
<div id="zuoYeLoading" class="loading">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">加载中...</span>
</div>
<p class="mt-2">正在生成作业,请稍候...</p>
</div>
<div id="zuoYeResult" class="result-container" style="display: none;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="container">
<p class="mb-0">© 2023 教师辅助工具 - 万有引力教学资源生成</p>
</div>
</footer>
<!-- Toast 通知容器 -->
<div class="toast-container"></div>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<!-- 自定义JavaScript -->
<script>
// 生成资源函数
async function generateResource(resourceType) {
// 获取表单数据
let systemPrompt, userPrompt, materialPath;
switch(resourceType) {
case 'daoXueAn':
systemPrompt = document.getElementById('daoXueAnSystemPrompt').value;
userPrompt = document.getElementById('daoXueAnUserPrompt').value;
break;
case 'jiaoAn':
systemPrompt = document.getElementById('jiaoAnSystemPrompt').value;
userPrompt = document.getElementById('jiaoAnUserPrompt').value;
break;
case 'keJian':
systemPrompt = document.getElementById('keJianSystemPrompt').value;
userPrompt = document.getElementById('keJianUserPrompt').value;
break;
case 'zuoYe':
systemPrompt = document.getElementById('zuoYeSystemPrompt').value;
userPrompt = document.getElementById('zuoYeUserPrompt').value;
// 设置默认的题目材料路径,不暴露给用户
materialPath = '../static/YunXiao.txt';
break;
}
// 显示加载状态
document.getElementById(resourceType + 'Loading').style.display = 'block';
document.getElementById(resourceType + 'Result').style.display = 'none';
// 准备请求数据
const requestData = {
system_prompt: systemPrompt,
user_prompt: userPrompt
};
if (materialPath) {
requestData.material_path = materialPath;
}
try {
// 发送请求
const response = await fetch(`/api/teacher/${resourceType}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(requestData)
});
if (!response.ok) {
throw new Error(`请求失败: ${response.status}`);
}
// 处理SSE响应
const reader = response.body.getReader();
const decoder = new TextDecoder();
let resultText = '';
// 显示结果容器
document.getElementById(resourceType + 'Loading').style.display = 'none';
document.getElementById(resourceType + 'Result').style.display = 'block';
const resultContainer = document.getElementById(resourceType + 'Result');
resultContainer.innerHTML = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split('\n\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.substring(6); // 移除 'data: ' 前缀
if (data === '[DONE]') {
showToast('生成完成!', 'success');
return;
}
if (data && !data.startsWith('开始生成')) {
resultText += data;
resultContainer.innerHTML = resultText;
// 滚动到底部
resultContainer.scrollTop = resultContainer.scrollHeight;
}
}
}
}
showToast('生成完成!', 'success');
} catch (error) {
console.error('生成资源时出错:', error);
document.getElementById(resourceType + 'Loading').style.display = 'none';
showToast(`生成失败: ${error.message}`, 'danger');
}
}
// 显示Toast通知
function showToast(message, type = 'info') {
const toastContainer = document.querySelector('.toast-container');
const toastId = 'toast-' + Date.now();
const toastHtml = `
<div id="${toastId}" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<i class="bi bi-${type === 'success' ? 'check-circle-fill text-success' : type === 'danger' ? 'exclamation-triangle-fill text-danger' : 'info-circle-fill text-info'} me-2"></i>
<strong class="me-auto">系统通知</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
${message}
</div>
</div>
`;
toastContainer.insertAdjacentHTML('beforeend', toastHtml);
const toastElement = document.getElementById(toastId);
const toast = new bootstrap.Toast(toastElement, {
autohide: true,
delay: 3000
});
toast.show();
// 监听隐藏事件,移除元素
toastElement.addEventListener('hidden.bs.toast', () => {
toastElement.remove();
});
}
</script>
</body>
</html>