160 lines
4.8 KiB
JavaScript
160 lines
4.8 KiB
JavaScript
// Initialize after page loading is complete
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
initializeCategoryDownload();
|
|
});
|
|
|
|
/**
|
|
* Trigger file download from database
|
|
* @param {string} filename - Name of the file to be downloaded (e.g., 'all_data.csv', 'ph.csv')
|
|
*/
|
|
async function downloadFile(filename) {
|
|
try {
|
|
// Extract type from filename (remove .csv extension)
|
|
const type = filename.replace('.csv', '');
|
|
|
|
// Map filename to API type
|
|
const typeMap = {
|
|
'all_data': 'all_data',
|
|
'ph': 'ph',
|
|
'temperature': 'temperature',
|
|
'oxygen': 'oxygen',
|
|
'culture_medium': 'culture_medium',
|
|
'max_growth_rate': 'max_growth_rate'
|
|
};
|
|
|
|
const apiType = typeMap[type];
|
|
if (!apiType) {
|
|
alert(`Unsupported download type: ${type}`);
|
|
return;
|
|
}
|
|
|
|
// Show loading toast
|
|
showDownloadToast(filename, true);
|
|
|
|
// Fetch data from API
|
|
const response = await fetch(`/api/download-data/${apiType}?cultured_type=cultured`);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
// Get CSV content
|
|
const csvContent = await response.text();
|
|
|
|
// Create blob and download
|
|
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
|
|
const link = document.createElement('a');
|
|
link.href = URL.createObjectURL(blob);
|
|
link.download = filename;
|
|
link.style.visibility = 'hidden';
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
|
|
// Clean up blob URL
|
|
URL.revokeObjectURL(link.href);
|
|
|
|
// Show success toast
|
|
showDownloadToast(filename, false);
|
|
|
|
} catch (error) {
|
|
console.error('Download failed:', error);
|
|
alert(`下载失败: ${error.message}`);
|
|
showDownloadToast(filename, false, true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initialize category-based download functionality
|
|
*/
|
|
function initializeCategoryDownload() {
|
|
const categorySelect = document.getElementById('category-select');
|
|
const downloadBtn = document.getElementById('category-download-btn');
|
|
|
|
// Listen for selection changes
|
|
categorySelect.addEventListener('change', function() {
|
|
downloadBtn.disabled = !this.value;
|
|
if (this.value) {
|
|
downloadBtn.classList.add('active');
|
|
} else {
|
|
downloadBtn.classList.remove('active');
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Download file based on selected category and taxonomy
|
|
*/
|
|
function downloadByCategory() {
|
|
const categorySelect = document.getElementById('category-select');
|
|
const taxonomySelect = document.getElementById('taxonomy-select');
|
|
|
|
const category = categorySelect.value;
|
|
const taxonomy = taxonomySelect.value;
|
|
|
|
if (!category) {
|
|
alert('Please select a data category first.');
|
|
return;
|
|
}
|
|
|
|
// Construct filename
|
|
let filename = category;
|
|
if (taxonomy) {
|
|
filename += `_${taxonomy}`;
|
|
}
|
|
filename += '.csv';
|
|
|
|
// Download file
|
|
downloadFile(filename);
|
|
}
|
|
|
|
/**
|
|
* Show download status toast notification
|
|
* @param {string} filename - Name of the file being downloaded
|
|
* @param {boolean} loading - Whether to show loading state
|
|
* @param {boolean} error - Whether to show error state
|
|
*/
|
|
function showDownloadToast(filename, loading = false, error = false) {
|
|
// Remove existing toast if any
|
|
const existingToast = document.querySelector('.download-toast');
|
|
if (existingToast) {
|
|
existingToast.remove();
|
|
}
|
|
|
|
// Create download prompt element
|
|
const toast = document.createElement('div');
|
|
toast.className = 'download-toast';
|
|
|
|
let iconClass = 'icon-success';
|
|
let message = `正在下载 ${filename}...`;
|
|
|
|
if (error) {
|
|
iconClass = 'icon-error';
|
|
message = `下载 ${filename} 失败`;
|
|
} else if (!loading) {
|
|
iconClass = 'icon-success';
|
|
message = `已成功下载 ${filename}`;
|
|
}
|
|
|
|
toast.innerHTML = `
|
|
<i class="iconfont ${iconClass}"></i>
|
|
<span>${message}</span>
|
|
`;
|
|
|
|
document.body.appendChild(toast);
|
|
|
|
// Show animation
|
|
setTimeout(() => {
|
|
toast.classList.add('show');
|
|
}, 100);
|
|
|
|
// Remove after 3 seconds
|
|
setTimeout(() => {
|
|
toast.classList.remove('show');
|
|
setTimeout(() => {
|
|
if (toast.parentNode) {
|
|
document.body.removeChild(toast);
|
|
}
|
|
}, 300);
|
|
}, 3000);
|
|
} |