115 lines
3.4 KiB
JavaScript
115 lines
3.4 KiB
JavaScript
'use client';
|
||
|
||
import { useTranslation } from 'react-i18next';
|
||
import { toast } from 'sonner';
|
||
import axios from 'axios';
|
||
|
||
const useQuestionExport = projectId => {
|
||
const { t } = useTranslation();
|
||
|
||
// 导出问题集
|
||
const exportQuestions = async exportOptions => {
|
||
try {
|
||
const apiUrl = `/api/projects/${projectId}/questions/export`;
|
||
const requestBody = {
|
||
format: exportOptions.format || 'json'
|
||
};
|
||
|
||
// 如果有选中的问题 ID,传递 ID 列表
|
||
if (exportOptions.selectedIds && exportOptions.selectedIds.length > 0) {
|
||
requestBody.selectedIds = exportOptions.selectedIds;
|
||
}
|
||
|
||
// 如果有筛选条件,传递筛选参数
|
||
if (exportOptions.filters) {
|
||
requestBody.filters = exportOptions.filters;
|
||
}
|
||
|
||
const response = await axios.post(apiUrl, requestBody);
|
||
const questions = response.data;
|
||
|
||
// 处理和下载数据
|
||
await processAndDownloadData(questions, exportOptions);
|
||
|
||
toast.success(t('questions.exportSuccess'));
|
||
return true;
|
||
} catch (error) {
|
||
console.error('Export failed:', error);
|
||
toast.error(error.message || t('questions.exportFailed'));
|
||
return false;
|
||
}
|
||
};
|
||
|
||
// 处理和下载数据的通用函数
|
||
const processAndDownloadData = async (data, exportOptions) => {
|
||
const format = exportOptions.format || 'json';
|
||
let content;
|
||
let filename;
|
||
let mimeType;
|
||
|
||
const timestamp = new Date().toISOString().split('T')[0];
|
||
|
||
switch (format) {
|
||
case 'json':
|
||
content = JSON.stringify(data, null, 2);
|
||
filename = `questions-${projectId}-${timestamp}.json`;
|
||
mimeType = 'application/json';
|
||
break;
|
||
|
||
case 'jsonl':
|
||
content = data.map(item => JSON.stringify(item)).join('\n');
|
||
filename = `questions-${projectId}-${timestamp}.jsonl`;
|
||
mimeType = 'application/jsonl';
|
||
break;
|
||
|
||
case 'txt':
|
||
content = data.map(item => item.question).join('\n\n');
|
||
filename = `questions-${projectId}-${timestamp}.txt`;
|
||
mimeType = 'text/plain';
|
||
break;
|
||
|
||
case 'csv':
|
||
// CSV 格式
|
||
const headers = Object.keys(data[0] || {});
|
||
const csvRows = [headers.join(',')];
|
||
data.forEach(item => {
|
||
const values = headers.map(header => {
|
||
const value = item[header] || '';
|
||
// 处理包含逗号或引号的值
|
||
if (typeof value === 'string' && (value.includes(',') || value.includes('"') || value.includes('\n'))) {
|
||
return `"${value.replace(/"/g, '""')}"`;
|
||
}
|
||
return value;
|
||
});
|
||
csvRows.push(values.join(','));
|
||
});
|
||
content = csvRows.join('\n');
|
||
filename = `questions-${projectId}-${timestamp}.csv`;
|
||
mimeType = 'text/csv';
|
||
break;
|
||
|
||
default:
|
||
content = JSON.stringify(data, null, 2);
|
||
filename = `questions-${projectId}-${timestamp}.json`;
|
||
mimeType = 'application/json';
|
||
}
|
||
|
||
// 创建下载链接
|
||
const blob = new Blob([content], { type: mimeType });
|
||
const url = URL.createObjectURL(blob);
|
||
const link = document.createElement('a');
|
||
link.href = url;
|
||
link.download = filename;
|
||
document.body.appendChild(link);
|
||
link.click();
|
||
document.body.removeChild(link);
|
||
URL.revokeObjectURL(url);
|
||
};
|
||
|
||
return {
|
||
exportQuestions
|
||
};
|
||
};
|
||
|
||
export default useQuestionExport;
|