Files
aiform_dev/frontend/src/components/form/StepClaimConfirmation.tsx
AI Assistant aed2a86ba8 fix: Fix claim_id and unified_id display in confirmation form
Problem:
- Claim ID and Unified ID showing as 'не указан' in confirmation form
- transformDraftToClaimPlanFormat was returning array instead of object
- StepClaimConfirmation was not correctly extracting IDs from claimPlanData

Solution:
1. Changed transformDraftToClaimPlanFormat return type:
   - Changed from array [{ propertyName, ... }] to object { propertyName, ... }
   - This matches what StepClaimConfirmation expects

2. Enhanced ID extraction in StepClaimConfirmation:
   - Added explicit claimId and unifiedId variables
   - Better fallback chain: claimPlanData.claim_id -> propertyName.meta.claim_id
   - Same for unified_id

3. Added comprehensive logging:
   - Log claimPlanData structure on component mount
   - Log extracted IDs before form generation
   - Log transformDraftToClaimPlanFormat input/output
   - Log claim.unified_id from API response

4. Improved data flow:
   - claim.unified_id from API -> transformDraftToClaimPlanFormat -> StepClaimConfirmation
   - Fallback to currentFormData.unified_id if claim.unified_id missing

Files:
- frontend/src/pages/ClaimForm.tsx: Changed return type, added logging
- frontend/src/components/form/StepClaimConfirmation.tsx: Enhanced ID extraction, added logging
2025-11-24 15:16:46 +03:00

236 lines
7.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useEffect, useRef, useState } from 'react';
import { Card, Spin, message } from 'antd';
interface Props {
claimPlanData: any; // Данные заявления от n8n
onNext: () => void;
onPrev: () => void;
}
export default function StepClaimConfirmation({
claimPlanData,
onNext,
onPrev,
}: Props) {
const [loading, setLoading] = useState(true);
const iframeRef = useRef<HTMLIFrameElement>(null);
const [htmlContent, setHtmlContent] = useState<string>('');
useEffect(() => {
if (!claimPlanData) {
message.error('Данные заявления не получены');
return;
}
console.log('📋 StepClaimConfirmation: получены данные claimPlanData:', claimPlanData);
console.log('📋 claimPlanData.claim_id:', claimPlanData?.claim_id);
console.log('📋 claimPlanData.unified_id:', claimPlanData?.unified_id);
console.log('📋 claimPlanData.propertyName?.meta?.claim_id:', claimPlanData?.propertyName?.meta?.claim_id);
console.log('📋 claimPlanData.propertyName?.meta?.unified_id:', claimPlanData?.propertyName?.meta?.unified_id);
// Формируем данные для формы подтверждения
// Формат должен соответствовать тому, что ожидает HTML форма
const claimId = claimPlanData?.claim_id || claimPlanData?.propertyName?.meta?.claim_id || '';
const unifiedId = claimPlanData?.unified_id || claimPlanData?.propertyName?.meta?.unified_id || '';
console.log('📋 Извлечённые ID:', { claimId, unifiedId });
const formData = {
case: {
user: claimPlanData?.propertyName?.applicant || {},
project: claimPlanData?.propertyName?.case || {},
offenders: claimPlanData?.propertyName?.offenders || [],
attachments: claimPlanData?.propertyName?.attachments_names || [],
meta: {
...claimPlanData?.propertyName?.meta,
session_token: claimPlanData?.session_token || '',
prefix: claimPlanData?.prefix || '',
telegram_id: claimPlanData?.telegram_id || '',
claim_id: claimId,
unified_id: unifiedId,
user_id: claimPlanData?.user_id || claimPlanData?.propertyName?.meta?.user_id || '',
},
},
session_token: claimPlanData?.session_token || '',
telegram_id: claimPlanData?.telegram_id || '',
token: claimPlanData?.token || '',
sms_meta: {
session_token: claimPlanData?.session_token || '',
prefix: claimPlanData?.prefix || '',
telegram_id: claimPlanData?.telegram_id || '',
claim_id: claimId,
unified_id: unifiedId,
user_id: claimPlanData?.user_id || claimPlanData?.propertyName?.meta?.user_id || '',
},
};
console.log('📋 Сформированные formData.meta:', formData.case.meta);
// Здесь нужно будет получить HTML форму от n8n или использовать готовый шаблон
// Пока используем заглушку - в реальности нужно будет вызывать n8n workflow для генерации HTML
const html = generateConfirmationFormHTML(formData);
setHtmlContent(html);
setLoading(false);
}, [claimPlanData]);
// Функция генерации HTML формы (временная заглушка)
// В реальности это должен делать n8n workflow
const generateConfirmationFormHTML = (data: any): string => {
// Экранируем данные для безопасной вставки в HTML
const caseJson = JSON.stringify(data)
.replace(/</g, '\\u003c')
.replace(/>/g, '\\u003e');
return `<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<title>Подтверждение данных</title>
<script src="https://telegram.org/js/telegram-web-app.js"></script>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
margin: 0;
padding: 20px;
background: #f5f5f5;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
padding: 24px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
h1 {
text-align: center;
color: #1f2937;
margin-bottom: 24px;
}
.info {
background: #f0f9ff;
border: 1px solid #bae6fd;
border-radius: 6px;
padding: 16px;
margin-bottom: 24px;
}
.info p {
margin: 8px 0;
color: #1e40af;
}
.button-group {
display: flex;
gap: 12px;
margin-top: 24px;
justify-content: center;
}
button {
padding: 12px 24px;
border: none;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
font-weight: 600;
}
.btn-primary {
background: #3b82f6;
color: white;
}
.btn-primary:hover {
background: #2563eb;
}
.btn-secondary {
background: #e5e7eb;
color: #374151;
}
.btn-secondary:hover {
background: #d1d5db;
}
</style>
</head>
<body>
<div class="container">
<h1>📋 Подтверждение данных заявления</h1>
<div class="info">
<p><strong>Статус:</strong> Данные заявления получены</p>
<p><strong>Claim ID:</strong> ${data.case?.meta?.claim_id || 'не указан'}</p>
<p><strong>Unified ID:</strong> ${data.case?.meta?.unified_id || 'не указан'}</p>
</div>
<div class="button-group">
<button class="btn-primary" onclick="window.parent.postMessage({type: 'claim_confirmed'}, '*')">
✅ Подтвердить и отправить
</button>
<button class="btn-secondary" onclick="window.parent.postMessage({type: 'claim_cancelled'}, '*')">
❌ Отмена
</button>
</div>
</div>
<script id="case-data" type="application/json">${caseJson}</script>
<script>
// Слушаем сообщения от родительского окна
window.addEventListener('message', function(event) {
console.log('Message received:', event.data);
});
// Отправляем сообщение родителю при загрузке
window.parent.postMessage({type: 'claim_form_loaded'}, '*');
</script>
</body>
</html>`;
};
useEffect(() => {
// Слушаем сообщения от iframe
const handleMessage = (event: MessageEvent) => {
console.log('📨 Message from iframe:', event.data);
if (event.data.type === 'claim_confirmed') {
message.success('Заявление подтверждено!');
onNext();
} else if (event.data.type === 'claim_cancelled') {
message.info('Подтверждение отменено');
onPrev();
} else if (event.data.type === 'claim_form_loaded') {
setLoading(false);
}
};
window.addEventListener('message', handleMessage);
return () => {
window.removeEventListener('message', handleMessage);
};
}, [onNext, onPrev]);
if (loading) {
return (
<Card>
<div style={{ textAlign: 'center', padding: '40px' }}>
<Spin size="large" />
<p style={{ marginTop: '16px' }}>Загрузка формы подтверждения...</p>
</div>
</Card>
);
}
return (
<Card>
<iframe
ref={iframeRef}
srcDoc={htmlContent}
style={{
width: '100%',
height: '800px',
border: 'none',
borderRadius: '8px',
}}
title="Форма подтверждения заявления"
/>
</Card>
);
}