This commit is contained in:
payacom
2026-08-31 20:45:41 +03:30
parent fa9f23c61d
commit 3f416a7a60
367 changed files with 621895 additions and 6443 deletions

View File

@@ -3,8 +3,8 @@
const { default: mongoose } = require('mongoose')
const UserModel = require('../../../models/UserModel')
const jMoment = require('moment-jalaali')
const NotificationModel = require('../../../models/NotificationModel')
const { default: axios } = require('axios')
const { notifyUser } = require('../../../utils/notifyUser')
const { syncVerifyBadge } = require('../../../utils/verifyBadge')
const getUsers = async (req, res, next) => {
try {
@@ -76,6 +76,9 @@ const getUsers = async (req, res, next) => {
last_name: user.last_name,
user_type: user.user_type,
is_verified: user.is_verified,
license_verified: user.license_verified,
gold_badge: user.gold_badge,
verify_badge: user.verify_badge,
profile_image: user.profile_image,
expertise: user.expertise,
sub_expertise: user.sub_expertise,
@@ -230,6 +233,9 @@ const getUserDetail = async (req, res, next) => {
user_score: user?.user_score,
services :user?.services,
is_verified: user?.is_verified,
license_verified: user?.license_verified,
gold_badge: user?.gold_badge,
verify_badge: user?.verify_badge,
rate: user?.rate,
bio: user?.bio,
eye_color: user?.eye_color,
@@ -244,98 +250,119 @@ const getUserDetail = async (req, res, next) => {
}
const updateUser = async (req, res, next) => {
try {
const userId = req.query.userId // دریافت شناسه کاربر از درخواست
const userId = req.query.userId
// چک کردن اعتبار شناسه کاربر
if (!mongoose.Types.ObjectId.isValid(userId)) {
return res.status(400).json({ message: 'شناسه کاربر معتبر نیست' })
}
// فیلدهایی که می‌خواهید آپدیت شوند را از درخواست دریافت کنید
const updateFields = req.body
const updateFields = { ...(req.body || {}) }
// نرمال‌سازی و انتقال شماره موبایل (رفع duplicate key)
if (Object.prototype.hasOwnProperty.call(updateFields, 'mobile')) {
let mobile = updateFields.mobile
if (mobile === '' || mobile === null) {
updateFields.$unset = { ...(updateFields.$unset || {}), mobile: '' }
delete updateFields.mobile
} else {
mobile = String(mobile).replace(/\D/g, '')
if (!/^09[0-9]{9}$/.test(mobile)) {
return res.status(422).json({
errors: [{ message: 'فرمت شماره موبایل صحیح نیست (مثال: 09123456789)' }]
})
}
updateFields.mobile = mobile
// اگر شماره متعلق به کاربر دیگری است، از او برداشته شود تا ادمین بتواند منتقل کند
const holder = await UserModel.findOne({
mobile,
_id: { $ne: userId }
}).select('_id user_name mobile')
if (holder) {
await UserModel.updateOne(
{ _id: holder._id },
{ $unset: { mobile: '' } }
)
console.log(
`[updateUser] freed mobile ${mobile} from user ${holder._id} (${holder.user_name})`
)
}
}
}
// اجرای آپدیت و بازگشت مقدار آپدیت شده
const updatedUser = await UserModel.findByIdAndUpdate(
userId,
updateFields,
{ new: true }
updateFields.$unset
? {
$set: Object.fromEntries(
Object.entries(updateFields).filter(([k]) => k !== '$unset')
),
$unset: updateFields.$unset
}
: updateFields,
{ new: true, runValidators: true }
)
// بررسی آیا کاربر وجود دارد یا نه
if (!updatedUser) {
return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' })
}
// ارسال پاسخ با مقادیر آپدیت شده
res.status(200).json({ message: 'کاربر با موفقیت ویرایش شد', id: updatedUser._id })
res.status(200).json({
message: 'کاربر با موفقیت ویرایش شد',
id: updatedUser._id,
mobile: updatedUser.mobile || null
})
} catch (error) {
const errors = []
if (error.code === 11000) {
// Duplicate key error
for (const key in error.keyValue) {
errors.push({ message: `ارور در فیلد ${key}` })
const field = Object.keys(error.keyValue || {})[0] || 'فیلد'
if (field === 'mobile') {
errors.push({
message:
'این شماره موبایل قبلاً برای کاربر دیگری ثبت شده است. ابتدا شماره را از آن کاربر حذف کنید یا دوباره ذخیره کنید تا به‌صورت خودکار منتقل شود.'
})
} else {
errors.push({ message: `مقدار تکراری در فیلد ${field}` })
}
} else {
errors.push({ message: 'خطا در آپدیت کاربر' })
console.error('[updateUser]', error)
errors.push({ message: error.message || 'خطا در آپدیت کاربر' })
}
res.status(500).json({ errors })
res.status(409).json({ errors })
}
}
const verifyUser = async (req, res, next) => {
try {
const userId = req.query.userId // دریافت شناسه کاربر از درخواست
const userId = req.query.userId
const user = await UserModel.findById(userId)
if (!user) {
return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' })
}
user.is_verified = 'verified';
user.is_Register = true;
await user.save();
const notification = new NotificationModel({
user_id: userId,
if (!user.national_card_image) {
return res.status(422).json({
message: 'کاربر هنوز تصویر کارت ملی ارسال نکرده است'
})
}
user.is_verified = 'verified'
user.is_Register = true
syncVerifyBadge(user)
await user.save()
await notifyUser(req.app?.get?.('io'), userId, {
type: 'verify',
title: 'تایید مدارک',
description: 'مدارک ارسالی شما با موفقیت تایید شد'
})
await notification.save()
// Sms
const userReciver = await UserModel.findById(userId)
const data = JSON.stringify({
mobile: userReciver?.mobile,
templateId: '632057',
parameters: [
{ name: 'USERS', value: userReciver?.first_name + ' ' + userReciver?.last_name }
]
description: 'مدارک و تصویر احراز هویت شما تایید شد. تیک تایید کنار نام کاربری شما فعال شد.'
})
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)
})
// End Sms
// ارسال پاسخ با مقادیر آپدیت شده
res.status(200).json({ message: 'مدارک کاربر با موفقیت تایید شد' })
return res.status(200).json({
message: 'مدارک کاربر با موفقیت تایید شد',
is_verified: user.is_verified
})
} catch (error) {
next(error)
}
@@ -358,6 +385,18 @@ const updateUserStatus = async (req, res, next) => {
if (!user) return res.status(404).json({ message: 'کاربر یافت نشد' });
await notifyUser(req.app?.get?.('io'), userId, block_status
? {
type: 'block',
title: 'مسدود شدن حساب',
description: 'حساب کاربری شما توسط پشتیبانی مسدود شد.'
}
: {
type: 'unblock',
title: 'رفع مسدودیت حساب',
description: 'حساب کاربری شما توسط پشتیبانی دوباره فعال شد.'
})
res.status(200).json({ message: 'وضعیت کاربر با موفقیت تغییر کرد', block_status: user.block_status });
} catch (error) {
console.error(error);
@@ -367,44 +406,101 @@ const updateUserStatus = async (req, res, next) => {
const rejectUser = async (req, res, next) => {
try {
const userId = req.query.userId // دریافت شناسه کاربر از درخواست
const userId = req.query.userId
const user = await UserModel.findById(userId)
if (!user) {
return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' })
}
user.is_verified = 'rejected'
user.is_Register = false
syncVerifyBadge(user)
await user.save()
const notification = new NotificationModel({
user_id: userId,
await notifyUser(req.app?.get?.('io'), userId, {
type: 'reject-user',
title: 'رد مدارک',
description: 'مدارک ارسالی شما رد شد، برای اطلاعات بیشتر از بخش تیکت به پشتیبانی پیام دهید.'
description:
'مدارک احراز هویت شما رد شد. لطفاً تصویر کارت ملی را دوباره از بخش احراز هویت ارسال کنید یا از طریق تیکت با پشتیبانی در ارتباط باشید.'
})
await notification.save()
// ارسال پاسخ با مقادیر آپدیت شده
res.status(200).json({ message: 'مدارک کاربر با موفقیت رد شد' })
return res.status(200).json({
message: 'مدارک کاربر با موفقیت رد شد',
is_verified: user.is_verified
})
} catch (error) {
next(error)
}
}
const changePass = async (req, res, next) => {
const grantGoldBadge = async (req, res, next) => {
try {
const { userId, password } = req.body;
const userId = req.query.userId
const user = await UserModel.findById(userId)
if (!user) {
return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' })
}
user.password = password
user.gold_badge = true
syncVerifyBadge(user)
await user.save()
// ارسال پاسخ با مقادیر آپدیت شده
res.status(200).json({ message: 'رمز عبور با موفقیت تغییر کرد' });
await notifyUser(req.app?.get?.('io'), userId, {
type: 'verify',
title: 'تیک طلایی',
description: 'تیک طلایی توسط مدیریت برای شما فعال شد.'
})
return res.status(200).json({
message: 'تیک طلایی با موفقیت فعال شد',
gold_badge: user.gold_badge,
verify_badge: user.verify_badge
})
} catch (error) {
next(error)
}
}
const revokeGoldBadge = async (req, res, next) => {
try {
const userId = req.query.userId
const user = await UserModel.findById(userId)
if (!user) {
return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' })
}
user.gold_badge = false
syncVerifyBadge(user)
await user.save()
return res.status(200).json({
message: 'تیک طلایی با موفقیت غیرفعال شد',
gold_badge: user.gold_badge,
verify_badge: user.verify_badge
})
} catch (error) {
next(error)
}
}
const changePass = async (req, res, next) => {
try {
const bcrypt = require('bcryptjs')
const { userId, password } = req.body
if (!password || String(password).length < 8) {
return res.status(422).json({ message: 'رمز عبور باید حداقل ۸ کاراکتر باشد' })
}
const user = await UserModel.findById(userId)
if (!user) {
return res.status(404).json({ message: 'کاربر مورد نظر یافت نشد' })
}
user.password = await bcrypt.hash(String(password), 10)
await user.save()
res.status(200).json({ message: 'رمز عبور با موفقیت تغییر کرد' })
} catch (error) {
next(error)
}
}
module.exports = {
getUsers, getUserDetail, updateUser, verifyUser, rejectUser, updateUserStatus, changePass
getUsers, getUserDetail, updateUser, verifyUser, rejectUser, updateUserStatus, changePass, grantGoldBadge, revokeGoldBadge
}