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

- 前端: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
+67
View File
@@ -0,0 +1,67 @@
const { chromium } = require('playwright-core');
const fs = require('fs');
const path = require('path');
const SHOTS = 'D:/AI/jiaoyu/_shots';
if (!fs.existsSync(SHOTS)) fs.mkdirSync(SHOTS, { recursive: true });
(async () => {
const browser = await chromium.launch({ channel: 'chrome', headless: true, executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe' });
const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 } });
const page = await ctx.newPage();
const allErrors = [];
page.on('pageerror', e => allErrors.push('PAGE: ' + e.message));
page.on('console', m => { if (m.type() === 'error') { const t = m.text(); if (!t.includes('favicon') && !t.includes('404')) allErrors.push('CON: ' + t.slice(0,150)); } });
// Login
const loginResp = await page.request.post('http://localhost:8000/api/auth/login', {
data: { phone: '13943441149', password: 'Test1234' }
});
const { access_token } = await loginResp.json();
const pages = [
{ name: 'home', url: 'http://localhost:5174/', wait: 2500 },
{ name: 'courseware-create', url: 'http://localhost:5174/courseware/create', wait: 2000 },
{ name: 'animation', url: 'http://localhost:5174/animation', wait: 2000 },
{ name: 'exercise', url: 'http://localhost:5174/exercise', wait: 2000 },
{ name: 'lesson-plan', url: 'http://localhost:5174/lesson-plan', wait: 2000 },
{ name: 'exam', url: 'http://localhost:5174/exam', wait: 2000 },
{ name: 'essay-grade', url: 'http://localhost:5174/essay-grade', wait: 2000 },
{ name: 'mindmap', url: 'http://localhost:5174/mindmap', wait: 2000 },
{ name: 'resources', url: 'http://localhost:5174/resources', wait: 2000 },
{ name: 'community', url: 'http://localhost:5174/community', wait: 2000 },
{ name: 'classroom', url: 'http://localhost:5174/classroom', wait: 2000 },
{ name: 'materials', url: 'http://localhost:5174/materials', wait: 2000 },
{ name: 'profile', url: 'http://localhost:5174/profile', wait: 2000 },
{ name: 'search', url: 'http://localhost:5174/search?q=数学', wait: 2000 },
{ name: 'assistant', url: 'http://localhost:5174/assistant', wait: 2000 },
];
const results = [];
for (const p of pages) {
const errorsBefore = allErrors.length;
await page.goto(p.url, { waitUntil: 'networkidle', timeout: 15000 }).catch(() => {});
// Inject token on first navigation
if (p.name === 'home') {
await page.evaluate((t) => { localStorage.setItem('access_token', t); localStorage.setItem('refresh_token', t); }, access_token);
await page.reload({ waitUntil: 'networkidle' });
}
await page.waitForTimeout(p.wait);
await page.screenshot({ path: path.join(SHOTS, p.name + '.png'), fullPage: false });
const bodyLen = await page.evaluate(() => document.body.innerText.length);
const h1 = await page.locator('h1, h2, .page-title, .tpl-title').first().textContent().catch(() => '');
const newErrors = allErrors.slice(errorsBefore);
results.push({ name: p.name, bodyLen, title: h1.trim().slice(0,40), errors: newErrors.length });
console.log('[' + p.name + '] bodyLen=' + bodyLen + ' title="' + h1.trim().slice(0,35) + '" errors=' + newErrors.length);
if (newErrors.length) newErrors.slice(0,2).forEach(e => console.log(' ' + e));
}
console.log('\n=== Summary ===');
console.log('Total pages:', results.length);
console.log('Total errors:', allErrors.length);
const small = results.filter(r => r.bodyLen < 200);
console.log('Pages with thin content (<200 chars):', small.length);
small.forEach(r => console.log(' ' + r.name + ': ' + r.bodyLen + ' chars'));
await browser.close();
})().catch(e => { console.error('FATAL', e.message); process.exit(1); });