- Исправлен N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js: использовать uploads_field_labels[0] вместо [grp] - Создан SQL_CLAIMSAVE_FIXED_NEW_FLOW_DEDUP.sql с дедупликацией documents_meta - Создан SQL_CLEANUP_DOCUMENTS_META_DUPLICATES.sql для очистки существующих дубликатов - Создан полный уникальный индекс idx_document_texts_hash_unique на document_texts(file_hash) - Добавлен SESSION_LOG_2025-11-28_documents_dedup.md с описанием всех изменений Fixes: - field_label теперь корректно отображает 'Переписка' вместо 'group-2' - documents_meta не накапливает дубликаты при повторных сохранениях - ON CONFLICT (file_hash) теперь работает для document_texts
212 lines
9.6 KiB
PHP
212 lines
9.6 KiB
PHP
<?php
|
||
error_reporting(E_ALL);
|
||
ini_set('display_errors', 1);
|
||
|
||
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
|
||
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
|
||
|
||
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
|
||
$projectId = 384256;
|
||
$s3Bucket = $config['s3']['bucket'];
|
||
|
||
// Список недоступных документов
|
||
$missingDocs = [
|
||
['id' => 384443, 'title' => '11 Доказательство соблюдения претензионного порядк'],
|
||
['id' => 386865, 'title' => '12 Доказательство направления иска ответчику'],
|
||
['id' => 386867, 'title' => '6 Расчет иска Гафиев'],
|
||
['id' => 386869, 'title' => '0 Исковое заявление Марсель Гафиев'],
|
||
['id' => 388119, 'title' => '12.1 Доказательство оплаты направления иска ответч'],
|
||
['id' => 388121, 'title' => '12.2 Доказательство направления иска ответчику'],
|
||
['id' => 389699, 'title' => 'Ходатайство_по_делу_М-1035-2025_1_стр'],
|
||
['id' => 394973, 'title' => 'Решение ГАфиев'],
|
||
];
|
||
|
||
echo "Поиск недостающих файлов проекта $projectId в S3\n";
|
||
echo str_repeat("=", 80) . "\n\n";
|
||
|
||
try {
|
||
$s3Client = new \Aws\S3\S3Client([
|
||
'version' => 'latest',
|
||
'region' => $config['s3']['region'],
|
||
'endpoint' => $config['s3']['endpoint'],
|
||
'use_path_style_endpoint' => true,
|
||
'credentials' => [
|
||
'key' => $config['s3']['key'],
|
||
'secret' => $config['s3']['secret'],
|
||
],
|
||
'suppress_php_deprecation_warning' => true
|
||
]);
|
||
|
||
// Ищем во всех temp/ папках
|
||
echo "1. Поиск во всех temp/ папках...\n";
|
||
$tempPrefixes = [];
|
||
|
||
// Получаем список всех temp/ папок
|
||
try {
|
||
$objects = $s3Client->listObjectsV2([
|
||
'Bucket' => $s3Bucket,
|
||
'Prefix' => 'temp/',
|
||
'Delimiter' => '/',
|
||
'MaxKeys' => 1000
|
||
]);
|
||
|
||
if (isset($objects['CommonPrefixes'])) {
|
||
foreach ($objects['CommonPrefixes'] as $prefix) {
|
||
$tempPrefixes[] = $prefix['Prefix'];
|
||
}
|
||
}
|
||
} catch (\Aws\Exception\AwsException $e) {
|
||
echo " Ошибка при получении списка temp/ папок: " . $e->getMessage() . "\n";
|
||
}
|
||
|
||
echo " Найдено temp/ папок: " . count($tempPrefixes) . "\n\n";
|
||
|
||
$foundFiles = [];
|
||
|
||
// Ищем файлы по ID документов во всех temp/ папках
|
||
foreach ($missingDocs as $doc) {
|
||
$docId = $doc['id'];
|
||
echo "Поиск файла для документа $docId: {$doc['title']}\n";
|
||
|
||
$found = false;
|
||
|
||
// Ищем в каждой temp/ папке
|
||
foreach ($tempPrefixes as $tempPrefix) {
|
||
try {
|
||
$objects = $s3Client->listObjectsV2([
|
||
'Bucket' => $s3Bucket,
|
||
'Prefix' => $tempPrefix,
|
||
'MaxKeys' => 1000
|
||
]);
|
||
|
||
if (isset($objects['Contents'])) {
|
||
foreach ($objects['Contents'] as $object) {
|
||
$key = $object['Key'];
|
||
|
||
// Ищем файлы с ID документа или близкими ID
|
||
if (strpos($key, (string)$docId) !== false ||
|
||
strpos($key, (string)($docId - 1)) !== false ||
|
||
strpos($key, (string)($docId + 1)) !== false ||
|
||
strpos($key, (string)($docId - 2)) !== false ||
|
||
strpos($key, (string)($docId + 2)) !== false) {
|
||
|
||
// Проверяем доступность
|
||
try {
|
||
$headResult = $s3Client->headObject([
|
||
'Bucket' => $s3Bucket,
|
||
'Key' => $key
|
||
]);
|
||
|
||
echo " ✅ НАЙДЕН в $tempPrefix\n";
|
||
echo " Путь: $key\n";
|
||
echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n";
|
||
|
||
$foundFiles[] = [
|
||
'doc_id' => $docId,
|
||
'doc_title' => $doc['title'],
|
||
's3_key' => $key,
|
||
'size' => $headResult['ContentLength']
|
||
];
|
||
|
||
$found = true;
|
||
break 2;
|
||
} catch (\Aws\Exception\AwsException $e) {
|
||
// Пропускаем
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} catch (\Aws\Exception\AwsException $e) {
|
||
// Пропускаем ошибки
|
||
}
|
||
}
|
||
|
||
// Также ищем по ключевым словам из названия
|
||
if (!$found) {
|
||
$keywords = [];
|
||
$title = mb_strtolower($doc['title']);
|
||
|
||
// Извлекаем ключевые слова
|
||
if (strpos($title, 'доказательство') !== false) $keywords[] = 'dokazatelstvo';
|
||
if (strpos($title, 'расчет') !== false) $keywords[] = 'raschet';
|
||
if (strpos($title, 'исковое') !== false) $keywords[] = 'iskovoe';
|
||
if (strpos($title, 'ходатайство') !== false) $keywords[] = 'hodataystvo';
|
||
if (strpos($title, 'решение') !== false) $keywords[] = 'reshenie';
|
||
if (strpos($title, 'оплаты') !== false) $keywords[] = 'oplaty';
|
||
if (strpos($title, 'направления') !== false) $keywords[] = 'napravleniya';
|
||
|
||
// Ищем по ключевым словам во всех temp/ папках
|
||
foreach ($tempPrefixes as $tempPrefix) {
|
||
try {
|
||
$objects = $s3Client->listObjectsV2([
|
||
'Bucket' => $s3Bucket,
|
||
'Prefix' => $tempPrefix,
|
||
'MaxKeys' => 1000
|
||
]);
|
||
|
||
if (isset($objects['Contents'])) {
|
||
foreach ($objects['Contents'] as $object) {
|
||
$key = $object['Key'];
|
||
$keyLower = mb_strtolower($key);
|
||
|
||
foreach ($keywords as $keyword) {
|
||
if (strpos($keyLower, $keyword) !== false) {
|
||
try {
|
||
$headResult = $s3Client->headObject([
|
||
'Bucket' => $s3Bucket,
|
||
'Key' => $key
|
||
]);
|
||
|
||
echo " ✅ НАЙДЕН по ключевому слову в $tempPrefix\n";
|
||
echo " Путь: $key\n";
|
||
echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n";
|
||
|
||
$foundFiles[] = [
|
||
'doc_id' => $docId,
|
||
'doc_title' => $doc['title'],
|
||
's3_key' => $key,
|
||
'size' => $headResult['ContentLength']
|
||
];
|
||
|
||
$found = true;
|
||
break 3;
|
||
} catch (\Aws\Exception\AwsException $e) {
|
||
// Пропускаем
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} catch (\Aws\Exception\AwsException $e) {
|
||
// Пропускаем ошибки
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!$found) {
|
||
echo " ❌ Файл не найден\n";
|
||
}
|
||
echo "\n";
|
||
}
|
||
|
||
echo str_repeat("=", 80) . "\n";
|
||
echo "РЕЗУЛЬТАТЫ:\n";
|
||
echo " Найдено файлов: " . count($foundFiles) . " из " . count($missingDocs) . "\n\n";
|
||
|
||
if (!empty($foundFiles)) {
|
||
echo "НАЙДЕННЫЕ ФАЙЛЫ:\n";
|
||
foreach ($foundFiles as $file) {
|
||
echo " Документ {$file['doc_id']}: {$file['doc_title']}\n";
|
||
echo " Путь в S3: {$file['s3_key']}\n";
|
||
echo " Размер: " . number_format($file['size'] / 1024, 2) . " KB\n\n";
|
||
}
|
||
|
||
echo "💡 Эти файлы можно переместить в правильную структуру\n";
|
||
}
|
||
|
||
} catch (Exception $e) {
|
||
echo "ОШИБКА: " . $e->getMessage() . "\n";
|
||
echo "Trace: " . $e->getTraceAsString() . "\n";
|
||
}
|
||
|