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');
    }
});