File size: 3,628 Bytes
3718e52 090a8b1 3718e52 090a8b1 3718e52 090a8b1 3718e52 090a8b1 93a78d8 090a8b1 3718e52 090a8b1 3718e52 090a8b1 3718e52 93a78d8 090a8b1 93a78d8 3718e52 090a8b1 93a78d8 090a8b1 93a78d8 090a8b1 93a78d8 090a8b1 3718e52 090a8b1 3718e52 090a8b1 3718e52 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 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');
}
}); |