document.addEventListener('DOMContentLoaded', function () { const form = document.getElementById('prediction-form'); const predictBtn = document.getElementById('predict-btn'); const spinner = predictBtn.querySelector('.spinner-border'); const resultsArea = document.getElementById('results-area'); const errorAlert = document.getElementById('error-alert'); const consentCheckbox = document.getElementById('consent-checkbox'); const dataFileInput = document.getElementById('data-file'); const downloadTemplateLink = document.getElementById('download-template'); downloadTemplateLink.addEventListener('click', function(e) { e.preventDefault(); const csvContent = "protein_sequence,substrate_smiles\n" + "MTEITAAMVKELRESTGAGMMDCKNALSETNGDFDKAVQLLREKGLGKAAKKADRLAAEG,CC(=O)O\n" + "MKAVQLLREKGLGKAAKKADRLAAEGTKAVQLLREKGLGKAAKKADRLAAEGGKAAKKADR,C(C(=O)O)N"; const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); const link = document.createElement("a"); const url = URL.createObjectURL(blob); link.setAttribute("href", url); link.setAttribute("download", "template.csv"); link.style.visibility = 'hidden'; document.body.appendChild(link); link.click(); document.body.removeChild(link); }); form.addEventListener('submit', async function (event) { event.preventDefault(); predictBtn.disabled = true; spinner.classList.remove('d-none'); resultsArea.classList.add('d-none'); errorAlert.classList.add('d-none'); const file = dataFileInput.files[0]; if (!file) { showError("错误:请先选择一个文件。"); return; } const formData = new FormData(); formData.append('data_file', file); formData.append('consent_given', consentCheckbox.checked); try { const response = await fetch('/predict', { method: 'POST', body: formData, }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || '服务器返回了一个未知错误。'); } const blob = await response.blob(); const contentDisposition = response.headers.get('Content-Disposition'); let filename = 'predictions.csv'; if (contentDisposition) { const filenameMatch = contentDisposition.match(/filename="(.+)"/); if (filenameMatch && filenameMatch.length > 1) { filename = filenameMatch[1]; } } const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.style.display = 'none'; a.href = url; a.download = filename; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); document.body.removeChild(a); resultsArea.classList.remove('d-none'); } catch (error) { showError('错误: ' + error.message); } finally { predictBtn.disabled = false; spinner.classList.add('d-none'); } }); function showError(message) { errorAlert.textContent = message; errorAlert.classList.remove('d-none'); predictBtn.disabled = false; spinner.classList.add('d-none'); } });