From 81acd49fd92a4fbee33f1ab250fc44df92d90ccf Mon Sep 17 00:00:00 2001 From: Fedor Date: Sun, 30 Nov 2025 11:45:35 +0300 Subject: [PATCH] =?UTF-8?q?feat(frontend):=20=D0=B8=D1=81=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20form?= =?UTF-8?q?=5Fdraft=20=D0=B4=D0=BB=D1=8F=20=D1=84=D0=BE=D1=80=D0=BC=D1=8B?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=B4=D1=82=D0=B2=D0=B5=D1=80=D0=B6=D0=B4=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - StepDraftSelection: кнопка 'Продолжить' активна для draft_docs_complete - ClaimForm: проверка form_draft при загрузке черновика - Если есть form_draft — преобразуем в propertyName и показываем форму подтверждения - Поддержка статуса draft_docs_complete для перехода к подтверждению --- .../components/form/StepDraftSelection.tsx | 18 +-- ticket_form/frontend/src/pages/ClaimForm.tsx | 132 ++++++++++++------ 2 files changed, 96 insertions(+), 54 deletions(-) diff --git a/ticket_form/frontend/src/components/form/StepDraftSelection.tsx b/ticket_form/frontend/src/components/form/StepDraftSelection.tsx index df09a6a1..bfbeaacc 100644 --- a/ticket_form/frontend/src/components/form/StepDraftSelection.tsx +++ b/ticket_form/frontend/src/components/form/StepDraftSelection.tsx @@ -127,10 +127,10 @@ const STATUS_CONFIG: Record, - label: 'Обработка', - description: 'Формируется заявление...', - action: 'Ожидайте', + icon: , + label: 'Документы загружены', + description: 'Все документы обработаны', + action: 'Продолжить', }, draft_claim_ready: { color: 'green', @@ -274,11 +274,8 @@ export default function StepDraftSelection({ if (draft.is_legacy && onRestartDraft) { // Legacy черновик - предлагаем начать заново с тем же описанием onRestartDraft(draftId, draft.problem_description || ''); - } else if (draft.status_code === 'draft_docs_complete') { - // Всё ещё обрабатывается - показываем сообщение - message.info('Заявление формируется. Пожалуйста, подождите.'); } else { - // Обычный переход + // ✅ Разрешаем переход на любом этапе до апрува по SMS onSelectDraft(draftId); } }; @@ -286,15 +283,12 @@ export default function StepDraftSelection({ // Кнопка действия const getActionButton = (draft: Draft) => { const config = getStatusConfig(draft); - const isProcessing = draft.status_code === 'draft_docs_complete'; return ( diff --git a/ticket_form/frontend/src/pages/ClaimForm.tsx b/ticket_form/frontend/src/pages/ClaimForm.tsx index acb91807..2369fab3 100644 --- a/ticket_form/frontend/src/pages/ClaimForm.tsx +++ b/ticket_form/frontend/src/pages/ClaimForm.tsx @@ -107,7 +107,7 @@ export default function ClaimForm() { const [hasDrafts, setHasDrafts] = useState(false); useEffect(() => { - // 🔥 VERSION CHECK: Если видишь это в консоли - фронт обновился! + // 🔥 VERSION CHECK: Если видишь это в консоли - фронт обновился! console.log('🔥 ClaimForm v3.8 - 2025-11-20 15:10 - Fix session_id priority in loadDraft'); }, []); @@ -613,8 +613,13 @@ export default function ClaimForm() { const hasDocuments = Array.isArray(documentsMeta) && documentsMeta.length > 0; const isDraft = claim.status_code === 'draft'; + // ✅ НОВОЕ: Проверяем наличие form_draft (собранные данные из RAG) + const formDraft = payload.form_draft; + const hasFormDraft = !!(formDraft && formDraft.user && formDraft.offenders); + const isDraftDocsComplete = claim.status_code === 'draft_docs_complete'; + const allStepsFilled = hasDescription && hasWizardPlan && hasAnswers && hasDocuments; - const isReadyForConfirmation = allStepsFilled && isDraft; + const isReadyForConfirmation = (allStepsFilled && isDraft) || (hasFormDraft && isDraftDocsComplete); console.log('🔍 Проверка полноты черновика:', { hasDescription, @@ -622,6 +627,8 @@ export default function ClaimForm() { hasAnswers, hasDocuments, isDraft, + hasFormDraft, + isDraftDocsComplete, allStepsFilled, isReadyForConfirmation, problemDescriptionFound: !!problemDescription, @@ -707,19 +714,60 @@ export default function ClaimForm() { // ✅ Если все шаги заполнены и статус = draft → переходим к форме подтверждения if (isReadyForConfirmation) { console.log('✅ Все шаги заполнены, преобразуем данные для формы подтверждения'); + console.log('✅ hasFormDraft:', hasFormDraft, 'isDraftDocsComplete:', isDraftDocsComplete); setIsPhoneVerified(true); - // Преобразуем данные из БД в формат propertyName для формы подтверждения - const claimPlanData = transformDraftToClaimPlanFormat({ - claim, - payload, - body, - isTelegramFormat, - finalClaimId, - actualSessionId, - currentFormData: formData, - }); + let claimPlanData; + + // ✅ НОВОЕ: Если есть form_draft — используем его! + if (hasFormDraft && formDraft) { + console.log('✅ Используем form_draft из БД:', formDraft); + + // Преобразуем form_draft в формат propertyName + claimPlanData = { + propertyName: { + applicant: formDraft.user || {}, + case: { + category: formDraft.project?.category || '', + description: formDraft.project?.description || problemDescription || '', + }, + contract_or_service: { + subject: formDraft.project?.subject || '', + agrprice: formDraft.project?.agrprice || '', + agrdate: formDraft.project?.agrdate || '', + startdate: formDraft.project?.startdate || '', + finishdate: formDraft.project?.finishdate || '', + country: formDraft.project?.country || '', + hotel: formDraft.project?.hotel || '', + }, + offenders: formDraft.offenders || [], + claim: {}, + meta: { + claim_id: finalClaimId, + unified_id: formData.unified_id || '', + session_token: actualSessionId, + }, + attachments_names: documentsMeta.map((d: any) => d.original_file_name || d.file_name || ''), + }, + session_token: actualSessionId, + claim_id: finalClaimId, + prefix: 'clpr_', + }; + } else { + // Старый способ: преобразуем данные из БД + claimPlanData = transformDraftToClaimPlanFormat({ + claim, + payload, + body, + isTelegramFormat, + finalClaimId, + actualSessionId, + currentFormData: formData, + }); + } + + console.log('✅ claimPlanData для формы подтверждения:', claimPlanData); // Сохраняем данные заявления в formData updateFormData({ @@ -900,17 +948,17 @@ export default function ClaimForm() { is_new_project: formData.is_new_project, // Основные поля формы (для удобства в n8n) - voucher: formData.voucher, - phone: formData.phone, + voucher: formData.voucher, + phone: formData.phone, email: formData.email, - event_type: formData.eventType, - payment_method: formData.paymentMethod, - bank_name: formData.bankName, - card_number: formData.cardNumber, - account_number: formData.accountNumber, + event_type: formData.eventType, + payment_method: formData.paymentMethod, + bank_name: formData.bankName, + card_number: formData.cardNumber, + account_number: formData.accountNumber, // Старый блок документов + новые загрузки визарда (пока как есть) - documents: formData.documents || {}, + documents: formData.documents || {}, wizard_uploads: formData.wizardUploads || {}, // Всё состояние формы целиком — на всякий случай @@ -1257,19 +1305,19 @@ export default function ClaimForm() { )} {/* Кнопка "Начать заново" - показываем только после шага телефона */} {currentStep > 0 && ( - + )} ) @@ -1284,15 +1332,15 @@ export default function ClaimForm() { ) : ( <> - - {steps.map((item, index) => ( - - ))} - + + {steps.map((item, index) => ( + + ))} +
{steps[currentStep] ? steps[currentStep].content : (