Initial commit

This commit is contained in:
payacom
2026-07-09 15:25:16 +03:30
parent 0b01b262fa
commit 51eb7d0224
21 changed files with 1544 additions and 98 deletions

View File

@@ -1395,12 +1395,28 @@ const createComment = async (req, res) => {
});
}
const parsedRate = Number(rate) || 0;
const existingRatedComment = await CourseComment.findOne({
user_id: userId,
course_id,
rate: { $gt: 0 },
});
if (existingRatedComment && parsedRate > 0) {
return res.status(400).json({
error: true,
message: "شما قبلاً به این دوره امتیاز داده‌اید.",
});
}
const finalRate = existingRatedComment ? 0 : parsedRate;
// ایجاد کامنت جدید
const newComment = await CourseComment.create({
user_id: userId,
course_id: course_id,
comment: comment,
rate: rate || 0,
rate: finalRate,
status: "accepted", // با توجه به مدل شما که default: 'accepted' است
});
@@ -4184,6 +4200,84 @@ const getFeatured = async (req, res) => {
};
const getFreeAcademyExploreContent = async (req, res, next) => {
try {
const page = parseInt(req.query.page, 10) || 1;
const limit = parseInt(req.query.limit, 10) || 15;
const skip = (page - 1) * limit;
const query = { is_free: true, status: "accept" };
const totalItems = await AcademyContentModel.countDocuments(query);
const contents = await AcademyContentModel.find(query)
.sort({ createdAt: -1 })
.skip(skip)
.limit(limit)
.lean();
const courseIds = [
...new Set(contents.map((item) => item.courseId).filter(Boolean)),
];
const courses = courseIds.length
? await CourseModel.find({ _id: { $in: courseIds } })
.select(
"cuorse_name course_image teacher_name academyId user_id caption likes"
)
.lean()
: [];
const courseMap = Object.fromEntries(
courses.map((course) => [String(course._id), course])
);
const userIds = [
...new Set(courses.map((course) => String(course.user_id)).filter(Boolean)),
];
const users = userIds.length
? await UserModel.find({ _id: { $in: userIds } })
.select("user_name first_name last_name profile_image")
.lean()
: [];
const userMap = Object.fromEntries(
users.map((user) => [String(user._id), user])
);
const items = contents.map((content) => {
const course = courseMap[String(content.courseId)] || {};
const user = userMap[String(course.user_id)] || {};
return {
...content,
course_name: course.cuorse_name || content.file_name || "",
course_image: course.course_image || "",
teacher_name: course.teacher_name || "",
academyId: course.academyId || "",
user_name: user.user_name || "",
first_name: user.first_name || "",
last_name: user.last_name || "",
profile_image: user.profile_image || "",
likesCount: Array.isArray(course.likes) ? course.likes.length : 0,
};
});
const totalPages = Math.ceil(totalItems / limit) || 1;
return res.status(200).json({
success: true,
data: {
items,
pagination: {
currentPage: page,
totalPages,
totalItems,
hasNextPage: page < totalPages,
},
},
});
} catch (error) {
console.error("Error in getFreeAcademyExploreContent:", error);
next(error);
}
};
module.exports = {
// ==========================================
// 🏢 ماژول آکادمی (Academy)
@@ -4234,6 +4328,9 @@ module.exports = {
// دریافت لیست همه دوره‌ها با فیلتر و جستجو
getCourses,
// محتوای رایگان آموزشگاه برای اکسپلور
getFreeAcademyExploreContent,
// دریافت دوره‌های یک آکادمی خاص
getAcademyCourse,