Добавлены модели и функциональность для управления администраторами, включая авторизацию через JWT, запросы и мутации для получения информации об администраторах и управления пользователями. Обновлены стили и логика работы с токенами в Apollo Client. Улучшен интерфейс взаимодействия с пользователем.
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
import jwt from 'jsonwebtoken'
|
||||
import bcrypt from 'bcryptjs'
|
||||
import { GraphQLError } from 'graphql'
|
||||
import { GraphQLScalarType, Kind } from 'graphql'
|
||||
import { prisma } from '@/lib/prisma'
|
||||
@ -18,6 +19,10 @@ interface Context {
|
||||
id: string
|
||||
phone: string
|
||||
}
|
||||
admin?: {
|
||||
id: string
|
||||
username: string
|
||||
}
|
||||
}
|
||||
|
||||
interface CreateEmployeeInput {
|
||||
@ -3736,4 +3741,167 @@ const logisticsMutations = {
|
||||
resolvers.Mutation = {
|
||||
...resolvers.Mutation,
|
||||
...logisticsMutations
|
||||
}
|
||||
|
||||
// Админ резолверы
|
||||
const adminQueries = {
|
||||
adminMe: async (_: unknown, __: unknown, context: Context) => {
|
||||
if (!context.admin) {
|
||||
throw new GraphQLError('Требуется авторизация администратора', {
|
||||
extensions: { code: 'UNAUTHENTICATED' }
|
||||
})
|
||||
}
|
||||
|
||||
const admin = await prisma.admin.findUnique({
|
||||
where: { id: context.admin.id }
|
||||
})
|
||||
|
||||
if (!admin) {
|
||||
throw new GraphQLError('Администратор не найден')
|
||||
}
|
||||
|
||||
return admin
|
||||
},
|
||||
|
||||
allUsers: async (_: unknown, args: { search?: string; limit?: number; offset?: number }, context: Context) => {
|
||||
if (!context.admin) {
|
||||
throw new GraphQLError('Требуется авторизация администратора', {
|
||||
extensions: { code: 'UNAUTHENTICATED' }
|
||||
})
|
||||
}
|
||||
|
||||
const limit = args.limit || 50
|
||||
const offset = args.offset || 0
|
||||
|
||||
// Строим условие поиска
|
||||
const whereCondition: Prisma.UserWhereInput = args.search
|
||||
? {
|
||||
OR: [
|
||||
{ phone: { contains: args.search, mode: 'insensitive' } },
|
||||
{ managerName: { contains: args.search, mode: 'insensitive' } },
|
||||
{
|
||||
organization: {
|
||||
OR: [
|
||||
{ name: { contains: args.search, mode: 'insensitive' } },
|
||||
{ fullName: { contains: args.search, mode: 'insensitive' } },
|
||||
{ inn: { contains: args.search, mode: 'insensitive' } }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
: {}
|
||||
|
||||
// Получаем пользователей с пагинацией
|
||||
const [users, total] = await Promise.all([
|
||||
prisma.user.findMany({
|
||||
where: whereCondition,
|
||||
include: {
|
||||
organization: true
|
||||
},
|
||||
take: limit,
|
||||
skip: offset,
|
||||
orderBy: { createdAt: 'desc' }
|
||||
}),
|
||||
prisma.user.count({
|
||||
where: whereCondition
|
||||
})
|
||||
])
|
||||
|
||||
return {
|
||||
users,
|
||||
total,
|
||||
hasMore: offset + limit < total
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const adminMutations = {
|
||||
adminLogin: async (_: unknown, args: { username: string; password: string }) => {
|
||||
try {
|
||||
// Найти администратора
|
||||
const admin = await prisma.admin.findUnique({
|
||||
where: { username: args.username }
|
||||
})
|
||||
|
||||
if (!admin) {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Неверные учетные данные'
|
||||
}
|
||||
}
|
||||
|
||||
// Проверить активность
|
||||
if (!admin.isActive) {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Аккаунт заблокирован'
|
||||
}
|
||||
}
|
||||
|
||||
// Проверить пароль
|
||||
const isPasswordValid = await bcrypt.compare(args.password, admin.password)
|
||||
|
||||
if (!isPasswordValid) {
|
||||
return {
|
||||
success: false,
|
||||
message: 'Неверные учетные данные'
|
||||
}
|
||||
}
|
||||
|
||||
// Обновить время последнего входа
|
||||
await prisma.admin.update({
|
||||
where: { id: admin.id },
|
||||
data: { lastLogin: new Date() }
|
||||
})
|
||||
|
||||
// Создать токен
|
||||
const token = jwt.sign(
|
||||
{
|
||||
adminId: admin.id,
|
||||
username: admin.username,
|
||||
type: 'admin'
|
||||
},
|
||||
process.env.JWT_SECRET!,
|
||||
{ expiresIn: '24h' }
|
||||
)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: 'Успешная авторизация',
|
||||
token,
|
||||
admin: {
|
||||
...admin,
|
||||
password: undefined // Не возвращаем пароль
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Admin login error:', error)
|
||||
return {
|
||||
success: false,
|
||||
message: 'Ошибка авторизации'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
adminLogout: async (_: unknown, __: unknown, context: Context) => {
|
||||
if (!context.admin) {
|
||||
throw new GraphQLError('Требуется авторизация администратора', {
|
||||
extensions: { code: 'UNAUTHENTICATED' }
|
||||
})
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Добавляем админ запросы и мутации к основным резолверам
|
||||
resolvers.Query = {
|
||||
...resolvers.Query,
|
||||
...adminQueries
|
||||
}
|
||||
|
||||
resolvers.Mutation = {
|
||||
...resolvers.Mutation,
|
||||
...adminMutations
|
||||
}
|
Reference in New Issue
Block a user