Files
aiform_prod/docs/N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js

161 lines
6.5 KiB
JavaScript
Raw Normal View History

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
2025-11-26 19:54:51 +03:00
// ============================================================================
// n8n Code Node: Обработка загруженных файлов (ИСПРАВЛЕННАЯ ВЕРСИЯ)
// ============================================================================
// OCR возвращает объединённые документы: один файл на группу (group_index)
// Структура: { data: [{ group_index_num: 0, files_count: 2, newfile: "...", ... }] }
// Решение: обрабатываем каждый элемент из data как объединённый документ
// ============================================================================
// ==== INPUT SHAPE SUPPORT ====
// OCR возвращает: { data: [ ...объединённые документы... ] }
const raw = $json;
const items = Array.isArray(raw?.data) ? raw.data : (Array.isArray(raw) ? raw : []);
if (!items.length) {
return [{
json: {
claim_id: null,
payload_partial_json: { documents_meta: [], edit_fields_raw: null, edit_fields_parsed: null },
filesRows: []
}
}];
}
// ==== CLAIM_ID DISCOVERY ====
let claim_id = $json.claim_id
|| $items('Edit Fields6')?.[0]?.json?.propertyName?.case_id
|| $('Edit Fields6').first().json.body.claim_id
|| null;
// ==== UTILS ====
const safeStr = (v) => (v == null ? '' : String(v));
const nowIso = new Date().toISOString();
const tryParseJSON = (x) => {
if (x == null) return null;
if (typeof x === 'object') return x;
if (typeof x === 'string') { try { return JSON.parse(x); } catch { return null; } }
return null;
};
// ==== ПРЕДВАРИТЕЛЬНО СОБИРАЕМ uploads_field_labels ИЗ BODY ====
const editRaw = $items('Edit Fields6')?.[0]?.json || null;
const body = editRaw?.body || null;
let uploads_descriptions = [];
let uploads_field_names = [];
let uploads_field_labels = [];
if (body && typeof body === 'object') {
const d = [];
const f = [];
const l = [];
for (const k of Object.keys(body)) {
const mD = k.match(/^uploads_descriptions\[(\d+)\]$/);
const mF = k.match(/^uploads_field_names\[(\d+)\]$/);
const mL = k.match(/^uploads_field_labels\[(\d+)\]$/);
if (mD) d[Number(mD[1])] = safeStr(body[k]);
if (mF) f[Number(mF[1])] = safeStr(body[k]);
if (mL) l[Number(mL[1])] = safeStr(body[k]);
}
uploads_descriptions = d.filter(v => v !== undefined);
uploads_field_names = f.filter(v => v !== undefined);
uploads_field_labels = l.filter(v => v !== undefined);
}
// ==== BUILD documents_meta + filesRows ====
// OCR возвращает объединённые документы: один файл на group_index
// Каждый элемент из data - это уже объединённый PDF (может содержать несколько страниц)
const documents_meta = [];
const filesRows = [];
for (const it of items) {
// ✅ ПРИОРИТЕТ: Используем group_index из body (переданный с фронтенда)
// Если его нет - используем group_index_num из OCR
// Если и его нет - пытаемся определить по document_type из uploads_field_names
let grp = null;
if (body && body.group_index !== undefined && body.group_index !== null) {
grp = Number(body.group_index);
} else if (it.group_index_num !== undefined && it.group_index_num !== null) {
grp = Number(it.group_index_num);
} else {
// Fallback: пытаемся определить по document_type
const doc_type = uploads_field_names[0] || uploads_field_labels[0] || '';
// Ищем индекс в documents_required по типу документа
// Это не идеально, но лучше чем всегда 0
grp = 0; // По умолчанию 0, если не можем определить
}
grp = grp || 0;
const file_index = 0; // После объединения всегда один файл на группу
const field_name = `uploads[${grp}][${file_index}]`;
// ✅ ИСПРАВЛЕНО: uploads_field_labels содержит элементы с индексом 0 (текущий запрос),
// а grp - это позиция в documents_required. Используем индекс 0 для массивов текущего запроса.
const field_label = uploads_field_labels[0] || uploads_field_names[0] || uploads_descriptions[0] || `group-${grp}`;
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
2025-11-26 19:54:51 +03:00
// OCR уже объединил файлы, используем newfile (путь к объединённому файлу)
const draft_key = safeStr(it.newfile || (it.folder && it.file_name ? `${it.folder}/${it.file_name}` : ''));
const original_name = safeStr(it.file_name || `group_${grp}.pdf`);
const description = safeStr(it.description || uploads_descriptions[0] || '');
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
2025-11-26 19:54:51 +03:00
const prefix = safeStr(it.prefix || '');
// files_count показывает, сколько исходных файлов было объединено
const files_count = Number(it.files_count) || 1;
const pages = Number(it.pages) || null;
documents_meta.push({
field_name,
field_label,
file_id: draft_key,
file_name: original_name,
original_file_name: original_name,
uploaded_at: nowIso,
files_count, // Информация: сколько файлов было объединено
pages, // Информация: сколько страниц в объединённом PDF
});
filesRows.push({
claim_id,
group_index: grp,
file_index, // Всегда 0 для объединённого документа
original_name,
draft_key,
mime: 'application/pdf',
size_bytes: null,
description,
prefix,
field_name,
field_label,
files_count, // Информация для отладки
pages, // Информация для отладки
});
}
// ==== ПОДТЯГИВАЕМ ВСЁ ИЗ "Edit Fields" ====
const propertyName = editRaw?.propertyName || null;
const answers_parsed = body ? (tryParseJSON(body.answers) || null) : null;
const wizard_plan_parsed = body ? (tryParseJSON(body.wizard_plan) || null) : null;
// ==== OUTPUT ====
return [{
json: {
claim_id,
payload_partial_json: {
documents_meta,
edit_fields_raw: editRaw || null,
edit_fields_parsed: {
propertyName,
body,
uploads_descriptions,
uploads_field_names,
uploads_field_labels,
answers_parsed,
wizard_plan_parsed,
}
},
filesRows
}
}];