modified: controllers/application/academy/academyCategoryController.js

modified:   controllers/application/academy/academyControllers.js
	modified:   controllers/application/academy/helpers/chatHelpers.js
	modified:   controllers/application/academy/middlewares/404.js
	modified:   controllers/application/academy/middlewares/adminAuth.js
	modified:   controllers/application/academy/middlewares/auth.js
	modified:   controllers/application/academy/middlewares/blockCheck.js
	modified:   controllers/application/academy/middlewares/exception.js
	modified:   controllers/application/academy/middlewares/index.js
	modified:   controllers/application/academy/middlewares/isHalfRegister.js
	modified:   controllers/application/academy/middlewares/isRegister.js
	modified:   controllers/application/academy/middlewares/lastOnline.js
	modified:   controllers/application/academy/middlewares/upload.js
	modified:   controllers/application/academy/models/AcademyCategoryModel.js
	modified:   controllers/application/academy/models/AcademyContentModel.js
	modified:   controllers/application/academy/models/AcademyLikeModel.js
	modified:   controllers/application/academy/models/AcademyModel.js
	modified:   controllers/application/academy/models/AcademyPaymentModel.js
	modified:   controllers/application/academy/models/AdminModel.js
	modified:   controllers/application/academy/models/AdvertisingCategoryModel.js
	modified:   controllers/application/academy/models/AdvertisingCommentModel.js
	modified:   controllers/application/academy/models/AdvertisingFeaturesModel.js
	modified:   controllers/application/academy/models/AdvertisingLikeModel.js
	modified:   controllers/application/academy/models/AdvertisingModel.js
	modified:   controllers/application/academy/models/AdvertisingProfile.js
	modified:   controllers/application/academy/models/AdvertisingRatingModel.js
	modified:   controllers/application/academy/models/AdvertisingTypeModel.js
	modified:   controllers/application/academy/models/CommentModel.js
	modified:   controllers/application/academy/models/CourseComentModel.js
	modified:   controllers/application/academy/models/CourseModel.js
	modified:   controllers/application/academy/models/CoursePaymentModel.js
	modified:   controllers/application/academy/models/ExpertiseModel.js
	modified:   controllers/application/academy/models/IsPaymentCourseModel.js
	modified:   controllers/application/academy/models/LikeModel.js
	modified:   controllers/application/academy/models/MessageModel.js
	modified:   controllers/application/academy/models/NotificationModel.js
	modified:   controllers/application/academy/models/OfferModel.js
	modified:   controllers/application/academy/models/OfferTypeModel.js
	modified:   controllers/application/academy/models/PaymentModel.js
	modified:   controllers/application/academy/models/PostModel.js
	modified:   controllers/application/academy/models/ProjectModel.js
	modified:   controllers/application/academy/models/RequestModel.js
	modified:   controllers/application/academy/models/SettingsModel.js
	modified:   controllers/application/academy/models/StateCity.js
	modified:   controllers/application/academy/models/TaxModel.js
	modified:   controllers/application/academy/models/TicketMessageModel.js
	modified:   controllers/application/academy/models/TicketModel.js
	modified:   controllers/application/academy/models/TypeAndPriceModel.js
	modified:   controllers/application/academy/models/UserModel.js
	modified:   controllers/application/academy/models/VersionModel.js
	modified:   controllers/application/academy/models/license.js
	modified:   controllers/application/advertising/advertisingController.js
	modified:   controllers/application/citysController.js
	modified:   controllers/application/expertise/expertiseController.js
	modified:   controllers/application/financial/financialController.js
	modified:   controllers/application/login/changePasswordController.js
	modified:   controllers/application/login/loginController.js
	modified:   controllers/application/login/loginWithUserName.js
	modified:   controllers/application/login/verifyController.js
	modified:   controllers/application/messages/messageController.js
	modified:   controllers/application/notification/notificationController.js
	modified:   controllers/application/offer/offerController.js
	modified:   controllers/application/payment/paymentController.js
	modified:   controllers/application/payment/paymentControllerWeb.js
	modified:   controllers/application/posts/likeController.js
	modified:   controllers/application/posts/postController.js
	modified:   controllers/application/profile/profileController.js
	modified:   controllers/application/projects/createProjectController.js
	modified:   controllers/application/projects/getProjectController.js
	modified:   controllers/application/projects/projectTypesController.js
	modified:   controllers/application/projects/requestProjectController.js
	modified:   controllers/application/projects/updateProjectController.js
	modified:   controllers/application/provincesController.js
	modified:   controllers/application/register/registerController.js
	modified:   controllers/application/register/userFullNameController.js
	modified:   controllers/application/register/userTypeController.js
	modified:   controllers/application/register/usernameController.js
	modified:   controllers/application/register/verifyController.js
	modified:   controllers/application/search-web/searchController.js
	modified:   controllers/application/search/searchController.js
	modified:   controllers/application/settings/settingsController.js
	modified:   controllers/application/tickets/ticketsController.js
	modified:   controllers/application/users/getUserController.js
	modified:   controllers/application/verify/addressController.js
	modified:   controllers/application/verify/authController.js
	modified:   controllers/application/verify/colorsController.js
	modified:   controllers/application/verify/conversationController.js
	modified:   controllers/application/verify/cooperationTypeController.js
	modified:   controllers/application/verify/expertiseController.js
	modified:   controllers/application/verify/genderController.js
	modified:   controllers/application/verify/servicesController.js
	modified:   controllers/application/verify/setNationalCardImageController.js
	modified:   controllers/application/verify/setProfileImageController.js
	modified:   controllers/application/verify/sizesController.js
	modified:   controllers/application/version/versionController.js
	modified:   controllers/application/workroom/workroomController.js
	modified:   controllers/panel/advertising/academyCategoryController.js
	modified:   controllers/panel/advertising/advertisingController.js
	modified:   controllers/panel/comments/advertisingCommentController.js
	modified:   controllers/panel/comments/commentController.js
	modified:   controllers/panel/expertise/expertiseController.js
	modified:   controllers/panel/financial/financialController.js
	modified:   controllers/panel/login/loginController.js
	modified:   controllers/panel/posts/postController.js
	modified:   controllers/panel/projects/projectController.js
	modified:   controllers/panel/projects/projectTypesController.js
	modified:   controllers/panel/settings/settingsController.js
	modified:   controllers/panel/shops/shopsController.js
	modified:   controllers/panel/tickets/ticketsController.js
	modified:   controllers/panel/users/usersController.js
	modified:   controllers/panel/version/versionController.js
	modified:   helpers/chatHelpers.js
	modified:   index.js
	deleted:    logs/sms-irs/13-03-2024.log
	modified:   middlewares/404.js
	modified:   middlewares/adminAuth.js
	modified:   middlewares/auth.js
	modified:   middlewares/blockCheck.js
	modified:   middlewares/exception.js
	modified:   middlewares/index.js
	modified:   middlewares/isHalfRegister.js
	modified:   middlewares/isRegister.js
	modified:   middlewares/lastOnline.js
	modified:   middlewares/upload.js
	modified:   models/AcademyCategoryModel.js
	modified:   models/AcademyContentModel.js
	modified:   models/AcademyLikeModel.js
	modified:   models/AcademyModel.js
	modified:   models/AcademyPaymentModel.js
	modified:   models/AdminModel.js
	modified:   models/AdvertisingCategoryModel.js
	modified:   models/AdvertisingCommentModel.js
	modified:   models/AdvertisingFeaturesModel.js
	modified:   models/AdvertisingLikeModel.js
	modified:   models/AdvertisingModel.js
	modified:   models/AdvertisingProfile.js
	modified:   models/AdvertisingRatingModel.js
	modified:   models/AdvertisingTypeModel.js
	modified:   models/CommentModel.js
	modified:   models/CourseComentModel.js
	modified:   models/CourseModel.js
	modified:   models/CoursePaymentModel.js
	modified:   models/ExpertiseModel.js
	modified:   models/IsPaymentCourseModel.js
	modified:   models/LikeModel.js
	modified:   models/MessageModel.js
	modified:   models/NotificationModel.js
	modified:   models/OfferModel.js
	modified:   models/OfferTypeModel.js
	modified:   models/PaymentModel.js
	modified:   models/PostModel.js
	modified:   models/ProjectModel.js
	modified:   models/RequestModel.js
	modified:   models/SettingsModel.js
	modified:   models/StateCity.js
	modified:   models/TaxModel.js
	modified:   models/TicketMessageModel.js
	modified:   models/TicketModel.js
	modified:   models/TypeAndPriceModel.js
	modified:   models/UserModel.js
	modified:   models/VersionModel.js
	modified:   models/license.js
	modified:   routes/application/academy/index.js
	modified:   routes/application/advertising/index.js
	modified:   routes/application/city/index.js
	modified:   routes/application/expertise/index.js
	modified:   routes/application/financial/index.js
	modified:   routes/application/login/index.js
	modified:   routes/application/messages/index.js
	modified:   routes/application/notification/index.js
	modified:   routes/application/offers/index.js
	modified:   routes/application/posts/index.js
	modified:   routes/application/profile/index.js
	modified:   routes/application/projects/index.js
	modified:   routes/application/provinces/index.js
	modified:   routes/application/register/index.js
	modified:   routes/application/search-web/index.js
	modified:   routes/application/search/index.js
	modified:   routes/application/settings/index.js
	modified:   routes/application/tickets/index.js
	modified:   routes/application/users/index.js
	modified:   routes/application/verify/index.js
	modified:   routes/application/version/index.js
	modified:   routes/application/workroom/index.js
	modified:   routes/index.js
	modified:   routes/panel/advertising/index.js
	modified:   routes/panel/comments/index.js
	modified:   routes/panel/expertise/index.js
	modified:   routes/panel/financial/index.js
	modified:   routes/panel/login/index.js
	modified:   routes/panel/posts/index.js
	modified:   routes/panel/projects/index.js
	modified:   routes/panel/settings/index.js
	modified:   routes/panel/shops/index.js
	modified:   routes/panel/tickets/index.js
	modified:   routes/panel/users/index.js
	modified:   routes/panel/version/index.js
	modified:   scripts/dns/db.modstagram.com
	modified:   scripts/dns/db.modstagram.ir
	modified:   scripts/dns/named.conf.local.snippet
	modified:   scripts/nginx/api.modstagram.com.conf
	modified:   scripts/nginx/app.modstagram.com.conf
	modified:   scripts/nginx/blog.modstagram.com.conf
	modified:   scripts/nginx/cdn.modstagram.com.conf
	modified:   scripts/nginx/cdn.modstagram.com.http.conf
	modified:   scripts/nginx/modstagram-redirects.conf
	modified:   scripts/nginx/modstagram.com.conf
	modified:   scripts/nginx/panel.modstagram.com.conf
	modified:   scripts/nginx/pay.modstagram.com.conf
	modified:   scripts/server-setup.sh
	modified:   services/AdvertisingCron.js
	modified:   services/ProjectCron.js
	modified:   services/TokenService.js
	deleted:    storage/courses/videos/course-69f8b2da55f31efffa601c57-1778257437373.mp4
	deleted:    storage/courses/videos/course-69f8b2da55f31efffa601c57-1778257586892.mp4
	deleted:    storage/courses/videos/course-69f8b2da55f31efffa601c57-1778257829783.mp4
	deleted:    storage/courses/videos/course-69f8b2da55f31efffa601c57-1778257903018.mp4
	deleted:    storage/posts/videos/1766758940571-0-video_2025-05-21_16-30-58.mp4
	deleted:    storage/posts/videos/1766781626514-0-video_2025-05-21_16-30-58.mp4
	deleted:    storage/posts/videos/1766824222908-0-Find 'modeling videos' on TikTok - TikTok Search_7.mp4
	deleted:    storage/posts/videos/1766824281937-0-Find 'modeling videos' on TikTok - TikTok Search_6.mp4
	deleted:    storage/posts/videos/1766824360366-0-Find 'bridal makeup' on TikTok - TikTok Search_4.mp4
	deleted:    storage/posts/videos/1766824425868-0-Find 'Makeup' on TikTok - TikTok Search_25.mp4
	deleted:    storage/posts/videos/1766824503238-0-Find 'Makeup' on TikTok - TikTok Search.mp4
	deleted:    storage/posts/videos/1766824554864-0-Jalal.hafed (@jalal.hafed) Official.mp4
	deleted:    storage/posts/videos/1766824618322-0-Find 'Hairdressing' on TikTok - TikTok Search_3.mp4
	deleted:    storage/posts/videos/1766824689078-0-Find 'Beauty clinic' on TikTok - TikTok Search_22.mp4
	deleted:    storage/posts/videos/1766824721659-0-Find 'Beauty clinic' on TikTok - TikTok Search_13.mp4
	deleted:    storage/posts/videos/1766824796958-0-Find 'photography' on TikTok - TikTok Search_6.mp4
	deleted:    storage/posts/videos/1766825351987-0-aaaa.mp4
	deleted:    storage/posts/videos/1766825448136-0-sasasa.mp4
	deleted:    storage/posts/videos/1766825535111-0-qqq.mp4
	deleted:    "storage/posts/videos/1766825855902-0-Nail desin by Labella beauty salon\360\237\214\270\360\237\222\205\360\237\217\273  #nail #nailart #manicure #manicure\360\237\222\205 #salon #pedicure #labella.mp4"
	deleted:    storage/posts/videos/1766825905907-0-dsdsdsdsdsds.mp4
	deleted:    "storage/posts/videos/1766826114243-0-Every piece of jewelry tells a story\360\237\217\271  @mirjaliligold @mohseneh_b.mp4"
	deleted:    "storage/posts/videos/1766826180365-0-Romeo, save me\360\237\246\242.mp4"
	deleted:    storage/posts/videos/1766826458195-0-aaaaa.mp4
	deleted:    storage/posts/videos/1766826609640-0-asasa.mp4
	deleted:    storage/posts/videos/1766826685281-0-s.mp4
	deleted:    storage/posts/videos/1766826815345-0-asasa.mp4
	deleted:    storage/posts/videos/1766826842822-0-aaa.mp4
	deleted:    "storage/posts/videos/1766827337926-0-Snow, mountains, and me\342\200\246 a story that never gets old!  #backstage #stylish #snow #style#streetstyle.mp4"
	deleted:    "storage/posts/videos/1766828100639-0-\330\263\330\263\330\263\330\263.mp4"
	deleted:    storage/posts/videos/1766828130001-0-aaa.mp4
	deleted:    storage/posts/videos/1766828157845-0-ssss.mp4
	deleted:    storage/posts/videos/1766828203643-0-aaaa.mp4
	deleted:    "storage/posts/videos/1766828345460-0-You deserve to be happy, and you can\342\200\231t stay where your heart doesn\342\200\231t belong  #\330\252\331\210\331\204\330\257\331\205_\331\205\330\250\330\247\330\261\332\251 #\330\242\330\250\333\214 #\330\247\331\207\331\210\330\247\330\262 #\330\252\331\210\331\204\330\257 #\330\250\331\204\330\247\332\257\330\261 @gallery.nilai.mp4"
	deleted:    storage/posts/videos/1766828424672-0-1111.mp4
	deleted:    storage/posts/videos/1766828464781-0-sss.mp4
	deleted:    storage/posts/videos/1766828486889-0-aaaa.mp4
	deleted:    storage/posts/videos/1766828514279-0-sss.mp4
	deleted:    storage/posts/videos/1766828727356-0-ddd.mp4
	deleted:    "storage/posts/videos/1766828816020-0-Jewlery project  Brand- @houseofme_official  Dop- @_alishariatt  Videographer- @peyman_bozorgomid  Assistant- @amir.kh.k  Model- @ana.elitee  #jewleryphotography #fashionreels #\330\261\333\214\331\204.mp4"
	deleted:    "storage/posts/videos/1766828848513-0-Some of my favorite shots Models- @saharjalilii @setayesh.ghalenoeii @parmisaadat @paaarand @asalllbayat @bitakhaajoii  #photographer #\330\271\332\251\330\247\330\263\333\214_\331\201\330\264\331\206 #photosoftheday.mp4"
	deleted:    "storage/posts/videos/1766831745457-0-\330\263\330\263\330\263.mp4"
	deleted:    "storage/posts/videos/1766831795030-0-\330\264\330\264\330\264\330\264.mp4"
	deleted:    "storage/posts/videos/1766833279276-0-\330\247\330\262 \332\206\330\264\330\247\331\205 \331\207\331\204\330\252 \330\257\330\247\330\257\331\205\342\200\214 \331\210\331\204\333\214 .....mp4"
	deleted:    "storage/posts/videos/1766835292259-0-\330\263\333\214\330\263.mp4"
	deleted:    storage/posts/videos/1766835327424-0-a.mp4
	deleted:    storage/posts/videos/1766835787091-0-s.mp4
	deleted:    storage/posts/videos/1767012113143-0-aaa.mp4
	deleted:    "storage/posts/videos/1767012137018-0-Makeup by-\360\237\221\207\360\237\217\275\360\237\215\267 @pegah.mua  @kiavash_royalvideo.mp4"
	deleted:    storage/posts/videos/1767012672738-0-dddd.mp4
	deleted:    storage/posts/videos/1767012722043-0-Instagram.mp4
	deleted:    "storage/posts/videos/1768740975998-0-Faouzia\343\200\212Desert Rose\343\200\213.mp4"
	deleted:    storage/posts/videos/1768741493380-0-a.mp4
	deleted:    "storage/posts/videos/1771318409261-0-\330\266\330\265\330\266\330\265\330\266\330\265\330\266.mp4"
	deleted:    "storage/posts/videos/1771319189820-0-\330\263\330\263\330\263\330\263.mp4"
	deleted:    storage/posts/videos/1771937200099-0-WhatsApp Video 2025-05-17 at 11.50.09.mp4
	deleted:    storage/posts/videos/1772005435124-0-qqqq.mp4
	deleted:    storage/posts/videos/1772005611958-0-aaaaa.mp4
	deleted:    storage/posts/videos/1772006456443-0-qqqqww.mp4
	deleted:    storage/posts/videos/1772006543741-0-1111.mp4
	deleted:    storage/posts/videos/1772006606627-0-wewewe.mp4
	deleted:    storage/posts/videos/1772006663579-0-wwww.mp4
	deleted:    storage/posts/videos/1772006685382-0-333.mp4
	deleted:    storage/posts/videos/1772006740696-0-www.mp4
	deleted:    storage/posts/videos/1772006786181-0-4444.mp4
	deleted:    storage/posts/videos/1772009213487-0-aaaa.mp4
	deleted:    storage/posts/videos/1772009260843-0-sss.mp4
	deleted:    "storage/posts/videos/1772013946491-0-\330\250\330\250\330\250\330\250\330\250.mp4"
	deleted:    "storage/posts/videos/1772089789739-0-\330\266\330\266\330\266\330\266.mp4"
	deleted:    storage/posts/videos/1772090631353-0-qqqq.mp4
	deleted:    "storage/posts/videos/1772092053138-0-\330\265\330\265\330\265.mp4"
	deleted:    storage/posts/videos/1772101142214-0-2222.mp4
	deleted:    "storage/posts/videos/1772101261385-0-\330\266\330\266\330\266\330\266.mp4"
	deleted:    storage/posts/videos/1772101312006-0-Instagram.mp4
	deleted:    "storage/posts/videos/1772101434744-0-\330\263\333\214\330\263\333\214\330\263\333\214.mp4"
	deleted:    "storage/posts/videos/1772203614700-0-\330\263\330\247\331\205\330\250\330\261\331\207 \330\250\331\204\331\210\331\206\330\257 \330\250\330\261\330\247\333\214 \331\201\330\247\330\267\331\205\331\207 \330\271\330\262\333\214\330\262\331\205\360\237\222\225.mp4"
	deleted:    "storage/posts/videos/1772203641829-0-\330\257\332\251\331\204\330\261\331\207 \331\210 \330\261\331\206\332\257 \331\210 \332\251\331\210\330\252\330\247\331\207\333\214 \330\250\330\261\330\247\333\214 \330\263\331\210\330\257\330\247 \331\202\330\264\331\206\332\257\331\205\360\237\222\225.mp4"
	deleted:    "storage/posts/videos/1772203698315-0-\330\247\333\214\331\206 \332\251\330\247\330\261 \330\262\333\214\330\250\330\247\331\205\331\210\331\206 \330\250\330\261\330\247\333\214 \330\255\330\250\333\214\330\250\331\207 \330\256\330\247\331\206\331\205 \330\271\330\262\333\214\330\262\360\237\222\225.mp4"
	deleted:    "storage/posts/videos/1772205300232-0-\330\264\330\264\330\264\330\264.mp4"
	deleted:    "storage/posts/videos/1772205333900-0-\330\265\330\265\330\265\330\265\330\265.mp4"
	deleted:    "storage/posts/videos/1772207461030-0-\330\265\330\265\330\265.mp4"
	deleted:    "storage/posts/videos/1772207616124-0-\330\264\330\264\330\264.mp4"
	deleted:    "storage/posts/videos/1772207684446-0-\330\253\330\253\330\253\330\253.mp4"
	deleted:    "storage/posts/videos/1772208440984-0-\331\201\331\201\331\201.mp4"
	deleted:    "storage/posts/videos/1772208506469-0-\330\253\330\253\330\253\330\253.mp4"
	deleted:    "storage/posts/videos/1772208627195-0-\330\264\330\264\330\264\330\264.mp4"
	deleted:    "storage/posts/videos/1772208646258-0-\330\250\330\263\333\214\330\263.mp4"
	deleted:    storage/posts/videos/1772208704438-0-111.mp4
	deleted:    "storage/posts/videos/1772211057722-0-\330\266\330\266\330\266.mp4"
	deleted:    "storage/posts/videos/1772211118907-0-\330\265\330\265\330\265\330\265.mp4"
	deleted:    "storage/posts/videos/1772211184550-0-\330\253\330\253\330\253.mp4"
	deleted:    "storage/posts/videos/1772211618341-0-\330\265\330\265\330\265\330\265.mp4"
	deleted:    storage/posts/videos/1772211740270-0-4444.mp4
This commit is contained in:
Amirreza
2026-07-05 15:59:26 +03:30
parent 06f6260df3
commit b3bb0d0ff3
306 changed files with 23083 additions and 23100 deletions

View File

@@ -1,383 +1,383 @@
const express = require("express");
const router = express.Router();
const academyController = require("../../../controllers/application/academy/academyControllers");
const multer = require("multer");
const path = require("path");
const fs = require("fs");
// const academyCategoryController = require("../../../controllers/application/academy/academyCategoryController");
// ==========================================
// ⚙️ تنظیمات اولیه و دایرکتوری‌ها
// ==========================================
// اطمینان از وجود دایرکتوری‌ها
const ensureDir = (dir) => {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
console.log("DEBUG: Created directory:", dir);
}
};
const BASE_DIR = process.cwd();
const courseVideoDir = path.join(BASE_DIR, "storage", "courses", "videos");
const courseImageDir = path.join(BASE_DIR, "storage", "courses", "images");
console.log("DEBUG: BASE_DIR:", BASE_DIR);
console.log("DEBUG: courseVideoDir:", courseVideoDir);
console.log("DEBUG: courseImageDir:", courseImageDir);
ensureDir(courseVideoDir);
ensureDir(courseImageDir);
// ==========================================
// 📁 تنظیمات آپلود فایل با Multer
// ==========================================
// تنظیمات ذخیره‌سازی فایل‌ها
const storage = multer.diskStorage({
destination: (req, file, cb) => {
console.log("DEBUG: Multer destination - fieldname:", file.fieldname);
// استفاده از دایرکتوری موقت برای آپلود اولیه
const tempDir = "/tmp/modstagram-uploads";
if (!fs.existsSync(tempDir)) {
fs.mkdirSync(tempDir, { recursive: true });
}
cb(null, tempDir);
},
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
const filename = uniqueSuffix + path.extname(file.originalname);
console.log("DEBUG: Generated filename:", filename);
cb(null, filename);
},
});
// تنظیمات Multer با محدودیت حجم 500 مگابایت
const upload = multer({
storage: storage,
limits: {
fileSize: 500 * 1024 * 1024, // 500 MB
},
});
// ==========================================
// 🏢 مسیرهای مربوط به آکادمی
// ==========================================
// دریافت اطلاعات آکادمی کاربر جاری
router.get("/", academyController.findAcademy);
// یافتن آکادمی با شناسه
router.post("/findAcademyById", academyController.findAcademyById);
// تکمیل پروفایل آکادمی
router.post("/academy/profile", academyController.academyProfile);
// ==========================================
// 📚 مسیرهای مدیریت دوره‌ها (Courses)
// ==========================================
// ایجاد دوره جدید
router.post("/academy/creat/course", academyController.creatCourse);
// ویرایش دوره
router.patch("/academy/update/course", academyController.updateCourse);
// حذف دوره (تغییر وضعیت به reject)
router.delete("/academy/delete/course", academyController.deleteCourse);
// دریافت لیست دوره‌های آکادمی جاری
router.get("/academy/get/course", academyController.getCourse);
// دریافت لیست همه دوره‌ها با فیلتر و صفحه‌بندی
router.get("/academy/get/curses", academyController.getCourses);
// دریافت دوره‌های یک آکادمی خاص
router.get("/academy/get/getAcademyCourse/:Id", academyController.getAcademyCourse);
// ==========================================
// 💳 مسیرهای پرداخت و مالی
// ==========================================
// پرداخت برای اشتراک پرو
router.post("/academy/course/payment", academyController.proPayment);
// کال‌بک درگاه پرداخت زرین‌پال (اشتراک پرو)
router.get("/academy/course/pro", academyController.handleCoursePaymentCallback);
// پرداخت برای خرید دوره
router.post("/academy/course/payment-web", academyController.coursePayment);
// کال‌بک درگاه پرداخت زرین‌پال (خرید دوره)
router.get("/academy/course/payment/verify", academyController.CoursePaymentCallback);
// ==========================================
// 🎬 مسیرهای محتوای دوره (ویدیوها و فایل‌ها)
// ==========================================
// دریافت محتوای دوره (ویدیوها)
router.get("/academy/course/content", academyController.getCourseContent);
// حذف ویدیو از دوره
router.delete("/academy/course/content/video", academyController.deleteCourseVideo);
// ==========================================
// 📹 مسیرهای آپلود ویدیو (۳ روش مختلف)
// ==========================================
// روش 1: آپلود معمولی با Multipart (با استفاده از Multer)
router.post(
"/academy/course/creat/video",
(req, res, next) => {
console.log("===== STEP 1: Route hit =====");
console.log("Content-Type:", req.headers["content-type"]);
next();
},
(req, res, next) => {
console.log("===== STEP 2: Before multer =====");
next();
},
(req, res, next) => {
// اجرای manual multer با try-catch
upload.single("video")(req, res, (err) => {
if (err) {
console.log("===== MULTER ERROR =====");
console.log("Error name:", err.name);
console.log("Error message:", err.message);
console.log("Full error:", err);
return res.status(400).json({
success: false,
message: `خطا در آپلود: ${err.message}`,
error: err.toString(),
});
}
console.log("===== STEP 3: Multer completed successfully =====");
next();
});
},
(req, res, next) => {
console.log("===== STEP 4: After multer =====");
console.log("req.file:", req.file);
console.log("req.body:", req.body);
if (!req.file) {
console.log("ERROR: No file in req.file!");
return res.status(400).json({
success: false,
message: "فایلی دریافت نشد",
});
}
next();
},
academyController.creatCourseVideo
);
// روش 2: آپلود با Base64 (برای فایل‌های کوچک)
router.post(
"/academy/course/creat/video-base64",
academyController.creatCourseVideoBase64
);
// روش 3: آپلود تکه‌تکه (Chunk Upload) - مناسب برای فایل‌های بزرگ
// دریافت هر تکه از ویدیو
router.post(
"/academy/course/creat/video-chunk",
academyController.creatCourseVideoChunk
);
// ادغام تکه‌ها بعد از اتمام آپلود
router.post(
"/academy/course/creat/video-chunk/merge",
academyController.mergeVideoChunks
);
// بررسی وضعیت آپلود (برای قابلیت Resume)
router.get("/academy/course/upload-status", academyController.getUploadStatus);
// ==========================================
// ❤️ مسیرهای لایک و تعامل
// ==========================================
// لایک کردن محتوای دوره
router.post("/academy/course/like", academyController.likeCourseContent);
// حذف لایک (دیسلایک)
router.post("/academy/course/dislike", academyController.dontLikeCourseContent);
// بررسی وضعیت لایک کاربر
router.post("/academy/course/is-like", academyController.isLikeCourseContent);
// دریافت تعداد لایک‌های یک دوره
router.get(
"/academy/course/likes-count/:courseId",
academyController.getCourseLikesCount
);
// دریافت لیست دوره‌های لایک شده توسط کاربر
router.get(
"/academy/user/liked-courses",
academyController.getUserLikedCourses
);
// ==========================================
// 💬 مسیرهای کامنت و نظرات
// ==========================================
// دریافت تعداد کل کامنت‌های یک دوره
router.get(
"/course/:courseId/comments/count",
academyController.getTotalCommentsCount
);
// دریافت لیست کامنت‌های یک دوره
router.get("/course/:courseId/comments", academyController.getCourseComments);
// ایجاد کامنت جدید
router.post("/comment/create", academyController.createComment);
// تغییر وضعیت کامنت (تایید/رد)
router.patch(
"/comment/:commentId/status",
academyController.updateCommentStatus
);
// حذف کامنت
router.delete("/comment/:commentId/delete", academyController.deleteComment);
// ==========================================
// 🛒 مسیرهای دوره‌های خریداری شده
// ==========================================
// دریافت دوره‌های خریداری شده توسط کاربر جاری
router.get(
"/course/getUserPurchasedCourses",
academyController.getUserPurchasedCourses
);
// دریافت دوره‌های خریداری شده (با populate - روش بهینه)
router.get(
"/course/getUserPurchasedCoursesWithPopulate",
academyController.getUserPurchasedCoursesWithPopulate
);
// دریافت همه پرداخت‌های آکادمی
router.get(
"/course/getAllAcademyPayments",
academyController.getAllAcademyPayments
);
// بررسی خرید دوره توسط کاربر
router.get(
"/course/checkCoursePurchase/:courseId",
academyController.checkCoursePurchase
);
// ==========================================
// 📊 مسیرهای آمار و گزارشات (STATIC)
// ==========================================
// آمار پرداخت‌ها
router.get("/payments/stats", academyController.getPaymentStats);
// آمار دوره‌ها
router.get("/courses/stats", academyController.getCourseStats);
// آمار دوره‌های خریداری شده
router.get("/purchased/stats", academyController.getPurchasedStats);
// آمار آکادمی‌ها
router.get("/academies/stats", academyController.getAcademyStats);
// ==========================================
// ⚙️ مسیرهای تنظیمات (Settings)
// ==========================================
// دریافت همه تنظیمات
router.get("/settings/all", academyController.getAllSettings);
router.get("/settings", academyController.getAllSettings);
// به‌روزرسانی همه تنظیمات
router.put("/settings/all", academyController.updateAllSettings);
router.put("/settings", academyController.updateAllSettings);
// دریافت و ویرایش قیمت دوره‌ها
router.get("/settings/course-prices", academyController.getCoursePrices);
router.put("/settings/course-price", academyController.updateCoursePrice);
// دریافت و ویرایش مالیات
router.get("/settings/tax", academyController.getTax);
router.put("/settings/tax", academyController.updateTax);
// ==========================================
// 🏷️ مسیرهای دسته‌بندی آکادمی (Categories)
// ==========================================
// دریافت لیست دسته‌بندی‌ها (با فیلتر و صفحه‌بندی)
router.get('/categories', academyController.getAll);
// دریافت درخت دسته‌بندی (ساختار سلسله‌مراتبی)
router.get('/categories/tree', academyController.getTree);
// دریافت دسته‌بندی‌های ویژه (برای نمایش در هوم پیج)
router.get('/categories/featured', academyController.getFeatured);
// دریافت دسته‌بندی با اسلاگ (برای سئو و لینک‌های زیبا)
router.get('/categories/slug/:slug', academyController.getBySlug);
// دریافت یک دسته‌بندی با شناسه
router.get('/categories/:id', academyController.getOne);
// ایجاد دسته‌بندی جدید
router.post('/categories', academyController.create);
// ویرایش دسته‌بندی (هم PUT و هم PATCH پشتیبانی می‌شود)
router.put('/categories/:id', academyController.update);
router.patch('/categories/:id', academyController.update);
// حذف دسته‌بندی (سافت دیلیت - فقط غیرفعال می‌شود)
router.delete('/categories/:id', academyController.remove);
// حذف فیزیکی دسته‌بندی (به همراه query string permanent=true)
router.delete('/categories/:id/permanent', (req, res) => {
req.query.permanent = 'true';
academyController.remove(req, res);
});
// تغییر وضعیت دسته‌بندی (فعال/غیرفعال)
router.patch('/categories/:id/status', academyController.toggleStatus);
// افزایش تعداد دوره‌های دسته‌بندی (هر بار یک دوره جدید اضافه می‌شود)
router.post('/categories/:id/increment-count', academyController.incrementCourseCount);
// ==========================================
// 👑 مسیرهای مدیریتی (پنل ادمین)
// ==========================================
// ------ مدیریت پرداخت‌ها ------
router.get("/payments", academyController.getAllPayments);
router.put("/payments/status", academyController.updatePaymentStatus);
// ------ مدیریت دوره‌ها ------
router.get("/courses", academyController.getAllCourses);
router.get("/courses/:id", academyController.getCourseById);
router.put("/courses/:id", academyController.updateCourse);
router.post("/courses", academyController.createCourse);
router.put("/academy/courses/status", academyController.updateCourseStatus);
router.delete("/courses/:courseId", academyController.admindeleteCourse);
// ------ مدیریت دوره‌های خریداری شده ------
router.get("/purchased", academyController.getAllPurchasedCourses);
// ------ مدیریت آکادمی‌ها ------
router.get("/academies", academyController.getAllAcademies);
router.get("/academies/:id", academyController.getAcademyById);
router.put("/academies/:id", academyController.updateAcademy);
router.post("/academies", academyController.createAcademy);
router.put("/academies/status", academyController.updateAcademyStatus);
router.delete("/academies/:id", academyController.deleteAcademy);
// ==========================================
// 📤 خروجی روت‌ها
// ==========================================
const express = require("express");
const router = express.Router();
const academyController = require("../../../controllers/application/academy/academyControllers");
const multer = require("multer");
const path = require("path");
const fs = require("fs");
// const academyCategoryController = require("../../../controllers/application/academy/academyCategoryController");
// ==========================================
// ⚙️ تنظیمات اولیه و دایرکتوری‌ها
// ==========================================
// اطمینان از وجود دایرکتوری‌ها
const ensureDir = (dir) => {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
console.log("DEBUG: Created directory:", dir);
}
};
const BASE_DIR = process.cwd();
const courseVideoDir = path.join(BASE_DIR, "storage", "courses", "videos");
const courseImageDir = path.join(BASE_DIR, "storage", "courses", "images");
console.log("DEBUG: BASE_DIR:", BASE_DIR);
console.log("DEBUG: courseVideoDir:", courseVideoDir);
console.log("DEBUG: courseImageDir:", courseImageDir);
ensureDir(courseVideoDir);
ensureDir(courseImageDir);
// ==========================================
// 📁 تنظیمات آپلود فایل با Multer
// ==========================================
// تنظیمات ذخیره‌سازی فایل‌ها
const storage = multer.diskStorage({
destination: (req, file, cb) => {
console.log("DEBUG: Multer destination - fieldname:", file.fieldname);
// استفاده از دایرکتوری موقت برای آپلود اولیه
const tempDir = "/tmp/modstagram-uploads";
if (!fs.existsSync(tempDir)) {
fs.mkdirSync(tempDir, { recursive: true });
}
cb(null, tempDir);
},
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
const filename = uniqueSuffix + path.extname(file.originalname);
console.log("DEBUG: Generated filename:", filename);
cb(null, filename);
},
});
// تنظیمات Multer با محدودیت حجم 500 مگابایت
const upload = multer({
storage: storage,
limits: {
fileSize: 500 * 1024 * 1024, // 500 MB
},
});
// ==========================================
// 🏢 مسیرهای مربوط به آکادمی
// ==========================================
// دریافت اطلاعات آکادمی کاربر جاری
router.get("/", academyController.findAcademy);
// یافتن آکادمی با شناسه
router.post("/findAcademyById", academyController.findAcademyById);
// تکمیل پروفایل آکادمی
router.post("/academy/profile", academyController.academyProfile);
// ==========================================
// 📚 مسیرهای مدیریت دوره‌ها (Courses)
// ==========================================
// ایجاد دوره جدید
router.post("/academy/creat/course", academyController.creatCourse);
// ویرایش دوره
router.patch("/academy/update/course", academyController.updateCourse);
// حذف دوره (تغییر وضعیت به reject)
router.delete("/academy/delete/course", academyController.deleteCourse);
// دریافت لیست دوره‌های آکادمی جاری
router.get("/academy/get/course", academyController.getCourse);
// دریافت لیست همه دوره‌ها با فیلتر و صفحه‌بندی
router.get("/academy/get/curses", academyController.getCourses);
// دریافت دوره‌های یک آکادمی خاص
router.get("/academy/get/getAcademyCourse/:Id", academyController.getAcademyCourse);
// ==========================================
// 💳 مسیرهای پرداخت و مالی
// ==========================================
// پرداخت برای اشتراک پرو
router.post("/academy/course/payment", academyController.proPayment);
// کال‌بک درگاه پرداخت زرین‌پال (اشتراک پرو)
router.get("/academy/course/pro", academyController.handleCoursePaymentCallback);
// پرداخت برای خرید دوره
router.post("/academy/course/payment-web", academyController.coursePayment);
// کال‌بک درگاه پرداخت زرین‌پال (خرید دوره)
router.get("/academy/course/payment/verify", academyController.CoursePaymentCallback);
// ==========================================
// 🎬 مسیرهای محتوای دوره (ویدیوها و فایل‌ها)
// ==========================================
// دریافت محتوای دوره (ویدیوها)
router.get("/academy/course/content", academyController.getCourseContent);
// حذف ویدیو از دوره
router.delete("/academy/course/content/video", academyController.deleteCourseVideo);
// ==========================================
// 📹 مسیرهای آپلود ویدیو (۳ روش مختلف)
// ==========================================
// روش 1: آپلود معمولی با Multipart (با استفاده از Multer)
router.post(
"/academy/course/creat/video",
(req, res, next) => {
console.log("===== STEP 1: Route hit =====");
console.log("Content-Type:", req.headers["content-type"]);
next();
},
(req, res, next) => {
console.log("===== STEP 2: Before multer =====");
next();
},
(req, res, next) => {
// اجرای manual multer با try-catch
upload.single("video")(req, res, (err) => {
if (err) {
console.log("===== MULTER ERROR =====");
console.log("Error name:", err.name);
console.log("Error message:", err.message);
console.log("Full error:", err);
return res.status(400).json({
success: false,
message: `خطا در آپلود: ${err.message}`,
error: err.toString(),
});
}
console.log("===== STEP 3: Multer completed successfully =====");
next();
});
},
(req, res, next) => {
console.log("===== STEP 4: After multer =====");
console.log("req.file:", req.file);
console.log("req.body:", req.body);
if (!req.file) {
console.log("ERROR: No file in req.file!");
return res.status(400).json({
success: false,
message: "فایلی دریافت نشد",
});
}
next();
},
academyController.creatCourseVideo
);
// روش 2: آپلود با Base64 (برای فایل‌های کوچک)
router.post(
"/academy/course/creat/video-base64",
academyController.creatCourseVideoBase64
);
// روش 3: آپلود تکه‌تکه (Chunk Upload) - مناسب برای فایل‌های بزرگ
// دریافت هر تکه از ویدیو
router.post(
"/academy/course/creat/video-chunk",
academyController.creatCourseVideoChunk
);
// ادغام تکه‌ها بعد از اتمام آپلود
router.post(
"/academy/course/creat/video-chunk/merge",
academyController.mergeVideoChunks
);
// بررسی وضعیت آپلود (برای قابلیت Resume)
router.get("/academy/course/upload-status", academyController.getUploadStatus);
// ==========================================
// ❤️ مسیرهای لایک و تعامل
// ==========================================
// لایک کردن محتوای دوره
router.post("/academy/course/like", academyController.likeCourseContent);
// حذف لایک (دیسلایک)
router.post("/academy/course/dislike", academyController.dontLikeCourseContent);
// بررسی وضعیت لایک کاربر
router.post("/academy/course/is-like", academyController.isLikeCourseContent);
// دریافت تعداد لایک‌های یک دوره
router.get(
"/academy/course/likes-count/:courseId",
academyController.getCourseLikesCount
);
// دریافت لیست دوره‌های لایک شده توسط کاربر
router.get(
"/academy/user/liked-courses",
academyController.getUserLikedCourses
);
// ==========================================
// 💬 مسیرهای کامنت و نظرات
// ==========================================
// دریافت تعداد کل کامنت‌های یک دوره
router.get(
"/course/:courseId/comments/count",
academyController.getTotalCommentsCount
);
// دریافت لیست کامنت‌های یک دوره
router.get("/course/:courseId/comments", academyController.getCourseComments);
// ایجاد کامنت جدید
router.post("/comment/create", academyController.createComment);
// تغییر وضعیت کامنت (تایید/رد)
router.patch(
"/comment/:commentId/status",
academyController.updateCommentStatus
);
// حذف کامنت
router.delete("/comment/:commentId/delete", academyController.deleteComment);
// ==========================================
// 🛒 مسیرهای دوره‌های خریداری شده
// ==========================================
// دریافت دوره‌های خریداری شده توسط کاربر جاری
router.get(
"/course/getUserPurchasedCourses",
academyController.getUserPurchasedCourses
);
// دریافت دوره‌های خریداری شده (با populate - روش بهینه)
router.get(
"/course/getUserPurchasedCoursesWithPopulate",
academyController.getUserPurchasedCoursesWithPopulate
);
// دریافت همه پرداخت‌های آکادمی
router.get(
"/course/getAllAcademyPayments",
academyController.getAllAcademyPayments
);
// بررسی خرید دوره توسط کاربر
router.get(
"/course/checkCoursePurchase/:courseId",
academyController.checkCoursePurchase
);
// ==========================================
// 📊 مسیرهای آمار و گزارشات (STATIC)
// ==========================================
// آمار پرداخت‌ها
router.get("/payments/stats", academyController.getPaymentStats);
// آمار دوره‌ها
router.get("/courses/stats", academyController.getCourseStats);
// آمار دوره‌های خریداری شده
router.get("/purchased/stats", academyController.getPurchasedStats);
// آمار آکادمی‌ها
router.get("/academies/stats", academyController.getAcademyStats);
// ==========================================
// ⚙️ مسیرهای تنظیمات (Settings)
// ==========================================
// دریافت همه تنظیمات
router.get("/settings/all", academyController.getAllSettings);
router.get("/settings", academyController.getAllSettings);
// به‌روزرسانی همه تنظیمات
router.put("/settings/all", academyController.updateAllSettings);
router.put("/settings", academyController.updateAllSettings);
// دریافت و ویرایش قیمت دوره‌ها
router.get("/settings/course-prices", academyController.getCoursePrices);
router.put("/settings/course-price", academyController.updateCoursePrice);
// دریافت و ویرایش مالیات
router.get("/settings/tax", academyController.getTax);
router.put("/settings/tax", academyController.updateTax);
// ==========================================
// 🏷️ مسیرهای دسته‌بندی آکادمی (Categories)
// ==========================================
// دریافت لیست دسته‌بندی‌ها (با فیلتر و صفحه‌بندی)
router.get('/categories', academyController.getAll);
// دریافت درخت دسته‌بندی (ساختار سلسله‌مراتبی)
router.get('/categories/tree', academyController.getTree);
// دریافت دسته‌بندی‌های ویژه (برای نمایش در هوم پیج)
router.get('/categories/featured', academyController.getFeatured);
// دریافت دسته‌بندی با اسلاگ (برای سئو و لینک‌های زیبا)
router.get('/categories/slug/:slug', academyController.getBySlug);
// دریافت یک دسته‌بندی با شناسه
router.get('/categories/:id', academyController.getOne);
// ایجاد دسته‌بندی جدید
router.post('/categories', academyController.create);
// ویرایش دسته‌بندی (هم PUT و هم PATCH پشتیبانی می‌شود)
router.put('/categories/:id', academyController.update);
router.patch('/categories/:id', academyController.update);
// حذف دسته‌بندی (سافت دیلیت - فقط غیرفعال می‌شود)
router.delete('/categories/:id', academyController.remove);
// حذف فیزیکی دسته‌بندی (به همراه query string permanent=true)
router.delete('/categories/:id/permanent', (req, res) => {
req.query.permanent = 'true';
academyController.remove(req, res);
});
// تغییر وضعیت دسته‌بندی (فعال/غیرفعال)
router.patch('/categories/:id/status', academyController.toggleStatus);
// افزایش تعداد دوره‌های دسته‌بندی (هر بار یک دوره جدید اضافه می‌شود)
router.post('/categories/:id/increment-count', academyController.incrementCourseCount);
// ==========================================
// 👑 مسیرهای مدیریتی (پنل ادمین)
// ==========================================
// ------ مدیریت پرداخت‌ها ------
router.get("/payments", academyController.getAllPayments);
router.put("/payments/status", academyController.updatePaymentStatus);
// ------ مدیریت دوره‌ها ------
router.get("/courses", academyController.getAllCourses);
router.get("/courses/:id", academyController.getCourseById);
router.put("/courses/:id", academyController.updateCourse);
router.post("/courses", academyController.createCourse);
router.put("/academy/courses/status", academyController.updateCourseStatus);
router.delete("/courses/:courseId", academyController.admindeleteCourse);
// ------ مدیریت دوره‌های خریداری شده ------
router.get("/purchased", academyController.getAllPurchasedCourses);
// ------ مدیریت آکادمی‌ها ------
router.get("/academies", academyController.getAllAcademies);
router.get("/academies/:id", academyController.getAcademyById);
router.put("/academies/:id", academyController.updateAcademy);
router.post("/academies", academyController.createAcademy);
router.put("/academies/status", academyController.updateAcademyStatus);
router.delete("/academies/:id", academyController.deleteAcademy);
// ==========================================
// 📤 خروجی روت‌ها
// ==========================================
module.exports = router;