Добавлены кастомные скроллбары в глобальные стили. Обновлен компонент карточек товаров: добавлены функции загрузки услуг и расходников для выбранных организаций, изменены интерфейсы для выбора фулфилмент-организаций и расходников, улучшена логика расчета стоимости с учетом дополнительных расходов. Оптимизирован код для повышения читаемости и производительности. Обновлены запросы GraphQL для получения услуг и расходников от контрагентов.
This commit is contained in:
@ -612,6 +612,39 @@ export const GET_MY_WILDBERRIES_SUPPLIES = gql`
|
||||
}
|
||||
`
|
||||
|
||||
// Запросы для получения услуг и расходников от конкретных организаций-контрагентов
|
||||
export const GET_COUNTERPARTY_SERVICES = gql`
|
||||
query GetCounterpartyServices($organizationId: ID!) {
|
||||
counterpartyServices(organizationId: $organizationId) {
|
||||
id
|
||||
name
|
||||
description
|
||||
price
|
||||
imageUrl
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const GET_COUNTERPARTY_SUPPLIES = gql`
|
||||
query GetCounterpartySupplies($organizationId: ID!) {
|
||||
counterpartySupplies(organizationId: $organizationId) {
|
||||
id
|
||||
name
|
||||
description
|
||||
price
|
||||
quantity
|
||||
unit
|
||||
category
|
||||
status
|
||||
imageUrl
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
// Админ запросы
|
||||
export const ADMIN_ME = gql`
|
||||
query AdminMe {
|
||||
|
@ -810,6 +810,104 @@ export const resolvers = {
|
||||
});
|
||||
},
|
||||
|
||||
// Публичные услуги контрагента (для фулфилмента)
|
||||
counterpartyServices: async (
|
||||
_: unknown,
|
||||
args: { organizationId: string },
|
||||
context: Context
|
||||
) => {
|
||||
if (!context.user) {
|
||||
throw new GraphQLError("Требуется авторизация", {
|
||||
extensions: { code: "UNAUTHENTICATED" },
|
||||
});
|
||||
}
|
||||
|
||||
const currentUser = await prisma.user.findUnique({
|
||||
where: { id: context.user.id },
|
||||
include: { organization: true },
|
||||
});
|
||||
|
||||
if (!currentUser?.organization) {
|
||||
throw new GraphQLError("У пользователя нет организации");
|
||||
}
|
||||
|
||||
// Проверяем, что запрашиваемая организация является контрагентом
|
||||
const counterparty = await prisma.counterparty.findFirst({
|
||||
where: {
|
||||
organizationId: currentUser.organization.id,
|
||||
counterpartyId: args.organizationId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!counterparty) {
|
||||
throw new GraphQLError("Организация не является вашим контрагентом");
|
||||
}
|
||||
|
||||
// Проверяем, что это фулфилмент центр
|
||||
const targetOrganization = await prisma.organization.findUnique({
|
||||
where: { id: args.organizationId },
|
||||
});
|
||||
|
||||
if (!targetOrganization || targetOrganization.type !== "FULFILLMENT") {
|
||||
throw new GraphQLError("Услуги доступны только у фулфилмент центров");
|
||||
}
|
||||
|
||||
return await prisma.service.findMany({
|
||||
where: { organizationId: args.organizationId },
|
||||
include: { organization: true },
|
||||
orderBy: { createdAt: "desc" },
|
||||
});
|
||||
},
|
||||
|
||||
// Публичные расходники контрагента (для оптовиков)
|
||||
counterpartySupplies: async (
|
||||
_: unknown,
|
||||
args: { organizationId: string },
|
||||
context: Context
|
||||
) => {
|
||||
if (!context.user) {
|
||||
throw new GraphQLError("Требуется авторизация", {
|
||||
extensions: { code: "UNAUTHENTICATED" },
|
||||
});
|
||||
}
|
||||
|
||||
const currentUser = await prisma.user.findUnique({
|
||||
where: { id: context.user.id },
|
||||
include: { organization: true },
|
||||
});
|
||||
|
||||
if (!currentUser?.organization) {
|
||||
throw new GraphQLError("У пользователя нет организации");
|
||||
}
|
||||
|
||||
// Проверяем, что запрашиваемая организация является контрагентом
|
||||
const counterparty = await prisma.counterparty.findFirst({
|
||||
where: {
|
||||
organizationId: currentUser.organization.id,
|
||||
counterpartyId: args.organizationId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!counterparty) {
|
||||
throw new GraphQLError("Организация не является вашим контрагентом");
|
||||
}
|
||||
|
||||
// Проверяем, что это фулфилмент центр (у них есть расходники)
|
||||
const targetOrganization = await prisma.organization.findUnique({
|
||||
where: { id: args.organizationId },
|
||||
});
|
||||
|
||||
if (!targetOrganization || targetOrganization.type !== "FULFILLMENT") {
|
||||
throw new GraphQLError("Расходники доступны только у фулфилмент центров");
|
||||
}
|
||||
|
||||
return await prisma.supply.findMany({
|
||||
where: { organizationId: args.organizationId },
|
||||
include: { organization: true },
|
||||
orderBy: { createdAt: "desc" },
|
||||
});
|
||||
},
|
||||
|
||||
// Корзина пользователя
|
||||
myCart: async (_: unknown, __: unknown, context: Context) => {
|
||||
if (!context.user) {
|
||||
@ -4312,6 +4410,32 @@ export const resolvers = {
|
||||
where: { organizationId: parent.id },
|
||||
});
|
||||
},
|
||||
services: async (parent: { id: string; services?: unknown[] }) => {
|
||||
// Если услуги уже загружены через include, возвращаем их
|
||||
if (parent.services) {
|
||||
return parent.services;
|
||||
}
|
||||
|
||||
// Иначе загружаем отдельно
|
||||
return await prisma.service.findMany({
|
||||
where: { organizationId: parent.id },
|
||||
include: { organization: true },
|
||||
orderBy: { createdAt: "desc" },
|
||||
});
|
||||
},
|
||||
supplies: async (parent: { id: string; supplies?: unknown[] }) => {
|
||||
// Если расходники уже загружены через include, возвращаем их
|
||||
if (parent.supplies) {
|
||||
return parent.supplies;
|
||||
}
|
||||
|
||||
// Иначе загружаем отдельно
|
||||
return await prisma.supply.findMany({
|
||||
where: { organizationId: parent.id },
|
||||
include: { organization: true },
|
||||
orderBy: { createdAt: "desc" },
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
Cart: {
|
||||
|
@ -66,6 +66,12 @@ export const typeDefs = gql`
|
||||
month: Int!
|
||||
): [EmployeeSchedule!]!
|
||||
|
||||
# Публичные услуги контрагента (для фулфилмента)
|
||||
counterpartyServices(organizationId: ID!): [Service!]!
|
||||
|
||||
# Публичные расходники контрагента (для оптовиков)
|
||||
counterpartySupplies(organizationId: ID!): [Supply!]!
|
||||
|
||||
# Админ запросы
|
||||
adminMe: Admin
|
||||
allUsers(search: String, limit: Int, offset: Int): UsersResponse!
|
||||
@ -235,6 +241,8 @@ export const typeDefs = gql`
|
||||
emails: JSON
|
||||
users: [User!]!
|
||||
apiKeys: [ApiKey!]!
|
||||
services: [Service!]!
|
||||
supplies: [Supply!]!
|
||||
isCounterparty: Boolean
|
||||
isCurrentUser: Boolean
|
||||
hasOutgoingRequest: Boolean
|
||||
|
Reference in New Issue
Block a user