update api chapterlesson
This commit is contained in:
parent
2fc0fb7a76
commit
5c2b5d55aa
11 changed files with 855 additions and 85 deletions
|
|
@ -22,6 +22,8 @@ import {
|
|||
CompleteLessonInput,
|
||||
CompleteLessonResponse,
|
||||
} from "../types/CoursesStudent.types";
|
||||
import { getPresignedUrl, listObjects, getVideoFolder, getAttachmentsFolder } from '../config/minio';
|
||||
|
||||
|
||||
export class CoursesStudentService {
|
||||
async enrollCourse(input: EnrollCourseInput): Promise<EnrollCourseResponse> {
|
||||
|
|
@ -265,6 +267,8 @@ export class CoursesStudentService {
|
|||
const { token, course_id, lesson_id } = input;
|
||||
const decoded = jwt.verify(token, config.jwt.secret) as { id: number; type: string };
|
||||
|
||||
// Import MinIO functions
|
||||
|
||||
// Check enrollment
|
||||
const enrollment = await prisma.enrollment.findUnique({
|
||||
where: {
|
||||
|
|
@ -319,6 +323,80 @@ export class CoursesStudentService {
|
|||
const prevLessonId = currentIndex > 0 ? allLessons[currentIndex - 1].id : null;
|
||||
const nextLessonId = currentIndex < allLessons.length - 1 ? allLessons[currentIndex + 1].id : null;
|
||||
|
||||
// Get course_id from chapter
|
||||
const chapter_course_id = lesson.chapter.course_id;
|
||||
|
||||
// Import additional MinIO functions
|
||||
// Using MinIO functions imported above
|
||||
|
||||
// Get video URL from video folder (first file)
|
||||
let video_url: string | null = null;
|
||||
try {
|
||||
const videoPrefix = getVideoFolder(chapter_course_id, lesson_id);
|
||||
const videoFiles = await listObjects(videoPrefix);
|
||||
if (videoFiles.length > 0) {
|
||||
// Get presigned URL for the first video file
|
||||
video_url = await getPresignedUrl(videoFiles[0].name, 3600);
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error(`Failed to get video from MinIO: ${err}`);
|
||||
}
|
||||
|
||||
// Get attachments from MinIO folder
|
||||
const attachmentsWithUrls: {
|
||||
file_name: string;
|
||||
file_path: string;
|
||||
file_size: number;
|
||||
mime_type: string;
|
||||
presigned_url: string | null;
|
||||
}[] = [];
|
||||
|
||||
try {
|
||||
const attachmentsPrefix = getAttachmentsFolder(chapter_course_id, lesson_id);
|
||||
const attachmentFiles = await listObjects(attachmentsPrefix);
|
||||
|
||||
for (const file of attachmentFiles) {
|
||||
let presigned_url: string | null = null;
|
||||
try {
|
||||
presigned_url = await getPresignedUrl(file.name, 3600);
|
||||
} catch (err) {
|
||||
logger.error(`Failed to generate presigned URL for ${file.name}: ${err}`);
|
||||
}
|
||||
|
||||
// Extract filename from path
|
||||
const fileName = file.name.split('/').pop() || file.name;
|
||||
// Guess mime type from extension
|
||||
const ext = fileName.split('.').pop()?.toLowerCase() || '';
|
||||
const mimeTypes: { [key: string]: string } = {
|
||||
'pdf': 'application/pdf',
|
||||
'doc': 'application/msword',
|
||||
'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'ppt': 'application/vnd.ms-powerpoint',
|
||||
'pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'xls': 'application/vnd.ms-excel',
|
||||
'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'png': 'image/png',
|
||||
'jpg': 'image/jpeg',
|
||||
'jpeg': 'image/jpeg',
|
||||
'gif': 'image/gif',
|
||||
'mp4': 'video/mp4',
|
||||
'zip': 'application/zip',
|
||||
};
|
||||
const mime_type = mimeTypes[ext] || 'application/octet-stream';
|
||||
|
||||
attachmentsWithUrls.push({
|
||||
file_name: fileName,
|
||||
file_path: file.name,
|
||||
file_size: file.size,
|
||||
mime_type,
|
||||
presigned_url,
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error(`Failed to list attachments from MinIO: ${err}`);
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
code: 200,
|
||||
message: 'Lesson retrieved successfully',
|
||||
|
|
@ -332,14 +410,8 @@ export class CoursesStudentService {
|
|||
is_sequential: lesson.is_sequential,
|
||||
prerequisite_lesson_ids: lesson.prerequisite_lesson_ids as number[] | null,
|
||||
require_pass_quiz: lesson.require_pass_quiz,
|
||||
attachments: lesson.attachments.map(att => ({
|
||||
id: att.id,
|
||||
file_name: att.file_name,
|
||||
file_path: att.file_path,
|
||||
file_size: att.file_size,
|
||||
mime_type: att.mime_type,
|
||||
description: att.description as { th: string; en: string } | null,
|
||||
})),
|
||||
video_url, // Presigned URL for video
|
||||
attachments: attachmentsWithUrls,
|
||||
quiz: lesson.quiz ? {
|
||||
id: lesson.quiz.id,
|
||||
title: lesson.quiz.title as { th: string; en: string },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue