Files
crm.clientright.ru/restore_project_373977.php
Fedor 840acca51a feat(documents): дедупликация documents_meta и исправление field_label
- Исправлен 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
2025-11-28 18:16:53 +03:00

169 lines
7.0 KiB
PHP
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.

<?php
/**
* Восстановление документов проекта 373977
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$projectId = 373977;
$s3Bucket = $config['s3']['bucket'];
$prefix = 'crm2/CRM_Active_Files/Documents/Project/ПолуляхУ_ДПООРОДСКАЯ_АКАДЕМИЯ_УРБАН_373977/';
$files = [
373981 => '8_Договора_оказание_услуг_373981.pdf',
373983 => '9_Подтверждение_оплаты_пооговору_373983.pdf',
373985 => '10_2_Скрин_личногоабинетастца_и_программа_обуч_373985.pdf',
373987 => '10_1_Скрин_личногоабинетастца_и_программа_обуч_373987.pdf',
373989 => '11_1_Подтверждение_проведения_претензионной_работы_373989.pdf',
373991 => '7_заявление_потребителя_373991.pdf',
374017 => '11_Доказательство_соблюдения_претензионного_порядк_374017.pdf',
375402 => '11.2_Претензия_в_защиту_интересов_Полулях_Ольга_1_375402.pdf',
375404 => '11.3_Доказательство_оплаты_направления_претензии_о_375404.pdf',
375406 => '11.4_Доказательствоаправления_претензии_ответчик_375406.pdf',
376051 => '0_Исковоеаявление_поелуолулях_7_стр_376051.pdf',
376054 => '6_Расчет_исковыхребований_Полулях_1_стр_376054.pdf',
376080 => '12.1_Доказательство_оплаты_направления_иска_ответч_376080.pdf',
376082 => '12.2_Доказательствоаправления_иска_ответчику_376082.pdf',
];
echo "=== ВОССТАНОВЛЕНИЕ ДОКУМЕНТОВ ПРОЕКТА {$projectId} ===\n";
echo str_repeat("=", 80) . "\n\n";
$dryRun = isset($argv[1]) && $argv[1] === '--dry-run';
if ($dryRun) {
echo "⚠️ РЕЖИМ ПРОВЕРКИ (dry-run)\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
]);
$stats = [
'total' => count($files),
'restored' => 0,
'already_exists' => 0,
'no_versions' => 0,
'failed' => 0,
];
foreach ($files as $docId => $filename) {
$key = $prefix . $filename;
echo "Документ ID: {$docId}\n";
echo " Файл: {$filename}\n";
// Проверяем, существует ли файл
if ($s3Client->doesObjectExist($s3Bucket, $key)) {
echo " ✅ Файл уже существует\n\n";
$stats['already_exists']++;
continue;
}
// Проверяем версии
try {
$versions = $s3Client->listObjectVersions([
'Bucket' => $s3Bucket,
'Prefix' => $key,
'MaxKeys' => 10,
]);
$deleteMarkers = $versions['DeleteMarkers'] ?? [];
$fileVersions = $versions['Versions'] ?? [];
if (empty($deleteMarkers) && empty($fileVersions)) {
echo " ❌ Нет версий для восстановления\n\n";
$stats['no_versions']++;
continue;
}
echo " Найдено delete markers: " . count($deleteMarkers) . "\n";
echo " Найдено версий: " . count($fileVersions) . "\n";
if (!$dryRun) {
// Удаляем все delete markers
foreach ($deleteMarkers as $marker) {
try {
$s3Client->deleteObject([
'Bucket' => $s3Bucket,
'Key' => $key,
'VersionId' => $marker['VersionId'],
]);
echo " ✅ Delete marker удален\n";
} catch (Exception $e) {
echo " ⚠️ Ошибка удаления delete marker: " . $e->getMessage() . "\n";
}
}
// Проверяем, появился ли файл после удаления delete marker
if (!$s3Client->doesObjectExist($s3Bucket, $key) && !empty($fileVersions)) {
// Копируем последнюю версию
$latestVersion = $fileVersions[0];
try {
$s3Client->copyObject([
'Bucket' => $s3Bucket,
'Key' => $key,
'CopySource' => "{$s3Bucket}/{$key}?versionId={$latestVersion['VersionId']}",
]);
echo " ✅ Файл восстановлен из версии\n";
} catch (Exception $e) {
echo " ⚠️ Ошибка копирования версии: " . $e->getMessage() . "\n";
}
} else {
echo " ✅ Файл восстановлен\n";
}
$stats['restored']++;
sleep(1);
} else {
echo " ⏸️ Будет восстановлен (dry-run)\n";
$stats['restored']++;
}
} catch (Exception $e) {
echo " ❌ Ошибка: " . $e->getMessage() . "\n";
$stats['failed']++;
}
echo "\n";
}
// Итоги
echo str_repeat("=", 80) . "\n";
echo "ИТОГИ:\n";
echo "Всего файлов: {$stats['total']}\n";
if (!$dryRun) {
echo "Восстановлено: {$stats['restored']}\n";
echo "Уже существует: {$stats['already_exists']}\n";
echo "Нет версий: {$stats['no_versions']}\n";
echo "Ошибок: {$stats['failed']}\n";
} else {
echo "Будет восстановлено: {$stats['restored']}\n";
echo "Уже существует: {$stats['already_exists']}\n";
echo "Нет версий: {$stats['no_versions']}\n";
}
echo "\n=== ГОТОВО ===\n";
} catch (Exception $e) {
echo "❌ Критическая ошибка: " . $e->getMessage() . "\n";
exit(1);
}