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,220 +1,220 @@
/* eslint-disable camelcase */
const { ProvinceModel, CityModel } = require('../../../models/StateCity')
const ProjectModel = require('../../../models/ProjectModel')
const UserModel = require('../../../models/UserModel')
const { check, validationResult } = require('express-validator')
const jwt = require('jsonwebtoken')
const createProjectValidationRules = () => {
return [
check('title').notEmpty().withMessage('عنوان نمی‌تواند خالی باشد'),
check('expertise').notEmpty().withMessage('تخصص نمی‌تواند خالی باشد'),
check('gender')
.isIn(['male', 'female'])
.withMessage('جنسیت باید male یا female باشد'),
check('age').notEmpty().withMessage('سن نمی‌تواند خالی باشد'),
check('conversation_projects')
.notEmpty()
.withMessage('پروژه‌های مکالمه نمی‌تواند خالی باشد')
.isBoolean()
.withMessage('مقدار پروژه‌های مکالمه باید یک مقدار boolean باشد'),
check('province').notEmpty().withMessage('استان نمی‌تواند خالی باشد'),
check('city').notEmpty().withMessage('شهر نمی‌تواند خالی باشد'),
check('offer_time')
.notEmpty()
.withMessage('زمان پروژه نمی‌تواند خالی باشد'),
check('offer_price')
.notEmpty()
.withMessage('قیمت پیشنهادی نمی‌تواند خالی باشد'),
check('description')
.notEmpty()
.withMessage('توضیحات نمی‌تواند خالی باشد'),
check('project_type')
.notEmpty()
.withMessage('نوع پروژه نمی‌تواند خالی باشد')
.isIn(['free', 'normal', 'force', 'highlight'])
.withMessage('نوع پروژه باید normal یا force یا highlight باشد')
]
}
const createProject = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const user = await UserModel.findById(decodedToken.id)
if (!user) {
return res.status(422).json({
error: true,
message: 'شما دسترسی به این بخش ندارید'
})
}
if (user.is_verified !== 'verified') {
return res.status(422).json({
error: true,
message: 'مدارک شما تایید نشده است'
})
}
// اعتبارسنجی درخواست
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() })
}
const {
title,
expertise,
sub_expertise,
gender,
age,
conversation_projects,
province,
city,
offer_time,
offer_price,
description,
project_type,
public_status,
created_for_user,
number_of_person
} = req.body
if (
!title ||
!expertise ||
!age ||
conversation_projects === null ||
!province ||
!city ||
!offer_time ||
!offer_price ||
!description ||
!project_type
) {
return res.status(422).json({
error: true,
message: 'اطلاعات ارسالی اشتباه است'
})
}
const provinceFind = await ProvinceModel.findOne(
{ id: province },
{ _id: 0 }
)
const cityFind = await CityModel.findOne({ id: city })
// اگر پروژه برای یک کاربر خاص باید ساخته شود
if (public_status && public_status === 'private' && created_for_user) {
const createdUser = await UserModel.findById(created_for_user)
if (!createdUser) {
return res.status(422).json({
error: true, message: 'کاربر مورد نظر برای ساخت پروژه یافت نشد'
})
}
// ایجاد شیء پروژه
const projectData = {
title,
expertise,
sub_expertise,
gender,
age,
conversation_projects,
province,
city,
offer_time,
offer_price,
description,
project_type,
creator_id: user._id, // ارتباط با کاربر
public_status,
created_for_user
}
// ساخت شیء پروژه
const project = new ProjectModel(projectData)
// ذخیره کردن رکورد در پایگاه داده
await project.save()
res.status(201).json({ message: 'پروژه با موفقیت ساخته شد', id: project._id }
)
} else {
if (number_of_person > 1) {
for (let i = 1; i <= number_of_person; i++) {
let currentProjectType
if (project_type === 'free' && i === 1) {
currentProjectType = 'free'
} else if (project_type === 'highlight' || project_type === 'force') {
currentProjectType = project_type
} else {
currentProjectType = 'normal'
}
const newProject = new ProjectModel({
title: `${title}_${i}`,
expertise,
sub_expertise,
gender,
age,
conversation_projects,
province: provinceFind,
city: cityFind,
offer_time,
offer_price,
description,
creator_id: user._id, // ارتباط با کاربر
project_type: currentProjectType,
public_status,
created_for_user
})
// ذخیره کردن رکورد در پایگاه داده
await newProject.save()
}
res.status(201).json({
message: 'پروژه‌ها با موفقیت ساخته شدند'
})
} else {
const project = new ProjectModel({
title,
expertise,
sub_expertise,
gender,
age,
conversation_projects,
province: provinceFind,
city: cityFind,
offer_time,
offer_price,
description,
creator_id: user._id, // ارتباط با کاربر
project_type
})
// ذخیره کردن رکورد در پایگاه داده
await project.save()
res.status(201).json({
message: 'پروژه با موفقیت ساخته شد',
id: project._id
})
}
}
} catch (error) {
next(error)
}
}
module.exports = {
createProjectValidationRules,
createProject
}
/* eslint-disable camelcase */
const { ProvinceModel, CityModel } = require('../../../models/StateCity')
const ProjectModel = require('../../../models/ProjectModel')
const UserModel = require('../../../models/UserModel')
const { check, validationResult } = require('express-validator')
const jwt = require('jsonwebtoken')
const createProjectValidationRules = () => {
return [
check('title').notEmpty().withMessage('عنوان نمی‌تواند خالی باشد'),
check('expertise').notEmpty().withMessage('تخصص نمی‌تواند خالی باشد'),
check('gender')
.isIn(['male', 'female'])
.withMessage('جنسیت باید male یا female باشد'),
check('age').notEmpty().withMessage('سن نمی‌تواند خالی باشد'),
check('conversation_projects')
.notEmpty()
.withMessage('پروژه‌های مکالمه نمی‌تواند خالی باشد')
.isBoolean()
.withMessage('مقدار پروژه‌های مکالمه باید یک مقدار boolean باشد'),
check('province').notEmpty().withMessage('استان نمی‌تواند خالی باشد'),
check('city').notEmpty().withMessage('شهر نمی‌تواند خالی باشد'),
check('offer_time')
.notEmpty()
.withMessage('زمان پروژه نمی‌تواند خالی باشد'),
check('offer_price')
.notEmpty()
.withMessage('قیمت پیشنهادی نمی‌تواند خالی باشد'),
check('description')
.notEmpty()
.withMessage('توضیحات نمی‌تواند خالی باشد'),
check('project_type')
.notEmpty()
.withMessage('نوع پروژه نمی‌تواند خالی باشد')
.isIn(['free', 'normal', 'force', 'highlight'])
.withMessage('نوع پروژه باید normal یا force یا highlight باشد')
]
}
const createProject = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const user = await UserModel.findById(decodedToken.id)
if (!user) {
return res.status(422).json({
error: true,
message: 'شما دسترسی به این بخش ندارید'
})
}
if (user.is_verified !== 'verified') {
return res.status(422).json({
error: true,
message: 'مدارک شما تایید نشده است'
})
}
// اعتبارسنجی درخواست
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() })
}
const {
title,
expertise,
sub_expertise,
gender,
age,
conversation_projects,
province,
city,
offer_time,
offer_price,
description,
project_type,
public_status,
created_for_user,
number_of_person
} = req.body
if (
!title ||
!expertise ||
!age ||
conversation_projects === null ||
!province ||
!city ||
!offer_time ||
!offer_price ||
!description ||
!project_type
) {
return res.status(422).json({
error: true,
message: 'اطلاعات ارسالی اشتباه است'
})
}
const provinceFind = await ProvinceModel.findOne(
{ id: province },
{ _id: 0 }
)
const cityFind = await CityModel.findOne({ id: city })
// اگر پروژه برای یک کاربر خاص باید ساخته شود
if (public_status && public_status === 'private' && created_for_user) {
const createdUser = await UserModel.findById(created_for_user)
if (!createdUser) {
return res.status(422).json({
error: true, message: 'کاربر مورد نظر برای ساخت پروژه یافت نشد'
})
}
// ایجاد شیء پروژه
const projectData = {
title,
expertise,
sub_expertise,
gender,
age,
conversation_projects,
province,
city,
offer_time,
offer_price,
description,
project_type,
creator_id: user._id, // ارتباط با کاربر
public_status,
created_for_user
}
// ساخت شیء پروژه
const project = new ProjectModel(projectData)
// ذخیره کردن رکورد در پایگاه داده
await project.save()
res.status(201).json({ message: 'پروژه با موفقیت ساخته شد', id: project._id }
)
} else {
if (number_of_person > 1) {
for (let i = 1; i <= number_of_person; i++) {
let currentProjectType
if (project_type === 'free' && i === 1) {
currentProjectType = 'free'
} else if (project_type === 'highlight' || project_type === 'force') {
currentProjectType = project_type
} else {
currentProjectType = 'normal'
}
const newProject = new ProjectModel({
title: `${title}_${i}`,
expertise,
sub_expertise,
gender,
age,
conversation_projects,
province: provinceFind,
city: cityFind,
offer_time,
offer_price,
description,
creator_id: user._id, // ارتباط با کاربر
project_type: currentProjectType,
public_status,
created_for_user
})
// ذخیره کردن رکورد در پایگاه داده
await newProject.save()
}
res.status(201).json({
message: 'پروژه‌ها با موفقیت ساخته شدند'
})
} else {
const project = new ProjectModel({
title,
expertise,
sub_expertise,
gender,
age,
conversation_projects,
province: provinceFind,
city: cityFind,
offer_time,
offer_price,
description,
creator_id: user._id, // ارتباط با کاربر
project_type
})
// ذخیره کردن رکورد در پایگاه داده
await project.save()
res.status(201).json({
message: 'پروژه با موفقیت ساخته شد',
id: project._id
})
}
}
} catch (error) {
next(error)
}
}
module.exports = {
createProjectValidationRules,
createProject
}

View File

@@ -1,406 +1,406 @@
/* eslint-disable camelcase */
const { default: mongoose } = require('mongoose')
const ProjectModel = require('../../../models/ProjectModel')
const RequestModel = require('../../../models/RequestModel')
const UserModel = require('../../../models/UserModel')
const jwt = require('jsonwebtoken')
const calculateRemainingTime = (milliseconds) => {
const days = Math.floor(milliseconds / (1000 * 60 * 60 * 24))
const hours = Math.floor((milliseconds % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
return `${days} روز و ${hours} ساعت`
}
const getProjects = async (req, res, next) => {
try {
// eslint-disable-next-line no-unused-vars
const { expertise, page = 1, limit = 10, most_price, most_requests, age, gender } = req.query
// ساخت فیلتر برای استفاده در جستجوی MongoDB
const filter = {
payment_status: 'done',
status: 'accepted',
public_status: 'public',
$or: [
{ isExpired: false }, // پروژه‌هایی که isExpired برابر با false است
{ isExpired: { $exists: false } } // پروژه‌هایی که فیلد isExpired وجود ندارد
]
}
if (expertise) {
filter.expertise = expertise
}
if (age) {
filter.age = age
}
if (gender) {
filter.gender = gender
}
// استفاده از مدل پیجینیت شده برای دریافت نتایج صفحه‌بندی شده
if (most_price || most_requests) {
// دریافت لیست پروژه‌ها با استفاده از فیلتر و گزینه‌های صفحه‌بندی
const options = {
page: parseInt(page), // تبدیل صفحه به عدد صحیح
limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح
sort: most_price === 'true' ? { offer_price: -1 } : { requested_users: 'desc' }
}
const projects = await ProjectModel.paginate(filter, options)
const newProj = projects.docs
res.status(200).json({
projects: newProj,
totalPages: projects.totalPages, // ارسال تعداد کل صفحات
totalItems: projects.totalDocs // ارسال تعداد کل آیتم‌ها
})
} else {
// دریافت لیست پروژه‌ها با استفاده از فیلتر و گزینه‌های صفحه‌بندی
const options = {
page: parseInt(page), // تبدیل صفحه به عدد صحیح
limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح
sort: { acceptedAt: -1, createdAt: -1 } // مرتب‌سازی بر اساس acceptedAt و سپس createdAt
}
const projects = await ProjectModel.paginate(filter, options)
const newProj = projects.docs
res.status(200).json({
projects: newProj,
totalPages: projects.totalPages, // ارسال تعداد کل صفحات
totalItems: projects.totalDocs // ارسال تعداد کل آیتم‌ها
})
}
} catch (error) {
next(error)
}
// try {
// const token = req.header('Authorization').split(' ')[1]
// if (!token) return res.status(401).send('Access Denied')
// // eslint-disable-next-line no-unused-vars
// const decodedToken = jwt.verify(token, process.env.APP_SECRET)
// const { expertise, page = 1, limit = 10 } = req.query // افزودن پارامترهای صفحه‌بندی به درخواست
// // ساخت فیلتر برای استفاده در جستجوی MongoDB
// const filter = {
// payment_status: 'done',
// status: 'accepted',
// public_status: 'public'
// } // افزودن شرط‌های دیگر برای فیلتر
// if (expertise) {
// filter.expertise = expertise
// }
// // استفاده از مدل پیجینیت شده برای دریافت نتایج صفحه‌بندی شده
// const options = {
// page: parseInt(page), // تبدیل صفحه به عدد صحیح
// limit: parseInt(limit) // تبدیل محدودیت به عدد صحیح
// }
// // دریافت لیست پروژه‌ها با استفاده از فیلتر و گزینه‌های صفحه‌بندی
// const projects = await ProjectModel.paginate(filter, options)
// // تبدیل نتایج به فرمت مورد نیاز
// const projectsWithUserInfo = await Promise.all(projects.docs.map(async project => {
// const creator = await UserModel.findById(project.creator_id).select('first_name last_name user_name user_type is_verified profile_image gender province city rate')
// const projectWithUserInfo = {
// ...project.toJSON(), // تبدیل آبجکت پروژه به JSON
// creator // اضافه کردن اطلاعات کاربر به آبجکت پروژه
// }
// // محاسبه مدت زمان باقی‌مانده برای هر پروژه
// const currentTime = new Date()
// const projectCreatedAt = new Date(project.createdAt)
// const timeDiff = project.offer_time * 24 * 60 * 60 * 1000 - (currentTime - projectCreatedAt)
// const remainingTime = calculateRemainingTime(timeDiff)
// projectWithUserInfo.remainingTime = remainingTime
// return projectWithUserInfo
// }))
// res.status(200).json({
// projects: projectsWithUserInfo,
// totalPages: projects.totalPages, // ارسال تعداد کل صفحات
// totalItems: projects.totalDocs // ارسال تعداد کل آیتم‌ها
// })
// } catch (error) {
// next(error)
// }
}
const getUserProjects = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const user_id = req.query.user_id
// eslint-disable-next-line no-unused-vars
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
// const userReqId = decodedToken.id
if (!mongoose.Types.ObjectId.isValid(user_id)) {
return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' })
}
const user = await UserModel.findById(user_id)
if (!user) {
return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' })
}
const response = {}
if (user.user_type === 'user') {
const options = {
page: req.query.page || 1, // صفحه پیش‌فرض ۱
limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه
sort: { createdAt: -1 }
}
// پیجینیشن بر روی لیست پروژه‌های کاربر اعمال می‌شود
const projects = await ProjectModel.paginate(
{ selected_user: user._id, status: 'done' }, // فیلتر
options // گزینه‌های پیجینیشن
)
response.projects = projects.docs
response.totalPages = projects.totalPages // ارسال تعداد کل صفحات
response.totalItems = projects.totalDocs // ارسال تعداد کل آیتم‌ها
response.allProjectsCount = await ProjectModel.countDocuments({ selected_user: user._id })
const completedProjects = await Promise.all([
ProjectModel.countDocuments({ selected_user: user._id, status: 'done' })
])
response.successfulProjects = completedProjects
} else {
const options = {
page: req.query.page || 1, // صفحه پیش‌فرض ۱
limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه
sort: { createdAt: -1 }
}
// پیجینیشن بر روی لیست پروژه‌های کاربر اعمال می‌شود
const projects = await ProjectModel.paginate(
{ creator_id: user._id, status: { $in: ['done', 'accepted'] } }, // فیلتر
options // گزینه‌های پیجینیشن
)
response.projects = projects.docs
response.totalPages = projects.totalPages // ارسال تعداد کل صفحات
response.totalItems = projects.totalDocs
response.allProjectsCount = await ProjectModel.countDocuments({ creator_id: user._id, payment_status: 'done' })
// تعداد پروژه‌های موفق را به دست آورید
const successfulProjects = await ProjectModel.countDocuments({ creator_id: user._id, status: 'done' })
response.successfulProjects = successfulProjects
}
return res.status(200).json({ data: response })
} catch (error) {
next(error)
}
}
const getUserProjectsWeb = async (req, res, next) => {
try {
const user_id = req.query.user_id
// eslint-disable-next-line no-unused-vars
if (!mongoose.Types.ObjectId.isValid(user_id)) {
return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' })
}
const user = await UserModel.findById(user_id)
if (!user) {
return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' })
}
const data = {}
if (user.user_type === 'user') {
const options = {
page: req.query.page || 1, // صفحه پیش‌فرض ۱
limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه
sort: { createdAt: -1 }
}
// پیجینیشن بر روی لیست پروژه‌های کاربر اعمال می‌شود
const projects = await ProjectModel.paginate(
{ selected_user: user._id, status: 'done' }, // فیلتر
options // گزینه‌های پیجینیشن
)
data.projects = projects.docs
data.totalPages = projects.totalPages // ارسال تعداد کل صفحات
data.totalItems = projects.totalDocs // ارسال تعداد کل آیتم‌ها
data.allProjectsCount = await ProjectModel.countDocuments({ selected_user: user._id })
const completedProjects = await Promise.all([
ProjectModel.countDocuments({ selected_user: user._id, status: 'done' })
])
data.successfulProjects = completedProjects
} else {
const options = {
page: req.query.page || 1, // صفحه پیش‌فرض ۱
limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه
sort: { createdAt: -1 }
}
// پیجینیشن بر روی لیست پروژه‌های کاربر اعمال می‌شود
const projects = await ProjectModel.paginate(
{ creator_id: user._id, status: { $in: ['done', 'accepted'] } }, // فیلتر
options // گزینه‌های پیجینیشن
)
data.projects = projects.docs
data.totalPages = projects.totalPages // ارسال تعداد کل صفحات
data.totalItems = projects.totalDocs
data.allProjectsCount = await ProjectModel.countDocuments({ creator_id: user._id, payment_status: 'done' })
// تعداد پروژه‌های موفق را به دست آورید
const successfulProjects = await ProjectModel.countDocuments({ creator_id: user._id, status: 'done' })
data.successfulProjects = successfulProjects
}
return res.status(200).json(data)
} catch (error) {
next(error)
}
}
const getSingleProjects = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const userId = decodedToken.id
const projectId = req.params.projectId
const projectRequests = await RequestModel.find({ project: projectId })
.populate('user', 'price time user_level first_name last_name user_name is_verified user_score rate profile_image')
.sort({ status: 1 })
.lean()
const modifiedRequests = projectRequests.map(request => ({
...request,
time: request.user._id.toString() === userId ? request.time : null,
price: request.user._id.toString() === userId ? request.price : null
}))
const project = await ProjectModel.findById(projectId)
if (!project) {
return res.status(404).json({ message: 'پروژه مورد نظر یافت نشد' })
}
// محاسبه مبلغ باقیمانده و مجموع مبلغ پرداخت شده
// تابع محاسبه مبلغ پرداخت شده
const getTotalPaidAmount = (installments) => {
let totalPaidAmount = 0
installments.forEach(installment => {
totalPaidAmount += installment.amount
})
return totalPaidAmount
}
// تابع محاسبه مبلغ باقیمانده
const getRemainingAmount = (project) => {
const totalPaidAmount = getTotalPaidAmount(project.installments)
const remainingAmount = project.final_price - totalPaidAmount
return remainingAmount
}
const totalPaidAmount = getTotalPaidAmount(project.installments)
const remainingAmount = getRemainingAmount(project)
// اطلاعات کاربر سازنده را نیز دریافت کنید و به آبجکت پروژه اضافه کنید
const creator = await UserModel.findById(project.creator_id).select('first_name last_name user_name user_type is_verified profile_image gender province city rate')
const projectWithUserInfo = {
...project._doc,
creator // اضافه کردن اطلاعات کاربر به آبجکت پروژه
}
const selectedUser = await UserModel.findById(project.selected_user).select('_id user_name first_name last_name user_type is_verified profile_image expertise sub_expertise province city rate user_level user_score')
projectWithUserInfo.selected_user = selectedUser
// محاسبه مدت زمان باقی‌مانده برای پروژه
const currentTime = new Date()
const projectCreatedAt = new Date(project.createdAt)
const timeDiff = project.offer_time * 24 * 60 * 60 * 1000 - (currentTime - projectCreatedAt)
const remainingTime = calculateRemainingTime(timeDiff)
projectWithUserInfo.remainingTime = remainingTime
let projectDetails = projectWithUserInfo
if ((project.selected_user && project.selected_user.toString()) === userId || project.creator_id.toString() === userId) {
projectDetails = {
...projectWithUserInfo,
total_paid_amount: totalPaidAmount,
remaining_amount: remainingAmount
}
} else {
projectDetails =
projectWithUserInfo
}
// }
res.status(200).json({ project: projectDetails, projectRequests: modifiedRequests })
} catch (error) {
next(error)
}
}
const getSingleProjectsWeb = async (req, res, next) => {
try {
let userId = null
let token = req.header('Authorization')
if (token) {
try {
token = token.split(' ')[1]
if (token) {
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
userId = decodedToken.id
}
} catch (err) {
console.warn('Invalid token:', err.message)
}
}
const projectId = req.params.projectId
const projectRequests = await RequestModel.find({ project: projectId })
.populate('user', 'price time user_level first_name last_name user_name is_verified user_score rate profile_image')
.sort({ status: 1 })
.lean()
// اگر کاربر لاگین کرده باشد، زمان و قیمت را نشان بده، در غیر این صورت حذف کن
const modifiedRequests = projectRequests.map(request => ({
...request,
time: userId && request.user._id.toString() === userId ? request.time : null,
price: userId && request.user._id.toString() === userId ? request.price : null
}))
const project = await ProjectModel.findById(projectId)
if (!project) {
return res.status(404).json({ message: 'پروژه مورد نظر یافت نشد' })
}
// محاسبه مبلغ باقیمانده و مجموع مبلغ پرداخت شده
const getTotalPaidAmount = (installments) => {
return installments.reduce((total, installment) => total + installment.amount, 0)
}
const getRemainingAmount = (project) => {
return project.final_price - getTotalPaidAmount(project.installments)
}
const totalPaidAmount = getTotalPaidAmount(project.installments)
const remainingAmount = getRemainingAmount(project)
// دریافت اطلاعات سازنده پروژه
const creator = await UserModel.findById(project.creator_id).select('first_name last_name user_name user_type is_verified profile_image gender province city rate')
const projectWithUserInfo = {
...project._doc,
creator
}
// دریافت اطلاعات کاربر منتخب در صورت وجود
const selectedUser = await UserModel.findById(project.selected_user).select('_id user_name first_name last_name user_type is_verified profile_image expertise sub_expertise province city rate user_level user_score')
projectWithUserInfo.selected_user = selectedUser
// محاسبه زمان باقی‌مانده برای پیشنهادات پروژه
const currentTime = new Date()
const projectCreatedAt = new Date(project.createdAt)
const timeDiff = project.offer_time * 24 * 60 * 60 * 1000 - (currentTime - projectCreatedAt)
projectWithUserInfo.remainingTime = calculateRemainingTime(timeDiff)
let projectDetails = projectWithUserInfo
// فقط اگر کاربر احراز هویت شده باشد و سازنده یا برنده پروژه باشد، اطلاعات مالی را برگردان
if (userId && (project.selected_user?.toString() === userId || project.creator_id.toString() === userId)) {
projectDetails = {
...projectWithUserInfo,
total_paid_amount: totalPaidAmount,
remaining_amount: remainingAmount
}
}
res.status(200).json({ project: projectDetails, projectRequests: modifiedRequests })
} catch (error) {
next(error)
}
}
// const projectDetails = await ProjectModel.findById(projectId).populate('requested_users', 'price time user_level first_name last_name user_name is_verified user_score rate profile_image') // جزییات درخواست‌های کاربران
module.exports = {
getProjects, getSingleProjects, getUserProjects, getUserProjectsWeb, getSingleProjectsWeb
}
/* eslint-disable camelcase */
const { default: mongoose } = require('mongoose')
const ProjectModel = require('../../../models/ProjectModel')
const RequestModel = require('../../../models/RequestModel')
const UserModel = require('../../../models/UserModel')
const jwt = require('jsonwebtoken')
const calculateRemainingTime = (milliseconds) => {
const days = Math.floor(milliseconds / (1000 * 60 * 60 * 24))
const hours = Math.floor((milliseconds % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
return `${days} روز و ${hours} ساعت`
}
const getProjects = async (req, res, next) => {
try {
// eslint-disable-next-line no-unused-vars
const { expertise, page = 1, limit = 10, most_price, most_requests, age, gender } = req.query
// ساخت فیلتر برای استفاده در جستجوی MongoDB
const filter = {
payment_status: 'done',
status: 'accepted',
public_status: 'public',
$or: [
{ isExpired: false }, // پروژه‌هایی که isExpired برابر با false است
{ isExpired: { $exists: false } } // پروژه‌هایی که فیلد isExpired وجود ندارد
]
}
if (expertise) {
filter.expertise = expertise
}
if (age) {
filter.age = age
}
if (gender) {
filter.gender = gender
}
// استفاده از مدل پیجینیت شده برای دریافت نتایج صفحه‌بندی شده
if (most_price || most_requests) {
// دریافت لیست پروژه‌ها با استفاده از فیلتر و گزینه‌های صفحه‌بندی
const options = {
page: parseInt(page), // تبدیل صفحه به عدد صحیح
limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح
sort: most_price === 'true' ? { offer_price: -1 } : { requested_users: 'desc' }
}
const projects = await ProjectModel.paginate(filter, options)
const newProj = projects.docs
res.status(200).json({
projects: newProj,
totalPages: projects.totalPages, // ارسال تعداد کل صفحات
totalItems: projects.totalDocs // ارسال تعداد کل آیتم‌ها
})
} else {
// دریافت لیست پروژه‌ها با استفاده از فیلتر و گزینه‌های صفحه‌بندی
const options = {
page: parseInt(page), // تبدیل صفحه به عدد صحیح
limit: parseInt(limit), // تبدیل محدودیت به عدد صحیح
sort: { acceptedAt: -1, createdAt: -1 } // مرتب‌سازی بر اساس acceptedAt و سپس createdAt
}
const projects = await ProjectModel.paginate(filter, options)
const newProj = projects.docs
res.status(200).json({
projects: newProj,
totalPages: projects.totalPages, // ارسال تعداد کل صفحات
totalItems: projects.totalDocs // ارسال تعداد کل آیتم‌ها
})
}
} catch (error) {
next(error)
}
// try {
// const token = req.header('Authorization').split(' ')[1]
// if (!token) return res.status(401).send('Access Denied')
// // eslint-disable-next-line no-unused-vars
// const decodedToken = jwt.verify(token, process.env.APP_SECRET)
// const { expertise, page = 1, limit = 10 } = req.query // افزودن پارامترهای صفحه‌بندی به درخواست
// // ساخت فیلتر برای استفاده در جستجوی MongoDB
// const filter = {
// payment_status: 'done',
// status: 'accepted',
// public_status: 'public'
// } // افزودن شرط‌های دیگر برای فیلتر
// if (expertise) {
// filter.expertise = expertise
// }
// // استفاده از مدل پیجینیت شده برای دریافت نتایج صفحه‌بندی شده
// const options = {
// page: parseInt(page), // تبدیل صفحه به عدد صحیح
// limit: parseInt(limit) // تبدیل محدودیت به عدد صحیح
// }
// // دریافت لیست پروژه‌ها با استفاده از فیلتر و گزینه‌های صفحه‌بندی
// const projects = await ProjectModel.paginate(filter, options)
// // تبدیل نتایج به فرمت مورد نیاز
// const projectsWithUserInfo = await Promise.all(projects.docs.map(async project => {
// const creator = await UserModel.findById(project.creator_id).select('first_name last_name user_name user_type is_verified profile_image gender province city rate')
// const projectWithUserInfo = {
// ...project.toJSON(), // تبدیل آبجکت پروژه به JSON
// creator // اضافه کردن اطلاعات کاربر به آبجکت پروژه
// }
// // محاسبه مدت زمان باقی‌مانده برای هر پروژه
// const currentTime = new Date()
// const projectCreatedAt = new Date(project.createdAt)
// const timeDiff = project.offer_time * 24 * 60 * 60 * 1000 - (currentTime - projectCreatedAt)
// const remainingTime = calculateRemainingTime(timeDiff)
// projectWithUserInfo.remainingTime = remainingTime
// return projectWithUserInfo
// }))
// res.status(200).json({
// projects: projectsWithUserInfo,
// totalPages: projects.totalPages, // ارسال تعداد کل صفحات
// totalItems: projects.totalDocs // ارسال تعداد کل آیتم‌ها
// })
// } catch (error) {
// next(error)
// }
}
const getUserProjects = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const user_id = req.query.user_id
// eslint-disable-next-line no-unused-vars
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
// const userReqId = decodedToken.id
if (!mongoose.Types.ObjectId.isValid(user_id)) {
return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' })
}
const user = await UserModel.findById(user_id)
if (!user) {
return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' })
}
const response = {}
if (user.user_type === 'user') {
const options = {
page: req.query.page || 1, // صفحه پیش‌فرض ۱
limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه
sort: { createdAt: -1 }
}
// پیجینیشن بر روی لیست پروژه‌های کاربر اعمال می‌شود
const projects = await ProjectModel.paginate(
{ selected_user: user._id, status: 'done' }, // فیلتر
options // گزینه‌های پیجینیشن
)
response.projects = projects.docs
response.totalPages = projects.totalPages // ارسال تعداد کل صفحات
response.totalItems = projects.totalDocs // ارسال تعداد کل آیتم‌ها
response.allProjectsCount = await ProjectModel.countDocuments({ selected_user: user._id })
const completedProjects = await Promise.all([
ProjectModel.countDocuments({ selected_user: user._id, status: 'done' })
])
response.successfulProjects = completedProjects
} else {
const options = {
page: req.query.page || 1, // صفحه پیش‌فرض ۱
limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه
sort: { createdAt: -1 }
}
// پیجینیشن بر روی لیست پروژه‌های کاربر اعمال می‌شود
const projects = await ProjectModel.paginate(
{ creator_id: user._id, status: { $in: ['done', 'accepted'] } }, // فیلتر
options // گزینه‌های پیجینیشن
)
response.projects = projects.docs
response.totalPages = projects.totalPages // ارسال تعداد کل صفحات
response.totalItems = projects.totalDocs
response.allProjectsCount = await ProjectModel.countDocuments({ creator_id: user._id, payment_status: 'done' })
// تعداد پروژه‌های موفق را به دست آورید
const successfulProjects = await ProjectModel.countDocuments({ creator_id: user._id, status: 'done' })
response.successfulProjects = successfulProjects
}
return res.status(200).json({ data: response })
} catch (error) {
next(error)
}
}
const getUserProjectsWeb = async (req, res, next) => {
try {
const user_id = req.query.user_id
// eslint-disable-next-line no-unused-vars
if (!mongoose.Types.ObjectId.isValid(user_id)) {
return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' })
}
const user = await UserModel.findById(user_id)
if (!user) {
return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' })
}
const data = {}
if (user.user_type === 'user') {
const options = {
page: req.query.page || 1, // صفحه پیش‌فرض ۱
limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه
sort: { createdAt: -1 }
}
// پیجینیشن بر روی لیست پروژه‌های کاربر اعمال می‌شود
const projects = await ProjectModel.paginate(
{ selected_user: user._id, status: 'done' }, // فیلتر
options // گزینه‌های پیجینیشن
)
data.projects = projects.docs
data.totalPages = projects.totalPages // ارسال تعداد کل صفحات
data.totalItems = projects.totalDocs // ارسال تعداد کل آیتم‌ها
data.allProjectsCount = await ProjectModel.countDocuments({ selected_user: user._id })
const completedProjects = await Promise.all([
ProjectModel.countDocuments({ selected_user: user._id, status: 'done' })
])
data.successfulProjects = completedProjects
} else {
const options = {
page: req.query.page || 1, // صفحه پیش‌فرض ۱
limit: req.query.limit || 10, // حداکثر تعداد موارد برای هر صفحه
sort: { createdAt: -1 }
}
// پیجینیشن بر روی لیست پروژه‌های کاربر اعمال می‌شود
const projects = await ProjectModel.paginate(
{ creator_id: user._id, status: { $in: ['done', 'accepted'] } }, // فیلتر
options // گزینه‌های پیجینیشن
)
data.projects = projects.docs
data.totalPages = projects.totalPages // ارسال تعداد کل صفحات
data.totalItems = projects.totalDocs
data.allProjectsCount = await ProjectModel.countDocuments({ creator_id: user._id, payment_status: 'done' })
// تعداد پروژه‌های موفق را به دست آورید
const successfulProjects = await ProjectModel.countDocuments({ creator_id: user._id, status: 'done' })
data.successfulProjects = successfulProjects
}
return res.status(200).json(data)
} catch (error) {
next(error)
}
}
const getSingleProjects = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const userId = decodedToken.id
const projectId = req.params.projectId
const projectRequests = await RequestModel.find({ project: projectId })
.populate('user', 'price time user_level first_name last_name user_name is_verified user_score rate profile_image')
.sort({ status: 1 })
.lean()
const modifiedRequests = projectRequests.map(request => ({
...request,
time: request.user._id.toString() === userId ? request.time : null,
price: request.user._id.toString() === userId ? request.price : null
}))
const project = await ProjectModel.findById(projectId)
if (!project) {
return res.status(404).json({ message: 'پروژه مورد نظر یافت نشد' })
}
// محاسبه مبلغ باقیمانده و مجموع مبلغ پرداخت شده
// تابع محاسبه مبلغ پرداخت شده
const getTotalPaidAmount = (installments) => {
let totalPaidAmount = 0
installments.forEach(installment => {
totalPaidAmount += installment.amount
})
return totalPaidAmount
}
// تابع محاسبه مبلغ باقیمانده
const getRemainingAmount = (project) => {
const totalPaidAmount = getTotalPaidAmount(project.installments)
const remainingAmount = project.final_price - totalPaidAmount
return remainingAmount
}
const totalPaidAmount = getTotalPaidAmount(project.installments)
const remainingAmount = getRemainingAmount(project)
// اطلاعات کاربر سازنده را نیز دریافت کنید و به آبجکت پروژه اضافه کنید
const creator = await UserModel.findById(project.creator_id).select('first_name last_name user_name user_type is_verified profile_image gender province city rate')
const projectWithUserInfo = {
...project._doc,
creator // اضافه کردن اطلاعات کاربر به آبجکت پروژه
}
const selectedUser = await UserModel.findById(project.selected_user).select('_id user_name first_name last_name user_type is_verified profile_image expertise sub_expertise province city rate user_level user_score')
projectWithUserInfo.selected_user = selectedUser
// محاسبه مدت زمان باقی‌مانده برای پروژه
const currentTime = new Date()
const projectCreatedAt = new Date(project.createdAt)
const timeDiff = project.offer_time * 24 * 60 * 60 * 1000 - (currentTime - projectCreatedAt)
const remainingTime = calculateRemainingTime(timeDiff)
projectWithUserInfo.remainingTime = remainingTime
let projectDetails = projectWithUserInfo
if ((project.selected_user && project.selected_user.toString()) === userId || project.creator_id.toString() === userId) {
projectDetails = {
...projectWithUserInfo,
total_paid_amount: totalPaidAmount,
remaining_amount: remainingAmount
}
} else {
projectDetails =
projectWithUserInfo
}
// }
res.status(200).json({ project: projectDetails, projectRequests: modifiedRequests })
} catch (error) {
next(error)
}
}
const getSingleProjectsWeb = async (req, res, next) => {
try {
let userId = null
let token = req.header('Authorization')
if (token) {
try {
token = token.split(' ')[1]
if (token) {
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
userId = decodedToken.id
}
} catch (err) {
console.warn('Invalid token:', err.message)
}
}
const projectId = req.params.projectId
const projectRequests = await RequestModel.find({ project: projectId })
.populate('user', 'price time user_level first_name last_name user_name is_verified user_score rate profile_image')
.sort({ status: 1 })
.lean()
// اگر کاربر لاگین کرده باشد، زمان و قیمت را نشان بده، در غیر این صورت حذف کن
const modifiedRequests = projectRequests.map(request => ({
...request,
time: userId && request.user._id.toString() === userId ? request.time : null,
price: userId && request.user._id.toString() === userId ? request.price : null
}))
const project = await ProjectModel.findById(projectId)
if (!project) {
return res.status(404).json({ message: 'پروژه مورد نظر یافت نشد' })
}
// محاسبه مبلغ باقیمانده و مجموع مبلغ پرداخت شده
const getTotalPaidAmount = (installments) => {
return installments.reduce((total, installment) => total + installment.amount, 0)
}
const getRemainingAmount = (project) => {
return project.final_price - getTotalPaidAmount(project.installments)
}
const totalPaidAmount = getTotalPaidAmount(project.installments)
const remainingAmount = getRemainingAmount(project)
// دریافت اطلاعات سازنده پروژه
const creator = await UserModel.findById(project.creator_id).select('first_name last_name user_name user_type is_verified profile_image gender province city rate')
const projectWithUserInfo = {
...project._doc,
creator
}
// دریافت اطلاعات کاربر منتخب در صورت وجود
const selectedUser = await UserModel.findById(project.selected_user).select('_id user_name first_name last_name user_type is_verified profile_image expertise sub_expertise province city rate user_level user_score')
projectWithUserInfo.selected_user = selectedUser
// محاسبه زمان باقی‌مانده برای پیشنهادات پروژه
const currentTime = new Date()
const projectCreatedAt = new Date(project.createdAt)
const timeDiff = project.offer_time * 24 * 60 * 60 * 1000 - (currentTime - projectCreatedAt)
projectWithUserInfo.remainingTime = calculateRemainingTime(timeDiff)
let projectDetails = projectWithUserInfo
// فقط اگر کاربر احراز هویت شده باشد و سازنده یا برنده پروژه باشد، اطلاعات مالی را برگردان
if (userId && (project.selected_user?.toString() === userId || project.creator_id.toString() === userId)) {
projectDetails = {
...projectWithUserInfo,
total_paid_amount: totalPaidAmount,
remaining_amount: remainingAmount
}
}
res.status(200).json({ project: projectDetails, projectRequests: modifiedRequests })
} catch (error) {
next(error)
}
}
// const projectDetails = await ProjectModel.findById(projectId).populate('requested_users', 'price time user_level first_name last_name user_name is_verified user_score rate profile_image') // جزییات درخواست‌های کاربران
module.exports = {
getProjects, getSingleProjects, getUserProjects, getUserProjectsWeb, getSingleProjectsWeb
}

View File

@@ -1,41 +1,41 @@
const TypeAndPriceModel = require('../../../models/TypeAndPriceModel')
const jwt = require('jsonwebtoken')
const UserModel = require('../../../models/UserModel')
const getProjectTypes = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const userId = decodedToken.id
const user = await UserModel.findById(userId)
if (!user) {
return res.status(422).json({
error: true,
message: 'کاربر یافت نشد'
})
}
// درخواست انواع پروژه از دیتابیس
let projectTypes = await TypeAndPriceModel.find({}, 'name price')
// بررسی برای مواردی مانند پیدا نشدن انواع پروژه
if (!projectTypes) {
return res.status(404).json({ message: 'انواع پروژه یافت نشد.' })
}
// اگر کاربر درخواست رایگان روزانه نداشته باشد، نوع پروژه رایگان را حذف کنید
if (user.daily_free_request <= 0) {
projectTypes = projectTypes.filter(projectType => projectType.name !== 'free')
}
// ارسال انواع پروژه به کاربر
res.status(200).json({ projectTypes })
} catch (error) {
// در صورت بروز خطا، ارسال پیام خطا به کاربر
console.error('Error in getProjectTypes:', error)
res.status(500).json({ message: 'خطا در دریافت انواع پروژه.' })
}
}
module.exports = {
getProjectTypes
}
const TypeAndPriceModel = require('../../../models/TypeAndPriceModel')
const jwt = require('jsonwebtoken')
const UserModel = require('../../../models/UserModel')
const getProjectTypes = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const userId = decodedToken.id
const user = await UserModel.findById(userId)
if (!user) {
return res.status(422).json({
error: true,
message: 'کاربر یافت نشد'
})
}
// درخواست انواع پروژه از دیتابیس
let projectTypes = await TypeAndPriceModel.find({}, 'name price')
// بررسی برای مواردی مانند پیدا نشدن انواع پروژه
if (!projectTypes) {
return res.status(404).json({ message: 'انواع پروژه یافت نشد.' })
}
// اگر کاربر درخواست رایگان روزانه نداشته باشد، نوع پروژه رایگان را حذف کنید
if (user.daily_free_request <= 0) {
projectTypes = projectTypes.filter(projectType => projectType.name !== 'free')
}
// ارسال انواع پروژه به کاربر
res.status(200).json({ projectTypes })
} catch (error) {
// در صورت بروز خطا، ارسال پیام خطا به کاربر
console.error('Error in getProjectTypes:', error)
res.status(500).json({ message: 'خطا در دریافت انواع پروژه.' })
}
}
module.exports = {
getProjectTypes
}

View File

@@ -1,195 +1,195 @@
/* eslint-disable camelcase */
const { default: axios } = require('axios')
const NotificationModel = require('../../../models/NotificationModel')
const ProjectModel = require('../../../models/ProjectModel')
const RequestModel = require('../../../models/RequestModel')
const UserModel = require('../../../models/UserModel')
const { check, validationResult } = require('express-validator')
const jwt = require('jsonwebtoken')
const requestProjectValidationRules = () => {
return [
check('project_id')
.notEmpty().withMessage('آیدی پروژه نمی‌تواند خالی باشد'),
check('request_time')
.notEmpty().withMessage('زمان پروژه نمی‌تواند خالی باشد'),
check('offer_price')
.notEmpty().withMessage('قیمت پیشنهادی نمی‌تواند خالی باشد')
]
}
const requestProject = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const user = await UserModel.findById(decodedToken.id)
if (!user || user.user_type !== 'user') {
return res.status(422).json({
error: true, message: 'شما دسترسی به این بخش ندارید'
})
}
if (user.is_verified !== 'verified') {
return res.status(422).json({
error: true, message: 'مدارک شما تایید نشده است'
})
}
// اعتبارسنجی درخواست
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() })
}
const { request_time, offer_price, project_id } = req.body
if (!project_id || !offer_price || !request_time
) {
return res.status(422).json({
error: true,
message: 'اطلاعات ارسالی اشتباه است'
})
}
// چک کردن برای وجود درخواست قبلی
const existingRequest = await RequestModel.findOne({ project: project_id, user: user._id })
if (existingRequest) {
return res.status(422).json({
error: true,
message: 'شما قبلاً برای این پروژه درخواست داده‌اید'
})
}
// ایجاد یک درخواست جدید
const request = new RequestModel({
project: project_id,
user: user._id,
time: request_time,
price: offer_price
})
await request.save()
// ثبت اعلان برای سازنده پروژه
const project = await ProjectModel.findById(project_id)
const creatorId = project.creator_id
const notification = new NotificationModel({
user_id: creatorId,
project_post_id: project_id,
type: 'request',
title: 'پیشنهاد جدید',
description: `کاربر ${user.user_name} یک پیشنهاد جدید برای پروژه شما ارسال کرده است.`
})
await notification.save()
const userReciver = await UserModel.findById(project.creator_id)
const data = JSON.stringify({
mobile: userReciver?.mobile,
templateId: '876533',
parameters: [
{ name: 'EMPLOYER', value: userReciver?.first_name + ' ' + userReciver?.last_name },
{ name: 'PROJECT', value: project?.title }
]
})
const config = {
method: 'post',
url: 'https://api.sms.ir/v1/send/verify',
headers: {
'Content-Type': 'application/json',
Accept: 'text/plain',
'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt'
},
data
}
axios(config)
.then(function (response) {
})
.catch(function (error) {
console.log(error)
})
// به روز رسانی پروژه با افزودن کاربر به لیست کاربران درخواست دهنده
const updatedProject = await ProjectModel.findOneAndUpdate(
{ _id: project_id },
{ $push: { requested_users: user._id } },
{ new: true }
)
if (!updatedProject) {
console.error('Error adding requested user: Project not found')
return res.status(404).json({ error: true, message: 'پروژه پیدا نشد' })
}
res.status(201).json({ message: 'درخواست با موفقیت شد', id: project_id }
)
} catch (error) {
next(error)
}
}
const editRequestProject = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const user = await UserModel.findById(decodedToken.id)
if (!user || user.user_type !== 'user') {
return res.status(422).json({
error: true, message: 'شما دسترسی به این بخش ندارید'
})
}
if (user.is_verified !== 'verified') {
return res.status(422).json({
error: true, message: 'مدارک شما تایید نشده است'
})
}
// اعتبارسنجی درخواست
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() })
}
const { request_time, offer_price, project_id } = req.body
if (!project_id || !offer_price || !request_time
) {
return res.status(422).json({
error: true,
message: 'اطلاعات ارسالی اشتباه است'
})
}
// چک کردن برای وجود درخواست قبلی
const existingRequest = await RequestModel.findOne({ project: project_id, user: user._id })
if (!existingRequest) {
return res.status(422).json({
error: true,
message: 'شما قبلاً برای این پروژه درخواست نداده‌اید'
})
}
// اکنون می‌توانید اطلاعات درخواست را ویرایش کنید
existingRequest.time = request_time
existingRequest.price = offer_price
await existingRequest.save()
// ثبت اعلان برای سازنده پروژه
const project = await ProjectModel.findById(project_id)
const creatorId = project.creator_id
const notification = new NotificationModel({
user_id: creatorId,
project_post_id: project_id,
type: 'request',
title: 'ویرایش پیشنهاد',
description: `کاربر ${user.user_name} پیشنهاد خود را ویرایش کرد.`
})
await notification.save()
res.status(200).json({
message: 'درخواست با موفقیت ویرایش شد',
id: project_id
})
} catch (error) {
next(error)
}
}
const acceptProject = async (req, res, next) => { }
module.exports = {
requestProjectValidationRules,
requestProject,
acceptProject,
editRequestProject
}
/* eslint-disable camelcase */
const { default: axios } = require('axios')
const NotificationModel = require('../../../models/NotificationModel')
const ProjectModel = require('../../../models/ProjectModel')
const RequestModel = require('../../../models/RequestModel')
const UserModel = require('../../../models/UserModel')
const { check, validationResult } = require('express-validator')
const jwt = require('jsonwebtoken')
const requestProjectValidationRules = () => {
return [
check('project_id')
.notEmpty().withMessage('آیدی پروژه نمی‌تواند خالی باشد'),
check('request_time')
.notEmpty().withMessage('زمان پروژه نمی‌تواند خالی باشد'),
check('offer_price')
.notEmpty().withMessage('قیمت پیشنهادی نمی‌تواند خالی باشد')
]
}
const requestProject = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const user = await UserModel.findById(decodedToken.id)
if (!user || user.user_type !== 'user') {
return res.status(422).json({
error: true, message: 'شما دسترسی به این بخش ندارید'
})
}
if (user.is_verified !== 'verified') {
return res.status(422).json({
error: true, message: 'مدارک شما تایید نشده است'
})
}
// اعتبارسنجی درخواست
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() })
}
const { request_time, offer_price, project_id } = req.body
if (!project_id || !offer_price || !request_time
) {
return res.status(422).json({
error: true,
message: 'اطلاعات ارسالی اشتباه است'
})
}
// چک کردن برای وجود درخواست قبلی
const existingRequest = await RequestModel.findOne({ project: project_id, user: user._id })
if (existingRequest) {
return res.status(422).json({
error: true,
message: 'شما قبلاً برای این پروژه درخواست داده‌اید'
})
}
// ایجاد یک درخواست جدید
const request = new RequestModel({
project: project_id,
user: user._id,
time: request_time,
price: offer_price
})
await request.save()
// ثبت اعلان برای سازنده پروژه
const project = await ProjectModel.findById(project_id)
const creatorId = project.creator_id
const notification = new NotificationModel({
user_id: creatorId,
project_post_id: project_id,
type: 'request',
title: 'پیشنهاد جدید',
description: `کاربر ${user.user_name} یک پیشنهاد جدید برای پروژه شما ارسال کرده است.`
})
await notification.save()
const userReciver = await UserModel.findById(project.creator_id)
const data = JSON.stringify({
mobile: userReciver?.mobile,
templateId: '876533',
parameters: [
{ name: 'EMPLOYER', value: userReciver?.first_name + ' ' + userReciver?.last_name },
{ name: 'PROJECT', value: project?.title }
]
})
const config = {
method: 'post',
url: 'https://api.sms.ir/v1/send/verify',
headers: {
'Content-Type': 'application/json',
Accept: 'text/plain',
'x-api-key': '2JKxGbTzE64t0YTkjip6RYHnm9mq1haMlidF8WWwQunwubHFVW6iaMmfFQbMXEDt'
},
data
}
axios(config)
.then(function (response) {
})
.catch(function (error) {
console.log(error)
})
// به روز رسانی پروژه با افزودن کاربر به لیست کاربران درخواست دهنده
const updatedProject = await ProjectModel.findOneAndUpdate(
{ _id: project_id },
{ $push: { requested_users: user._id } },
{ new: true }
)
if (!updatedProject) {
console.error('Error adding requested user: Project not found')
return res.status(404).json({ error: true, message: 'پروژه پیدا نشد' })
}
res.status(201).json({ message: 'درخواست با موفقیت شد', id: project_id }
)
} catch (error) {
next(error)
}
}
const editRequestProject = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const user = await UserModel.findById(decodedToken.id)
if (!user || user.user_type !== 'user') {
return res.status(422).json({
error: true, message: 'شما دسترسی به این بخش ندارید'
})
}
if (user.is_verified !== 'verified') {
return res.status(422).json({
error: true, message: 'مدارک شما تایید نشده است'
})
}
// اعتبارسنجی درخواست
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() })
}
const { request_time, offer_price, project_id } = req.body
if (!project_id || !offer_price || !request_time
) {
return res.status(422).json({
error: true,
message: 'اطلاعات ارسالی اشتباه است'
})
}
// چک کردن برای وجود درخواست قبلی
const existingRequest = await RequestModel.findOne({ project: project_id, user: user._id })
if (!existingRequest) {
return res.status(422).json({
error: true,
message: 'شما قبلاً برای این پروژه درخواست نداده‌اید'
})
}
// اکنون می‌توانید اطلاعات درخواست را ویرایش کنید
existingRequest.time = request_time
existingRequest.price = offer_price
await existingRequest.save()
// ثبت اعلان برای سازنده پروژه
const project = await ProjectModel.findById(project_id)
const creatorId = project.creator_id
const notification = new NotificationModel({
user_id: creatorId,
project_post_id: project_id,
type: 'request',
title: 'ویرایش پیشنهاد',
description: `کاربر ${user.user_name} پیشنهاد خود را ویرایش کرد.`
})
await notification.save()
res.status(200).json({
message: 'درخواست با موفقیت ویرایش شد',
id: project_id
})
} catch (error) {
next(error)
}
}
const acceptProject = async (req, res, next) => { }
module.exports = {
requestProjectValidationRules,
requestProject,
acceptProject,
editRequestProject
}

View File

@@ -1,381 +1,381 @@
/* eslint-disable camelcase */
const ProjectModel = require('../../../models/ProjectModel')
const jwt = require('jsonwebtoken')
const UserModel = require('../../../models/UserModel')
const { check, validationResult } = require('express-validator')
const { ProvinceModel, CityModel } = require('../../../models/StateCity')
const NotificationModel = require('../../../models/NotificationModel')
const CommentModel = require('../../../models/CommentModel')
const doneProject = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const userId = decodedToken.id
const { project_id, comment, rate, user_id } = req.body
if (!project_id || !comment || !rate || !user_id) {
return res.status(400).send({ message: 'All fields are required' })
}
const project = await ProjectModel.findOne({ _id: project_id, creator_id: userId })
if (!project) {
return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' })
}
const getTotalPaidAmount = (installments) => {
return installments.reduce((total, installment) => total + installment.amount, 0)
}
const getRemainingAmount = (project) => {
const totalPaidAmount = getTotalPaidAmount(project.installments)
return project.final_price - totalPaidAmount
}
const remainingAmount = getRemainingAmount(project)
if (remainingAmount !== 0) {
return res.status(422).send({ message: 'مبلغ کامل پرداخت نشده است' })
}
project.status = 'done'
await project.save()
const newComment = new CommentModel({
user: user_id,
project: project_id,
creator: userId,
rating: rate,
comment,
comment_for: 'user',
status: 'pending'
})
await newComment.save()
const user = await UserModel.findById(user_id)
// پیدا کردن کامنت‌ها و محاسبه‌ی امتیاز کل
const comments = await CommentModel.find({ user: user_id, comment_for: 'user' })
const totalRating = Number(comments.reduce((acc, comment) => acc + comment.rating, 0))
let userLevel
if (user.expertise === 'مدل') {
if (totalRating <= 50) userLevel = 'تازه وارد'
else if (totalRating <= 100) userLevel = 'استاندارد'
else if (totalRating <= 300) userLevel = 'حرفه‌ای'
else userLevel = 'استاد'
} else if (['زیبایی', 'عکاس'].includes(user.expertise)) {
if (totalRating <= 50) userLevel = 'تازه وارد'
else if (totalRating <= 100) userLevel = 'استاندارد'
else if (totalRating <= 300) userLevel = 'حرفه‌ای'
else userLevel = 'استاد'
}
user.user_score = totalRating
user.user_level = userLevel
const totalComments = await CommentModel.countDocuments({ user: user_id, comment_for: 'user' })
const averageRating = totalRating / totalComments
user.rate = averageRating.toFixed(1)
await user.save()
const notification = new NotificationModel({
user_id: user._id,
project_post_id: project_id,
type: 'end_project',
title: 'اتمام پروژه',
description: `کارفرما پروژه ${project?.title} را به وضعیت انجام شده تغییر داد و برای شما نظر ثبت کرد(برای ثبت نظر لمس کنید)
نظر کارفرما : ${comment}
`
})
await notification.save()
res.status(200).json({ message: 'پروژه با موفقیت تغییر یافت شد' })
} catch (error) {
next(error)
}
}
const doneProjectWeb = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const userId = decodedToken.id
const { project_id, comment, rate, user_id } = req.body
if (!project_id || !comment || !rate || !user_id) {
return res.status(400).send({ message: 'All fields are required' })
}
const project = await ProjectModel.findOne({ _id: project_id, creator_id: userId })
if (!project) {
return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' })
}
project.status = 'done'
await project.save()
const newComment = new CommentModel({
user: user_id,
project: project_id,
creator: userId,
rating: rate,
comment,
comment_for: 'user',
status: 'pending'
})
await newComment.save()
const user = await UserModel.findById(user_id)
// پیدا کردن کامنت‌ها و محاسبه‌ی امتیاز کل
const comments = await CommentModel.find({ user: user_id, comment_for: 'user' })
const totalRating = Number(comments.reduce((acc, comment) => acc + comment.rating, 0))
let userLevel
if (user.expertise === 'مدل') {
if (totalRating <= 50) userLevel = 'تازه وارد'
else if (totalRating <= 100) userLevel = 'استاندارد'
else if (totalRating <= 300) userLevel = 'حرفه‌ای'
else userLevel = 'استاد'
} else if (['زیبایی', 'عکاس'].includes(user.expertise)) {
if (totalRating <= 50) userLevel = 'تازه وارد'
else if (totalRating <= 100) userLevel = 'استاندارد'
else if (totalRating <= 300) userLevel = 'حرفه‌ای'
else userLevel = 'استاد'
}
user.user_score = totalRating
user.user_level = userLevel
const totalComments = await CommentModel.countDocuments({ user: user_id, comment_for: 'user' })
const averageRating = totalRating / totalComments
user.rate = averageRating.toFixed(1)
await user.save()
const notification = new NotificationModel({
user_id: user._id,
project_post_id: project_id,
type: 'end_project',
title: 'اتمام پروژه',
description: `کارفرما پروژه ${project?.title} را به وضعیت انجام شده تغییر داد و برای شما نظر ثبت کرد(برای ثبت نظر لمس کنید)
نظر کارفرما : ${comment}
`
})
await notification.save()
res.status(200).json({ message: 'پروژه با موفقیت تغییر یافت شد' })
} catch (error) {
next(error)
}
}
const cancleProject = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const userId = decodedToken.id
const { project_id, comment, rate, user_id } = req.body
if (!project_id || !comment || !rate || !user_id) {
return res.status(400).send({ message: 'All fields are required' })
}
const project = await ProjectModel.findOne({ _id: project_id, creator_id: userId })
if (!project) {
return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' })
}
project.status = 'cancled'
await project.save()
const newComment = new CommentModel({
user: user_id,
project: project_id,
creator: userId,
rating: rate,
comment,
comment_for: 'project',
status: 'pending'
})
await newComment.save()
res.status(200).json({ message: 'پروژه با موفقیت تغییر یافت شد' })
} catch (error) {
next(error)
}
}
const editProjectValidationRules = () => {
return [
check('title').notEmpty().withMessage('عنوان نمی‌تواند خالی باشد'),
check('expertise').notEmpty().withMessage('تخصص نمی‌تواند خالی باشد'),
check('gender')
.isIn(['male', 'female'])
.withMessage('جنسیت باید male یا female باشد'),
check('age').notEmpty().withMessage('سن نمی‌تواند خالی باشد'),
check('conversation_projects')
.notEmpty()
.withMessage('پروژه‌های مکالمه نمی‌تواند خالی باشد')
.isBoolean()
.withMessage('مقدار پروژه‌های مکالمه باید یک مقدار boolean باشد'),
check('province').notEmpty().withMessage('استان نمی‌تواند خالی باشد'),
check('city').notEmpty().withMessage('شهر نمی‌تواند خالی باشد'),
check('offer_time')
.notEmpty()
.withMessage('زمان پروژه نمی‌تواند خالی باشد'),
check('offer_price')
.notEmpty()
.withMessage('قیمت پیشنهادی نمی‌تواند خالی باشد'),
check('description')
.notEmpty()
.withMessage('توضیحات نمی‌تواند خالی باشد')
]
}
const editProject = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const user = await UserModel.findById(decodedToken.id)
if (!user) {
return res.status(422).json({
error: true,
message: 'شما دسترسی به این بخش ندارید'
})
}
if (user.is_verified !== 'verified') {
return res.status(422).json({
error: true,
message: 'مدارک شما تایید نشده است'
})
}
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() })
}
const {
title,
expertise,
sub_expertise,
gender,
age,
conversation_projects,
province,
city,
offer_time,
offer_price,
description,
projectId
} = req.body
const project = await ProjectModel.findById(projectId)
if (!project) {
return res.status(404).json({
error: true,
message: 'پروژه مورد نظر یافت نشد'
})
}
// eslint-disable-next-line eqeqeq
if (user._id.toString() != project.creator_id.toString()) {
return res.status(422).json({
error: true,
message: 'شما نمیتوانید این پروژه را ویرایش کنید'
})
}
if (project.status !== 'paid' && project.status !== 'pre_payment') {
return res.status(422).json({
error: true,
message: 'شما نمیتوانید این پروژه را ویرایش کنید'
})
}
// اعتبارسنجی اطلاعات ویرایش شده
if (
!title ||
!expertise ||
!age ||
conversation_projects === null ||
!province ||
!city ||
!offer_time ||
!offer_price ||
!description
) {
return res.status(422).json({
error: true,
message: 'اطلاعات ارسالی اشتباه است'
})
}
const provinceFind = await ProvinceModel.findOne(
{ id: province },
{ _id: 0 }
)
const cityFind = await CityModel.findOne({ id: city })
// ویرایش یک نسخه از پروژه
project.title = title
project.expertise = expertise
project.sub_expertise = sub_expertise
project.gender = gender
project.age = age
project.conversation_projects = conversation_projects
project.province = provinceFind
project.city = cityFind
project.offer_time = offer_time
project.offer_price = offer_price
project.description = description
// ذخیره کردن تغییرات در پایگاه داده
await project.save()
res.status(200).json({
message: 'پروژه با موفقیت ویرایش شد',
id: project._id
})
} catch (error) {
next(error)
}
}
const setRateProject = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const userId = decodedToken.id
const { project_id, comment, rate } = req.body
const project = await ProjectModel.findOne({ _id: project_id, selected_user: userId })
if (!project) {
return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' })
}
project.ratings.push({
project_id,
rating: rate,
comment,
creator_id: userId
})
await project.save()
res.status(200).json({ message: 'نظر شما با موفقیت ثبت شد.' })
} catch (error) {
next(error)
}
}
module.exports = {
doneProject, cancleProject, editProject, editProjectValidationRules, setRateProject, doneProjectWeb
}
/* eslint-disable camelcase */
const ProjectModel = require('../../../models/ProjectModel')
const jwt = require('jsonwebtoken')
const UserModel = require('../../../models/UserModel')
const { check, validationResult } = require('express-validator')
const { ProvinceModel, CityModel } = require('../../../models/StateCity')
const NotificationModel = require('../../../models/NotificationModel')
const CommentModel = require('../../../models/CommentModel')
const doneProject = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const userId = decodedToken.id
const { project_id, comment, rate, user_id } = req.body
if (!project_id || !comment || !rate || !user_id) {
return res.status(400).send({ message: 'All fields are required' })
}
const project = await ProjectModel.findOne({ _id: project_id, creator_id: userId })
if (!project) {
return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' })
}
const getTotalPaidAmount = (installments) => {
return installments.reduce((total, installment) => total + installment.amount, 0)
}
const getRemainingAmount = (project) => {
const totalPaidAmount = getTotalPaidAmount(project.installments)
return project.final_price - totalPaidAmount
}
const remainingAmount = getRemainingAmount(project)
if (remainingAmount !== 0) {
return res.status(422).send({ message: 'مبلغ کامل پرداخت نشده است' })
}
project.status = 'done'
await project.save()
const newComment = new CommentModel({
user: user_id,
project: project_id,
creator: userId,
rating: rate,
comment,
comment_for: 'user',
status: 'pending'
})
await newComment.save()
const user = await UserModel.findById(user_id)
// پیدا کردن کامنت‌ها و محاسبه‌ی امتیاز کل
const comments = await CommentModel.find({ user: user_id, comment_for: 'user' })
const totalRating = Number(comments.reduce((acc, comment) => acc + comment.rating, 0))
let userLevel
if (user.expertise === 'مدل') {
if (totalRating <= 50) userLevel = 'تازه وارد'
else if (totalRating <= 100) userLevel = 'استاندارد'
else if (totalRating <= 300) userLevel = 'حرفه‌ای'
else userLevel = 'استاد'
} else if (['زیبایی', 'عکاس'].includes(user.expertise)) {
if (totalRating <= 50) userLevel = 'تازه وارد'
else if (totalRating <= 100) userLevel = 'استاندارد'
else if (totalRating <= 300) userLevel = 'حرفه‌ای'
else userLevel = 'استاد'
}
user.user_score = totalRating
user.user_level = userLevel
const totalComments = await CommentModel.countDocuments({ user: user_id, comment_for: 'user' })
const averageRating = totalRating / totalComments
user.rate = averageRating.toFixed(1)
await user.save()
const notification = new NotificationModel({
user_id: user._id,
project_post_id: project_id,
type: 'end_project',
title: 'اتمام پروژه',
description: `کارفرما پروژه ${project?.title} را به وضعیت انجام شده تغییر داد و برای شما نظر ثبت کرد(برای ثبت نظر لمس کنید)
نظر کارفرما : ${comment}
`
})
await notification.save()
res.status(200).json({ message: 'پروژه با موفقیت تغییر یافت شد' })
} catch (error) {
next(error)
}
}
const doneProjectWeb = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const userId = decodedToken.id
const { project_id, comment, rate, user_id } = req.body
if (!project_id || !comment || !rate || !user_id) {
return res.status(400).send({ message: 'All fields are required' })
}
const project = await ProjectModel.findOne({ _id: project_id, creator_id: userId })
if (!project) {
return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' })
}
project.status = 'done'
await project.save()
const newComment = new CommentModel({
user: user_id,
project: project_id,
creator: userId,
rating: rate,
comment,
comment_for: 'user',
status: 'pending'
})
await newComment.save()
const user = await UserModel.findById(user_id)
// پیدا کردن کامنت‌ها و محاسبه‌ی امتیاز کل
const comments = await CommentModel.find({ user: user_id, comment_for: 'user' })
const totalRating = Number(comments.reduce((acc, comment) => acc + comment.rating, 0))
let userLevel
if (user.expertise === 'مدل') {
if (totalRating <= 50) userLevel = 'تازه وارد'
else if (totalRating <= 100) userLevel = 'استاندارد'
else if (totalRating <= 300) userLevel = 'حرفه‌ای'
else userLevel = 'استاد'
} else if (['زیبایی', 'عکاس'].includes(user.expertise)) {
if (totalRating <= 50) userLevel = 'تازه وارد'
else if (totalRating <= 100) userLevel = 'استاندارد'
else if (totalRating <= 300) userLevel = 'حرفه‌ای'
else userLevel = 'استاد'
}
user.user_score = totalRating
user.user_level = userLevel
const totalComments = await CommentModel.countDocuments({ user: user_id, comment_for: 'user' })
const averageRating = totalRating / totalComments
user.rate = averageRating.toFixed(1)
await user.save()
const notification = new NotificationModel({
user_id: user._id,
project_post_id: project_id,
type: 'end_project',
title: 'اتمام پروژه',
description: `کارفرما پروژه ${project?.title} را به وضعیت انجام شده تغییر داد و برای شما نظر ثبت کرد(برای ثبت نظر لمس کنید)
نظر کارفرما : ${comment}
`
})
await notification.save()
res.status(200).json({ message: 'پروژه با موفقیت تغییر یافت شد' })
} catch (error) {
next(error)
}
}
const cancleProject = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const userId = decodedToken.id
const { project_id, comment, rate, user_id } = req.body
if (!project_id || !comment || !rate || !user_id) {
return res.status(400).send({ message: 'All fields are required' })
}
const project = await ProjectModel.findOne({ _id: project_id, creator_id: userId })
if (!project) {
return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' })
}
project.status = 'cancled'
await project.save()
const newComment = new CommentModel({
user: user_id,
project: project_id,
creator: userId,
rating: rate,
comment,
comment_for: 'project',
status: 'pending'
})
await newComment.save()
res.status(200).json({ message: 'پروژه با موفقیت تغییر یافت شد' })
} catch (error) {
next(error)
}
}
const editProjectValidationRules = () => {
return [
check('title').notEmpty().withMessage('عنوان نمی‌تواند خالی باشد'),
check('expertise').notEmpty().withMessage('تخصص نمی‌تواند خالی باشد'),
check('gender')
.isIn(['male', 'female'])
.withMessage('جنسیت باید male یا female باشد'),
check('age').notEmpty().withMessage('سن نمی‌تواند خالی باشد'),
check('conversation_projects')
.notEmpty()
.withMessage('پروژه‌های مکالمه نمی‌تواند خالی باشد')
.isBoolean()
.withMessage('مقدار پروژه‌های مکالمه باید یک مقدار boolean باشد'),
check('province').notEmpty().withMessage('استان نمی‌تواند خالی باشد'),
check('city').notEmpty().withMessage('شهر نمی‌تواند خالی باشد'),
check('offer_time')
.notEmpty()
.withMessage('زمان پروژه نمی‌تواند خالی باشد'),
check('offer_price')
.notEmpty()
.withMessage('قیمت پیشنهادی نمی‌تواند خالی باشد'),
check('description')
.notEmpty()
.withMessage('توضیحات نمی‌تواند خالی باشد')
]
}
const editProject = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const user = await UserModel.findById(decodedToken.id)
if (!user) {
return res.status(422).json({
error: true,
message: 'شما دسترسی به این بخش ندارید'
})
}
if (user.is_verified !== 'verified') {
return res.status(422).json({
error: true,
message: 'مدارک شما تایید نشده است'
})
}
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() })
}
const {
title,
expertise,
sub_expertise,
gender,
age,
conversation_projects,
province,
city,
offer_time,
offer_price,
description,
projectId
} = req.body
const project = await ProjectModel.findById(projectId)
if (!project) {
return res.status(404).json({
error: true,
message: 'پروژه مورد نظر یافت نشد'
})
}
// eslint-disable-next-line eqeqeq
if (user._id.toString() != project.creator_id.toString()) {
return res.status(422).json({
error: true,
message: 'شما نمیتوانید این پروژه را ویرایش کنید'
})
}
if (project.status !== 'paid' && project.status !== 'pre_payment') {
return res.status(422).json({
error: true,
message: 'شما نمیتوانید این پروژه را ویرایش کنید'
})
}
// اعتبارسنجی اطلاعات ویرایش شده
if (
!title ||
!expertise ||
!age ||
conversation_projects === null ||
!province ||
!city ||
!offer_time ||
!offer_price ||
!description
) {
return res.status(422).json({
error: true,
message: 'اطلاعات ارسالی اشتباه است'
})
}
const provinceFind = await ProvinceModel.findOne(
{ id: province },
{ _id: 0 }
)
const cityFind = await CityModel.findOne({ id: city })
// ویرایش یک نسخه از پروژه
project.title = title
project.expertise = expertise
project.sub_expertise = sub_expertise
project.gender = gender
project.age = age
project.conversation_projects = conversation_projects
project.province = provinceFind
project.city = cityFind
project.offer_time = offer_time
project.offer_price = offer_price
project.description = description
// ذخیره کردن تغییرات در پایگاه داده
await project.save()
res.status(200).json({
message: 'پروژه با موفقیت ویرایش شد',
id: project._id
})
} catch (error) {
next(error)
}
}
const setRateProject = async (req, res, next) => {
try {
const token = req.header('Authorization').split(' ')[1]
if (!token) return res.status(401).send('Access Denied')
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
const userId = decodedToken.id
const { project_id, comment, rate } = req.body
const project = await ProjectModel.findOne({ _id: project_id, selected_user: userId })
if (!project) {
return res.status(403).send({ message: 'Access denied: You are not the creator of this project.' })
}
project.ratings.push({
project_id,
rating: rate,
comment,
creator_id: userId
})
await project.save()
res.status(200).json({ message: 'نظر شما با موفقیت ثبت شد.' })
} catch (error) {
next(error)
}
}
module.exports = {
doneProject, cancleProject, editProject, editProjectValidationRules, setRateProject, doneProjectWeb
}