86 lines
2.5 KiB
JavaScript
86 lines
2.5 KiB
JavaScript
import { NextResponse } from 'next/server';
|
|
import { getImageDatasetsForExport } from '@/lib/db/imageDatasets';
|
|
import archiver from 'archiver';
|
|
import { getProjectPath } from '@/lib/db/base';
|
|
import path from 'path';
|
|
import fs from 'fs';
|
|
|
|
/**
|
|
* 导出图片文件压缩包
|
|
*/
|
|
export async function GET(request, { params }) {
|
|
try {
|
|
const { projectId } = params;
|
|
const { searchParams } = new URL(request.url);
|
|
const confirmedOnly = searchParams.get('confirmedOnly') === 'true';
|
|
|
|
// 验证项目ID
|
|
if (!projectId) {
|
|
return NextResponse.json({ error: 'Project ID cannot be empty' }, { status: 400 });
|
|
}
|
|
|
|
// 获取数据集(用于确定需要哪些图片)
|
|
const datasets = await getImageDatasetsForExport(projectId, confirmedOnly);
|
|
|
|
if (!datasets || datasets.length === 0) {
|
|
return NextResponse.json({ error: 'No data to export' }, { status: 404 });
|
|
}
|
|
|
|
// 获取所有需要的图片名称
|
|
const imageNames = new Set(datasets.map(d => d.imageName).filter(Boolean));
|
|
|
|
if (imageNames.size === 0) {
|
|
return NextResponse.json({ error: 'No images to export' }, { status: 404 });
|
|
}
|
|
|
|
// 创建压缩包
|
|
const archive = archiver('zip', {
|
|
zlib: { level: 9 }
|
|
});
|
|
|
|
// 设置响应头
|
|
const dateStr = new Date().toISOString().slice(0, 10);
|
|
const filename = `images-${projectId}-${dateStr}.zip`;
|
|
|
|
// 添加图片文件到压缩包
|
|
const projectPath = await getProjectPath(projectId);
|
|
const imageDir = path.join(projectPath, 'images');
|
|
|
|
if (!fs.existsSync(imageDir)) {
|
|
return NextResponse.json({ error: 'Image directory not found' }, { status: 404 });
|
|
}
|
|
|
|
let addedCount = 0;
|
|
for (const imageName of imageNames) {
|
|
const imagePath = path.join(imageDir, imageName);
|
|
if (fs.existsSync(imagePath)) {
|
|
archive.file(imagePath, { name: imageName });
|
|
addedCount++;
|
|
}
|
|
}
|
|
|
|
if (addedCount === 0) {
|
|
return NextResponse.json({ error: 'No image files found' }, { status: 404 });
|
|
}
|
|
|
|
// 完成压缩
|
|
archive.finalize();
|
|
|
|
// 返回流式响应
|
|
return new NextResponse(archive, {
|
|
headers: {
|
|
'Content-Type': 'application/zip',
|
|
'Content-Disposition': `attachment; filename="${filename}"`
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error('Failed to export images:', String(error));
|
|
return NextResponse.json(
|
|
{
|
|
error: error.message || 'Failed to export images'
|
|
},
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|