智教助手平台:完整初始化

- 前端:Vue3 + TS + Element Plus,24 个页面路由(课件/组题/教案/动画/思维导图/作文批改/命题/课堂/资源/社区等)
- 后端:FastAPI + SQLAlchemy + SQLite,17 个路由模块,AI 服务层含降级模板
- AI:glm-5.x 推理模型已禁用思维链,确保输出真实内容
- 修复:ai_service 两处请求体注入 enable_thinking/thinking disabled
- 测试账号:13900999999 / test1234
This commit is contained in:
Zhang Jing Xuan
2026-07-29 16:29:10 +08:00
commit 0841b1a103
193 changed files with 44995 additions and 0 deletions
+107
View File
@@ -0,0 +1,107 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>API调试工具</title>
<style>
body{font-family:monospace;padding:20px;background:#1e1e1e;color:#d4d4d4;font-size:13px;}
button{padding:8px 16px;margin:4px;border:none;border-radius:4px;cursor:pointer;font-size:13px;}
.btn-login{background:#4F46E5;color:#fff;}
.btn-gen{background:#10B981;color:#fff;}
#log{background:#000;padding:16px;border-radius:8px;white-space:pre-wrap;max-height:600px;overflow:auto;margin-top:16px;line-height:1.6;}
.ok{color:#4ADE80;} .err{color:#F87171;} .info{color:#60A5FA;} .warn{color:#FBBF24;}
</style>
</head>
<body>
<h2>AI课件生成 - 调试工具</h2>
<button class="btn-login" onclick="doLogin()">1. 登录获取Token</button>
<button class="btn-gen" onclick="doGenerate()">2. 调用AI生成课件</button>
<div id="log"></div>
<script>
let token = '';
const log = document.getElementById('log');
function addLog(msg, cls='info') {
log.innerHTML += `<span class="${cls}">${msg}</span>\n`;
log.scrollTop = log.scrollHeight;
}
async function doLogin() {
log.innerHTML = '';
addLog('正在登录...', 'info');
try {
const r = await fetch('/api/auth/login', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({phone: '13800001111', password: 'Test1234'})
});
const data = await r.json();
if (data.access_token) {
token = data.access_token;
addLog(`登录成功! Token: ${token.substring(0,30)}...`, 'ok');
} else {
addLog(`登录失败: ${JSON.stringify(data)}`, 'err');
}
} catch(e) {
addLog(`登录异常: ${e.message}`, 'err');
}
}
async function doGenerate() {
if (!token) { addLog('请先登录!', 'warn'); return; }
addLog('正在调用AI生成课件(可能需要1-3分钟)...', 'info');
try {
const r = await fetch('/api/coursewares/ai-generate', {
method: 'POST',
headers: {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token},
body: JSON.stringify({prompt:'生成一元一次方程课件',subject:'数学',grade:'初一',page_count:3})
});
addLog(`HTTP状态: ${r.status} ${r.statusText}`, r.ok ? 'ok' : 'err');
const text = await r.text();
addLog(`响应长度: ${text.length} 字符`, 'info');
// Try parse
let data;
try {
data = JSON.parse(text);
} catch(e) {
addLog(`JSON解析失败: ${e.message}`, 'err');
addLog(`前500字符: ${text.substring(0,500)}`, 'warn');
return;
}
addLog(`顶层keys: ${Object.keys(data).join(', ')}`, 'info');
addLog(`success: ${data.success}`, 'info');
if (data.data) {
addLog(`data.data类型: ${typeof data.data}`, 'info');
if (typeof data.data === 'object') {
addLog(`data.data keys: ${Object.keys(data.data).join(', ')}`, 'info');
const pages = data.data.pages;
addLog(`pages: ${pages ? pages.length : 'undefined/null'}`, pages?.length ? 'ok' : 'err');
if (pages && pages.length > 0) {
for (let i = 0; i < pages.length; i++) {
const p = pages[i];
const content = p.content || '';
addLog(` Page ${i+1}: type=${p.type} title=${p.title} content_len=${content.length} has_html=${content.includes('<div')}`, 'info');
}
addLog(`\nPage 1 content前200字符:\n${pages[0].content.substring(0,200)}`, 'ok');
} else {
addLog(`\n⚠️ pages为空或undefined!`, 'err');
addLog(`完整data.data: ${JSON.stringify(data.data).substring(0,1000)}`, 'warn');
}
} else {
addLog(`⚠️ data.data不是对象: ${typeof data.data}`, 'err');
addLog(`data.data值: ${String(data.data).substring(0,500)}`, 'warn');
}
} else {
addLog(`⚠️ 没有data字段!`, 'err');
addLog(`完整响应: ${text.substring(0,1000)}`, 'warn');
}
} catch(e) {
addLog(`请求异常: ${e.message}`, 'err');
}
}
</script>
</body>
</html>
+10
View File
@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<defs>
<linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#4F46E5"/>
<stop offset="100%" stop-color="#8B5CF6"/>
</linearGradient>
</defs>
<rect width="32" height="32" rx="8" fill="url(#g)"/>
<text x="16" y="23" text-anchor="middle" fill="white" font-family="system-ui" font-weight="700" font-size="18">AI</text>
</svg>

After

Width:  |  Height:  |  Size: 447 B

+32
View File
@@ -0,0 +1,32 @@
<!DOCTYPE html><html><head><meta charset='UTF-8'></head><body style='margin:0;background:#eee;display:flex;justify-content:center;padding:20px;'><div style="width:800px;height:600px;margin:0 auto;background:linear-gradient(135deg,#0f2027,#203a43,#2c5364);display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;overflow:hidden;font-family:'Microsoft YaHei',sans-serif;">
<div style="position:absolute;top:-80px;left:-80px;width:260px;height:260px;border-radius:50%;background:rgba(255,165,0,0.08);"></div>
<div style="position:absolute;bottom:-60px;right:-60px;width:220px;height:220px;border-radius:50%;background:rgba(0,200,150,0.08);"></div>
<div style="position:absolute;top:40px;right:60px;width:100px;height:100px;border:3px solid rgba(255,255,255,0.06);border-radius:50%;"></div>
<div style="position:absolute;bottom:60px;left:50px;width:60px;height:60px;border:2px solid rgba(255,255,255,0.05);border-radius:50%;"></div>
<div style="position:relative;z-index:2;text-align:center;">
<div style="display:inline-block;background:linear-gradient(135deg,#ff6b35,#f7931e);padding:8px 32px;border-radius:30px;margin-bottom:20px;">
<span style="color:#fff;font-size:15px;font-weight:bold;letter-spacing:4px;">初一数学</span>
</div>
<h1 style="font-size:52px;color:#ffffff;margin:0 0 12px 0;letter-spacing:6px;text-shadow:0 4px 20px rgba(0,0,0,0.3);">一元一次方程</h1>
<div style="width:80px;height:3px;background:linear-gradient(90deg,#ff6b35,#00c896);margin:0 auto 20px auto;border-radius:2px;"></div>
<p style="color:rgba(255,255,255,0.7);font-size:18px;margin:0 0 30px 0;letter-spacing:2px;">从生活问题到代数思维的桥梁</p>
<div style="display:flex;gap:20px;justify-content:center;">
<div style="background:rgba(255,255,255,0.08);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.1);border-radius:16px;padding:20px 24px;text-align:center;width:160px;">
<div style="font-size:36px;margin-bottom:8px;">📖</div>
<div style="color:#fff;font-size:14px;font-weight:bold;">定义与性质</div>
<div style="color:rgba(255,255,255,0.5);font-size:12px;margin-top:4px;">概念理解</div>
</div>
<div style="background:rgba(255,255,255,0.08);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.1);border-radius:16px;padding:20px 24px;text-align:center;width:160px;">
<div style="font-size:36px;margin-bottom:8px;">✏️</div>
<div style="color:#fff;font-size:14px;font-weight:bold;">解题步骤</div>
<div style="color:rgba(255,255,255,0.5);font-size:12px;margin-top:4px;">方法掌握</div>
</div>
<div style="background:rgba(255,255,255,0.08);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.1);border-radius:16px;padding:20px 24px;text-align:center;width:160px;">
<div style="font-size:36px;margin-bottom:8px;">🎯</div>
<div style="color:#fff;font-size:14px;font-weight:bold;">实战练习</div>
<div style="color:rgba(255,255,255,0.5);font-size:12px;margin-top:4px;">巩固提升</div>
</div>
</div>
</div>
<div style="position:absolute;bottom:20px;color:rgba(255,255,255,0.3);font-size:12px;letter-spacing:1px;">点击下方箭头开始学习 →</div>
</div></body></html>
+51
View File
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Test</title></head>
<body style="background:#eee;padding:20px;">
<h2>Test: iframe srcdoc rendering</h2>
<div style="margin-bottom:10px;">
<button onclick="loadContent()">Load Content into iframe</button>
</div>
<iframe id="test-iframe" style="width:820px;height:620px;border:1px solid #ccc;"></iframe>
<textarea id="raw" style="width:100%;height:200px;margin-top:10px;"><div style="width:800px;height:600px;margin:0 auto;background:linear-gradient(135deg,#0f2027,#203a43,#2c5364);display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;overflow:hidden;font-family:'Microsoft YaHei',sans-serif;">
<div style="position:absolute;top:-80px;left:-80px;width:260px;height:260px;border-radius:50%;background:rgba(255,165,0,0.08);"></div>
<div style="position:absolute;bottom:-60px;right:-60px;width:220px;height:220px;border-radius:50%;background:rgba(0,200,150,0.08);"></div>
<div style="position:absolute;top:40px;right:60px;width:100px;height:100px;border:3px solid rgba(255,255,255,0.06);border-radius:50%;"></div>
<div style="position:absolute;bottom:60px;left:50px;width:60px;height:60px;border:2px solid rgba(255,255,255,0.05);border-radius:50%;"></div>
<div style="position:relative;z-index:2;text-align:center;">
<div style="display:inline-block;background:linear-gradient(135deg,#ff6b35,#f7931e);padding:8px 32px;border-radius:30px;margin-bottom:20px;">
<span style="color:#fff;font-size:15px;font-weight:bold;letter-spacing:4px;">初一数学</span>
</div>
<h1 style="font-size:52px;color:#ffffff;margin:0 0 12px 0;letter-spacing:6px;text-shadow:0 4px 20px rgba(0,0,0,0.3);">一元一次方程</h1>
<div style="width:80px;height:3px;background:linear-gradient(90deg,#ff6b35,#00c896);margin:0 auto 20px auto;border-radius:2px;"></div>
<p style="color:rgba(255,255,255,0.7);font-size:18px;margin:0 0 30px 0;letter-spacing:2px;">从生活问题到代数思维的桥梁</p>
<div style="display:flex;gap:20px;justify-content:center;">
<div style="background:rgba(255,255,255,0.08);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.1);border-radius:16px;padding:20px 24px;text-align:center;width:160px;">
<div style="font-size:36px;margin-bottom:8px;">📖</div>
<div style="color:#fff;font-size:14px;font-weight:bold;">定义与性质</div>
<div style="color:rgba(255,255,255,0.5);font-size:12px;margin-top:4px;">概念理解</div>
</div>
<div style="background:rgba(255,255,255,0.08);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.1);border-radius:16px;padding:20px 24px;text-align:center;width:160px;">
<div style="font-size:36px;margin-bottom:8px;">✏️</div>
<div style="color:#fff;font-size:14px;font-weight:bold;">解题步骤</div>
<div style="color:rgba(255,255,255,0.5);font-size:12px;margin-top:4px;">方法掌握</div>
</div>
<div style="background:rgba(255,255,255,0.08);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.1);border-radius:16px;padding:20px 24px;text-align:center;width:160px;">
<div style="font-size:36px;margin-bottom:8px;">🎯</div>
<div style="color:#fff;font-size:14px;font-weight:bold;">实战练习</div>
<div style="color:rgba(255,255,255,0.5);font-size:12px;margin-top:4px;">巩固提升</div>
</div>
</div>
</div>
<div style="position:absolute;bottom:20px;color:rgba(255,255,255,0.3);font-size:12px;letter-spacing:1px;">点击下方箭头开始学习 →</div>
</div></textarea>
<script>
function loadContent() {
const iframe = document.getElementById('test-iframe');
const raw = document.getElementById('raw').value;
iframe.srcdoc = raw;
}
</script>
</body>
</html>
+46
View File
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>Vue Iframe Test</title></head>
<body style="padding:20px;background:#f5f5f5;font-family:sans-serif;">
<h2>Test: Does srcdoc work?</h2>
<div id="app"></div>
<script>
const html = `<div style="width:800px;height:600px;margin:0 auto;background:linear-gradient(135deg,#0f2027,#203a43,#2c5364);display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;overflow:hidden;font-family:'Microsoft YaHei',sans-serif;">
<div style="position:absolute;top:-80px;left:-80px;width:260px;height:260px;border-radius:50%;background:rgba(255,165,0,0.08);"></div>
<div style="position:absolute;bottom:-60px;right:-60px;width:220px;height:220px;border-radius:50%;background:rgba(0,200,150,0.08);"></div>
<div style="position:absolute;top:40px;right:60px;width:100px;height:100px;border:3px solid rgba(255,255,255,0.06);border-radius:50%;"></div>
<div style="position:absolute;bottom:60px;left:50px;width:60px;height:60px;border:2px solid rgba(255,255,255,0.05);border-radius:50%;"></div>
<div style="position:relative;z-index:2;text-align:center;">
<div style="display:inline-block;background:linear-gradient(135deg,#ff6b35,#f7931e);padding:8px 32px;border-radius:30px;margin-bottom:20px;">
<span style="color:#fff;font-size:15px;font-weight:bold;letter-spacing:4px;">初一数学</span>
</div>
<h1 style="font-size:52px;color:#ffffff;margin:0 0 12px 0;letter-spacing:6px;text-shadow:0 4px 20px rgba(0,0,0,0.3);">一元一次方程</h1>
<div style="width:80px;height:3px;background:linear-gradient(90deg,#ff6b35,#00c896);margin:0 auto 20px auto;border-radius:2px;"></div>
<p style="color:rgba(255,255,255,0.7);font-size:18px;margin:0 0 30px 0;letter-spacing:2px;">从生活问题到代数思维的桥梁</p>
<div style="display:flex;gap:20px;justify-content:center;">
<div style="background:rgba(255,255,255,0.08);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.1);border-radius:16px;padding:20px 24px;text-align:center;width:160px;">
<div style="font-size:36px;margin-bottom:8px;">📖</div>
<div style="color:#fff;font-size:14px;font-weight:bold;">定义与性质</div>
<div style="color:rgba(255,255,255,0.5);font-size:12px;margin-top:4px;">概念理解</div>
</div>
<div style="background:rgba(255,255,255,0.08);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.1);border-radius:16px;padding:20px 24px;text-align:center;width:160px;">
<div style="font-size:36px;margin-bottom:8px;">✏️</div>
<div style="color:#fff;font-size:14px;font-weight:bold;">解题步骤</div>
<div style="color:rgba(255,255,255,0.5);font-size:12px;margin-top:4px;">方法掌握</div>
</div>
<div style="background:rgba(255,255,255,0.08);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.1);border-radius:16px;padding:20px 24px;text-align:center;width:160px;">
<div style="font-size:36px;margin-bottom:8px;">🎯</div>
<div style="color:#fff;font-size:14px;font-weight:bold;">实战练习</div>
<div style="color:rgba(255,255,255,0.5);font-size:12px;margin-top:4px;">巩固提升</div>
</div>
</div>
</div>
<div style="position:absolute;bottom:20px;color:rgba(255,255,255,0.3);font-size:12px;letter-spacing:1px;">点击下方箭头开始学习 →</div>
</div>`;
const div = document.getElementById('app');
const iframe = document.createElement('iframe');
iframe.style.cssText = 'width:820px;height:620px;border:2px solid blue;display:block;';
div.appendChild(iframe);
iframe.srcdoc = html;
document.body.innerHTML += '<p style="color:green;">iframe created, srcdoc set, length=' + html.length + '</p>';
</script>
</body></html>
+40
View File
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>Iframe Test</title></head>
<body style="background:#eee;padding:20px;font-family:sans-serif;">
<h2>Iframe srcdoc Test</h2>
<p>Below should show the courseware page:</p>
<div style="border:2px solid red;width:820px;height:620px;">
<iframe style="width:100%;height:100%;border:none;" srcdoc="&lt;div style=&quot;width:800px;height:600px;margin:0 auto;background:linear-gradient(135deg,#0f2027,#203a43,#2c5364);display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;overflow:hidden;font-family:&#x27;Microsoft YaHei&#x27;,sans-serif;&quot;&gt;
&lt;div style=&quot;position:absolute;top:-80px;left:-80px;width:260px;height:260px;border-radius:50%;background:rgba(255,165,0,0.08);&quot;&gt;&lt;/div&gt;
&lt;div style=&quot;position:absolute;bottom:-60px;right:-60px;width:220px;height:220px;border-radius:50%;background:rgba(0,200,150,0.08);&quot;&gt;&lt;/div&gt;
&lt;div style=&quot;position:absolute;top:40px;right:60px;width:100px;height:100px;border:3px solid rgba(255,255,255,0.06);border-radius:50%;&quot;&gt;&lt;/div&gt;
&lt;div style=&quot;position:absolute;bottom:60px;left:50px;width:60px;height:60px;border:2px solid rgba(255,255,255,0.05);border-radius:50%;&quot;&gt;&lt;/div&gt;
&lt;div style=&quot;position:relative;z-index:2;text-align:center;&quot;&gt;
&lt;div style=&quot;display:inline-block;background:linear-gradient(135deg,#ff6b35,#f7931e);padding:8px 32px;border-radius:30px;margin-bottom:20px;&quot;&gt;
&lt;span style=&quot;color:#fff;font-size:15px;font-weight:bold;letter-spacing:4px;&quot;&gt;初一数学&lt;/span&gt;
&lt;/div&gt;
&lt;h1 style=&quot;font-size:52px;color:#ffffff;margin:0 0 12px 0;letter-spacing:6px;text-shadow:0 4px 20px rgba(0,0,0,0.3);&quot;&gt;一元一次方程&lt;/h1&gt;
&lt;div style=&quot;width:80px;height:3px;background:linear-gradient(90deg,#ff6b35,#00c896);margin:0 auto 20px auto;border-radius:2px;&quot;&gt;&lt;/div&gt;
&lt;p style=&quot;color:rgba(255,255,255,0.7);font-size:18px;margin:0 0 30px 0;letter-spacing:2px;&quot;&gt;从生活问题到代数思维的桥梁&lt;/p&gt;
&lt;div style=&quot;display:flex;gap:20px;justify-content:center;&quot;&gt;
&lt;div style=&quot;background:rgba(255,255,255,0.08);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.1);border-radius:16px;padding:20px 24px;text-align:center;width:160px;&quot;&gt;
&lt;div style=&quot;font-size:36px;margin-bottom:8px;&quot;&gt;📖&lt;/div&gt;
&lt;div style=&quot;color:#fff;font-size:14px;font-weight:bold;&quot;&gt;定义与性质&lt;/div&gt;
&lt;div style=&quot;color:rgba(255,255,255,0.5);font-size:12px;margin-top:4px;&quot;&gt;概念理解&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background:rgba(255,255,255,0.08);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.1);border-radius:16px;padding:20px 24px;text-align:center;width:160px;&quot;&gt;
&lt;div style=&quot;font-size:36px;margin-bottom:8px;&quot;&gt;✏️&lt;/div&gt;
&lt;div style=&quot;color:#fff;font-size:14px;font-weight:bold;&quot;&gt;解题步骤&lt;/div&gt;
&lt;div style=&quot;color:rgba(255,255,255,0.5);font-size:12px;margin-top:4px;&quot;&gt;方法掌握&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background:rgba(255,255,255,0.08);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.1);border-radius:16px;padding:20px 24px;text-align:center;width:160px;&quot;&gt;
&lt;div style=&quot;font-size:36px;margin-bottom:8px;&quot;&gt;🎯&lt;/div&gt;
&lt;div style=&quot;color:#fff;font-size:14px;font-weight:bold;&quot;&gt;实战练习&lt;/div&gt;
&lt;div style=&quot;color:rgba(255,255,255,0.5);font-size:12px;margin-top:4px;&quot;&gt;巩固提升&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;position:absolute;bottom:20px;color:rgba(255,255,255,0.3);font-size:12px;letter-spacing:1px;&quot;&gt;点击下方箭头开始学习 →&lt;/div&gt;
&lt;/div&gt;"></iframe>
</div>
</body></html>