update:add ci cd files ==> do not edit those file

This commit is contained in:
mahyargdz
2024-10-10 21:49:00 +03:30
parent 6fe34708a2
commit 8cf0492c87
464 changed files with 79533 additions and 0 deletions
@@ -0,0 +1,132 @@
const BlogCategory = require('../models/BlogCategory')
const BlogPost = require('../models/BlogPost')
const {body, validationResult} = require('express-validator')
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions')
const {_sr} = require('../plugins/serverResponses')
module.exports.create = [
[
body('fa_title')
.notEmpty().withMessage(_sr['fa'].required.title)
.bail()
.custom((value, {req}) => {
return BlogCategory.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
.then(category => {
if (category) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
}),
body('en_title')
.notEmpty().withMessage(_sr['fa'].required.title)
.bail()
.custom((value, {req}) => {
return BlogCategory.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
.then(category => {
if (category) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
})
],
checkValidations(validationResult),
(req, res) => {
const {fa_title, en_title, fa_description, en_description} = req.body
const data = {
locale: {
fa: {
title: fa_title,
description: fa_description
},
en: {
title: en_title,
description: en_description
}
}
}
const category = new BlogCategory(data)
category.save(err => {
if (err) return res500(res, err)
else return res.json({message: _sr['fa'].response.success_save})
})
}
]
module.exports.getAll = [
(req, res) => {
BlogCategory.find({}, (err, categories) => {
if (err) return res500(res, err)
else return res.json(categories)
})
}
]
module.exports.getOne = [
(req, res) => {
BlogCategory.findById(req.params.id, (err, category) => {
if (err) return res500(res, err)
else return res.json(category)
})
}
]
module.exports.update = [
[
body('fa_title')
.notEmpty().withMessage(_sr['fa'].required.title)
.bail()
.custom((value, {req}) => {
return BlogCategory.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
.then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
}),
body('en_title')
.notEmpty().withMessage(_sr['fa'].required.title)
.bail()
.custom((value, {req}) => {
return BlogCategory.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
.then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
})
],
checkValidations(validationResult),
(req, res) => {
const {fa_title, en_title, fa_description, en_description} = req.body
const data = {
locale: {
fa: {
title: fa_title,
description: fa_description
},
en: {
title: en_title,
description: en_description
}
}
}
BlogCategory.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err || !oldData) return res404(res, err)
else return res.json({message: _sr['fa'].response.success_save})
})
}
]
module.exports.delete = [
async (req, res) => {
try {
const posts = await BlogPost.find({category: req.params.id})
if (posts.length) return res.status(403).json({message: 'Can not remove categories that have posts.'})
BlogCategory.findByIdAndRemove(req.params.id, (err, oldData) => {
if (err || !oldData) return res404(res, err)
else return res.json({message: _sr['fa'].response.success_remove})
})
} catch (e) {
return res500(res, e)
}
}
]
+358
View File
@@ -0,0 +1,358 @@
const BlogCategory = require('../models/BlogCategory')
const BlogPost = require('../models/BlogPost')
const mongoose = require('mongoose')
const sharp = require('sharp')
const fs = require('fs')
const {body, validationResult} = require('express-validator')
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions')
const {_sr} = require('../plugins/serverResponses')
// variables
const coverWidth = 1920
const coverHeight = 300
const coverQuality = 100
const coverThumbWidth = 400
const coverThumbHeight = 210
const coverThumbQuality = 100
const lastSectionImageWidth = 1920
const lastSectionImageHeight = 400
const lastSectionImageQuality = 100
const blogPaginateLimit = 10
const shortDescriptionLength = 250
const videoLimit = 150;
module.exports.create = [
[
body('en_title')
.notEmpty().withMessage(_sr['fa'].required.title)
.bail()
.custom((value, {req}) => {
return BlogPost.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
.then(post => {
if (post) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
}),
body('fa_title')
.if((value, {req}) => value)
.custom((value, {req}) => {
return BlogPost.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
.then(post => {
if (post) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
})
],
checkValidations(validationResult),
async (req, res) => {
if (!req.files || !req.files.cover) return res.status(422).json({validation: {cover: {msg: _sr['fa'].required.cover}}})
if (!_sr.supportedImageFormats.includes(req.files.cover.mimetype.split('/')[1])) return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}})
const {
fa_title,
en_title
} = req.body
const data = {
locale: {
fa: {
title: fa_title
},
en: {
title: en_title
}
}
}
const image = req.files.cover
const imageName = 'blog_' + Date.now() + '.jpg'
const imageThumb = 'thumb_' + imageName
try {
const target = await sharp(image.data)
await target
.resize(coverWidth, coverHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: coverQuality})
.toFile(`./static/uploads/images/blog/${imageName}`)
await target
.resize(coverThumbWidth, coverThumbHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: coverThumbQuality})
.toFile(`./static/uploads/images/blog/thumb/${imageThumb}`)
data.cover = imageName
data.thumb = imageThumb
} catch (e) {
return res500(res, e)
}
const post = new BlogPost(data)
post.save((err, data) => {
if (err) return res500(res, err)
return res.json(data)
})
}
]
module.exports.getAll = [
async (req, res) => {
///////////// get available options
// '/api/public/blogPosts' --> gets all published posts
// '/api/public/blogPosts?getAll=true' --> gets all posts either published or not
// '/api/public/blogPosts?limit=4' --> gets only 4 published post of all categories
// '/api/public/blogPosts?category=${encodeURIComponent(categoryTitle)}&page=${pageNumber}' --> gets posts depend on the category title and in chunked data
if (req.query.category) {
try {
const categoryID = await BlogCategory.findOne({$or: [{'locale.fa.title': req.query.category}, {'locale.en.title': req.query.category}]})
const filter = req.query.category === 'all' ? {published: true} : {published: true, category: categoryID._id}
BlogPost.paginate(filter, {page: req.query.page, limit: blogPaginateLimit, populate: 'category', sort: {_id: -1}}, (err, posts) => {
if (err) return res500(res, {message: _sr['fa'].not_found.item_id})
return res.json(posts)
})
} catch (e) {
return res500(res, e)
}
} else {
let query = {published: true}
if (req.query.getAll) delete query.published
const limit = Number(req.query.limit) || false
BlogPost.find(query).sort({_id: -1}).limit(limit).populate('category').exec((err, posts) => {
if (err) return res500(res, err)
else return res.json(posts)
})
}
}
]
module.exports.getOne = [
(req, res) => {
const query = req.params.id
const isObjectId = mongoose.isValidObjectId(query)
const noCategory = req.query.noCategory
const filter = isObjectId ? {_id: query} : {$or: [{'locale.fa.title': query}, {'locale.en.title': query}]}
BlogPost.findOne(filter).populate(noCategory ? '' : 'category').exec((err, post) => {
if (err || !post) return res404(res, err)
else return res.json(post)
})
}
]
module.exports.update = [
[
body('en_title')
.notEmpty().withMessage(_sr['fa'].required.title)
.bail()
.custom((value, {req}) => {
return BlogPost.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
.then(post => {
if (post && post._id.toString() !== req.params.id) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
}),
body('fa_title')
.if((value, {req}) => value)
.custom((value, {req}) => {
return BlogPost.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
.then(post => {
if (post && post._id.toString() !== req.params.id) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
}),
body('category')
.notEmpty().withMessage(_sr['fa'].required.category)
.bail()
.custom((value, {req}) => {
if (mongoose.isValidObjectId(value)) {
return BlogCategory.findById(value)
.then(category => {
if (!category) return Promise.reject(_sr['fa'].not_found.item_id)
else return true
})
} else return Promise.reject(_sr['fa'].required.category)
})
],
checkValidations(validationResult),
async (req, res) => {
const {
fa_title,
en_title,
fa_description,
en_description,
fa_short_description,
en_short_description,
fa_last_section_image_title,
en_last_section_image_title,
fa_last_section_image_description,
en_last_section_image_description,
fa_last_section_title,
en_last_section_title,
fa_last_section_description,
en_last_section_description,
category,
published
} = req.body
const data = {
locale: {
fa: {
title: fa_title || '',
description: fa_description || '',
short_description: fa_short_description.slice(0, shortDescriptionLength) || '' + ' ... ',
last_section_image_title: fa_last_section_image_title || '',
last_section_image_description: fa_last_section_image_description || '',
last_section_title: fa_last_section_title || '',
last_section_description: fa_last_section_description || ''
},
en: {
title: en_title || '',
description: en_description || '',
short_description: en_short_description.slice(0, shortDescriptionLength) || '' + ' ... ',
last_section_image_title: en_last_section_image_title || '',
last_section_image_description: en_last_section_image_description || '',
last_section_title: en_last_section_title || '',
last_section_description: en_last_section_description || ''
}
},
category, published
}
if (req.files) {
if (req.files.cover) {
if (!_sr.supportedImageFormats.includes(req.files.cover.mimetype.split('/')[1])) return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}})
const image = req.files.cover
const imageName = 'blog_' + Date.now() + '.jpg'
const imageThumb = 'thumb_' + imageName
try {
const target = await sharp(image.data)
await target
.resize(coverWidth, coverHeight, {fit: 'cover'})
.withMetadata()
.withMetadata()
.toFormat('jpg')
.jpeg({quality: coverQuality})
.toFile(`./static/uploads/images/blog/${imageName}`)
await target
.resize(coverThumbWidth, coverThumbHeight, {fit: 'cover'})
.withMetadata()
.withMetadata()
.toFormat('jpg')
.jpeg({quality: coverThumbQuality})
.toFile(`./static/uploads/images/blog/thumb/${imageThumb}`)
data.cover = imageName
data.thumb = imageThumb
} catch (e) {
return res500(res, e)
}
}
if (req.files.last_section_image) {
if (!_sr.supportedImageFormats.includes(req.files.last_section_image.mimetype.split('/')[1])) return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}})
const image = req.files.last_section_image
const imageName = 'blog_' + Date.now() + '.jpg'
const imageThumb = 'thumb_' + imageName
try {
const target = await sharp(image.data)
await target
.resize(lastSectionImageWidth, lastSectionImageHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: lastSectionImageQuality})
.toFile(`./static/uploads/images/blog/${imageName}`)
data.last_section_image = imageName
} catch (e) {
return res500(res, e)
}
}
if (req.files.video) {
const file = req?.files?.video
if (file.mimetype.split('/')[1] !== 'mp4') return res.status(422).json({validation: {video: {msg: _sr['fa'].format.video}}})
///// start convert byte to mb
const mb = file.size / (1024 * 1024);
///// check limit size of video
if (mb > videoLimit) {
return res.status(422).json({
validation: {file: {msg: `${_sr['fa'].max_char.data_size} 150 مگابایت`}}
});
}
const videoName = 'blog_' + Date.now() + '.mp4'
const uploadPath = `./static/uploads/videos/blog/${videoName}`;
try {
await file.mv(uploadPath);
data.video = videoName
} catch (e) {
return res500(res, e)
}
}
}
BlogPost.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err || !oldData) return res404(res, err)
if (req.files && req.files.cover) {
fs.unlink(`./static/${oldData.cover}`, (err) => {
if (err) console.log(err)
})
fs.unlink(`./static/${oldData.thumb}`, (err) => {
if (err) console.log(err)
})
}
if (req.files && req.files.last_section_image && oldData.last_section_image) {
fs.unlink(`./static/${oldData.last_section_image}`, (err) => {
if (err) console.log(err)
})
}
if (req.files && req.files.video && oldData.video) {
fs.unlink(`./static/${oldData.video}`, (err) => {
if (err) console.log(err)
})
}
return res.json({message: _sr['fa'].response.success_save})
})
}
]
module.exports.delete = [
(req, res) => {
BlogPost.findByIdAndRemove(req.params.id, (err, data) => {
if (err || !data) return res404(res, err)
fs.unlink(`./static/${data.cover}`, err => {
if (err) console.log(err)
})
fs.unlink(`./static/${data.thumb}`, err => {
if (err) console.log(err)
})
if (data.last_section_image) fs.unlink(`./static/${data.last_section_image}`, err => {
if (err) console.log(err)
})
if (data.video) fs.unlink(`./static/${data.video}`, err => {
if (err) console.log(err)
})
return res.json({message: _sr['fa'].response.success_remove})
})
}
]
+160
View File
@@ -0,0 +1,160 @@
const Catalog = require('../models/Catalog')
const mongoose = require('mongoose')
const sharp = require('sharp')
const fs = require('fs')
const {res404, res500} = require('../plugins/controllersHelperFunctions')
const {_sr} = require('../plugins/serverResponses')
// variables
const coverWidth = 390
const coverHeight = 551
const coverQuality = 100
module.exports.create = [
async (req, res) => {
if (!req.files || !req.files.file) return res.status(422).json({validation: {file: {msg: _sr['fa'].required.file}}})
if (!req.files || !req.files.cover) return res.status(422).json({validation: {cover: {msg: _sr['fa'].required.cover}}})
if (!_sr.supportedImageFormats.includes(req.files.cover.mimetype.split('/')[1])) return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}})
const {showInFa, showInEn, fa_title, en_title} = req.body
const data = {
locale: {
fa: {
title: fa_title
},
en: {
title: en_title
}
},
showInFa, showInEn
}
// file
const file = req.files.file
const fileName = 'orisoxin_catalog_' + Date.now() + '_' + file.name
file.mv(`./static/uploads/catalogs/file/${fileName}`)
data.file = fileName
// cover
const image = req.files.cover
const imageName = 'orisoxin_catalog_cover_' + Date.now() + '.jpg'
try {
const target = await sharp(image.data)
await target
.resize(coverWidth, coverHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: coverQuality})
.toFile(`./static/uploads/catalogs/cover/${imageName}`)
data.cover = imageName
} catch (e) {
return res500(res, e)
}
const catalog = new Catalog(data)
catalog.save((err, data) => {
if (err) return res500(res, err)
return res.json(data)
})
}
]
module.exports.getAll = [
(req, res) => {
Catalog.find({}).sort({_id: -1}).exec((err, images) => {
if (err) return res500(res, err)
else return res.json(images)
})
}
]
module.exports.getOne = [
(req, res) => {
Catalog.findById(req.params.id, (err, image) => {
if (err || !image) return res404(res, err)
else return res.json(image)
})
}
]
module.exports.update = [
async (req, res) => {
const {showInFa, showInEn, fa_title, en_title} = req.body
const data = {
locale: {
fa: {
title: fa_title
},
en: {
title: en_title
}
},
showInFa, showInEn
}
if (req.files) {
if (req.files.file) {
const file = req.files.file
const fileName = 'orisoxin_catalog_' + Date.now() + '_' + file.name
file.mv(`./static/uploads/catalogs/file/${fileName}`)
data.file = fileName
}
if (req.files.cover) {
if (!_sr.supportedImageFormats.includes(req.files.cover.mimetype.split('/')[1])) return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}})
const image = req.files.cover
const imageName = 'orisoxsin_cover_' + Date.now() + '.jpg'
try {
const target = await sharp(image.data)
await target
.resize(coverWidth, coverHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: coverQuality})
.toFile(`./static/uploads/catalogs/cover/${imageName}`)
data.cover = imageName
} catch (e) {
return res500(res, e)
}
}
}
Catalog.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err || !oldData) return res404(res, err)
if (req.files && req.files.file) {
fs.unlink(`./static/${oldData.file}`, (err) => {
if (err) console.log(err)
})
}
if (req.files && req.files.cover) {
fs.unlink(`./static/${oldData.cover}`, (err) => {
if (err) console.log(err)
})
}
return res.json({message: _sr['fa'].response.success_save})
})
}
]
module.exports.delete = [
(req, res) => {
Catalog.findByIdAndRemove(req.params.id, (err, data) => {
if (err || !data) return res404(res, err)
fs.unlink(`./static/${data.file}`, err => {
if (err) console.log(err)
})
fs.unlink(`./static/${data.cover}`, err => {
if (err) console.log(err)
})
return res.json({message: _sr['fa'].response.success_remove})
})
}
]
+125
View File
@@ -0,0 +1,125 @@
const ContactUs = require('../models/ContactUs')
const {body, validationResult} = require('express-validator')
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions')
const {_sr} = require('../plugins/serverResponses')
const nodemailer = require('nodemailer')
module.exports.create = [
[
body('locale')
.isLength({min: 2}).withMessage('locale is required')
.bail()
.custom((value, {req}) => {
return value === 'fa' || value === 'en' ? true : Promise.reject('locale is not correct')
}),
body('name')
.notEmpty().withMessage((value, {req}) => _sr[req.body.locale].required.name)
.bail()
.isLength({min: 2}).withMessage((value, {req}) => _sr[req.body.locale].min_char.min2),
body('email')
.notEmpty().withMessage((value, {req}) => _sr[req.body.locale].required.email)
.bail()
.isEmail().withMessage((value, {req}) => _sr[req.body.locale].format.email),
body('subject')
.notEmpty().withMessage((value, {req}) => _sr[req.body.locale].required.subject)
.bail()
.isLength({min: 4}).withMessage((value, {req}) => _sr[req.body.locale].min_char.min4),
body('message')
.notEmpty().withMessage((value, {req}) => _sr[req.body.locale].required.message)
.bail()
.isLength({min: 10}).withMessage((value, {req}) => _sr[req.body.locale].min_char.min10)
],
checkValidations(validationResult),
(req, res) => {
const {locale, name, email, subject, message} = req.body
const data = {locale, name, email, subject, message}
let transporter = nodemailer.createTransport({
host: 'mail.negareh-demo2.ir',
port: 587,
secure: false, // true for 465, false for other ports
auth: {
user: 'client@negareh-demo2.ir',
pass: 'JSAT}Q-RB_s0'
},
tls: {
rejectUnauthorized: false
}
})
const emailHTMLTemplate = `
<div style="direction: rtl;background-color: #ed1d24;overflow: hidden;">
<div style="width: 50%;border-radius: 10px;margin: 150px auto;background: #fff;text-align: center;padding: 20px;box-shadow: 0 15px 30px #000;">
<h2 style="color: #000;font-size: 22px;font-weight: bold;">
عنوان پیام:
</h2>
<p style="color: #000;margin-bottom: 20px;">${subject}</p>
<h2 style="color: #000;font-size: 22px;font-weight: bold;">
متن پیام:
</h2>
<p style="color: #000;margin-bottom: 20px;">${message}</p>
<div style="text-align: center;margin-top: 20px;">
<h2 style="color: #000;font-size: 22px;font-weight: bold;">
مشخصات فرستنده:
</h2>
<span>${name}</span>
<span>-</span>
<span>${email}</span>
</div>
</div>
<span style="opacity: 0">${Date.now()}</span>
</div>
`
// send mail with defined transport object
transporter.sendMail({
from: '"OrisOxin Website" <client@negareh-demo2.ir>', // sender address
to: 'info@orisoxin.com', // list of receivers
subject: subject,
text: message,
html: emailHTMLTemplate
})
new ContactUs(data).save((err, data) => {
if (err) return res500(res, err)
return res.json({message: _sr[req.body.locale].response.success_save})
})
}
]
module.exports.getAll = [
(req, res) => {
ContactUs.find({}, (err, data) => {
if (err) return res500(res, err)
return res.json(data)
})
}
]
module.exports.getOne = [
(req, res) => {
ContactUs.findById(req.params.id, (err, data) => {
if (err || !data) return res404(res, err)
data.read = true
data.save((err, message) => {
if (err) console.log(err)
return res.json(message)
})
})
}
]
@@ -0,0 +1,184 @@
const CustomerComment = require('../models/CustomerComment')
const sharp = require('sharp')
const fs = require('fs')
const {body, validationResult} = require('express-validator')
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions')
const {_sr} = require('../plugins/serverResponses')
// variables
const imageWidth = 350
const imageHeight = 350
const imageQuality = 100
module.exports.create = [
[
body('fa_name')
.notEmpty().withMessage((value, {req}) => _sr['fa'].required.name)
.bail()
.isLength({min: 2}).withMessage((value, {req}) => _sr['fa'].min_char.min2),
body('en_name')
.notEmpty().withMessage((value, {req}) => _sr['fa'].required.name)
.bail()
.isLength({min: 2}).withMessage((value, {req}) => _sr['fa'].min_char.min2),
body('fa_comment')
.notEmpty().withMessage((value, {req}) => _sr['fa'].required.caption)
.bail()
.isLength({min: 2}).withMessage((value, {req}) => _sr['fa'].min_char.min2),
body('en_comment')
.notEmpty().withMessage((value, {req}) => _sr['fa'].required.caption)
.bail()
.isLength({min: 2}).withMessage((value, {req}) => _sr['fa'].min_char.min2)
],
checkValidations(validationResult),
async (req, res) => {
const {fa_name, en_name, fa_position, en_position, fa_comment, en_comment} = req.body
const data = {
locale: {
fa: {
name: fa_name,
position: fa_position,
comment: fa_comment
},
en: {
name: en_name,
position: en_position,
comment: en_comment
}
}
}
if (req.files && req.files.image) {
const image = req.files.image
const imageName = 'customer_' + Date.now() + '.jpg'
data.image = imageName
try {
const target = await sharp(image.data)
await target
.resize(imageWidth, imageHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: imageQuality})
.toFile(`./static/uploads/images/customer/${imageName}`)
} catch (e) {
return res500(res, e)
}
}
new CustomerComment(data).save((err, data) => {
if (err) return res500(res, err)
return res.json({message: _sr['fa'].response.success_save})
})
}
]
module.exports.getAll = [
(req, res) => {
CustomerComment.find({}, (err, data) => {
if (err) return res500(res, err)
return res.json(data)
})
}
]
module.exports.getOne = [
(req, res) => {
CustomerComment.findById(req.params.id, (err, data) => {
if (err || !data) return res404(res, err)
else return res.json(data)
})
}
]
module.exports.update = [
[
body('fa_name')
.notEmpty().withMessage((value, {req}) => _sr['fa'].required.name)
.bail()
.isLength({min: 2}).withMessage((value, {req}) => _sr['fa'].min_char.min2),
body('en_name')
.notEmpty().withMessage((value, {req}) => _sr['fa'].required.name)
.bail()
.isLength({min: 2}).withMessage((value, {req}) => _sr['fa'].min_char.min2),
body('fa_comment')
.notEmpty().withMessage((value, {req}) => _sr['fa'].required.caption)
.bail()
.isLength({min: 2}).withMessage((value, {req}) => _sr['fa'].min_char.min2),
body('en_comment')
.notEmpty().withMessage((value, {req}) => _sr['fa'].required.caption)
.bail()
.isLength({min: 2}).withMessage((value, {req}) => _sr['fa'].min_char.min2)
],
checkValidations(validationResult),
async (req, res) => {
const {fa_name, en_name, fa_position, en_position, fa_comment, en_comment} = req.body
const data = {
locale: {
fa: {
name: fa_name,
position: fa_position,
comment: fa_comment
},
en: {
name: en_name,
position: en_position,
comment: en_comment
}
}
}
if (req.files && req.files.image) {
const image = req.files.image
const imageName = 'customer_' + Date.now() + '.jpg'
data.image = imageName
try {
const target = await sharp(image.data)
await target
.resize(imageWidth, imageHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: imageQuality})
.toFile(`./static/uploads/images/customer/${imageName}`)
} catch (e) {
return res500(res, e)
}
}
CustomerComment.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err || !oldData) return res404(res, err)
if (oldData.image && req.files && req.files.image) {
fs.unlink(`./static/${oldData.image}`, err => {
if (err) console.log(err)
})
}
return res.json({message: _sr['fa'].response.success_save})
})
}
]
module.exports.delete = [
(req, res) => {
CustomerComment.findByIdAndRemove(req.params.id, (err, oldData) => {
if (err || !oldData) return res404(res, err)
if (oldData.image) {
fs.unlink(`./static/${oldData.image}`, err => {
if (err) console.log(err)
})
}
return res.json({message: _sr['fa'].response.success_remove})
})
}
]
@@ -0,0 +1,221 @@
const GalleryCategory = require('../models/GalleryCategory')
const Gallery = require('../models/Gallery')
const {body, validationResult} = require('express-validator')
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions')
const {_sr} = require('../plugins/serverResponses')
const sharp = require('sharp')
const fs = require('fs')
const imageQuality = 100
const imageThumbWidth = 500
const imageThumbHeight = 500
const imageThumbQuality = 80
module.exports.create = [
[
body('fa_title')
.notEmpty().withMessage(_sr['fa'].required.title)
.bail()
.custom((value, {req}) => {
return GalleryCategory.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
.then(category => {
if (category) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
}),
body('en_title')
.notEmpty().withMessage(_sr['fa'].required.title)
.bail()
.custom((value, {req}) => {
return GalleryCategory.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
.then(category => {
if (category) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
})
],
checkValidations(validationResult),
async (req, res) => {
const {fa_title, en_title, fa_description, en_description , index} = req.body
if (!req.files || !req.files.cover) return res.status(422).json({validation: {cover: {msg: _sr['fa'].required.cover}}})
if (!_sr.supportedImageFormats.includes(req.files.cover.mimetype.split('/')[1])) return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}})
const image = req.files.cover
const imageName = 'categoryIMG_' + Date.now() + '.jpg'
const imageThumb = 'thumb_' + imageName
const data = {
locale: {
fa: {
title: fa_title,
description: fa_description
},
en: {
title: en_title,
description: en_description
}
},
index
}
try {
const target = await sharp(image.data)
await target
.toFormat('jpg')
.jpeg({quality: imageQuality})
.toFile(`./static/uploads/images/galleryCover/${imageName}`)
await target
.resize(imageThumbWidth, imageThumbHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: imageThumbQuality})
.toFile(`./static/uploads/images/galleryCover/thumb/${imageThumb}`)
data.cover = imageName
data.thumb = imageThumb
} catch (e) {
return res500(res, e)
}
const category = new GalleryCategory(data)
category.save(err => {
if (err) return res500(res, err)
else return res.json({message: _sr['fa'].response.success_save})
})
}
]
module.exports.getAll = [
(req, res) => {
GalleryCategory.find({}, (err, categories) => {
if (err) return res500(res, err)
else return res.json(categories)
}).sort({index : 1})
}
]
module.exports.getOne = [
(req, res) => {
GalleryCategory.findById(req.params.id, (err, category) => {
if (err) return res500(res, err)
else return res.json(category)
})
}
]
module.exports.update = [
[
body('fa_title')
.notEmpty().withMessage(_sr['fa'].required.title)
.bail()
.custom((value, {req}) => {
return GalleryCategory.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
.then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
}),
body('en_title')
.notEmpty().withMessage(_sr['fa'].required.title)
.bail()
.custom((value, {req}) => {
return GalleryCategory.findOne({$or: [{'locale.fa.title': value}, {'locale.en.title': value}]})
.then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
})
],
checkValidations(validationResult),
async (req, res) => {
const {fa_title, en_title, fa_description, en_description,index} = req.body
const image = req?.files?.cover
const data = {
locale: {
fa: {
title: fa_title,
description: fa_description
},
en: {
title: en_title,
description: en_description
}
},
index
}
if (image) {
if (!_sr.supportedImageFormats.includes(req.files.cover.mimetype.split('/')[1])) return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}})
const imageName = 'categoryIMG_' + Date.now() + '.jpg'
const imageThumb = 'thumb_' + imageName
try {
const target = await sharp(image.data)
await target
.toFormat('jpg')
.jpeg({quality: imageQuality})
.toFile(`./static/uploads/images/galleryCover/${imageName}`)
await target
.resize(imageThumbWidth, imageThumbHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: imageThumbQuality})
.toFile(`./static/uploads/images/galleryCover/thumb/${imageThumb}`)
data.cover = imageName
data.thumb = imageThumb
} catch (e) {
return res500(res, e)
}
}
GalleryCategory.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err || !oldData) return res404(res, err)
else {
if (image && oldData.cover) {
fs.unlink(`./static/${oldData.cover}`, (err) => {
if (err) console.log(err)
})
fs.unlink(`./static/${oldData.thumb}`, (err) => {
if (err) console.log(err)
})
}
return res.json({message: _sr['fa'].response.success_save})
}
})
}
]
module.exports.delete = [
async (req, res) => {
try {
const posts = await Gallery.find({category: req.params.id})
if (posts.length) return res.status(403).json({message: 'Can not remove categories that have posts.'})
GalleryCategory.findByIdAndRemove(req.params.id, (err, oldData) => {
if (err || !oldData) return res404(res, err)
else {
if (oldData.cover) {
fs.unlink(`./static/${oldData.cover}`, (err) => {
if (err) console.log(err)
})
fs.unlink(`./static/${oldData.thumb}`, (err) => {
if (err) console.log(err)
})
}
return res.json({message: _sr['fa'].response.success_remove})
}
})
} catch (e) {
return res500(res, e)
}
}
]
+190
View File
@@ -0,0 +1,190 @@
const Gallery = require('../models/Gallery')
const mongoose = require('mongoose')
const sharp = require('sharp')
const fs = require('fs')
const {body, validationResult} = require('express-validator')
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions')
const {_sr} = require('../plugins/serverResponses')
// variables
const imageQuality = 100
const imageThumbWidth = 500
const imageThumbHeight = 500
const imageThumbQuality = 80
module.exports.create = [
[
body('category')
.if((value, {req}) => req.body.noCategory === 'false')
.notEmpty().withMessage(_sr['fa'].required.category)
.bail()
.custom((value, {req}) => {
return mongoose.isValidObjectId(value) ? true : Promise.reject(_sr['fa'].required.category)
})
],
checkValidations(validationResult),
async (req, res) => {
try {
if (!req.files || !req.files.image) return res.status(422).json({validation: {image: {msg: _sr['fa'].required.image}}})
if (!_sr.supportedImageFormats.includes(req.files.image.mimetype.split('/')[1])) return res.status(422).json({validation: {image: {msg: _sr['fa'].format.image}}})
const {fa_caption, en_caption, category, noCategory} = req.body
const data = {
locale: {
fa: {
caption: fa_caption
},
en: {
caption: en_caption
}
},
noCategory
}
if (mongoose.isValidObjectId(category)) data.category = category
const image = req.files.image
const imageName = 'gallery_' + Date.now() + '.jpg'
const imageThumb = 'thumb_' + imageName
try {
const target = await sharp(image.data)
await target
.toFormat('jpg')
.jpeg({quality: imageQuality})
.toFile(`./static/uploads/images/gallery/${imageName}`)
await target
.resize(imageThumbWidth, imageThumbHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: imageThumbQuality})
.toFile(`./static/uploads/images/gallery/${imageThumb}`)
data.image = imageName
data.thumb = imageThumb
} catch (e) {
return res500(res , _sr['fa'].response.problem)
}
const post = new Gallery(data)
post.save((err, data) => {
if (err) return res500(res , _sr['fa'].response.problem)
return res.json(data)
})
}catch (e) {
return res500(res , _sr['fa'].response.problem)
}
}
]
module.exports.getAll = [
(req, res) => {
Gallery.find({}).populate('category').sort({_id: -1}).exec((err, images) => {
if (err) return res500(res, err)
else return res.json(images)
})
}
]
module.exports.getByCategoryId = [
(req, res) => {
Gallery.find({category: req.params.id}).sort({_id: -1}).exec((err, images) => {
if (err) return res500(res, err)
else return res.json(images)
})
}
]
module.exports.getOne = [
(req, res) => {
Gallery.findById(req.params.id, (err, image) => {
if (err || !image) return res404(res, err)
else return res.json(image)
})
}
]
module.exports.update = [
[
body('category')
.if((value, {req}) => req.body.noCategory === 'false')
.notEmpty().withMessage(_sr['fa'].required.category)
.bail()
.custom((value, {req}) => {
return mongoose.isValidObjectId(value) ? true : Promise.reject(_sr['fa'].required.category)
})
],
checkValidations(validationResult),
async (req, res) => {
const {fa_caption, en_caption, category, noCategory} = req.body
const data = {
locale: {
fa: {
caption: fa_caption
},
en: {
caption: en_caption
}
},
noCategory
}
if (mongoose.isValidObjectId(category)) data.category = category
if (req.files && req.files.image) {
if (!_sr.supportedImageFormats.includes(req.files.image.mimetype.split('/')[1])) return res.status(422).json({validation: {image: {msg: _sr['fa'].format.image}}})
const image = req.files.image
const imageName = 'gallery_' + Date.now() + '.jpg'
const imageThumb = 'thumb_' + imageName
try {
const target = await sharp(image.data)
await target
.toFormat('jpg')
.jpeg({quality: imageQuality})
.toFile(`./static/uploads/images/gallery/${imageName}`)
await target
.resize(imageThumbWidth, imageThumbHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: imageThumbQuality})
.toFile(`./static/uploads/images/gallery/${imageThumb}`)
data.image = imageName
data.thumb = imageThumb
} catch (e) {
return res500(res, e)
}
}
Gallery.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err || !oldData) return res404(res, err)
if (req.files && req.files.image) {
fs.unlink(`./static/${oldData.image}`, (err) => {
if (err) console.log(err)
})
fs.unlink(`./static/${oldData.thumb}`, (err) => {
if (err) console.log(err)
})
}
return res.json({message: _sr['fa'].response.success_save})
})
}
]
module.exports.delete = [
(req, res) => {
Gallery.findByIdAndRemove(req.params.id, (err, data) => {
if (err || !data) return res404(res, err)
fs.unlink(`./static/${data.image}`, err => {
if (err) console.log(err)
})
fs.unlink(`./static/${data.thumb}`, err => {
if (err) console.log(err)
})
return res.json({message: _sr['fa'].response.success_remove})
})
}
]
@@ -0,0 +1,247 @@
const Project = require('../models/Project')
const ProjectCategory = require('../models/ProjectCategory')
const {body, validationResult} = require('express-validator')
const {_sr} = require('../plugins/serverResponses')
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions')
const mongoose = require('mongoose')
module.exports.create = [
[
body('fa_name')
.notEmpty().withMessage(_sr['fa'].required.title)
.bail()
.custom((value, {req}) => {
return ProjectCategory.findOne({$or: [{'locale.fa.name': value}, {'locale.en.name': value}]})
.then(product => {
if (product) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
}),
body('en_name')
.notEmpty().withMessage(_sr['fa'].required.title)
.bail()
.custom((value, {req}) => {
return ProjectCategory.findOne({$or: [{'locale.fa.name': value}, {'locale.en.name': value}]})
.then(product => {
if (product) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
}),
],
checkValidations(validationResult),
(req, res) => {
const {fa_name, en_name} = req.body
const data = {
locale: {
fa: {
name: fa_name
},
en: {
name: en_name
}
}
}
const projectCategory = new ProjectCategory(data)
projectCategory.save((err, data) => {
if (err) return res500(res, err)
else return res.json(data)
})
}
]
module.exports.getAll = [
(req, res) => {
ProjectCategory.find({}).exec((err, projects) => {
if (err) return res500(res, err)
else return res.json(projects)
})
}
]
module.exports.getOne = [
(req, res) => {
ProjectCategory.findById(req.params.id, (err, projectCategory) => {
if (err || !projectCategory) return res404(res, err)
else return res.json(projectCategory)
})
}
]
module.exports.update = [
[
body('fa_name')
.notEmpty().withMessage(_sr['fa'].required.title)
.bail()
.custom((value, {req}) => {
return ProjectCategory.findOne({$or: [{'locale.fa.name': value}, {'locale.en.name': value}]})
.then(product => {
if (product && product._id.toString() !== req.params.id) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
}),
body('en_name')
.notEmpty().withMessage(_sr['fa'].required.title)
.bail()
.custom((value, {req}) => {
return ProjectCategory.findOne({$or: [{'locale.fa.name': value}, {'locale.en.name': value}]})
.then(product => {
if (product && product._id.toString() !== req.params.id) return Promise.reject(_sr['fa'].duplicated.title)
else return true
})
})
],
checkValidations(validationResult),
(req, res) => {
const {
fa_name,
en_name
} = req.body
const data = {
locale: {
fa: {
name: fa_name
},
en: {
name: en_name
}
}
}
ProjectCategory.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err || !oldData) return res404(res, err)
return res.json({message: _sr['fa'].response.success_save})
})
}
]
module.exports.delete = [
async (req, res) => {
const projects = await Project.find({category: req.params.id})
if (projects.length) return res.status(403).json({message: 'نمیتوان دسته بندی هایی که دارای پروژه هستند را حذف کرد.'})
ProjectCategory.findByIdAndRemove(req.params.id, (err, oldData) => {
if (err || !oldData) return res404(res, err)
return res.json({message: _sr['fa'].response.success_remove})
})
}
]
////////////////////////////
module.exports.addTagToCategory = [
[
body('fa_tagName')
.notEmpty().withMessage(_sr['fa'].required.title),
body('en_tagName')
.notEmpty().withMessage(_sr['fa'].required.title)
],
checkValidations(validationResult),
(req, res) => {
const {fa_tagName, en_tagName} = req.body
ProjectCategory.findById(req.params.categoryId, (err, data) => {
if (err || !data) return res404(res, err)
data.tags.push({
locale: {
fa: {
name: fa_tagName
},
en: {
name: en_tagName
}
}
})
data.save(err => {
if (err) console.log(err)
else return res.json({message: _sr['fa'].response.success_save})
})
})
}
]
module.exports.removeTagFromCategory = [
async (req, res) => {
const projects = await Project.find({tag: req.params.id})
if (projects.length) return res.status(403).json({message: 'نمیتوان دسته بندی هایی که دارای پروژه هستند را حذف کرد.'})
ProjectCategory.findOne({'tags._id': req.params.tagId}, (err, project) => {
if (err || !project) return res404(res, err)
const tag = project.tags.id(req.params.tagId)
tag.remove(err => {
if (err) console.log(err)
})
project.save(err => {
if (err) console.log(err)
else return res.json({message: _sr['fa'].response.success_save})
})
})
}
]
// module.exports.getAll = [
// (req, res) => {
// return res.json([
// {
// id: 'drilling',
// locale: {
// fa: {
// name: 'صنعت حفاری',
// },
// en: {
// name: 'Drilling industry'
// }
// }
// },
// {
// id: 'piping',
// locale: {
// fa: {
// name: 'صنعت خطوط لوله و اتصالات',
// },
// en: {
// name: 'Pipeline and fittings industry'
// }
// }
// },
// {
// id: 'ward',
// locale: {
// fa: {
// name: 'صنعت پتروشیمی',
// },
// en: {
// name: 'Petrochemical industry'
// }
// }
// },
// // {
// // id: 'srp',
// // locale: {
// // fa: {
// // name: 'پمپ های درون چاهی SRP',
// // },
// // en: {
// // name: 'Manufacturer of SRP well pumps'
// // }
// // }
// // },
// // {
// // id: 'sm',
// // locale: {
// // fa: {
// // name: 'طراحی و ساخت unit های فرآورش و نمک زدایی پیش ساخته Skid Mounted',
// // },
// // en: {
// // name: 'Skid Mounted'
// // }
// // }
// // },
// ])
// }
// ]
+515
View File
@@ -0,0 +1,515 @@
const Project = require('../models/Project')
const {body, validationResult} = require('express-validator')
const {_sr} = require('../plugins/serverResponses')
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions')
const sharp = require('sharp')
const mongoose = require('mongoose')
const fs = require('fs')
const readXlsxFile = require('read-excel-file/node')
// variables
const shortDescriptionMaxLength = 250
const coverWidth = 1920
const coverHeight = 418
const coverQuality = 100
const thumbWidth = 770
const thumbHeight = 354
const thumbQuality = 80
const s2ImageWidth = 1272
const s2ImageHeight = 670
const s2ImageQuality = 100
const s4ImageWidth = 1920
const s4ImageHeight = 500
const s4ImageQuality = 100
const s5ImageWidth = 1270
const s5ImageHeight = 950
const s5ImageQuality = 100
const s6ImageWidth = 1270
const s6ImageHeight = 950
const s6ImageQuality = 100
module.exports.create = [
[
body('fa_title')
.notEmpty().withMessage(_sr['fa'].required.title),
body('en_title')
.notEmpty().withMessage(_sr['fa'].required.title),
body('category')
.notEmpty().withMessage(_sr['fa'].required.category),
body('project_date')
.notEmpty().withMessage(_sr['fa'].required.date)
.bail()
.isNumeric().withMessage(_sr['fa'].format.number)
.bail()
.isLength({min: 4, max: 4}).withMessage('مقدار باید 4 رقمی باشد'),
body('has_details')
.notEmpty().withMessage('this flag is required')
],
checkValidations(validationResult),
(req, res) => {
const {fa_title, en_title, fa_client, en_client, category, tag, has_details, project_date} = req.body
const data = {
locale: {
fa: {
title: fa_title,
client: fa_client
},
en: {
title: en_title,
client: en_client
}
},
category,
has_details,
project_date
}
if (tag) data.tag = tag
if (!has_details) data.completed = true
const project = new Project(data)
project.save((err, data) => {
if (err) return res500(res, err)
else return res.json(data)
})
}
]
module.exports.addExel = [
async (req, res) => {
const allData = []
// const rows = await readXlsxFile(`LSAW.xlsx`, {sheet: 1})
// await Project.deleteMany({category : '61544d48340d0704add10a10'})
// for (let i = 0; i < rows.length; i++) {
// // const project = await Project.findOne({$or : [
// // {'locale.en.title' : rows[i][1].replace(/\n/g, " ")},
// // {'locale.fa.title' : rows[i][1].replace(/\n/g, " ")}
// // ]})
//
// // if (!project){
// allData.push({
// locale: {
// fa: {
// title:rows[i][1] && typeof rows[i][1]==='string'? rows[i][1].replace(/\n/g, " ") : rows[i][1],
// client: rows[i][3],
// area : rows[i][2]
// },
// en: {
// title: rows[i][1] && typeof rows[i][1]==='string'? rows[i][1].replace(/\n/g, " ") : rows[i][1],
// client: rows[i][3],
// area : rows[i][2]
// }
// },
// category : '61544d0d41304b825a19901c',
// tag : '61554c9e4b787cbf8b9bd6fd',
// importWithCode : true,
// project_date : rows[i][4]
// })
// }
// }
// console.log(allData.length)
// let addData = allData.map(data => Project.create(data));
// const result = await Promise.all(addData)
// return res.json(result)
const allPro = await Project.find()
for (const pro of allPro) {
if (pro?.locale?.en?.size || pro?.locale?.en?.area){
pro.size = pro.locale.en.size
pro.area = pro.locale.en.size
}
}
return res.json(allData)
// return res.json(rows)
// const data = {
// locale: {
// fa: {
// title: fa_title,
// client: fa_client
// },
// en: {
// title: en_title,
// client: en_client
// }
// },
// category,
// has_details,
// project_date
// }
// if (tag) data.tag = tag
// if (!has_details) data.completed = true
// const project = new Project(data)
// project.save((err, data) => {
// if (err) return res500(res, err)
// else return res.json(data)
// })
}
]
module.exports.getAll = [
(req, res) => {
Project.find().populate('category').sort({project_date : -1}).exec((err, projects) => {
if (err) return res500(res, err)
else return res.json(projects)
})
}
]
module.exports.getOne = [
(req, res) => {
const query = req.params.id
const isObjectId = mongoose.isValidObjectId(query)
const filter = isObjectId ? {_id: query} : {$or: [{'locale.fa.title': query}, {'locale.en.title': query}]}
Project.findOne(filter, (err, project) => {
if (err || !project) return res404(res, err)
else return res.json(project)
})
}
]
module.exports.update = [
[
body('category')
.notEmpty().withMessage(_sr['fa'].required.category),
body('fa_title')
.notEmpty().withMessage(_sr['fa'].required.title),
body('en_title')
.notEmpty().withMessage(_sr['fa'].required.title),
body('category')
.notEmpty().withMessage(_sr['fa'].required.category),
body('project_date')
.notEmpty().withMessage(_sr['fa'].required.date)
.bail()
.isNumeric().withMessage(_sr['fa'].format.number)
.bail()
.isLength({min: 4, max: 4}).withMessage('مقدار باید 4 رقمی باشد'),
body('has_details')
.notEmpty().withMessage('this flag is required')
],
checkValidations(validationResult),
(req, res) => {
const {
fa_title,
en_title,
fa_short_description,
en_short_description,
fa_description,
en_description,
//
fa_client,
en_client,
//
fa_size,
en_size,
//
fa_area,
en_area,
//
fa_s3_title,
en_s3_title,
fa_s3_description,
en_s3_description,
//
fa_s5_title,
en_s5_title,
fa_s5_description,
en_s5_description,
//
fa_s6_title,
en_s6_title,
fa_s6_description,
en_s6_description,
category,
tag,
project_date,
has_details
} = req.body
const data = {
locale: {
fa: {
title: fa_title,
short_description: fa_short_description.slice(0, shortDescriptionMaxLength) + ' ... ',
description: fa_description,
//
client: fa_client,
size: fa_size,
area: fa_area,
//
s3_title: fa_s3_title,
s3_description: fa_s3_description,
//
s5_title: fa_s5_title,
s5_description: fa_s5_description,
//
s6_title: fa_s6_title,
s6_description: fa_s6_description
},
en: {
title: en_title,
short_description: en_short_description.slice(0, shortDescriptionMaxLength) + ' ... ',
description: en_description,
//
client: en_client,
size: en_size,
area: en_area,
//
s3_title: en_s3_title,
s3_description: en_s3_description,
//
s5_title: en_s5_title,
s5_description: en_s5_description,
//
s6_title: en_s6_title,
s6_description: en_s6_description
}
},
category,
project_date,
has_details,
}
if (tag) data.tag = tag
if (req.files) {
if (req.files.cover) {
const cover = req.files.cover
const coverName = 'project_' + Date.now() + '.jpg'
if (!_sr.supportedImageFormats.includes(cover.mimetype.split('/')[1])) return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}})
data.cover = coverName
data.thumb = 'thumb_' + coverName
const target = new sharp(cover.data)
target
.resize(coverWidth, coverHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: coverQuality})
.toFile(`./static/uploads/images/projects/${coverName}`)
target
.resize(thumbWidth, thumbHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: thumbQuality})
.toFile(`./static/uploads/images/projects/thumb_${coverName}`)
}
if (req.files.s2_image) {
const s2_image = req.files.s2_image
const s2_imageName = 's2_image_' + Date.now() + '.jpg'
if (!_sr.supportedImageFormats.includes(s2_image.mimetype.split('/')[1])) return res.status(422).json({validation: {s2_image: {msg: _sr['fa'].format.image}}})
data.s2_image = s2_imageName
const target = new sharp(s2_image.data)
target
.resize(s2ImageWidth, s2ImageHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: s2ImageQuality})
.toFile(`./static/uploads/images/projects/${s2_imageName}`)
}
if (req.files.s4_image) {
const s4_image = req.files.s4_image
const s4_imageName = 's4_image_' + Date.now() + '.jpg'
if (!_sr.supportedImageFormats.includes(s4_image.mimetype.split('/')[1])) return res.status(422).json({validation: {s4_image: {msg: _sr['fa'].format.image}}})
data.s4_image = s4_imageName
const target = new sharp(s4_image.data)
target
.resize(s4ImageWidth, s4ImageHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: s4ImageQuality})
.toFile(`./static/uploads/images/projects/${s4_imageName}`)
}
if (req.files.s5_image) {
const s5_image = req.files.s5_image
const s5_imageName = 's5_image_' + Date.now() + '.jpg'
if (!_sr.supportedImageFormats.includes(s5_image.mimetype.split('/')[1])) return res.status(422).json({validation: {s5_image: {msg: _sr['fa'].format.image}}})
data.s5_image = s5_imageName
const target = new sharp(s5_image.data)
target
.resize(s5ImageWidth, s5ImageHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: s5ImageQuality})
.toFile(`./static/uploads/images/projects/${s5_imageName}`)
}
if (req.files.s6_image) {
const s6_image = req.files.s6_image
const s6_imageName = 's6_image_' + Date.now() + '.jpg'
if (!_sr.supportedImageFormats.includes(s6_image.mimetype.split('/')[1])) return res.status(422).json({validation: {s6_image: {msg: _sr['fa'].format.image}}})
data.s6_image = s6_imageName
const target = new sharp(s6_image.data)
target
.resize(s6ImageWidth, s6ImageHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: s6ImageQuality})
.toFile(`./static/uploads/images/projects/${s6_imageName}`)
}
}
Project.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err || !oldData) return res404(res, err)
if (req.files) {
if (req.files.cover && oldData.cover) {
fs.unlink(`./static/${oldData.cover}`, err => {
if (err) console.log(err)
})
fs.unlink(`./static/${oldData.thumb}`, err => {
if (err) console.log(err)
})
}
if (req.files.s2_image && oldData.s2_image) {
fs.unlink(`./static/${oldData.s2_image}`, err => {
if (err) console.log(err)
})
}
if (req.files.s4_image && oldData.s4_image) {
fs.unlink(`./static/${oldData.s4_image}`, err => {
if (err) console.log(err)
})
}
if (req.files.s5_image && oldData.s5_image) {
fs.unlink(`./static/${oldData.s5_image}`, err => {
if (err) console.log(err)
})
}
if (req.files.s6_image && oldData.s6_image) {
fs.unlink(`./static/${oldData.s6_image}`, err => {
if (err) console.log(err)
})
}
}
return res.json({message: _sr['fa'].response.success_save})
})
}
]
module.exports.delete = [
(req, res) => {
Project.findByIdAndRemove(req.params.id, async (err, oldData) => {
if (err || !oldData) return res404(res, err)
if (oldData.cover) {
fs.unlink(`./static/${oldData.cover}`, err => {
if (err) console.log(err)
})
fs.unlink(`./static/${oldData.thumb}`, err => {
if (err) console.log(err)
})
}
if (oldData.s2_image) {
fs.unlink(`./static/${oldData.s2_image}`, err => {
if (err) console.log(err)
})
}
if (oldData.s4_image) {
fs.unlink(`./static/${oldData.s4_image}`, err => {
if (err) console.log(err)
})
}
if (oldData.s5_image) {
fs.unlink(`./static/${oldData.s5_image}`, err => {
if (err) console.log(err)
})
}
if (oldData.s6_image) {
fs.unlink(`./static/${oldData.s6_image}`, err => {
if (err) console.log(err)
})
}
return res.json({message: _sr['fa'].response.success_remove})
})
}
]
////////////////////////////
module.exports.addImageToProjectGallery = [
async (req, res) => {
if (!req.files || !req.files.image) return res.status(422).json({validation: {image: {msg: _sr['fa'].required.image}}})
try {
const project = await Project.findById(req.params.project_id)
if (!project) return res404(res, 'project not found')
const image = req.files.image
const imageName = 'project_images_' + Date.now() + '.jpg'
const thumbName = 'thumb_' + imageName
if (!_sr.supportedImageFormats.includes(image.mimetype.split('/')[1])) return res.status(422).json({validation: {image: {msg: _sr['fa'].format.image}}})
const target = new sharp(image.data)
target
.resize(s4ImageWidth, s4ImageHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: s4ImageQuality})
.toFile(`./static/uploads/images/projects/${thumbName}`)
image.mv(`./static/uploads/images/projects/${imageName}`, err => {
if (err) console.log(err)
})
project.images.push({image: imageName, thumb: thumbName})
project.save(err => {
if (err) return res500(res, err)
else return res.json({message: _sr['fa'].response.success_save})
})
} catch (e) {
return res404(res, e)
}
}
]
module.exports.removeImageFromProject = [
(req, res) => {
Project.findOne({'images._id': req.params.image_id}, (err, project) => {
if (err || !project) return res404(res, err)
const image = project.images.id(req.params.image_id)
image.remove(err => {
if (err) console.log(err)
fs.unlink(`../static/${image.image}`, err => {
if (err) console.log(err)
})
fs.unlink(`../static/${image.thumb}`, err => {
if (err) console.log(err)
})
})
project.save(err => {
if (err) console.log(err)
else return res.json({message: _sr['fa'].response.success_save})
})
})
}
]
+193
View File
@@ -0,0 +1,193 @@
const SiteSetting = require('../models/SiteSetting')
const BlogPost = require('../models/BlogPost')
const GalleryCategory = require('../models/GalleryCategory')
const Project = require('../models/Project')
const mongoose = require('mongoose')
const sharp = require('sharp')
const fs = require('fs')
const {body, param, validationResult} = require('express-validator')
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions')
const {_sr} = require('../plugins/serverResponses')
// variables
const imageWidth = 1920
const imageHeight = 600
const imageQuality = 100
module.exports.update = [
async (req, res) => {
try {
const setting = await SiteSetting.findOne()
if (setting) {
} else {
}
} catch (e) {
return res500(res, _sr['fa'].response.problem)
}
}
]
module.exports.getAllByAdmin = [
async (req, res) => {
try {
const images = await SiteSetting.findOne()
if (images) {
return res.json(images)
} else {
const create = await SiteSetting.create({})
return res.json(create)
}
} catch (e) {
return res500(res, _sr['fa'].response.problem)
}
}
]
module.exports.uploadCover = [
[
param('id')
.notEmpty().withMessage('لطفا نوع عکس را مشخص کنید')
],
checkValidations(validationResult),
async (req, res) => {
try {
const picType = req?.params?.id
const image = req?.files?.file
let validation = {validation: {}}
if (!image) {
validation.validation[picType] = {msg: _sr['fa'].required.image}
return res.status(422).json(validation)
}
if (image.mimetype.split('/')[1] !== 'jpeg' && image.mimetype.split('/')[1] !== 'jpg') {
validation.validation[picType] = {msg: _sr['fa'].format.image}
res.status(422).json(validation)
}
const setting = await SiteSetting.findOne()
if (!setting) return res500(res, _sr['fa'].response.problem)
if (!setting[picType]) {
validation[picType] = {msg: 'نوع عکس وارد شده صحیح نمی باشد'}
return res.status(422).json(validation)
}
const imageName = `setting_${picType}_${Date.now()}.jpeg`
if (image && !setting[picType].includes('undefined')) {
fs.unlink(`../static/${setting[picType]}`, (err) => {
if (err) console.log(err)
})
}
const target = await sharp(image.data)
await target
.resize(imageWidth, imageHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpeg')
.jpeg({quality: imageQuality})
.toFile(`./static/uploads/images/setting/${imageName}`)
setting[picType] = imageName
await setting.save();
return res.json({message: _sr['fa'].response.success_save})
} catch (e) {
console.log(e.message)
return res500(res, _sr['fa'].response.problem)
}
}
]
module.exports.getAllByUser = [
async (req, res) => {
try {
const images = await SiteSetting.findOne()
if (images) {
return res.json(images)
} else {
return res.json({
aboutUS: null,
activity: null,
projects: null,
gallery: null,
catalog: null,
blogs: null,
})
}
} catch (e) {
return res500(res, _sr['fa'].response.problem)
}
}
]
module.exports.search = [
async (req, res) => {
const {terms} = req.query;
try {
const requests = [
BlogPost.find({
published: true,
$or: [
{'locale.fa.title': {$regex: terms, $options: 'i'}},
{'locale.fa.description': {$regex: terms, $options: 'i'}},
{'locale.fa.short_description': {$regex: terms, $options: 'i'}},
{'locale.en.title': {$regex: terms, $options: 'i'}},
{'locale.en.description': {$regex: terms, $options: 'i'}},
{'locale.en.short_description': {$regex: terms, $options: 'i'}},
]
}),
GalleryCategory.find({
$or: [
{'locale.fa.title': {$regex: terms, $options: 'i'}},
{'locale.en.title': {$regex: terms, $options: 'i'}},
]
}),
Project.find({
$or: [
{'locale.fa.title': {$regex: terms, $options: 'i'}},
{'locale.fa.short_description': {$regex: terms, $options: 'i'}},
{'locale.fa.description': {$regex: terms, $options: 'i'}},
{'locale.fa.s3_title': {$regex: terms, $options: 'i'}},
{'locale.fa.s3_description': {$regex: terms, $options: 'i'}},
{'locale.fa.s5_title': {$regex: terms, $options: 'i'}},
{'locale.fa.s5_description': {$regex: terms, $options: 'i'}},
{'locale.fa.s6_title': {$regex: terms, $options: 'i'}},
{'locale.fa.s6_description': {$regex: terms, $options: 'i'}},
{'locale.en.title': {$regex: terms, $options: 'i'}},
{'locale.en.short_description': {$regex: terms, $options: 'i'}},
{'locale.en.description': {$regex: terms, $options: 'i'}},
{'locale.en.s3_title': {$regex: terms, $options: 'i'}},
{'locale.en.s3_description': {$regex: terms, $options: 'i'}},
{'locale.en.s5_title': {$regex: terms, $options: 'i'}},
{'locale.en.s5_description': {$regex: terms, $options: 'i'}},
{'locale.en.s6_title': {$regex: terms, $options: 'i'}},
{'locale.en.s6_description': {$regex: terms, $options: 'i'}},
]
})
]
const getData = await Promise.all(requests);
let [blogs, categoryGallery, projects] = getData;
return res.json({
blogs,
categoryGallery,
projects
});
} catch (e) {
return res500(res, _sr['fa'].response.problem);
}
}
]
+281
View File
@@ -0,0 +1,281 @@
const Slide = require('../models/Slide')
const {body, validationResult} = require('express-validator')
const {_sr} = require('../plugins/serverResponses')
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions')
const sharp = require('sharp')
const mongoose = require('mongoose')
const fs = require('fs')
// variables
const coverWidth = 1920
const coverHeight = 1080
const coverQuality = 100
module.exports.create = [
async (req, res) => {
try {
const isImage = req.body.isImage === 'true'
if (isImage && (!req.files || !req.files.image)) return res.status(422).json({validation: {image: {msg: _sr['fa'].required.image}}})
if (!isImage && (!req.files || !req.files.video)) return res.status(422).json({validation: {video: {msg: _sr['fa'].required.video}}})
if (isImage && !_sr.supportedImageFormats.includes(req.files.image.mimetype.split('/')[1])) return res.status(422).json({validation: {image: {msg: _sr['fa'].format.image}}})
if (!isImage && !_sr.supportedVideoFormats.includes(req.files.video.mimetype.split('/')[1])) return res.status(422).json({validation: {video: {msg: _sr['fa'].format.video}}})
const data = {isImage}
if (isImage) {
const image = req.files.image
const imageName = 'slider_' + Date.now() + '.jpg'
data.image = imageName
const target = await sharp(image.data)
await target
.resize(coverWidth, coverHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: coverQuality})
.toFile(`./static/uploads/images/slider/${imageName}`)
} else {
const video = req.files.video
const videoName = 'slider_' + Date.now() + '.' + video.mimetype.split('/')[1]
data.video = videoName
video.mv(`./static/uploads/images/slider/${videoName}`)
}
const slide = new Slide(data)
slide.save(err => {
if (err) return res500(res, err)
else return res.json({message: _sr['fa'].response.success_save})
})
} catch (e) {
return res500(res, e)
}
}
]
module.exports.getAll = [
(req, res) => {
Slide.find({}).exec((err, projects) => {
if (err) return res500(res, err)
else return res.json(projects)
})
}
]
module.exports.getOne = [
(req, res) => {
Slide.findById(req.params.id, (err, slide) => {
if (err || !slide) return res404(res, err)
else return res.json(slide)
})
}
]
// module.exports.update = [
// (req, res) => {
// const {
// fa_title,
// en_title,
// fa_short_description,
// en_short_description,
// fa_description,
// en_description,
// //
// fa_client,
// en_client,
// //
// fa_skills,
// en_skills,
// //
// fa_website,
// en_website,
// //
// fa_s3_title,
// en_s3_title,
// fa_s3_description,
// en_s3_description,
// //
// fa_s5_title,
// en_s5_title,
// fa_s5_description,
// en_s5_description,
// //
// fa_s6_title,
// en_s6_title,
// fa_s6_description,
// en_s6_description,
// category,
// project_date,
// has_details
// } = req.body
//
// const data = {
// locale: {
// fa: {
// title: fa_title,
// short_description: fa_short_description.slice(0, shortDescriptionMaxLength) + ' ... ',
// description: fa_description,
// //
// client: fa_client,
// skills: fa_skills,
// website: fa_website,
// //
// s3_title: fa_s3_title,
// s3_description: fa_s3_description,
// //
// s5_title: fa_s5_title,
// s5_description: fa_s5_description,
// //
// s6_title: fa_s6_title,
// s6_description: fa_s6_description
// },
// en: {
// title: en_title,
// short_description: en_short_description.slice(0, shortDescriptionMaxLength) + ' ... ',
// description: en_description,
// //
// client: en_client,
// skills: en_skills,
// website: en_website,
// //
// s3_title: en_s3_title,
// s3_description: en_s3_description,
// //
// s5_title: en_s5_title,
// s5_description: en_s5_description,
// //
// s6_title: en_s6_title,
// s6_description: en_s6_description
// }
// },
// category,
// project_date,
// has_details
// }
//
// if (req.files) {
// if (req.files.cover) {
// const cover = req.files.cover
// const coverName = 'project_' + Date.now() + '.jpg'
// if (!_sr.supportedImageFormats.includes(cover.mimetype.split('/')[1])) return res.status(422).json({validation: {cover: {msg: _sr['fa'].format.image}}})
// data.cover = coverName
// data.thumb = 'thumb_' + coverName
//
// const target = new sharp(cover.data)
// target
// .resize(coverWidth, coverHeight, {fit: 'cover'})
// .toFormat('jpg')
// .jpeg({quality: coverQuality})
// .toFile(`./static/uploads/images/projects/${coverName}`)
//
// target
// .resize(thumbWidth, thumbHeight, {fit: 'cover'})
// .toFormat('jpg')
// .jpeg({quality: thumbQuality})
// .toFile(`./static/uploads/images/projects/thumb_${coverName}`)
// }
//
// if (req.files.s2_image) {
// const s2_image = req.files.s2_image
// const s2_imageName = 's2_image_' + Date.now() + '.jpg'
// if (!_sr.supportedImageFormats.includes(s2_image.mimetype.split('/')[1])) return res.status(422).json({validation: {s2_image: {msg: _sr['fa'].format.image}}})
// data.s2_image = s2_imageName
//
// const target = new sharp(s2_image.data)
// target
// .resize(s2ImageWidth, s2ImageHeight, {fit: 'cover'})
// .toFormat('jpg')
// .jpeg({quality: s2ImageQuality})
// .toFile(`./static/uploads/images/projects/${s2_imageName}`)
// }
//
// if (req.files.s4_image) {
// const s4_image = req.files.s4_image
// const s4_imageName = 's4_image_' + Date.now() + '.jpg'
// if (!_sr.supportedImageFormats.includes(s4_image.mimetype.split('/')[1])) return res.status(422).json({validation: {s4_image: {msg: _sr['fa'].format.image}}})
// data.s4_image = s4_imageName
//
// const target = new sharp(s4_image.data)
// target
// .resize(s4ImageWidth, s4ImageHeight, {fit: 'cover'})
// .toFormat('jpg')
// .jpeg({quality: s4ImageQuality})
// .toFile(`./static/uploads/images/projects/${s4_imageName}`)
// }
//
// if (req.files.s5_image) {
// const s5_image = req.files.s5_image
// const s5_imageName = 's5_image_' + Date.now() + '.jpg'
// if (!_sr.supportedImageFormats.includes(s5_image.mimetype.split('/')[1])) return res.status(422).json({validation: {s5_image: {msg: _sr['fa'].format.image}}})
// data.s5_image = s5_imageName
//
// const target = new sharp(s5_image.data)
// target
// .resize(s5ImageWidth, s5ImageHeight, {fit: 'cover'})
// .toFormat('jpg')
// .jpeg({quality: s5ImageQuality})
// .toFile(`./static/uploads/images/projects/${s5_imageName}`)
// }
//
// if (req.files.s6_image) {
// const s6_image = req.files.s6_image
// const s6_imageName = 's6_image_' + Date.now() + '.jpg'
// if (!_sr.supportedImageFormats.includes(s6_image.mimetype.split('/')[1])) return res.status(422).json({validation: {s6_image: {msg: _sr['fa'].format.image}}})
// data.s6_image = s6_imageName
//
// const target = new sharp(s6_image.data)
// target
// .resize(s6ImageWidth, s6ImageHeight, {fit: 'cover'})
// .toFormat('jpg')
// .jpeg({quality: s6ImageQuality})
// .toFile(`./static/uploads/images/projects/${s6_imageName}`)
// }
// }
//
// Project.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
// if (err || !oldData) return res404(res, err)
// if (req.files) {
// if (req.files.cover && oldData.cover) {
// fs.unlink(`./static/${oldData.cover}`, err => {
// if (err) console.log(err)
// })
// fs.unlink(`./static/${oldData.thumb}`, err => {
// if (err) console.log(err)
// })
// }
//
// if (req.files.s2_image && oldData.s2_image) {
// fs.unlink(`./static/${oldData.s2_image}`, err => {
// if (err) console.log(err)
// })
// }
// if (req.files.s4_image && oldData.s4_image) {
// fs.unlink(`./static/${oldData.s4_image}`, err => {
// if (err) console.log(err)
// })
// }
// if (req.files.s5_image && oldData.s5_image) {
// fs.unlink(`./static/${oldData.s5_image}`, err => {
// if (err) console.log(err)
// })
// }
// if (req.files.s6_image && oldData.s6_image) {
// fs.unlink(`./static/${oldData.s6_image}`, err => {
// if (err) console.log(err)
// })
// }
//
// }
// return res.json({message: _sr['fa'].response.success_save})
// })
// }
// ]
module.exports.delete = [
(req, res) => {
Slide.findByIdAndRemove(req.params.id, async (err, oldData) => {
if (err || !oldData) return res404(res, err)
fs.unlink(`./static/${oldData.isImage ? oldData.image : oldData.video}`, err => {
if (err) console.log(err)
})
return res.json({message: _sr['fa'].response.success_remove})
})
}
]
+184
View File
@@ -0,0 +1,184 @@
const Team = require('../models/Team')
const {body, validationResult} = require('express-validator')
const {_sr} = require('../plugins/serverResponses')
const {res404, res500, checkValidations} = require('../plugins/controllersHelperFunctions')
const sharp = require('sharp')
const fs = require('fs')
// variables
const imageWidth = 400
const imageHeight = 500
const imageQuality = 100
module.exports.create = [
[
body('index')
.notEmpty().withMessage('شماره ترتیب را انتخاب کنید'),
body('fa_first_name')
.notEmpty().withMessage(_sr['fa'].required.first_name),
body('en_first_name')
.notEmpty().withMessage(_sr['fa'].required.first_name),
body('fa_last_name')
.notEmpty().withMessage(_sr['fa'].required.last_name),
body('en_last_name')
.notEmpty().withMessage(_sr['fa'].required.last_name),
body('fa_position')
.notEmpty().withMessage('سمت را بنویسید'),
body('en_position')
.notEmpty().withMessage('سمت را بنویسید')
],
checkValidations(validationResult),
async (req, res) => {
if (!req.files || !req.files.image) return res.status(422).json({validation: {image: {msg: _sr['fa'].required.image}}})
const {fa_first_name, en_first_name, fa_last_name, en_last_name, fa_position, en_position, index} = req.body
const data = {
locale: {
fa: {
first_name: fa_first_name,
last_name: fa_last_name,
position: fa_position
},
en: {
first_name: en_first_name,
last_name: en_last_name,
position: en_position
}
},
index
}
const image = req.files.image
const imageName = 'team_' + en_first_name + '_' + Date.now() + '.jpg'
data.image = imageName
try {
const target = await sharp(image.data)
await target
.resize(imageWidth, imageHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: imageQuality})
.toFile(`./static/uploads/images/team/${imageName}`)
} catch (e) {
return res500(res, e)
}
const teamMate = new Team(data)
teamMate.save(err => {
if (err) return res500(res, err)
else return res.json({message: _sr['fa'].response.success_save})
})
}
]
module.exports.getAll = [
(req, res) => {
Team.find({}).sort({index: 1}).exec((err, data) => {
if (err) return res500(res, err)
else return res.json(data)
})
}
]
module.exports.getOne = [
(req, res) => {
Team.findById(req.params.id, (err, data) => {
if (err || !data) return res404(res, err)
else return res.json(data)
})
}
]
module.exports.update = [
[
body('index')
.notEmpty().withMessage('شماره ترتیب را انتخاب کنید'),
body('fa_first_name')
.notEmpty().withMessage(_sr['fa'].required.first_name),
body('en_first_name')
.notEmpty().withMessage(_sr['fa'].required.first_name),
body('en_last_name')
.notEmpty().withMessage(_sr['fa'].required.last_name),
body('en_last_name')
.notEmpty().withMessage(_sr['fa'].required.last_name),
body('fa_position')
.notEmpty().withMessage('سمت را بنویسید'),
body('en_position')
.notEmpty().withMessage('سمت را بنویسید')
],
checkValidations(validationResult),
async (req, res) => {
const {fa_first_name, en_first_name, fa_last_name, en_last_name, fa_position, en_position, index} = req.body
const data = {
locale: {
fa: {
first_name: fa_first_name,
last_name: fa_last_name,
position: fa_position
},
en: {
first_name: en_first_name,
last_name: en_last_name,
position: en_position
}
},
index
}
if (req.files && req.files.image) {
const image = req.files.image
const imageName = 'team_' + en_first_name + '_' + Date.now() + '.jpg'
data.image = imageName
try {
const target = await sharp(image.data)
await target
.resize(imageWidth, imageHeight, {fit: 'cover'})
.withMetadata()
.toFormat('jpg')
.jpeg({quality: imageQuality})
.toFile(`./static/uploads/images/team/${imageName}`)
} catch (e) {
return res500(res, e)
}
}
Team.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err || !oldData) return res404(res, err)
if (req.files && req.files.image) {
fs.unlink(`./static/${oldData.image}`, err => {
if (err) console.log(err)
})
}
return res.json({message: _sr['fa'].response.success_save})
})
}
]
module.exports.delete = [
(req, res) => {
Team.findByIdAndRemove(req.params.id, (err, data) => {
if (err || !data) return res404(res, err)
fs.unlink(`./static/${data.image}`, err => {
if (err) console.log(err)
})
return res.json({message: _sr['fa'].response.success_remove})
})
}
]
+141
View File
@@ -0,0 +1,141 @@
const User = require('../models/User')
const {body, validationResult} = require('express-validator')
const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')
const sharp = require('sharp')
const {secretKey, getID} = require('./../authentication')
const {_sr} = require('../plugins/serverResponses')
const {res404, res500, hasWhiteSpaces, isLatinCharactersWithSymbol, generateRandomDigits, removeWhiteSpaces, checkValidations} = require('../plugins/controllersHelperFunctions')
const fs = require('fs')
const moment = require('moment-jalaali')
module.exports.create_admin = [
[
body('username')
.notEmpty().withMessage(_sr['fa'].required.username)
.bail()
.custom((value, {req}) => {
if (hasWhiteSpaces(value)) return Promise.reject(_sr['fa'].response.whiteSpace)
return User.findOne({username: value}).then(user => {
if (user) return Promise.reject(_sr['fa'].duplicated.username)
else return true
})
}),
body('password')
.custom((value, {req}) => {
if (hasWhiteSpaces(value)) return Promise.reject(_sr['fa'].response.whiteSpace)
if (removeWhiteSpaces(value).length < 4) return Promise.reject(_sr['fa'].min_char.min4)
if (value !== req.body.password_confirmation) return Promise.reject(_sr['fa'].response.passwords_not_match)
else return true
})
],
checkValidations(validationResult),
async (req, res) => {
const {username, password} = req.body
const data = {username, scope: ['admin']}
try {
const salt = await bcrypt.genSalt(10)
const hash = await bcrypt.hash(password, salt)
data.password = hash
const admin = new User(data)
await admin.save()
return res.json({message: _sr['fa'].response.success_save})
} catch (e) {
return res500(res, e)
}
}
]
/////////////////////////////////////////////////////////////////////// login
module.exports.login = [
[
body('username')
.isLength({min: 4}).withMessage(_sr['fa'].min_char.min4)
.bail()
.if((value, {req}) => {
return req.body.password && req.body.password.length >= 4
})
.custom((value, {req}) => {
return User.findOne({$or: [{email: value.toLowerCase()}, {username: value}]})
.then(user => {
if (!user) return Promise.reject(_sr['fa'].not_found.password)
else return true
})
}),
body('password')
.notEmpty().withMessage(_sr['fa'].required.password)
.bail()
.isLength({min: 4}).withMessage(_sr['fa'].min_char.min4),
body('remember_me')
.exists().withMessage(_sr['fa'].required.remember_me)
.bail()
.isBoolean().withMessage(_sr['fa'].format.boolean)
],
checkValidations(validationResult),
(req, res) => {
User.findOne({$or: [{email: req.body.username.toLowerCase()}, {username: req.body.username}]}, (err, user) => {
if (err || !user) return res404(res, err)
bcrypt.compare(req.body.password, user.password, (err, isMatch) => {
if (err || !isMatch) return res.status(422).json({validation: {username: {msg: _sr['fa'].not_found.password}}})
if (user.token) {
jwt.verify(user.token.replace(/^Bearer\s/, ''), secretKey, (err, decoded) => {
if (err) {
let token = jwt.sign({_id: user._id}, secretKey, {expiresIn: req.body.remember_me ? '7d' : '1h'})
user.token = token
user.save(err => {
if (err) console.log(err)
return res.json({token: token})
})
} else return res.json({token: user.token})
})
} else {
let token = jwt.sign({_id: user._id}, secretKey, {expiresIn: req.body.remember_me ? '7d' : '1h'})
user.token = token
user.save(err => {
if (err) console.log(err)
return res.json({token: token})
})
}
})
})
}
]
/////////////////////////////////////////////////////////////////////// logout
module.exports.logout = [
(req, res) => {
const token = req.headers.authorization
if (token) {
User.findOneAndUpdate({token: token}, {token: null}, (err, oldData) => {
if (err || !oldData) res.status(401).json({message: 'Your not logged in'})
else return res.json({message: 'You are logged out.'})
})
} else {
return res.status(401).json({message: 'Your not logged in'})
}
}
]
/////////////////////////////////////////////////////////////////////// get user
module.exports.getUser = [
(req, res) => {
const token = req.headers.authorization
if (token) {
jwt.verify(token, secretKey, (err, decoded) => {
if (err) return res.status(401).json({message: 'unauthenticated'})
User.findById(decoded._id, (err, user) => {
if (err || !user) return res404(res, err)
else return res.json({user: user})
})
})
} else {
return res.status(401).json({message: 'unauthenticated'})
}
}
]