90 lines
3.8 KiB
JavaScript
90 lines
3.8 KiB
JavaScript
const form = document.getElementById('predictForm');
|
|
const fileInput = document.getElementById('fileInput');
|
|
const dropZone = document.getElementById('dropZone');
|
|
const selectedFileName = document.getElementById('selectedFileName');
|
|
const submitBtn = document.getElementById('submitBtn');
|
|
const submitText = document.getElementById('submitText');
|
|
let submitIcon = document.getElementById('submitIcon');
|
|
const alertBox = document.getElementById('alertBox');
|
|
const mainGrid = document.getElementById('mainGrid');
|
|
const inlineResult = document.getElementById('inlineResult');
|
|
const resultImage = document.getElementById('resultImage');
|
|
const resultImportanceWrap = document.getElementById('resultImportanceWrap');
|
|
const resultImportanceImage = document.getElementById('resultImportanceImage');
|
|
const excelBtn = document.getElementById('excelBtn');
|
|
const resultPageBtn = document.getElementById('resultPageBtn');
|
|
const summaryFilename = document.getElementById('summaryFilename');
|
|
const summaryCount = document.getElementById('summaryCount');
|
|
|
|
function showAlert(message, type='error') {
|
|
alertBox.classList.remove('hidden', 'bg-dangerSoft', 'text-dangerText', 'border-red-200', 'bg-blueSoft', 'text-primary', 'border-blue-200');
|
|
if (type === 'error') {
|
|
alertBox.classList.add('bg-dangerSoft', 'text-dangerText', 'border-red-200');
|
|
} else {
|
|
alertBox.classList.add('bg-blueSoft', 'text-primary', 'border-blue-200');
|
|
}
|
|
alertBox.textContent = message;
|
|
}
|
|
|
|
fileInput.addEventListener('change', () => {
|
|
const file = fileInput.files[0];
|
|
if (!file) return;
|
|
selectedFileName.textContent = '已选择文件:' + file.name;
|
|
selectedFileName.classList.remove('hidden');
|
|
});
|
|
['dragenter', 'dragover'].forEach(evt => dropZone.addEventListener(evt, e => {
|
|
e.preventDefault();
|
|
dropZone.classList.add('border-primary', 'bg-blue-50');
|
|
}));
|
|
['dragleave', 'drop'].forEach(evt => dropZone.addEventListener(evt, e => {
|
|
e.preventDefault();
|
|
dropZone.classList.remove('border-primary', 'bg-blue-50');
|
|
}));
|
|
|
|
form.addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
alertBox.classList.add('hidden');
|
|
if (!fileInput.files.length) {
|
|
showAlert('请先选择要上传的文件。');
|
|
return;
|
|
}
|
|
|
|
submitBtn.disabled = true;
|
|
submitText.textContent = '预测中...';
|
|
submitIcon.replaceWith(Object.assign(document.createElement('span'), { id: 'submitSpinner', className: 'spinner' }));
|
|
|
|
try {
|
|
const formData = new FormData(form);
|
|
const resp = await fetch(form.action, { method: 'POST', body: formData });
|
|
const data = await resp.json();
|
|
if (!resp.ok) {
|
|
showAlert(data.error || '预测失败,请稍后重试。');
|
|
return;
|
|
}
|
|
resultImage.src = data.image_url;
|
|
if (data.importance_url) {
|
|
resultImportanceImage.src = data.importance_url;
|
|
resultImportanceWrap.classList.remove('hidden');
|
|
} else {
|
|
resultImportanceWrap.classList.add('hidden');
|
|
}
|
|
excelBtn.href = data.excel_url;
|
|
resultPageBtn.href = data.result_url;
|
|
summaryFilename.textContent = data.original_filename;
|
|
summaryCount.textContent = data.sample_count;
|
|
inlineResult.classList.remove('hidden');
|
|
mainGrid.classList.remove('xl:grid-cols-[1.45fr_1fr]');
|
|
mainGrid.classList.add('xl:grid-cols-[1.25fr_0.95fr_1.05fr]');
|
|
showAlert('预测完成,已生成图表与 Excel 报告。', 'success');
|
|
inlineResult.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
} catch (err) {
|
|
showAlert('请求失败,请检查后端服务是否正常。');
|
|
} finally {
|
|
submitBtn.disabled = false;
|
|
submitText.textContent = '分析并预测';
|
|
const restoredIcon = Object.assign(document.createElement('span'), { id: 'submitIcon', className: 'material-symbols-outlined', textContent: 'analytics' });
|
|
document.getElementById('submitSpinner')?.replaceWith(restoredIcon);
|
|
submitIcon = restoredIcon;
|
|
}
|
|
});
|