Add generate API, Prototype for developer, Clean data
Some checks failed
Deploy eCourt Note Web to Server / Validate Database Schema (Drizzle) (push) Successful in 5s
Deploy eCourt Note Web to Server / Build Web Docker Image (push) Failing after 1m11s
Deploy eCourt Note Web to Server / Deploy eCourt Note Web to Server (push) Has been skipped
Deploy eCourt Note Web to Server / Notify Deployment Status (push) Failing after 0s
Some checks failed
Deploy eCourt Note Web to Server / Validate Database Schema (Drizzle) (push) Successful in 5s
Deploy eCourt Note Web to Server / Build Web Docker Image (push) Failing after 1m11s
Deploy eCourt Note Web to Server / Deploy eCourt Note Web to Server (push) Has been skipped
Deploy eCourt Note Web to Server / Notify Deployment Status (push) Failing after 0s
This commit is contained in:
parent
6ce071ee14
commit
a3d14fd58d
26 changed files with 911 additions and 1267 deletions
101
app/api/template/generate/route.ts
Normal file
101
app/api/template/generate/route.ts
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
// สร้าง docx จาก json
|
||||
// - json.info.ticket_data จะมี tid ให้โหลดไฟล์ template นี้มาใช้
|
||||
// - สร้าง signature/hash จาก json.info.ticket_data
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import {readFile} from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { applyTemplate } from '../render/route'
|
||||
import { DocumentTemplate, templateContentControls, setCustomDocProps, templateDynamicContents } from "@/lib/lib-tmpl";
|
||||
const EXTERNAL_API_KEY = process.env.EXTERNAL_API_KEY || 'secret-api-key-1234';
|
||||
const TMPL_PATH = process.env.TMPL_PATH || ''
|
||||
const PRIVATE_KEY_HEX = process.env.PRIVATE_KEY_HEX ||''
|
||||
const SECRET = process.env.SECRET || ''
|
||||
|
||||
if (EXTERNAL_API_KEY || !TMPL_PATH || !PRIVATE_KEY_HEX || !SECRET)
|
||||
console.log("api/template/generate: require EXTERNAL_API_KEY, TMPL_PATH and PRIVATE_KEY_HEX")
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
// 1. ตรวจสอบ API Key จาก HTTP Header (x-api-key)
|
||||
const apiKey = request.headers.get('x-api-key');
|
||||
|
||||
if (!apiKey || apiKey !== EXTERNAL_API_KEY) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Unauthorized: Invalid API Key' },
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// รับข้อมูล JSON Payload
|
||||
const templateData:DocumentTemplate = (await request.json());
|
||||
console.log(templateData)
|
||||
// ต้องมี templateData.info.ticket_data เป็น json string เสมอ
|
||||
if (!templateData || !templateData.info ||
|
||||
!templateData.info.ticket_data ||
|
||||
typeof templateData.info.ticket_data !== "string"
|
||||
) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: "template/generate json.info.ticket_data not avaliable",
|
||||
},
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
const ticketObj = JSON.parse(templateData.info.ticket_data)
|
||||
const tid = String(ticketObj.tid)
|
||||
const fid = String(ticketObj.fid)
|
||||
const uid = String(ticketObj.uid)
|
||||
if(!tid||!fid||!uid)
|
||||
{
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: "template/generate require json.info.ticket_data.(fid|tid|uid)",
|
||||
},
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//เปิดไฟล์ template
|
||||
const tmplPath = path.join(TMPL_PATH, `${tid}.docx`);
|
||||
let templateBuffer: Buffer = await readFile(tmplPath)
|
||||
|
||||
const output = await applyTemplate(templateBuffer, templateData, SECRET, PRIVATE_KEY_HEX);
|
||||
|
||||
// สร้าง ReadableStream ของไฟล์ .docx
|
||||
// ในโค้ดจริง ส่วนนี้จะดึง Binary Buffer จาก Library เช่น docx, docxtemplater หรืออ่านจาก File System
|
||||
// const encoder = new TextEncoder();
|
||||
|
||||
const docxStream = new ReadableStream({
|
||||
start(controller) {
|
||||
controller.enqueue(output);
|
||||
controller.close();
|
||||
},
|
||||
});
|
||||
|
||||
// 4. ส่ง Return เป็น Response พร้อม Stream และ Headers กำหนด MIME type ของ MS Word
|
||||
const dlFileName = encodeURIComponent(`${tid}_${fid}_${uid}XX`)
|
||||
return new NextResponse(docxStream, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type':
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'Content-Disposition': `attachment; filename="${dlFileName}.docx"`,
|
||||
'Cache-Control': 'no-store, max-age=0',
|
||||
},
|
||||
});
|
||||
} catch (error:any) {
|
||||
if ( error.code === 'ENOENT') {
|
||||
return NextResponse.json(
|
||||
{ error: 'NotFound: Invalid template ID or incorrect storage path'},
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
console.error('Error generating docx:', error);
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to generate document payload'},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue