zip.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // ZIP 打包处理模块
  2. // 负责接收图片和 JSON 数据,打包成 ZIP 文件并返回
  3. const archiver = require('archiver');
  4. const http = require('http');
  5. class ZipHandler {
  6. /**
  7. * 处理打包请求
  8. * @param {http.IncomingMessage} req - HTTP 请求对象
  9. * @param {http.ServerResponse} res - HTTP 响应对象
  10. */
  11. static handlePackRequest(req, res) {
  12. if (req.method !== 'POST') {
  13. res.writeHead(405, { 'Content-Type': 'application/json' });
  14. res.end(JSON.stringify({ error: 'Method not allowed' }));
  15. return;
  16. }
  17. let body = '';
  18. req.on('data', (chunk) => {
  19. body += chunk.toString();
  20. });
  21. req.on('end', () => {
  22. try {
  23. const data = JSON.parse(body);
  24. const { folderName, imageData, jsonData } = data;
  25. if (!folderName || !imageData || !jsonData) {
  26. res.writeHead(400, { 'Content-Type': 'application/json' });
  27. res.end(JSON.stringify({ error: 'Missing required fields: folderName, imageData, jsonData' }));
  28. return;
  29. }
  30. // 创建 ZIP 文件
  31. this.createZip(folderName, imageData, jsonData, res);
  32. } catch (error) {
  33. console.error('[ZipHandler] 解析请求数据失败:', error);
  34. res.writeHead(400, { 'Content-Type': 'application/json' });
  35. res.end(JSON.stringify({ error: 'Invalid JSON data', details: error.message }));
  36. }
  37. });
  38. req.on('error', (error) => {
  39. console.error('[ZipHandler] 请求错误:', error);
  40. res.writeHead(500, { 'Content-Type': 'application/json' });
  41. res.end(JSON.stringify({ error: 'Request error', details: error.message }));
  42. });
  43. }
  44. /**
  45. * 创建 ZIP 文件并返回
  46. * @param {string} folderName - 文件夹名称
  47. * @param {string} imageData - Base64 编码的图片数据
  48. * @param {string} jsonData - JSON 字符串数据
  49. * @param {http.ServerResponse} res - HTTP 响应对象
  50. */
  51. static createZip(folderName, imageData, jsonData, res) {
  52. try {
  53. // 设置响应头
  54. res.writeHead(200, {
  55. 'Content-Type': 'application/zip',
  56. 'Content-Disposition': `attachment; filename="${folderName}.zip"`,
  57. 'Access-Control-Allow-Origin': '*'
  58. });
  59. // 创建 archiver 实例
  60. const archive = archiver('zip', {
  61. zlib: { level: 6 } // 压缩级别
  62. });
  63. // 监听错误
  64. archive.on('error', (err) => {
  65. console.error('[ZipHandler] ZIP 创建错误:', err);
  66. if (!res.headersSent) {
  67. res.writeHead(500, { 'Content-Type': 'application/json' });
  68. res.end(JSON.stringify({ error: 'Failed to create zip', details: err.message }));
  69. }
  70. });
  71. // 将 ZIP 流连接到响应
  72. archive.pipe(res);
  73. // 将 Base64 图片数据转换为 Buffer
  74. const imageBuffer = Buffer.from(imageData, 'base64');
  75. // 添加文件到 ZIP
  76. archive.append(imageBuffer, { name: `${folderName}.png` });
  77. archive.append(jsonData, { name: `${folderName}.json` });
  78. // 完成打包
  79. archive.finalize();
  80. console.log(`[ZipHandler] ✓ 成功创建 ZIP: ${folderName}.zip`);
  81. } catch (error) {
  82. console.error('[ZipHandler] 创建 ZIP 失败:', error);
  83. if (!res.headersSent) {
  84. res.writeHead(500, { 'Content-Type': 'application/json' });
  85. res.end(JSON.stringify({ error: 'Failed to create zip', details: error.message }));
  86. }
  87. }
  88. }
  89. }
  90. module.exports = ZipHandler;