1141 lines
33 KiB
JavaScript
1141 lines
33 KiB
JavaScript
const Category = require('../models/Category');
|
|
const Content = require('../models/Content');
|
|
const {body, validationResult} = require('express-validator');
|
|
const {_sr} = require('../plugins/serverResponses');
|
|
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions');
|
|
const News = require('../models/News');
|
|
const sharp = require('sharp')
|
|
const fs = require('fs')
|
|
|
|
|
|
// variables
|
|
const titleFilterRegex = new RegExp('/', 'g')
|
|
const noCover = '/img/no-cover.jpg'
|
|
const coverNewsWidth = 400;
|
|
const coverNewsHeight = 400;
|
|
const coverQuality = 100;
|
|
////////////////// functions
|
|
const _customTitle = async (categories) => {
|
|
try {
|
|
const newCatArr = [];
|
|
for (const item of categories) {
|
|
const title = [];
|
|
const treeCat = item.treeCat;
|
|
|
|
for (let i = treeCat.length - 1; i >= 0; i--) {
|
|
title.push(treeCat[i].title);
|
|
}
|
|
|
|
title.push(item.title);
|
|
|
|
item.title = title.join(" >> ");
|
|
|
|
newCatArr.push(item);
|
|
}
|
|
|
|
return newCatArr;
|
|
} catch (error) {
|
|
console.log(error)
|
|
return []
|
|
}
|
|
}
|
|
|
|
/** یک آرایه داریم که خونه اول رو میگیریم و میریزیم داخل آرایه جدید بعد داخل فور دوم کل آرایه رو طی میکنیم
|
|
* و اونایی که قسمتی از تایتل دیتای پوش شده داخل آرایه جدید رو دارن داخل این آرایه جدید پوش میکنیم
|
|
*/
|
|
|
|
// todo this is peace of shit please change it in future
|
|
const _sortedCategory = async (categories) => {
|
|
try {
|
|
let sortedArr = [];
|
|
|
|
// let clone = JSON.parse(JSON.stringify(categories));
|
|
//
|
|
// for (const cat of clone) {
|
|
// if (cat.parent){
|
|
// let getParent = categories.find(item => item._id === cat.parent._id)
|
|
// }
|
|
// }
|
|
|
|
for (let i = 0; i < categories.length; i++) {
|
|
if (!sortedArr.includes(categories[i]) && !categories[i].parent) {
|
|
sortedArr.push(categories[i]);
|
|
}
|
|
for (let j = 0; j < categories.length; j++) {
|
|
if (categories[i].childs.includes(categories[j]._id) && !sortedArr.includes(categories[j])) {
|
|
sortedArr.push(categories[j]);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sortedArr.length !== categories.length) {
|
|
for (const cat of categories) {
|
|
if (!sortedArr.includes(cat)) {
|
|
sortedArr.push(cat);
|
|
}
|
|
}
|
|
}
|
|
|
|
return sortedArr;
|
|
} catch (error) {
|
|
console.log(error)
|
|
return []
|
|
}
|
|
}
|
|
|
|
const _checkSpecPermission = async (req, category) => {
|
|
return !req.user.specialPermissions.includes(category._id) && //check parent id exist in special permissions or not
|
|
!req.user.specialPermissions.some(item => category?.treeCat?.join().includes(item));
|
|
}
|
|
/////////////////////////////////////////////////////////////////////// admin
|
|
module.exports.addCategory = [
|
|
[
|
|
body('title')
|
|
.notEmpty().withMessage(_sr['fa'].required.title)
|
|
.custom((value, {
|
|
req
|
|
}) => {
|
|
return Category.findOne({
|
|
title: value
|
|
})
|
|
.then(category => {
|
|
if (category) return Promise.reject(_sr['fa'].duplicated.title);
|
|
else return true
|
|
})
|
|
}),
|
|
|
|
body('parent')
|
|
.optional().isString().withMessage(`parent ${_sr['fa'].optional.string}`),
|
|
|
|
// body('showInMenu')
|
|
// .isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('navIndex')
|
|
.optional().isNumeric().withMessage(_sr['fa'].format.number),
|
|
|
|
body('priority')
|
|
.isNumeric().withMessage(_sr['fa'].format.number),
|
|
|
|
// body('showInSectionOne')
|
|
// .optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
//
|
|
// body('showInSectionTwo')
|
|
// .optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
//
|
|
// body('showInSectionThree')
|
|
// .optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('siteMap')
|
|
.isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('special')
|
|
.isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('url')
|
|
.optional().isString().withMessage(`url ${_sr['fa'].optional.string}`),
|
|
|
|
body('pageContent')
|
|
.optional().isString().withMessage(`pageContent ${_sr['fa'].optional.string}`),
|
|
|
|
body('news')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('child')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasNewsTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasContentTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasMediaTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasSubMenusTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasTermsTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasNotificationsTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasSpecNewsTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasNazarTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasNewsFileTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('modelType')
|
|
.custom((value, {
|
|
req
|
|
}) => {
|
|
if (req.user.portals.join() === portal.join()) {
|
|
if (!portal.includes(value)) {
|
|
return Promise.reject(_sr['fa'].required.field);
|
|
} else {
|
|
return true
|
|
}
|
|
} else {
|
|
return true
|
|
}
|
|
})
|
|
|
|
],
|
|
checkValidations(validationResult),
|
|
async (req, res) => {
|
|
try {
|
|
let {
|
|
title,
|
|
parent,
|
|
// showInMenu,
|
|
navIndex,
|
|
priority,
|
|
// showInSectionOne,
|
|
// showInSectionTwo,
|
|
// showInSectionThree,
|
|
siteMap,
|
|
special,
|
|
modelType,
|
|
showInFooter,
|
|
url,
|
|
pageContent,
|
|
news,
|
|
child,
|
|
hasNewsTab,
|
|
hasContentTab,
|
|
hasMediaTab,
|
|
hasSubMenusTab,
|
|
hasTermsTab,
|
|
hasNotificationsTab,
|
|
hasSpecNewsTab,
|
|
hasNazarTab,
|
|
hasNewsFileTab,
|
|
defaultPageType,
|
|
hasManagerInfo,
|
|
managerName,
|
|
managerDescription
|
|
} = req.body;
|
|
|
|
///////////// permissions
|
|
if (req.user.specialPermissions.length && _.isEmpty(parent)) {
|
|
return res.status(403).json({
|
|
message: `شما مجاز به اضافه کردن دسته بندی اصلی نیستید`
|
|
});
|
|
}
|
|
|
|
// if (req.user.specialPermissions.length && !_.isEmpty(parent) && !req.user.permissions.includes('categories-add')){
|
|
// return res.status(403).json(`شما اجازه اضافه کردن یک دسته بندی جدید را ندارید`);
|
|
// }
|
|
|
|
/** set portals */
|
|
modelType = (req.user.portals.join() === portal.join()) ? modelType : req.user.portals[0];
|
|
|
|
/** only one category can be in to the section one and two */
|
|
// if (showInSectionOne === true) {
|
|
// await _checkOtherSection('one');
|
|
// }
|
|
//
|
|
// if (showInSectionTwo === true) {
|
|
// await _checkOtherSection('two');
|
|
// }
|
|
|
|
const catData = {
|
|
title: title.trim().replace(titleFilterRegex, '-'),
|
|
priority: priority,
|
|
parent: parent || null,
|
|
// showInMenu: showInMenu,
|
|
navIndex: navIndex,
|
|
siteMap: siteMap,
|
|
special: special,
|
|
showInFooter,
|
|
url,
|
|
// showInSectionOne,
|
|
// showInSectionTwo,
|
|
// showInSectionThree,
|
|
pageContent,
|
|
modelType,
|
|
news,
|
|
child,
|
|
hasNewsTab,
|
|
hasContentTab,
|
|
hasMediaTab,
|
|
hasSubMenusTab,
|
|
hasTermsTab,
|
|
hasNotificationsTab,
|
|
hasSpecNewsTab,
|
|
hasNazarTab,
|
|
hasNewsFileTab,
|
|
defaultPageType,
|
|
hasManagerInfo,
|
|
managerName,
|
|
managerDescription,
|
|
_creator: req.user._id,
|
|
_updatedBy: req.user._id
|
|
}
|
|
|
|
let getParent;
|
|
|
|
if (parent) {
|
|
/**
|
|
* check parent exist or not
|
|
*/
|
|
getParent = await Category.findById(parent)
|
|
// .populate({
|
|
// path: 'parent',
|
|
// populate: {
|
|
// path: 'parent',
|
|
// model: 'Category'
|
|
// }
|
|
// });
|
|
|
|
/**
|
|
* if not found show error
|
|
*/
|
|
if (!getParent) return res404(res, `دسته بندی پدر پیدا نشد`);
|
|
|
|
////// start permissions
|
|
/** check special permission */
|
|
if (req.user.specialPermissions.length && await _checkSpecPermission(req, getParent)) {
|
|
return res.status(403).json({
|
|
message: `شما اجازه اضافه کردن فرزند جدید برای این دسته بندی را ندارید`
|
|
});
|
|
}
|
|
|
|
/** check can add child */
|
|
if (!getParent.child) return res.status(403).json({message: `این دسته بندی نمی تواند زیرمجموعه داشته باشد`});
|
|
|
|
|
|
/** check access portal */
|
|
if (!req.user.portals.includes(getParent.modelType)) return res.status(403).json({
|
|
message: `شما اجازه انتخاب این دسته بندی را ندارید`
|
|
});
|
|
|
|
|
|
/** check type */
|
|
if (getParent.modelType !== modelType) return res500(res, `شما اجازه استفاده این دسته بندی به عنوان سردسته را ندارید`);
|
|
////// end permissions
|
|
|
|
/**
|
|
* add level of new category
|
|
*/
|
|
catData.level = Number(getParent.level) + 1;
|
|
|
|
|
|
/** add tree cat */
|
|
// catData.treeCat = await _makeTreeCat(getParent);
|
|
const treeCatClone = JSON.parse(JSON.stringify(getParent.treeCat))
|
|
treeCatClone.push(getParent._id)
|
|
catData.treeCat = treeCatClone
|
|
catData.rootParent = getParent.rootParent || getParent._id
|
|
}
|
|
|
|
/**
|
|
* add new category
|
|
*/
|
|
const create = await Category.create(catData);
|
|
/**
|
|
* check added or not
|
|
*/
|
|
if (!create) return res500(res, `مشکلی در ثبت اطلاعات پیش آمده لطفا دوباره تلاش کنید`);
|
|
|
|
/**
|
|
* if have parent should added new category in child of parent category
|
|
* and set level for new category
|
|
*/
|
|
if (getParent) {
|
|
/**
|
|
* add new category for parent
|
|
*/
|
|
getParent.childs.push(create._id);
|
|
await getParent.save();
|
|
}
|
|
|
|
if (req.files?.managerCover) {
|
|
const image = req.files.managerCover;
|
|
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
|
|
return res.status(422).json({
|
|
validation: {
|
|
cover: {
|
|
msg: _sr['fa'].format.image
|
|
}
|
|
}
|
|
});
|
|
}
|
|
const imageName = `manager_${Date.now()}_${create._id}.${image.mimetype.split('/')[1]}`;
|
|
try {
|
|
const target = sharp(image.data)
|
|
await target
|
|
.resize(coverNewsWidth, coverNewsHeight, {fit: 'cover'})
|
|
.jpeg({quality: coverQuality})
|
|
.toFile(`./static/uploads/images/category/${imageName}`);
|
|
|
|
|
|
/**
|
|
* if exist old pic delete it from file
|
|
*/
|
|
// if (targetNews.cover !== noCover && !targetNews.imported) {
|
|
// let oldPic = `./static${targetNews.cover}`;
|
|
//
|
|
// if (await fs.existsSync(oldPic)) {
|
|
// fs.unlink(oldPic, (err) => {
|
|
// if (err) return res500(res, err?.message);
|
|
// });
|
|
// }
|
|
// }
|
|
|
|
// if (targetNews.thumbCover !== noCover && !targetNews.imported) {
|
|
// let oldPic = `./static${targetNews.thumbCover}`;
|
|
//
|
|
// if (await fs.existsSync(oldPic)) {
|
|
// fs.unlink(oldPic, (err) => {
|
|
// if (err) return res500(res, err?.message);
|
|
// });
|
|
// }
|
|
// }
|
|
|
|
create.managerCover = imageName;
|
|
await create.save()
|
|
} catch (e) {
|
|
return res500(res, e?.message);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* show result
|
|
*/
|
|
return res.json(create);
|
|
} catch (error) {
|
|
console.log(error);
|
|
/**
|
|
* if we got unkown error show to client
|
|
*/
|
|
res500(res, error.message);
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.updateCategory = [
|
|
[
|
|
body('title')
|
|
.notEmpty().withMessage(_sr['fa'].required.title),
|
|
|
|
// body('parent')
|
|
// .optional().isString().withMessage(`parent ${_sr['fa'].optional.string}`),
|
|
|
|
// body('showInMenu')
|
|
// .isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('navIndex')
|
|
.isNumeric().withMessage(_sr['fa'].format.number),
|
|
|
|
body('priority')
|
|
.isNumeric().withMessage(_sr['fa'].format.number),
|
|
|
|
// body('showInSectionOne')
|
|
// .optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
// body('showInSectionTwo')
|
|
// .optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
// body('showInSectionThree')
|
|
// .optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('siteMap')
|
|
.isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('special')
|
|
.isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('showInFooter')
|
|
.isNumeric().withMessage(_sr['fa'].format.number)
|
|
.bail()
|
|
.isIn([0, 1, 2, 3]).withMessage(`از بین اعداد 1و2و3 یک عدد ارسال کنید`),
|
|
|
|
body('url')
|
|
.optional().isString().withMessage(`url ${_sr['fa'].optional.string}`),
|
|
|
|
body('pageContent')
|
|
.optional().isString().withMessage(`pageContent ${_sr['fa'].optional.string}`),
|
|
|
|
body('news')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('child')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasNewsTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasContentTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasMediaTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasSubMenusTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasTermsTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasNotificationsTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasSpecNewsTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasNazarTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
|
|
body('hasNewsFileTab')
|
|
.optional().isBoolean().withMessage(_sr['fa'].format.boolean),
|
|
],
|
|
checkValidations(validationResult),
|
|
async (req, res) => {
|
|
try {
|
|
|
|
/**
|
|
* get data from input
|
|
*/
|
|
let {
|
|
title,
|
|
parent,
|
|
// showInMenu,
|
|
navIndex,
|
|
priority,
|
|
// showInSectionOne,
|
|
// showInSectionTwo,
|
|
// showInSectionThree,
|
|
siteMap,
|
|
special,
|
|
showInFooter,
|
|
url,
|
|
pageContent,
|
|
news,
|
|
child,
|
|
hasNewsTab,
|
|
hasContentTab,
|
|
hasMediaTab,
|
|
hasSubMenusTab,
|
|
hasTermsTab,
|
|
hasNotificationsTab,
|
|
hasSpecNewsTab,
|
|
hasNazarTab,
|
|
hasNewsFileTab,
|
|
defaultPageType,
|
|
hasManagerInfo,
|
|
managerName,
|
|
managerDescription
|
|
} = req.body;
|
|
|
|
/**
|
|
* get id
|
|
*/
|
|
const catId = req.params.id;
|
|
|
|
////////// permissions
|
|
// if (req.user.specialPermissions.length && !req.user.permissions.includes('categories-update')){
|
|
// return res.status(403).json(`شما اجازه بروزرسانی این دسته بندی را ندارید`);
|
|
// }
|
|
|
|
/**
|
|
* check category exist or not
|
|
*/
|
|
const targetCategory = await Category.findOne({
|
|
_id: catId
|
|
});
|
|
|
|
if (!targetCategory) return res404(res, `دسته بندی مورد نظر پیدا نشد`);
|
|
|
|
/** check special permission */
|
|
if (req.user.specialPermissions.length && await _checkSpecPermission(req, targetCategory)) {
|
|
return res.status(403).json({
|
|
message: `شما اجازه بروزرسانی این دسته بندی را ندارید`
|
|
});
|
|
}
|
|
|
|
/** check access portal */
|
|
if (!req.user.portals.includes(targetCategory.modelType)) {
|
|
return res.status(403).json({
|
|
message: `شما اجازه آپدیت این دسته بندی را ندارید`
|
|
});
|
|
}
|
|
|
|
/** only one category can be in to the section one and two */
|
|
// if (showInSectionOne === 'true') {
|
|
// targetCategory.showInSectionOne = await _checkOtherSection('one');
|
|
// }
|
|
|
|
// if (showInSectionTwo === 'true') {
|
|
// targetCategory.showInSectionTwo = await _checkOtherSection('two');
|
|
// }
|
|
|
|
|
|
if (targetCategory.title !== title) {
|
|
const checkDuppTitle = await Category.findOne({
|
|
title: title
|
|
});
|
|
|
|
if (checkDuppTitle) {
|
|
return res.status(422).json({validation: {title: {msg: _sr['fa'].duplicated.title}}});
|
|
}
|
|
}
|
|
|
|
// if(parent != null && targetCategory.parent != null && parent != targetCategory.parent) {
|
|
|
|
// /** check have news or not */
|
|
// var checkHaveNews = await News.find({allCat : [targetCategory._id]});
|
|
|
|
// if(checkHaveNews.length){
|
|
// return res.status(403).json({message :`این دسته بندی دارای اخبار می باشد و شما نمیتوانید دسته بندی والد آن را تغییر دهید لطفا ابتدا اخبار را حذف کرده سپس این کار را انجام دهید`});
|
|
// }
|
|
|
|
// /**
|
|
// * check new parent
|
|
// */
|
|
// var newParentCategory = await Category.findOne({_id : parent});
|
|
|
|
// if(!newParentCategory){
|
|
// return res404(res,`دسته بندی انتخاب شده پیدا نشد`);
|
|
// };
|
|
|
|
|
|
// if(newParentCategory.treeCat.includes(targetCategory._id)){
|
|
// return res.status(422).json({validation : {parent : {msg : ``}}})
|
|
// }
|
|
|
|
// /**
|
|
// * get category parent
|
|
// */
|
|
// if(targetCategory.parent){
|
|
// var parentCategory = await Category.findOne({_id : targetCategory.parent});
|
|
|
|
// if(parentCategory){
|
|
// /**
|
|
// * delete catId from old category
|
|
// */
|
|
// const index = parentCategory.childs.indexOf(targetCategory._id);
|
|
// if (index > -1) {
|
|
// parentCategory.childs.splice(index, 1);
|
|
|
|
// await parentCategory.save();
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// if(!newParentCategory.child){
|
|
// return res.status(403).json({message :`این دسته بندی اجازه داشتن زیرمجموعه ندارد`});
|
|
// }
|
|
|
|
// /** check access portal */
|
|
// if(!req.user.portals.includes(newParentCategory.modelType)){
|
|
// return res.status(403).json({message :`شما اجازه انتخاب این دسته بندی را ندارید`});
|
|
// }
|
|
|
|
// /** check type */
|
|
// if(newParentCategory.modelType != modelType){
|
|
// return res.status(403).json({message :`شما اجازه استفاده این دسته بندی به عنوان سردسته را ندارید`});
|
|
// }
|
|
|
|
// /**
|
|
// * add catId for new parnet
|
|
// */
|
|
// newParentCategory.childs.push(targetCategory._id);
|
|
// await newParentCategory.save();
|
|
|
|
// /**
|
|
// * update level
|
|
// */
|
|
// targetCategory.level = newParentCategory.level + 1;
|
|
// }
|
|
|
|
/**
|
|
* make update object
|
|
*/
|
|
targetCategory.title = title.trim().replace(titleFilterRegex, '-');
|
|
// targetCategory.showInMenu = showInMenu;
|
|
targetCategory.navIndex = navIndex;
|
|
targetCategory.priority = priority;
|
|
// targetCategory.showInSectionOne = showInSectionOne;
|
|
// targetCategory.showInSectionTwo = showInSectionTwo;
|
|
// targetCategory.showInSectionThree = showInSectionThree;
|
|
targetCategory.siteMap = siteMap;
|
|
targetCategory.special = special;
|
|
targetCategory._creator = req.user._id;
|
|
targetCategory._updatedBy = req.user._id;
|
|
targetCategory.showInFooter = showInFooter;
|
|
targetCategory.pageContent = pageContent;
|
|
targetCategory.child = child;
|
|
targetCategory.url = url;
|
|
targetCategory.news = news;
|
|
targetCategory.hasNewsTab = hasNewsTab;
|
|
targetCategory.hasContentTab = hasContentTab;
|
|
targetCategory.hasMediaTab = hasMediaTab;
|
|
targetCategory.hasSubMenusTab = hasSubMenusTab;
|
|
targetCategory.hasTermsTab = hasTermsTab;
|
|
targetCategory.hasNotificationsTab = hasNotificationsTab;
|
|
targetCategory.hasSpecNewsTab = hasSpecNewsTab;
|
|
targetCategory.hasNazarTab = hasNazarTab;
|
|
targetCategory.hasNewsFileTab = hasNewsFileTab;
|
|
targetCategory.defaultPageType = defaultPageType;
|
|
|
|
targetCategory.hasManagerInfo = hasManagerInfo;
|
|
targetCategory.managerName = managerName;
|
|
targetCategory.managerDescription = managerDescription;
|
|
|
|
|
|
if (req.files?.managerCover) {
|
|
const image = req.files.managerCover;
|
|
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) {
|
|
return res.status(422).json({
|
|
validation: {
|
|
cover: {
|
|
msg: _sr['fa'].format.image
|
|
}
|
|
}
|
|
});
|
|
}
|
|
const imageName = `manager_${Date.now()}_${targetCategory._id}.${image.mimetype.split('/')[1]}`;
|
|
try {
|
|
const target = sharp(image.data)
|
|
await target
|
|
.resize(coverNewsWidth, coverNewsHeight, {fit: 'cover'})
|
|
.jpeg({quality: coverQuality})
|
|
.toFile(`./static/uploads/images/category/${imageName}`);
|
|
|
|
|
|
/**
|
|
* if exist old pic delete it from file
|
|
*/
|
|
if (targetCategory.managerCover !== noCover) {
|
|
let oldPic = `./static${targetCategory.managerCover}`;
|
|
|
|
if (await fs.existsSync(oldPic)) {
|
|
fs.unlink(oldPic, (err) => {
|
|
if (err) return res500(res, err?.message);
|
|
});
|
|
}
|
|
}
|
|
|
|
targetCategory.managerCover = imageName;
|
|
} catch (e) {
|
|
return res500(res, e?.message);
|
|
}
|
|
}
|
|
|
|
await targetCategory.save();
|
|
|
|
/**
|
|
* show result
|
|
*/
|
|
return res.json(targetCategory);
|
|
|
|
} catch (error) {
|
|
return res500(res, error.message);
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.deletOneCategory = [
|
|
async (req, res) => {
|
|
try {
|
|
const catId = req.params.id;
|
|
|
|
/**
|
|
* check category
|
|
*/
|
|
const targetCategory = await Category.findOne({
|
|
_id: catId
|
|
});
|
|
|
|
if (!targetCategory) {
|
|
return res404(res, `دسته بندی مورد نظر پیدا نشد`);
|
|
}
|
|
|
|
/** check special permission */
|
|
if (req.user.specialPermissions.length && await _checkSpecPermission(req, targetCategory)) {
|
|
return res.status(403).json({
|
|
message: `شما اجازه حذف این دسته بندی را ندارید`
|
|
});
|
|
}
|
|
|
|
/** check access portal */
|
|
if (!req.user.portals.includes(targetCategory.modelType)) {
|
|
return res.status(403).json({
|
|
message: `شما اجازه حذف این دسته بندی را ندارید`
|
|
});
|
|
}
|
|
|
|
/** check special permissions */
|
|
if (req.user.specialPermissions.includes(targetCategory._id) && !targetCategory.parent) {
|
|
return res.status(403).json({
|
|
message: `شما اجازه حذف این دسته بندی را ندارید`
|
|
});
|
|
}
|
|
|
|
/** check owner ship */
|
|
if (req.user.specialPermissions.includes(targetCategory._id) && targetCategory.parent !== req.user._id) {
|
|
return res.status(403).json({
|
|
message: `شما اجازه حذف این دسته بندی را ندارید`
|
|
});
|
|
}
|
|
|
|
const checkHaveNews = await News.find({
|
|
allCat: [targetCategory._id]
|
|
});
|
|
|
|
if (checkHaveNews.length) {
|
|
return res.status(403).json({
|
|
message: `دسته بندی شما دارای خبر می باشد و قبل از حذف آن باید اخبار مربوط به این دسته بندی را حذف کنید`
|
|
});
|
|
}
|
|
|
|
if (targetCategory.childs.length) {
|
|
return res.status(403).json({
|
|
message: `دسته بندی مورد نظر دارای زیرمجموعه می باشد ابتدا زیرمجوعه ها را حذف کنید`
|
|
});
|
|
}
|
|
|
|
/**
|
|
* get category parent
|
|
*/
|
|
if (targetCategory.parent) {
|
|
const categoryParent = await Category.findOne({
|
|
_id: targetCategory.parent
|
|
});
|
|
|
|
if (categoryParent) {
|
|
/**
|
|
* delete catId from category parent
|
|
*/
|
|
const index = categoryParent.childs.indexOf(targetCategory._id);
|
|
if (index > -1) {
|
|
categoryParent.childs.splice(index, 1);
|
|
|
|
await categoryParent.save();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* delete category
|
|
*/
|
|
targetCategory.delete();
|
|
|
|
/**
|
|
* show result
|
|
*/
|
|
return res.json(targetCategory);
|
|
|
|
} catch (error) {
|
|
/**
|
|
* if we got unkown error show to client
|
|
*/
|
|
res500(res, error);
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.deleteAllCategory = [
|
|
async (req, res) => {
|
|
try {
|
|
|
|
} catch (error) {
|
|
/**
|
|
* if we got unkown error show to client
|
|
*/
|
|
res500(res, error);
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.getOneCategory = [
|
|
async (req, res) => {
|
|
try {
|
|
const catId = req.params.id;
|
|
|
|
/**
|
|
* get category
|
|
*/
|
|
const targetCategory = await Category.findOne({
|
|
_id: catId
|
|
});
|
|
|
|
/**
|
|
* if not exist
|
|
*/
|
|
if (!targetCategory) {
|
|
return res404(res, `دسته بندی مورد نظر پیدا نشد`);
|
|
}
|
|
|
|
/** check access portal */
|
|
if (!req.user.portals.includes(targetCategory.modelType)) {
|
|
return res.status(403).json({
|
|
message: `شما اجازه دسترسی به اطلاعات این دسته بندی را ندارید`
|
|
});
|
|
}
|
|
|
|
/**
|
|
* show result
|
|
*/
|
|
return res.json(targetCategory);
|
|
} catch (error) {
|
|
/**
|
|
* if we got unkown error show to client
|
|
*/
|
|
res500(res, error);
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.getAll = [
|
|
async (req, res) => {
|
|
try {
|
|
|
|
const findQuery = {};
|
|
let populate = {};
|
|
|
|
if (req.user.specialPermissions.length) {
|
|
findQuery._id = {$in: req.user.specialPermissions};
|
|
} else {
|
|
findQuery.parent = null;
|
|
// populate = {
|
|
// path: 'childs',
|
|
// populate: {
|
|
// path: 'childs'
|
|
// }
|
|
// };
|
|
}
|
|
|
|
if (req.user.portals.join() !== portal.join()) {
|
|
findQuery.modelType = req.user.portals[0];
|
|
}
|
|
|
|
/**
|
|
* get all category
|
|
*/
|
|
const getAll = await Category.find(findQuery).populate('').sort({
|
|
navIndex: 1
|
|
});
|
|
|
|
/**
|
|
* این قسمت ابجکت های تکراری را از بین میبره
|
|
*/
|
|
// if (req.user.specialPermissions.length) {
|
|
// /** جدا کردن دسته بندی های اصلی */
|
|
// const parents = getAll.filter((item) => !item.parent);
|
|
// /** جدا کردن دسته بندی های غیر اصلی */
|
|
// const nonParents = getAll.filter((item) => item.parent);
|
|
//
|
|
// /** با یک لوپ تو در تو اگر دسته بندی غیر اصلی در فرزندان دسته بندی اصلی وجود داشت حذف میشه */
|
|
// for (let i = 0; i < nonParents.length; i++) {
|
|
// for (let j = 0; j < parents.length; j++) {
|
|
// if (nonParents[i].treeCat.includes(parents[j]._id)) {
|
|
// getAll.splice(getAll.findIndex(item => item._id === nonParents[i]._id), 1);
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
/**
|
|
* show result
|
|
*/
|
|
return res.json(getAll);
|
|
} catch (error) {
|
|
return res500(res, error.message);
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.search = [
|
|
async (req, res) => {
|
|
try {
|
|
const term = req.body?.term?.toString().trim() || '';
|
|
|
|
/**
|
|
* search
|
|
*/
|
|
const search = await Category.find({
|
|
title: {
|
|
$regex: '.*' + term + '.*',
|
|
$options: 'i'
|
|
},
|
|
modelType: 'normal',
|
|
type: 'category'
|
|
});
|
|
|
|
/**
|
|
* show result
|
|
*/
|
|
return res.json(search);
|
|
} catch (error) {
|
|
return res500(res, error.message);
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.permissions = [
|
|
async (req, res) => {
|
|
try {
|
|
const type = req.query.type;
|
|
|
|
const findQuery = type ? {
|
|
modelType: type
|
|
} : {};
|
|
|
|
const categories = await Category.find(findQuery).populate('treeCat').sort({navIndex: 1}).lean();
|
|
|
|
let changeTitles = await _customTitle(categories);
|
|
|
|
let sortedCats = await _sortedCategory(changeTitles);
|
|
|
|
return res.json(sortedCats);
|
|
} catch (error) {
|
|
res500(res, error?.message);
|
|
}
|
|
}
|
|
]
|
|
|
|
module.exports.getParent = [
|
|
async (req, res) => {
|
|
try {
|
|
|
|
const findQuery = {};
|
|
|
|
const type = req.query.type;
|
|
|
|
// findQuery.parent = null;
|
|
|
|
if (req.user.specialPermissions.length) {
|
|
findQuery.$or = [
|
|
{
|
|
_id: {
|
|
$in: req.user.specialPermissions
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
if (req.user.portals.length) {
|
|
findQuery.modelType = {
|
|
$in: req.user.portals
|
|
};
|
|
}
|
|
|
|
if (type && type === 'news') {
|
|
findQuery.news = true;
|
|
}
|
|
|
|
if (type && type === 'child') {
|
|
findQuery.child = true;
|
|
}
|
|
|
|
/**
|
|
* get all category
|
|
*/
|
|
const getAll = await Category.find(findQuery).populate('parent').populate('treeCat').sort({navIndex: 1});
|
|
|
|
|
|
let changeTitles = await _customTitle(getAll);
|
|
|
|
let sortedCats = await _sortedCategory(changeTitles);
|
|
|
|
/**
|
|
* show result
|
|
*/
|
|
return res.json(sortedCats);
|
|
} catch (error) {
|
|
return res500(res, error?.message);
|
|
}
|
|
}
|
|
]
|
|
|
|
//////////// add attachment file to category
|
|
module.exports.addTermsFileToCategory = [
|
|
[
|
|
body('termsTitle')
|
|
.notEmpty().withMessage(_sr['fa'].required.title)
|
|
],
|
|
checkValidations(validationResult),
|
|
(req, res) => {
|
|
if (!req.files?.file) return res.status(422).json({validation: {file: {msg: _sr['fa'].required.file}}})
|
|
if (req.files?.file.mimetype.split('/')[1] !== 'pdf') return res.status(422).json({validation: {file: {msg: 'فقط فرمت PDF قابل قبول است'}}})
|
|
|
|
const data = {title: req.body.termsTitle}
|
|
const file = req.files.file
|
|
const fileName = req.body.termsTitle.replace(titleFilterRegex, '-') + '_' + Date.now() + '.pdf'
|
|
file.mv(`./static/uploads/files/terms/${fileName}`)
|
|
data.file = fileName
|
|
|
|
Category.findById(req.params.categoryId, (err, category) => {
|
|
if (err || !category) return res404(res, err)
|
|
category.terms.push(data)
|
|
category.save(err => {
|
|
if (err) return res500(res, err)
|
|
else return res.json({message: _sr['fa'].response.success_save})
|
|
})
|
|
})
|
|
}
|
|
]
|
|
|
|
module.exports.removeTermsFileFromCategory = [
|
|
(req, res) => {
|
|
Category.findOne({'terms._id': req.params.fileId}, (err, category) => {
|
|
if (err || !category) return res404(res, err)
|
|
const file = category.terms.id(req.params.fileId)
|
|
if (!file) return res404(res, 'not found')
|
|
file.remove()
|
|
fs.unlink(`./static/${file.file}`, err => {
|
|
if (err) console.log(err)
|
|
})
|
|
category.save(err => {
|
|
if (err) return res500(res, err)
|
|
else return res.json({message: _sr['fa'].response.success_remove})
|
|
})
|
|
})
|
|
}
|
|
]
|
|
|
|
/////////////////////////////////////////////////////////////////////// public
|
|
module.exports.getMenu = [
|
|
async (req, res) => {
|
|
try {
|
|
const portal = req.query?.portal || 'ostandari';
|
|
|
|
const findQuery = {
|
|
parent: null,
|
|
// showInMenu: true,
|
|
modelType: portal
|
|
};
|
|
let result = {};
|
|
/**
|
|
* get all category
|
|
*/
|
|
const getAll = await Category.find(findQuery).populate('treeCat').sort({
|
|
navIndex: 1,
|
|
// created_at: 1
|
|
}).select('title childs navIndex url modelType treeCat defaultPageType');
|
|
|
|
/// get all page content
|
|
const getContent = await Content.find({showInMenu : true})
|
|
|
|
result.categories = getAll;
|
|
result.staticContents = !!getContent.length;
|
|
|
|
|
|
/**
|
|
* show result
|
|
*/
|
|
return res.json(result)
|
|
} catch (error) {
|
|
return res500(res, error.message);
|
|
}
|
|
}
|
|
]
|