feat: complete web app features and fix encoding
This commit is contained in:
@@ -26,6 +26,73 @@ const currentItem = document.getElementById('currentItem');
|
||||
const resultSection = document.getElementById('resultSection');
|
||||
const sortedList = document.getElementById('sortedList');
|
||||
const resetBtn = document.getElementById('resetBtn');
|
||||
const exportTxtBtn = document.getElementById('exportTxtBtn');
|
||||
const exportJsonBtn = document.getElementById('exportJsonBtn');
|
||||
const exportCsvBtn = document.getElementById('exportCsvBtn');
|
||||
|
||||
// 本地存储键名
|
||||
const STORAGE_KEY_EXTRACTED = 'recitation_extracted_items';
|
||||
const STORAGE_KEY_SORTED = 'recitation_sorted_items';
|
||||
const STORAGE_KEY_ORIGINAL_TEXT = 'recitation_original_text';
|
||||
|
||||
// 页面加载时恢复数据
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
restoreFromStorage();
|
||||
});
|
||||
|
||||
// 保存到本地存储
|
||||
function saveToStorage() {
|
||||
try {
|
||||
if (extractedItems.length > 0) {
|
||||
localStorage.setItem(STORAGE_KEY_EXTRACTED, JSON.stringify(extractedItems));
|
||||
}
|
||||
if (sortedItems.length > 0) {
|
||||
localStorage.setItem(STORAGE_KEY_SORTED, JSON.stringify(sortedItems));
|
||||
}
|
||||
if (textInput.value.trim()) {
|
||||
localStorage.setItem(STORAGE_KEY_ORIGINAL_TEXT, textInput.value);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('保存到本地存储失败:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// 从本地存储恢复
|
||||
function restoreFromStorage() {
|
||||
try {
|
||||
const savedExtracted = localStorage.getItem(STORAGE_KEY_EXTRACTED);
|
||||
const savedSorted = localStorage.getItem(STORAGE_KEY_SORTED);
|
||||
const savedText = localStorage.getItem(STORAGE_KEY_ORIGINAL_TEXT);
|
||||
|
||||
if (savedText) {
|
||||
textInput.value = savedText;
|
||||
}
|
||||
|
||||
if (savedExtracted) {
|
||||
extractedItems = JSON.parse(savedExtracted);
|
||||
displayExtractedItems(extractedItems);
|
||||
extractedSection.style.display = 'block';
|
||||
textInput.disabled = true;
|
||||
}
|
||||
|
||||
if (savedSorted) {
|
||||
sortedItems = JSON.parse(savedSorted);
|
||||
displaySortedItems(sortedItems);
|
||||
createWheel(sortedItems);
|
||||
wheelSection.style.display = 'block';
|
||||
resultSection.style.display = 'block';
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('从本地存储恢复失败:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// 清除本地存储
|
||||
function clearStorage() {
|
||||
localStorage.removeItem(STORAGE_KEY_EXTRACTED);
|
||||
localStorage.removeItem(STORAGE_KEY_SORTED);
|
||||
localStorage.removeItem(STORAGE_KEY_ORIGINAL_TEXT);
|
||||
}
|
||||
|
||||
// 提取知识点
|
||||
extractBtn.addEventListener('click', async () => {
|
||||
@@ -55,6 +122,7 @@ extractBtn.addEventListener('click', async () => {
|
||||
displayExtractedItems(extractedItems);
|
||||
extractedSection.style.display = 'block';
|
||||
textInput.disabled = true;
|
||||
saveToStorage(); // 保存到本地存储
|
||||
} else {
|
||||
alert(data.message || '提取失败');
|
||||
}
|
||||
@@ -108,6 +176,7 @@ sortBtn.addEventListener('click', async () => {
|
||||
wheelSection.style.display = 'block';
|
||||
resultSection.style.display = 'block';
|
||||
currentSpinIndex = 0;
|
||||
saveToStorage(); // 保存到本地存储
|
||||
} else {
|
||||
alert(data.message || '排序失败');
|
||||
}
|
||||
@@ -259,6 +328,50 @@ function displaySortedItems(items) {
|
||||
});
|
||||
}
|
||||
|
||||
// 导出功能
|
||||
exportTxtBtn.addEventListener('click', () => exportData('txt'));
|
||||
exportJsonBtn.addEventListener('click', () => exportData('json'));
|
||||
exportCsvBtn.addEventListener('click', () => exportData('csv'));
|
||||
|
||||
function exportData(format) {
|
||||
if (sortedItems.length === 0) {
|
||||
alert('没有可导出的数据');
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('/api/export/sorted', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json; charset=utf-8'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
items: sortedItems,
|
||||
format: format
|
||||
})
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('导出失败');
|
||||
}
|
||||
return response.blob();
|
||||
})
|
||||
.then(blob => {
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
const timestamp = new Date().toISOString().slice(0, 19).replace(/[:-]/g, '').replace('T', '_');
|
||||
a.download = `背诵排序结果_${timestamp}.${format}`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
document.body.removeChild(a);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('导出失败:', error);
|
||||
alert('导出失败,请重试');
|
||||
});
|
||||
}
|
||||
|
||||
// 重置
|
||||
resetBtn.addEventListener('click', () => {
|
||||
extractedItems = [];
|
||||
@@ -281,5 +394,7 @@ resetBtn.addEventListener('click', () => {
|
||||
|
||||
isSpinning = false;
|
||||
spinBtn.disabled = false;
|
||||
|
||||
clearStorage(); // 清除本地存储
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user