This commit is contained in:
2026-06-13 14:01:25 +03:30
parent 5f82f62763
commit fdda306e85
8 changed files with 367 additions and 90 deletions

View File

@@ -23,9 +23,9 @@ class RoleControllerClass extends Controller {
}
}
async findAll(_req: any, res: ServerResponse, next: NextFunction) {
async findAll(req: any, res: ServerResponse, next: NextFunction) {
try {
const roles = await this.#serivce.findAll();
const roles = await this.#serivce.findAll(req);
return res.status(200).json({
status: 200,
@@ -36,6 +36,18 @@ class RoleControllerClass extends Controller {
}
}
async findList(req: any, res: ServerResponse, next: NextFunction) {
try {
const roles = await this.#serivce.findList();
return res.status(200).json({
status: 200,
data: roles,
});
} catch (error) {
next(error);
}
}
findById = async (req: any, res: ServerResponse, next: NextFunction) => {
try {
const role = await this.#serivce.findById(req.params.id);

View File

@@ -3,7 +3,8 @@ import RoleController from "./role.controller";
const RoleRouter = Router();
RoleRouter.post("/create", RoleController.create);
RoleRouter.get("/list", RoleController.findAll);
RoleRouter.get("/list", RoleController.findList);
RoleRouter.get("/all", RoleController.findAll);
RoleRouter.get("/:id", RoleController.findById);
RoleRouter.put("/update/:id", RoleController.update);
RoleRouter.delete("/remove/:id", RoleController.delete);

View File

@@ -1,9 +1,12 @@
import createHttpError from "http-errors";
import Permission from "../../models/Permission";
import Role from "../../models/Role";
import User from "../../models/User";
import { GlobalMessages } from "../../core/messages";
import { Op } from "sequelize";
class RoleServiceClass {
async create(data: { name: string; description?: string }) {
async create(data: { name: string; description?: string,permissions:string[] }) {
const existingRole = await Role.findOne({
where: { name: data.name },
});
@@ -12,15 +15,28 @@ class RoleServiceClass {
throw new Error("Role already exists");
}
// 1⃣ ساخت Role
const role = await Role.create({
name: data.name,
description: data.description,
});
// 2⃣ اگر permission ارسال شده بود
if (data.permissions && data.permissions.length) {
const permissions = await Permission.findAll({
where: {
id: data.permissions,
},
});
// 3⃣ اتصال permissions به role
await role.setPermissions(permissions);
}
return role;
}
async findAll() {
async findList() {
return await Role.findAll({
include: [
{
@@ -37,6 +53,77 @@ class RoleServiceClass {
});
}
async findAll(req: any) {
try {
const {
page = 1,
limit = 10,
name, // فیلتر نام نقش (اختیاری)
startDate,
endDate,
} = req.query;
// ۱. محاسبه offset برای صفحه‌بندی
const offset = (page - 1) * limit;
// ۲. ساخت آبجکت فیلترها به صورت داینامیک
const whereClause: any = {};
if (name) {
// استفاده از Op.iLike برای جستجوی متنی (Case-Insensitive) در دیتابیس‌های PostgreSQL
// اگر از MySQL استفاده می‌کنید، از Op.like استفاده کنید
whereClause.name = { [Op.iLike]: `%${name}%` };
}
if (startDate || endDate) {
whereClause.createdAt = {};
if (startDate) {
whereClause.createdAt[Op.gte] = new Date(startDate); // تاریخ شروع (بزرگتر مساوی)
}
if (endDate) {
// تنظیم ساعت روی پایان روز برای شامل شدن کلِ روز آخر
const end = new Date(endDate);
end.setHours(23, 59, 59, 999);
whereClause.createdAt[Op.lte] = end; // تاریخ پایان (کوچکتر مساوی)
}
}
// ۳. استفاده از findAndCountAll برای دریافت هم‌زمان دیتا و تعداد کل رکوردها
const { count, rows } = await Role.findAndCountAll({
where: whereClause,
distinct: true, // اضافه کردن این خط مشکل شمارش تکراری را حل می‌کند
col: "id", // به صورت اختیاری مشخص کنید روی کدام ستون distinct انجام شود
include: [
{
model: Permission,
as: "permissions",
through: { attributes: [] },
},
{
model: User,
as: "users",
},
],
order: [["createdAt", "DESC"]],
limit: parseInt(limit),
offset: parseInt(offset.toString()),
});
// ۴. خروجی استاندارد صفحه‌بندی شده
return {
data: rows,
totalItems: count,
totalPages: Math.ceil(count / limit),
currentPage: parseInt(page),
};
} catch (error) {
// مدیریت خطا مشابه متد Ticket
throw new createHttpError.InternalServerError(
GlobalMessages.errors.server,
);
}
}
async findById(id: string) {
const role = await Role.findByPk(id, {
include: [