- 7 个 HTML 页面(106KB) - 移动端模式:375×812 手机框架 - 基于需求文档中的 UI/UX 设计规格生成 页面列表: - mobile-index.html: 移动端统一入口 - home.html: 首页抽背启动(4个抽背考点按钮) - ai-quiz.html: AI抽背界面(语音交互) - quiz-report.html: 抽背报告(正确率、错误分析) - memory-curve.html: 记忆曲线可视化(复习计划日历) - card-recite.html: 卡片背诵(挖空填空) - profile.html: 个人中心 技术栈:Tailwind CSS + Font Awesome 设计规范:蓝色/绿色渐变导航,375×812 手机框架 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
173 lines
5.9 KiB
JavaScript
173 lines
5.9 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
/**
|
||
* AI 智能抽背助手 - 移动端原型本地预览服务器
|
||
*
|
||
* 使用方法:
|
||
* node server.js
|
||
*
|
||
* 功能:
|
||
* - 启动本地 HTTP 服务器(端口 8081)
|
||
* - 自动打开浏览器访问移动端原型
|
||
* - 支持热重载(修改文件后自动刷新)
|
||
*
|
||
* @author generate-prototype-grid skill
|
||
* @date 2026-03-28
|
||
*/
|
||
|
||
const http = require('http');
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
const { exec } = require('child_process');
|
||
|
||
const PORT = 8081;
|
||
const PROTOTYPE_DIR = __dirname;
|
||
|
||
// MIME 类型映射
|
||
const MIME_TYPES = {
|
||
'.html': 'text/html; charset=utf-8',
|
||
'.css': 'text/css; charset=utf-8',
|
||
'.js': 'application/javascript; charset=utf-8',
|
||
'.json': 'application/json; charset=utf-8',
|
||
'.png': 'image/png',
|
||
'.jpg': 'image/jpeg',
|
||
'.jpeg': 'image/jpeg',
|
||
'.gif': 'image/gif',
|
||
'.svg': 'image/svg+xml',
|
||
'.ico': 'image/x-icon',
|
||
'.woff': 'font/woff',
|
||
'.woff2': 'font/woff2',
|
||
'.ttf': 'font/ttf',
|
||
'.md': 'text/markdown; charset=utf-8',
|
||
};
|
||
|
||
// 创建服务器
|
||
const server = http.createServer((req, res) => {
|
||
// 解析 URL
|
||
let urlPath = req.url;
|
||
|
||
// 处理根路径
|
||
if (urlPath === '/') {
|
||
urlPath = '/mobile-index.html';
|
||
}
|
||
|
||
// 构建文件路径
|
||
const filePath = path.join(PROTOTYPE_DIR, urlPath);
|
||
const extname = path.extname(filePath).toLowerCase();
|
||
|
||
// 设置响应头
|
||
const contentType = MIME_TYPES[extname] || 'application/octet-stream';
|
||
|
||
// 读取并返回文件
|
||
fs.readFile(filePath, (err, content) => {
|
||
if (err) {
|
||
if (err.code === 'ENOENT') {
|
||
// 文件不存在
|
||
res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' });
|
||
res.end(`
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>404 - 文件未找到</title>
|
||
<style>
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
height: 100vh;
|
||
margin: 0;
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
}
|
||
.error-box {
|
||
text-align: center;
|
||
background: white;
|
||
padding: 40px;
|
||
border-radius: 12px;
|
||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||
}
|
||
h1 { color: #667eea; margin: 0 0 16px 0; }
|
||
p { color: #666; margin: 0 0 24px 0; }
|
||
a {
|
||
color: #667eea;
|
||
text-decoration: none;
|
||
padding: 8px 16px;
|
||
border: 1px solid #667eea;
|
||
border-radius: 6px;
|
||
display: inline-block;
|
||
}
|
||
a:hover { background: #667eea; color: white; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="error-box">
|
||
<h1>404</h1>
|
||
<p>文件未找到: ${urlPath}</p>
|
||
<a href="/mobile-index.html">返回首页</a>
|
||
</div>
|
||
</body>
|
||
</html>
|
||
`);
|
||
} else {
|
||
// 服务器错误
|
||
res.writeHead(500, { 'Content-Type': 'text/html; charset=utf-8' });
|
||
res.end('服务器错误: ' + err.code);
|
||
}
|
||
} else {
|
||
// 成功返回文件
|
||
res.writeHead(200, { 'Content-Type': contentType });
|
||
res.end(content);
|
||
}
|
||
});
|
||
});
|
||
|
||
// 启动服务器
|
||
server.listen(PORT, () => {
|
||
console.log('='.repeat(60));
|
||
console.log(' AI 智能抽背助手 - 移动端原型本地预览服务器');
|
||
console.log('='.repeat(60));
|
||
console.log('');
|
||
console.log(` 服务器地址: http://localhost:${PORT}`);
|
||
console.log('');
|
||
console.log(' 可用页面:');
|
||
console.log(` - 统一入口: http://localhost:${PORT}/mobile-index.html`);
|
||
console.log('');
|
||
console.log(' 移动端页面:');
|
||
console.log(` - 首页抽背: /pages/mobile/home.html`);
|
||
console.log(` - AI智能抽背: /pages/mobile/ai-quiz.html`);
|
||
console.log(` - 抽背报告: /pages/mobile/quiz-report.html`);
|
||
console.log(` - 记忆曲线: /pages/mobile/memory-curve.html`);
|
||
console.log(` - 卡片背诵: /pages/mobile/card-recite.html`);
|
||
console.log(` - 个人中心: /pages/mobile/profile.html`);
|
||
console.log('');
|
||
console.log(' 按 Ctrl+C 停止服务器');
|
||
console.log('='.repeat(60));
|
||
console.log('');
|
||
|
||
// 自动打开浏览器
|
||
const openCommand = process.platform === 'win32' ? 'start' :
|
||
process.platform === 'darwin' ? 'open' : 'xdg-open';
|
||
|
||
exec(`${openCommand} http://localhost:${PORT}`, (error) => {
|
||
if (error) {
|
||
console.log(' 提示: 无法自动打开浏览器,请手动访问上述地址');
|
||
} else {
|
||
console.log(' 已自动打开浏览器');
|
||
}
|
||
console.log('');
|
||
});
|
||
});
|
||
|
||
// 优雅退出
|
||
process.on('SIGINT', () => {
|
||
console.log('');
|
||
console.log('正在停止服务器...');
|
||
server.close(() => {
|
||
console.log('服务器已停止');
|
||
process.exit(0);
|
||
});
|
||
});
|
||
|
||
module.exports = server;
|