Добавлен новый компонент для отображения бизнес-процессов в интерфейсе управления. Обновлен компонент UIKitSection для интеграции нового демо и улучшения навигации. Оптимизирована логика отображения данных и улучшена читаемость кода. Исправлены текстовые метки для повышения удобства использования.

This commit is contained in:
Veronika Smirnova
2025-07-27 20:10:39 +03:00
parent f198994400
commit ec28803549
17 changed files with 4304 additions and 1205 deletions

View File

@ -1,4 +1,4 @@
import { gql } from 'graphql-tag'
import { gql } from "graphql-tag";
export const SEND_SMS_CODE = gql`
mutation SendSmsCode($phone: String!) {
@ -7,7 +7,7 @@ export const SEND_SMS_CODE = gql`
message
}
}
`
`;
export const VERIFY_SMS_CODE = gql`
mutation VerifySmsCode($phone: String!, $code: String!) {
@ -56,7 +56,7 @@ export const VERIFY_SMS_CODE = gql`
}
}
}
`
`;
export const VERIFY_INN = gql`
mutation VerifyInn($inn: String!) {
@ -71,10 +71,12 @@ export const VERIFY_INN = gql`
}
}
}
`
`;
export const REGISTER_FULFILLMENT_ORGANIZATION = gql`
mutation RegisterFulfillmentOrganization($input: FulfillmentRegistrationInput!) {
mutation RegisterFulfillmentOrganization(
$input: FulfillmentRegistrationInput!
) {
registerFulfillmentOrganization(input: $input) {
success
message
@ -119,7 +121,7 @@ export const REGISTER_FULFILLMENT_ORGANIZATION = gql`
}
}
}
`
`;
export const REGISTER_SELLER_ORGANIZATION = gql`
mutation RegisterSellerOrganization($input: SellerRegistrationInput!) {
@ -167,7 +169,7 @@ export const REGISTER_SELLER_ORGANIZATION = gql`
}
}
}
`
`;
export const ADD_MARKETPLACE_API_KEY = gql`
mutation AddMarketplaceApiKey($input: MarketplaceApiKeyInput!) {
@ -183,13 +185,13 @@ export const ADD_MARKETPLACE_API_KEY = gql`
}
}
}
`
`;
export const REMOVE_MARKETPLACE_API_KEY = gql`
mutation RemoveMarketplaceApiKey($marketplace: MarketplaceType!) {
removeMarketplaceApiKey(marketplace: $marketplace)
}
`
`;
export const UPDATE_USER_PROFILE = gql`
mutation UpdateUserProfile($input: UpdateUserProfileInput!) {
@ -237,7 +239,7 @@ export const UPDATE_USER_PROFILE = gql`
}
}
}
`
`;
export const UPDATE_ORGANIZATION_BY_INN = gql`
mutation UpdateOrganizationByInn($inn: String!) {
@ -285,12 +287,15 @@ export const UPDATE_ORGANIZATION_BY_INN = gql`
}
}
}
`
`;
// Мутации для контрагентов
export const SEND_COUNTERPARTY_REQUEST = gql`
mutation SendCounterpartyRequest($organizationId: ID!, $message: String) {
sendCounterpartyRequest(organizationId: $organizationId, message: $message) {
sendCounterpartyRequest(
organizationId: $organizationId
message: $message
) {
success
message
request {
@ -315,7 +320,7 @@ export const SEND_COUNTERPARTY_REQUEST = gql`
}
}
}
`
`;
export const RESPOND_TO_COUNTERPARTY_REQUEST = gql`
mutation RespondToCounterpartyRequest($requestId: ID!, $accept: Boolean!) {
@ -344,24 +349,32 @@ export const RESPOND_TO_COUNTERPARTY_REQUEST = gql`
}
}
}
`
`;
export const CANCEL_COUNTERPARTY_REQUEST = gql`
mutation CancelCounterpartyRequest($requestId: ID!) {
cancelCounterpartyRequest(requestId: $requestId)
}
`
`;
export const REMOVE_COUNTERPARTY = gql`
mutation RemoveCounterparty($organizationId: ID!) {
removeCounterparty(organizationId: $organizationId)
}
`
`;
// Мутации для сообщений
export const SEND_MESSAGE = gql`
mutation SendMessage($receiverOrganizationId: ID!, $content: String!, $type: MessageType = TEXT) {
sendMessage(receiverOrganizationId: $receiverOrganizationId, content: $content, type: $type) {
mutation SendMessage(
$receiverOrganizationId: ID!
$content: String!
$type: MessageType = TEXT
) {
sendMessage(
receiverOrganizationId: $receiverOrganizationId
content: $content
type: $type
) {
success
message
messageData {
@ -403,11 +416,19 @@ export const SEND_MESSAGE = gql`
}
}
}
`
`;
export const SEND_VOICE_MESSAGE = gql`
mutation SendVoiceMessage($receiverOrganizationId: ID!, $voiceUrl: String!, $voiceDuration: Int!) {
sendVoiceMessage(receiverOrganizationId: $receiverOrganizationId, voiceUrl: $voiceUrl, voiceDuration: $voiceDuration) {
mutation SendVoiceMessage(
$receiverOrganizationId: ID!
$voiceUrl: String!
$voiceDuration: Int!
) {
sendVoiceMessage(
receiverOrganizationId: $receiverOrganizationId
voiceUrl: $voiceUrl
voiceDuration: $voiceDuration
) {
success
message
messageData {
@ -449,11 +470,23 @@ export const SEND_VOICE_MESSAGE = gql`
}
}
}
`
`;
export const SEND_IMAGE_MESSAGE = gql`
mutation SendImageMessage($receiverOrganizationId: ID!, $fileUrl: String!, $fileName: String!, $fileSize: Int!, $fileType: String!) {
sendImageMessage(receiverOrganizationId: $receiverOrganizationId, fileUrl: $fileUrl, fileName: $fileName, fileSize: $fileSize, fileType: $fileType) {
mutation SendImageMessage(
$receiverOrganizationId: ID!
$fileUrl: String!
$fileName: String!
$fileSize: Int!
$fileType: String!
) {
sendImageMessage(
receiverOrganizationId: $receiverOrganizationId
fileUrl: $fileUrl
fileName: $fileName
fileSize: $fileSize
fileType: $fileType
) {
success
message
messageData {
@ -495,11 +528,23 @@ export const SEND_IMAGE_MESSAGE = gql`
}
}
}
`
`;
export const SEND_FILE_MESSAGE = gql`
mutation SendFileMessage($receiverOrganizationId: ID!, $fileUrl: String!, $fileName: String!, $fileSize: Int!, $fileType: String!) {
sendFileMessage(receiverOrganizationId: $receiverOrganizationId, fileUrl: $fileUrl, fileName: $fileName, fileSize: $fileSize, fileType: $fileType) {
mutation SendFileMessage(
$receiverOrganizationId: ID!
$fileUrl: String!
$fileName: String!
$fileSize: Int!
$fileType: String!
) {
sendFileMessage(
receiverOrganizationId: $receiverOrganizationId
fileUrl: $fileUrl
fileName: $fileName
fileSize: $fileSize
fileType: $fileType
) {
success
message
messageData {
@ -541,13 +586,13 @@ export const SEND_FILE_MESSAGE = gql`
}
}
}
`
`;
export const MARK_MESSAGES_AS_READ = gql`
mutation MarkMessagesAsRead($conversationId: ID!) {
markMessagesAsRead(conversationId: $conversationId)
}
`
`;
// Мутации для услуг
export const CREATE_SERVICE = gql`
@ -566,7 +611,7 @@ export const CREATE_SERVICE = gql`
}
}
}
`
`;
export const UPDATE_SERVICE = gql`
mutation UpdateService($id: ID!, $input: ServiceInput!) {
@ -584,13 +629,13 @@ export const UPDATE_SERVICE = gql`
}
}
}
`
`;
export const DELETE_SERVICE = gql`
mutation DeleteService($id: ID!) {
deleteService(id: $id)
}
`
`;
// Мутации для расходников
export const CREATE_SUPPLY = gql`
@ -617,7 +662,7 @@ export const CREATE_SUPPLY = gql`
}
}
}
`
`;
export const UPDATE_SUPPLY = gql`
mutation UpdateSupply($id: ID!, $input: SupplyInput!) {
@ -643,13 +688,13 @@ export const UPDATE_SUPPLY = gql`
}
}
}
`
`;
export const DELETE_SUPPLY = gql`
mutation DeleteSupply($id: ID!) {
deleteSupply(id: $id)
}
`
`;
// Мутация для заказа поставки расходников
export const CREATE_SUPPLY_ORDER = gql`
@ -697,7 +742,7 @@ export const CREATE_SUPPLY_ORDER = gql`
}
}
}
`
`;
// Мутации для логистики
export const CREATE_LOGISTICS = gql`
@ -717,7 +762,7 @@ export const CREATE_LOGISTICS = gql`
}
}
}
`
`;
export const UPDATE_LOGISTICS = gql`
mutation UpdateLogistics($id: ID!, $input: LogisticsInput!) {
@ -736,13 +781,13 @@ export const UPDATE_LOGISTICS = gql`
}
}
}
`
`;
export const DELETE_LOGISTICS = gql`
mutation DeleteLogistics($id: ID!) {
deleteLogistics(id: $id)
}
`
`;
// Мутации для товаров оптовика
export const CREATE_PRODUCT = gql`
@ -775,7 +820,7 @@ export const CREATE_PRODUCT = gql`
}
}
}
`
`;
export const UPDATE_PRODUCT = gql`
mutation UpdateProduct($id: ID!, $input: ProductInput!) {
@ -807,13 +852,13 @@ export const UPDATE_PRODUCT = gql`
}
}
}
`
`;
export const DELETE_PRODUCT = gql`
mutation DeleteProduct($id: ID!) {
deleteProduct(id: $id)
}
`
`;
// Мутации для корзины
export const ADD_TO_CART = gql`
@ -849,7 +894,7 @@ export const ADD_TO_CART = gql`
}
}
}
`
`;
export const UPDATE_CART_ITEM = gql`
mutation UpdateCartItem($productId: ID!, $quantity: Int!) {
@ -884,7 +929,7 @@ export const UPDATE_CART_ITEM = gql`
}
}
}
`
`;
export const REMOVE_FROM_CART = gql`
mutation RemoveFromCart($productId: ID!) {
@ -919,13 +964,13 @@ export const REMOVE_FROM_CART = gql`
}
}
}
`
`;
export const CLEAR_CART = gql`
mutation ClearCart {
clearCart
}
`
`;
// Мутации для избранного
export const ADD_TO_FAVORITES = gql`
@ -954,7 +999,7 @@ export const ADD_TO_FAVORITES = gql`
}
}
}
`
`;
export const REMOVE_FROM_FAVORITES = gql`
mutation RemoveFromFavorites($productId: ID!) {
@ -982,7 +1027,7 @@ export const REMOVE_FROM_FAVORITES = gql`
}
}
}
`
`;
// Мутации для категорий
export const CREATE_CATEGORY = gql`
@ -998,7 +1043,7 @@ export const CREATE_CATEGORY = gql`
}
}
}
`
`;
export const UPDATE_CATEGORY = gql`
mutation UpdateCategory($id: ID!, $input: CategoryInput!) {
@ -1013,13 +1058,13 @@ export const UPDATE_CATEGORY = gql`
}
}
}
`
`;
export const DELETE_CATEGORY = gql`
mutation DeleteCategory($id: ID!) {
deleteCategory(id: $id)
}
`
`;
// Мутации для сотрудников
export const CREATE_EMPLOYEE = gql`
@ -1048,7 +1093,7 @@ export const CREATE_EMPLOYEE = gql`
}
}
}
`
`;
export const UPDATE_EMPLOYEE = gql`
mutation UpdateEmployee($id: ID!, $input: UpdateEmployeeInput!) {
@ -1081,19 +1126,19 @@ export const UPDATE_EMPLOYEE = gql`
}
}
}
`
`;
export const DELETE_EMPLOYEE = gql`
mutation DeleteEmployee($id: ID!) {
deleteEmployee(id: $id)
}
`
`;
export const UPDATE_EMPLOYEE_SCHEDULE = gql`
mutation UpdateEmployeeSchedule($input: UpdateScheduleInput!) {
updateEmployeeSchedule(input: $input)
}
`
`;
export const CREATE_WILDBERRIES_SUPPLY = gql`
mutation CreateWildberriesSupply($input: CreateWildberriesSupplyInput!) {
@ -1110,7 +1155,7 @@ export const CREATE_WILDBERRIES_SUPPLY = gql`
}
}
}
`
`;
// Админ мутации
export const ADMIN_LOGIN = gql`
@ -1130,13 +1175,13 @@ export const ADMIN_LOGIN = gql`
}
}
}
`
`;
export const ADMIN_LOGOUT = gql`
mutation AdminLogout {
adminLogout
}
`
`;
export const CREATE_SUPPLY_SUPPLIER = gql`
mutation CreateSupplySupplier($input: CreateSupplySupplierInput!) {
@ -1156,4 +1201,46 @@ export const CREATE_SUPPLY_SUPPLIER = gql`
}
}
}
`
`;
// Мутация для обновления статуса заказа поставки
export const UPDATE_SUPPLY_ORDER_STATUS = gql`
mutation UpdateSupplyOrderStatus($id: ID!, $status: SupplyOrderStatus!) {
updateSupplyOrderStatus(id: $id, status: $status) {
success
message
order {
id
status
deliveryDate
totalAmount
totalItems
partner {
id
name
fullName
}
items {
id
quantity
price
totalPrice
product {
id
name
article
description
price
quantity
images
mainImage
category {
id
name
}
}
}
}
}
}
`;

View File

@ -398,14 +398,18 @@ export const resolvers = {
const suppliers = await prisma.supplySupplier.findMany({
where: { organizationId: currentUser.organization.id },
orderBy: { createdAt: 'desc' }
orderBy: { createdAt: "desc" },
});
return suppliers;
},
// Логистика конкретной организации
organizationLogistics: async (_: unknown, args: { organizationId: string }, context: Context) => {
organizationLogistics: async (
_: unknown,
args: { organizationId: string },
context: Context
) => {
if (!context.user) {
throw new GraphQLError("Требуется авторизация", {
extensions: { code: "UNAUTHENTICATED" },
@ -3259,38 +3263,38 @@ export const resolvers = {
totalItems: totalItems,
organizationId: currentUser.organization.id,
fulfillmentCenterId: fulfillmentCenterId,
status: initialStatus as any,
status: initialStatus,
items: {
create: orderItems,
},
},
include: {
partner: {
include: {
users: true,
include: {
partner: {
include: {
users: true,
},
},
},
organization: {
include: {
users: true,
organization: {
include: {
users: true,
},
},
},
fulfillmentCenter: {
include: {
users: true,
fulfillmentCenter: {
include: {
users: true,
},
},
},
items: {
include: {
product: {
include: {
category: true,
organization: true,
items: {
include: {
product: {
include: {
category: true,
organization: true,
},
},
},
},
},
},
});
// Создаем расходники на основе заказанных товаров
@ -4643,6 +4647,182 @@ export const resolvers = {
};
}
},
// Обновить статус заказа поставки
updateSupplyOrderStatus: async (
_: unknown,
args: {
id: string;
status:
| "PENDING"
| "CONFIRMED"
| "IN_TRANSIT"
| "DELIVERED"
| "CANCELLED";
},
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("У пользователя нет организации");
}
try {
// Находим заказ поставки
const existingOrder = await prisma.supplyOrder.findFirst({
where: {
id: args.id,
OR: [
{ organizationId: currentUser.organization.id }, // Создатель заказа
{ partnerId: currentUser.organization.id }, // Поставщик
{ fulfillmentCenterId: currentUser.organization.id }, // Фулфилмент-центр
],
},
include: {
items: {
include: {
product: {
include: {
category: true,
},
},
},
},
partner: true,
fulfillmentCenter: true,
},
});
if (!existingOrder) {
throw new GraphQLError("Заказ поставки не найден или нет доступа");
}
// Обновляем статус заказа
const updatedOrder = await prisma.supplyOrder.update({
where: { id: args.id },
data: { status: args.status },
include: {
partner: true,
items: {
include: {
product: {
include: {
category: true,
},
},
},
},
},
});
// Если статус изменился на DELIVERED, обновляем склад фулфилмента
if (args.status === "DELIVERED" && existingOrder.fulfillmentCenterId) {
console.log("🚚 Обновляем склад фулфилмента:", {
fulfillmentCenterId: existingOrder.fulfillmentCenterId,
itemsCount: existingOrder.items.length,
items: existingOrder.items.map((item) => ({
productName: item.product.name,
quantity: item.quantity,
})),
});
// Обновляем расходники фулфилмента
for (const item of existingOrder.items) {
console.log("📦 Обрабатываем товар:", {
productName: item.product.name,
quantity: item.quantity,
fulfillmentCenterId: existingOrder.fulfillmentCenterId,
});
// Ищем существующий расходник
const existingSupply = await prisma.supply.findFirst({
where: {
name: item.product.name,
organizationId: existingOrder.fulfillmentCenterId,
},
});
console.log("🔍 Найден существующий расходник:", !!existingSupply);
if (existingSupply) {
console.log("📈 Обновляем существующий расходник:", {
id: existingSupply.id,
oldStock: existingSupply.currentStock,
newStock: existingSupply.currentStock + item.quantity,
});
// Обновляем количество существующего расходника
await prisma.supply.update({
where: { id: existingSupply.id },
data: {
currentStock: existingSupply.currentStock + item.quantity,
status: "available", // Меняем статус на "доступен"
},
});
} else {
console.log(" Создаем новый расходник:", {
name: item.product.name,
quantity: item.quantity,
organizationId: existingOrder.fulfillmentCenterId,
});
// Создаем новый расходник
const newSupply = await prisma.supply.create({
data: {
name: item.product.name,
description:
item.product.description ||
`Поставка от ${existingOrder.partner.name}`,
price: item.price,
quantity: item.quantity,
unit: "шт",
category: item.product.category?.name || "Упаковка",
status: "available",
date: new Date(),
supplier:
existingOrder.partner.name ||
existingOrder.partner.fullName ||
"Не указан",
minStock: Math.round(item.quantity * 0.1),
currentStock: item.quantity,
organizationId: existingOrder.fulfillmentCenterId,
},
});
console.log("✅ Создан новый расходник:", {
id: newSupply.id,
name: newSupply.name,
currentStock: newSupply.currentStock,
});
}
}
console.log("🎉 Склад фулфилмента успешно обновлен!");
}
return {
success: true,
message: `Статус заказа поставки обновлен на "${args.status}"`,
order: updatedOrder,
};
} catch (error) {
console.error("Error updating supply order status:", error);
return {
success: false,
message: "Ошибка при обновлении статуса заказа поставки",
};
}
},
},
// Резолверы типов

View File

@ -181,6 +181,7 @@ export const typeDefs = gql`
# Заказы поставок расходников
createSupplyOrder(input: SupplyOrderInput!): SupplyOrderResponse!
updateSupplyOrderStatus(id: ID!, status: SupplyOrderStatus!): SupplyOrderResponse!
# Работа с логистикой
createLogistics(input: LogisticsInput!): LogisticsResponse!