uploads และ downloads
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
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'));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user