import { GeneralService } from '../share/generalservice.js'; import { sendError } from '../utils/response.js'; import fs from 'fs'; import path from 'path'; import archiver from 'archiver'; // ⚠️ ต้อง npm install archiver export class projectDownload { constructor() { this.generalService = new GeneralService(); } // GET Route ไม่รับ Body ดังนั้นรับ Parameter จาก Query String หรือ Params async onNavigate(req, res) { this.generalService.devhint(1, 'projectDownload.js', 'onNavigate() start'); // รับ prjseq จาก Query String (เช่น /projectdownload?prjseq=123) const prjseq = req.query.prjseq; if (!prjseq) { return res.status(400).json(sendError('กรุณาระบุ prjseq', 'Missing prjseq parameter')); } return await this.onProjectDownload(req, res, prjseq); } async onProjectDownload(req, res, prjseq) { try { const folderPath = `uploads/projects/${prjseq}`; // 1. ตรวจสอบว่า Folder มีอยู่จริงหรือไม่ if (!fs.existsSync(folderPath)) { return res.status(404).json(sendError('ไม่พบเอกสารของโครงการนี้', 'Project documents not found')); } // 2. ตั้งค่า Response Header ให้เป็นไฟล์ Zip const archive = archiver('zip', { zlib: { level: 9 } // บีบอัดสูงสุด }); const zipFilename = `project_${prjseq}_documents.zip`; res.attachment(zipFilename); // บอก Browser ว่าให้ Download เป็นชื่อนี้ // 3. Handle Events archive.on('error', function(err) { console.error('Zip Error:', err); res.status(500).send({error: err.message}); }); // เมื่อบีบอัดเสร็จและส่งข้อมูลครบ archive.on('end', function() { console.log(`Archive wrote ${archive.pointer()} bytes`); }); // 4. Pipe Archive -> Response (Stream) archive.pipe(res); // 5. เอาไฟล์ใน Folder ใส่ Zip // name: false หมายถึงเอาไฟล์ใส่ root ของ zip เลย ไม่ต้องซ้อน folder archive.directory(folderPath, false); // 6. สั่งจบการบีบอัด (จะเริ่มส่งข้อมูลทันที) await archive.finalize(); // ⚠️ หมายเหตุ: เราไม่ return อะไรกลับไป เพราะเรา Pipe Stream ใส่ res โดยตรงแล้ว // globalResponseHandler จะไม่ทำงานเพราะเราไม่ได้ res.json() ซึ่งถูกต้องแล้วสำหรับการโหลดไฟล์ } catch (error) { console.error('Download Controller Error:', error); return res.status(500).json(sendError('เกิดข้อผิดพลาดในการดาวน์โหลด', 'Download Error')); } } }