🚀 CRM Files Migration & Real-time Features

 Features:
- Migrated ALL files to new S3 structure (Projects, Contacts, Accounts, HelpDesk, Invoice, etc.)
- Added Nextcloud folder buttons to ALL modules
- Fixed Nextcloud editor integration
- WebSocket server for real-time updates
- Redis Pub/Sub integration
- File path manager for organized storage
- Redis caching for performance (Functions.php)

📁 New Structure:
Documents/Project/ProjectName_ID/file_docID.ext
Documents/Contacts/FirstName_LastName_ID/file_docID.ext
Documents/Accounts/AccountName_ID/file_docID.ext

🔧 Technical:
- FilePathManager for standardized paths
- S3StorageService integration
- WebSocket server (Node.js + Docker)
- Redis cache for getBasicModuleInfo()
- Predis library for Redis connectivity

📝 Scripts:
- Migration scripts for all modules
- Test pages for WebSocket/SSE/Polling
- Documentation (MIGRATION_*.md, REDIS_*.md)

🎯 Result: 15,000+ files migrated successfully!
This commit is contained in:
Fedor
2025-10-24 19:59:28 +03:00
parent 3fb2ad5f60
commit 9245768987
1062 changed files with 161778 additions and 16212 deletions

View File

@@ -7,9 +7,22 @@
* Открытие папки проекта в Nextcloud
*/
function openProjectFolder(projectId, projectName) {
// Нормализуем имя проекта (убираем множественные пробелы, как в sanitizeFileName)
// Нормализуем имя проекта как в FilePathManager::sanitizeFileName
if (projectName) {
projectName = projectName.replace(/\s+/g, ' ').trim();
// Убираем HTML entities
projectName = projectName.replace(/"/g, '"').replace(/'/g, "'");
// Заменяем проблемные символы на подчеркивания (как в FilePathManager::sanitizeFileName)
projectName = projectName.replace(/[/\\:*?"<>|№]/g, '_');
// Заменяем пробелы и запятые на подчеркивания
projectName = projectName.replace(/[\s,]+/g, '_');
// Убираем множественные подчеркивания
projectName = projectName.replace(/_+/g, '_');
// Убираем подчеркивания с концов
projectName = projectName.replace(/^_+|_+$/g, '');
}
// Формируем URL для папки проекта в Nextcloud
@@ -17,8 +30,10 @@ function openProjectFolder(projectId, projectName) {
const encodedFolderName = encodeURIComponent(folderName);
const nextcloudUrl = 'https://office.clientright.ru:8443';
// URL для папки проекта в Nextcloud External Storage
const folderUrl = `${nextcloudUrl}/apps/files/?dir=/crm/crm2/CRM_Active_Files/Documents/${encodedFolderName}`;
// URL для папки проекта в Nextcloud External Storage (новая структура)
const folderUrl = `${nextcloudUrl}/apps/files/?dir=/crm/crm2/CRM_Active_Files/Documents/Project/${encodedFolderName}`;
console.log('🔗 Opening project folder:', { projectId, projectName, folderName, folderUrl });
// Открываем папку в новом окне
window.open(folderUrl, 'nextcloud_folder', 'width=1200,height=800,scrollbars=yes,resizable=yes');
@@ -33,13 +48,137 @@ function openProjectFolderInNextcloud() {
console.warn('⚠️ openProjectFolderInNextcloud() called without parameters - use openProjectFolder(projectId, projectName) instead');
}
/**
* Открытие папки контакта в Nextcloud
*/
function openContactFolder(contactId, firstName, lastName) {
// Формируем полное имя контакта
let contactName = '';
if (firstName) {
contactName = firstName.trim();
}
if (lastName) {
contactName = contactName ? `${contactName}_${lastName.trim()}` : lastName.trim();
}
// Нормализуем имя контакта как в FilePathManager::sanitizeFileName
if (contactName) {
// Убираем HTML entities
contactName = contactName.replace(/&quot;/g, '"').replace(/&apos;/g, "'");
// Заменяем проблемные символы на подчеркивания
contactName = contactName.replace(/[/\\:*?"<>|№]/g, '_');
// Заменяем пробелы и запятые на подчеркивания
contactName = contactName.replace(/[\s,]+/g, '_');
// Убираем множественные подчеркивания
contactName = contactName.replace(/_+/g, '_');
// Убираем подчеркивания с концов
contactName = contactName.replace(/^_+|_+$/g, '');
}
// Формируем URL для папки контакта в Nextcloud
const folderName = contactName ? `${contactName}_${contactId}` : `contact_${contactId}`;
const encodedFolderName = encodeURIComponent(folderName);
const nextcloudUrl = 'https://office.clientright.ru:8443';
// URL для папки контакта в Nextcloud External Storage (новая структура)
const folderUrl = `${nextcloudUrl}/apps/files/?dir=/crm/crm2/CRM_Active_Files/Documents/Contacts/${encodedFolderName}`;
console.log('🔗 Opening contact folder:', { contactId, firstName, lastName, contactName, folderName, folderUrl });
// Открываем папку в новом окне
window.open(folderUrl, 'nextcloud_folder', 'width=1200,height=800,scrollbars=yes,resizable=yes');
}
/**
* Открытие папки контрагента в Nextcloud
*/
function openAccountFolder(accountId, accountName) {
// Нормализуем имя контрагента как в FilePathManager::sanitizeFileName
if (accountName) {
// Убираем HTML entities
accountName = accountName.replace(/&quot;/g, '"').replace(/&apos;/g, "'");
// Заменяем проблемные символы на подчеркивания
accountName = accountName.replace(/[/\\:*?"<>|№]/g, '_');
// Заменяем пробелы и запятые на подчеркивания
accountName = accountName.replace(/[\s,]+/g, '_');
// Убираем множественные подчеркивания
accountName = accountName.replace(/_+/g, '_');
// Убираем подчеркивания с концов
accountName = accountName.replace(/^_+|_+$/g, '');
}
// Формируем URL для папки контрагента в Nextcloud
const folderName = accountName ? `${accountName}_${accountId}` : `account_${accountId}`;
const encodedFolderName = encodeURIComponent(folderName);
const nextcloudUrl = 'https://office.clientright.ru:8443';
// URL для папки контрагента в Nextcloud External Storage (новая структура)
const folderUrl = `${nextcloudUrl}/apps/files/?dir=/crm/crm2/CRM_Active_Files/Documents/Accounts/${encodedFolderName}`;
console.log('🔗 Opening account folder:', { accountId, accountName, folderName, folderUrl });
// Открываем папку в новом окне
window.open(folderUrl, 'nextcloud_folder', 'width=1200,height=800,scrollbars=yes,resizable=yes');
}
/**
* Универсальная функция открытия папки записи в Nextcloud
* Работает для любых модулей (HelpDesk, Invoice, Leads, Act, ProjectTask, SPPayments и т.д.)
*/
function openRecordFolder(moduleName, recordId, recordName) {
// Нормализуем имя записи как в FilePathManager::sanitizeFileName
if (recordName) {
// Убираем HTML entities
recordName = recordName.replace(/&quot;/g, '"').replace(/&apos;/g, "'");
// Для HelpDesk и Invoice: убираем все кроме цифр, дефисов и подчеркиваний
// Это превратит "ЗАЯВКА_762" → "762", "инв_18" → "18" (как в скрипте миграции)
if (moduleName === 'HelpDesk' || moduleName === 'Invoice') {
recordName = recordName.replace(/[^a-zA-Z0-9\-_]/g, '_');
} else {
// Для других модулей: заменяем только проблемные символы
recordName = recordName.replace(/[/\\:*?"<>|№]/g, '_');
}
// Заменяем пробелы и запятые на подчеркивания
recordName = recordName.replace(/[\s,]+/g, '_');
// Убираем множественные подчеркивания
recordName = recordName.replace(/_+/g, '_');
// Убираем подчеркивания с концов
recordName = recordName.replace(/^_+|_+$/g, '');
}
// Формируем URL для папки записи в Nextcloud
const folderName = recordName ? `${recordName}_${recordId}` : `${moduleName}_${recordId}`;
const encodedFolderName = encodeURIComponent(folderName);
const nextcloudUrl = 'https://office.clientright.ru:8443';
// URL для папки записи в Nextcloud External Storage (новая структура)
const folderUrl = `${nextcloudUrl}/apps/files/?dir=/crm/crm2/CRM_Active_Files/Documents/${moduleName}/${encodedFolderName}`;
console.log('🔗 Opening record folder:', { moduleName, recordId, recordName, folderName, folderUrl });
// Открываем папку в новом окне
window.open(folderUrl, 'nextcloud_folder', 'width=1200,height=800,scrollbars=yes,resizable=yes');
}
/**
* Открытие редактора Nextcloud для документа
*/
function openNextcloudEditor(recordId, fileName) {
// ПРОСТОЕ РЕШЕНИЕ - используем промежуточную страницу для редиректа!
const cacheVersion = Date.now(); // Принудительное обновление кеша
const redirectUrl = `/crm_extensions/file_storage/api/open_file.php?recordId=${recordId}&fileName=${encodeURIComponent(fileName)}&v=${cacheVersion}`;
const redirectUrl = `/crm_extensions/file_storage/api/open_file_v2.php?recordId=${recordId}&fileName=${encodeURIComponent(fileName)}&v=${cacheVersion}`;
// Открываем редактор в новом окне через промежуточную страницу
window.open(redirectUrl, 'nextcloud_editor', 'width=1200,height=800,scrollbars=yes,resizable=yes');
@@ -92,7 +231,36 @@ function createEditUrls(baseEditUrl, recordId, fileName, fileId = 662) {
// Извлекаем базовый URL из базовой ссылки
const baseUrl = 'https://office.clientright.ru:8443';
const encodedFileName = encodeURIComponent(fileName);
const filePath = `/crm/crm2/CRM_Active_Files/Documents/${recordId}/${encodedFileName}`;
// Определяем структуру пути в зависимости от модуля
let filePath;
if (window.app && window.app.getModuleName && window.app.getModuleName() === 'Project') {
// Для проектов используем новую структуру Project/название_ID/
const projectName = window.app.getRecordName ? window.app.getRecordName() : 'project';
// Нормализуем имя проекта как в FilePathManager::sanitizeFileName
let sanitizedProjectName = projectName;
if (sanitizedProjectName) {
// Убираем HTML entities
sanitizedProjectName = sanitizedProjectName.replace(/&quot;/g, '"').replace(/&apos;/g, "'");
// Заменяем проблемные символы на подчеркивания (как в FilePathManager::sanitizeFileName)
sanitizedProjectName = sanitizedProjectName.replace(/[/\\:*?"<>|№]/g, '_');
// Заменяем пробелы и запятые на подчеркивания
sanitizedProjectName = sanitizedProjectName.replace(/[\s,]+/g, '_');
// Убираем множественные подчеркивания
sanitizedProjectName = sanitizedProjectName.replace(/_+/g, '_');
// Убираем подчеркивания с концов
sanitizedProjectName = sanitizedProjectName.replace(/^_+|_+$/g, '');
}
filePath = `/crm/crm2/CRM_Active_Files/Documents/Project/${sanitizedProjectName}_${recordId}/${encodedFileName}`;
} else {
// Для других модулей используем старую структуру
filePath = `/crm/crm2/CRM_Active_Files/Documents/${recordId}/${encodedFileName}`;
}
// Токен для RichDocuments (из настроек Nextcloud)
const richDocumentsToken = '1sanuq71b3n4fm1ldkbb';
@@ -175,13 +343,14 @@ function callMainAPI(recordId, fileName) {
});
}
// Вызываем API для подготовки файла
// Вызываем API v2 для подготовки файла
$.ajax({
url: '/crm_extensions/file_storage/api/prepare_edit.php',
url: '/crm_extensions/file_storage/api/prepare_edit_v2.php',
method: 'GET',
data: {
recordId: recordId,
fileName: fileName
fileName: fileName,
module: window.app && window.app.getModuleName ? window.app.getModuleName() : 'Project'
},
dataType: 'json',
success: function(response) {