Initial commit: gamer project

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
lizhilun
2026-03-12 11:23:10 +08:00
co-authored by Claude Opus 4.6
commit a0d7bfdc3d
26 changed files with 5410 additions and 0 deletions
+108
View File
@@ -0,0 +1,108 @@
// 导出功能
function showExportDialog() {
document.getElementById('exportModal').classList.add('show');
}
function closeExportModal() {
document.getElementById('exportModal').classList.remove('show');
}
async function doExport(format) {
closeExportModal();
showToast('正在导出...');
try {
const res = await fetch(API + '/api/export?format=' + format, { headers: headers() });
if (!res.ok) {
const err = await res.json();
showToast(err.error || '导出失败');
return;
}
const disposition = res.headers.get('Content-Disposition');
let filename = 'gamer-export.' + format;
if (disposition) {
const match = disposition.match(/filename="?([^"]+)"?/);
if (match) filename = match[1];
}
const blob = await res.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
showToast('导出成功');
} catch (e) {
showToast('导出失败: 网络错误');
}
}
// 导入功能
let pendingImportContent = null;
function triggerImport() {
document.getElementById('importFileInput').value = '';
document.getElementById('importFileInput').click();
}
function handleImportFile(event) {
const file = event.target.files[0];
if (!file) return;
const ext = file.name.split('.').pop().toLowerCase();
if (ext !== 'json' && ext !== 'csv') {
showToast('请选择 JSON 或 CSV 文件');
return;
}
const reader = new FileReader();
reader.onload = function(e) {
const content = e.target.result;
pendingImportContent = content;
let count = 0;
try {
const trimmed = content.replace(/^\uFEFF/, '').trim();
if (trimmed.startsWith('{')) {
const data = JSON.parse(trimmed);
count = data.recordCount || (data.records ? data.records.length : 0);
} else {
count = Math.max(0, trimmed.split('\n').filter(l => l.trim()).length - 1);
}
} catch (err) {
showToast('文件格式无法识别');
return;
}
document.getElementById('importConfirmMsg').textContent =
'文件: ' + file.name + '\n检测到 ' + count + ' 条记录,确认导入?\n(重复记录将自动跳过)';
document.getElementById('importConfirmModal').classList.add('show');
};
reader.readAsText(file, 'UTF-8');
}
function closeImportConfirm() {
document.getElementById('importConfirmModal').classList.remove('show');
pendingImportContent = null;
}
async function confirmImport() {
document.getElementById('importConfirmModal').classList.remove('show');
if (!pendingImportContent) return;
showToast('正在导入...');
try {
const res = await fetch(API + '/api/import', {
method: 'POST',
headers: { 'Content-Type': 'text/plain; charset=utf-8', 'Authorization': 'Bearer ' + token },
body: pendingImportContent
});
const data = await res.json();
if (!res.ok) {
showToast(data.error || '导入失败');
return;
}
showToast('导入完成: ' + data.imported + '条新增, ' + data.skipped + '条跳过');
pendingImportContent = null;
loadStats();
loadTotalStats();
} catch (e) {
showToast('导入失败: 网络错误');
}
}