基于html2web和deepseek实现单词卡片识记功能的web设计
代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>单词卡识记系统</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
width: 100%;
max-width: 1200px;
background-color: rgba(255, 255, 255, 0.9);
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
overflow: hidden;
}
header {
background: linear-gradient(to right, #4a00e0, #8e2de2);
color: white;
padding: 20px;
text-align: center;
}
h1 {
font-size: 2.5rem;
margin-bottom: 10px;
}
.subtitle {
font-size: 1.2rem;
opacity: 0.9;
}
.app-container {
display: flex;
min-height: 600px;
}
.sidebar {
width: 300px;
background-color: #f5f7fa;
padding: 20px;
border-right: 1px solid #e1e4e8;
}
.main-content {
flex: 1;
padding: 20px;
display: flex;
flex-direction: column;
}
.auth-section {
padding: 20px;
background-color: white;
border-radius: 10px;
margin-bottom: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: 600;
color: #333;
}
input, select {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 1rem;
}
button {
background: linear-gradient(to right, #4a00e0, #8e2de2);
color: white;
border: none;
padding: 10px 15px;
border-radius: 5px;
cursor: pointer;
font-size: 1rem;
transition: all 0.3s ease;
}
button:hover {
opacity: 0.9;
transform: translateY(-2px);
}
.btn-secondary {
background: linear-gradient(to right, #8e9eab, #eef2f3);
color: #333;
}
.user-info {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #e1e4e8;
}
.language-filter {
margin-bottom: 20px;
}
.word-list {
flex: 1;
overflow-y: auto;
max-height: 400px;
}
.word-card {
background-color: white;
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease;
}
.word-card:hover {
transform: translateY(-3px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
.word-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.word {
font-size: 1.5rem;
font-weight: bold;
color: #4a00e0;
}
.language-tag {
background-color: #8e2de2;
color: white;
padding: 3px 8px;
border-radius: 20px;
font-size: 0.8rem;
}
.meaning {
color: #555;
margin-bottom: 10px;
}
.example {
font-style: italic;
color: #777;
border-left: 3px solid #8e2de2;
padding-left: 10px;
margin-bottom: 10px;
}
.word-actions {
display: flex;
gap: 10px;
}
.btn-small {
padding: 5px 10px;
font-size: 0.8rem;
}
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-content {
background-color: white;
padding: 30px;
border-radius: 10px;
width: 90%;
max-width: 500px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.close-btn {
background: none;
border: none;
font-size: 1.5rem;
cursor: pointer;
color: #777;
}
.hidden {
display: none;
}
.tabs {
display: flex;
margin-bottom: 20px;
border-bottom: 1px solid #e1e4e8;
}
.tab {
padding: 10px 20px;
cursor: pointer;
border-bottom: 3px solid transparent;
}
.tab.active {
border-bottom: 3px solid #4a00e0;
color: #4a00e0;
font-weight: bold;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
.stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 15px;
margin-bottom: 20px;
}
.stat-card {
background: white;
padding: 15px;
border-radius: 8px;
text-align: center;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.stat-number {
font-size: 2rem;
font-weight: bold;
color: #4a00e0;
}
.stat-label {
font-size: 0.9rem;
color: #777;
}
.import-export-section {
margin-top: 20px;
padding-top: 20px;
border-top: 1px solid #e1e4e8;
}
.import-export-buttons {
display: flex;
flex-direction: column;
gap: 10px;
}
.file-input {
display: none;
}
@media (max-width: 768px) {
.app-container {
flex-direction: column;
}
.sidebar {
width: 100%;
border-right: none;
border-bottom: 1px solid #e1e4e8;
}
.stats {
grid-template-columns: 1fr;
}
.import-export-buttons {
flex-direction: row;
justify-content: space-between;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>单词卡识记系统</h1>
<div class="subtitle">高效学习,轻松记忆</div>
</header>
<div class="app-container">
<div class="sidebar">
<div id="auth-section" class="auth-section">
<h2>用户登录</h2>
<div class="form-group">
<label for="username">用户名</label>
<input type="text" id="username" placeholder="请输入用户名">
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" placeholder="请输入密码">
</div>
<button id="login-btn">登录</button>
<button id="show-register-btn" class="btn-secondary">注册新账户</button>
</div>
<div id="user-section" class="user-info hidden">
<div>
<h3 id="current-user">用户名</h3>
<p id="user-stats">单词数: 0</p>
</div>
<button id="logout-btn" class="btn-secondary">退出</button>
</div>
<div class="language-filter">
<h3>语种筛选</h3>
<select id="language-filter">
<option value="all">全部语种</option>
<option value="英语">英语</option>
<option value="日语">日语</option>
<option value="法语">法语</option>
<option value="德语">德语</option>
<option value="西班牙语">西班牙语</option>
<option value="其他">其他</option>
</select>
</div>
<div class="stats">
<div class="stat-card">
<div class="stat-number" id="total-words">0</div>
<div class="stat-label">总单词数</div>
</div>
<div class="stat-card">
<div class="stat-number" id="language-count">0</div>
<div class="stat-label">语种数</div>
</div>
<div class="stat-card">
<div class="stat-number" id="today-added">0</div>
<div class="stat-label">今日新增</div>
</div>
</div>
<div class="import-export-section">
<h3>数据管理</h3>
<div class="import-export-buttons">
<button id="export-btn" class="btn-secondary">导出单词数据</button>
<button id="import-btn" class="btn-secondary">导入单词数据</button>
<input type="file" id="file-input" class="file-input" accept=".json">
</div>
</div>
</div>
<div class="main-content">
<div class="tabs">
<div class="tab active" data-tab="words">单词列表</div>
<div class="tab" data-tab="add-word">添加单词</div>
<div class="tab" data-tab="review">复习模式</div>
</div>
<div id="words-tab" class="tab-content active">
<h2>我的单词卡</h2>
<div class="word-list" id="word-list">
<!-- 单词卡片将通过JavaScript动态生成 -->
</div>
</div>
<div id="add-word-tab" class="tab-content">
<h2>添加新单词</h2>
<div class="auth-section">
<div class="form-group">
<label for="new-word">单词</label>
<input type="text" id="new-word" placeholder="输入单词">
</div>
<div class="form-group">
<label for="new-meaning">释义</label>
<input type="text" id="new-meaning" placeholder="输入单词释义">
</div>
<div class="form-group">
<label for="new-example">例句</label>
<input type="text" id="new-example" placeholder="输入例句(可选)">
</div>
<div class="form-group">
<label for="new-language">语种</label>
<select id="new-language">
<option value="英语">英语</option>
<option value="日语">日语</option>
<option value="法语">法语</option>
<option value="德语">德语</option>
<option value="西班牙语">西班牙语</option>
<option value="其他">其他</option>
</select>
</div>
<button id="add-word-btn">添加单词</button>
</div>
</div>
<div id="review-tab" class="tab-content">
<h2>复习模式</h2>
<div class="auth-section">
<div id="review-card" class="word-card" style="text-align: center; padding: 40px;">
<p>请先添加单词,然后开始复习</p>
</div>
<div style="text-align: center; margin-top: 20px;">
<button id="start-review" class="btn-secondary">开始复习</button>
<button id="next-card" class="hidden">下一个</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 编辑单词模态框 -->
<div id="edit-modal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>编辑单词</h3>
<button class="close-btn">×</button>
</div>
<div class="form-group">
<label for="edit-word">单词</label>
<input type="text" id="edit-word">
</div>
<div class="form-group">
<label for="edit-meaning">释义</label>
<input type="text" id="edit-meaning">
</div>
<div class="form-group">
<label for="edit-example">例句</label>
<input type="text" id="edit-example">
</div>
<div class="form-group">
<label for="edit-language">语种</label>
<select id="edit-language">
<option value="英语">英语</option>
<option value="日语">日语</option>
<option value="法语">法语</option>
<option value="德语">德语</option>
<option value="西班牙语">西班牙语</option>
<option value="其他">其他</option>
</select>
</div>
<button id="save-edit-btn">保存修改</button>
</div>
</div>
<script>
// 数据管理
class DataManager {
constructor() {
this.users = JSON.parse(localStorage.getItem('wordCardUsers')) || {};
this.currentUser = null;
this.words = JSON.parse(localStorage.getItem('wordCardWords')) || {};
}
// 用户注册
register(username, password) {
if (this.users[username]) {
return { success: false, message: '用户名已存在' };
}
this.users[username] = { password, createdAt: new Date().toISOString() };
this.words[username] = [];
this.saveData();
return { success: true, message: '注册成功' };
}
// 用户登录
login(username, password) {
if (!this.users[username]) {
return { success: false, message: '用户不存在' };
}
if (this.users[username].password !== password) {
return { success: false, message: '密码错误' };
}
this.currentUser = username;
return { success: true, message: '登录成功' };
}
// 用户退出
logout() {
this.currentUser = null;
}
// 添加单词
addWord(word, meaning, example, language) {
if (!this.currentUser) return false;
const newWord = {
id: Date.now(),
word,
meaning,
example,
language,
createdAt: new Date().toISOString(),
lastReviewed: null
};
this.words[this.currentUser].push(newWord);
this.saveData();
return true;
}
// 获取用户单词
getUserWords() {
if (!this.currentUser) return [];
return this.words[this.currentUser] || [];
}
// 更新单词
updateWord(id, word, meaning, example, language) {
if (!this.currentUser) return false;
const userWords = this.words[this.currentUser];
const wordIndex = userWords.findIndex(w => w.id === id);
if (wordIndex === -1) return false;
userWords[wordIndex] = {
...userWords[wordIndex],
word,
meaning,
example,
language
};
this.saveData();
return true;
}
// 删除单词
deleteWord(id) {
if (!this.currentUser) return false;
this.words[this.currentUser] = this.words[this.currentUser].filter(w => w.id !== id);
this.saveData();
return true;
}
// 保存数据到localStorage
saveData() {
localStorage.setItem('wordCardUsers', JSON.stringify(this.users));
localStorage.setItem('wordCardWords', JSON.stringify(this.words));
}
// 获取统计数据
getStats() {
if (!this.currentUser) return { totalWords: 0, languageCount: 0, todayAdded: 0 };
const userWords = this.words[this.currentUser] || [];
const totalWords = userWords.length;
const languages = new Set(userWords.map(word => word.language));
const languageCount = languages.size;
const today = new Date().toDateString();
const todayAdded = userWords.filter(word =>
new Date(word.createdAt).toDateString() === today
).length;
return { totalWords, languageCount, todayAdded };
}
// 导出单词数据
exportWords() {
if (!this.currentUser) return null;
const userWords = this.words[this.currentUser] || [];
const exportData = {
version: "1.0",
exportDate: new Date().toISOString(),
words: userWords
};
return JSON.stringify(exportData, null, 2);
}
// 导入单词数据
importWords(jsonData) {
if (!this.currentUser) return { success: false, message: '请先登录' };
try {
const importData = JSON.parse(jsonData);
// 验证数据结构
if (!importData.words || !Array.isArray(importData.words)) {
return { success: false, message: '文件格式不正确' };
}
const newWords = importData.words;
let importedCount = 0;
let skippedCount = 0;
// 导入单词,检查重复
newWords.forEach(word => {
// 检查是否已存在相同单词和语种的记录
const isDuplicate = this.words[this.currentUser].some(w =>
w.word === word.word && w.language === word.language
);
if (!isDuplicate) {
// 为新单词生成新的ID和时间戳
const newWord = {
...word,
id: Date.now() + Math.random(), // 确保ID唯一
createdAt: new Date().toISOString()
};
this.words[this.currentUser].push(newWord);
importedCount++;
} else {
skippedCount++;
}
});
this.saveData();
return {
success: true,
message: `导入成功!新增 ${importedCount} 个单词,跳过 ${skippedCount} 个重复单词`
};
} catch (error) {
return { success: false, message: '文件解析失败,请检查文件格式' };
}
}
}
// UI管理器
class UIManager {
constructor(dataManager) {
this.dataManager = dataManager;
this.currentEditingId = null;
this.reviewWords = [];
this.currentReviewIndex = 0;
this.isShowingAnswer = false;
this.initializeEventListeners();
this.checkLoginStatus();
}
// 初始化事件监听器
initializeEventListeners() {
// 登录/注册相关
document.getElementById('login-btn').addEventListener('click', () => this.handleLogin());
document.getElementById('show-register-btn').addEventListener('click', () => this.showRegisterForm());
document.getElementById('logout-btn').addEventListener('click', () => this.handleLogout());
// 单词管理相关
document.getElementById('add-word-btn').addEventListener('click', () => this.handleAddWord());
document.getElementById('language-filter').addEventListener('change', () => this.renderWordList());
// 标签切换
document.querySelectorAll('.tab').forEach(tab => {
tab.addEventListener('click', (e) => this.switchTab(e.target.dataset.tab));
});
// 模态框相关
document.querySelector('.close-btn').addEventListener('click', () => this.hideEditModal());
document.getElementById('save-edit-btn').addEventListener('click', () => this.handleSaveEdit());
// 复习模式相关
document.getElementById('start-review').addEventListener('click', () => this.startReview());
document.getElementById('next-card').addEventListener('click', () => this.nextReviewCard());
// 导入导出相关
document.getElementById('export-btn').addEventListener('click', () => this.handleExport());
document.getElementById('import-btn').addEventListener('click', () => this.handleImport());
document.getElementById('file-input').addEventListener('change', (e) => this.handleFileSelect(e));
// 注册表单提交
document.addEventListener('click', (e) => {
if (e.target.id === 'register-btn') {
this.handleRegister();
}
});
// 按Enter键提交表单
document.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
if (document.getElementById('auth-section').classList.contains('register-mode')) {
this.handleRegister();
} else {
this.handleLogin();
}
}
});
}
// 检查登录状态
checkLoginStatus() {
if (this.dataManager.currentUser) {
this.showUserInterface();
} else {
this.showAuthInterface();
}
}
// 显示认证界面
showAuthInterface() {
document.getElementById('auth-section').classList.remove('hidden');
document.getElementById('user-section').classList.add('hidden');
document.getElementById('words-tab').classList.add('hidden');
document.getElementById('add-word-tab').classList.add('hidden');
document.getElementById('review-tab').classList.add('hidden');
document.querySelector('.language-filter').classList.add('hidden');
document.querySelector('.stats').classList.add('hidden');
document.querySelector('.import-export-section').classList.add('hidden');
}
// 显示用户界面
showUserInterface() {
document.getElementById('auth-section').classList.add('hidden');
document.getElementById('user-section').classList.remove('hidden');
document.getElementById('words-tab').classList.remove('hidden');
document.querySelector('.language-filter').classList.remove('hidden');
document.querySelector('.stats').classList.remove('hidden');
document.querySelector('.import-export-section').classList.remove('hidden');
document.getElementById('current-user').textContent = this.dataManager.currentUser;
this.updateStats();
this.renderWordList();
}
// 处理登录
handleLogin() {
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
if (!username || !password) {
alert('请输入用户名和密码');
return;
}
const result = this.dataManager.login(username, password);
if (result.success) {
this.showUserInterface();
this.clearAuthForm();
} else {
alert(result.message);
}
}
// 处理注册
handleRegister() {
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
if (!username || !password) {
alert('请输入用户名和密码');
return;
}
const result = this.dataManager.register(username, password);
if (result.success) {
alert('注册成功,请登录');
this.showLoginForm();
this.clearAuthForm();
} else {
alert(result.message);
}
}
// 显示注册表单
showRegisterForm() {
document.getElementById('auth-section').classList.add('register-mode');
document.querySelector('#auth-section h2').textContent = '用户注册';
document.getElementById('login-btn').classList.add('hidden');
document.getElementById('show-register-btn').classList.add('hidden');
const registerBtn = document.createElement('button');
registerBtn.id = 'register-btn';
registerBtn.textContent = '注册';
document.getElementById('auth-section').appendChild(registerBtn);
}
// 显示登录表单
showLoginForm() {
document.getElementById('auth-section').classList.remove('register-mode');
document.querySelector('#auth-section h2').textContent = '用户登录';
document.getElementById('login-btn').classList.remove('hidden');
document.getElementById('show-register-btn').classList.remove('hidden');
const registerBtn = document.getElementById('register-btn');
if (registerBtn) {
registerBtn.remove();
}
}
// 处理退出
handleLogout() {
this.dataManager.logout();
this.showAuthInterface();
}
// 清空认证表单
clearAuthForm() {
document.getElementById('username').value = '';
document.getElementById('password').value = '';
}
// 处理添加单词
handleAddWord() {
const word = document.getElementById('new-word').value;
const meaning = document.getElementById('new-meaning').value;
const example = document.getElementById('new-example').value;
const language = document.getElementById('new-language').value;
if (!word || !meaning) {
alert('请填写单词和释义');
return;
}
const success = this.dataManager.addWord(word, meaning, example, language);
if (success) {
alert('单词添加成功');
document.getElementById('new-word').value = '';
document.getElementById('new-meaning').value = '';
document.getElementById('new-example').value = '';
this.renderWordList();
this.updateStats();
this.switchTab('words');
} else {
alert('添加失败,请重试');
}
}
// 渲染单词列表
renderWordList() {
const wordList = document.getElementById('word-list');
const languageFilter = document.getElementById('language-filter').value;
let words = this.dataManager.getUserWords();
if (languageFilter !== 'all') {
words = words.filter(word => word.language === languageFilter);
}
if (words.length === 0) {
wordList.innerHTML = '<p style="text-align: center; padding: 20px;">暂无单词,请添加单词</p>';
return;
}
wordList.innerHTML = words.map(word => `
<div class="word-card">
<div class="word-header">
<div class="word">${word.word}</div>
<div class="language-tag">${word.language}</div>
</div>
<div class="meaning">${word.meaning}</div>
${word.example ? `<div class="example">${word.example}</div>` : ''}
<div class="word-actions">
<button class="btn-small edit-btn" data-id="${word.id}">编辑</button>
<button class="btn-small btn-secondary delete-btn" data-id="${word.id}">删除</button>
</div>
</div>
`).join('');
// 添加编辑和删除按钮的事件监听
document.querySelectorAll('.edit-btn').forEach(btn => {
btn.addEventListener('click', (e) => this.showEditModal(parseInt(e.target.dataset.id)));
});
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.addEventListener('click', (e) => this.handleDeleteWord(parseInt(e.target.dataset.id)));
});
}
// 显示编辑模态框
showEditModal(id) {
const word = this.dataManager.getUserWords().find(w => w.id === id);
if (!word) return;
this.currentEditingId = id;
document.getElementById('edit-word').value = word.word;
document.getElementById('edit-meaning').value = word.meaning;
document.getElementById('edit-example').value = word.example || '';
document.getElementById('edit-language').value = word.language;
document.getElementById('edit-modal').style.display = 'flex';
}
// 隐藏编辑模态框
hideEditModal() {
document.getElementById('edit-modal').style.display = 'none';
this.currentEditingId = null;
}
// 处理保存编辑
handleSaveEdit() {
if (this.currentEditingId === null) return;
const word = document.getElementById('edit-word').value;
const meaning = document.getElementById('edit-meaning').value;
const example = document.getElementById('edit-example').value;
const language = document.getElementById('edit-language').value;
if (!word || !meaning) {
alert('请填写单词和释义');
return;
}
const success = this.dataManager.updateWord(this.currentEditingId, word, meaning, example, language);
if (success) {
alert('修改成功');
this.hideEditModal();
this.renderWordList();
this.updateStats();
} else {
alert('修改失败,请重试');
}
}
// 处理删除单词
handleDeleteWord(id) {
if (confirm('确定要删除这个单词吗?')) {
const success = this.dataManager.deleteWord(id);
if (success) {
this.renderWordList();
this.updateStats();
} else {
alert('删除失败,请重试');
}
}
}
// 切换标签
switchTab(tabName) {
// 更新标签状态
document.querySelectorAll('.tab').forEach(tab => {
tab.classList.remove('active');
});
document.querySelector(`.tab[data-tab="${tabName}"]`).classList.add('active');
// 更新内容区域
document.querySelectorAll('.tab-content').forEach(content => {
content.classList.remove('active');
});
document.getElementById(`${tabName}-tab`).classList.add('active');
}
// 更新统计数据
updateStats() {
const stats = this.dataManager.getStats();
document.getElementById('total-words').textContent = stats.totalWords;
document.getElementById('language-count').textContent = stats.languageCount;
document.getElementById('today-added').textContent = stats.todayAdded;
document.getElementById('user-stats').textContent = `单词数: ${stats.totalWords}`;
}
// 开始复习
startReview() {
this.reviewWords = [...this.dataManager.getUserWords()];
if (this.reviewWords.length === 0) {
alert('没有单词可以复习,请先添加单词');
return;
}
// 随机排序单词
this.reviewWords.sort(() => Math.random() - 0.5);
this.currentReviewIndex = 0;
this.isShowingAnswer = false;
this.showReviewCard();
document.getElementById('start-review').classList.add('hidden');
document.getElementById('next-card').classList.remove('hidden');
}
// 显示复习卡片
showReviewCard() {
if (this.currentReviewIndex >= this.reviewWords.length) {
document.getElementById('review-card').innerHTML = `
<h3>复习完成!</h3>
<p>你已经复习了所有单词</p>
`;
document.getElementById('next-card').classList.add('hidden');
document.getElementById('start-review').classList.remove('hidden');
return;
}
const word = this.reviewWords[this.currentReviewIndex];
if (!this.isShowingAnswer) {
document.getElementById('review-card').innerHTML = `
<div class="word">${word.word}</div>
<div class="language-tag" style="margin: 10px auto;">${word.language}</div>
<p>点击卡片显示答案</p>
`;
document.getElementById('review-card').style.cursor = 'pointer';
document.getElementById('review-card').onclick = () => this.showAnswer();
} else {
document.getElementById('review-card').innerHTML = `
<div class="word">${word.word}</div>
<div class="language-tag" style="margin: 10px auto;">${word.language}</div>
<div class="meaning">${word.meaning}</div>
${word.example ? `<div class="example">${word.example}</div>` : ''}
`;
document.getElementById('review-card').style.cursor = 'default';
document.getElementById('review-card').onclick = null;
}
}
// 显示答案
showAnswer() {
this.isShowingAnswer = true;
this.showReviewCard();
}
// 下一个复习卡片
nextReviewCard() {
this.currentReviewIndex++;
this.isShowingAnswer = false;
this.showReviewCard();
}
// 处理导出
handleExport() {
if (!this.dataManager.currentUser) {
alert('请先登录');
return;
}
const words = this.dataManager.getUserWords();
if (words.length === 0) {
alert('没有单词可以导出');
return;
}
const exportData = this.dataManager.exportWords();
if (!exportData) {
alert('导出失败');
return;
}
// 创建下载链接
const blob = new Blob([exportData], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `单词数据_${this.dataManager.currentUser}_${new Date().toISOString().split('T')[0]}.json`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
alert('导出成功!');
}
// 处理导入
handleImport() {
if (!this.dataManager.currentUser) {
alert('请先登录');
return;
}
document.getElementById('file-input').click();
}
// 处理文件选择
handleFileSelect(event) {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (e) => {
const result = this.dataManager.importWords(e.target.result);
if (result.success) {
alert(result.message);
this.renderWordList();
this.updateStats();
} else {
alert(result.message);
}
// 清空文件输入
event.target.value = '';
};
reader.readAsText(file);
}
}
// 初始化应用
document.addEventListener('DOMContentLoaded', () => {
const dataManager = new DataManager();
const uiManager = new UIManager(dataManager);
});
</script>
</body>
</html>