379 lines
10 KiB
TypeScript
379 lines
10 KiB
TypeScript
|
import { Request, Response } from 'express';
|
|||
|
import bcrypt from 'bcrypt';
|
|||
|
import { prisma } from '../utils/prisma';
|
|||
|
|
|||
|
export class AdminController {
|
|||
|
static async getUsers(req: Request, res: Response) {
|
|||
|
try {
|
|||
|
const users = await prisma.user.findMany({
|
|||
|
include: {
|
|||
|
role: true,
|
|||
|
categoryAccess: {
|
|||
|
include: {
|
|||
|
category: true
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
const formattedUsers = users.map(user => ({
|
|||
|
id: user.id,
|
|||
|
username: user.username,
|
|||
|
role: user.role.name,
|
|||
|
isActive: user.is_active,
|
|||
|
lastLogin: user.last_login,
|
|||
|
categories: user.categoryAccess.map(access => access.category.name)
|
|||
|
}));
|
|||
|
|
|||
|
res.json(formattedUsers);
|
|||
|
} catch (error) {
|
|||
|
console.error('Error getting users:', error);
|
|||
|
res.status(500).json({ message: 'Ошибка сервера' });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static async createUser(req: Request, res: Response) {
|
|||
|
try {
|
|||
|
const { username, password, roleId, categoryIds } = req.body;
|
|||
|
|
|||
|
const existingUser = await prisma.user.findUnique({
|
|||
|
where: { username }
|
|||
|
});
|
|||
|
|
|||
|
if (existingUser) {
|
|||
|
return res.status(400).json({ message: 'Пользователь уже существует' });
|
|||
|
}
|
|||
|
|
|||
|
const passwordHash = await bcrypt.hash(password, 10);
|
|||
|
|
|||
|
const user = await prisma.user.create({
|
|||
|
data: {
|
|||
|
username,
|
|||
|
password_hash: passwordHash,
|
|||
|
role_id: roleId,
|
|||
|
is_active: true,
|
|||
|
categoryAccess: {
|
|||
|
create: categoryIds.map((categoryId: number) => ({
|
|||
|
category_id: categoryId
|
|||
|
}))
|
|||
|
}
|
|||
|
},
|
|||
|
include: {
|
|||
|
role: true,
|
|||
|
categoryAccess: {
|
|||
|
include: {
|
|||
|
category: true
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
const formattedUser = {
|
|||
|
id: user.id,
|
|||
|
username: user.username,
|
|||
|
role: user.role.name,
|
|||
|
isActive: user.is_active,
|
|||
|
lastLogin: user.last_login,
|
|||
|
categories: user.categoryAccess.map(access => access.category.name)
|
|||
|
};
|
|||
|
|
|||
|
res.json(formattedUser);
|
|||
|
} catch (error) {
|
|||
|
console.error('Error creating user:', error);
|
|||
|
res.status(500).json({ message: 'Ошибка сервера' });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static async updateUser(req: Request, res: Response) {
|
|||
|
try {
|
|||
|
const { id } = req.params;
|
|||
|
const { password, roleId, isActive, categoryIds } = req.body;
|
|||
|
|
|||
|
const updateData: any = {
|
|||
|
role_id: roleId,
|
|||
|
is_active: isActive
|
|||
|
};
|
|||
|
|
|||
|
if (password) {
|
|||
|
updateData.password_hash = await bcrypt.hash(password, 10);
|
|||
|
}
|
|||
|
|
|||
|
const user = await prisma.user.update({
|
|||
|
where: { id: Number(id) },
|
|||
|
data: {
|
|||
|
...updateData,
|
|||
|
categoryAccess: {
|
|||
|
deleteMany: {}, // Удаляем текущие доступы
|
|||
|
create: categoryIds.map((categoryId: number) => ({
|
|||
|
category_id: categoryId
|
|||
|
}))
|
|||
|
}
|
|||
|
},
|
|||
|
include: {
|
|||
|
role: true,
|
|||
|
categoryAccess: {
|
|||
|
include: {
|
|||
|
category: true
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
const formattedUser = {
|
|||
|
id: user.id,
|
|||
|
username: user.username,
|
|||
|
role: user.role.name,
|
|||
|
isActive: user.is_active,
|
|||
|
lastLogin: user.last_login,
|
|||
|
categories: user.categoryAccess.map(access => access.category.name)
|
|||
|
};
|
|||
|
|
|||
|
res.json({ message: 'Пользователь успешно обновлен', user: formattedUser });
|
|||
|
} catch (error) {
|
|||
|
console.error('Error updating user:', error);
|
|||
|
res.status(500).json({ message: 'Ошибка сервера' });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static async deleteUser(req: Request, res: Response) {
|
|||
|
try {
|
|||
|
const { id } = req.params;
|
|||
|
|
|||
|
await prisma.user.delete({
|
|||
|
where: { id: Number(id) }
|
|||
|
});
|
|||
|
|
|||
|
res.json({ message: 'Пользователь успешно удален' });
|
|||
|
} catch (error) {
|
|||
|
console.error('Error deleting user:', error);
|
|||
|
res.status(500).json({ message: 'Ошибка сервера' });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static async getRoles(req: Request, res: Response) {
|
|||
|
try {
|
|||
|
const roles = await prisma.role.findMany({
|
|||
|
include: {
|
|||
|
permissions: {
|
|||
|
include: {
|
|||
|
permission: true
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
res.json(roles);
|
|||
|
} catch (error) {
|
|||
|
console.error('Error fetching roles:', error);
|
|||
|
res.status(500).json({ message: 'Ошибка сервера' });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static async getPermissions(req: Request, res: Response) {
|
|||
|
try {
|
|||
|
const permissions = await prisma.permission.findMany();
|
|||
|
res.json(permissions);
|
|||
|
} catch (error) {
|
|||
|
console.error('Error fetching permissions:', error);
|
|||
|
res.status(500).json({ message: 'Ошибка сервера' });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static async createRole(req: Request, res: Response) {
|
|||
|
try {
|
|||
|
const { name, description, permissions } = req.body;
|
|||
|
|
|||
|
const existingRole = await prisma.role.findUnique({
|
|||
|
where: { name }
|
|||
|
});
|
|||
|
|
|||
|
if (existingRole) {
|
|||
|
return res.status(400).json({ message: 'Роль с таким названием уже существует' });
|
|||
|
}
|
|||
|
|
|||
|
const role = await prisma.role.create({
|
|||
|
data: {
|
|||
|
name,
|
|||
|
description,
|
|||
|
permissions: {
|
|||
|
create: permissions.map((permissionId: number) => ({
|
|||
|
permission_id: permissionId
|
|||
|
}))
|
|||
|
}
|
|||
|
},
|
|||
|
include: {
|
|||
|
permissions: {
|
|||
|
include: {
|
|||
|
permission: true
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
res.json(role);
|
|||
|
} catch (error) {
|
|||
|
console.error('Error creating role:', error);
|
|||
|
res.status(500).json({ message: 'Ошибка сервера' });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static async updateRole(req: Request, res: Response) {
|
|||
|
try {
|
|||
|
const { id } = req.params;
|
|||
|
const { name, description, permissions } = req.body;
|
|||
|
|
|||
|
const role = await prisma.role.findUnique({
|
|||
|
where: { id: Number(id) }
|
|||
|
});
|
|||
|
|
|||
|
if (role?.name === 'admin') {
|
|||
|
return res.status(403).json({ message: 'Роль администратора нельзя изменить' });
|
|||
|
}
|
|||
|
|
|||
|
await prisma.rolePermission.deleteMany({
|
|||
|
where: { role_id: Number(id) }
|
|||
|
});
|
|||
|
|
|||
|
const updatedRole = await prisma.role.update({
|
|||
|
where: { id: Number(id) },
|
|||
|
data: {
|
|||
|
name,
|
|||
|
description,
|
|||
|
permissions: {
|
|||
|
create: permissions.map((permissionId: number) => ({
|
|||
|
permission_id: permissionId
|
|||
|
}))
|
|||
|
}
|
|||
|
},
|
|||
|
include: {
|
|||
|
permissions: {
|
|||
|
include: {
|
|||
|
permission: true
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
res.json(updatedRole);
|
|||
|
} catch (error) {
|
|||
|
console.error('Error updating role:', error);
|
|||
|
res.status(500).json({ message: 'Ошибка сервера' });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static async deleteRole(req: Request, res: Response) {
|
|||
|
try {
|
|||
|
const { id } = req.params;
|
|||
|
|
|||
|
const role = await prisma.role.findUnique({
|
|||
|
where: { id: Number(id) }
|
|||
|
});
|
|||
|
|
|||
|
if (role?.name === 'admin') {
|
|||
|
return res.status(403).json({ message: 'Роль администратора нельзя удалить' });
|
|||
|
}
|
|||
|
|
|||
|
await prisma.role.delete({
|
|||
|
where: { id: Number(id) }
|
|||
|
});
|
|||
|
|
|||
|
res.json({ message: 'Роль успешно удалена' });
|
|||
|
} catch (error) {
|
|||
|
console.error('Error deleting role:', error);
|
|||
|
res.status(500).json({ message: 'Ошибка сервера' });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static async getLocations(req: Request, res: Response) {
|
|||
|
try {
|
|||
|
const locations = await prisma.location.findMany();
|
|||
|
res.json(locations);
|
|||
|
} catch (error) {
|
|||
|
console.error('Error fetching locations:', error);
|
|||
|
res.status(500).json({ message: 'Ошибка сервера' });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static async getCategories(req: Request, res: Response) {
|
|||
|
try {
|
|||
|
const categories = await prisma.category.findMany({
|
|||
|
include: {
|
|||
|
location: true
|
|||
|
}
|
|||
|
});
|
|||
|
res.json(categories);
|
|||
|
} catch (error) {
|
|||
|
console.error('Error fetching categories:', error);
|
|||
|
res.status(500).json({ message: 'Ошибка сервера' });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static async createCategory(req: Request, res: Response) {
|
|||
|
try {
|
|||
|
const { name, location_id } = req.body;
|
|||
|
|
|||
|
const category = await prisma.category.create({
|
|||
|
data: {
|
|||
|
name,
|
|||
|
location_id
|
|||
|
},
|
|||
|
include: {
|
|||
|
location: true
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
res.json(category);
|
|||
|
} catch (error) {
|
|||
|
console.error('Error creating category:', error);
|
|||
|
res.status(500).json({ message: 'Ошибка сервера' });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static async updateCategory(req: Request, res: Response) {
|
|||
|
try {
|
|||
|
const { id } = req.params;
|
|||
|
const { name, location_id } = req.body;
|
|||
|
|
|||
|
const category = await prisma.category.update({
|
|||
|
where: { id: Number(id) },
|
|||
|
data: {
|
|||
|
name,
|
|||
|
location_id
|
|||
|
},
|
|||
|
include: {
|
|||
|
location: true
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
res.json(category);
|
|||
|
} catch (error) {
|
|||
|
console.error('Error updating category:', error);
|
|||
|
res.status(500).json({ message: 'Ошибка сервера' });
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static async deleteCategory(req: Request, res: Response) {
|
|||
|
try {
|
|||
|
const { id } = req.params;
|
|||
|
|
|||
|
const itemsCount = await prisma.item.count({
|
|||
|
where: { category_id: Number(id) }
|
|||
|
});
|
|||
|
|
|||
|
if (itemsCount > 0) {
|
|||
|
return res.status(400).json({
|
|||
|
message: 'Невозможно удалить категорию, содержащую товары'
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
await prisma.category.delete({
|
|||
|
where: { id: Number(id) }
|
|||
|
});
|
|||
|
|
|||
|
res.json({ message: 'Категория успешно удалена' });
|
|||
|
} catch (error) {
|
|||
|
console.error('Error deleting category:', error);
|
|||
|
res.status(500).json({ message: 'Ошибка сервера' });
|
|||
|
}
|
|||
|
}
|
|||
|
}
|