2026-02-16 01:18:51 +08:00
|
|
|
|
// static/history.js
|
|
|
|
|
|
|
|
|
|
|
|
// 页面加载完成后加载历史记录
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
|
|
loadHistory();
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
async function loadHistory() {
|
|
|
|
|
|
const fileList = document.getElementById('fileList');
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
2026-02-16 01:32:13 +08:00
|
|
|
|
const response = await fetch('/api/history', {
|
|
|
|
|
|
method: 'POST'
|
|
|
|
|
|
});
|
2026-02-16 01:18:51 +08:00
|
|
|
|
if (!response.ok) {
|
|
|
|
|
|
throw new Error('获取历史记录失败');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
|
|
|
|
|
|
|
if (data.files && data.files.length > 0) {
|
|
|
|
|
|
displayFileList(data.files);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
fileList.innerHTML = `
|
|
|
|
|
|
<div class="no-records">
|
|
|
|
|
|
<div style="font-size: 48px; margin-bottom: 20px;">📁</div>
|
|
|
|
|
|
<h3>暂无历史记录</h3>
|
|
|
|
|
|
<p>还没有上传过STP文件</p>
|
|
|
|
|
|
<button class="upload-btn" onclick="location.href='/upload'">
|
|
|
|
|
|
上传第一个文件
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
fileList.innerHTML = `
|
|
|
|
|
|
<div class="no-records">
|
|
|
|
|
|
<div style="font-size: 48px; margin-bottom: 20px;">❌</div>
|
|
|
|
|
|
<h3>加载失败</h3>
|
|
|
|
|
|
<p>${error.message}</p>
|
|
|
|
|
|
<button class="upload-btn" onclick="loadHistory()">
|
|
|
|
|
|
重试
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
`;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function displayFileList(files) {
|
|
|
|
|
|
const fileList = document.getElementById('fileList');
|
|
|
|
|
|
|
|
|
|
|
|
fileList.innerHTML = files.map(file => `
|
|
|
|
|
|
<div class="file-item" id="file-${file.filename}">
|
|
|
|
|
|
<div class="file-header" onclick="toggleFileRecords('${file.filename}')">
|
|
|
|
|
|
<div class="file-info">
|
|
|
|
|
|
<div class="file-name">📄 ${file.filename}</div>
|
|
|
|
|
|
<div class="file-meta">
|
|
|
|
|
|
总记录: ${file.record_count} 条 |
|
|
|
|
|
|
最后上传: ${new Date(file.last_upload).toLocaleString()}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button class="expand-btn" onclick="event.stopPropagation(); toggleFileRecords('${file.filename}')">
|
|
|
|
|
|
➕
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="record-list" id="records-${file.filename}">
|
|
|
|
|
|
<div class="loading">
|
|
|
|
|
|
<div class="spinner"></div>
|
|
|
|
|
|
<p>正在加载记录详情...</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
`).join('');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function toggleFileRecords(filename) {
|
|
|
|
|
|
const fileItem = document.getElementById(`file-${filename}`);
|
|
|
|
|
|
const recordList = document.getElementById(`records-${filename}`);
|
|
|
|
|
|
const expandBtn = fileItem.querySelector('.expand-btn');
|
|
|
|
|
|
|
|
|
|
|
|
// 切换展开状态
|
|
|
|
|
|
if (fileItem.classList.contains('expanded')) {
|
|
|
|
|
|
fileItem.classList.remove('expanded');
|
|
|
|
|
|
expandBtn.textContent = '➕';
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 先设置展开状态
|
|
|
|
|
|
fileItem.classList.add('expanded');
|
|
|
|
|
|
expandBtn.textContent = '➖';
|
|
|
|
|
|
|
|
|
|
|
|
// 如果已经加载过数据,直接显示
|
|
|
|
|
|
if (recordList.dataset.loaded === 'true') {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
2026-02-16 01:32:13 +08:00
|
|
|
|
const response = await fetch(`/api/history/${encodeURIComponent(filename)}`, {
|
|
|
|
|
|
method: 'POST'
|
|
|
|
|
|
});
|
2026-02-16 01:18:51 +08:00
|
|
|
|
if (!response.ok) {
|
|
|
|
|
|
throw new Error('获取记录详情失败');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const records = await response.json();
|
|
|
|
|
|
|
|
|
|
|
|
if (records.length > 0) {
|
|
|
|
|
|
recordList.innerHTML = records.map(record => `
|
|
|
|
|
|
<div class="record-item" onclick="viewRecordDetails('${record.task_id}')">
|
|
|
|
|
|
<div class="record-header">
|
|
|
|
|
|
<div class="record-time">
|
|
|
|
|
|
📅 ${new Date(record.upload_time).toLocaleString()}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="record-status status-${record.status}">
|
|
|
|
|
|
${getStatusText(record.status)}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="record-details">
|
|
|
|
|
|
<div>文件大小: ${formatFileSize(record.file_size)}</div>
|
|
|
|
|
|
<div>任务ID: ${record.task_id}</div>
|
|
|
|
|
|
<div>状态: ${record.status}</div>
|
|
|
|
|
|
${record.completed_at ? `<div>完成时间: ${new Date(record.completed_at).toLocaleTimeString()}</div>` : ''}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
`).join('');
|
|
|
|
|
|
} else {
|
|
|
|
|
|
recordList.innerHTML = `
|
|
|
|
|
|
<div class="no-records">
|
|
|
|
|
|
<p>暂无详细记录</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
recordList.dataset.loaded = 'true';
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
recordList.innerHTML = `
|
|
|
|
|
|
<div class="no-records">
|
|
|
|
|
|
<p>❌ 加载失败: ${error.message}</p>
|
|
|
|
|
|
<button class="upload-btn" onclick="toggleFileRecords('${filename}')">
|
|
|
|
|
|
重试
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
`;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function viewRecordDetails(taskId) {
|
|
|
|
|
|
// 跳转到详细结果页面
|
|
|
|
|
|
window.location.href = `/result/${taskId}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function getStatusText(status) {
|
|
|
|
|
|
const statusMap = {
|
|
|
|
|
|
'completed': '已完成',
|
|
|
|
|
|
'processing': '处理中',
|
|
|
|
|
|
'failed': '失败'
|
|
|
|
|
|
};
|
|
|
|
|
|
return statusMap[status] || status;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function formatFileSize(bytes) {
|
|
|
|
|
|
if (!bytes || bytes === 0) return '0 Bytes';
|
|
|
|
|
|
const k = 1024;
|
|
|
|
|
|
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
|
|
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
|
|
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
2026-02-16 01:35:58 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 跳转到上传页面
|
|
|
|
|
|
async function goToUpload() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 上传页面需要GET请求,直接跳转
|
|
|
|
|
|
window.location.href = '/';
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('跳转失败:', error);
|
|
|
|
|
|
window.location.href = '/';
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 跳转到主页
|
|
|
|
|
|
async function goToHome() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 主页需要GET请求,直接跳转
|
|
|
|
|
|
window.location.href = '/';
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('跳转失败:', error);
|
|
|
|
|
|
window.location.href = '/';
|
|
|
|
|
|
}
|
2026-02-16 01:18:51 +08:00
|
|
|
|
}
|