Pull Request branch dev-clone to main #1
|
|
@ -42,16 +42,39 @@ export const validationFormSchema = z.object({
|
||||||
|
|
||||||
export const answerUpdateSchema = answerFormSchema.partial();
|
export const answerUpdateSchema = answerFormSchema.partial();
|
||||||
|
|
||||||
// Helper function to save the file
|
// Helper untuk menyimpan file
|
||||||
async function saveFile(filePath: string, fileBuffer: Buffer): Promise<void> {
|
async function saveFile(filePath: string, fileBuffer: Buffer): Promise<void> {
|
||||||
await fs.promises.writeFile(filePath, fileBuffer);
|
await fs.promises.writeFile(filePath, fileBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to update the filename in the database
|
// Cari answer berdasarkan assessmentId dan questionId
|
||||||
async function updateFilenameInDatabase(answerId: string, filename: string): Promise<void> {
|
async function findAnswerId(assessmentId: string, questionId: string): Promise<string | null> {
|
||||||
|
const result = await db
|
||||||
|
.select({ answerId: answers.id })
|
||||||
|
.from(answers)
|
||||||
|
.leftJoin(options, eq(answers.optionId, options.id))
|
||||||
|
.where(
|
||||||
|
and(
|
||||||
|
eq(answers.assessmentId, assessmentId),
|
||||||
|
eq(options.questionId, questionId)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
await db.update(answers)
|
return result.length > 0 ? result[0].answerId : null;
|
||||||
.set({ filename })
|
}
|
||||||
|
|
||||||
|
// Update filename di tabel answers
|
||||||
|
async function updateFilename(answerId: string, filename: string): Promise<void> {
|
||||||
|
// Dapatkan tanggal dan waktu saat ini
|
||||||
|
const currentDate = new Date();
|
||||||
|
|
||||||
|
await db
|
||||||
|
.update(answers)
|
||||||
|
.set({
|
||||||
|
filename,
|
||||||
|
updatedAt: currentDate,
|
||||||
|
})
|
||||||
.where(eq(answers.id, answerId));
|
.where(eq(answers.id, answerId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -481,75 +504,58 @@ const assessmentsRoute = new Hono<HonoEnv>()
|
||||||
"/uploadFile",
|
"/uploadFile",
|
||||||
checkPermission("assessments.uploadFile"),
|
checkPermission("assessments.uploadFile"),
|
||||||
async (c) => {
|
async (c) => {
|
||||||
// Get the Content-Type header
|
|
||||||
const contentType = c.req.header('content-type');
|
const contentType = c.req.header('content-type');
|
||||||
if (!contentType || !contentType.includes('multipart/form-data')) {
|
if (!contentType || !contentType.includes('multipart/form-data')) {
|
||||||
throw notFound({
|
return c.json({ message: "Invalid Content-Type" }, 400);
|
||||||
message: "Invalid Content-Type",
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract boundary
|
|
||||||
const boundary = contentType.split('boundary=')[1];
|
const boundary = contentType.split('boundary=')[1];
|
||||||
if (!boundary) {
|
if (!boundary) {
|
||||||
throw notFound({
|
return c.json({ message: "Boundary not found" }, 400);
|
||||||
message: "Boundary not found",
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the raw body
|
|
||||||
const body = await c.req.arrayBuffer();
|
const body = await c.req.arrayBuffer();
|
||||||
const bodyString = Buffer.from(body).toString();
|
const bodyString = Buffer.from(body).toString();
|
||||||
|
|
||||||
// Split the body by the boundary
|
|
||||||
const parts = bodyString.split(`--${boundary}`);
|
const parts = bodyString.split(`--${boundary}`);
|
||||||
|
|
||||||
let fileUrl = null;
|
let fileUrl: string | null = null;
|
||||||
|
|
||||||
for (const part of parts) {
|
for (const part of parts) {
|
||||||
if (part.includes('Content-Disposition: form-data;')) {
|
if (part.includes('Content-Disposition: form-data;')) {
|
||||||
// Extract file name
|
|
||||||
const match = /filename="(.+?)"/.exec(part);
|
const match = /filename="(.+?)"/.exec(part);
|
||||||
if (match) {
|
if (match) {
|
||||||
const fileName = match[1];
|
const fileName = match[1];
|
||||||
const fileContentStart = part.indexOf('\r\n\r\n') + 4;
|
const fileContentStart = part.indexOf('\r\n\r\n') + 4;
|
||||||
const fileContentEnd = part.lastIndexOf('\r\n');
|
const fileContentEnd = part.lastIndexOf('\r\n');
|
||||||
|
|
||||||
// Extract file content as Buffer
|
|
||||||
const fileBuffer = Buffer.from(part.slice(fileContentStart, fileContentEnd), 'binary');
|
const fileBuffer = Buffer.from(part.slice(fileContentStart, fileContentEnd), 'binary');
|
||||||
|
|
||||||
// Define file path and save the file
|
const filePath = path.join('files', `${Date.now()}-${fileName}`);
|
||||||
const filePath = path.join('images', Date.now() + '-' + fileName);
|
|
||||||
await saveFile(filePath, fileBuffer);
|
await saveFile(filePath, fileBuffer);
|
||||||
|
|
||||||
// Assuming answerId is passed as a query parameter or in the form-data
|
const assessmentId = c.req.query('assessmentId');
|
||||||
const answerId = c.req.query('answerId');
|
const questionId = c.req.query('questionId');
|
||||||
if (!answerId) {
|
|
||||||
throw notFound({
|
if (!assessmentId || !questionId) {
|
||||||
message: "answerId is required",
|
return c.json({ message: "assessmentId and questionId are required" }, 400);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await updateFilenameInDatabase(answerId, path.basename(filePath));
|
const answerId = await findAnswerId(assessmentId, questionId);
|
||||||
|
|
||||||
// Set the file URL for the final response
|
if (!answerId) {
|
||||||
fileUrl = `/images/${path.basename(filePath)}`;
|
return c.json({ message: 'Answer not found' }, 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
await updateFilename(answerId, path.basename(filePath));
|
||||||
|
fileUrl = `/files/${path.basename(filePath)}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fileUrl) {
|
if (!fileUrl) {
|
||||||
throw notFound({
|
return c.json({ message: 'No file uploaded' }, 400);
|
||||||
message: 'No file uploaded',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.json(
|
return c.json({ success: true, imageUrl: fileUrl });
|
||||||
{
|
|
||||||
success: true,
|
|
||||||
imageUrl: fileUrl
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user