fix: Исправление загрузки документов и SQL запросов
- Исправлена потеря документов при обновлении черновика (SQL объединяет вместо перезаписи) - Исправлено определение типа документа (приоритет field_label над field_name) - Исправлены дубликаты в documents_meta и documents_uploaded - Добавлена передача group_index с фронтенда для правильного field_name - Исправлены все документы в таблице clpr_claim_documents с правильными field_name - Обновлены SQL запросы: claimsave и claimsave_final для нового флоу - Добавлена поддержка multi-file upload для одного документа - Исправлены дубликаты в списке загруженных документов на фронтенде Файлы: - SQL: SQL_CLAIMSAVE_FIXED_NEW_FLOW.sql, SQL_CLAIMSAVE_FINAL_FIXED_NEW_FLOW_WITH_UPLOADED.sql - n8n: N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js (поддержка group_index) - Backend: documents.py (передача group_index в n8n) - Frontend: StepWizardPlan.tsx (передача group_index, исправление дубликатов) - Скрипты: fix_claim_documents_field_names.py, fix_documents_meta_duplicates.py Результат: документы больше не теряются, имеют правильные типы и field_name
This commit is contained in:
@@ -17,6 +17,18 @@ import './ClaimForm.css';
|
||||
|
||||
const { Step } = Steps;
|
||||
|
||||
/**
|
||||
* Генерация UUID v4
|
||||
* Формат: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
|
||||
*/
|
||||
function generateUUIDv4(): string {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
||||
const r = (Math.random() * 16) | 0;
|
||||
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
interface FormData {
|
||||
// Шаг 1: Phone
|
||||
phone?: string;
|
||||
@@ -633,12 +645,33 @@ export default function ClaimForm() {
|
||||
console.log('🔄 Загрузка черновика: session_id из черновика:', claim.session_token);
|
||||
console.log('🔄 Загрузка черновика: текущий sessionIdRef.current:', sessionIdRef.current);
|
||||
console.log('🔄 Загрузка черновика: текущий formData.session_id:', formData.session_id);
|
||||
const actualSessionId = sessionIdRef.current || formData.session_id;
|
||||
|
||||
// ✅ При загрузке черновика используем session_id из черновика (для продолжения работы с той же жалобой)
|
||||
// Если session_id из черновика есть - используем его, иначе текущий
|
||||
const actualSessionId = claim.session_token || sessionIdRef.current || formData.session_id;
|
||||
console.log('🔄 Загрузка черновика: ИСПОЛЬЗУЕМ session_id:', actualSessionId);
|
||||
|
||||
// ✅ Обновляем sessionIdRef на сессию из черновика (если есть)
|
||||
if (claim.session_token && claim.session_token !== sessionIdRef.current) {
|
||||
sessionIdRef.current = claim.session_token;
|
||||
console.log('🔄 Обновляем sessionIdRef на сессию из черновика:', claim.session_token);
|
||||
}
|
||||
|
||||
// ✅ НОВЫЙ ФЛОУ: Извлекаем documents_required из payload
|
||||
const documentsRequired = body.documents_required || payload.documents_required || [];
|
||||
const documentsUploaded = body.documents_uploaded || payload.documents_uploaded || [];
|
||||
const documentsSkipped = body.documents_skipped || payload.documents_skipped || [];
|
||||
const currentDocIndex = body.current_doc_index ?? payload.current_doc_index ?? 0;
|
||||
|
||||
console.log('📋 Загрузка черновика - documents_required:', documentsRequired.length, 'шт.');
|
||||
console.log('📋 Загрузка черновика - body.documents_required:', body.documents_required);
|
||||
console.log('📋 Загрузка черновика - payload.documents_required:', payload.documents_required);
|
||||
console.log('📋 Загрузка черновика - status_code:', claim.status_code);
|
||||
console.log('📋 Загрузка черновика - все ключи payload:', Object.keys(payload));
|
||||
|
||||
updateFormData({
|
||||
claim_id: finalClaimId, // ✅ Используем извлечённый claim_id
|
||||
session_id: actualSessionId, // ✅ Используем ТЕКУЩИЙ session_id, а не старый из черновика
|
||||
session_id: actualSessionId, // ✅ Используем session_id из черновика (если есть) или текущий
|
||||
phone: body.phone || payload.phone || formData.phone,
|
||||
email: body.email || payload.email || formData.email,
|
||||
problemDescription: problemDescription || formData.problemDescription,
|
||||
@@ -661,6 +694,11 @@ export default function ClaimForm() {
|
||||
contact_id: body.contact_id || payload.contact_id || formData.contact_id,
|
||||
project_id: body.project_id || payload.project_id || formData.project_id,
|
||||
unified_id: formData.unified_id, // ✅ Сохраняем unified_id
|
||||
// ✅ НОВЫЙ ФЛОУ: Документы
|
||||
documents_required: documentsRequired,
|
||||
documents_uploaded: documentsUploaded,
|
||||
documents_skipped: documentsSkipped,
|
||||
current_doc_index: currentDocIndex,
|
||||
});
|
||||
|
||||
setSelectedDraftId(finalClaimId);
|
||||
@@ -703,11 +741,16 @@ export default function ClaimForm() {
|
||||
|
||||
let targetStep = 1; // По умолчанию - описание (шаг 1)
|
||||
|
||||
if (wizardPlan) {
|
||||
// ✅ Если есть wizard_plan - переходим к визарду (шаг 2)
|
||||
// ✅ НОВЫЙ ФЛОУ: Если есть documents_required, показываем загрузку документов
|
||||
if (documentsRequired.length > 0) {
|
||||
targetStep = 2;
|
||||
console.log('✅ Переходим к StepWizardPlan (шаг 2) - НОВЫЙ ФЛОУ: есть documents_required, показываем загрузку документов');
|
||||
console.log('✅ documents_required:', documentsRequired.length, 'документов');
|
||||
} else if (wizardPlan) {
|
||||
// ✅ СТАРЫЙ ФЛОУ: Если есть wizard_plan - переходим к визарду (шаг 2)
|
||||
// Пользователь уже описывал проблему, и есть план вопросов
|
||||
targetStep = 2;
|
||||
console.log('✅ Переходим к StepWizardPlan (шаг 2) - есть wizard_plan');
|
||||
console.log('✅ Переходим к StepWizardPlan (шаг 2) - СТАРЫЙ ФЛОУ: есть wizard_plan');
|
||||
console.log('✅ answers в черновике:', answers ? 'есть (показываем заполненную форму)' : 'нет (показываем пустую форму)');
|
||||
} else if (problemDescription) {
|
||||
// Если есть описание, но нет плана - переходим к визарду (шаг 2), чтобы получить план
|
||||
@@ -793,12 +836,27 @@ export default function ClaimForm() {
|
||||
console.log('🆕 Текущий currentStep:', currentStep);
|
||||
console.log('🆕 isPhoneVerified:', isPhoneVerified);
|
||||
|
||||
// ✅ Генерируем НОВУЮ сессию для новой жалобы
|
||||
const newSessionId = 'sess_' + generateUUIDv4();
|
||||
console.log('🆕 Генерируем новую сессию для жалобы:', newSessionId);
|
||||
console.log('🆕 Старая сессия:', sessionIdRef.current);
|
||||
|
||||
// ✅ Обновляем sessionIdRef на новую сессию
|
||||
sessionIdRef.current = newSessionId;
|
||||
|
||||
// ✅ session_token в localStorage остаётся ПРЕЖНИМ (авторизация сохраняется)
|
||||
const savedSessionToken = localStorage.getItem('session_token');
|
||||
console.log('🆕 session_token в localStorage (авторизация):', savedSessionToken || '(не сохранён)');
|
||||
console.log('🆕 Авторизация сохранена: unified_id=', formData.unified_id, 'phone=', formData.phone);
|
||||
|
||||
setShowDraftSelection(false);
|
||||
setSelectedDraftId(null);
|
||||
setHasDrafts(false); // ✅ Сбрасываем флаг наличия черновиков
|
||||
|
||||
// Очищаем данные формы, кроме телефона и session_id
|
||||
// ✅ Очищаем данные формы и устанавливаем НОВЫЙ session_id
|
||||
// unified_id, phone, contact_id остаются прежними - авторизация сохранена!
|
||||
updateFormData({
|
||||
session_id: newSessionId, // ✅ Новая сессия для новой жалобы
|
||||
claim_id: undefined,
|
||||
problemDescription: undefined,
|
||||
wizardPlan: undefined,
|
||||
@@ -809,6 +867,7 @@ export default function ClaimForm() {
|
||||
wizardUploads: undefined,
|
||||
wizardSkippedDocuments: undefined,
|
||||
eventType: undefined,
|
||||
// ✅ unified_id, phone, contact_id НЕ очищаем - авторизация сохраняется!
|
||||
});
|
||||
|
||||
console.log('🆕 Переходим к шагу описания проблемы (пропускаем Phone и DraftSelection)');
|
||||
@@ -819,7 +878,7 @@ export default function ClaimForm() {
|
||||
// Шаг 1 - Description (сюда переходим)
|
||||
// Шаг 2 - WizardPlan
|
||||
setCurrentStep(1); // ✅ Переходим к описанию (индекс 1)
|
||||
}, [updateFormData, currentStep, isPhoneVerified]);
|
||||
}, [updateFormData, currentStep, isPhoneVerified, formData.unified_id, formData.phone]);
|
||||
|
||||
const handleSubmit = useCallback(async () => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user