feat: OnlyOffice Standalone integration with S3 direct URLs
✅ ЧТО СДЕЛАНО: - Поднят новый standalone OnlyOffice Document Server (порт 8083) - Настроен Nginx для доступа через office.clientright.ru:9443 - Создан open_file_v3_standalone.php для работы с новым OnlyOffice - Реализована поддержка прямых S3 URL (bucket публичный) - Добавлен s3_proxy.php с поддержкой Range requests - Создан onlyoffice_callback.php для сохранения (базовая версия) - Файлы успешно открываются и загружаются! ⚠️ TODO (на завтра): - Доработать onlyoffice_callback.php для сохранения обратно в ОРИГИНАЛЬНЫЙ путь в S3 - Добавить Redis маппинг documentKey → S3 path - Обновить CRM JS для использования open_file_v3_standalone.php - Протестировать сохранение файлов - Удалить тестовые файлы 📊 РЕЗУЛЬТАТ: - OnlyOffice Standalone РАБОТАЕТ! ✅ - Файлы открываются напрямую из S3 ✅ - Редактор загружается БЫСТРО ✅ - Автосохранение настроено ✅ (но нужна доработка callback)
This commit is contained in:
130
crm_extensions/file_storage/nextcloud_fileid_indexer.js
Executable file
130
crm_extensions/file_storage/nextcloud_fileid_indexer.js
Executable file
@@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Nextcloud FileID Indexer
|
||||
*
|
||||
* Индексирует fileId из Nextcloud БД в Redis для быстрого доступа
|
||||
* Структура: crm:nc:fileid:{path} => fileId
|
||||
*/
|
||||
|
||||
const mysql = require('mysql2/promise');
|
||||
const Redis = require('ioredis');
|
||||
|
||||
const CONFIG = {
|
||||
nextcloud_db: {
|
||||
host: '192.168.128.3',
|
||||
user: 'nextcloud',
|
||||
password: 'nextcloud_password',
|
||||
database: 'nextcloud'
|
||||
},
|
||||
redis: {
|
||||
host: '147.45.146.17',
|
||||
port: 6379,
|
||||
password: 'CRM_Redis_Pass_2025_Secure!'
|
||||
},
|
||||
// Индексируем только файлы из этих папок
|
||||
pathPrefixes: [
|
||||
'files/crm/crm2/',
|
||||
'files/crm/erv_app/'
|
||||
],
|
||||
indexInterval: 60000 // Обновляем индекс каждую минуту
|
||||
};
|
||||
|
||||
const redis = new Redis(CONFIG.redis);
|
||||
let connection = null;
|
||||
|
||||
async function connectDB() {
|
||||
try {
|
||||
connection = await mysql.createConnection(CONFIG.nextcloud_db);
|
||||
console.log('✅ Подключились к БД Nextcloud');
|
||||
} catch (err) {
|
||||
console.error('❌ Ошибка подключения к БД:', err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
async function indexFiles() {
|
||||
try {
|
||||
console.log(`\n🔍 Индексация файлов... (${new Date().toISOString()})`);
|
||||
|
||||
let totalIndexed = 0;
|
||||
|
||||
for (const prefix of CONFIG.pathPrefixes) {
|
||||
// Получаем все файлы из этой папки
|
||||
const [rows] = await connection.execute(
|
||||
'SELECT fileid, path, name, size, mtime FROM oc_filecache WHERE path LIKE ? AND mimetype != 2',
|
||||
[prefix + '%']
|
||||
);
|
||||
|
||||
console.log(` 📁 ${prefix}: найдено ${rows.length} файлов`);
|
||||
|
||||
// Индексируем в Redis
|
||||
const pipeline = redis.pipeline();
|
||||
|
||||
for (const row of rows) {
|
||||
const key = `crm:nc:fileid:${row.path}`;
|
||||
const value = JSON.stringify({
|
||||
fileId: row.fileid,
|
||||
name: row.name,
|
||||
size: row.size,
|
||||
mtime: row.mtime
|
||||
});
|
||||
|
||||
// Храним 24 часа (обновляется каждую минуту)
|
||||
pipeline.setex(key, 86400, value);
|
||||
totalIndexed++;
|
||||
}
|
||||
|
||||
await pipeline.exec();
|
||||
}
|
||||
|
||||
console.log(`✅ Проиндексировано: ${totalIndexed} файлов`);
|
||||
|
||||
} catch (err) {
|
||||
console.error('❌ Ошибка индексации:', err.message);
|
||||
console.error(err.stack);
|
||||
}
|
||||
}
|
||||
|
||||
async function start() {
|
||||
console.log('🚀 Nextcloud FileID Indexer');
|
||||
console.log('════════════════════════════════════════════════════════════════════════════════');
|
||||
console.log(`🗄️ Nextcloud DB: ${CONFIG.nextcloud_db.host}/${CONFIG.nextcloud_db.database}`);
|
||||
console.log(`📡 Redis: ${CONFIG.redis.host}:${CONFIG.redis.port}`);
|
||||
console.log(`🔄 Интервал: ${CONFIG.indexInterval / 1000}с`);
|
||||
console.log('════════════════════════════════════════════════════════════════════════════════\n');
|
||||
|
||||
await connectDB();
|
||||
|
||||
console.log('👂 Начинаем индексацию...\n');
|
||||
|
||||
// Первая индексация
|
||||
await indexFiles();
|
||||
|
||||
// Периодическая индексация
|
||||
setInterval(indexFiles, CONFIG.indexInterval);
|
||||
}
|
||||
|
||||
// Запуск
|
||||
redis.on('connect', () => {
|
||||
console.log('✅ Подключились к Redis\n');
|
||||
start();
|
||||
});
|
||||
|
||||
redis.on('error', (err) => {
|
||||
console.error('❌ Redis ошибка:', err.message);
|
||||
});
|
||||
|
||||
process.on('SIGINT', async () => {
|
||||
console.log('\n\n⛔ Остановка индексатора...');
|
||||
if (connection) await connection.end();
|
||||
redis.disconnect();
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
process.on('SIGTERM', async () => {
|
||||
console.log('\n\n⛔ Остановка индексатора...');
|
||||
if (connection) await connection.end();
|
||||
redis.disconnect();
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user