Files
crm.clientright.ru/ticket_form/docs/CODE_FILES_RENAME_FIXED.js

165 lines
6.2 KiB
JavaScript
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.

// === НАСТРОЙКА ===
const FILES_ROWS_NODE = 'editfiletobd1'; // <--- имя ноды, где формировались filesRows
// === ВХОД ИЗ PG ===
const sql = $json || {};
const claim_id = sql?.claim?.claim_id || $json.claim_id || null;
const docs = Array.isArray(sql.documents) ? sql.documents : [];
// === filesRows из предыдущей ноды ===
const filesRows = $items(FILES_ROWS_NODE)?.[0]?.json?.filesRows || [];
// === Получаем project_id и project_name ===
// Пробуем получить из Edit Fields6, затем из текущего $json, затем из предыдущих нод
let project_id = null;
let project_name = null;
// 1. Пробуем из Edit Fields6
try {
const editFields6 = $('Edit Fields6').first().json.propertyName || {};
project_id = editFields6.project_id || null;
project_name = editFields6.project_name || null;
} catch (e) {
// Игнорируем, пробуем другие источники
}
// 2. Пробуем из текущего $json
if (!project_id) {
project_id = $json?.project_id || null;
}
if (!project_name) {
project_name = $json?.project_name || null;
}
// 3. Пробуем из предыдущей ноды (если есть нода, которая получает данные из Redis)
if (!project_name) {
try {
// Пробуем найти ноду, которая получает данные сессии из Redis
const redisNode = $node["Get Session"] || $node["GetSession"] || $node["Redis Get"];
if (redisNode && redisNode.json) {
const sessionData = typeof redisNode.json.value === 'string'
? JSON.parse(redisNode.json.value)
: redisNode.json.value;
if (!project_name) {
project_name = sessionData?.project_name || null;
}
if (!project_id) {
project_id = sessionData?.project_id || null;
}
}
} catch (e) {
// Игнорируем ошибки
}
}
// === Утилиты ===
const S = v => (v == null ? '' : String(v));
const extOf = n => (S(n).match(/\.([a-z0-9]+)$/i)?.[1]?.toLowerCase() || 'pdf');
const baseName = k => S(k).split('/').pop() || 'file.pdf';
const slugify = s => {
s = S(s).toLowerCase().trim();
const map = {а:'a',б:'b',в:'v',г:'g',д:'d',е:'e',ё:'e',ж:'zh',з:'z',и:'i',й:'y',к:'k',л:'l',
м:'m',н:'n',о:'o',п:'p',р:'r',с:'s',т:'t',у:'u',ф:'f',х:'h',ц:'c',ч:'ch',ш:'sh',
щ:'sch',ъ:'',ы:'y',ь:'',э:'e',ю:'yu',я:'ya'};
s = s.replace(/[а-яё]/g, ch => map[ch] ?? ch);
return s.replace(/[^a-z0-9]+/g,'-').replace(/^-+|-+$/g,'') || 'doc';
};
// field_name -> doc_id
const byField = Object.create(null);
for (const d of docs) if (d?.field_name && d?.id) byField[d.field_name] = d.id;
// Правило финального пути
// Новый формат: /f9825c87-4e3558f6-f9b6-405c-ad3d-d1535c49b61c/crm2/CRM_Active_Files/Documents/Project/{project_name}_{project_id}/{doc_id}__{slug}.{ext}
// Пример: /.../Project/ERV_6381_КлиентПрав_398957/{doc_id}__{slug}.{ext}
// project_name уже содержит "ERV_6381_КлиентПрав", просто добавляем к нему _project_id
const buildFinalKey = (row, doc_id) => {
const bucketPrefix = 'f9825c87-4e3558f6-f9b6-405c-ad3d-d1535c49b61c';
const basePath = 'crm2/CRM_Active_Files/Documents/Project';
// Используем название поля из формы визарда
// Приоритет: field_label (из uploads_field_labels) > field_name (из uploads_field_names) > description > group_index
// field_label должен приходить из n8n workflow, где формируется filesRows из uploads_field_labels[i]
const fieldLabel = row.field_label || row.field_name || row.description || `group-${row.group_index}`;
const slug = slugify(fieldLabel);
const ext = extOf(row.original_name || 'pdf');
// Формируем название папки: {project_name}_{project_id}
// project_name уже содержит "ERV_6381_КлиентПрав", добавляем к нему _project_id
let projectFolder = 'unknown';
if (project_name && project_id) {
projectFolder = `${project_name}_${project_id}`;
} else if (project_id) {
// Fallback: если нет project_name, используем старый формат
projectFolder = `${project_id}_Клиентправ`;
}
// Очищаем от недопустимых символов для пути
projectFolder = String(projectFolder)
.replace(/[\/\\\?\*\:\|\"<>]/g, '_')
.replace(/^\.+|\.+$/g, '')
.trim() || 'unknown';
// Формируем путь: /{bucketPrefix}/{basePath}/{project_folder}/{doc_id}__{slug}.{ext}
return `/${bucketPrefix}/${basePath}/${projectFolder}/${doc_id}__${slug}.${ext}`;
};
// Собираем renames + финальные метаданные
const renames = [];
const finalDocumentsMeta = [];
const nowIso = new Date().toISOString();
for (const row of filesRows) {
const g = Number(row.group_index) || 0;
const field_name = `uploads[${g}][0]`;
const doc_id = byField[field_name] || `grp${g}`; // фолбэк если чего-то не сошлось
const fromKey = S(row.draft_key);
const toKey = buildFinalKey(row, doc_id);
// Получаем название поля из row (field_label должен быть добавлен в ноде editfiletobd1)
const field_label = row.field_label || row.field_name || row.description || `group-${g}`;
renames.push({
from: fromKey,
to: toKey,
doc_id,
field_name,
field_label // ✅ Добавляем название поля
});
finalDocumentsMeta.push({
field_name,
field_label, // ✅ Добавляем название поля
file_id: toKey,
file_name: baseName(toKey),
original_file_name: baseName(row.original_name || toKey),
uploaded_at: nowIso
});
}
return [{
json: {
claim_id,
project_id,
renames, // план копирования/переименования на S3
payload_partial_json: { documents_meta: finalDocumentsMeta } // для финального апдейта в БД
}
}];