ваше сообщение коммита
This commit is contained in:
@@ -114,13 +114,13 @@ app.use((req, res, next) => sessionConfig.sessionMiddleware(req, res, next));
|
|||||||
|
|
||||||
// Добавим middleware для проверки сессии
|
// Добавим middleware для проверки сессии
|
||||||
app.use(async (req, res, next) => {
|
app.use(async (req, res, next) => {
|
||||||
console.log('Request cookies:', req.headers.cookie);
|
// console.log('Request cookies:', req.headers.cookie);
|
||||||
console.log('Session ID:', req.sessionID);
|
// console.log('Session ID:', req.sessionID);
|
||||||
|
|
||||||
// Проверяем сессию в базе данных
|
// Проверяем сессию в базе данных
|
||||||
if (req.sessionID) {
|
if (req.sessionID) {
|
||||||
const result = await db.getQuery()('SELECT sess FROM session WHERE sid = $1', [req.sessionID]);
|
const result = await db.getQuery()('SELECT sess FROM session WHERE sid = $1', [req.sessionID]);
|
||||||
console.log('Session from DB:', result.rows[0]?.sess);
|
// console.log('Session from DB:', result.rows[0]?.sess);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Если сессия уже есть, используем её
|
// Если сессия уже есть, используем её
|
||||||
@@ -156,7 +156,7 @@ app.use(async (req, res, next) => {
|
|||||||
await new Promise((resolve) => req.session.save(resolve));
|
await new Promise((resolve) => req.session.save(resolve));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error checking auth header:', error);
|
// console.error('Error checking auth header:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +188,7 @@ app.use(
|
|||||||
|
|
||||||
// Логирование запросов
|
// Логирование запросов
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
console.log('[APP] Глобальный лог:', req.method, req.originalUrl);
|
// console.log('[APP] Глобальный лог:', req.method, req.originalUrl);
|
||||||
logger.info(`${req.method} ${req.url}`);
|
logger.info(`${req.method} ${req.url}`);
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
@@ -224,21 +224,21 @@ const nonceStore = new Map(); // или любая другая реализац
|
|||||||
const redactedValue = '***********';
|
const redactedValue = '***********';
|
||||||
|
|
||||||
// Логируем переменные окружения для отладки
|
// Логируем переменные окружения для отладки
|
||||||
console.log('NODE_ENV:', process.env.NODE_ENV);
|
// console.log('NODE_ENV:', process.env.NODE_ENV);
|
||||||
console.log('PORT:', process.env.PORT);
|
// console.log('PORT:', process.env.PORT);
|
||||||
console.log('POSTGRES_HOST:', process.env.POSTGRES_HOST);
|
// console.log('POSTGRES_HOST:', process.env.POSTGRES_HOST);
|
||||||
console.log('POSTGRES_PORT:', process.env.POSTGRES_PORT);
|
// console.log('POSTGRES_PORT:', process.env.POSTGRES_PORT);
|
||||||
console.log('POSTGRES_DB:', process.env.POSTGRES_DB);
|
// console.log('POSTGRES_DB:', process.env.POSTGRES_DB);
|
||||||
console.log('POSTGRES_USER:', redactedValue);
|
// console.log('POSTGRES_USER:', redactedValue);
|
||||||
console.log('POSTGRES_PASSWORD:', redactedValue);
|
// console.log('POSTGRES_PASSWORD:', redactedValue);
|
||||||
console.log('TELEGRAM_BOT_TOKEN:', redactedValue);
|
// console.log('TELEGRAM_BOT_TOKEN:', redactedValue);
|
||||||
console.log('TELEGRAM_BOT_USERNAME:', process.env.TELEGRAM_BOT_USERNAME);
|
// console.log('TELEGRAM_BOT_USERNAME:', process.env.TELEGRAM_BOT_USERNAME);
|
||||||
console.log('OPENAI_API_KEY:', redactedValue);
|
// console.log('OPENAI_API_KEY:', redactedValue);
|
||||||
// console.log('SESSION_SECRET:', process.env.SESSION_SECRET); // Убираем вывод секретного ключа
|
// console.log('SESSION_SECRET:', process.env.SESSION_SECRET); // Убираем вывод секретного ключа
|
||||||
console.log('EMAIL_USER:', process.env.EMAIL_USER);
|
// console.log('EMAIL_USER:', process.env.EMAIL_USER);
|
||||||
console.log('EMAIL_PASSWORD:', redactedValue);
|
// console.log('EMAIL_PASSWORD:', redactedValue);
|
||||||
|
|
||||||
console.log('typeof errorHandler:', typeof errorHandler, errorHandler.name);
|
// console.log('typeof errorHandler:', typeof errorHandler, errorHandler.name);
|
||||||
|
|
||||||
// Добавляем обработчик ошибок последним
|
// Добавляем обработчик ошибок последним
|
||||||
app.use(errorHandler);
|
app.use(errorHandler);
|
||||||
@@ -303,7 +303,7 @@ setInterval(
|
|||||||
try {
|
try {
|
||||||
await db.getQuery('DELETE FROM session WHERE expire < NOW()');
|
await db.getQuery('DELETE FROM session WHERE expire < NOW()');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error cleaning old sessions:', error);
|
// console.error('Error cleaning old sessions:', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
15 * 60 * 1000
|
15 * 60 * 1000
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ async function initRoles() {
|
|||||||
(4, 'admin', 'Администратор с полным доступом');
|
(4, 'admin', 'Администратор с полным доступом');
|
||||||
`);
|
`);
|
||||||
|
|
||||||
console.log('Таблица roles создана и заполнена');
|
// console.log('Таблица roles создана и заполнена');
|
||||||
} else {
|
} else {
|
||||||
// Проверяем наличие ролей
|
// Проверяем наличие ролей
|
||||||
const rolesExist = await pool.query(`
|
const rolesExist = await pool.query(`
|
||||||
@@ -74,11 +74,11 @@ async function initRoles() {
|
|||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Таблица roles обновлена');
|
// console.log('Таблица roles обновлена');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при инициализации таблицы roles:', error);
|
// console.error('Ошибка при инициализации таблицы roles:', error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
* GitHub: https://github.com/HB3-ACCELERATOR
|
* GitHub: https://github.com/HB3-ACCELERATOR
|
||||||
*/
|
*/
|
||||||
|
|
||||||
console.log('[DIAG][auth.js] Файл загружен:', __filename);
|
// console.log('[DIAG][auth.js] Файл загружен:', __filename);
|
||||||
|
|
||||||
const { createError } = require('../utils/error');
|
const { createError } = require('../utils/error');
|
||||||
const authService = require('../services/auth-service');
|
const authService = require('../services/auth-service');
|
||||||
@@ -30,14 +30,14 @@ try {
|
|||||||
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
||||||
}
|
}
|
||||||
} catch (keyError) {
|
} catch (keyError) {
|
||||||
console.error('Error reading encryption key:', keyError);
|
// console.error('Error reading encryption key:', keyError);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Middleware для проверки аутентификации
|
* Middleware для проверки аутентификации
|
||||||
*/
|
*/
|
||||||
const requireAuth = async (req, res, next) => {
|
const requireAuth = async (req, res, next) => {
|
||||||
console.log('[DIAG][requireAuth] session:', req.session);
|
// console.log('[DIAG][requireAuth] session:', req.session);
|
||||||
if (!req.session || !req.session.authenticated) {
|
if (!req.session || !req.session.authenticated) {
|
||||||
return res.status(401).json({ error: 'Требуется аутентификация' });
|
return res.status(401).json({ error: 'Требуется аутентификация' });
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ async function checkRole(req, res, next) {
|
|||||||
|
|
||||||
next();
|
next();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in checkRole middleware:', error);
|
// console.error('Error in checkRole middleware:', error);
|
||||||
res.status(500).json({ error: 'Internal server error' });
|
res.status(500).json({ error: 'Internal server error' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ const { ERROR_CODES } = require('../utils/constants');
|
|||||||
* Middleware для обработки ошибок
|
* Middleware для обработки ошибок
|
||||||
*/
|
*/
|
||||||
const errorHandler = (err, req, res, next) => {
|
const errorHandler = (err, req, res, next) => {
|
||||||
console.log('errorHandler called, arguments:', arguments);
|
// console.log('errorHandler called, arguments:', arguments);
|
||||||
console.log('typeof res:', typeof res, 'isFunction:', typeof res === 'function');
|
// console.log('typeof res:', typeof res, 'isFunction:', typeof res === 'function');
|
||||||
console.error('errorHandler: err =', err);
|
// console.error('errorHandler: err =', err);
|
||||||
console.error('errorHandler: typeof err =', typeof err);
|
// console.error('errorHandler: typeof err =', typeof err);
|
||||||
console.error('errorHandler: stack =', err && err.stack);
|
// console.error('errorHandler: stack =', err && err.stack);
|
||||||
// Логируем ошибку
|
// Логируем ошибку
|
||||||
logger.error(`Error: ${err.message}`, {
|
logger.error(`Error: ${err.message}`, {
|
||||||
stack: err.stack,
|
stack: err.stack,
|
||||||
|
|||||||
@@ -146,28 +146,28 @@ router.post('/', async (req, res) => {
|
|||||||
// 4. Если это исходящее сообщение для Telegram — отправляем через бота
|
// 4. Если это исходящее сообщение для Telegram — отправляем через бота
|
||||||
if (channel === 'telegram' && direction === 'out') {
|
if (channel === 'telegram' && direction === 'out') {
|
||||||
try {
|
try {
|
||||||
console.log(`[messages.js] Попытка отправки сообщения в Telegram для user_id=${user_id}`);
|
// console.log(`[messages.js] Попытка отправки сообщения в Telegram для user_id=${user_id}`);
|
||||||
// Получаем Telegram ID пользователя
|
// Получаем Telegram ID пользователя
|
||||||
const tgIdentity = await db.getQuery()(
|
const tgIdentity = await db.getQuery()(
|
||||||
'SELECT decrypt_text(provider_id_encrypted, $3) as provider_id FROM user_identities WHERE user_id = $1 AND provider_encrypted = encrypt_text($2, $3) LIMIT 1',
|
'SELECT decrypt_text(provider_id_encrypted, $3) as provider_id FROM user_identities WHERE user_id = $1 AND provider_encrypted = encrypt_text($2, $3) LIMIT 1',
|
||||||
[user_id, 'telegram', encryptionKey]
|
[user_id, 'telegram', encryptionKey]
|
||||||
);
|
);
|
||||||
console.log(`[messages.js] Результат поиска Telegram ID:`, tgIdentity.rows);
|
// console.log(`[messages.js] Результат поиска Telegram ID:`, tgIdentity.rows);
|
||||||
if (tgIdentity.rows.length > 0) {
|
if (tgIdentity.rows.length > 0) {
|
||||||
const telegramId = tgIdentity.rows[0].provider_id;
|
const telegramId = tgIdentity.rows[0].provider_id;
|
||||||
console.log(`[messages.js] Отправка сообщения в Telegram ID: ${telegramId}, текст: ${content}`);
|
// console.log(`[messages.js] Отправка сообщения в Telegram ID: ${telegramId}, текст: ${content}`);
|
||||||
const bot = await telegramBot.getBot();
|
const bot = await telegramBot.getBot();
|
||||||
try {
|
try {
|
||||||
const sendResult = await bot.telegram.sendMessage(telegramId, content);
|
const sendResult = await bot.telegram.sendMessage(telegramId, content);
|
||||||
console.log(`[messages.js] Результат отправки в Telegram:`, sendResult);
|
// console.log(`[messages.js] Результат отправки в Telegram:`, sendResult);
|
||||||
} catch (sendErr) {
|
} catch (sendErr) {
|
||||||
console.error(`[messages.js] Ошибка при отправке в Telegram:`, sendErr);
|
// console.error(`[messages.js] Ошибка при отправке в Telegram:`, sendErr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.warn(`[messages.js] Не найден Telegram ID для user_id=${user_id}`);
|
// console.warn(`[messages.js] Не найден Telegram ID для user_id=${user_id}`);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('[messages.js] Ошибка отправки сообщения в Telegram:', err);
|
// console.error('[messages.js] Ошибка отправки сообщения в Telegram:', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 5. Если это исходящее сообщение для Email — отправляем email
|
// 5. Если это исходящее сообщение для Email — отправляем email
|
||||||
@@ -183,7 +183,7 @@ router.post('/', async (req, res) => {
|
|||||||
await emailBot.sendEmail(email, 'Новое сообщение', content);
|
await emailBot.sendEmail(email, 'Новое сообщение', content);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('[messages.js] Ошибка отправки email:', err);
|
// console.error('[messages.js] Ошибка отправки email:', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
broadcastMessagesUpdate();
|
broadcastMessagesUpdate();
|
||||||
@@ -196,16 +196,16 @@ router.post('/', async (req, res) => {
|
|||||||
// POST /api/messages/mark-read
|
// POST /api/messages/mark-read
|
||||||
router.post('/mark-read', async (req, res) => {
|
router.post('/mark-read', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
console.log('[DEBUG] /mark-read req.user:', req.user);
|
// console.log('[DEBUG] /mark-read req.user:', req.user);
|
||||||
console.log('[DEBUG] /mark-read req.body:', req.body);
|
// console.log('[DEBUG] /mark-read req.body:', req.body);
|
||||||
const adminId = req.user && req.user.id;
|
const adminId = req.user && req.user.id;
|
||||||
const { userId, lastReadAt } = req.body;
|
const { userId, lastReadAt } = req.body;
|
||||||
if (!adminId) {
|
if (!adminId) {
|
||||||
console.error('[ERROR] /mark-read: adminId (req.user.id) is missing');
|
// console.error('[ERROR] /mark-read: adminId (req.user.id) is missing');
|
||||||
return res.status(401).json({ error: 'Unauthorized: adminId missing' });
|
return res.status(401).json({ error: 'Unauthorized: adminId missing' });
|
||||||
}
|
}
|
||||||
if (!userId || !lastReadAt) {
|
if (!userId || !lastReadAt) {
|
||||||
console.error('[ERROR] /mark-read: userId or lastReadAt missing');
|
// console.error('[ERROR] /mark-read: userId or lastReadAt missing');
|
||||||
return res.status(400).json({ error: 'userId and lastReadAt required' });
|
return res.status(400).json({ error: 'userId and lastReadAt required' });
|
||||||
}
|
}
|
||||||
await db.query(`
|
await db.query(`
|
||||||
@@ -215,7 +215,7 @@ router.post('/mark-read', async (req, res) => {
|
|||||||
`, [adminId, userId, lastReadAt]);
|
`, [adminId, userId, lastReadAt]);
|
||||||
res.json({ success: true });
|
res.json({ success: true });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[ERROR] /mark-read:', e);
|
// console.error('[ERROR] /mark-read:', e);
|
||||||
res.status(500).json({ error: e.message });
|
res.status(500).json({ error: e.message });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -223,23 +223,23 @@ router.post('/mark-read', async (req, res) => {
|
|||||||
// GET /api/messages/read-status
|
// GET /api/messages/read-status
|
||||||
router.get('/read-status', async (req, res) => {
|
router.get('/read-status', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
console.log('[DEBUG] /read-status req.user:', req.user);
|
// console.log('[DEBUG] /read-status req.user:', req.user);
|
||||||
console.log('[DEBUG] /read-status req.session:', req.session);
|
// console.log('[DEBUG] /read-status req.session:', req.session);
|
||||||
console.log('[DEBUG] /read-status req.session.userId:', req.session && req.session.userId);
|
// console.log('[DEBUG] /read-status req.session.userId:', req.session && req.session.userId);
|
||||||
const adminId = req.user && req.user.id;
|
const adminId = req.user && req.user.id;
|
||||||
if (!adminId) {
|
if (!adminId) {
|
||||||
console.error('[ERROR] /read-status: adminId (req.user.id) is missing');
|
// console.error('[ERROR] /read-status: adminId (req.user.id) is missing');
|
||||||
return res.status(401).json({ error: 'Unauthorized: adminId missing' });
|
return res.status(401).json({ error: 'Unauthorized: adminId missing' });
|
||||||
}
|
}
|
||||||
const result = await db.query('SELECT user_id, last_read_at FROM admin_read_messages WHERE admin_id = $1', [adminId]);
|
const result = await db.query('SELECT user_id, last_read_at FROM admin_read_messages WHERE admin_id = $1', [adminId]);
|
||||||
console.log('[DEBUG] /read-status SQL result:', result.rows);
|
// console.log('[DEBUG] /read-status SQL result:', result.rows);
|
||||||
const map = {};
|
const map = {};
|
||||||
for (const row of result.rows) {
|
for (const row of result.rows) {
|
||||||
map[row.user_id] = row.last_read_at;
|
map[row.user_id] = row.last_read_at;
|
||||||
}
|
}
|
||||||
res.json(map);
|
res.json(map);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[ERROR] /read-status:', e);
|
// console.error('[ERROR] /read-status:', e);
|
||||||
res.status(500).json({ error: e.message });
|
res.status(500).json({ error: e.message });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
* GitHub: https://github.com/HB3-ACCELERATOR
|
* GitHub: https://github.com/HB3-ACCELERATOR
|
||||||
*/
|
*/
|
||||||
|
|
||||||
console.log('[DIAG][tables.js] Файл загружен:', __filename);
|
// console.log('[DIAG][tables.js] Файл загружен:', __filename);
|
||||||
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
@@ -32,7 +32,7 @@ function getEncryptionKey() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
router.use((req, res, next) => {
|
router.use((req, res, next) => {
|
||||||
console.log('Tables router received:', req.method, req.originalUrl);
|
// console.log('Tables router received:', req.method, req.originalUrl);
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ router.get('/', async (req, res, next) => {
|
|||||||
try {
|
try {
|
||||||
encryptionKey = getEncryptionKey();
|
encryptionKey = getEncryptionKey();
|
||||||
} catch (keyError) {
|
} catch (keyError) {
|
||||||
console.error('Error reading encryption key:', keyError);
|
// console.error('Error reading encryption key:', keyError);
|
||||||
return res.status(500).json({ error: 'Database encryption error' });
|
return res.status(500).json({ error: 'Database encryption error' });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ router.post('/', async (req, res, next) => {
|
|||||||
try {
|
try {
|
||||||
encryptionKey = getEncryptionKey();
|
encryptionKey = getEncryptionKey();
|
||||||
} catch (keyError) {
|
} catch (keyError) {
|
||||||
console.error('Error reading encryption key:', keyError);
|
// console.error('Error reading encryption key:', keyError);
|
||||||
return res.status(500).json({ error: 'Database encryption error' });
|
return res.status(500).json({ error: 'Database encryption error' });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ router.get('/rag-sources', async (req, res, next) => {
|
|||||||
|
|
||||||
res.json(result.rows);
|
res.json(result.rows);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('[RAG Sources] Error:', err);
|
// console.error('[RAG Sources] Error:', err);
|
||||||
next(err);
|
next(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -236,7 +236,7 @@ router.post('/:id/rows', async (req, res, next) => {
|
|||||||
'INSERT INTO user_rows (table_id) VALUES ($1) RETURNING *',
|
'INSERT INTO user_rows (table_id) VALUES ($1) RETURNING *',
|
||||||
[tableId]
|
[tableId]
|
||||||
);
|
);
|
||||||
console.log('[DEBUG][addRow] result.rows[0]:', result.rows[0]);
|
// console.log('[DEBUG][addRow] result.rows[0]:', result.rows[0]);
|
||||||
// Получаем ключ шифрования
|
// Получаем ключ шифрования
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
@@ -260,11 +260,11 @@ router.post('/:id/rows', async (req, res, next) => {
|
|||||||
// Получаем все строки и значения для upsert
|
// Получаем все строки и значения для upsert
|
||||||
const rows = (await db.getQuery()('SELECT r.id as row_id, decrypt_text(c.value_encrypted, $2) as text, decrypt_text(c2.value_encrypted, $2) as answer FROM user_rows r LEFT JOIN user_cell_values c ON c.row_id = r.id AND c.column_id = 1 LEFT JOIN user_cell_values c2 ON c2.row_id = r.id AND c2.column_id = 2 WHERE r.table_id = $1', [tableId, encryptionKey])).rows;
|
const rows = (await db.getQuery()('SELECT r.id as row_id, decrypt_text(c.value_encrypted, $2) as text, decrypt_text(c2.value_encrypted, $2) as answer FROM user_rows r LEFT JOIN user_cell_values c ON c.row_id = r.id AND c.column_id = 1 LEFT JOIN user_cell_values c2 ON c2.row_id = r.id AND c2.column_id = 2 WHERE r.table_id = $1', [tableId, encryptionKey])).rows;
|
||||||
const upsertRows = rows.filter(r => r.row_id && r.text).map(r => ({ row_id: r.row_id, text: r.text, metadata: { answer: r.answer } }));
|
const upsertRows = rows.filter(r => r.row_id && r.text).map(r => ({ row_id: r.row_id, text: r.text, metadata: { answer: r.answer } }));
|
||||||
console.log('[DEBUG][upsertRows]', upsertRows);
|
// console.log('[DEBUG][upsertRows]', upsertRows);
|
||||||
if (upsertRows.length > 0) {
|
if (upsertRows.length > 0) {
|
||||||
await vectorSearchClient.upsert(tableId, upsertRows);
|
await vectorSearchClient.upsert(tableId, upsertRows);
|
||||||
}
|
}
|
||||||
console.log('[DEBUG][addRow] res.json:', result.rows[0]);
|
// console.log('[DEBUG][addRow] res.json:', result.rows[0]);
|
||||||
res.json(result.rows[0]);
|
res.json(result.rows[0]);
|
||||||
broadcastTableUpdate(tableId);
|
broadcastTableUpdate(tableId);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ const db = require('../db');
|
|||||||
const { requireAuth } = require('../middleware/auth');
|
const { requireAuth } = require('../middleware/auth');
|
||||||
const { broadcastTagsUpdate } = require('../wsHub');
|
const { broadcastTagsUpdate } = require('../wsHub');
|
||||||
|
|
||||||
console.log('[tags.js] ROUTER LOADED');
|
// console.log('[tags.js] ROUTER LOADED');
|
||||||
|
|
||||||
router.use((req, res, next) => {
|
router.use((req, res, next) => {
|
||||||
console.log('[tags.js] ROUTER REQUEST:', req.method, req.originalUrl);
|
// console.log('[tags.js] ROUTER REQUEST:', req.method, req.originalUrl);
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -100,15 +100,15 @@ router.post('/user/:rowId/multirelations', async (req, res) => {
|
|||||||
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
||||||
}
|
}
|
||||||
} catch (keyError) {
|
} catch (keyError) {
|
||||||
console.error('Error reading encryption key:', keyError);
|
// console.error('Error reading encryption key:', keyError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Проверяем, является ли это обновлением тегов (проверяем связанную таблицу)
|
// Проверяем, является ли это обновлением тегов (проверяем связанную таблицу)
|
||||||
const relatedTableName = (await db.getQuery()('SELECT decrypt_text(name_encrypted, $2) as name FROM user_tables WHERE id = $1', [to_table_id, encryptionKey])).rows[0];
|
const relatedTableName = (await db.getQuery()('SELECT decrypt_text(name_encrypted, $2) as name FROM user_tables WHERE id = $1', [to_table_id, encryptionKey])).rows[0];
|
||||||
console.log('🔄 [Tags] Multirelations: проверяем связанную таблицу:', { to_table_id, tableName: relatedTableName?.name });
|
// console.log('🔄 [Tags] Multirelations: проверяем связанную таблицу:', { to_table_id, tableName: relatedTableName?.name });
|
||||||
|
|
||||||
if (relatedTableName && relatedTableName.name === 'Теги клиентов') {
|
if (relatedTableName && relatedTableName.name === 'Теги клиентов') {
|
||||||
console.log('🔄 [Tags] Multirelations: обновление тегов для строки:', rowId);
|
// console.log('🔄 [Tags] Multirelations: обновление тегов для строки:', rowId);
|
||||||
|
|
||||||
// Удаляем старые связи для этой строки/столбца
|
// Удаляем старые связи для этой строки/столбца
|
||||||
await db.getQuery()('DELETE FROM user_table_relations WHERE from_row_id = $1 AND column_id = $2', [rowId, column_id]);
|
await db.getQuery()('DELETE FROM user_table_relations WHERE from_row_id = $1 AND column_id = $2', [rowId, column_id]);
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ const { deleteUserById } = require('../services/userDeleteService');
|
|||||||
const { broadcastContactsUpdate } = require('../wsHub');
|
const { broadcastContactsUpdate } = require('../wsHub');
|
||||||
// const userService = require('../services/userService');
|
// const userService = require('../services/userService');
|
||||||
|
|
||||||
console.log('[users.js] ROUTER LOADED');
|
// console.log('[users.js] ROUTER LOADED');
|
||||||
|
|
||||||
router.use((req, res, next) => {
|
router.use((req, res, next) => {
|
||||||
console.log('[users.js] ROUTER REQUEST:', req.method, req.originalUrl);
|
// console.log('[users.js] ROUTER REQUEST:', req.method, req.originalUrl);
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ router.get('/profile', requireAuth, async (req, res) => {
|
|||||||
}
|
}
|
||||||
res.json({ success: true, user });
|
res.json({ success: true, user });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error getting user profile:', error);
|
// console.error('Error getting user profile:', error);
|
||||||
res.status(500).json({ success: false, message: 'Internal server error' });
|
res.status(500).json({ success: false, message: 'Internal server error' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -57,7 +57,7 @@ router.put('/profile', requireAuth, async (req, res) => {
|
|||||||
const updatedUser = await userService.updateUserProfile(userId, profileData);
|
const updatedUser = await userService.updateUserProfile(userId, profileData);
|
||||||
res.json({ success: true, user: updatedUser, message: 'Profile updated successfully' });
|
res.json({ success: true, user: updatedUser, message: 'Profile updated successfully' });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error updating user profile:', error);
|
// console.error('Error updating user profile:', error);
|
||||||
// Можно добавить более специфичную обработку ошибок, например, если данные невалидны
|
// Можно добавить более специфичную обработку ошибок, например, если данные невалидны
|
||||||
res.status(500).json({ success: false, message: 'Internal server error' });
|
res.status(500).json({ success: false, message: 'Internal server error' });
|
||||||
}
|
}
|
||||||
@@ -382,19 +382,19 @@ router.patch('/:id', requireAuth, async (req, res) => {
|
|||||||
|
|
||||||
// DELETE /api/users/:id — удалить контакт и все связанные данные
|
// DELETE /api/users/:id — удалить контакт и все связанные данные
|
||||||
router.delete('/:id', requireAuth, async (req, res) => {
|
router.delete('/:id', requireAuth, async (req, res) => {
|
||||||
console.log('[users.js] DELETE HANDLER', req.params.id);
|
// console.log('[users.js] DELETE HANDLER', req.params.id);
|
||||||
const userId = Number(req.params.id);
|
const userId = Number(req.params.id);
|
||||||
console.log('[ROUTER] Перед вызовом deleteUserById для userId:', userId);
|
// console.log('[ROUTER] Перед вызовом deleteUserById для userId:', userId);
|
||||||
try {
|
try {
|
||||||
const deletedCount = await deleteUserById(userId);
|
const deletedCount = await deleteUserById(userId);
|
||||||
console.log('[ROUTER] deleteUserById вернул:', deletedCount);
|
// console.log('[ROUTER] deleteUserById вернул:', deletedCount);
|
||||||
if (deletedCount === 0) {
|
if (deletedCount === 0) {
|
||||||
return res.status(404).json({ success: false, deleted: 0, error: 'User not found' });
|
return res.status(404).json({ success: false, deleted: 0, error: 'User not found' });
|
||||||
}
|
}
|
||||||
broadcastContactsUpdate();
|
broadcastContactsUpdate();
|
||||||
res.json({ success: true, deleted: deletedCount });
|
res.json({ success: true, deleted: deletedCount });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[DELETE] Ошибка при удалении пользователя:', e);
|
// console.error('[DELETE] Ошибка при удалении пользователя:', e);
|
||||||
res.status(500).json({ error: 'DB error', details: e.message });
|
res.status(500).json({ error: 'DB error', details: e.message });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ const requiredDependencies = ['express-rate-limit', 'winston', 'helmet', 'csurf'
|
|||||||
const missingDependencies = requiredDependencies.filter((dep) => !dependencies[dep]);
|
const missingDependencies = requiredDependencies.filter((dep) => !dependencies[dep]);
|
||||||
|
|
||||||
if (missingDependencies.length > 0) {
|
if (missingDependencies.length > 0) {
|
||||||
console.error('Missing dependencies:', missingDependencies);
|
// console.error('Missing dependencies:', missingDependencies);
|
||||||
console.error('Please install them with: yarn add ' + missingDependencies.join(' '));
|
// console.error('Please install them with: yarn add ' + missingDependencies.join(' '));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('All required dependencies are installed.');
|
// console.log('All required dependencies are installed.');
|
||||||
|
|||||||
@@ -15,19 +15,19 @@ const db = require('../db');
|
|||||||
|
|
||||||
async function cleanupSessions() {
|
async function cleanupSessions() {
|
||||||
try {
|
try {
|
||||||
console.log('Starting session cleanup...');
|
// console.log('Starting session cleanup...');
|
||||||
|
|
||||||
const result = await sessionService.cleanupProcessedGuestIds();
|
const result = await sessionService.cleanupProcessedGuestIds();
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
console.log('Session cleanup completed successfully');
|
// console.log('Session cleanup completed successfully');
|
||||||
} else {
|
} else {
|
||||||
console.log('Session cleanup failed');
|
// console.log('Session cleanup failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error during cleanup:', error);
|
// console.error('Error during cleanup:', error);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ process.env.OLLAMA_MODEL = 'qwen2.5:7b';
|
|||||||
const aiQueueService = require('../services/ai-queue');
|
const aiQueueService = require('../services/ai-queue');
|
||||||
|
|
||||||
async function testQueueInDocker() {
|
async function testQueueInDocker() {
|
||||||
console.log('🐳 Тестирование AI очереди в Docker...\n');
|
// console.log('🐳 Тестирование AI очереди в Docker...\n');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Проверяем инициализацию
|
// Проверяем инициализацию
|
||||||
console.log('1. Проверка инициализации очереди...');
|
// console.log('1. Проверка инициализации очереди...');
|
||||||
const stats = aiQueueService.getStats();
|
const stats = aiQueueService.getStats();
|
||||||
console.log('✅ Очередь инициализирована:', stats.isInitialized);
|
// console.log('✅ Очередь инициализирована:', stats.isInitialized);
|
||||||
console.log('📊 Статистика:', {
|
// console.log('📊 Статистика:', {
|
||||||
totalProcessed: stats.totalProcessed,
|
totalProcessed: stats.totalProcessed,
|
||||||
totalFailed: stats.totalFailed,
|
totalFailed: stats.totalFailed,
|
||||||
currentQueueSize: stats.currentQueueSize,
|
currentQueueSize: stats.currentQueueSize,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const OLLAMA_URL = process.env.OLLAMA_URL || 'http://ollama:11434';
|
|||||||
const MODEL_NAME = process.env.OLLAMA_MODEL || 'qwen2.5:7b';
|
const MODEL_NAME = process.env.OLLAMA_MODEL || 'qwen2.5:7b';
|
||||||
|
|
||||||
async function warmupModel() {
|
async function warmupModel() {
|
||||||
console.log('🔥 Разогрев модели Ollama...');
|
// console.log('🔥 Разогрев модели Ollama...');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Проверяем доступность Ollama
|
// Проверяем доступность Ollama
|
||||||
@@ -20,7 +20,7 @@ async function warmupModel() {
|
|||||||
throw new Error(`Ollama недоступен: ${healthResponse.status}`);
|
throw new Error(`Ollama недоступен: ${healthResponse.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('✅ Ollama доступен');
|
// console.log('✅ Ollama доступен');
|
||||||
|
|
||||||
// Отправляем простой запрос для разогрева
|
// Отправляем простой запрос для разогрева
|
||||||
const warmupResponse = await fetch(`${OLLAMA_URL}/v1/chat/completions`, {
|
const warmupResponse = await fetch(`${OLLAMA_URL}/v1/chat/completions`, {
|
||||||
@@ -54,11 +54,11 @@ async function warmupModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await warmupResponse.json();
|
const data = await warmupResponse.json();
|
||||||
console.log('✅ Модель разогрета успешно');
|
// console.log('✅ Модель разогрета успешно');
|
||||||
console.log(`📝 Ответ модели: ${data.choices?.[0]?.message?.content?.substring(0, 100)}...`);
|
// console.log(`📝 Ответ модели: ${data.choices?.[0]?.message?.content?.substring(0, 100)}...`);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Ошибка разогрева модели:', error.message);
|
// console.error('❌ Ошибка разогрева модели:', error.message);
|
||||||
// Не прерываем запуск приложения
|
// Не прерываем запуск приложения
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,41 +22,41 @@ const { warmupModel } = require('./scripts/warmup-model'); // Добавляем
|
|||||||
|
|
||||||
const PORT = process.env.PORT || 8000;
|
const PORT = process.env.PORT || 8000;
|
||||||
|
|
||||||
console.log('Начало выполнения server.js');
|
// console.log('Начало выполнения server.js');
|
||||||
console.log('Переменная окружения PORT:', process.env.PORT);
|
// console.log('Переменная окружения PORT:', process.env.PORT);
|
||||||
console.log('Используемый порт:', process.env.PORT || 8000);
|
// console.log('Используемый порт:', process.env.PORT || 8000);
|
||||||
|
|
||||||
// Инициализация сервисов
|
// Инициализация сервисов
|
||||||
async function initServices() {
|
async function initServices() {
|
||||||
try {
|
try {
|
||||||
console.log('Инициализация сервисов...');
|
// console.log('Инициализация сервисов...');
|
||||||
console.log('[initServices] Запуск Email-бота...');
|
// console.log('[initServices] Запуск Email-бота...');
|
||||||
console.log('[initServices] Создаю экземпляр EmailBotService...');
|
// console.log('[initServices] Создаю экземпляр EmailBotService...');
|
||||||
let emailBot;
|
let emailBot;
|
||||||
try {
|
try {
|
||||||
emailBot = new EmailBotService();
|
emailBot = new EmailBotService();
|
||||||
console.log('[initServices] Экземпляр EmailBotService создан');
|
// console.log('[initServices] Экземпляр EmailBotService создан');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('[initServices] Ошибка при создании экземпляра EmailBotService:', err);
|
// console.error('[initServices] Ошибка при создании экземпляра EmailBotService:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
console.log('[initServices] Перед вызовом emailBot.start()');
|
// console.log('[initServices] Перед вызовом emailBot.start()');
|
||||||
try {
|
try {
|
||||||
await emailBot.start();
|
await emailBot.start();
|
||||||
console.log('[initServices] Email-бот успешно запущен');
|
// console.log('[initServices] Email-бот успешно запущен');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('[initServices] Ошибка при запуске emailBot:', err);
|
// console.error('[initServices] Ошибка при запуске emailBot:', err);
|
||||||
}
|
}
|
||||||
console.log('[initServices] Запуск Telegram-бота...');
|
// console.log('[initServices] Запуск Telegram-бота...');
|
||||||
try {
|
try {
|
||||||
await getBot();
|
await getBot();
|
||||||
console.log('[initServices] Telegram-бот успешно запущен');
|
// console.log('[initServices] Telegram-бот успешно запущен');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('[initServices] Ошибка при запуске Telegram-бота:', err);
|
// console.error('[initServices] Ошибка при запуске Telegram-бота:', err);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// console.error('Ошибка при инициализации сервисов:', error);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error('Ошибка при инициализации сервисов:', error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
@@ -67,22 +67,22 @@ async function startServer() {
|
|||||||
await seedAIAssistantSettings(); // Инициализация ассистента после загрузки модели Ollama
|
await seedAIAssistantSettings(); // Инициализация ассистента после загрузки модели Ollama
|
||||||
|
|
||||||
// Разогрев модели Ollama
|
// Разогрев модели Ollama
|
||||||
console.log('🔥 Запуск разогрева модели...');
|
// console.log('🔥 Запуск разогрева модели...');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
warmupModel().catch(err => {
|
warmupModel().catch(err => {
|
||||||
console.error('❌ Ошибка разогрева модели:', err.message);
|
// console.error('❌ Ошибка разогрева модели:', err.message);
|
||||||
});
|
});
|
||||||
}, 10000); // Задержка 10 секунд для полной инициализации
|
}, 10000); // Задержка 10 секунд для полной инициализации
|
||||||
|
|
||||||
await initServices(); // Только теперь запускать сервисы
|
await initServices(); // Только теперь запускать сервисы
|
||||||
console.log(`Server is running on port ${PORT}`);
|
// console.log(`Server is running on port ${PORT}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
server.listen(PORT, async () => {
|
server.listen(PORT, async () => {
|
||||||
try {
|
try {
|
||||||
await startServer();
|
await startServer();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error starting server:', error);
|
// console.error('Error starting server:', error);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ async function checkAdminRole(address) {
|
|||||||
if (fs.existsSync(keyPath)) {
|
if (fs.existsSync(keyPath)) {
|
||||||
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
||||||
}
|
}
|
||||||
} catch (keyError) {
|
} catch (keyError) {
|
||||||
console.error('Error reading encryption key:', keyError);
|
// console.error('Error reading encryption key:', keyError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Получаем токены и RPC из базы с расшифровкой
|
// Получаем токены и RPC из базы с расшифровкой
|
||||||
const tokensResult = await db.getQuery()(
|
const tokensResult = await db.getQuery()(
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
* GitHub: https://github.com/HB3-ACCELERATOR
|
* GitHub: https://github.com/HB3-ACCELERATOR
|
||||||
*/
|
*/
|
||||||
|
|
||||||
console.log('[ai-assistant] loaded');
|
// console.log('[ai-assistant] loaded');
|
||||||
|
|
||||||
const { ChatOllama } = require('@langchain/ollama');
|
const { ChatOllama } = require('@langchain/ollama');
|
||||||
const { HNSWLib } = require('@langchain/community/vectorstores/hnswlib');
|
const { HNSWLib } = require('@langchain/community/vectorstores/hnswlib');
|
||||||
@@ -51,7 +51,7 @@ class AIAssistant {
|
|||||||
this.isModelLoaded = false;
|
this.isModelLoaded = false;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Model health check failed:', error);
|
// console.error('Model health check failed:', error);
|
||||||
this.isModelLoaded = false;
|
this.isModelLoaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ class AIAssistant {
|
|||||||
// Основной метод для получения ответа
|
// Основной метод для получения ответа
|
||||||
async getResponse(message, language = 'auto', history = null, systemPrompt = '', rules = null) {
|
async getResponse(message, language = 'auto', history = null, systemPrompt = '', rules = null) {
|
||||||
try {
|
try {
|
||||||
console.log('getResponse called with:', { message, language, history, systemPrompt, rules });
|
// console.log('getResponse called with:', { message, language, history, systemPrompt, rules });
|
||||||
|
|
||||||
// Очищаем старый кэш
|
// Очищаем старый кэш
|
||||||
this.cleanupCache();
|
this.cleanupCache();
|
||||||
@@ -150,7 +150,7 @@ class AIAssistant {
|
|||||||
// Проверяем здоровье модели
|
// Проверяем здоровье модели
|
||||||
const isHealthy = await this.checkModelHealth();
|
const isHealthy = await this.checkModelHealth();
|
||||||
if (!isHealthy) {
|
if (!isHealthy) {
|
||||||
console.warn('Model is not healthy, returning fallback response');
|
// console.warn('Model is not healthy, returning fallback response');
|
||||||
return 'Извините, модель временно недоступна. Пожалуйста, попробуйте позже.';
|
return 'Извините, модель временно недоступна. Пожалуйста, попробуйте позже.';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +161,7 @@ class AIAssistant {
|
|||||||
});
|
});
|
||||||
const cachedResponse = aiCache.get(cacheKey);
|
const cachedResponse = aiCache.get(cacheKey);
|
||||||
if (cachedResponse) {
|
if (cachedResponse) {
|
||||||
console.log('Returning cached response');
|
// console.log('Returning cached response');
|
||||||
return cachedResponse;
|
return cachedResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@ class AIAssistant {
|
|||||||
|
|
||||||
// Определяем язык, если не указан явно
|
// Определяем язык, если не указан явно
|
||||||
const detectedLanguage = language === 'auto' ? this.detectLanguage(message) : language;
|
const detectedLanguage = language === 'auto' ? this.detectLanguage(message) : language;
|
||||||
console.log('Detected language:', detectedLanguage);
|
// console.log('Detected language:', detectedLanguage);
|
||||||
|
|
||||||
// Формируем system prompt с учётом правил
|
// Формируем system prompt с учётом правил
|
||||||
let fullSystemPrompt = systemPrompt || '';
|
let fullSystemPrompt = systemPrompt || '';
|
||||||
@@ -234,22 +234,22 @@ class AIAssistant {
|
|||||||
|
|
||||||
// Пробуем прямой API запрос (OpenAI-совместимый endpoint)
|
// Пробуем прямой API запрос (OpenAI-совместимый endpoint)
|
||||||
try {
|
try {
|
||||||
console.log('Trying direct API request...');
|
// console.log('Trying direct API request...');
|
||||||
response = await this.fallbackRequestOpenAI(messages, detectedLanguage, fullSystemPrompt);
|
response = await this.fallbackRequestOpenAI(messages, detectedLanguage, fullSystemPrompt);
|
||||||
console.log('Direct API response received:', response);
|
// console.log('Direct API response received:', response);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in direct API request:', error);
|
// console.error('Error in direct API request:', error);
|
||||||
|
|
||||||
// Если прямой запрос не удался, пробуем через ChatOllama (склеиваем сообщения в текст)
|
// Если прямой запрос не удался, пробуем через ChatOllama (склеиваем сообщения в текст)
|
||||||
const chat = this.createChat(detectedLanguage, fullSystemPrompt);
|
const chat = this.createChat(detectedLanguage, fullSystemPrompt);
|
||||||
try {
|
try {
|
||||||
const prompt = messages.map(m => `${m.role === 'user' ? 'Пользователь' : m.role === 'assistant' ? 'Ассистент' : 'Система'}: ${m.content}`).join('\n');
|
const prompt = messages.map(m => `${m.role === 'user' ? 'Пользователь' : m.role === 'assistant' ? 'Ассистент' : 'Система'}: ${m.content}`).join('\n');
|
||||||
console.log('Sending request to ChatOllama...');
|
// console.log('Sending request to ChatOllama...');
|
||||||
const chatResponse = await chat.invoke(prompt);
|
const chatResponse = await chat.invoke(prompt);
|
||||||
console.log('ChatOllama response:', chatResponse);
|
// console.log('ChatOllama response:', chatResponse);
|
||||||
response = chatResponse.content;
|
response = chatResponse.content;
|
||||||
} catch (chatError) {
|
} catch (chatError) {
|
||||||
console.error('Error using ChatOllama:', chatError);
|
// console.error('Error using ChatOllama:', chatError);
|
||||||
throw chatError;
|
throw chatError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,7 +261,7 @@ class AIAssistant {
|
|||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in getResponse:', error);
|
// console.error('Error in getResponse:', error);
|
||||||
return 'Извините, я не смог обработать ваш запрос. Пожалуйста, попробуйте позже.';
|
return 'Извините, я не смог обработать ваш запрос. Пожалуйста, попробуйте позже.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,7 +269,7 @@ class AIAssistant {
|
|||||||
// Новый метод для OpenAI/Qwen2.5 совместимого endpoint
|
// Новый метод для OpenAI/Qwen2.5 совместимого endpoint
|
||||||
async fallbackRequestOpenAI(messages, language, systemPrompt = '') {
|
async fallbackRequestOpenAI(messages, language, systemPrompt = '') {
|
||||||
try {
|
try {
|
||||||
console.log('Using fallbackRequestOpenAI with:', { messages, language, systemPrompt });
|
// console.log('Using fallbackRequestOpenAI with:', { messages, language, systemPrompt });
|
||||||
const model = this.defaultModel;
|
const model = this.defaultModel;
|
||||||
|
|
||||||
// Создаем AbortController для таймаута
|
// Создаем AbortController для таймаута
|
||||||
@@ -315,7 +315,7 @@ class AIAssistant {
|
|||||||
}
|
}
|
||||||
return data.response || '';
|
return data.response || '';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in fallbackRequestOpenAI:', error);
|
// console.error('Error in fallbackRequestOpenAI:', error);
|
||||||
if (error.name === 'AbortError') {
|
if (error.name === 'AbortError') {
|
||||||
throw new Error('Request timeout - модель не ответила в течение 120 секунд');
|
throw new Error('Request timeout - модель не ответила в течение 120 секунд');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ async function getSettings() {
|
|||||||
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
||||||
}
|
}
|
||||||
} catch (keyError) {
|
} catch (keyError) {
|
||||||
console.error('Error reading encryption key:', keyError);
|
// console.error('Error reading encryption key:', keyError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Получаем связанные данные из telegram_settings и email_settings
|
// Получаем связанные данные из telegram_settings и email_settings
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ async function getAllLLMModels() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ollamaError) {
|
} catch (ollamaError) {
|
||||||
console.error('Error checking Ollama models:', ollamaError);
|
// console.error('Error checking Ollama models:', ollamaError);
|
||||||
// Если не удалось проверить Ollama, добавляем базовые модели
|
// Если не удалось проверить Ollama, добавляем базовые модели
|
||||||
allModels.push({ id: 'qwen2.5:7b', provider: 'ollama' });
|
allModels.push({ id: 'qwen2.5:7b', provider: 'ollama' });
|
||||||
}
|
}
|
||||||
@@ -167,7 +167,7 @@ async function getAllLLMModels() {
|
|||||||
|
|
||||||
return uniqueModels;
|
return uniqueModels;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error getting LLM models:', error);
|
// console.error('Error getting LLM models:', error);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,7 +213,7 @@ async function getAllEmbeddingModels() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ollamaError) {
|
} catch (ollamaError) {
|
||||||
console.error('Error checking Ollama embedding models:', ollamaError);
|
// console.error('Error checking Ollama embedding models:', ollamaError);
|
||||||
// Если не удалось проверить Ollama, добавляем базовые embedding модели
|
// Если не удалось проверить Ollama, добавляем базовые embedding модели
|
||||||
allModels.push({ id: 'mxbai-embed-large:latest', provider: 'ollama' });
|
allModels.push({ id: 'mxbai-embed-large:latest', provider: 'ollama' });
|
||||||
}
|
}
|
||||||
@@ -232,7 +232,7 @@ async function getAllEmbeddingModels() {
|
|||||||
|
|
||||||
return uniqueModels;
|
return uniqueModels;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error getting embedding models:', error);
|
// console.error('Error getting embedding models:', error);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
* GitHub: https://github.com/HB3-ACCELERATOR
|
* GitHub: https://github.com/HB3-ACCELERATOR
|
||||||
*/
|
*/
|
||||||
|
|
||||||
console.log('[EmailBot] emailBot.js loaded');
|
// console.log('[EmailBot] emailBot.js loaded');
|
||||||
const encryptedDb = require('./encryptedDatabaseService');
|
const encryptedDb = require('./encryptedDatabaseService');
|
||||||
const db = require('../db');
|
const db = require('../db');
|
||||||
const nodemailer = require('nodemailer');
|
const nodemailer = require('nodemailer');
|
||||||
@@ -28,7 +28,7 @@ const { isUserBlocked } = require('../utils/userUtils');
|
|||||||
|
|
||||||
class EmailBotService {
|
class EmailBotService {
|
||||||
constructor() {
|
constructor() {
|
||||||
console.log('[EmailBot] constructor called');
|
// console.log('[EmailBot] constructor called');
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSettingsFromDb() {
|
async getSettingsFromDb() {
|
||||||
@@ -43,7 +43,7 @@ class EmailBotService {
|
|||||||
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
||||||
}
|
}
|
||||||
} catch (keyError) {
|
} catch (keyError) {
|
||||||
console.error('Error reading encryption key:', keyError);
|
// console.error('Error reading encryption key:', keyError);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { rows } = await db.getQuery()(
|
const { rows } = await db.getQuery()(
|
||||||
@@ -530,7 +530,7 @@ class EmailBotService {
|
|||||||
|
|
||||||
async start() {
|
async start() {
|
||||||
try {
|
try {
|
||||||
console.log('[EmailBot] start() called');
|
// console.log('[EmailBot] start() called');
|
||||||
logger.info('[EmailBot] start() called');
|
logger.info('[EmailBot] start() called');
|
||||||
const imapConfig = await this.getImapConfig();
|
const imapConfig = await this.getImapConfig();
|
||||||
// Логируем IMAP-конфиг (без пароля)
|
// Логируем IMAP-конфиг (без пароля)
|
||||||
@@ -580,7 +580,7 @@ class EmailBotService {
|
|||||||
};
|
};
|
||||||
tryConnect();
|
tryConnect();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('[EmailBot] Ошибка при старте:', err);
|
// console.error('[EmailBot] Ошибка при старте:', err);
|
||||||
logger.error('[EmailBot] Ошибка при старте:', err);
|
logger.error('[EmailBot] Ошибка при старте:', err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@@ -592,5 +592,5 @@ class EmailBotService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[EmailBot] module.exports = EmailBotService');
|
// console.log('[EmailBot] module.exports = EmailBotService');
|
||||||
module.exports = EmailBotService;
|
module.exports = EmailBotService;
|
||||||
|
|||||||
@@ -20,34 +20,34 @@ class EncryptedDataService {
|
|||||||
this.isEncryptionEnabled = !!this.encryptionKey;
|
this.isEncryptionEnabled = !!this.encryptionKey;
|
||||||
|
|
||||||
if (this.isEncryptionEnabled) {
|
if (this.isEncryptionEnabled) {
|
||||||
console.log('🔐 Шифрование базы данных активировано');
|
// console.log('🔐 Шифрование базы данных активировано');
|
||||||
console.log('📋 Автоматическое определение зашифрованных колонок');
|
// console.log('📋 Автоматическое определение зашифрованных колонок');
|
||||||
} else {
|
} else {
|
||||||
console.log('⚠️ Шифрование базы данных отключено - ключ не найден');
|
// console.log('⚠️ Шифрование базы данных отключено - ключ не найден');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadEncryptionKey() {
|
loadEncryptionKey() {
|
||||||
try {
|
try {
|
||||||
const keyPath = path.join(__dirname, '../../ssl/keys/full_db_encryption.key');
|
const keyPath = path.join(__dirname, '../../ssl/keys/full_db_encryption.key');
|
||||||
console.log(`[EncryptedDB] Trying key path: ${keyPath}`);
|
// console.log(`[EncryptedDB] Trying key path: ${keyPath}`);
|
||||||
if (fs.existsSync(keyPath)) {
|
if (fs.existsSync(keyPath)) {
|
||||||
const key = fs.readFileSync(keyPath, 'utf8').trim();
|
const key = fs.readFileSync(keyPath, 'utf8').trim();
|
||||||
console.log(`[EncryptedDB] Key loaded from: ${keyPath}, length: ${key.length}`);
|
// console.log(`[EncryptedDB] Key loaded from: ${keyPath}, length: ${key.length}`);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
// Попробуем альтернативный путь относительно корня приложения
|
// Попробуем альтернативный путь относительно корня приложения
|
||||||
const altKeyPath = '/app/ssl/keys/full_db_encryption.key';
|
const altKeyPath = '/app/ssl/keys/full_db_encryption.key';
|
||||||
console.log(`[EncryptedDB] Trying alternative key path: ${altKeyPath}`);
|
// console.log(`[EncryptedDB] Trying alternative key path: ${altKeyPath}`);
|
||||||
if (fs.existsSync(altKeyPath)) {
|
if (fs.existsSync(altKeyPath)) {
|
||||||
const key = fs.readFileSync(altKeyPath, 'utf8').trim();
|
const key = fs.readFileSync(altKeyPath, 'utf8').trim();
|
||||||
console.log(`[EncryptedDB] Key loaded from: ${altKeyPath}, length: ${key.length}`);
|
// console.log(`[EncryptedDB] Key loaded from: ${altKeyPath}, length: ${key.length}`);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
console.log(`[EncryptedDB] No key file found, using default key`);
|
// console.log(`[EncryptedDB] No key file found, using default key`);
|
||||||
return 'default-key';
|
return 'default-key';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Ошибка загрузки ключа шифрования:', error);
|
// console.error('❌ Ошибка загрузки ключа шифрования:', error);
|
||||||
return 'default-key';
|
return 'default-key';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ class EncryptedDataService {
|
|||||||
const selectFields = columns.map(col => {
|
const selectFields = columns.map(col => {
|
||||||
if (col.column_name.endsWith('_encrypted')) {
|
if (col.column_name.endsWith('_encrypted')) {
|
||||||
const originalName = col.column_name.replace('_encrypted', '');
|
const originalName = col.column_name.replace('_encrypted', '');
|
||||||
console.log(`🔓 Расшифровываем поле ${col.column_name} -> ${originalName}`);
|
// console.log(`🔓 Расшифровываем поле ${col.column_name} -> ${originalName}`);
|
||||||
if (col.data_type === 'jsonb') {
|
if (col.data_type === 'jsonb') {
|
||||||
return `decrypt_json(${col.column_name}, $1) as "${originalName}"`;
|
return `decrypt_json(${col.column_name}, $1) as "${originalName}"`;
|
||||||
} else {
|
} else {
|
||||||
@@ -89,7 +89,7 @@ class EncryptedDataService {
|
|||||||
|
|
||||||
// Если есть зашифрованная версия, пропускаем незашифрованную
|
// Если есть зашифрованная версия, пропускаем незашифрованную
|
||||||
if (hasEncryptedVersion) {
|
if (hasEncryptedVersion) {
|
||||||
console.log(`⚠️ Пропускаем незашифрованное поле ${col.column_name} (есть зашифрованная версия)`);
|
// console.log(`⚠️ Пропускаем незашифрованное поле ${col.column_name} (есть зашифрованная версия)`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,16 +171,16 @@ class EncryptedDataService {
|
|||||||
query += ` LIMIT ${limit}`;
|
query += ` LIMIT ${limit}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`🔍 [getData] Выполняем запрос:`, query);
|
// console.log(`🔍 [getData] Выполняем запрос:`, query);
|
||||||
console.log(`🔍 [getData] Параметры:`, params);
|
// console.log(`🔍 [getData] Параметры:`, params);
|
||||||
|
|
||||||
const { rows } = await db.getQuery()(query, params);
|
const { rows } = await db.getQuery()(query, params);
|
||||||
|
|
||||||
console.log(`📊 Результат запроса из ${tableName}:`, rows);
|
// console.log(`📊 Результат запроса из ${tableName}:`, rows);
|
||||||
|
|
||||||
return rows;
|
return rows;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`❌ Ошибка получения данных из ${tableName}:`, error);
|
// console.error(`❌ Ошибка получения данных из ${tableName}:`, error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,19 +223,19 @@ class EncryptedDataService {
|
|||||||
const encryptedColumn = columns.find(col => col.column_name === `${key}_encrypted`);
|
const encryptedColumn = columns.find(col => col.column_name === `${key}_encrypted`);
|
||||||
const unencryptedColumn = columns.find(col => col.column_name === key);
|
const unencryptedColumn = columns.find(col => col.column_name === key);
|
||||||
|
|
||||||
console.log(`🔍 Обрабатываем поле ${key} = "${value}" (тип: ${typeof value})`);
|
// console.log(`🔍 Обрабатываем поле ${key} = "${value}" (тип: ${typeof value})`);
|
||||||
|
|
||||||
if (encryptedColumn) {
|
if (encryptedColumn) {
|
||||||
// Если есть зашифрованная колонка, шифруем данные
|
// Если есть зашифрованная колонка, шифруем данные
|
||||||
// Проверяем, что значение не пустое перед шифрованием
|
// Проверяем, что значение не пустое перед шифрованием
|
||||||
if (value === null || value === undefined || (typeof value === 'string' && value.trim() === '')) {
|
if (value === null || value === undefined || (typeof value === 'string' && value.trim() === '')) {
|
||||||
// Пропускаем пустые значения
|
// Пропускаем пустые значения
|
||||||
console.log(`⚠️ Пропускаем пустое зашифрованное поле ${key}`);
|
// console.log(`⚠️ Пропускаем пустое зашифрованное поле ${key}`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const currentParamIndex = paramIndex++;
|
const currentParamIndex = paramIndex++;
|
||||||
filteredData[key] = value; // Добавляем в отфильтрованные данные
|
filteredData[key] = value; // Добавляем в отфильтрованные данные
|
||||||
console.log(`✅ Добавили зашифрованное поле ${key} в filteredData`);
|
// console.log(`✅ Добавили зашифрованное поле ${key} в filteredData`);
|
||||||
if (encryptedColumn.data_type === 'jsonb') {
|
if (encryptedColumn.data_type === 'jsonb') {
|
||||||
encryptedData[`${key}_encrypted`] = `encrypt_json($${currentParamIndex}, ${hasEncryptedFields ? '$1::text' : 'NULL'})`;
|
encryptedData[`${key}_encrypted`] = `encrypt_json($${currentParamIndex}, ${hasEncryptedFields ? '$1::text' : 'NULL'})`;
|
||||||
} else {
|
} else {
|
||||||
@@ -247,15 +247,15 @@ class EncryptedDataService {
|
|||||||
if ((value === null || value === undefined || (typeof value === 'string' && value.trim() === '')) &&
|
if ((value === null || value === undefined || (typeof value === 'string' && value.trim() === '')) &&
|
||||||
key !== 'role' && key !== 'sender_type') {
|
key !== 'role' && key !== 'sender_type') {
|
||||||
// Пропускаем пустые значения, кроме role и sender_type
|
// Пропускаем пустые значения, кроме role и sender_type
|
||||||
console.log(`⚠️ Пропускаем пустое незашифрованное поле ${key}`);
|
// console.log(`⚠️ Пропускаем пустое незашифрованное поле ${key}`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
filteredData[key] = value; // Добавляем в отфильтрованные данные
|
filteredData[key] = value; // Добавляем в отфильтрованные данные
|
||||||
unencryptedData[key] = `$${paramIndex++}`;
|
unencryptedData[key] = `$${paramIndex++}`;
|
||||||
console.log(`✅ Добавили незашифрованное поле ${key} в filteredData и unencryptedData`);
|
// console.log(`✅ Добавили незашифрованное поле ${key} в filteredData и unencryptedData`);
|
||||||
} else {
|
} else {
|
||||||
// Если колонка не найдена, пропускаем
|
// Если колонка не найдена, пропускаем
|
||||||
console.warn(`⚠️ Колонка ${key} не найдена в таблице ${tableName}`);
|
// console.warn(`⚠️ Колонка ${key} не найдена в таблице ${tableName}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,9 +263,9 @@ class EncryptedDataService {
|
|||||||
|
|
||||||
// Проверяем, есть ли данные для сохранения
|
// Проверяем, есть ли данные для сохранения
|
||||||
if (Object.keys(allData).length === 0) {
|
if (Object.keys(allData).length === 0) {
|
||||||
console.warn(`⚠️ Нет данных для сохранения в таблице ${tableName} - все значения пустые`);
|
// console.warn(`⚠️ Нет данных для сохранения в таблице ${tableName} - все значения пустые`);
|
||||||
console.warn(`⚠️ Исходные данные:`, data);
|
// console.warn(`⚠️ Исходные данные:`, data);
|
||||||
console.warn(`⚠️ Отфильтрованные данные:`, filteredData);
|
// console.warn(`⚠️ Отфильтрованные данные:`, filteredData);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,7 +301,7 @@ class EncryptedDataService {
|
|||||||
return rows[0];
|
return rows[0];
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`❌ Ошибка сохранения данных в ${tableName}:`, error);
|
// console.error(`❌ Ошибка сохранения данных в ${tableName}:`, error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,7 +352,7 @@ class EncryptedDataService {
|
|||||||
const result = await db.getQuery()(query, params);
|
const result = await db.getQuery()(query, params);
|
||||||
return result.rows;
|
return result.rows;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`❌ Ошибка удаления данных из ${tableName}:`, error);
|
// console.error(`❌ Ошибка удаления данных из ${tableName}:`, error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
* GitHub: https://github.com/HB3-ACCELERATOR
|
* GitHub: https://github.com/HB3-ACCELERATOR
|
||||||
*/
|
*/
|
||||||
|
|
||||||
console.log('[identity-service] loaded');
|
// console.log('[identity-service] loaded');
|
||||||
|
|
||||||
const encryptedDb = require('./encryptedDatabaseService');
|
const encryptedDb = require('./encryptedDatabaseService');
|
||||||
const db = require('../db');
|
const db = require('../db');
|
||||||
|
|||||||
@@ -14,23 +14,23 @@ const encryptedDb = require('./encryptedDatabaseService');
|
|||||||
const vectorSearch = require('./vectorSearchClient');
|
const vectorSearch = require('./vectorSearchClient');
|
||||||
const { getProviderSettings } = require('./aiProviderSettingsService');
|
const { getProviderSettings } = require('./aiProviderSettingsService');
|
||||||
|
|
||||||
console.log('[RAG] ragService.js loaded');
|
// console.log('[RAG] ragService.js loaded');
|
||||||
|
|
||||||
// Простой кэш для RAG результатов
|
// Простой кэш для RAG результатов
|
||||||
const ragCache = new Map();
|
const ragCache = new Map();
|
||||||
const RAG_CACHE_TTL = 5 * 60 * 1000; // 5 минут
|
const RAG_CACHE_TTL = 5 * 60 * 1000; // 5 минут
|
||||||
|
|
||||||
async function getTableData(tableId) {
|
async function getTableData(tableId) {
|
||||||
console.log(`[RAG] getTableData called for tableId: ${tableId}`);
|
// console.log(`[RAG] getTableData called for tableId: ${tableId}`);
|
||||||
|
|
||||||
const columns = await encryptedDb.getData('user_columns', { table_id: tableId });
|
const columns = await encryptedDb.getData('user_columns', { table_id: tableId });
|
||||||
console.log(`[RAG] Found ${columns.length} columns:`, columns.map(col => ({ id: col.id, name: col.name, purpose: col.options?.purpose })));
|
// console.log(`[RAG] Found ${columns.length} columns:`, columns.map(col => ({ id: col.id, name: col.name, purpose: col.options?.purpose })));
|
||||||
|
|
||||||
const rows = await encryptedDb.getData('user_rows', { table_id: tableId });
|
const rows = await encryptedDb.getData('user_rows', { table_id: tableId });
|
||||||
console.log(`[RAG] Found ${rows.length} rows:`, rows.map(row => ({ id: row.id, name: row.name })));
|
// console.log(`[RAG] Found ${rows.length} rows:`, rows.map(row => ({ id: row.id, name: row.name })));
|
||||||
|
|
||||||
const cellValues = await encryptedDb.getData('user_cell_values', { row_id: { $in: rows.map(row => row.id) } });
|
const cellValues = await encryptedDb.getData('user_cell_values', { row_id: { $in: rows.map(row => row.id) } });
|
||||||
console.log(`[RAG] Found ${cellValues.length} cell values`);
|
// console.log(`[RAG] Found ${cellValues.length} cell values`);
|
||||||
|
|
||||||
const getColId = purpose => columns.find(col => col.options?.purpose === purpose)?.id;
|
const getColId = purpose => columns.find(col => col.options?.purpose === purpose)?.id;
|
||||||
const questionColId = getColId('question');
|
const questionColId = getColId('question');
|
||||||
@@ -40,14 +40,14 @@ async function getTableData(tableId) {
|
|||||||
const priorityColId = getColId('priority');
|
const priorityColId = getColId('priority');
|
||||||
const dateColId = getColId('date');
|
const dateColId = getColId('date');
|
||||||
|
|
||||||
console.log(`[RAG] Column IDs:`, {
|
// console.log(`[RAG] Column IDs:`, {
|
||||||
question: questionColId,
|
// question: questionColId,
|
||||||
answer: answerColId,
|
// answer: answerColId,
|
||||||
context: contextColId,
|
// context: contextColId,
|
||||||
product: productColId,
|
// product: productColId,
|
||||||
priority: priorityColId,
|
// priority: priorityColId,
|
||||||
date: dateColId
|
// date: dateColId
|
||||||
});
|
// });
|
||||||
|
|
||||||
const data = rows.map(row => {
|
const data = rows.map(row => {
|
||||||
const cells = cellValues.filter(cell => cell.row_id === row.id);
|
const cells = cellValues.filter(cell => cell.row_id === row.id);
|
||||||
@@ -61,34 +61,34 @@ async function getTableData(tableId) {
|
|||||||
priority: cells.find(c => c.column_id === priorityColId)?.value,
|
priority: cells.find(c => c.column_id === priorityColId)?.value,
|
||||||
date: cells.find(c => c.column_id === dateColId)?.value,
|
date: cells.find(c => c.column_id === dateColId)?.value,
|
||||||
};
|
};
|
||||||
console.log(`[RAG] Processed row ${row.id}:`, result);
|
// console.log(`[RAG] Processed row ${row.id}:`, result);
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function ragAnswer({ tableId, userQuestion, product = null, threshold = 10 }) {
|
async function ragAnswer({ tableId, userQuestion, product = null, threshold = 10 }) {
|
||||||
console.log(`[RAG] ragAnswer called: tableId=${tableId}, userQuestion="${userQuestion}"`);
|
// console.log(`[RAG] ragAnswer called: tableId=${tableId}, userQuestion="${userQuestion}"`);
|
||||||
|
|
||||||
// Проверяем кэш
|
// Проверяем кэш
|
||||||
const cacheKey = `${tableId}:${userQuestion}:${product}`;
|
const cacheKey = `${tableId}:${userQuestion}:${product}`;
|
||||||
const cached = ragCache.get(cacheKey);
|
const cached = ragCache.get(cacheKey);
|
||||||
if (cached && (Date.now() - cached.timestamp) < RAG_CACHE_TTL) {
|
if (cached && (Date.now() - cached.timestamp) < RAG_CACHE_TTL) {
|
||||||
console.log(`[RAG] Returning cached result for: ${cacheKey}`);
|
// console.log(`[RAG] Returning cached result for: ${cacheKey}`);
|
||||||
return cached.result;
|
return cached.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await getTableData(tableId);
|
const data = await getTableData(tableId);
|
||||||
console.log(`[RAG] Got ${data.length} rows from database`);
|
// console.log(`[RAG] Got ${data.length} rows from database`);
|
||||||
|
|
||||||
// Подробное логирование данных
|
// Подробное логирование данных
|
||||||
data.forEach((row, index) => {
|
data.forEach((row, index) => {
|
||||||
console.log(`[RAG] Row ${index}:`, {
|
// console.log(`[RAG] Row ${index}:`, {
|
||||||
id: row.id,
|
// id: row.id,
|
||||||
question: row.question,
|
// question: row.question,
|
||||||
answer: row.answer,
|
// answer: row.answer,
|
||||||
product: row.product
|
// product: row.product
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
|
||||||
const questions = data.map(row => row.question && typeof row.question === 'string' ? row.question.trim() : row.question);
|
const questions = data.map(row => row.question && typeof row.question === 'string' ? row.question.trim() : row.question);
|
||||||
@@ -108,61 +108,61 @@ async function ragAnswer({ tableId, userQuestion, product = null, threshold = 10
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
console.log(`[RAG] Prepared ${rowsForUpsert.length} rows for upsert`);
|
// console.log(`[RAG] Prepared ${rowsForUpsert.length} rows for upsert`);
|
||||||
console.log(`[RAG] First row:`, rowsForUpsert[0]);
|
// console.log(`[RAG] First row:`, rowsForUpsert[0]);
|
||||||
|
|
||||||
// Upsert все вопросы в индекс (можно оптимизировать по изменению)
|
// Upsert все вопросы в индекс (можно оптимизировать по изменению)
|
||||||
if (rowsForUpsert.length > 0) {
|
if (rowsForUpsert.length > 0) {
|
||||||
await vectorSearch.upsert(tableId, rowsForUpsert);
|
await vectorSearch.upsert(tableId, rowsForUpsert);
|
||||||
console.log(`[RAG] Upsert completed`);
|
// console.log(`[RAG] Upsert completed`);
|
||||||
} else {
|
} else {
|
||||||
console.log(`[RAG] No rows to upsert, skipping`);
|
// console.log(`[RAG] No rows to upsert, skipping`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Поиск
|
// Поиск
|
||||||
let results = [];
|
let results = [];
|
||||||
if (rowsForUpsert.length > 0) {
|
if (rowsForUpsert.length > 0) {
|
||||||
results = await vectorSearch.search(tableId, userQuestion, 2); // Уменьшаем до 2 результатов
|
results = await vectorSearch.search(tableId, userQuestion, 2); // Уменьшаем до 2 результатов
|
||||||
console.log(`[RAG] Search completed, got ${results.length} results`);
|
// console.log(`[RAG] Search completed, got ${results.length} results`);
|
||||||
|
|
||||||
// Подробное логирование результатов поиска
|
// Подробное логирование результатов поиска
|
||||||
results.forEach((result, index) => {
|
results.forEach((result, index) => {
|
||||||
console.log(`[RAG] Search result ${index}:`, {
|
// console.log(`[RAG] Search result ${index}:`, {
|
||||||
row_id: result.row_id,
|
// row_id: result.row_id,
|
||||||
score: result.score,
|
// score: result.score,
|
||||||
metadata: result.metadata
|
// metadata: result.metadata
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log(`[RAG] No data in table, skipping search`);
|
// console.log(`[RAG] No data in table, skipping search`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Фильтрация по тегам/продукту
|
// Фильтрация по тегам/продукту
|
||||||
let filtered = results;
|
let filtered = results;
|
||||||
console.log(`[RAG] Before filtering: ${filtered.length} results`);
|
// console.log(`[RAG] Before filtering: ${filtered.length} results`);
|
||||||
|
|
||||||
if (product) {
|
if (product) {
|
||||||
console.log(`[RAG] Filtering by product:`, product);
|
// console.log(`[RAG] Filtering by product:`, product);
|
||||||
filtered = filtered.filter(row => Array.isArray(row.metadata.product) ? row.metadata.product.includes(product) : row.metadata.product === product);
|
filtered = filtered.filter(row => Array.isArray(row.metadata.product) ? row.metadata.product.includes(product) : row.metadata.product === product);
|
||||||
console.log(`[RAG] After product filtering: ${filtered.length} results`);
|
// console.log(`[RAG] After product filtering: ${filtered.length} results`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Берём ближайший результат с учётом порога (по модулю)
|
// Берём ближайший результат с учётом порога (по модулю)
|
||||||
console.log(`[RAG] Looking for best result with abs(threshold): ${threshold}`);
|
// console.log(`[RAG] Looking for best result with abs(threshold): ${threshold}`);
|
||||||
const best = filtered.reduce((acc, row) => {
|
const best = filtered.reduce((acc, row) => {
|
||||||
if (Math.abs(row.score) <= threshold && (acc === null || Math.abs(row.score) < Math.abs(acc.score))) {
|
if (Math.abs(row.score) <= threshold && (acc === null || Math.abs(row.score) < Math.abs(acc.score))) {
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}, null);
|
}, null);
|
||||||
console.log(`[RAG] Best result:`, best);
|
// console.log(`[RAG] Best result:`, best);
|
||||||
|
|
||||||
// Логируем все результаты с их score для диагностики
|
// Логируем все результаты с их score для диагностики
|
||||||
if (filtered.length > 0) {
|
if (filtered.length > 0) {
|
||||||
console.log(`[RAG] All filtered results with scores:`);
|
// console.log(`[RAG] All filtered results with scores:`);
|
||||||
filtered.forEach((result, index) => {
|
// filtered.forEach((result, index) => {
|
||||||
console.log(`[RAG] ${index}: score=${result.score}, meets_threshold=${Math.abs(result.score) <= threshold}`);
|
// console.log(`[RAG] ${index}: score=${result.score}, meets_threshold=${Math.abs(result.score) <= threshold}`);
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = {
|
const result = {
|
||||||
@@ -238,18 +238,18 @@ async function generateLLMResponse({
|
|||||||
model,
|
model,
|
||||||
language
|
language
|
||||||
}) {
|
}) {
|
||||||
console.log(`[RAG] generateLLMResponse called with:`, {
|
// console.log(`[RAG] generateLLMResponse called with:`, {
|
||||||
userQuestion,
|
// userQuestion,
|
||||||
context,
|
// context,
|
||||||
answer,
|
// answer,
|
||||||
systemPrompt,
|
// systemPrompt,
|
||||||
userTags,
|
// userTags,
|
||||||
product,
|
// product,
|
||||||
priority,
|
// priority,
|
||||||
date,
|
// date,
|
||||||
model,
|
// model,
|
||||||
language
|
// language
|
||||||
});
|
// });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const aiAssistant = require('./ai-assistant');
|
const aiAssistant = require('./ai-assistant');
|
||||||
@@ -286,10 +286,10 @@ async function generateLLMResponse({
|
|||||||
rules
|
rules
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(`[RAG] LLM response generated:`, llmResponse);
|
// console.log(`[RAG] LLM response generated:`, llmResponse);
|
||||||
return llmResponse;
|
return llmResponse;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`[RAG] Error generating LLM response:`, error);
|
// console.error(`[RAG] Error generating LLM response:`, error);
|
||||||
return 'Извините, произошла ошибка при генерации ответа.';
|
return 'Извините, произошла ошибка при генерации ответа.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ async function getTelegramSettings() {
|
|||||||
|
|
||||||
// Создание и настройка бота
|
// Создание и настройка бота
|
||||||
async function getBot() {
|
async function getBot() {
|
||||||
console.log('[TelegramBot] getBot() called');
|
// console.log('[TelegramBot] getBot() called');
|
||||||
if (!botInstance) {
|
if (!botInstance) {
|
||||||
console.log('[TelegramBot] Creating new bot instance...');
|
// console.log('[TelegramBot] Creating new bot instance...');
|
||||||
const settings = await getTelegramSettings();
|
const settings = await getTelegramSettings();
|
||||||
console.log('[TelegramBot] Got settings, creating Telegraf instance...');
|
// console.log('[TelegramBot] Got settings, creating Telegraf instance...');
|
||||||
botInstance = new Telegraf(settings.bot_token);
|
botInstance = new Telegraf(settings.bot_token);
|
||||||
console.log('[TelegramBot] Telegraf instance created');
|
// console.log('[TelegramBot] Telegraf instance created');
|
||||||
|
|
||||||
// Обработка команды /start
|
// Обработка команды /start
|
||||||
botInstance.command('start', (ctx) => {
|
botInstance.command('start', (ctx) => {
|
||||||
@@ -489,7 +489,7 @@ async function getBot() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Запуск бота с таймаутом
|
// Запуск бота с таймаутом
|
||||||
console.log('[TelegramBot] Before botInstance.launch()');
|
// console.log('[TelegramBot] Before botInstance.launch()');
|
||||||
try {
|
try {
|
||||||
// Запускаем бота с таймаутом
|
// Запускаем бота с таймаутом
|
||||||
const launchPromise = botInstance.launch();
|
const launchPromise = botInstance.launch();
|
||||||
@@ -498,12 +498,12 @@ async function getBot() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await Promise.race([launchPromise, timeoutPromise]);
|
await Promise.race([launchPromise, timeoutPromise]);
|
||||||
console.log('[TelegramBot] After botInstance.launch()');
|
// console.log('[TelegramBot] After botInstance.launch()');
|
||||||
logger.info('[TelegramBot] Бот запущен');
|
logger.info('[TelegramBot] Бот запущен');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[TelegramBot] Error launching bot:', error);
|
// console.error('[TelegramBot] Error launching bot:', error);
|
||||||
// Не выбрасываем ошибку, чтобы не блокировать запуск сервера
|
// Не выбрасываем ошибку, чтобы не блокировать запуск сервера
|
||||||
console.log('[TelegramBot] Bot launch failed, but continuing...');
|
// console.log('[TelegramBot] Bot launch failed, but continuing...');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,23 +13,23 @@
|
|||||||
const encryptedDb = require('./encryptedDatabaseService');
|
const encryptedDb = require('./encryptedDatabaseService');
|
||||||
|
|
||||||
async function deleteUserById(userId) {
|
async function deleteUserById(userId) {
|
||||||
console.log('[DELETE] Вызван deleteUserById для userId:', userId);
|
// console.log('[DELETE] Вызван deleteUserById для userId:', userId);
|
||||||
try {
|
try {
|
||||||
console.log('[DELETE] Начинаем удаление user_identities для userId:', userId);
|
// console.log('[DELETE] Начинаем удаление user_identities для userId:', userId);
|
||||||
const resIdentities = await encryptedDb.deleteData('user_identities', { user_id: userId });
|
const resIdentities = await encryptedDb.deleteData('user_identities', { user_id: userId });
|
||||||
console.log('[DELETE] Удалено user_identities:', resIdentities.length);
|
// console.log('[DELETE] Удалено user_identities:', resIdentities.length);
|
||||||
|
|
||||||
console.log('[DELETE] Начинаем удаление messages для userId:', userId);
|
// console.log('[DELETE] Начинаем удаление messages для userId:', userId);
|
||||||
const resMessages = await encryptedDb.deleteData('messages', { user_id: userId });
|
const resMessages = await encryptedDb.deleteData('messages', { user_id: userId });
|
||||||
console.log('[DELETE] Удалено messages:', resMessages.length);
|
// console.log('[DELETE] Удалено messages:', resMessages.length);
|
||||||
|
|
||||||
console.log('[DELETE] Начинаем удаление пользователя из users:', userId);
|
// console.log('[DELETE] Начинаем удаление пользователя из users:', userId);
|
||||||
const result = await encryptedDb.deleteData('users', { id: userId });
|
const result = await encryptedDb.deleteData('users', { id: userId });
|
||||||
console.log('[DELETE] Результат удаления пользователя:', result.length, result);
|
// console.log('[DELETE] Результат удаления пользователя:', result.length, result);
|
||||||
|
|
||||||
return result.length;
|
return result.length;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[DELETE] Ошибка при удалении пользователя:', e);
|
// console.error('[DELETE] Ошибка при удалении пользователя:', e);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ function initWSS(server) {
|
|||||||
wss = new WebSocket.Server({ server, path: '/ws' });
|
wss = new WebSocket.Server({ server, path: '/ws' });
|
||||||
|
|
||||||
wss.on('connection', (ws, req) => {
|
wss.on('connection', (ws, req) => {
|
||||||
console.log('🔌 [WebSocket] Новое подключение');
|
// console.log('🔌 [WebSocket] Новое подключение');
|
||||||
console.log('🔌 [WebSocket] IP клиента:', req.socket.remoteAddress);
|
// console.log('🔌 [WebSocket] IP клиента:', req.socket.remoteAddress);
|
||||||
console.log('🔌 [WebSocket] User-Agent:', req.headers['user-agent']);
|
// console.log('🔌 [WebSocket] User-Agent:', req.headers['user-agent']);
|
||||||
console.log('🔌 [WebSocket] Origin:', req.headers.origin);
|
// console.log('🔌 [WebSocket] Origin:', req.headers.origin);
|
||||||
|
|
||||||
// Добавляем клиента в общий список
|
// Добавляем клиента в общий список
|
||||||
if (!wsClients.has('anonymous')) {
|
if (!wsClients.has('anonymous')) {
|
||||||
@@ -43,7 +43,7 @@ function initWSS(server) {
|
|||||||
ws.on('message', (message) => {
|
ws.on('message', (message) => {
|
||||||
try {
|
try {
|
||||||
const data = JSON.parse(message);
|
const data = JSON.parse(message);
|
||||||
console.log('📨 [WebSocket] Получено сообщение:', data);
|
// console.log('📨 [WebSocket] Получено сообщение:', data);
|
||||||
|
|
||||||
if (data.type === 'auth' && data.userId) {
|
if (data.type === 'auth' && data.userId) {
|
||||||
// Аутентификация пользователя
|
// Аутентификация пользователя
|
||||||
@@ -58,12 +58,12 @@ function initWSS(server) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ [WebSocket] Ошибка парсинга сообщения:', error);
|
// console.error('❌ [WebSocket] Ошибка парсинга сообщения:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ws.on('close', (code, reason) => {
|
ws.on('close', (code, reason) => {
|
||||||
console.log('🔌 [WebSocket] Соединение закрыто', { code, reason: reason.toString() });
|
// console.log('🔌 [WebSocket] Соединение закрыто', { code, reason: reason.toString() });
|
||||||
// Удаляем клиента из всех списков
|
// Удаляем клиента из всех списков
|
||||||
for (const [userId, clients] of wsClients.entries()) {
|
for (const [userId, clients] of wsClients.entries()) {
|
||||||
clients.delete(ws);
|
clients.delete(ws);
|
||||||
@@ -74,15 +74,15 @@ function initWSS(server) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ws.on('error', (error) => {
|
ws.on('error', (error) => {
|
||||||
console.error('❌ [WebSocket] Ошибка соединения:', error.message);
|
// console.error('❌ [WebSocket] Ошибка соединения:', error.message);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('🚀 [WebSocket] Сервер запущен на /ws');
|
// console.log('🚀 [WebSocket] Сервер запущен на /ws');
|
||||||
}
|
}
|
||||||
|
|
||||||
function authenticateUser(ws, userId) {
|
function authenticateUser(ws, userId) {
|
||||||
console.log(`🔐 [WebSocket] Аутентификация пользователя ${userId}`);
|
// console.log(`🔐 [WebSocket] Аутентификация пользователя ${userId}`);
|
||||||
|
|
||||||
// Удаляем из анонимных
|
// Удаляем из анонимных
|
||||||
if (wsClients.has('anonymous')) {
|
if (wsClients.has('anonymous')) {
|
||||||
@@ -103,7 +103,7 @@ function authenticateUser(ws, userId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function broadcastContactsUpdate() {
|
function broadcastContactsUpdate() {
|
||||||
console.log('📢 [WebSocket] Отправка обновления контактов всем клиентам');
|
// console.log('📢 [WebSocket] Отправка обновления контактов всем клиентам');
|
||||||
for (const [userId, clients] of wsClients.entries()) {
|
for (const [userId, clients] of wsClients.entries()) {
|
||||||
for (const ws of clients) {
|
for (const ws of clients) {
|
||||||
if (ws.readyState === WebSocket.OPEN) {
|
if (ws.readyState === WebSocket.OPEN) {
|
||||||
@@ -114,7 +114,7 @@ function broadcastContactsUpdate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function broadcastMessagesUpdate() {
|
function broadcastMessagesUpdate() {
|
||||||
console.log('📢 [WebSocket] Отправка обновления сообщений всем клиентам');
|
// console.log('📢 [WebSocket] Отправка обновления сообщений всем клиентам');
|
||||||
for (const [userId, clients] of wsClients.entries()) {
|
for (const [userId, clients] of wsClients.entries()) {
|
||||||
for (const ws of clients) {
|
for (const ws of clients) {
|
||||||
if (ws.readyState === WebSocket.OPEN) {
|
if (ws.readyState === WebSocket.OPEN) {
|
||||||
@@ -125,10 +125,10 @@ function broadcastMessagesUpdate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function broadcastChatMessage(message, targetUserId = null) {
|
function broadcastChatMessage(message, targetUserId = null) {
|
||||||
console.log(`📢 [WebSocket] Отправка сообщения чата`, {
|
// console.log(`📢 [WebSocket] Отправка сообщения чата`, {
|
||||||
messageId: message.id,
|
// messageId: message.id,
|
||||||
targetUserId
|
// targetUserId
|
||||||
});
|
// });
|
||||||
|
|
||||||
if (targetUserId) {
|
if (targetUserId) {
|
||||||
// Отправляем конкретному пользователю
|
// Отправляем конкретному пользователю
|
||||||
@@ -159,10 +159,10 @@ function broadcastChatMessage(message, targetUserId = null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function broadcastConversationUpdate(conversationId, targetUserId = null) {
|
function broadcastConversationUpdate(conversationId, targetUserId = null) {
|
||||||
console.log(`📢 [WebSocket] Отправка обновления диалога`, {
|
// console.log(`📢 [WebSocket] Отправка обновления диалога`, {
|
||||||
conversationId,
|
// conversationId,
|
||||||
targetUserId
|
// targetUserId
|
||||||
});
|
// });
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
type: 'conversation-updated',
|
type: 'conversation-updated',
|
||||||
@@ -192,7 +192,7 @@ function broadcastConversationUpdate(conversationId, targetUserId = null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function broadcastTableUpdate(tableId) {
|
function broadcastTableUpdate(tableId) {
|
||||||
console.log('📢 [WebSocket] Отправка обновления таблицы', tableId);
|
// console.log('📢 [WebSocket] Отправка обновления таблицы', tableId);
|
||||||
const payload = { type: 'table-updated', tableId };
|
const payload = { type: 'table-updated', tableId };
|
||||||
for (const [userId, clients] of wsClients.entries()) {
|
for (const [userId, clients] of wsClients.entries()) {
|
||||||
for (const ws of clients) {
|
for (const ws of clients) {
|
||||||
@@ -204,11 +204,11 @@ function broadcastTableUpdate(tableId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function broadcastTableRelationsUpdate(tableId, rowId, targetUserId = null) {
|
function broadcastTableRelationsUpdate(tableId, rowId, targetUserId = null) {
|
||||||
console.log(`📢 [WebSocket] Отправка обновления связей таблицы`, {
|
// console.log(`📢 [WebSocket] Отправка обновления связей таблицы`, {
|
||||||
tableId,
|
// tableId,
|
||||||
rowId,
|
// rowId,
|
||||||
targetUserId
|
// targetUserId
|
||||||
});
|
// });
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
type: 'table-relations-updated',
|
type: 'table-relations-updated',
|
||||||
@@ -246,7 +246,7 @@ function broadcastTagsUpdate(targetUserId = null, rowId = null) {
|
|||||||
|
|
||||||
// Устанавливаем новый таймаут
|
// Устанавливаем новый таймаут
|
||||||
tagsUpdateTimeout = setTimeout(() => {
|
tagsUpdateTimeout = setTimeout(() => {
|
||||||
console.log('🔔 [WebSocket] Отправляем уведомление об обновлении тегов', rowId ? `для строки ${rowId}` : '');
|
// console.log('🔔 [WebSocket] Отправляем уведомление об обновлении тегов', rowId ? `для строки ${rowId}` : '');
|
||||||
const message = JSON.stringify({
|
const message = JSON.stringify({
|
||||||
type: 'tags-updated',
|
type: 'tags-updated',
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
@@ -262,7 +262,7 @@ function broadcastTagsUpdate(targetUserId = null, rowId = null) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`🔔 [WebSocket] Отправлено tags-updated ${sentCount} клиентам`);
|
// console.log(`🔔 [WebSocket] Отправлено tags-updated ${sentCount} клиентам`);
|
||||||
}, TAGS_UPDATE_DEBOUNCE);
|
}, TAGS_UPDATE_DEBOUNCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,7 +300,7 @@ function getStats() {
|
|||||||
|
|
||||||
// Функция для отправки уведомлений о статусе AI
|
// Функция для отправки уведомлений о статусе AI
|
||||||
function broadcastAIStatus(status) {
|
function broadcastAIStatus(status) {
|
||||||
console.log('📢 [WebSocket] Отправка статуса AI всем клиентам');
|
// console.log('📢 [WebSocket] Отправка статуса AI всем клиентам');
|
||||||
for (const [userId, clients] of wsClients.entries()) {
|
for (const [userId, clients] of wsClients.entries()) {
|
||||||
for (const ws of clients) {
|
for (const ws of clients) {
|
||||||
if (ws.readyState === WebSocket.OPEN) {
|
if (ws.readyState === WebSocket.OPEN) {
|
||||||
|
|||||||
@@ -74,14 +74,14 @@
|
|||||||
isLoadingTokens.value = true;
|
isLoadingTokens.value = true;
|
||||||
try {
|
try {
|
||||||
const walletAddress = getIdentityValue('wallet');
|
const walletAddress = getIdentityValue('wallet');
|
||||||
console.log('[App] Обновление балансов для адреса:', walletAddress);
|
// console.log('[App] Обновление балансов для адреса:', walletAddress);
|
||||||
|
|
||||||
const balances = await fetchTokenBalances(walletAddress);
|
const balances = await fetchTokenBalances(walletAddress);
|
||||||
console.log('[App] Полученные балансы:', balances);
|
// console.log('[App] Полученные балансы:', balances);
|
||||||
|
|
||||||
tokenBalances.value = balances || {};
|
tokenBalances.value = balances || {};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[App] Ошибка при получении балансов:', error);
|
// console.error('[App] Ошибка при получении балансов:', error);
|
||||||
tokenBalances.value = {};
|
tokenBalances.value = {};
|
||||||
} finally {
|
} finally {
|
||||||
isLoadingTokens.value = false;
|
isLoadingTokens.value = false;
|
||||||
@@ -96,11 +96,11 @@
|
|||||||
const oldWalletId = oldWalletIdentity ? oldWalletIdentity.provider_id : null;
|
const oldWalletId = oldWalletIdentity ? oldWalletIdentity.provider_id : null;
|
||||||
|
|
||||||
if (newWalletId !== oldWalletId) {
|
if (newWalletId !== oldWalletId) {
|
||||||
console.log('[App] Обнаружено изменение идентификатора кошелька, обновляем балансы');
|
// console.log('[App] Обнаружено изменение идентификатора кошелька, обновляем балансы');
|
||||||
refreshTokenBalances();
|
refreshTokenBalances();
|
||||||
} else if (hasIdentityType('wallet') && Object.keys(tokenBalances.value).length === 0 && !isLoadingTokens.value) {
|
} else if (hasIdentityType('wallet') && Object.keys(tokenBalances.value).length === 0 && !isLoadingTokens.value) {
|
||||||
// Если кошелек есть, но баланс пустой и не грузится - пробуем загрузить
|
// Если кошелек есть, но баланс пустой и не грузится - пробуем загрузить
|
||||||
console.log('[App] Кошелек есть, но баланс пуст, пытаемся загрузить.');
|
// console.log('[App] Кошелек есть, но баланс пуст, пытаемся загрузить.');
|
||||||
refreshTokenBalances();
|
refreshTokenBalances();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
|
|
||||||
// Мониторинг изменений состояния аутентификации
|
// Мониторинг изменений состояния аутентификации
|
||||||
watch(auth.isAuthenticated, (isAuth) => {
|
watch(auth.isAuthenticated, (isAuth) => {
|
||||||
console.log('[App] Состояние аутентификации изменилось:', isAuth);
|
// console.log('[App] Состояние аутентификации изменилось:', isAuth);
|
||||||
if (isAuth) {
|
if (isAuth) {
|
||||||
// Убираем задержку, полагаемся на watch(identities) или прямо вызываем
|
// Убираем задержку, полагаемся на watch(identities) или прямо вызываем
|
||||||
// setTimeout(refreshTokenBalances, 500);
|
// setTimeout(refreshTokenBalances, 500);
|
||||||
@@ -121,16 +121,16 @@
|
|||||||
|
|
||||||
// --- Возвращаем и улучшаем функцию-обработчик ---
|
// --- Возвращаем и улучшаем функцию-обработчик ---
|
||||||
const handleAuthActionCompleted = async () => {
|
const handleAuthActionCompleted = async () => {
|
||||||
console.log('[App] Auth action completed, triggering updates...');
|
// console.log('[App] Auth action completed, triggering updates...');
|
||||||
isLoading.value = true; // Показываем индикатор загрузки
|
isLoading.value = true; // Показываем индикатор загрузки
|
||||||
try {
|
try {
|
||||||
// 1. Проверяем аутентификацию (обновит identities и isAuthenticated)
|
// 1. Проверяем аутентификацию (обновит identities и isAuthenticated)
|
||||||
await auth.checkAuth();
|
await auth.checkAuth();
|
||||||
console.log('[App] auth.checkAuth() completed. isAuthenticated:', auth.isAuthenticated.value);
|
// console.log('[App] auth.checkAuth() completed. isAuthenticated:', auth.isAuthenticated.value);
|
||||||
|
|
||||||
// 2. Обновляем баланс (использует обновленные identities)
|
// 2. Обновляем баланс (использует обновленные identities)
|
||||||
await refreshTokenBalances();
|
await refreshTokenBalances();
|
||||||
console.log('[App] refreshTokenBalances() completed.');
|
// console.log('[App] refreshTokenBalances() completed.');
|
||||||
|
|
||||||
// 3. Явно оповещаем компоненты об изменении состояния авторизации
|
// 3. Явно оповещаем компоненты об изменении состояния авторизации
|
||||||
// Передаем актуальное состояние из useAuth
|
// Передаем актуальное состояние из useAuth
|
||||||
@@ -140,10 +140,10 @@
|
|||||||
userId: auth.userId.value, // Предполагаем, что userId есть в useAuth
|
userId: auth.userId.value, // Предполагаем, что userId есть в useAuth
|
||||||
fromApp: true // Флаг, что событие от App.vue
|
fromApp: true // Флаг, что событие от App.vue
|
||||||
});
|
});
|
||||||
console.log('[App] auth-state-changed event emitted.');
|
// console.log('[App] auth-state-changed event emitted.');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[App] Error during auth action handling:", error);
|
// console.error("[App] Error during auth action handling:", error);
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false; // Скрываем индикатор загрузки
|
isLoading.value = false; // Скрываем индикатор загрузки
|
||||||
}
|
}
|
||||||
@@ -157,7 +157,7 @@
|
|||||||
|
|
||||||
// Подписываемся на событие изменения настроек аутентификации
|
// Подписываемся на событие изменения настроек аутентификации
|
||||||
const unsubscribe = eventBus.on('auth-settings-saved', () => {
|
const unsubscribe = eventBus.on('auth-settings-saved', () => {
|
||||||
console.log('[App] Получено событие сохранения настроек аутентификации, обновляем балансы');
|
// console.log('[App] Получено событие сохранения настроек аутентификации, обновляем балансы');
|
||||||
if (auth.isAuthenticated.value) {
|
if (auth.isAuthenticated.value) {
|
||||||
refreshTokenBalances();
|
refreshTokenBalances();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ api.interceptors.response.use(
|
|||||||
// Проверяем, что ответ действительно JSON
|
// Проверяем, что ответ действительно JSON
|
||||||
if (response.headers['content-type'] &&
|
if (response.headers['content-type'] &&
|
||||||
!response.headers['content-type'].includes('application/json')) {
|
!response.headers['content-type'].includes('application/json')) {
|
||||||
console.warn('Server returned non-JSON response:', response.headers['content-type']);
|
// console.warn('Server returned non-JSON response:', response.headers['content-type']);
|
||||||
// Если это HTML, значит, запрос ушёл не туда
|
// Если это HTML, значит, запрос ушёл не туда
|
||||||
if (response.headers['content-type'].includes('text/html')) {
|
if (response.headers['content-type'].includes('text/html')) {
|
||||||
throw new Error('Server returned HTML instead of JSON. Check API endpoint.');
|
throw new Error('Server returned HTML instead of JSON. Check API endpoint.');
|
||||||
@@ -50,7 +50,7 @@ api.interceptors.response.use(
|
|||||||
if (error.response && error.response.data &&
|
if (error.response && error.response.data &&
|
||||||
typeof error.response.data === 'string' &&
|
typeof error.response.data === 'string' &&
|
||||||
error.response.data.includes('<!DOCTYPE')) {
|
error.response.data.includes('<!DOCTYPE')) {
|
||||||
console.error('API Error: Server returned HTML instead of JSON');
|
// console.error('API Error: Server returned HTML instead of JSON');
|
||||||
error.message = 'Ошибка: сервер вернул HTML вместо JSON. Проверьте подключение к API.';
|
error.message = 'Ошибка: сервер вернул HTML вместо JSON. Проверьте подключение к API.';
|
||||||
}
|
}
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
@@ -65,7 +65,7 @@ const sendGuestMessageToServer = async (messageText) => {
|
|||||||
// language: userLanguage.value, // TODO: Реализовать получение языка пользователя
|
// language: userLanguage.value, // TODO: Реализовать получение языка пользователя
|
||||||
}, { withCredentials: true });
|
}, { withCredentials: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при отправке гостевого сообщения на сервер:', error);
|
// console.error('Ошибка при отправке гостевого сообщения на сервер:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ export default {
|
|||||||
stats.value = response.data.data
|
stats.value = response.data.data
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching queue stats:', error)
|
// console.error('Error fetching queue stats:', error)
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
@@ -210,7 +210,7 @@ export default {
|
|||||||
await fetchStats()
|
await fetchStats()
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error controlling queue (${action}):`, error)
|
// console.error(`Error controlling queue (${action}):`, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ const emit = defineEmits(['auth-action-completed']);
|
|||||||
|
|
||||||
// Callback после успешной аутентификации/привязки через Email/Telegram
|
// Callback после успешной аутентификации/привязки через Email/Telegram
|
||||||
const handleAuthFlowSuccess = (authType) => {
|
const handleAuthFlowSuccess = (authType) => {
|
||||||
console.log(`[BaseLayout] Auth flow success: ${authType}`);
|
// console.log(`[BaseLayout] Auth flow success: ${authType}`);
|
||||||
// Отправляем событие для обновления данных на страницах
|
// Отправляем событие для обновления данных на страницах
|
||||||
eventBus.emit('auth-success', { authType });
|
eventBus.emit('auth-success', { authType });
|
||||||
};
|
};
|
||||||
@@ -116,7 +116,7 @@ const handleWalletAuth = async () => {
|
|||||||
isConnectingWallet.value = true;
|
isConnectingWallet.value = true;
|
||||||
try {
|
try {
|
||||||
const result = await connectWithWallet();
|
const result = await connectWithWallet();
|
||||||
console.log('[BaseLayout] Результат подключения кошелька:', result);
|
// console.log('[BaseLayout] Результат подключения кошелька:', result);
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
if (auth.isAuthenticated.value) {
|
if (auth.isAuthenticated.value) {
|
||||||
@@ -132,7 +132,7 @@ const handleWalletAuth = async () => {
|
|||||||
// Новая аутентификация через кошелек
|
// Новая аутентификация через кошелек
|
||||||
const authResponse = await auth.checkAuth();
|
const authResponse = await auth.checkAuth();
|
||||||
if (authResponse.authenticated && authResponse.authType === 'wallet') {
|
if (authResponse.authenticated && authResponse.authType === 'wallet') {
|
||||||
console.log('[BaseLayout] Кошелёк успешно подключен и аутентифицирован');
|
// console.log('[BaseLayout] Кошелёк успешно подключен и аутентифицирован');
|
||||||
showSuccessMessage('Кошелёк успешно подключен!');
|
showSuccessMessage('Кошелёк успешно подключен!');
|
||||||
emit('auth-action-completed');
|
emit('auth-action-completed');
|
||||||
} else {
|
} else {
|
||||||
@@ -140,11 +140,11 @@ const handleWalletAuth = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('[BaseLayout] Не удалось подключить кошелёк:', result.error);
|
// console.error('[BaseLayout] Не удалось подключить кошелёк:', result.error);
|
||||||
showErrorMessage(result.error || 'Не удалось подключить кошелёк');
|
showErrorMessage(result.error || 'Не удалось подключить кошелёк');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[BaseLayout] Ошибка при подключении кошелька:', error);
|
// console.error('[BaseLayout] Ошибка при подключении кошелька:', error);
|
||||||
showErrorMessage('Произошла ошибка при подключении кошелька');
|
showErrorMessage('Произошла ошибка при подключении кошелька');
|
||||||
} finally {
|
} finally {
|
||||||
isConnectingWallet.value = false;
|
isConnectingWallet.value = false;
|
||||||
@@ -155,7 +155,7 @@ const handleWalletAuth = async () => {
|
|||||||
* Выполняет выход из аккаунта
|
* Выполняет выход из аккаунта
|
||||||
*/
|
*/
|
||||||
const disconnectWallet = async () => {
|
const disconnectWallet = async () => {
|
||||||
console.log('[BaseLayout] Выполняется выход из системы...');
|
// console.log('[BaseLayout] Выполняется выход из системы...');
|
||||||
try {
|
try {
|
||||||
await api.post('/auth/logout');
|
await api.post('/auth/logout');
|
||||||
showSuccessMessage('Вы успешно вышли из системы');
|
showSuccessMessage('Вы успешно вышли из системы');
|
||||||
@@ -163,7 +163,7 @@ const disconnectWallet = async () => {
|
|||||||
removeFromStorage('hasUserSentMessage');
|
removeFromStorage('hasUserSentMessage');
|
||||||
emit('auth-action-completed');
|
emit('auth-action-completed');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[BaseLayout] Ошибка при выходе из системы:', error);
|
// console.error('[BaseLayout] Ошибка при выходе из системы:', error);
|
||||||
showErrorMessage('Произошла ошибка при выходе из системы');
|
showErrorMessage('Произошла ошибка при выходе из системы');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -181,7 +181,7 @@ const toggleWalletSidebar = () => {
|
|||||||
// =====================================================================
|
// =====================================================================
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log('[BaseLayout] Компонент загружен');
|
// console.log('[BaseLayout] Компонент загружен');
|
||||||
|
|
||||||
// Загружаем сохраненное состояние боковой панели
|
// Загружаем сохраненное состояние боковой панели
|
||||||
const savedSidebarState = getFromStorage('showWalletSidebar');
|
const savedSidebarState = getFromStorage('showWalletSidebar');
|
||||||
|
|||||||
@@ -166,26 +166,26 @@ const videoStream = ref(null);
|
|||||||
const recordedAudioChunks = ref([]);
|
const recordedAudioChunks = ref([]);
|
||||||
const recordedVideoChunks = ref([]);
|
const recordedVideoChunks = ref([]);
|
||||||
|
|
||||||
const startAudioRecording = async () => {
|
const startAudioRecording = async () => {
|
||||||
console.log('[ChatInterface] startAudioRecording called');
|
// console.log('[ChatInterface] startAudioRecording called');
|
||||||
try {
|
try {
|
||||||
if (isAudioRecording.value) return;
|
if (isAudioRecording.value) return;
|
||||||
audioStream.value = await navigator.mediaDevices.getUserMedia({ audio: true });
|
audioStream.value = await navigator.mediaDevices.getUserMedia({ audio: true });
|
||||||
console.log('[ChatInterface] Got audio stream:', audioStream.value);
|
// console.log('[ChatInterface] Got audio stream:', audioStream.value);
|
||||||
recordedAudioChunks.value = [];
|
recordedAudioChunks.value = [];
|
||||||
audioRecorder.value = new MediaRecorder(audioStream.value);
|
audioRecorder.value = new MediaRecorder(audioStream.value);
|
||||||
audioRecorder.value.ondataavailable = (event) => {
|
audioRecorder.value.ondataavailable = (event) => {
|
||||||
console.log('[ChatInterface] audioRecorder.ondataavailable fired');
|
// console.log('[ChatInterface] audioRecorder.ondataavailable fired');
|
||||||
if (event.data.size > 0) recordedAudioChunks.value.push(event.data);
|
if (event.data.size > 0) recordedAudioChunks.value.push(event.data);
|
||||||
};
|
};
|
||||||
audioRecorder.value.onstop = () => {
|
audioRecorder.value.onstop = () => {
|
||||||
console.log('[ChatInterface] audioRecorder.onstop fired');
|
// console.log('[ChatInterface] audioRecorder.onstop fired');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (recordedAudioChunks.value.length === 0) {
|
if (recordedAudioChunks.value.length === 0) {
|
||||||
console.warn('[ChatInterface] No audio chunks recorded.');
|
// console.warn('[ChatInterface] No audio chunks recorded.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log(`[ChatInterface] Creating audio Blob from ${recordedAudioChunks.value.length} chunks.`);
|
// console.log(`[ChatInterface] Creating audio Blob from ${recordedAudioChunks.value.length} chunks.`);
|
||||||
const audioBlob = new Blob(recordedAudioChunks.value, { type: 'audio/webm' });
|
const audioBlob = new Blob(recordedAudioChunks.value, { type: 'audio/webm' });
|
||||||
const audioFile = new File([audioBlob], `audio-${Date.now()}.webm`, { type: 'audio/webm' });
|
const audioFile = new File([audioBlob], `audio-${Date.now()}.webm`, { type: 'audio/webm' });
|
||||||
addAttachment(audioFile);
|
addAttachment(audioFile);
|
||||||
@@ -194,64 +194,64 @@ const startAudioRecording = async () => {
|
|||||||
};
|
};
|
||||||
audioRecorder.value.start();
|
audioRecorder.value.start();
|
||||||
isAudioRecording.value = true;
|
isAudioRecording.value = true;
|
||||||
console.log('[ChatInterface] Audio recording started, recorder state:', audioRecorder.value.state);
|
// console.log('[ChatInterface] Audio recording started, recorder state:', audioRecorder.value.state);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[ChatInterface] Error starting audio recording:', error);
|
// console.error('[ChatInterface] Error starting audio recording:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const stopAudioRecording = async () => {
|
const stopAudioRecording = async () => {
|
||||||
console.log('[ChatInterface] stopAudioRecording called');
|
// console.log('[ChatInterface] stopAudioRecording called');
|
||||||
if (!isAudioRecording.value || !audioRecorder.value || audioRecorder.value.state === 'inactive') {
|
if (!isAudioRecording.value || !audioRecorder.value || audioRecorder.value.state === 'inactive') {
|
||||||
console.log('[ChatInterface] stopAudioRecording: Not recording or recorder inactive, state:', audioRecorder.value?.state);
|
// console.log('[ChatInterface] stopAudioRecording: Not recording or recorder inactive, state:', audioRecorder.value?.state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
audioRecorder.value.stop();
|
audioRecorder.value.stop();
|
||||||
console.log('[ChatInterface] audioRecorder.stop() called');
|
// console.log('[ChatInterface] audioRecorder.stop() called');
|
||||||
isAudioRecording.value = false;
|
isAudioRecording.value = false;
|
||||||
if (audioStream.value) {
|
if (audioStream.value) {
|
||||||
audioStream.value.getTracks().forEach(track => track.stop());
|
audioStream.value.getTracks().forEach(track => track.stop());
|
||||||
console.log('[ChatInterface] Audio stream tracks stopped.');
|
// console.log('[ChatInterface] Audio stream tracks stopped.');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[ChatInterface] Error stopping audio recording:', error);
|
// console.error('[ChatInterface] Error stopping audio recording:', error);
|
||||||
isAudioRecording.value = false;
|
isAudioRecording.value = false;
|
||||||
if (audioStream.value) audioStream.value.getTracks().forEach(track => track.stop());
|
if (audioStream.value) audioStream.value.getTracks().forEach(track => track.stop());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const startVideoRecording = async () => {
|
const startVideoRecording = async () => {
|
||||||
console.log('[ChatInterface] startVideoRecording called');
|
// console.log('[ChatInterface] startVideoRecording called');
|
||||||
try {
|
try {
|
||||||
if (isVideoRecording.value) return;
|
if (isVideoRecording.value) return;
|
||||||
videoStream.value = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
|
videoStream.value = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
|
||||||
console.log('[ChatInterface] Got video stream:', videoStream.value);
|
// console.log('[ChatInterface] Got video stream:', videoStream.value);
|
||||||
recordedVideoChunks.value = [];
|
recordedVideoChunks.value = [];
|
||||||
let options = { mimeType: 'video/webm;codecs=vp9,opus' };
|
let options = { mimeType: 'video/webm;codecs=vp9,opus' };
|
||||||
if (!MediaRecorder.isTypeSupported(options.mimeType)) {
|
if (!MediaRecorder.isTypeSupported(options.mimeType)) {
|
||||||
console.warn(`MIME type ${options.mimeType} not supported, trying video/webm...`);
|
// console.warn(`MIME type ${options.mimeType} not supported, trying video/webm...`);
|
||||||
options = { mimeType: 'video/webm' };
|
options = { mimeType: 'video/webm' };
|
||||||
if (!MediaRecorder.isTypeSupported(options.mimeType)) {
|
if (!MediaRecorder.isTypeSupported(options.mimeType)) {
|
||||||
console.warn(`MIME type ${options.mimeType} not supported, using default.`);
|
// console.warn(`MIME type ${options.mimeType} not supported, using default.`);
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('[ChatInterface] Using MediaRecorder options:', options);
|
// console.log('[ChatInterface] Using MediaRecorder options:', options);
|
||||||
videoRecorder.value = new MediaRecorder(videoStream.value, options);
|
videoRecorder.value = new MediaRecorder(videoStream.value, options);
|
||||||
|
|
||||||
videoRecorder.value.ondataavailable = (event) => {
|
videoRecorder.value.ondataavailable = (event) => {
|
||||||
console.log('[ChatInterface] videoRecorder.ondataavailable fired');
|
// console.log('[ChatInterface] videoRecorder.ondataavailable fired');
|
||||||
if (event.data.size > 0) recordedVideoChunks.value.push(event.data);
|
if (event.data.size > 0) recordedVideoChunks.value.push(event.data);
|
||||||
};
|
};
|
||||||
videoRecorder.value.onstop = () => {
|
videoRecorder.value.onstop = () => {
|
||||||
console.log('[ChatInterface] videoRecorder.onstop fired');
|
// console.log('[ChatInterface] videoRecorder.onstop fired');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (recordedVideoChunks.value.length === 0) {
|
if (recordedVideoChunks.value.length === 0) {
|
||||||
console.warn('[ChatInterface] No video chunks recorded.');
|
// console.warn('[ChatInterface] No video chunks recorded.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log(`[ChatInterface] Creating video Blob from ${recordedVideoChunks.value.length} chunks.`);
|
// console.log(`[ChatInterface] Creating video Blob from ${recordedVideoChunks.value.length} chunks.`);
|
||||||
const videoBlob = new Blob(recordedVideoChunks.value, { type: videoRecorder.value.mimeType || 'video/webm' });
|
const videoBlob = new Blob(recordedVideoChunks.value, { type: videoRecorder.value.mimeType || 'video/webm' });
|
||||||
const videoFile = new File([videoBlob], `video-${Date.now()}.webm`, { type: videoRecorder.value.mimeType || 'video/webm' });
|
const videoFile = new File([videoBlob], `video-${Date.now()}.webm`, { type: videoRecorder.value.mimeType || 'video/webm' });
|
||||||
addAttachment(videoFile);
|
addAttachment(videoFile);
|
||||||
@@ -260,28 +260,28 @@ const startVideoRecording = async () => {
|
|||||||
};
|
};
|
||||||
videoRecorder.value.start();
|
videoRecorder.value.start();
|
||||||
isVideoRecording.value = true;
|
isVideoRecording.value = true;
|
||||||
console.log('[ChatInterface] Video recording started, recorder state:', videoRecorder.value.state);
|
// console.log('[ChatInterface] Video recording started, recorder state:', videoRecorder.value.state);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[ChatInterface] Error starting video recording:', error);
|
// console.error('[ChatInterface] Error starting video recording:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const stopVideoRecording = async () => {
|
const stopVideoRecording = async () => {
|
||||||
console.log('[ChatInterface] stopVideoRecording called');
|
// console.log('[ChatInterface] stopVideoRecording called');
|
||||||
if (!isVideoRecording.value || !videoRecorder.value || videoRecorder.value.state === 'inactive') {
|
if (!isVideoRecording.value || !videoRecorder.value || videoRecorder.value.state === 'inactive') {
|
||||||
console.log('[ChatInterface] stopVideoRecording: Not recording or recorder inactive, state:', videoRecorder.value?.state);
|
// console.log('[ChatInterface] stopVideoRecording: Not recording or recorder inactive, state:', videoRecorder.value?.state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
videoRecorder.value.stop();
|
videoRecorder.value.stop();
|
||||||
console.log('[ChatInterface] videoRecorder.stop() called');
|
// console.log('[ChatInterface] videoRecorder.stop() called');
|
||||||
isVideoRecording.value = false;
|
isVideoRecording.value = false;
|
||||||
if (videoStream.value) {
|
if (videoStream.value) {
|
||||||
videoStream.value.getTracks().forEach(track => track.stop());
|
videoStream.value.getTracks().forEach(track => track.stop());
|
||||||
console.log('[ChatInterface] Video stream tracks stopped.');
|
// console.log('[ChatInterface] Video stream tracks stopped.');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[ChatInterface] Error stopping video recording:', error);
|
// console.error('[ChatInterface] Error stopping video recording:', error);
|
||||||
isVideoRecording.value = false;
|
isVideoRecording.value = false;
|
||||||
if (videoStream.value) videoStream.value.getTracks().forEach(track => track.stop());
|
if (videoStream.value) videoStream.value.getTracks().forEach(track => track.stop());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ async function deleteMessagesSelected() {
|
|||||||
deletedConversations += result.deletedConversations || 0;
|
deletedConversations += result.deletedConversations || 0;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Ошибка при удалении сообщений для контакта ${id}:`, error);
|
// console.error(`Ошибка при удалении сообщений для контакта ${id}:`, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ const connectToDLE = async () => {
|
|||||||
connectionStatus.value = 'connecting';
|
connectionStatus.value = 'connecting';
|
||||||
|
|
||||||
// Здесь будет подключение к DLE через Web3
|
// Здесь будет подключение к DLE через Web3
|
||||||
console.log('Подключение к DLE:', props.dleAddress);
|
// console.log('Подключение к DLE:', props.dleAddress);
|
||||||
|
|
||||||
// Имитация подключения
|
// Имитация подключения
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
@@ -252,7 +252,7 @@ const connectToDLE = async () => {
|
|||||||
|
|
||||||
connectionStatus.value = 'connected';
|
connectionStatus.value = 'connected';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка подключения к DLE:', error);
|
// console.error('Ошибка подключения к DLE:', error);
|
||||||
connectionStatus.value = 'error';
|
connectionStatus.value = 'error';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -312,7 +312,7 @@ const loadDLEData = async () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка загрузки данных DLE:', error);
|
// console.error('Ошибка загрузки данных DLE:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -351,7 +351,7 @@ const signProposal = async (proposalId) => {
|
|||||||
isSigning.value = true;
|
isSigning.value = true;
|
||||||
|
|
||||||
// Здесь будет подписание предложения
|
// Здесь будет подписание предложения
|
||||||
console.log('Подписание предложения:', proposalId);
|
// console.log('Подписание предложения:', proposalId);
|
||||||
|
|
||||||
const proposal = proposals.value.find(p => p.id === proposalId);
|
const proposal = proposals.value.find(p => p.id === proposalId);
|
||||||
if (proposal) {
|
if (proposal) {
|
||||||
@@ -362,7 +362,7 @@ const signProposal = async (proposalId) => {
|
|||||||
emit('proposal-signed', { proposalId, dleAddress: props.dleAddress });
|
emit('proposal-signed', { proposalId, dleAddress: props.dleAddress });
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка подписания предложения:', error);
|
// console.error('Ошибка подписания предложения:', error);
|
||||||
} finally {
|
} finally {
|
||||||
isSigning.value = false;
|
isSigning.value = false;
|
||||||
}
|
}
|
||||||
@@ -375,7 +375,7 @@ const executeProposal = async (proposalId) => {
|
|||||||
isExecuting.value = true;
|
isExecuting.value = true;
|
||||||
|
|
||||||
// Здесь будет выполнение предложения
|
// Здесь будет выполнение предложения
|
||||||
console.log('Выполнение предложения:', proposalId);
|
// console.log('Выполнение предложения:', proposalId);
|
||||||
|
|
||||||
const proposal = proposals.value.find(p => p.id === proposalId);
|
const proposal = proposals.value.find(p => p.id === proposalId);
|
||||||
if (proposal) {
|
if (proposal) {
|
||||||
@@ -385,7 +385,7 @@ const executeProposal = async (proposalId) => {
|
|||||||
emit('proposal-executed', { proposalId, dleAddress: props.dleAddress });
|
emit('proposal-executed', { proposalId, dleAddress: props.dleAddress });
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка выполнения предложения:', error);
|
// console.error('Ошибка выполнения предложения:', error);
|
||||||
} finally {
|
} finally {
|
||||||
isExecuting.value = false;
|
isExecuting.value = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ onMounted(() => {
|
|||||||
// Следим за изменениями авторизации и сообщаем о них через eventBus
|
// Следим за изменениями авторизации и сообщаем о них через eventBus
|
||||||
unwatch = watch(isAuthenticated, (newValue, oldValue) => {
|
unwatch = watch(isAuthenticated, (newValue, oldValue) => {
|
||||||
if (newValue !== oldValue) {
|
if (newValue !== oldValue) {
|
||||||
console.log('[Header] Состояние аутентификации изменилось:', newValue);
|
// console.log('[Header] Состояние аутентификации изменилось:', newValue);
|
||||||
// Оповещаем остальные компоненты через шину событий
|
// Оповещаем остальные компоненты через шину событий
|
||||||
eventBus.emit('auth-state-changed', {
|
eventBus.emit('auth-state-changed', {
|
||||||
isAuthenticated: newValue,
|
isAuthenticated: newValue,
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ const base64ToBlob = (base64, mimetype) => {
|
|||||||
const byteArray = new Uint8Array(byteNumbers);
|
const byteArray = new Uint8Array(byteNumbers);
|
||||||
return new Blob([byteArray], { type: mimetype });
|
return new Blob([byteArray], { type: mimetype });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Error decoding base64 string:", e);
|
// console.error("Error decoding base64 string:", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -161,7 +161,7 @@ const formattedTime = computed(() => {
|
|||||||
try {
|
try {
|
||||||
const date = new Date(timestamp);
|
const date = new Date(timestamp);
|
||||||
if (isNaN(date.getTime())) {
|
if (isNaN(date.getTime())) {
|
||||||
console.warn('Invalid timestamp in Message.vue:', timestamp);
|
// console.warn('Invalid timestamp in Message.vue:', timestamp);
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
return date.toLocaleString([], {
|
return date.toLocaleString([], {
|
||||||
@@ -172,7 +172,7 @@ const formattedTime = computed(() => {
|
|||||||
minute: '2-digit',
|
minute: '2-digit',
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error formatting time in Message.vue:', error, timestamp);
|
// console.error('Error formatting time in Message.vue:', error, timestamp);
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ async function checkConnection() {
|
|||||||
await loadInstalledModels();
|
await loadInstalledModels();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка проверки подключения:', error);
|
// console.error('Ошибка проверки подключения:', error);
|
||||||
isConnected.value = false;
|
isConnected.value = false;
|
||||||
} finally {
|
} finally {
|
||||||
checking.value = false;
|
checking.value = false;
|
||||||
@@ -148,7 +148,7 @@ async function loadInstalledModels() {
|
|||||||
const response = await axios.get('/ollama/models');
|
const response = await axios.get('/ollama/models');
|
||||||
installedModels.value = response.data.models || [];
|
installedModels.value = response.data.models || [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка загрузки моделей:', error);
|
// console.error('Ошибка загрузки моделей:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ async function searchModels() {
|
|||||||
// Пока просто устанавливаем модель напрямую
|
// Пока просто устанавливаем модель напрямую
|
||||||
await installModel(searchQuery.value.trim());
|
await installModel(searchQuery.value.trim());
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка поиска моделей:', error);
|
// console.error('Ошибка поиска моделей:', error);
|
||||||
} finally {
|
} finally {
|
||||||
searching.value = false;
|
searching.value = false;
|
||||||
}
|
}
|
||||||
@@ -176,7 +176,7 @@ async function installModel(modelName) {
|
|||||||
await loadInstalledModels();
|
await loadInstalledModels();
|
||||||
searchQuery.value = '';
|
searchQuery.value = '';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка установки модели:', error);
|
// console.error('Ошибка установки модели:', error);
|
||||||
} finally {
|
} finally {
|
||||||
installing.value = '';
|
installing.value = '';
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,7 @@ async function removeModel(modelName) {
|
|||||||
await axios.delete(`/ollama/models/${encodeURIComponent(modelName)}`);
|
await axios.delete(`/ollama/models/${encodeURIComponent(modelName)}`);
|
||||||
await loadInstalledModels();
|
await loadInstalledModels();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка удаления модели:', error);
|
// console.error('Ошибка удаления модели:', error);
|
||||||
} finally {
|
} finally {
|
||||||
removing.value = '';
|
removing.value = '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ const closeSidebar = () => {
|
|||||||
|
|
||||||
// Обработка события изменения авторизации
|
// Обработка события изменения авторизации
|
||||||
const handleAuthEvent = (event) => {
|
const handleAuthEvent = (event) => {
|
||||||
console.log('[Sidebar] Получено событие изменения авторизации:', event);
|
// console.log('[Sidebar] Получено событие изменения авторизации:', event);
|
||||||
// Здесь можно обновить данные, если нужно дополнительное обновление
|
// Здесь можно обновить данные, если нужно дополнительное обновление
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -239,11 +239,11 @@ const handleDeleteIdentity = async (provider, providerId) => {
|
|||||||
|
|
||||||
// Добавляем watch для отслеживания props
|
// Добавляем watch для отслеживания props
|
||||||
watch(() => props.tokenBalances, (newVal, oldVal) => {
|
watch(() => props.tokenBalances, (newVal, oldVal) => {
|
||||||
console.log('[Sidebar] tokenBalances prop changed:', JSON.stringify(newVal));
|
// console.log('[Sidebar] tokenBalances prop changed:', JSON.stringify(newVal));
|
||||||
}, { deep: true });
|
}, { deep: true });
|
||||||
|
|
||||||
watch(() => props.isLoadingTokens, (newVal, oldVal) => {
|
watch(() => props.isLoadingTokens, (newVal, oldVal) => {
|
||||||
console.log(`[Sidebar] isLoadingTokens prop changed: ${newVal}`);
|
// console.log(`[Sidebar] isLoadingTokens prop changed: ${newVal}`);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@
|
|||||||
error.value = result.error || 'Не удалось подключить кошелек';
|
error.value = result.error || 'Не удалось подключить кошелек';
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error connecting wallet:', err);
|
// console.error('Error connecting wallet:', err);
|
||||||
error.value = err.message || 'Произошла ошибка при подключении кошелька';
|
error.value = err.message || 'Произошла ошибка при подключении кошелька';
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ watch(editing, (val) => {
|
|||||||
// Добавляем watch для отслеживания изменений в мультисвязях с дебаунсингом
|
// Добавляем watch для отслеживания изменений в мультисвязях с дебаунсингом
|
||||||
let debounceTimer = null;
|
let debounceTimer = null;
|
||||||
watch(editMultiRelationValues, (newValues, oldValues) => {
|
watch(editMultiRelationValues, (newValues, oldValues) => {
|
||||||
console.log('[editMultiRelationValues] changed from:', oldValues, 'to:', newValues);
|
// console.log('[editMultiRelationValues] changed from:', oldValues, 'to:', newValues);
|
||||||
|
|
||||||
// Очищаем предыдущий таймер
|
// Очищаем предыдущий таймер
|
||||||
if (debounceTimer) {
|
if (debounceTimer) {
|
||||||
@@ -204,7 +204,7 @@ let unsubscribeFromWebSocket = null;
|
|||||||
// Функция для очистки кэша
|
// Функция для очистки кэша
|
||||||
function clearCache() {
|
function clearCache() {
|
||||||
cacheService.clearAll();
|
cacheService.clearAll();
|
||||||
console.log('[TableCell] Кэш очищен');
|
// console.log('[TableCell] Кэш очищен');
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebSocket для тегов
|
// WebSocket для тегов
|
||||||
@@ -223,7 +223,7 @@ let isMultiRelationValuesLoaded = false;
|
|||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
console.log(`[TableCell] 🚀 Начало монтирования ячейки row:${props.rowId} col:${props.column.id} в ${startTime}`);
|
// console.log(`[TableCell] 🚀 Начало монтирования ячейки row:${props.rowId} col:${props.column.id} в ${startTime}`);
|
||||||
|
|
||||||
if (props.column.type === 'multiselect') {
|
if (props.column.type === 'multiselect') {
|
||||||
multiOptions.value = (props.column.options && props.column.options.options) || [];
|
multiOptions.value = (props.column.options && props.column.options.options) || [];
|
||||||
@@ -250,14 +250,14 @@ onMounted(async () => {
|
|||||||
} else if (props.column.type === 'multiselect-relation') {
|
} else if (props.column.type === 'multiselect-relation') {
|
||||||
// Загружаем опции только один раз
|
// Загружаем опции только один раз
|
||||||
if (!isInitialized) {
|
if (!isInitialized) {
|
||||||
console.log(`[TableCell] 📥 Загружаем опции для row:${props.rowId} col:${props.column.id}`);
|
// console.log(`[TableCell] 📥 Загружаем опции для row:${props.rowId} col:${props.column.id}`);
|
||||||
await loadMultiRelationOptions();
|
await loadMultiRelationOptions();
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Загружаем relations только один раз для каждой комбинации rowId + columnId
|
// Загружаем relations только один раз для каждой комбинации rowId + columnId
|
||||||
if (!isMultiRelationValuesLoaded) {
|
if (!isMultiRelationValuesLoaded) {
|
||||||
console.log(`[TableCell] 📥 Загружаем relations для row:${props.rowId} col:${props.column.id}`);
|
// console.log(`[TableCell] 📥 Загружаем relations для row:${props.rowId} col:${props.column.id}`);
|
||||||
await loadMultiRelationValues();
|
await loadMultiRelationValues();
|
||||||
isMultiRelationValuesLoaded = true;
|
isMultiRelationValuesLoaded = true;
|
||||||
}
|
}
|
||||||
@@ -265,7 +265,7 @@ onMounted(async () => {
|
|||||||
// Подписываемся на обновления таблицы
|
// Подписываемся на обновления таблицы
|
||||||
if (props.column.type === 'multiselect-relation') {
|
if (props.column.type === 'multiselect-relation') {
|
||||||
unsubscribeFromWebSocket = subscribeToTableRelationsUpdates(props.column.table_id, async () => {
|
unsubscribeFromWebSocket = subscribeToTableRelationsUpdates(props.column.table_id, async () => {
|
||||||
console.log('[TableCell] Получено обновление таблицы, перезагружаем relations');
|
// console.log('[TableCell] Получено обновление таблицы, перезагружаем relations');
|
||||||
// Сбрасываем флаг загрузки
|
// Сбрасываем флаг загрузки
|
||||||
isMultiRelationValuesLoaded = false;
|
isMultiRelationValuesLoaded = false;
|
||||||
// Очищаем кэш relations для текущей строки
|
// Очищаем кэш relations для текущей строки
|
||||||
@@ -277,7 +277,7 @@ onMounted(async () => {
|
|||||||
// Подписываемся на обновления тегов, если это связанная таблица тегов
|
// Подписываемся на обновления тегов, если это связанная таблица тегов
|
||||||
if (props.column.options && props.column.options.relatedTableId) {
|
if (props.column.options && props.column.options.relatedTableId) {
|
||||||
unsubscribeFromTags = onTagsUpdate(async () => {
|
unsubscribeFromTags = onTagsUpdate(async () => {
|
||||||
console.log('[TableCell] Получено обновление тегов, перезагружаем опции');
|
// console.log('[TableCell] Получено обновление тегов, перезагружаем опции');
|
||||||
// Сбрасываем флаги загрузки
|
// Сбрасываем флаги загрузки
|
||||||
isInitialized = false;
|
isInitialized = false;
|
||||||
isMultiRelationValuesLoaded = false;
|
isMultiRelationValuesLoaded = false;
|
||||||
@@ -300,7 +300,7 @@ onMounted(async () => {
|
|||||||
localValue.value = cell ? cell.value : '';
|
localValue.value = cell ? cell.value : '';
|
||||||
}
|
}
|
||||||
const endTime = Date.now();
|
const endTime = Date.now();
|
||||||
console.log(`[TableCell] ✅ Завершено монтирование ячейки row:${props.rowId} col:${props.column.id} за ${endTime - startTime}ms`);
|
// console.log(`[TableCell] ✅ Завершено монтирование ячейки row:${props.rowId} col:${props.column.id} за ${endTime - startTime}ms`);
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
@@ -487,7 +487,7 @@ async function loadLookupValues() {
|
|||||||
async function loadMultiRelationOptions() {
|
async function loadMultiRelationOptions() {
|
||||||
// Проверяем, не загружены ли уже опции
|
// Проверяем, не загружены ли уже опции
|
||||||
if (multiRelationOptions.value.length > 0) {
|
if (multiRelationOptions.value.length > 0) {
|
||||||
console.log('[loadMultiRelationOptions] Опции уже загружены, пропускаем');
|
// console.log('[loadMultiRelationOptions] Опции уже загружены, пропускаем');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,10 +499,10 @@ async function loadMultiRelationOptions() {
|
|||||||
let tableData;
|
let tableData;
|
||||||
|
|
||||||
if (cachedTableData) {
|
if (cachedTableData) {
|
||||||
console.log(`[loadMultiRelationOptions] ✅ Используем предварительно загруженные данные таблицы ${rel.relatedTableId}`);
|
// console.log(`[loadMultiRelationOptions] ✅ Используем предварительно загруженные данные таблицы ${rel.relatedTableId}`);
|
||||||
tableData = cachedTableData;
|
tableData = cachedTableData;
|
||||||
} else {
|
} else {
|
||||||
console.log(`[loadMultiRelationOptions] ⚠️ Данные таблицы ${rel.relatedTableId} не найдены в кэше, загружаем заново`);
|
// console.log(`[loadMultiRelationOptions] ⚠️ Данные таблицы ${rel.relatedTableId} не найдены в кэше, загружаем заново`);
|
||||||
const response = await fetch(`/api/tables/${rel.relatedTableId}`);
|
const response = await fetch(`/api/tables/${rel.relatedTableId}`);
|
||||||
tableData = await response.json();
|
tableData = await response.json();
|
||||||
// Сохраняем в кэш
|
// Сохраняем в кэш
|
||||||
@@ -517,9 +517,9 @@ async function loadMultiRelationOptions() {
|
|||||||
opts.push({ id: row.id, display: cell ? cell.value : `ID ${row.id}` });
|
opts.push({ id: row.id, display: cell ? cell.value : `ID ${row.id}` });
|
||||||
}
|
}
|
||||||
multiRelationOptions.value = opts;
|
multiRelationOptions.value = opts;
|
||||||
console.log(`[loadMultiRelationOptions] Загружено ${opts.length} опций для таблицы ${rel.relatedTableId}`);
|
// console.log(`[loadMultiRelationOptions] Загружено ${opts.length} опций для таблицы ${rel.relatedTableId}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[loadMultiRelationOptions] Error:', e);
|
// console.error('[loadMultiRelationOptions] Error:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -531,7 +531,7 @@ const LOAD_DEBOUNCE_DELAY = 50; // 50ms (уменьшено для ускоре
|
|||||||
async function loadMultiRelationValues() {
|
async function loadMultiRelationValues() {
|
||||||
// Проверяем, не загружены ли уже данные
|
// Проверяем, не загружены ли уже данные
|
||||||
if (isMultiRelationValuesLoaded) {
|
if (isMultiRelationValuesLoaded) {
|
||||||
console.log('[loadMultiRelationValues] Данные уже загружены, пропускаем');
|
// console.log('[loadMultiRelationValues] Данные уже загружены, пропускаем');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,7 +543,7 @@ async function loadMultiRelationValues() {
|
|||||||
// Устанавливаем новый таймер
|
// Устанавливаем новый таймер
|
||||||
loadMultiRelationValuesTimer = setTimeout(async () => {
|
loadMultiRelationValuesTimer = setTimeout(async () => {
|
||||||
// Получаем связи для текущей строки
|
// Получаем связи для текущей строки
|
||||||
console.log('[loadMultiRelationValues] called for row:', props.rowId, 'column:', props.column.id);
|
// console.log('[loadMultiRelationValues] called for row:', props.rowId, 'column:', props.column.id);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const rel = props.column.options || {};
|
const rel = props.column.options || {};
|
||||||
@@ -554,10 +554,10 @@ async function loadMultiRelationValues() {
|
|||||||
|
|
||||||
const cachedRelations = cacheService.getRelationsData(props.rowId, props.column.id);
|
const cachedRelations = cacheService.getRelationsData(props.rowId, props.column.id);
|
||||||
if (cachedRelations) {
|
if (cachedRelations) {
|
||||||
console.log('[loadMultiRelationValues] ✅ Используем предварительно загруженные relations для строки', props.rowId);
|
// console.log('[loadMultiRelationValues] ✅ Используем предварительно загруженные relations для строки', props.rowId);
|
||||||
relations = cachedRelations;
|
relations = cachedRelations;
|
||||||
} else {
|
} else {
|
||||||
console.log('[loadMultiRelationValues] ⚠️ Relations не найдены в кэше, загружаем заново для строки', props.rowId);
|
// console.log('[loadMultiRelationValues] ⚠️ Relations не найдены в кэше, загружаем заново для строки', props.rowId);
|
||||||
// Выполняем запросы параллельно
|
// Выполняем запросы параллельно
|
||||||
const [relationsRes, tableRes] = await Promise.all([
|
const [relationsRes, tableRes] = await Promise.all([
|
||||||
fetch(`/api/tables/${props.column.table_id}/row/${props.rowId}/relations`),
|
fetch(`/api/tables/${props.column.table_id}/row/${props.rowId}/relations`),
|
||||||
@@ -573,13 +573,13 @@ async function loadMultiRelationValues() {
|
|||||||
cacheService.setRelationsData(props.rowId, props.column.id, relations);
|
cacheService.setRelationsData(props.rowId, props.column.id, relations);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[loadMultiRelationValues] API response status: 200 relations:', relations);
|
// console.log('[loadMultiRelationValues] API response status: 200 relations:', relations);
|
||||||
|
|
||||||
// Приводим все id к строке для корректного сравнения
|
// Приводим все id к строке для корректного сравнения
|
||||||
const relatedRowIds = relations
|
const relatedRowIds = relations
|
||||||
.filter(r => String(r.column_id) === String(props.column.id) && String(r.to_table_id) === String(rel.relatedTableId))
|
.filter(r => String(r.column_id) === String(props.column.id) && String(r.to_table_id) === String(rel.relatedTableId))
|
||||||
.map(r => String(r.to_row_id));
|
.map(r => String(r.to_row_id));
|
||||||
console.log('[loadMultiRelationValues] filtered related row ids:', relatedRowIds);
|
// console.log('[loadMultiRelationValues] filtered related row ids:', relatedRowIds);
|
||||||
|
|
||||||
// Обновляем значения
|
// Обновляем значения
|
||||||
editMultiRelationValues.value = relatedRowIds;
|
editMultiRelationValues.value = relatedRowIds;
|
||||||
@@ -603,48 +603,48 @@ async function loadMultiRelationValues() {
|
|||||||
selectedMultiRelationNames.value = multiRelationOptions.value
|
selectedMultiRelationNames.value = multiRelationOptions.value
|
||||||
.filter(opt => relatedRowIds.includes(String(opt.id)))
|
.filter(opt => relatedRowIds.includes(String(opt.id)))
|
||||||
.map(opt => opt.display);
|
.map(opt => opt.display);
|
||||||
console.log('[loadMultiRelationValues] selectedMultiRelationNames:', selectedMultiRelationNames.value);
|
// console.log('[loadMultiRelationValues] selectedMultiRelationNames:', selectedMultiRelationNames.value);
|
||||||
|
|
||||||
// Отмечаем, что данные загружены
|
// Отмечаем, что данные загружены
|
||||||
isMultiRelationValuesLoaded = true;
|
isMultiRelationValuesLoaded = true;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[loadMultiRelationValues] Error:', e);
|
// console.error('[loadMultiRelationValues] Error:', e);
|
||||||
}
|
}
|
||||||
}, LOAD_DEBOUNCE_DELAY);
|
}, LOAD_DEBOUNCE_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveMultiRelation() {
|
async function saveMultiRelation() {
|
||||||
console.log('[saveMultiRelation] called');
|
// console.log('[saveMultiRelation] called');
|
||||||
const rel = props.column.options || {};
|
const rel = props.column.options || {};
|
||||||
console.log('[saveMultiRelation] editMultiRelationValues:', editMultiRelationValues.value);
|
// console.log('[saveMultiRelation] editMultiRelationValues:', editMultiRelationValues.value);
|
||||||
try {
|
try {
|
||||||
const payload = {
|
const payload = {
|
||||||
column_id: props.column.id,
|
column_id: props.column.id,
|
||||||
to_table_id: rel.relatedTableId,
|
to_table_id: rel.relatedTableId,
|
||||||
to_row_ids: editMultiRelationValues.value
|
to_row_ids: editMultiRelationValues.value
|
||||||
};
|
};
|
||||||
console.log('[saveMultiRelation] POST payload:', payload);
|
// console.log('[saveMultiRelation] POST payload:', payload);
|
||||||
console.log('[TableCell] Отправляем запрос на обновление relations для строки:', props.rowId);
|
// console.log('[TableCell] Отправляем запрос на обновление relations для строки:', props.rowId);
|
||||||
console.log('[TableCell] Данные запроса:', payload);
|
// console.log('[TableCell] Данные запроса:', payload);
|
||||||
const response = await fetch(`/api/tables/${props.column.table_id}/row/${props.rowId}/relations`, {
|
const response = await fetch(`/api/tables/${props.column.table_id}/row/${props.rowId}/relations`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(payload)
|
body: JSON.stringify(payload)
|
||||||
});
|
});
|
||||||
const result = await response.json().catch(() => ({}));
|
const result = await response.json().catch(() => ({}));
|
||||||
console.log('[TableCell] Ответ сервера для строки:', props.rowId, 'статус:', response.status, 'результат:', result);
|
// console.log('[TableCell] Ответ сервера для строки:', props.rowId, 'статус:', response.status, 'результат:', result);
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
console.log('[TableCell] Успешно сохранены теги для строки:', props.rowId);
|
// console.log('[TableCell] Успешно сохранены теги для строки:', props.rowId);
|
||||||
} else {
|
} else {
|
||||||
console.error('[TableCell] Ошибка сохранения тегов для строки:', props.rowId, 'статус:', response.status);
|
// console.error('[TableCell] Ошибка сохранения тегов для строки:', props.rowId, 'статус:', response.status);
|
||||||
}
|
}
|
||||||
editing.value = false;
|
editing.value = false;
|
||||||
await loadMultiRelationValues();
|
await loadMultiRelationValues();
|
||||||
console.log('[saveMultiRelation] emitting update with:', editMultiRelationValues.value);
|
// console.log('[saveMultiRelation] emitting update with:', editMultiRelationValues.value);
|
||||||
emit('update', editMultiRelationValues.value);
|
emit('update', editMultiRelationValues.value);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[saveMultiRelation] Ошибка при сохранении мультисвязи:', e);
|
// console.error('[saveMultiRelation] Ошибка при сохранении мультисвязи:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -653,7 +653,7 @@ async function addTag() {
|
|||||||
const rel = props.column.options || {};
|
const rel = props.column.options || {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('[addTag] Добавляем новый тег:', newTagName.value);
|
// console.log('[addTag] Добавляем новый тег:', newTagName.value);
|
||||||
|
|
||||||
// 1. Создаем новую пустую строку в связанной таблице
|
// 1. Создаем новую пустую строку в связанной таблице
|
||||||
const rowResponse = await fetch(`/api/tables/${rel.relatedTableId}/rows`, {
|
const rowResponse = await fetch(`/api/tables/${rel.relatedTableId}/rows`, {
|
||||||
@@ -662,7 +662,7 @@ async function addTag() {
|
|||||||
});
|
});
|
||||||
const newRow = await rowResponse.json();
|
const newRow = await rowResponse.json();
|
||||||
|
|
||||||
console.log('[addTag] Новая строка создана:', newRow);
|
// console.log('[addTag] Новая строка создана:', newRow);
|
||||||
|
|
||||||
// 2. Добавляем значение в ячейку через POST /cell
|
// 2. Добавляем значение в ячейку через POST /cell
|
||||||
const cellResponse = await fetch(`/api/tables/cell`, {
|
const cellResponse = await fetch(`/api/tables/cell`, {
|
||||||
@@ -676,7 +676,7 @@ async function addTag() {
|
|||||||
});
|
});
|
||||||
const cellResult = await cellResponse.json();
|
const cellResult = await cellResponse.json();
|
||||||
|
|
||||||
console.log('[addTag] Значение ячейки сохранено:', cellResult);
|
// console.log('[addTag] Значение ячейки сохранено:', cellResult);
|
||||||
|
|
||||||
// Очищаем форму
|
// Очищаем форму
|
||||||
newTagName.value = '';
|
newTagName.value = '';
|
||||||
@@ -688,12 +688,12 @@ async function addTag() {
|
|||||||
Promise.resolve(editMultiRelationValues.value.push(String(newRow.id)))
|
Promise.resolve(editMultiRelationValues.value.push(String(newRow.id)))
|
||||||
]);
|
]);
|
||||||
|
|
||||||
console.log('[addTag] Тег добавлен в выбранные:', editMultiRelationValues.value);
|
// console.log('[addTag] Тег добавлен в выбранные:', editMultiRelationValues.value);
|
||||||
|
|
||||||
// Сохраняем изменения, чтобы отправить WebSocket уведомление
|
// Сохраняем изменения, чтобы отправить WebSocket уведомление
|
||||||
await saveMultiRelation();
|
await saveMultiRelation();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[addTag] Ошибка при добавлении тега:', e);
|
// console.error('[addTag] Ошибка при добавлении тега:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -702,13 +702,13 @@ async function deleteTag(tagId) {
|
|||||||
if (!confirm('Удалить этот тег?')) return;
|
if (!confirm('Удалить этот тег?')) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('[deleteTag] Удаляем тег с ID:', tagId);
|
// console.log('[deleteTag] Удаляем тег с ID:', tagId);
|
||||||
|
|
||||||
// Удаляем тег из связанной таблицы
|
// Удаляем тег из связанной таблицы
|
||||||
const response = await fetch(`/api/tables/row/${tagId}`, { method: 'DELETE' });
|
const response = await fetch(`/api/tables/row/${tagId}`, { method: 'DELETE' });
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
console.log('[deleteTag] Ответ сервера:', response.status, result);
|
// console.log('[deleteTag] Ответ сервера:', response.status, result);
|
||||||
|
|
||||||
// Убираем тег из выбранных значений, если он был выбран
|
// Убираем тег из выбранных значений, если он был выбран
|
||||||
editMultiRelationValues.value = editMultiRelationValues.value.filter(id => String(id) !== String(tagId));
|
editMultiRelationValues.value = editMultiRelationValues.value.filter(id => String(id) !== String(tagId));
|
||||||
@@ -716,12 +716,12 @@ async function deleteTag(tagId) {
|
|||||||
// Обновляем список опций
|
// Обновляем список опций
|
||||||
await loadMultiRelationOptions();
|
await loadMultiRelationOptions();
|
||||||
|
|
||||||
console.log('[deleteTag] Тег удален:', tagId);
|
// console.log('[deleteTag] Тег удален:', tagId);
|
||||||
|
|
||||||
// Сохраняем изменения, чтобы отправить WebSocket уведомление
|
// Сохраняем изменения, чтобы отправить WebSocket уведомление
|
||||||
await saveMultiRelation();
|
await saveMultiRelation();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[deleteTag] Ошибка при удалении тега:', e);
|
// console.error('[deleteTag] Ошибка при удалении тега:', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -361,7 +361,7 @@ async function fetchFilteredRows() {
|
|||||||
params.append(def.filterKey, Array.isArray(val) ? val.join(',') : val);
|
params.append(def.filterKey, Array.isArray(val) ? val.join(',') : val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('fetchFilteredRows params:', params.toString()); // Для отладки
|
// console.log('fetchFilteredRows params:', params.toString()); // Для отладки
|
||||||
const data = await tablesService.getFilteredRows(props.tableId, params);
|
const data = await tablesService.getFilteredRows(props.tableId, params);
|
||||||
// Локальная фильтрация по multiselect-relation (если backend не фильтрует)
|
// Локальная фильтрация по multiselect-relation (если backend не фильтрует)
|
||||||
filteredRows.value = data.filter(row => {
|
filteredRows.value = data.filter(row => {
|
||||||
@@ -387,7 +387,7 @@ async function fetchFilteredRows() {
|
|||||||
// Основная загрузка таблицы
|
// Основная загрузка таблицы
|
||||||
async function fetchTable() {
|
async function fetchTable() {
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
console.log(`[UserTableView] 🚀 Начало загрузки таблицы ${props.tableId} в ${startTime}`);
|
// console.log(`[UserTableView] 🚀 Начало загрузки таблицы ${props.tableId} в ${startTime}`);
|
||||||
|
|
||||||
const data = await tablesService.getTable(props.tableId);
|
const data = await tablesService.getTable(props.tableId);
|
||||||
columns.value = data.columns;
|
columns.value = data.columns;
|
||||||
@@ -395,12 +395,12 @@ async function fetchTable() {
|
|||||||
cellValues.value = data.cellValues;
|
cellValues.value = data.cellValues;
|
||||||
tableMeta.value = { name: data.name, description: data.description };
|
tableMeta.value = { name: data.name, description: data.description };
|
||||||
|
|
||||||
console.log(`[UserTableView] 📊 Загружено ${rows.value.length} строк, ${columns.value.length} столбцов`);
|
// console.log(`[UserTableView] 📊 Загружено ${rows.value.length} строк, ${columns.value.length} столбцов`);
|
||||||
|
|
||||||
// Предварительно загружаем все relations для всех строк параллельно
|
// Предварительно загружаем все relations для всех строк параллельно
|
||||||
const relationColumns = columns.value.filter(col => col.type === 'multiselect-relation');
|
const relationColumns = columns.value.filter(col => col.type === 'multiselect-relation');
|
||||||
if (relationColumns.length > 0) {
|
if (relationColumns.length > 0) {
|
||||||
console.log(`[UserTableView] 🔄 Предварительно загружаем relations для ${relationColumns.length} столбцов`);
|
// console.log(`[UserTableView] 🔄 Предварительно загружаем relations для ${relationColumns.length} столбцов`);
|
||||||
|
|
||||||
const relationPromises = [];
|
const relationPromises = [];
|
||||||
for (const row of rows.value) {
|
for (const row of rows.value) {
|
||||||
@@ -413,7 +413,7 @@ async function fetchTable() {
|
|||||||
return { rowId: row.id, colId: col.id, relations };
|
return { rowId: row.id, colId: col.id, relations };
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error(`[UserTableView] Ошибка загрузки relations для row:${row.id} col:${col.id}:`, error);
|
// console.error(`[UserTableView] Ошибка загрузки relations для row:${row.id} col:${col.id}:`, error);
|
||||||
return { rowId: row.id, colId: col.id, relations: [] };
|
return { rowId: row.id, colId: col.id, relations: [] };
|
||||||
});
|
});
|
||||||
relationPromises.push(promise);
|
relationPromises.push(promise);
|
||||||
@@ -422,7 +422,7 @@ async function fetchTable() {
|
|||||||
|
|
||||||
// Ждем загрузки всех relations
|
// Ждем загрузки всех relations
|
||||||
const results = await Promise.all(relationPromises);
|
const results = await Promise.all(relationPromises);
|
||||||
console.log(`[UserTableView] ✅ Предварительно загружено ${results.length} relations`);
|
// console.log(`[UserTableView] ✅ Предварительно загружено ${results.length} relations`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Предварительно загружаем данные связанных таблиц для опций
|
// Предварительно загружаем данные связанных таблиц для опций
|
||||||
@@ -434,7 +434,7 @@ async function fetchTable() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (relatedTableIds.size > 0) {
|
if (relatedTableIds.size > 0) {
|
||||||
console.log(`[UserTableView] 🔄 Предварительно загружаем данные ${relatedTableIds.size} связанных таблиц для опций`);
|
// console.log(`[UserTableView] 🔄 Предварительно загружаем данные ${relatedTableIds.size} связанных таблиц для опций`);
|
||||||
|
|
||||||
const tablePromises = Array.from(relatedTableIds).map(tableId =>
|
const tablePromises = Array.from(relatedTableIds).map(tableId =>
|
||||||
fetch(`/api/tables/${tableId}`)
|
fetch(`/api/tables/${tableId}`)
|
||||||
@@ -445,13 +445,13 @@ async function fetchTable() {
|
|||||||
return { tableId, tableData };
|
return { tableId, tableData };
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error(`[UserTableView] Ошибка загрузки таблицы ${tableId}:`, error);
|
// console.error(`[UserTableView] Ошибка загрузки таблицы ${tableId}:`, error);
|
||||||
return { tableId, tableData: null };
|
return { tableId, tableData: null };
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const tableResults = await Promise.all(tablePromises);
|
const tableResults = await Promise.all(tablePromises);
|
||||||
console.log(`[UserTableView] ✅ Предварительно загружено ${tableResults.length} связанных таблиц`);
|
// console.log(`[UserTableView] ✅ Предварительно загружено ${tableResults.length} связанных таблиц`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Выполняем обновление фильтров и фильтрацию строк параллельно
|
// Выполняем обновление фильтров и фильтрацию строк параллельно
|
||||||
@@ -462,15 +462,15 @@ async function fetchTable() {
|
|||||||
|
|
||||||
// Выводим статистику кэша для отладки
|
// Выводим статистику кэша для отладки
|
||||||
const cacheStats = cacheService.getStats();
|
const cacheStats = cacheService.getStats();
|
||||||
console.log('[UserTableView] Статистика кэша после загрузки таблицы:', {
|
// console.log('[UserTableView] Статистика кэша после загрузки таблицы:', {
|
||||||
tableCacheSize: cacheStats.tableCacheSize,
|
// tableCacheSize: cacheStats.tableCacheSize,
|
||||||
relationsCacheSize: cacheStats.relationsCacheSize,
|
// relationsCacheSize: cacheStats.relationsCacheSize,
|
||||||
tableCacheKeys: cacheStats.tableCacheKeys,
|
// tableCacheKeys: cacheStats.tableCacheKeys,
|
||||||
relationsCacheKeys: cacheStats.relationsCacheKeys.slice(0, 5) // Показываем только первые 5 ключей
|
// relationsCacheKeys: cacheStats.relationsCacheKeys.slice(0, 5) // Показываем только первые 5 ключей
|
||||||
});
|
// });
|
||||||
|
|
||||||
const endTime = Date.now();
|
const endTime = Date.now();
|
||||||
console.log(`[UserTableView] ✅ Завершена загрузка таблицы ${props.tableId} за ${endTime - startTime}ms`);
|
// console.log(`[UserTableView] ✅ Завершена загрузка таблицы ${props.tableId} за ${endTime - startTime}ms`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateRelationFilterDefs() {
|
async function updateRelationFilterDefs() {
|
||||||
@@ -485,7 +485,7 @@ async function updateRelationFilterDefs() {
|
|||||||
// Проверяем кэш
|
// Проверяем кэш
|
||||||
const cached = cacheService.getTableData(tableId);
|
const cached = cacheService.getTableData(tableId);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
console.log(`[updateRelationFilterDefs] Используем кэшированные данные таблицы ${tableId}`);
|
// console.log(`[updateRelationFilterDefs] Используем кэшированные данные таблицы ${tableId}`);
|
||||||
relatedTableMap.set(tableId, Promise.resolve(cached));
|
relatedTableMap.set(tableId, Promise.resolve(cached));
|
||||||
} else {
|
} else {
|
||||||
relatedTableMap.set(tableId, tablesService.getTable(tableId));
|
relatedTableMap.set(tableId, tablesService.getTable(tableId));
|
||||||
@@ -536,7 +536,7 @@ async function updateRelationFilterDefs() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('relationFilterDefs:', defs); // Для отладки
|
// console.log('relationFilterDefs:', defs); // Для отладки
|
||||||
relationFilterDefs.value = defs;
|
relationFilterDefs.value = defs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -553,7 +553,7 @@ onMounted(() => {
|
|||||||
fetchTable();
|
fetchTable();
|
||||||
// Подписка на WebSocket обновления таблицы
|
// Подписка на WebSocket обновления таблицы
|
||||||
unsubscribeFromTableUpdate = websocketService.onTableUpdate(props.tableId, () => {
|
unsubscribeFromTableUpdate = websocketService.onTableUpdate(props.tableId, () => {
|
||||||
console.log('[UserTableView] Получено событие table-updated, перезагружаем данные');
|
// console.log('[UserTableView] Получено событие table-updated, перезагружаем данные');
|
||||||
// Очищаем кэш текущей таблицы
|
// Очищаем кэш текущей таблицы
|
||||||
cacheService.clearTableCache(props.tableId);
|
cacheService.clearTableCache(props.tableId);
|
||||||
fetchTable();
|
fetchTable();
|
||||||
@@ -561,15 +561,15 @@ onMounted(() => {
|
|||||||
|
|
||||||
// Подписка на WebSocket обновления тегов
|
// Подписка на WebSocket обновления тегов
|
||||||
const { onTagsUpdate } = useTagsWebSocket();
|
const { onTagsUpdate } = useTagsWebSocket();
|
||||||
console.log('[UserTableView] Подписываемся на обновления тегов для таблицы:', props.tableId);
|
// console.log('[UserTableView] Подписываемся на обновления тегов для таблицы:', props.tableId);
|
||||||
console.log('[UserTableView] onTagsUpdate функция:', typeof onTagsUpdate);
|
// console.log('[UserTableView] onTagsUpdate функция:', typeof onTagsUpdate);
|
||||||
unsubscribeFromTagsUpdate = onTagsUpdate(async (data) => {
|
unsubscribeFromTagsUpdate = onTagsUpdate(async (data) => {
|
||||||
console.log('[UserTableView] 🔔 ПОЛУЧЕНО СОБЫТИЕ TAGS-UPDATED!');
|
// console.log('[UserTableView] 🔔 ПОЛУЧЕНО СОБЫТИЕ TAGS-UPDATED!');
|
||||||
console.log('[UserTableView] Получено событие tags-updated, обновляем данные для таблицы:', props.tableId, data);
|
// console.log('[UserTableView] Получено событие tags-updated, обновляем данные для таблицы:', props.tableId, data);
|
||||||
|
|
||||||
// Если есть информация о конкретной строке, обновляем только её
|
// Если есть информация о конкретной строке, обновляем только её
|
||||||
if (data && data.rowId) {
|
if (data && data.rowId) {
|
||||||
console.log('[UserTableView] Точечное обновление для строки:', data.rowId);
|
// console.log('[UserTableView] Точечное обновление для строки:', data.rowId);
|
||||||
try {
|
try {
|
||||||
// Очищаем кэш relations только для конкретной строки
|
// Очищаем кэш relations только для конкретной строки
|
||||||
const tagColumns = columns.value.filter(col =>
|
const tagColumns = columns.value.filter(col =>
|
||||||
@@ -581,19 +581,19 @@ onMounted(() => {
|
|||||||
cacheService.clearRelationsData(data.rowId, col.id);
|
cacheService.clearRelationsData(data.rowId, col.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[UserTableView] Кэш relations очищен для строки, обновляем данные строки:', data.rowId);
|
// console.log('[UserTableView] Кэш relations очищен для строки, обновляем данные строки:', data.rowId);
|
||||||
|
|
||||||
// Обновляем только данные конкретной строки
|
// Обновляем только данные конкретной строки
|
||||||
await updateRowData(data.rowId);
|
await updateRowData(data.rowId);
|
||||||
console.log('[UserTableView] Данные строки обновлены:', data.rowId);
|
// console.log('[UserTableView] Данные строки обновлены:', data.rowId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[UserTableView] Ошибка при точечном обновлении:', error);
|
// console.error('[UserTableView] Ошибка при точечном обновлении:', error);
|
||||||
// Fallback: полная перезагрузка при ошибке
|
// Fallback: полная перезагрузка при ошибке
|
||||||
await fetchTable();
|
await fetchTable();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Если нет информации о строке, используем старую логику
|
// Если нет информации о строке, используем старую логику
|
||||||
console.log('[UserTableView] Общее обновление тегов');
|
// console.log('[UserTableView] Общее обновление тегов');
|
||||||
try {
|
try {
|
||||||
// Очищаем кэш relations для всех строк этой таблицы
|
// Очищаем кэш relations для всех строк этой таблицы
|
||||||
const tableRows = rows.value || [];
|
const tableRows = rows.value || [];
|
||||||
@@ -609,11 +609,11 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[UserTableView] Кэш relations очищен, перезагружаем данные таблицы:', props.tableId);
|
// console.log('[UserTableView] Кэш relations очищен, перезагружаем данные таблицы:', props.tableId);
|
||||||
await fetchTable();
|
await fetchTable();
|
||||||
console.log('[UserTableView] Данные таблицы перезагружены:', props.tableId);
|
// console.log('[UserTableView] Данные таблицы перезагружены:', props.tableId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[UserTableView] Ошибка при обновлении после tags-updated:', error);
|
// console.error('[UserTableView] Ошибка при обновлении после tags-updated:', error);
|
||||||
// Fallback: полная перезагрузка при ошибке
|
// Fallback: полная перезагрузка при ошибке
|
||||||
cacheService.clearTableCache(props.tableId);
|
cacheService.clearTableCache(props.tableId);
|
||||||
await fetchTable();
|
await fetchTable();
|
||||||
@@ -764,13 +764,13 @@ async function rebuildIndex() {
|
|||||||
// Функция для точечного обновления данных конкретной строки
|
// Функция для точечного обновления данных конкретной строки
|
||||||
async function updateRowData(rowId) {
|
async function updateRowData(rowId) {
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
console.log(`[UserTableView] 🔄 Начало обновления данных строки ${rowId}`);
|
// console.log(`[UserTableView] 🔄 Начало обновления данных строки ${rowId}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Находим строку в текущих данных
|
// Находим строку в текущих данных
|
||||||
const rowIndex = rows.value.findIndex(row => row.id === rowId);
|
const rowIndex = rows.value.findIndex(row => row.id === rowId);
|
||||||
if (rowIndex === -1) {
|
if (rowIndex === -1) {
|
||||||
console.log(`[UserTableView] Строка ${rowId} не найдена в текущих данных`);
|
// console.log(`[UserTableView] Строка ${rowId} не найдена в текущих данных`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -781,7 +781,7 @@ async function updateRowData(rowId) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (tagColumns.length > 0) {
|
if (tagColumns.length > 0) {
|
||||||
console.log(`[UserTableView] 🔄 Загружаем relations для строки ${rowId} (${tagColumns.length} столбцов)`);
|
// console.log(`[UserTableView] 🔄 Загружаем relations для строки ${rowId} (${tagColumns.length} столбцов)`);
|
||||||
|
|
||||||
const relationPromises = tagColumns.map(col =>
|
const relationPromises = tagColumns.map(col =>
|
||||||
fetch(`/api/tables/${col.table_id}/row/${rowId}/relations`)
|
fetch(`/api/tables/${col.table_id}/row/${rowId}/relations`)
|
||||||
@@ -792,19 +792,19 @@ async function updateRowData(rowId) {
|
|||||||
return { rowId, colId: col.id, relations };
|
return { rowId, colId: col.id, relations };
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error(`[UserTableView] Ошибка загрузки relations для row:${rowId} col:${col.id}:`, error);
|
// console.error(`[UserTableView] Ошибка загрузки relations для row:${rowId} col:${col.id}:`, error);
|
||||||
return { rowId, colId: col.id, relations: [] };
|
return { rowId, colId: col.id, relations: [] };
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
await Promise.all(relationPromises);
|
await Promise.all(relationPromises);
|
||||||
console.log(`[UserTableView] ✅ Relations для строки ${rowId} обновлены`);
|
// console.log(`[UserTableView] ✅ Relations для строки ${rowId} обновлены`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const endTime = Date.now();
|
const endTime = Date.now();
|
||||||
console.log(`[UserTableView] ✅ Завершено обновление строки ${rowId} за ${endTime - startTime}ms`);
|
// console.log(`[UserTableView] ✅ Завершено обновление строки ${rowId} за ${endTime - startTime}ms`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`[UserTableView] ❌ Ошибка при обновлении строки ${rowId}:`, error);
|
// console.error(`[UserTableView] ❌ Ошибка при обновлении строки ${rowId}:`, error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export function useAuthFlow(options = {}) {
|
|||||||
if (telegramAuth.value.checkInterval) {
|
if (telegramAuth.value.checkInterval) {
|
||||||
clearInterval(telegramAuth.value.checkInterval);
|
clearInterval(telegramAuth.value.checkInterval);
|
||||||
telegramAuth.value.checkInterval = null;
|
telegramAuth.value.checkInterval = null;
|
||||||
console.log('[useAuthFlow] Интервал проверки Telegram авторизации очищен');
|
// console.log('[useAuthFlow] Интервал проверки Telegram авторизации очищен');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -69,13 +69,13 @@ export function useAuthFlow(options = {}) {
|
|||||||
clearTelegramInterval(); // На всякий случай
|
clearTelegramInterval(); // На всякий случай
|
||||||
telegramAuth.value.checkInterval = setInterval(async () => {
|
telegramAuth.value.checkInterval = setInterval(async () => {
|
||||||
try {
|
try {
|
||||||
console.log('[useAuthFlow] Проверка статуса Telegram...');
|
// console.log('[useAuthFlow] Проверка статуса Telegram...');
|
||||||
// Используем checkAuth из useAuth для обновления состояния
|
// Используем checkAuth из useAuth для обновления состояния
|
||||||
const checkResponse = await auth.checkAuth();
|
const checkResponse = await auth.checkAuth();
|
||||||
const telegramId = auth.telegramId.value;
|
const telegramId = auth.telegramId.value;
|
||||||
|
|
||||||
if (auth.isAuthenticated.value && telegramId) {
|
if (auth.isAuthenticated.value && telegramId) {
|
||||||
console.log('[useAuthFlow] Telegram успешно связан/подтвержден.');
|
// console.log('[useAuthFlow] Telegram успешно связан/подтвержден.');
|
||||||
clearTelegramInterval();
|
clearTelegramInterval();
|
||||||
telegramAuth.value.showVerification = false;
|
telegramAuth.value.showVerification = false;
|
||||||
telegramAuth.value.verificationCode = '';
|
telegramAuth.value.verificationCode = '';
|
||||||
@@ -87,7 +87,7 @@ export function useAuthFlow(options = {}) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (intervalError) {
|
} catch (intervalError) {
|
||||||
console.error('[useAuthFlow] Ошибка при проверке статуса Telegram в интервале:', intervalError);
|
// console.error('[useAuthFlow] Ошибка при проверке статуса Telegram в интервале:', intervalError);
|
||||||
// Решаем, останавливать ли интервал при ошибке
|
// Решаем, останавливать ли интервал при ошибке
|
||||||
// telegramAuth.value.error = 'Ошибка проверки статуса Telegram.';
|
// telegramAuth.value.error = 'Ошибка проверки статуса Telegram.';
|
||||||
// clearTelegramInterval();
|
// clearTelegramInterval();
|
||||||
@@ -99,7 +99,7 @@ export function useAuthFlow(options = {}) {
|
|||||||
showErrorMessage(telegramAuth.value.error);
|
showErrorMessage(telegramAuth.value.error);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[useAuthFlow] Ошибка инициализации Telegram аутентификации:', error);
|
// console.error('[useAuthFlow] Ошибка инициализации Telegram аутентификации:', error);
|
||||||
const message = error?.response?.data?.error || 'Ошибка при инициализации аутентификации через Telegram';
|
const message = error?.response?.data?.error || 'Ошибка при инициализации аутентификации через Telegram';
|
||||||
telegramAuth.value.error = message;
|
telegramAuth.value.error = message;
|
||||||
showErrorMessage(message);
|
showErrorMessage(message);
|
||||||
@@ -114,7 +114,7 @@ export function useAuthFlow(options = {}) {
|
|||||||
telegramAuth.value.verificationCode = '';
|
telegramAuth.value.verificationCode = '';
|
||||||
telegramAuth.value.error = '';
|
telegramAuth.value.error = '';
|
||||||
telegramAuth.value.isLoading = false;
|
telegramAuth.value.isLoading = false;
|
||||||
console.log('[useAuthFlow] Аутентификация Telegram отменена');
|
// console.log('[useAuthFlow] Аутентификация Telegram отменена');
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Email ---
|
// --- Email ---
|
||||||
@@ -148,13 +148,13 @@ export function useAuthFlow(options = {}) {
|
|||||||
emailAuth.value.showForm = false;
|
emailAuth.value.showForm = false;
|
||||||
emailAuth.value.showVerification = true;
|
emailAuth.value.showVerification = true;
|
||||||
emailAuth.value.verificationCode = ''; // Очищаем поле кода
|
emailAuth.value.verificationCode = ''; // Очищаем поле кода
|
||||||
console.log('[useAuthFlow] Код верификации Email отправлен на:', emailAuth.value.verificationEmail);
|
// console.log('[useAuthFlow] Код верификации Email отправлен на:', emailAuth.value.verificationEmail);
|
||||||
} else {
|
} else {
|
||||||
emailAuth.value.error = response.data.error || 'Ошибка инициализации аутентификации по email';
|
emailAuth.value.error = response.data.error || 'Ошибка инициализации аутентификации по email';
|
||||||
showErrorMessage(emailAuth.value.error);
|
showErrorMessage(emailAuth.value.error);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[useAuthFlow] Ошибка при запросе инициализации Email:', error);
|
// console.error('[useAuthFlow] Ошибка при запросе инициализации Email:', error);
|
||||||
const message = error?.response?.data?.error || 'Ошибка при запросе кода подтверждения';
|
const message = error?.response?.data?.error || 'Ошибка при запросе кода подтверждения';
|
||||||
emailAuth.value.error = message;
|
emailAuth.value.error = message;
|
||||||
showErrorMessage(message);
|
showErrorMessage(message);
|
||||||
|
|||||||
@@ -64,14 +64,14 @@ export function useChat(auth) {
|
|||||||
const { silent = false, initial = false, authType = null } = options;
|
const { silent = false, initial = false, authType = null } = options;
|
||||||
|
|
||||||
if (messageLoading.value.isHistoryLoadingInProgress) {
|
if (messageLoading.value.isHistoryLoadingInProgress) {
|
||||||
console.warn('[useChat] Загрузка истории уже идет, пропуск.');
|
// console.warn('[useChat] Загрузка истории уже идет, пропуск.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
messageLoading.value.isHistoryLoadingInProgress = true;
|
messageLoading.value.isHistoryLoadingInProgress = true;
|
||||||
|
|
||||||
// Если initial=true, сбрасываем offset и hasMoreMessages
|
// Если initial=true, сбрасываем offset и hasMoreMessages
|
||||||
if (initial) {
|
if (initial) {
|
||||||
console.log('[useChat] Начальная загрузка истории...');
|
// console.log('[useChat] Начальная загрузка истории...');
|
||||||
messageLoading.value.offset = 0;
|
messageLoading.value.offset = 0;
|
||||||
messageLoading.value.hasMoreMessages = false;
|
messageLoading.value.hasMoreMessages = false;
|
||||||
messages.value = []; // Очищаем текущие сообщения перед начальной загрузкой
|
messages.value = []; // Очищаем текущие сообщения перед начальной загрузкой
|
||||||
@@ -86,17 +86,17 @@ export function useChat(auth) {
|
|||||||
messageLoading.value.isLoadingHistory = true;
|
messageLoading.value.isLoadingHistory = true;
|
||||||
if (!silent && initial) isLoading.value = true; // Показываем общий лоадер только при начальной загрузке
|
if (!silent && initial) isLoading.value = true; // Показываем общий лоадер только при начальной загрузке
|
||||||
|
|
||||||
console.log(
|
// console.log(
|
||||||
`[useChat] Загрузка истории сообщений (initial: ${initial}, authType: ${authType}, offset: ${messageLoading.value.offset})...`
|
// `[useChat] Загрузка истории сообщений (initial: ${initial}, authType: ${authType}, offset: ${messageLoading.value.offset})...`
|
||||||
);
|
// );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// --- Логика ожидания привязки гостя (упрощенная) ---
|
// --- Логика ожидания привязки гостя (упрощенная) ---
|
||||||
// TODO: Рассмотреть более надежный механизм, если это необходимо
|
// TODO: Рассмотреть более надежный механизм, если это необходимо
|
||||||
if (authType) {
|
if (authType) {
|
||||||
console.log(`[useChat] Ожидание после ${authType} аутентификации...`);
|
// console.log(`[useChat] Ожидание после ${authType} аутентификации...`);
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1500)); // Увеличена задержка
|
await new Promise((resolve) => setTimeout(resolve, 1500)); // Увеличена задержка
|
||||||
console.log('[useChat] Ожидание завершено, продолжаем загрузку истории.');
|
// console.log('[useChat] Ожидание завершено, продолжаем загрузку истории.');
|
||||||
}
|
}
|
||||||
// --- Конец логики ожидания ---
|
// --- Конец логики ожидания ---
|
||||||
|
|
||||||
@@ -107,9 +107,9 @@ export function useChat(auth) {
|
|||||||
const countResponse = await api.get('/chat/history', { params: { count_only: true } });
|
const countResponse = await api.get('/chat/history', { params: { count_only: true } });
|
||||||
if (!countResponse.data.success) throw new Error('Не удалось получить количество сообщений');
|
if (!countResponse.data.success) throw new Error('Не удалось получить количество сообщений');
|
||||||
totalMessages = countResponse.data.total || countResponse.data.count || 0;
|
totalMessages = countResponse.data.total || countResponse.data.count || 0;
|
||||||
console.log(`[useChat] Всего сообщений в истории: ${totalMessages}`);
|
// console.log(`[useChat] Всего сообщений в истории: ${totalMessages}`);
|
||||||
} catch(countError) {
|
} catch(countError) {
|
||||||
console.error('[useChat] Ошибка получения количества сообщений:', countError);
|
// console.error('[useChat] Ошибка получения количества сообщений:', countError);
|
||||||
// Не прерываем выполнение, попробуем загрузить без total
|
// Не прерываем выполнение, попробуем загрузить без total
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ export function useChat(auth) {
|
|||||||
// Если это первая загрузка и мы знаем total, рассчитаем смещение для последних сообщений
|
// Если это первая загрузка и мы знаем total, рассчитаем смещение для последних сообщений
|
||||||
if (initial && totalMessages > 0 && totalMessages > messageLoading.value.limit) {
|
if (initial && totalMessages > 0 && totalMessages > messageLoading.value.limit) {
|
||||||
effectiveOffset = Math.max(0, totalMessages - messageLoading.value.limit);
|
effectiveOffset = Math.max(0, totalMessages - messageLoading.value.limit);
|
||||||
console.log(`[useChat] Рассчитано начальное смещение: ${effectiveOffset}`);
|
// console.log(`[useChat] Рассчитано начальное смещение: ${effectiveOffset}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await api.get('/chat/history', {
|
const response = await api.get('/chat/history', {
|
||||||
@@ -130,7 +130,7 @@ export function useChat(auth) {
|
|||||||
|
|
||||||
if (response.data.success) {
|
if (response.data.success) {
|
||||||
const loadedMessages = response.data.messages || [];
|
const loadedMessages = response.data.messages || [];
|
||||||
console.log(`[useChat] Загружено ${loadedMessages.length} сообщений.`);
|
// console.log(`[useChat] Загружено ${loadedMessages.length} сообщений.`);
|
||||||
|
|
||||||
if (loadedMessages.length > 0) {
|
if (loadedMessages.length > 0) {
|
||||||
// Добавляем к существующим (в начало для истории, в конец для начальной загрузки)
|
// Добавляем к существующим (в начало для истории, в конец для начальной загрузки)
|
||||||
@@ -147,7 +147,7 @@ export function useChat(auth) {
|
|||||||
} else {
|
} else {
|
||||||
messageLoading.value.offset += loadedMessages.length;
|
messageLoading.value.offset += loadedMessages.length;
|
||||||
}
|
}
|
||||||
console.log(`[useChat] Новое смещение: ${messageLoading.value.offset}`);
|
// console.log(`[useChat] Новое смещение: ${messageLoading.value.offset}`);
|
||||||
|
|
||||||
// Проверяем, есть ли еще сообщения для загрузки
|
// Проверяем, есть ли еще сообщения для загрузки
|
||||||
// Используем totalMessages, если он был успешно получен
|
// Используем totalMessages, если он был успешно получен
|
||||||
@@ -157,7 +157,7 @@ export function useChat(auth) {
|
|||||||
// Если total не известен, считаем, что есть еще, если загрузили полный лимит
|
// Если total не известен, считаем, что есть еще, если загрузили полный лимит
|
||||||
messageLoading.value.hasMoreMessages = loadedMessages.length === messageLoading.value.limit;
|
messageLoading.value.hasMoreMessages = loadedMessages.length === messageLoading.value.limit;
|
||||||
}
|
}
|
||||||
console.log(`[useChat] Есть еще сообщения: ${messageLoading.value.hasMoreMessages}`);
|
// console.log(`[useChat] Есть еще сообщения: ${messageLoading.value.hasMoreMessages}`);
|
||||||
} else {
|
} else {
|
||||||
// Если сообщений не пришло, значит, больше нет
|
// Если сообщений не пришло, значит, больше нет
|
||||||
messageLoading.value.hasMoreMessages = false;
|
messageLoading.value.hasMoreMessages = false;
|
||||||
@@ -177,11 +177,11 @@ export function useChat(auth) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.error('[useChat] API вернул ошибку при загрузке истории:', response.data.error);
|
// console.error('[useChat] API вернул ошибку при загрузке истории:', response.data.error);
|
||||||
messageLoading.value.hasMoreMessages = false; // Считаем, что больше нет при ошибке
|
messageLoading.value.hasMoreMessages = false; // Считаем, что больше нет при ошибке
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[useChat] Ошибка загрузки истории сообщений:', error);
|
// console.error('[useChat] Ошибка загрузки истории сообщений:', error);
|
||||||
messageLoading.value.hasMoreMessages = false; // Считаем, что больше нет при ошибке
|
messageLoading.value.hasMoreMessages = false; // Считаем, что больше нет при ошибке
|
||||||
} finally {
|
} finally {
|
||||||
messageLoading.value.isLoadingHistory = false;
|
messageLoading.value.isLoadingHistory = false;
|
||||||
@@ -193,12 +193,12 @@ export function useChat(auth) {
|
|||||||
// --- Отправка сообщения ---
|
// --- Отправка сообщения ---
|
||||||
const handleSendMessage = async (payload) => {
|
const handleSendMessage = async (payload) => {
|
||||||
// --- НАЧАЛО ДОБАВЛЕННЫХ ЛОГОВ ---
|
// --- НАЧАЛО ДОБАВЛЕННЫХ ЛОГОВ ---
|
||||||
console.log('[useChat] handleSendMessage called. Payload:', payload);
|
// console.log('[useChat] handleSendMessage called. Payload:', payload);
|
||||||
console.log('[useChat] Current auth state:', {
|
// console.log('[useChat] Current auth state:', {
|
||||||
isAuthenticated: auth.isAuthenticated.value,
|
// isAuthenticated: auth.isAuthenticated.value,
|
||||||
userId: auth.userId.value,
|
// userId: auth.userId.value,
|
||||||
authType: auth.authType.value,
|
// authType: auth.authType.value,
|
||||||
});
|
// });
|
||||||
// --- КОНЕЦ ДОБАВЛЕННЫХ ЛОГОВ ---
|
// --- КОНЕЦ ДОБАВЛЕННЫХ ЛОГОВ ---
|
||||||
|
|
||||||
const { message: text, attachments: files } = payload; // files - массив File объектов
|
const { message: text, attachments: files } = payload; // files - массив File объектов
|
||||||
@@ -206,7 +206,7 @@ export function useChat(auth) {
|
|||||||
|
|
||||||
// Проверка на пустое сообщение (если нет ни текста, ни файлов)
|
// Проверка на пустое сообщение (если нет ни текста, ни файлов)
|
||||||
if (!userMessageContent && (!files || files.length === 0)) {
|
if (!userMessageContent && (!files || files.length === 0)) {
|
||||||
console.warn('[useChat] Попытка отправить пустое сообщение.');
|
// console.warn('[useChat] Попытка отправить пустое сообщение.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +268,7 @@ export function useChat(auth) {
|
|||||||
const userMsgIndex = messages.value.findIndex((m) => m.id === tempId);
|
const userMsgIndex = messages.value.findIndex((m) => m.id === tempId);
|
||||||
|
|
||||||
if (response.data.success) {
|
if (response.data.success) {
|
||||||
console.log('[useChat] Сообщение успешно отправлено:', response.data);
|
// console.log('[useChat] Сообщение успешно отправлено:', response.data);
|
||||||
// Обновляем локальное сообщение данными с сервера
|
// Обновляем локальное сообщение данными с сервера
|
||||||
if (userMsgIndex !== -1) {
|
if (userMsgIndex !== -1) {
|
||||||
const serverUserMessage = response.data.userMessage || { id: response.data.messageId };
|
const serverUserMessage = response.data.userMessage || { id: response.data.messageId };
|
||||||
@@ -317,7 +317,7 @@ export function useChat(auth) {
|
|||||||
});
|
});
|
||||||
setToStorage('guestMessages', storedMessages);
|
setToStorage('guestMessages', storedMessages);
|
||||||
} catch (storageError) {
|
} catch (storageError) {
|
||||||
console.error('[useChat] Ошибка сохранения гостевого сообщения в localStorage:', storageError);
|
// console.error('[useChat] Ошибка сохранения гостевого сообщения в localStorage:', storageError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,7 +329,7 @@ export function useChat(auth) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[useChat] Ошибка отправки сообщения:', error);
|
// console.error('[useChat] Ошибка отправки сообщения:', error);
|
||||||
const userMsgIndex = messages.value.findIndex((m) => m.id === tempId);
|
const userMsgIndex = messages.value.findIndex((m) => m.id === tempId);
|
||||||
if (userMsgIndex !== -1) {
|
if (userMsgIndex !== -1) {
|
||||||
messages.value[userMsgIndex].hasError = true;
|
messages.value[userMsgIndex].hasError = true;
|
||||||
@@ -354,7 +354,7 @@ export function useChat(auth) {
|
|||||||
try {
|
try {
|
||||||
const storedMessages = getFromStorage('guestMessages');
|
const storedMessages = getFromStorage('guestMessages');
|
||||||
if (storedMessages && Array.isArray(storedMessages) && storedMessages.length > 0) {
|
if (storedMessages && Array.isArray(storedMessages) && storedMessages.length > 0) {
|
||||||
console.log(`[useChat] Найдено ${storedMessages.length} сохраненных гостевых сообщений`);
|
// console.log(`[useChat] Найдено ${storedMessages.length} сохраненных гостевых сообщений`);
|
||||||
// Добавляем только если текущий список пуст (чтобы не дублировать при HMR)
|
// Добавляем только если текущий список пуст (чтобы не дублировать при HMR)
|
||||||
if(messages.value.length === 0) {
|
if(messages.value.length === 0) {
|
||||||
messages.value = storedMessages.map(m => ({ ...m, isGuest: true })); // Помечаем как гостевые
|
messages.value = storedMessages.map(m => ({ ...m, isGuest: true })); // Помечаем как гостевые
|
||||||
@@ -362,7 +362,7 @@ export function useChat(auth) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[useChat] Ошибка загрузки гостевых сообщений из localStorage:', e);
|
// console.error('[useChat] Ошибка загрузки гостевых сообщений из localStorage:', e);
|
||||||
removeFromStorage('guestMessages'); // Очистить при ошибке парсинга
|
removeFromStorage('guestMessages'); // Очистить при ошибке парсинга
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -381,7 +381,7 @@ export function useChat(auth) {
|
|||||||
guestId.value = '';
|
guestId.value = '';
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[useChat] Ошибка связывания гостевых сообщений:', error);
|
// console.error('[useChat] Ошибка связывания гостевых сообщений:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -401,7 +401,7 @@ export function useChat(auth) {
|
|||||||
// Сброс чата при выходе пользователя
|
// Сброс чата при выходе пользователя
|
||||||
watch(() => auth.isAuthenticated.value, (isAuth, wasAuth) => {
|
watch(() => auth.isAuthenticated.value, (isAuth, wasAuth) => {
|
||||||
if (!isAuth && wasAuth) { // Если пользователь разлогинился
|
if (!isAuth && wasAuth) { // Если пользователь разлогинился
|
||||||
console.log('[useChat] Пользователь вышел, сброс состояния чата.');
|
// console.log('[useChat] Пользователь вышел, сброс состояния чата.');
|
||||||
messages.value = [];
|
messages.value = [];
|
||||||
messageLoading.value.offset = 0;
|
messageLoading.value.offset = 0;
|
||||||
messageLoading.value.hasMoreMessages = false;
|
messageLoading.value.hasMoreMessages = false;
|
||||||
@@ -413,7 +413,7 @@ export function useChat(auth) {
|
|||||||
// Гостевые данные очищаются при успешной аутентификации в loadMessages
|
// Гостевые данные очищаются при успешной аутентификации в loadMessages
|
||||||
// или если пользователь сам очистит localStorage
|
// или если пользователь сам очистит localStorage
|
||||||
} else if (isAuth && !wasAuth) { // Если пользователь вошел
|
} else if (isAuth && !wasAuth) { // Если пользователь вошел
|
||||||
console.log('[useChat] Пользователь вошел, подключаем WebSocket.');
|
// console.log('[useChat] Пользователь вошел, подключаем WebSocket.');
|
||||||
// Отложенное подключение, чтобы дождаться загрузки данных пользователя
|
// Отложенное подключение, чтобы дождаться загрузки данных пользователя
|
||||||
setTimeout(() => setupChatWebSocket(), 100);
|
setTimeout(() => setupChatWebSocket(), 100);
|
||||||
}
|
}
|
||||||
@@ -422,7 +422,7 @@ export function useChat(auth) {
|
|||||||
// Отслеживаем загрузку данных пользователя для подключения WebSocket
|
// Отслеживаем загрузку данных пользователя для подключения WebSocket
|
||||||
watch(() => auth.user?.value, (newUser, oldUser) => {
|
watch(() => auth.user?.value, (newUser, oldUser) => {
|
||||||
if (newUser && newUser.id && auth.isAuthenticated.value) {
|
if (newUser && newUser.id && auth.isAuthenticated.value) {
|
||||||
console.log('[useChat] Данные пользователя загружены, подключаем WebSocket:', newUser.id);
|
// console.log('[useChat] Данные пользователя загружены, подключаем WebSocket:', newUser.id);
|
||||||
setupChatWebSocket();
|
setupChatWebSocket();
|
||||||
}
|
}
|
||||||
}, { immediate: false });
|
}, { immediate: false });
|
||||||
@@ -431,12 +431,12 @@ export function useChat(auth) {
|
|||||||
function setupChatWebSocket() {
|
function setupChatWebSocket() {
|
||||||
// Подключаемся к WebSocket только если пользователь аутентифицирован
|
// Подключаемся к WebSocket только если пользователь аутентифицирован
|
||||||
if (auth.isAuthenticated.value && auth.user && auth.user.value && auth.user.value.id) {
|
if (auth.isAuthenticated.value && auth.user && auth.user.value && auth.user.value.id) {
|
||||||
console.log('[useChat] Подключение к WebSocket для пользователя:', auth.user.value.id);
|
// console.log('[useChat] Подключение к WebSocket для пользователя:', auth.user.value.id);
|
||||||
websocketService.connect(auth.user.value.id);
|
websocketService.connect(auth.user.value.id);
|
||||||
|
|
||||||
// Создаем и сохраняем callback функции
|
// Создаем и сохраняем callback функции
|
||||||
wsCallbacks.chatMessage = (message) => {
|
wsCallbacks.chatMessage = (message) => {
|
||||||
console.log('[useChat] Получено новое сообщение через WebSocket:', message);
|
// console.log('[useChat] Получено новое сообщение через WebSocket:', message);
|
||||||
// Проверяем, что сообщение не дублируется
|
// Проверяем, что сообщение не дублируется
|
||||||
const existingMessage = messages.value.find(m => m.id === message.id);
|
const existingMessage = messages.value.find(m => m.id === message.id);
|
||||||
if (!existingMessage) {
|
if (!existingMessage) {
|
||||||
@@ -445,20 +445,20 @@ export function useChat(auth) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
wsCallbacks.conversationUpdated = (conversationId) => {
|
wsCallbacks.conversationUpdated = (conversationId) => {
|
||||||
console.log('[useChat] Обновление диалога через WebSocket:', conversationId);
|
// console.log('[useChat] Обновление диалога через WebSocket:', conversationId);
|
||||||
// Можно добавить логику обновления списка диалогов
|
// Можно добавить логику обновления списка диалогов
|
||||||
};
|
};
|
||||||
|
|
||||||
wsCallbacks.connected = () => {
|
wsCallbacks.connected = () => {
|
||||||
console.log('[useChat] WebSocket подключен');
|
// console.log('[useChat] WebSocket подключен');
|
||||||
};
|
};
|
||||||
|
|
||||||
wsCallbacks.disconnected = () => {
|
wsCallbacks.disconnected = () => {
|
||||||
console.log('[useChat] WebSocket отключен');
|
// console.log('[useChat] WebSocket отключен');
|
||||||
};
|
};
|
||||||
|
|
||||||
wsCallbacks.error = (error) => {
|
wsCallbacks.error = (error) => {
|
||||||
console.error('[useChat] WebSocket ошибка:', error);
|
// console.error('[useChat] WebSocket ошибка:', error);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Подписываемся на события
|
// Подписываемся на события
|
||||||
@@ -468,7 +468,7 @@ export function useChat(auth) {
|
|||||||
websocketService.on('disconnected', wsCallbacks.disconnected);
|
websocketService.on('disconnected', wsCallbacks.disconnected);
|
||||||
websocketService.on('error', wsCallbacks.error);
|
websocketService.on('error', wsCallbacks.error);
|
||||||
} else {
|
} else {
|
||||||
console.log('[useChat] WebSocket не подключен: пользователь не аутентифицирован или данные не загружены');
|
// console.log('[useChat] WebSocket не подключен: пользователь не аутентифицирован или данные не загружены');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,30 +33,30 @@ export function useTokenBalances() {
|
|||||||
if (walletAddress) {
|
if (walletAddress) {
|
||||||
try {
|
try {
|
||||||
isLoadingTokens.value = true;
|
isLoadingTokens.value = true;
|
||||||
console.log('[useTokenBalances] Запрос балансов для адреса:', walletAddress);
|
// console.log('[useTokenBalances] Запрос балансов для адреса:', walletAddress);
|
||||||
const response = await fetchTokenBalances(walletAddress);
|
const response = await fetchTokenBalances(walletAddress);
|
||||||
// Ожидаем, что response — это массив объектов
|
// Ожидаем, что response — это массив объектов
|
||||||
tokenBalances.value = Array.isArray(response) ? response : (response?.data || []);
|
tokenBalances.value = Array.isArray(response) ? response : (response?.data || []);
|
||||||
console.log('[useTokenBalances] Обновленные балансы:', tokenBalances.value);
|
// console.log('[useTokenBalances] Обновленные балансы:', tokenBalances.value);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[useTokenBalances] Ошибка при обновлении балансов:', error);
|
// console.error('[useTokenBalances] Ошибка при обновлении балансов:', error);
|
||||||
tokenBalances.value = [];
|
tokenBalances.value = [];
|
||||||
} finally {
|
} finally {
|
||||||
isLoadingTokens.value = false;
|
isLoadingTokens.value = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('[useTokenBalances] Не найден адрес кошелька для запроса балансов.');
|
// console.log('[useTokenBalances] Не найден адрес кошелька для запроса балансов.');
|
||||||
tokenBalances.value = [];
|
tokenBalances.value = [];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('[useTokenBalances] Пользователь не аутентифицирован, сброс балансов.');
|
// console.log('[useTokenBalances] Пользователь не аутентифицирован, сброс балансов.');
|
||||||
tokenBalances.value = [];
|
tokenBalances.value = [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const startBalanceUpdates = (intervalMs = 300000) => {
|
const startBalanceUpdates = (intervalMs = 300000) => {
|
||||||
stopBalanceUpdates(); // Остановить предыдущий интервал, если он был
|
stopBalanceUpdates(); // Остановить предыдущий интервал, если он был
|
||||||
console.log('[useTokenBalances] Запуск обновления балансов...');
|
// console.log('[useTokenBalances] Запуск обновления балансов...');
|
||||||
updateBalances(); // Обновить сразу
|
updateBalances(); // Обновить сразу
|
||||||
balanceUpdateInterval = setInterval(updateBalances, intervalMs);
|
balanceUpdateInterval = setInterval(updateBalances, intervalMs);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ app.use(ElementPlus);
|
|||||||
// ]).catch(err => console.error('Failed to load API mocks:', err));
|
// ]).catch(err => console.error('Failed to load API mocks:', err));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
console.log('API URL:', axios.defaults.baseURL);
|
// console.log('API URL:', axios.defaults.baseURL);
|
||||||
console.log('main.js: Starting application with router');
|
// console.log('main.js: Starting application with router');
|
||||||
|
|
||||||
app.mount('#app');
|
app.mount('#app');
|
||||||
console.log('main.js: Application with router mounted');
|
// console.log('main.js: Application with router mounted');
|
||||||
|
|||||||
@@ -14,14 +14,13 @@ import { createRouter, createWebHistory } from 'vue-router';
|
|||||||
import HomeView from '../views/HomeView.vue';
|
import HomeView from '../views/HomeView.vue';
|
||||||
// Импортируем (пока не созданные) компоненты для подстраниц настроек
|
// Импортируем (пока не созданные) компоненты для подстраниц настроек
|
||||||
const SettingsAiView = () => import('../views/settings/AiSettingsView.vue');
|
const SettingsAiView = () => import('../views/settings/AiSettingsView.vue');
|
||||||
const SettingsBlockchainView = () => import('../views/settings/BlockchainSettingsView.vue');
|
|
||||||
const SettingsSecurityView = () => import('../views/settings/SecuritySettingsView.vue');
|
const SettingsSecurityView = () => import('../views/settings/SecuritySettingsView.vue');
|
||||||
const SettingsInterfaceView = () => import('../views/settings/Interface/InterfaceSettingsView.vue');
|
const SettingsInterfaceView = () => import('../views/settings/Interface/InterfaceSettingsView.vue');
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { setToStorage } from '../utils/storage.js';
|
import { setToStorage } from '../utils/storage.js';
|
||||||
|
|
||||||
console.log('router/index.js: Script loaded');
|
// console.log('router/index.js: Script loaded');
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
@@ -50,16 +49,7 @@ const routes = [
|
|||||||
name: 'settings-ai',
|
name: 'settings-ai',
|
||||||
component: SettingsAiView,
|
component: SettingsAiView,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'blockchain',
|
|
||||||
name: 'settings-blockchain',
|
|
||||||
component: SettingsBlockchainView,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'blockchain/dle-deploy',
|
|
||||||
name: 'settings-blockchain-dle-deploy',
|
|
||||||
component: () => import('../views/settings/BlockchainSettingsView.vue'),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'dle-v2-deploy',
|
path: 'dle-v2-deploy',
|
||||||
name: 'settings-dle-v2-deploy',
|
name: 'settings-dle-v2-deploy',
|
||||||
@@ -286,7 +276,7 @@ const router = createRouter({
|
|||||||
routes,
|
routes,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('router/index.js: Router created');
|
// console.log('router/index.js: Router created');
|
||||||
|
|
||||||
// Защита маршрутов
|
// Защита маршрутов
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
|
|||||||
@@ -16,14 +16,14 @@ class CacheService {
|
|||||||
const cached = this.tableCache.get(cacheKey);
|
const cached = this.tableCache.get(cacheKey);
|
||||||
|
|
||||||
if (cached && Date.now() - cached.timestamp < this.tableCacheTimeout) {
|
if (cached && Date.now() - cached.timestamp < this.tableCacheTimeout) {
|
||||||
console.log(`[CacheService] ✅ КЭШ ПОПАДАНИЕ для таблицы ${tableId} (${cacheKey})`);
|
// console.log(`[CacheService] ✅ КЭШ ПОПАДАНИЕ для таблицы ${tableId} (${cacheKey})`);
|
||||||
return cached.data;
|
return cached.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cached) {
|
if (cached) {
|
||||||
console.log(`[CacheService] ⏰ Кэш истек для таблицы ${tableId} (${cacheKey})`);
|
// console.log(`[CacheService] ⏰ Кэш истек для таблицы ${tableId} (${cacheKey})`);
|
||||||
} else {
|
} else {
|
||||||
console.log(`[CacheService] ❌ Кэш отсутствует для таблицы ${tableId} (${cacheKey})`);
|
// console.log(`[CacheService] ❌ Кэш отсутствует для таблицы ${tableId} (${cacheKey})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -35,7 +35,7 @@ class CacheService {
|
|||||||
data,
|
data,
|
||||||
timestamp: Date.now()
|
timestamp: Date.now()
|
||||||
});
|
});
|
||||||
console.log(`[CacheService] Сохранены данные таблицы ${tableId} в кэш`);
|
// console.log(`[CacheService] Сохранены данные таблицы ${tableId} в кэш`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Кэширование relations
|
// Кэширование relations
|
||||||
@@ -44,7 +44,7 @@ class CacheService {
|
|||||||
const cached = this.relationsCache.get(cacheKey);
|
const cached = this.relationsCache.get(cacheKey);
|
||||||
|
|
||||||
if (cached && Date.now() - cached.timestamp < this.relationsCacheTimeout) {
|
if (cached && Date.now() - cached.timestamp < this.relationsCacheTimeout) {
|
||||||
console.log(`[CacheService] Используем кэшированные relations для строки ${rowId}`);
|
// console.log(`[CacheService] Используем кэшированные relations для строки ${rowId}`);
|
||||||
return cached.data;
|
return cached.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ class CacheService {
|
|||||||
data,
|
data,
|
||||||
timestamp: Date.now()
|
timestamp: Date.now()
|
||||||
});
|
});
|
||||||
console.log(`[CacheService] Сохранены relations строки ${rowId} в кэш`);
|
// console.log(`[CacheService] Сохранены relations строки ${rowId} в кэш`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Очистка кэша
|
// Очистка кэша
|
||||||
@@ -69,11 +69,11 @@ class CacheService {
|
|||||||
this.tableCache.delete(key);
|
this.tableCache.delete(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(`[CacheService] Очищен кэш таблицы ${tableId}`);
|
// console.log(`[CacheService] Очищен кэш таблицы ${tableId}`);
|
||||||
} else {
|
} else {
|
||||||
// Очищаем весь кэш таблиц
|
// Очищаем весь кэш таблиц
|
||||||
this.tableCache.clear();
|
this.tableCache.clear();
|
||||||
console.log('[CacheService] Очищен весь кэш таблиц');
|
// console.log('[CacheService] Очищен весь кэш таблиц');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,11 +85,11 @@ class CacheService {
|
|||||||
this.relationsCache.delete(key);
|
this.relationsCache.delete(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(`[CacheService] Очищен кэш relations строки ${rowId}`);
|
// console.log(`[CacheService] Очищен кэш relations строки ${rowId}`);
|
||||||
} else {
|
} else {
|
||||||
// Очищаем весь кэш relations
|
// Очищаем весь кэш relations
|
||||||
this.relationsCache.clear();
|
this.relationsCache.clear();
|
||||||
console.log('[CacheService] Очищен весь кэш relations');
|
// console.log('[CacheService] Очищен весь кэш relations');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ class CacheService {
|
|||||||
clearAll() {
|
clearAll() {
|
||||||
this.tableCache.clear();
|
this.tableCache.clear();
|
||||||
this.relationsCache.clear();
|
this.relationsCache.clear();
|
||||||
console.log('[CacheService] Очищены все кэши');
|
// console.log('[CacheService] Очищены все кэши');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Получение статистики кэша
|
// Получение статистики кэша
|
||||||
|
|||||||
@@ -27,10 +27,10 @@ export default {
|
|||||||
async deleteContact(id) {
|
async deleteContact(id) {
|
||||||
try {
|
try {
|
||||||
const res = await api.delete(`/users/${id}`);
|
const res = await api.delete(`/users/${id}`);
|
||||||
console.log('Ответ на удаление контакта:', res.status, res.data);
|
// console.log('Ответ на удаление контакта:', res.status, res.data);
|
||||||
return res.data;
|
return res.data;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Ошибка при удалении контакта:', err.response?.status, err.response?.data, err);
|
// console.error('Ошибка при удалении контакта:', err.response?.status, err.response?.data, err);
|
||||||
|
|
||||||
// Если пользователь уже удален (404), считаем это успехом
|
// Если пользователь уже удален (404), считаем это успехом
|
||||||
if (err.response?.status === 404) {
|
if (err.response?.status === 404) {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class DLEV2Service {
|
|||||||
const response = await api.post('/dle-v2', dleParams);
|
const response = await api.post('/dle-v2', dleParams);
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при создании DLE v2:', error);
|
// console.error('Ошибка при создании DLE v2:', error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ class DLEV2Service {
|
|||||||
const response = await api.get('/dle-v2');
|
const response = await api.get('/dle-v2');
|
||||||
return response.data.data || [];
|
return response.data.data || [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при получении списка DLE v2:', error);
|
// console.error('Ошибка при получении списка DLE v2:', error);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ class DLEV2Service {
|
|||||||
const response = await api.get('/dle-v2/defaults');
|
const response = await api.get('/dle-v2/defaults');
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при получении настроек по умолчанию DLE v2:', error);
|
// console.error('Ошибка при получении настроек по умолчанию DLE v2:', error);
|
||||||
return {
|
return {
|
||||||
votingDelay: 1,
|
votingDelay: 1,
|
||||||
votingPeriod: 45818,
|
votingPeriod: 45818,
|
||||||
@@ -76,7 +76,7 @@ class DLEV2Service {
|
|||||||
const response = await api.delete(`/dle-v2/${dleAddress}`);
|
const response = await api.delete(`/dle-v2/${dleAddress}`);
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при удалении DLE v2:', error);
|
// console.error('Ошибка при удалении DLE v2:', error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,13 +56,13 @@ export default {
|
|||||||
return res.data;
|
return res.data;
|
||||||
},
|
},
|
||||||
async deleteTable(id) {
|
async deleteTable(id) {
|
||||||
console.log('tablesService.deleteTable called with id:', id);
|
// console.log('tablesService.deleteTable called with id:', id);
|
||||||
try {
|
try {
|
||||||
const res = await api.delete(`${tablesApi}/${id}`);
|
const res = await api.delete(`${tablesApi}/${id}`);
|
||||||
console.log('Delete response:', res.data);
|
// console.log('Delete response:', res.data);
|
||||||
return res.data;
|
return res.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in deleteTable service:', error);
|
// console.error('Error in deleteTable service:', error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,14 +18,14 @@ export const fetchTokenBalances = async (address = null) => {
|
|||||||
let url = '/tokens/balances';
|
let url = '/tokens/balances';
|
||||||
if (address) {
|
if (address) {
|
||||||
url += `?address=${encodeURIComponent(address)}`;
|
url += `?address=${encodeURIComponent(address)}`;
|
||||||
console.log(`Fetching token balances for specific address: ${address}`);
|
// console.log(`Fetching token balances for specific address: ${address}`);
|
||||||
} else {
|
} else {
|
||||||
console.log('Fetching token balances for session user');
|
// console.log('Fetching token balances for session user');
|
||||||
}
|
}
|
||||||
const response = await api.get(url);
|
const response = await api.get(url);
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching token balances:', error);
|
// console.error('Error fetching token balances:', error);
|
||||||
return {
|
return {
|
||||||
eth: '0',
|
eth: '0',
|
||||||
bsc: '0',
|
bsc: '0',
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import axios from '../api/axios';
|
|||||||
import { SiweMessage } from 'siwe';
|
import { SiweMessage } from 'siwe';
|
||||||
|
|
||||||
export async function connectWithWallet() {
|
export async function connectWithWallet() {
|
||||||
console.log('Starting wallet connection...');
|
// console.log('Starting wallet connection...');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Проверяем наличие MetaMask
|
// Проверяем наличие MetaMask
|
||||||
@@ -23,12 +23,12 @@ export async function connectWithWallet() {
|
|||||||
throw new Error('MetaMask not detected. Please install MetaMask.');
|
throw new Error('MetaMask not detected. Please install MetaMask.');
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('MetaMask detected, requesting accounts...');
|
// console.log('MetaMask detected, requesting accounts...');
|
||||||
|
|
||||||
// Запрашиваем доступ к аккаунтам
|
// Запрашиваем доступ к аккаунтам
|
||||||
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
|
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
|
||||||
|
|
||||||
console.log('Got accounts:', accounts);
|
// console.log('Got accounts:', accounts);
|
||||||
|
|
||||||
if (!accounts || accounts.length === 0) {
|
if (!accounts || accounts.length === 0) {
|
||||||
throw new Error('No accounts found. Please unlock MetaMask.');
|
throw new Error('No accounts found. Please unlock MetaMask.');
|
||||||
@@ -36,13 +36,13 @@ export async function connectWithWallet() {
|
|||||||
|
|
||||||
// Берем первый аккаунт
|
// Берем первый аккаунт
|
||||||
const address = ethers.getAddress(accounts[0]);
|
const address = ethers.getAddress(accounts[0]);
|
||||||
console.log('Normalized address:', address);
|
// console.log('Normalized address:', address);
|
||||||
|
|
||||||
// Запрашиваем nonce с сервера
|
// Запрашиваем nonce с сервера
|
||||||
console.log('Requesting nonce...');
|
// console.log('Requesting nonce...');
|
||||||
const nonceResponse = await axios.get(`/auth/nonce?address=${address}`);
|
const nonceResponse = await axios.get(`/auth/nonce?address=${address}`);
|
||||||
const nonce = nonceResponse.data.nonce;
|
const nonce = nonceResponse.data.nonce;
|
||||||
console.log('Got nonce:', nonce);
|
// console.log('Got nonce:', nonce);
|
||||||
|
|
||||||
// Создаем сообщение для подписи
|
// Создаем сообщение для подписи
|
||||||
const domain = window.location.host;
|
const domain = window.location.host;
|
||||||
@@ -63,30 +63,30 @@ export async function connectWithWallet() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const message = siweMessage.prepareMessage();
|
const message = siweMessage.prepareMessage();
|
||||||
console.log('SIWE message:', message);
|
// console.log('SIWE message:', message);
|
||||||
console.log('SIWE message details:', {
|
// console.log('SIWE message details:', {
|
||||||
domain,
|
// domain,
|
||||||
address,
|
// address,
|
||||||
statement,
|
// statement,
|
||||||
uri: origin,
|
// uri: origin,
|
||||||
version: '1',
|
// version: '1',
|
||||||
chainId: 1,
|
// chainId: 1,
|
||||||
nonce,
|
// nonce,
|
||||||
issuedAt,
|
// issuedAt,
|
||||||
resources: [`${origin}/api/auth/verify`],
|
// resources: [`${origin}/api/auth/verify`],
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Запрашиваем подпись
|
// Запрашиваем подпись
|
||||||
console.log('Requesting signature...');
|
// console.log('Requesting signature...');
|
||||||
const signature = await window.ethereum.request({
|
const signature = await window.ethereum.request({
|
||||||
method: 'personal_sign',
|
method: 'personal_sign',
|
||||||
params: [message, address.toLowerCase()],
|
params: [message, address.toLowerCase()],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Got signature:', signature);
|
// console.log('Got signature:', signature);
|
||||||
|
|
||||||
// Отправляем подпись на сервер для верификации
|
// Отправляем подпись на сервер для верификации
|
||||||
console.log('Sending verification request...');
|
// console.log('Sending verification request...');
|
||||||
const verificationResponse = await axios.post('/auth/verify', {
|
const verificationResponse = await axios.post('/auth/verify', {
|
||||||
signature,
|
signature,
|
||||||
address,
|
address,
|
||||||
@@ -94,7 +94,7 @@ export async function connectWithWallet() {
|
|||||||
issuedAt,
|
issuedAt,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Verification response:', verificationResponse.data);
|
// console.log('Verification response:', verificationResponse.data);
|
||||||
|
|
||||||
// Обновляем состояние аутентификации
|
// Обновляем состояние аутентификации
|
||||||
if (verificationResponse.data.success) {
|
if (verificationResponse.data.success) {
|
||||||
@@ -107,7 +107,7 @@ export async function connectWithWallet() {
|
|||||||
|
|
||||||
return verificationResponse.data;
|
return verificationResponse.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error connecting wallet:', error);
|
// console.error('Error connecting wallet:', error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class WebSshService {
|
|||||||
this.isAgentRunning = false;
|
this.isAgentRunning = false;
|
||||||
return { running: false };
|
return { running: false };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Агент не доступен:', error);
|
// console.error('Агент не доступен:', error);
|
||||||
this.isAgentRunning = false;
|
this.isAgentRunning = false;
|
||||||
return { running: false, error: error.message };
|
return { running: false, error: error.message };
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@ class WebSshService {
|
|||||||
return await this.downloadAndInstallAgent();
|
return await this.downloadAndInstallAgent();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при установке агента:', error);
|
// console.error('Ошибка при установке агента:', error);
|
||||||
return await this.downloadAndInstallAgent();
|
return await this.downloadAndInstallAgent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@ EOF
|
|||||||
requiresManualInstall: true
|
requiresManualInstall: true
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при создании установочного скрипта:', error);
|
// console.error('Ошибка при создании установочного скрипта:', error);
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: 'Ошибка при подготовке установки агента',
|
message: 'Ошибка при подготовке установки агента',
|
||||||
@@ -216,7 +216,7 @@ EOF
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при создании туннеля:', error);
|
// console.error('Ошибка при создании туннеля:', error);
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: `Ошибка подключения к агенту: ${error.message}`
|
message: `Ошибка подключения к агенту: ${error.message}`
|
||||||
@@ -259,7 +259,7 @@ EOF
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при отключении туннеля:', error);
|
// console.error('Ошибка при отключении туннеля:', error);
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
message: `Ошибка подключения к агенту: ${error.message}`
|
message: `Ошибка подключения к агенту: ${error.message}`
|
||||||
@@ -291,7 +291,7 @@ EOF
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при получении статуса:', error);
|
// console.error('Ошибка при получении статуса:', error);
|
||||||
return {
|
return {
|
||||||
connected: false,
|
connected: false,
|
||||||
domain: null,
|
domain: null,
|
||||||
@@ -337,7 +337,7 @@ app.post('/tunnel/create', async (req, res) => {
|
|||||||
try {
|
try {
|
||||||
const { domain, email, sshHost, sshUser, sshKey, localPort, serverPort, sshPort } = req.body;
|
const { domain, email, sshHost, sshUser, sshKey, localPort, serverPort, sshPort } = req.body;
|
||||||
|
|
||||||
console.log('Создание туннеля для домена:', domain);
|
// console.log('Создание туннеля для домена:', domain);
|
||||||
|
|
||||||
// Сохраняем SSH ключ во временный файл
|
// Сохраняем SSH ключ во временный файл
|
||||||
const keyPath = path.join(__dirname, 'temp_ssh_key');
|
const keyPath = path.join(__dirname, 'temp_ssh_key');
|
||||||
@@ -395,11 +395,11 @@ server {
|
|||||||
const sshProcess = spawn('ssh', sshArgs);
|
const sshProcess = spawn('ssh', sshArgs);
|
||||||
|
|
||||||
sshProcess.on('error', (error) => {
|
sshProcess.on('error', (error) => {
|
||||||
console.error('SSH процесс ошибка:', error);
|
// console.error('SSH процесс ошибка:', error);
|
||||||
});
|
});
|
||||||
|
|
||||||
sshProcess.on('close', (code) => {
|
sshProcess.on('close', (code) => {
|
||||||
console.log('SSH процесс завершен с кодом:', code);
|
// console.log('SSH процесс завершен с кодом:', code);
|
||||||
tunnelState.connected = false;
|
tunnelState.connected = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -419,7 +419,7 @@ server {
|
|||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка создания туннеля:', error);
|
// console.error('Ошибка создания туннеля:', error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: error.message
|
message: error.message
|
||||||
@@ -446,7 +446,7 @@ app.post('/tunnel/disconnect', (req, res) => {
|
|||||||
message: 'Туннель отключен'
|
message: 'Туннель отключен'
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка отключения туннеля:', error);
|
// console.error('Ошибка отключения туннеля:', error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: error.message
|
message: error.message
|
||||||
@@ -465,7 +465,7 @@ app.get('/tunnel/status', (req, res) => {
|
|||||||
|
|
||||||
// Запуск сервера
|
// Запуск сервера
|
||||||
app.listen(PORT, 'localhost', () => {
|
app.listen(PORT, 'localhost', () => {
|
||||||
console.log(\`WebSSH Agent запущен на порту \${PORT}\`);
|
// console.log(\`WebSSH Agent запущен на порту \${PORT}\`);
|
||||||
});
|
});
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
class WebSocketService {
|
class WebSocketService {
|
||||||
constructor() {
|
constructor() {
|
||||||
console.log('🔌 [WebSocket] Конструктор вызван');
|
// console.log('🔌 [WebSocket] Конструктор вызван');
|
||||||
this.ws = null;
|
this.ws = null;
|
||||||
this.isConnected = false;
|
this.isConnected = false;
|
||||||
this.reconnectAttempts = 0;
|
this.reconnectAttempts = 0;
|
||||||
@@ -24,14 +24,14 @@ class WebSocketService {
|
|||||||
this.reconnectDelay = 1000; // 1 секунда
|
this.reconnectDelay = 1000; // 1 секунда
|
||||||
this.listeners = new Map();
|
this.listeners = new Map();
|
||||||
this.userId = null;
|
this.userId = null;
|
||||||
console.log('🔌 [WebSocket] Конструктор завершен');
|
// console.log('🔌 [WebSocket] Конструктор завершен');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Подключение к WebSocket серверу
|
// Подключение к WebSocket серверу
|
||||||
connect(userId = null) {
|
connect(userId = null) {
|
||||||
console.log('🔌 [WebSocket] Попытка подключения, userId:', userId);
|
// console.log('🔌 [WebSocket] Попытка подключения, userId:', userId);
|
||||||
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
||||||
console.log('🔌 [WebSocket] Уже подключен');
|
// console.log('🔌 [WebSocket] Уже подключен');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,13 +43,13 @@ class WebSocketService {
|
|||||||
// В Docker окружении используем тот же хост, что и для HTTP
|
// В Docker окружении используем тот же хост, что и для HTTP
|
||||||
const wsUrl = `${protocol}//${window.location.host}/ws`;
|
const wsUrl = `${protocol}//${window.location.host}/ws`;
|
||||||
|
|
||||||
console.log('🔌 [WebSocket] Подключение к:', wsUrl);
|
// console.log('🔌 [WebSocket] Подключение к:', wsUrl);
|
||||||
console.log('🔌 [WebSocket] Текущий хост:', window.location.host);
|
// console.log('🔌 [WebSocket] Текущий хост:', window.location.host);
|
||||||
|
|
||||||
this.ws = new WebSocket(wsUrl);
|
this.ws = new WebSocket(wsUrl);
|
||||||
|
|
||||||
this.ws.onopen = () => {
|
this.ws.onopen = () => {
|
||||||
console.log('✅ [WebSocket] Подключение установлено');
|
// console.log('✅ [WebSocket] Подключение установлено');
|
||||||
this.isConnected = true;
|
this.isConnected = true;
|
||||||
this.reconnectAttempts = 0;
|
this.reconnectAttempts = 0;
|
||||||
|
|
||||||
@@ -65,66 +65,42 @@ class WebSocketService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.ws.onclose = (event) => {
|
this.ws.onclose = (event) => {
|
||||||
console.log('🔌 [WebSocket] Соединение закрыто:', event.code, event.reason);
|
// console.log('🔌 [WebSocket] Соединение закрыто:', event.code, event.reason);
|
||||||
this.isConnected = false;
|
this.isConnected = false;
|
||||||
this.emit('disconnected', event);
|
this.emit('disconnected', event);
|
||||||
|
|
||||||
// Попытка переподключения
|
// Попытка переподключения
|
||||||
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
||||||
this.reconnectAttempts++;
|
this.reconnectAttempts++;
|
||||||
console.log(`🔄 [WebSocket] Попытка переподключения ${this.reconnectAttempts}/${this.maxReconnectAttempts}`);
|
// console.log(`🔄 [WebSocket] Попытка переподключения ${this.reconnectAttempts}/${this.maxReconnectAttempts}`);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.connect(this.userId);
|
this.connect(this.userId);
|
||||||
}, this.reconnectDelay * this.reconnectAttempts);
|
}, this.reconnectDelay * this.reconnectAttempts);
|
||||||
} else {
|
} else {
|
||||||
console.error('❌ [WebSocket] Превышено максимальное количество попыток переподключения');
|
// console.error('❌ [WebSocket] Превышено максимальное количество попыток переподключения');
|
||||||
this.emit('reconnect-failed');
|
this.emit('reconnect-failed');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.ws.onerror = (error) => {
|
this.ws.onerror = (error) => {
|
||||||
console.error('❌ [WebSocket] Ошибка соединения:', error);
|
// console.error('❌ [WebSocket] Ошибка соединения:', error);
|
||||||
this.emit('error', error);
|
this.emit('error', error);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.ws.onmessage = (event) => {
|
this.ws.onmessage = (event) => {
|
||||||
try {
|
try {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
console.log('📨 [WebSocket] Получено сообщение:', data);
|
// console.log('📨 [WebSocket] Получено сообщение:', data);
|
||||||
console.log('📨 [WebSocket] Тип сообщения:', data.type);
|
// console.log('📨 [WebSocket] Тип сообщения:', data.type);
|
||||||
this.handleMessage(data);
|
this.handleMessage(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ [WebSocket] Ошибка парсинга сообщения:', error);
|
// console.error('❌ [WebSocket] Ошибка парсинга сообщения:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.ws.onclose = (event) => {
|
|
||||||
console.log('🔌 [WebSocket] Соединение закрыто:', event.code, event.reason);
|
|
||||||
this.isConnected = false;
|
|
||||||
this.emit('disconnected', event);
|
|
||||||
|
|
||||||
// Попытка переподключения
|
|
||||||
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
||||||
this.reconnectAttempts++;
|
|
||||||
console.log(`🔄 [WebSocket] Попытка переподключения ${this.reconnectAttempts}/${this.maxReconnectAttempts}`);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
this.connect(this.userId);
|
|
||||||
}, this.reconnectDelay * this.reconnectAttempts);
|
|
||||||
} else {
|
|
||||||
console.error('❌ [WebSocket] Превышено максимальное количество попыток переподключения');
|
|
||||||
this.emit('reconnect-failed');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.ws.onerror = (error) => {
|
|
||||||
console.error('❌ [WebSocket] Ошибка соединения:', error);
|
|
||||||
this.emit('error', error);
|
|
||||||
};
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ [WebSocket] Ошибка создания соединения:', error);
|
// console.error('❌ [WebSocket] Ошибка создания соединения:', error);
|
||||||
this.emit('error', error);
|
this.emit('error', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,7 +110,7 @@ class WebSocketService {
|
|||||||
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
||||||
this.ws.send(JSON.stringify(data));
|
this.ws.send(JSON.stringify(data));
|
||||||
} else {
|
} else {
|
||||||
console.warn('⚠️ [WebSocket] Соединение не установлено, сообщение не отправлено:', data);
|
// console.warn('⚠️ [WebSocket] Соединение не установлено, сообщение не отправлено:', data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,57 +118,57 @@ class WebSocketService {
|
|||||||
handleMessage(data) {
|
handleMessage(data) {
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
case 'auth-success':
|
case 'auth-success':
|
||||||
console.log('✅ [WebSocket] Аутентификация успешна для пользователя:', data.userId);
|
// console.log('✅ [WebSocket] Аутентификация успешна для пользователя:', data.userId);
|
||||||
this.emit('auth-success', data);
|
this.emit('auth-success', data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'chat-message':
|
case 'chat-message':
|
||||||
console.log('💬 [WebSocket] Новое сообщение чата:', data.message);
|
// console.log('💬 [WebSocket] Новое сообщение чата:', data.message);
|
||||||
this.emit('chat-message', data.message);
|
this.emit('chat-message', data.message);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'conversation-updated':
|
case 'conversation-updated':
|
||||||
console.log('📝 [WebSocket] Обновление диалога:', data.conversationId);
|
// console.log('📝 [WebSocket] Обновление диалога:', data.conversationId);
|
||||||
this.emit('conversation-updated', data.conversationId);
|
this.emit('conversation-updated', data.conversationId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'messages-updated':
|
case 'messages-updated':
|
||||||
console.log('📨 [WebSocket] Обновление сообщений');
|
// console.log('📨 [WebSocket] Обновление сообщений');
|
||||||
this.emit('messages-updated');
|
this.emit('messages-updated');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'contacts-updated':
|
case 'contacts-updated':
|
||||||
console.log('👥 [WebSocket] Обновление контактов');
|
// console.log('👥 [WebSocket] Обновление контактов');
|
||||||
this.emit('contacts-updated');
|
this.emit('contacts-updated');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'tags-updated':
|
case 'tags-updated':
|
||||||
console.log('🔔 [websocketService] Получено сообщение tags-updated:', data);
|
// console.log('🔔 [websocketService] Получено сообщение tags-updated:', data);
|
||||||
console.log('🔔 [websocketService] Количество слушателей tags-updated:', this.listeners.get('tags-updated')?.length || 0);
|
// console.log('🔔 [websocketService] Количество слушателей tags-updated:', this.listeners.get('tags-updated')?.length || 0);
|
||||||
this.emit('tags-updated', data);
|
this.emit('tags-updated', data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'table-updated':
|
case 'table-updated':
|
||||||
console.log('[WebSocket] table-updated:', data.tableId);
|
// console.log('[WebSocket] table-updated:', data.tableId);
|
||||||
if (tableUpdateSubscribers[data.tableId]) {
|
if (tableUpdateSubscribers[data.tableId]) {
|
||||||
tableUpdateSubscribers[data.tableId].forEach(cb => cb(data));
|
tableUpdateSubscribers[data.tableId].forEach(cb => cb(data));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console.log('❓ [WebSocket] Неизвестный тип сообщения:', data.type);
|
// console.log('❓ [WebSocket] Неизвестный тип сообщения:', data.type);
|
||||||
this.emit('unknown-message', data);
|
this.emit('unknown-message', data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Подписка на события
|
// Подписка на события
|
||||||
on(event, callback) {
|
on(event, callback) {
|
||||||
console.log('🔌 [WebSocket] Подписка на событие:', event);
|
// console.log('🔌 [WebSocket] Подписка на событие:', event);
|
||||||
if (!this.listeners.has(event)) {
|
if (!this.listeners.has(event)) {
|
||||||
this.listeners.set(event, []);
|
this.listeners.set(event, []);
|
||||||
}
|
}
|
||||||
this.listeners.get(event).push(callback);
|
this.listeners.get(event).push(callback);
|
||||||
console.log('🔌 [WebSocket] Количество слушателей для', event, ':', this.listeners.get(event).length);
|
// console.log('🔌 [WebSocket] Количество слушателей для', event, ':', this.listeners.get(event).length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Отписка от событий
|
// Отписка от событий
|
||||||
@@ -208,20 +184,20 @@ class WebSocketService {
|
|||||||
|
|
||||||
// Эмиссия событий
|
// Эмиссия событий
|
||||||
emit(event, data) {
|
emit(event, data) {
|
||||||
console.log('🔌 [WebSocket] Эмиссия события:', event, 'с данными:', data);
|
// console.log('🔌 [WebSocket] Эмиссия события:', event, 'с данными:', data);
|
||||||
if (this.listeners.has(event)) {
|
if (this.listeners.has(event)) {
|
||||||
const callbacks = this.listeners.get(event);
|
const callbacks = this.listeners.get(event);
|
||||||
console.log('🔌 [WebSocket] Количество колбэков для', event, ':', callbacks.length);
|
// console.log('🔌 [WebSocket] Количество колбэков для', event, ':', callbacks.length);
|
||||||
callbacks.forEach((callback, index) => {
|
callbacks.forEach((callback, index) => {
|
||||||
try {
|
try {
|
||||||
console.log('🔌 [WebSocket] Выполняем колбэк #', index, 'для события', event);
|
// console.log('🔌 [WebSocket] Выполняем колбэк #', index, 'для события', event);
|
||||||
callback(data);
|
callback(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`❌ [WebSocket] Ошибка в обработчике события ${event}:`, error);
|
// console.error(`❌ [WebSocket] Ошибка в обработчике события ${event}:`, error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log('🔌 [WebSocket] Нет слушателей для события:', event);
|
// console.log('🔌 [WebSocket] Нет слушателей для события:', event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +209,7 @@ class WebSocketService {
|
|||||||
}
|
}
|
||||||
this.isConnected = false;
|
this.isConnected = false;
|
||||||
this.listeners.clear();
|
this.listeners.clear();
|
||||||
console.log('🔌 [WebSocket] Отключен');
|
// console.log('🔌 [WebSocket] Отключен');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Получение статуса соединения
|
// Получение статуса соединения
|
||||||
@@ -249,7 +225,7 @@ class WebSocketService {
|
|||||||
|
|
||||||
// Создаем единственный экземпляр
|
// Создаем единственный экземпляр
|
||||||
const websocketService = new WebSocketService();
|
const websocketService = new WebSocketService();
|
||||||
console.log('🔌 [WebSocket] Сервис создан');
|
// console.log('🔌 [WebSocket] Сервис создан');
|
||||||
|
|
||||||
// Подписчики на обновления таблиц: tableId -> [callback]
|
// Подписчики на обновления таблиц: tableId -> [callback]
|
||||||
const tableUpdateSubscribers = {};
|
const tableUpdateSubscribers = {};
|
||||||
@@ -269,17 +245,17 @@ export default {
|
|||||||
websocketService,
|
websocketService,
|
||||||
onTableUpdate,
|
onTableUpdate,
|
||||||
};
|
};
|
||||||
console.log('🔌 [WebSocket] Экспорт завершен');
|
// console.log('🔌 [WebSocket] Экспорт завершен');
|
||||||
|
|
||||||
// Автоматически подключаемся при загрузке модуля
|
// Автоматически подключаемся при загрузке модуля
|
||||||
console.log('🔌 [WebSocket] Автоматическое подключение...');
|
// console.log('🔌 [WebSocket] Автоматическое подключение...');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
console.log('🔌 [WebSocket] Подключаемся через 1 секунду...');
|
// console.log('🔌 [WebSocket] Подключаемся через 1 секунду...');
|
||||||
websocketService.connect();
|
websocketService.connect();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
// Добавляем периодическую проверку состояния соединения
|
// Добавляем периодическую проверку состояния соединения
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
const status = websocketService.getStatus();
|
const status = websocketService.getStatus();
|
||||||
console.log('🔌 [WebSocket] Статус соединения:', status);
|
// console.log('🔌 [WebSocket] Статус соединения:', status);
|
||||||
}, 10000); // Проверяем каждые 10 секунд
|
}, 10000); // Проверяем каждые 10 секунд
|
||||||
@@ -17,7 +17,7 @@ export const isLocalStorageAvailable = () => {
|
|||||||
window.localStorage.removeItem(test);
|
window.localStorage.removeItem(test);
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('localStorage is not available:', e);
|
// console.error('localStorage is not available:', e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -33,7 +33,7 @@ export const getFromStorage = (key, defaultValue = null) => {
|
|||||||
return item || defaultValue;
|
return item || defaultValue;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`Error getting ${key} from localStorage:`, e);
|
// console.error(`Error getting ${key} from localStorage:`, e);
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -48,7 +48,7 @@ export const setToStorage = (key, value) => {
|
|||||||
window.localStorage.setItem(key, valueToStore);
|
window.localStorage.setItem(key, valueToStore);
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`Error setting ${key} in localStorage:`, e);
|
// console.error(`Error setting ${key} in localStorage:`, e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -59,7 +59,7 @@ export const removeFromStorage = (key) => {
|
|||||||
window.localStorage.removeItem(key);
|
window.localStorage.removeItem(key);
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`Error removing ${key} from localStorage:`, e);
|
// console.error(`Error removing ${key} from localStorage:`, e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -16,11 +16,11 @@ import { SiweMessage } from 'siwe';
|
|||||||
|
|
||||||
export const connectWallet = async () => {
|
export const connectWallet = async () => {
|
||||||
try {
|
try {
|
||||||
console.log('Starting wallet connection...');
|
// console.log('Starting wallet connection...');
|
||||||
|
|
||||||
// Проверяем наличие MetaMask или другого Ethereum провайдера
|
// Проверяем наличие MetaMask или другого Ethereum провайдера
|
||||||
if (!window.ethereum) {
|
if (!window.ethereum) {
|
||||||
console.error('No Ethereum provider (like MetaMask) detected!');
|
// console.error('No Ethereum provider (like MetaMask) detected!');
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error:
|
error:
|
||||||
@@ -28,11 +28,11 @@ export const connectWallet = async () => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('MetaMask detected, requesting accounts...');
|
// console.log('MetaMask detected, requesting accounts...');
|
||||||
|
|
||||||
// Запрашиваем доступ к аккаунтам
|
// Запрашиваем доступ к аккаунтам
|
||||||
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
|
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' });
|
||||||
console.log('Got accounts:', accounts);
|
// console.log('Got accounts:', accounts);
|
||||||
|
|
||||||
if (!accounts || accounts.length === 0) {
|
if (!accounts || accounts.length === 0) {
|
||||||
return {
|
return {
|
||||||
@@ -45,13 +45,13 @@ export const connectWallet = async () => {
|
|||||||
const address = accounts[0];
|
const address = accounts[0];
|
||||||
// Нормализуем адрес (приводим к нижнему регистру для последующих сравнений)
|
// Нормализуем адрес (приводим к нижнему регистру для последующих сравнений)
|
||||||
const normalizedAddress = ethers.utils.getAddress(address);
|
const normalizedAddress = ethers.utils.getAddress(address);
|
||||||
console.log('Normalized address:', normalizedAddress);
|
// console.log('Normalized address:', normalizedAddress);
|
||||||
|
|
||||||
// Запрашиваем nonce с сервера
|
// Запрашиваем nonce с сервера
|
||||||
console.log('Requesting nonce...');
|
// console.log('Requesting nonce...');
|
||||||
const nonceResponse = await axios.get(`/auth/nonce?address=${normalizedAddress}`);
|
const nonceResponse = await axios.get(`/auth/nonce?address=${normalizedAddress}`);
|
||||||
const nonce = nonceResponse.data.nonce;
|
const nonce = nonceResponse.data.nonce;
|
||||||
console.log('Got nonce:', nonce);
|
// console.log('Got nonce:', nonce);
|
||||||
|
|
||||||
if (!nonce) {
|
if (!nonce) {
|
||||||
return {
|
return {
|
||||||
@@ -83,10 +83,10 @@ export const connectWallet = async () => {
|
|||||||
|
|
||||||
// Получаем строку сообщения для подписи
|
// Получаем строку сообщения для подписи
|
||||||
const messageToSign = message.prepareMessage();
|
const messageToSign = message.prepareMessage();
|
||||||
console.log('SIWE message:', messageToSign);
|
// console.log('SIWE message:', messageToSign);
|
||||||
|
|
||||||
// Запрашиваем подпись
|
// Запрашиваем подпись
|
||||||
console.log('Requesting signature...');
|
// console.log('Requesting signature...');
|
||||||
const signature = await signer.signMessage(messageToSign);
|
const signature = await signer.signMessage(messageToSign);
|
||||||
|
|
||||||
if (!signature) {
|
if (!signature) {
|
||||||
@@ -96,17 +96,17 @@ export const connectWallet = async () => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Got signature:', signature);
|
// console.log('Got signature:', signature);
|
||||||
|
|
||||||
// Отправляем верификацию на сервер
|
// Отправляем верификацию на сервер
|
||||||
console.log('Sending verification request...');
|
// console.log('Sending verification request...');
|
||||||
const requestData = {
|
const requestData = {
|
||||||
address: normalizedAddress,
|
address: normalizedAddress,
|
||||||
signature,
|
signature,
|
||||||
nonce,
|
nonce,
|
||||||
issuedAt: new Date().toISOString(),
|
issuedAt: new Date().toISOString(),
|
||||||
};
|
};
|
||||||
console.log('Request data:', requestData);
|
// console.log('Request data:', requestData);
|
||||||
|
|
||||||
const verifyResponse = await axios.post('/api/auth/verify', requestData, {
|
const verifyResponse = await axios.post('/api/auth/verify', requestData, {
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
@@ -130,7 +130,7 @@ export const connectWallet = async () => {
|
|||||||
if (authButtonsEl) authButtonsEl.style.display = 'none';
|
if (authButtonsEl) authButtonsEl.style.display = 'none';
|
||||||
if (logoutButtonEl) logoutButtonEl.style.display = 'inline-block';
|
if (logoutButtonEl) logoutButtonEl.style.display = 'inline-block';
|
||||||
|
|
||||||
console.log('Verification response:', verifyResponse.data);
|
// console.log('Verification response:', verifyResponse.data);
|
||||||
|
|
||||||
if (verifyResponse.data.success) {
|
if (verifyResponse.data.success) {
|
||||||
return {
|
return {
|
||||||
@@ -146,7 +146,7 @@ export const connectWallet = async () => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error connecting wallet:', error);
|
// console.error('Error connecting wallet:', error);
|
||||||
|
|
||||||
// Формируем понятное сообщение об ошибке
|
// Формируем понятное сообщение об ошибке
|
||||||
let errorMessage = 'Произошла ошибка при подключении кошелька.';
|
let errorMessage = 'Произошла ошибка при подключении кошелька.';
|
||||||
|
|||||||
@@ -93,24 +93,24 @@ function connectWebSocket() {
|
|||||||
const wsProtocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
|
const wsProtocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
|
||||||
ws = new WebSocket(`${wsProtocol}://${window.location.host}/ws`);
|
ws = new WebSocket(`${wsProtocol}://${window.location.host}/ws`);
|
||||||
ws.onopen = () => {
|
ws.onopen = () => {
|
||||||
console.log('[CRM] WebSocket соединение установлено');
|
// console.log('[CRM] WebSocket соединение установлено');
|
||||||
};
|
};
|
||||||
ws.onmessage = (event) => {
|
ws.onmessage = (event) => {
|
||||||
try {
|
try {
|
||||||
const msg = JSON.parse(event.data);
|
const msg = JSON.parse(event.data);
|
||||||
if (msg.type === 'contacts-updated') {
|
if (msg.type === 'contacts-updated') {
|
||||||
console.log('[CRM] Получено событие contacts-updated, обновляем контакты');
|
// console.log('[CRM] Получено событие contacts-updated, обновляем контакты');
|
||||||
loadContacts();
|
loadContacts();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[CRM] Ошибка обработки сообщения WebSocket:', e);
|
// console.error('[CRM] Ошибка обработки сообщения WebSocket:', e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ws.onclose = () => {
|
ws.onclose = () => {
|
||||||
console.log('[CRM] WebSocket соединение закрыто');
|
// console.log('[CRM] WebSocket соединение закрыто');
|
||||||
};
|
};
|
||||||
ws.onerror = (e) => {
|
ws.onerror = (e) => {
|
||||||
console.error('[CRM] WebSocket ошибка:', e);
|
// console.error('[CRM] WebSocket ошибка:', e);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ const loadDLEs = async () => {
|
|||||||
selectedDleIndex.value = 0;
|
selectedDleIndex.value = 0;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при загрузке списка DLE:', error);
|
// console.error('Ошибка при загрузке списка DLE:', error);
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ const loadDLEs = async () => {
|
|||||||
|
|
||||||
// Обработчик события изменения авторизации
|
// Обработчик события изменения авторизации
|
||||||
const handleAuthEvent = (eventData) => {
|
const handleAuthEvent = (eventData) => {
|
||||||
console.log('[CrmView] Получено событие изменения авторизации:', eventData);
|
// console.log('[CrmView] Получено событие изменения авторизации:', eventData);
|
||||||
if (eventData.isAuthenticated) {
|
if (eventData.isAuthenticated) {
|
||||||
loadDLEs();
|
loadDLEs();
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@ const handleAuthEvent = (eventData) => {
|
|||||||
let unsubscribe = null;
|
let unsubscribe = null;
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log('[CrmView] Компонент загружен');
|
// console.log('[CrmView] Компонент загружен');
|
||||||
|
|
||||||
// Если пользователь авторизован, загружаем данные
|
// Если пользователь авторизован, загружаем данные
|
||||||
if (auth.isAuthenticated.value) {
|
if (auth.isAuthenticated.value) {
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
import BaseLayout from '../components/BaseLayout.vue';
|
import BaseLayout from '../components/BaseLayout.vue';
|
||||||
import ChatInterface from '../components/ChatInterface.vue';
|
import ChatInterface from '../components/ChatInterface.vue';
|
||||||
|
|
||||||
console.log('HomeView.vue: Using BaseLayout');
|
// console.log('HomeView.vue: Using BaseLayout');
|
||||||
|
|
||||||
// Определяем props, переданные из App.vue через RouterView
|
// Определяем props, переданные из App.vue через RouterView
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
let unsubscribe = null;
|
let unsubscribe = null;
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
console.log('[HomeView] Компонент загружен (обновленная версия)');
|
// console.log('[HomeView] Компонент загружен (обновленная версия)');
|
||||||
|
|
||||||
// Подписка на события авторизации
|
// Подписка на события авторизации
|
||||||
unsubscribe = eventBus.on('auth-state-changed', handleAuthEvent);
|
unsubscribe = eventBus.on('auth-state-changed', handleAuthEvent);
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
|
|
||||||
// Функция обновления сообщений после авторизации
|
// Функция обновления сообщений после авторизации
|
||||||
const handleAuthEvent = async (eventData) => {
|
const handleAuthEvent = async (eventData) => {
|
||||||
console.log('[HomeView] Получено событие изменения авторизации:', eventData);
|
// console.log('[HomeView] Получено событие изменения авторизации:', eventData);
|
||||||
if (eventData.isAuthenticated) {
|
if (eventData.isAuthenticated) {
|
||||||
// Сначала связываем гостевые сообщения, если есть
|
// Сначала связываем гостевые сообщения, если есть
|
||||||
await linkGuestMessagesAfterAuth();
|
await linkGuestMessagesAfterAuth();
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ async function loadContact() {
|
|||||||
error.value = 'Контакт не найден';
|
error.value = 'Контакт не найден';
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Ошибка загрузки контакта:', e);
|
// console.error('Ошибка загрузки контакта:', e);
|
||||||
contact.value = null;
|
contact.value = null;
|
||||||
error.value = 'Контакт не найден';
|
error.value = 'Контакт не найден';
|
||||||
} finally {
|
} finally {
|
||||||
@@ -72,7 +72,7 @@ async function deleteContact() {
|
|||||||
error.value = '';
|
error.value = '';
|
||||||
try {
|
try {
|
||||||
const result = await contactsService.deleteContact(contact.value.id);
|
const result = await contactsService.deleteContact(contact.value.id);
|
||||||
console.log('Результат удаления:', result);
|
// console.log('Результат удаления:', result);
|
||||||
|
|
||||||
// Если удаление успешно или пользователь уже удален
|
// Если удаление успешно или пользователь уже удален
|
||||||
if (result.success || result.message === 'Пользователь уже удален') {
|
if (result.success || result.message === 'Пользователь уже удален') {
|
||||||
@@ -81,7 +81,7 @@ async function deleteContact() {
|
|||||||
error.value = 'Ошибка при удалении контакта';
|
error.value = 'Ошибка при удалении контакта';
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Ошибка при удалении:', e);
|
// console.error('Ошибка при удалении:', e);
|
||||||
error.value = 'Ошибка при удалении контакта';
|
error.value = 'Ошибка при удалении контакта';
|
||||||
} finally {
|
} finally {
|
||||||
isDeleting.value = false;
|
isDeleting.value = false;
|
||||||
|
|||||||
@@ -470,9 +470,9 @@ async function handleSendMessage({ message, attachments }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleAiReply(selectedMessages = []) {
|
async function handleAiReply(selectedMessages = []) {
|
||||||
console.log('[AI-ASSISTANT] Кнопка нажата, messages:', messages.value);
|
// console.log('[AI-ASSISTANT] Кнопка нажата, messages:', messages.value);
|
||||||
if (isAiLoading.value) {
|
if (isAiLoading.value) {
|
||||||
console.log('[AI-ASSISTANT] Уже идёт генерация, выход');
|
// console.log('[AI-ASSISTANT] Уже идёт генерация, выход');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!Array.isArray(selectedMessages) || selectedMessages.length === 0) {
|
if (!Array.isArray(selectedMessages) || selectedMessages.length === 0) {
|
||||||
@@ -485,7 +485,7 @@ async function handleAiReply(selectedMessages = []) {
|
|||||||
const draftResp = await messagesService.generateAiDraft(conversationId.value, selectedMessages);
|
const draftResp = await messagesService.generateAiDraft(conversationId.value, selectedMessages);
|
||||||
if (draftResp && draftResp.success && draftResp.aiMessage) {
|
if (draftResp && draftResp.success && draftResp.aiMessage) {
|
||||||
chatNewMessage.value = draftResp.aiMessage;
|
chatNewMessage.value = draftResp.aiMessage;
|
||||||
console.log('[AI-ASSISTANT] Черновик сгенерирован:', draftResp.aiMessage);
|
// console.log('[AI-ASSISTANT] Черновик сгенерирован:', draftResp.aiMessage);
|
||||||
} else {
|
} else {
|
||||||
alert('Не удалось сгенерировать ответ ИИ.');
|
alert('Не удалось сгенерировать ответ ИИ.');
|
||||||
}
|
}
|
||||||
@@ -493,7 +493,7 @@ async function handleAiReply(selectedMessages = []) {
|
|||||||
alert('Ошибка генерации ответа ИИ: ' + (e?.message || e));
|
alert('Ошибка генерации ответа ИИ: ' + (e?.message || e));
|
||||||
} finally {
|
} finally {
|
||||||
isAiLoading.value = false;
|
isAiLoading.value = false;
|
||||||
console.log('[AI-ASSISTANT] Генерация завершена');
|
// console.log('[AI-ASSISTANT] Генерация завершена');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,9 +536,9 @@ async function createTag() {
|
|||||||
const descCol = table.columns[1];
|
const descCol = table.columns[1];
|
||||||
// 1. Создаём строку
|
// 1. Создаём строку
|
||||||
const newRow = await tablesService.addRow(tableId);
|
const newRow = await tablesService.addRow(tableId);
|
||||||
console.log('DEBUG newRow:', newRow);
|
// console.log('DEBUG newRow:', newRow);
|
||||||
if (!newRow || !newRow.id) {
|
if (!newRow || !newRow.id) {
|
||||||
console.error('Ошибка: не удалось получить id новой строки', newRow);
|
// console.error('Ошибка: не удалось получить id новой строки', newRow);
|
||||||
alert('Ошибка: не удалось получить id новой строки. См. консоль.');
|
alert('Ошибка: не удалось получить id новой строки. См. консоль.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -618,7 +618,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
// Подписываемся на обновления тегов
|
// Подписываемся на обновления тегов
|
||||||
unsubscribeFromTags = onTagsUpdate(async () => {
|
unsubscribeFromTags = onTagsUpdate(async () => {
|
||||||
console.log('[ContactDetailsView] Получено обновление тегов, перезагружаем списки тегов');
|
// console.log('[ContactDetailsView] Получено обновление тегов, перезагружаем списки тегов');
|
||||||
await loadAllTags();
|
await loadAllTags();
|
||||||
await loadUserTags();
|
await loadUserTags();
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1006,10 +1006,10 @@ const getOkvedLevel = (code) => {
|
|||||||
|
|
||||||
// Функция для загрузки ОКВЭД кодов определенного уровня
|
// Функция для загрузки ОКВЭД кодов определенного уровня
|
||||||
const fetchOkvedCodes = async (level, parentCode, optionsRef, loadingRef) => {
|
const fetchOkvedCodes = async (level, parentCode, optionsRef, loadingRef) => {
|
||||||
console.log(`🔍 fetchOkvedCodes вызвана: level=${level}, parentCode=${parentCode || 'root'}`);
|
// console.log(`🔍 fetchOkvedCodes вызвана: level=${level}, parentCode=${parentCode || 'root'}`);
|
||||||
|
|
||||||
if (!optionsRef || !loadingRef) {
|
if (!optionsRef || !loadingRef) {
|
||||||
console.error('[DleDeployForm] fetchOkvedCodes requires optionsRef and loadingRef');
|
// console.error('[DleDeployForm] fetchOkvedCodes requires optionsRef and loadingRef');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1017,8 +1017,8 @@ const fetchOkvedCodes = async (level, parentCode, optionsRef, loadingRef) => {
|
|||||||
optionsRef.value = [];
|
optionsRef.value = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log(`[DleDeployForm] Загрузка ОКВЭД уровень ${level}, родитель: ${parentCode || 'root'}`);
|
// console.log(`[DleDeployForm] Загрузка ОКВЭД уровень ${level}, родитель: ${parentCode || 'root'}`);
|
||||||
console.log(`[DleDeployForm] Доступно ОКВЭД кодов: ${russianClassifiers.okved?.length || 0}`);
|
// console.log(`[DleDeployForm] Доступно ОКВЭД кодов: ${russianClassifiers.okved?.length || 0}`);
|
||||||
|
|
||||||
// Фильтруем коды из уже загруженных данных
|
// Фильтруем коды из уже загруженных данных
|
||||||
let filteredCodes = [];
|
let filteredCodes = [];
|
||||||
@@ -1042,11 +1042,11 @@ const fetchOkvedCodes = async (level, parentCode, optionsRef, loadingRef) => {
|
|||||||
text: `${code.code} - ${code.title}`
|
text: `${code.code} - ${code.title}`
|
||||||
}));
|
}));
|
||||||
|
|
||||||
console.log(`[DleDeployForm] Загружено ОКВЭД кодов уровня ${level}: ${optionsRef.value.length}`);
|
// console.log(`[DleDeployForm] Загружено ОКВЭД кодов уровня ${level}: ${optionsRef.value.length}`);
|
||||||
console.log(`[DleDeployForm] Первые 3 кода:`, optionsRef.value.slice(0, 3));
|
// console.log(`[DleDeployForm] Первые 3 кода:`, optionsRef.value.slice(0, 3));
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[DleDeployForm] Ошибка при загрузке ОКВЭД кодов:', error);
|
// console.error('[DleDeployForm] Ошибка при загрузке ОКВЭД кодов:', error);
|
||||||
} finally {
|
} finally {
|
||||||
loadingRef.value = false;
|
loadingRef.value = false;
|
||||||
}
|
}
|
||||||
@@ -1083,7 +1083,7 @@ const updateCurrentOkvedSelection = () => {
|
|||||||
|
|
||||||
// Watchers для 2-уровневой загрузки ОКВЭД
|
// Watchers для 2-уровневой загрузки ОКВЭД
|
||||||
watch(selectedOkvedLevel1, (newVal) => {
|
watch(selectedOkvedLevel1, (newVal) => {
|
||||||
console.log('[DleDeployForm] selectedOkvedLevel1 changed to:', newVal);
|
// console.log('[DleDeployForm] selectedOkvedLevel1 changed to:', newVal);
|
||||||
selectedOkvedLevel2.value = '';
|
selectedOkvedLevel2.value = '';
|
||||||
okvedLevel2Options.value = [];
|
okvedLevel2Options.value = [];
|
||||||
|
|
||||||
@@ -1094,7 +1094,7 @@ watch(selectedOkvedLevel1, (newVal) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
watch(selectedOkvedLevel2, () => {
|
watch(selectedOkvedLevel2, () => {
|
||||||
console.log('[DleDeployForm] selectedOkvedLevel2 changed to:', selectedOkvedLevel2.value);
|
// console.log('[DleDeployForm] selectedOkvedLevel2 changed to:', selectedOkvedLevel2.value);
|
||||||
updateCurrentOkvedSelection();
|
updateCurrentOkvedSelection();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1297,9 +1297,9 @@ const saveFormData = () => {
|
|||||||
showUnifiedKey: showUnifiedKey.value
|
showUnifiedKey: showUnifiedKey.value
|
||||||
};
|
};
|
||||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(dataToSave));
|
localStorage.setItem(STORAGE_KEY, JSON.stringify(dataToSave));
|
||||||
console.log('[DleDeployForm] Данные формы сохранены в localStorage');
|
// console.log('[DleDeployForm] Данные формы сохранены в localStorage');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[DleDeployForm] Ошибка сохранения данных:', error);
|
// console.error('[DleDeployForm] Ошибка сохранения данных:', error);
|
||||||
}
|
}
|
||||||
}, 500); // Задержка 500мс
|
}, 500); // Задержка 500мс
|
||||||
};
|
};
|
||||||
@@ -1362,11 +1362,11 @@ const loadFormData = () => {
|
|||||||
Object.assign(keyValidation, parsedData.keyValidation || {});
|
Object.assign(keyValidation, parsedData.keyValidation || {});
|
||||||
showUnifiedKey.value = parsedData.showUnifiedKey || false;
|
showUnifiedKey.value = parsedData.showUnifiedKey || false;
|
||||||
|
|
||||||
console.log('[DleDeployForm] Данные формы восстановлены из localStorage');
|
// console.log('[DleDeployForm] Данные формы восстановлены из localStorage');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[DleDeployForm] Ошибка восстановления данных:', error);
|
// console.error('[DleDeployForm] Ошибка восстановления данных:', error);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -1375,9 +1375,9 @@ const loadFormData = () => {
|
|||||||
const clearStoredData = () => {
|
const clearStoredData = () => {
|
||||||
try {
|
try {
|
||||||
localStorage.removeItem(STORAGE_KEY);
|
localStorage.removeItem(STORAGE_KEY);
|
||||||
console.log('[DleDeployForm] Данные формы удалены из localStorage');
|
// console.log('[DleDeployForm] Данные формы удалены из localStorage');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[DleDeployForm] Ошибка очистки localStorage:', error);
|
// console.error('[DleDeployForm] Ошибка очистки localStorage:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1463,7 +1463,7 @@ const searchByPostalCode = async () => {
|
|||||||
params.append('countrycodes', 'RU');
|
params.append('countrycodes', 'RU');
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[SearchByPostalCode] Querying Nominatim: ${params.toString()}`);
|
// console.log(`[SearchByPostalCode] Querying Nominatim: ${params.toString()}`);
|
||||||
const response = await axios.get(`/geocoding/nominatim-search?${params.toString()}`);
|
const response = await axios.get(`/geocoding/nominatim-search?${params.toString()}`);
|
||||||
|
|
||||||
if (response.data && Array.isArray(response.data) && response.data.length > 0) {
|
if (response.data && Array.isArray(response.data) && response.data.length > 0) {
|
||||||
@@ -1483,18 +1483,18 @@ const searchByPostalCode = async () => {
|
|||||||
rawData: result.address // Сохраняем все сырые данные для анализа
|
rawData: result.address // Сохраняем все сырые данные для анализа
|
||||||
}));
|
}));
|
||||||
|
|
||||||
console.log(`[SearchByPostalCode] Found ${searchResults.value.length} results`);
|
// console.log(`[SearchByPostalCode] Found ${searchResults.value.length} results`);
|
||||||
|
|
||||||
// Автоматически заполняем поля первым результатом
|
// Автоматически заполняем поля первым результатом
|
||||||
if (searchResults.value.length > 0) {
|
if (searchResults.value.length > 0) {
|
||||||
fillFromSearchResult(searchResults.value[0]);
|
fillFromSearchResult(searchResults.value[0]);
|
||||||
console.log('[SearchByPostalCode] Auto-filled with first result');
|
// console.log('[SearchByPostalCode] Auto-filled with first result');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('[SearchByPostalCode] No results found');
|
// console.log('[SearchByPostalCode] No results found');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при поиске по индексу:', error);
|
// console.error('Ошибка при поиске по индексу:', error);
|
||||||
} finally {
|
} finally {
|
||||||
isSearchingAddress.value = false;
|
isSearchingAddress.value = false;
|
||||||
}
|
}
|
||||||
@@ -1509,7 +1509,7 @@ const findOktmoByAddress = (result) => {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[FindOktmo] Searching OKTMO for region: "${region}"`);
|
// console.log(`[FindOktmo] Searching OKTMO for region: "${region}"`);
|
||||||
|
|
||||||
// Ищем совпадение по названию региона
|
// Ищем совпадение по названию региона
|
||||||
const foundOktmo = russianClassifiers.oktmo.find(oktmo => {
|
const foundOktmo = russianClassifiers.oktmo.find(oktmo => {
|
||||||
@@ -1523,11 +1523,11 @@ const findOktmoByAddress = (result) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (foundOktmo) {
|
if (foundOktmo) {
|
||||||
console.log(`[FindOktmo] Found OKTMO: ${foundOktmo.code} - ${foundOktmo.title}`);
|
// console.log(`[FindOktmo] Found OKTMO: ${foundOktmo.code} - ${foundOktmo.title}`);
|
||||||
return foundOktmo.code;
|
return foundOktmo.code;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[FindOktmo] No OKTMO found for region: "${region}"`);
|
// console.log(`[FindOktmo] No OKTMO found for region: "${region}"`);
|
||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1549,13 +1549,13 @@ const fillFromSearchResult = (result) => {
|
|||||||
if (autoOktmo) {
|
if (autoOktmo) {
|
||||||
dleSettings.selectedOktmo = autoOktmo;
|
dleSettings.selectedOktmo = autoOktmo;
|
||||||
autoSelectedOktmo.value = true; // Помечаем как автовыбранный
|
autoSelectedOktmo.value = true; // Помечаем как автовыбранный
|
||||||
console.log(`[FillFromSearchResult] Auto-selected OKTMO: ${autoOktmo}`);
|
// console.log(`[FillFromSearchResult] Auto-selected OKTMO: ${autoOktmo}`);
|
||||||
} else {
|
} else {
|
||||||
autoSelectedOktmo.value = false;
|
autoSelectedOktmo.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[FillFromSearchResult] Filled address data:', dleSettings.addressData);
|
// console.log('[FillFromSearchResult] Filled address data:', dleSettings.addressData);
|
||||||
console.log('[FillFromSearchResult] Saved API result:', result);
|
// console.log('[FillFromSearchResult] Saved API result:', result);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Проверка адреса (повторный запрос для валидации)
|
// Проверка адреса (повторный запрос для валидации)
|
||||||
|
|||||||
@@ -99,15 +99,15 @@ function validatePrivateKey(key) {
|
|||||||
if (!key) return false;
|
if (!key) return false;
|
||||||
const trimmed = key.trim();
|
const trimmed = key.trim();
|
||||||
if (!trimmed.startsWith('-----BEGIN OPENSSH PRIVATE KEY-----')) {
|
if (!trimmed.startsWith('-----BEGIN OPENSSH PRIVATE KEY-----')) {
|
||||||
console.error('Ключ не начинается с -----BEGIN OPENSSH PRIVATE KEY-----');
|
// console.error('Ключ не начинается с -----BEGIN OPENSSH PRIVATE KEY-----');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!trimmed.endsWith('-----END OPENSSH PRIVATE KEY-----')) {
|
if (!trimmed.endsWith('-----END OPENSSH PRIVATE KEY-----')) {
|
||||||
console.error('Ключ не заканчивается на -----END OPENSSH PRIVATE KEY-----');
|
// console.error('Ключ не заканчивается на -----END OPENSSH PRIVATE KEY-----');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (trimmed.split('\n').length < 3) {
|
if (trimmed.split('\n').length < 3) {
|
||||||
console.error('Ключ слишком короткий или не содержит переносов строк');
|
// console.error('Ключ слишком короткий или не содержит переносов строк');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -124,15 +124,15 @@ const handleSubmit = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Логирование ключа (только для отладки!)
|
// Логирование ключа (только для отладки!)
|
||||||
console.log('SSH ключ (начало):', form.sshKey.slice(0, 40));
|
// console.log('SSH ключ (начало):', form.sshKey.slice(0, 40));
|
||||||
console.log('SSH ключ (конец):', form.sshKey.slice(-40));
|
// console.log('SSH ключ (конец):', form.sshKey.slice(-40));
|
||||||
console.log('Длина ключа:', form.sshKey.length);
|
// console.log('Длина ключа:', form.sshKey.length);
|
||||||
|
|
||||||
// Логирование отправляемых данных (без самого ключа)
|
// Логирование отправляемых данных (без самого ключа)
|
||||||
console.log('Данные для агента:', {
|
// console.log('Данные для агента:', {
|
||||||
...form,
|
// ...form,
|
||||||
sshKey: form.sshKey ? `[скрыто, длина: ${form.sshKey.length}]` : 'нет ключа'
|
// sshKey: form.sshKey ? `[скрыто, длина: ${form.sshKey.length}]` : 'нет ключа'
|
||||||
});
|
// });
|
||||||
|
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
addLog('info', 'Запуск публикации...');
|
addLog('info', 'Запуск публикации...');
|
||||||
@@ -228,7 +228,7 @@ const checkConnectionStatus = async () => {
|
|||||||
? `Подключено к ${status.domain}`
|
? `Подключено к ${status.domain}`
|
||||||
: 'Не подключено';
|
: 'Не подключено';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка проверки статуса:', error);
|
// console.error('Ошибка проверки статуса:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -467,7 +467,7 @@ async function addModule() {
|
|||||||
alert('✅ Модуль успешно добавлен!');
|
alert('✅ Модуль успешно добавлен!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при добавлении модуля:', error);
|
// console.error('Ошибка при добавлении модуля:', error);
|
||||||
alert('❌ Ошибка при добавлении модуля: ' + error.message);
|
alert('❌ Ошибка при добавлении модуля: ' + error.message);
|
||||||
} finally {
|
} finally {
|
||||||
isAdding.value = false;
|
isAdding.value = false;
|
||||||
@@ -486,7 +486,7 @@ async function removeModule(moduleId) {
|
|||||||
alert('✅ Модуль успешно удален!');
|
alert('✅ Модуль успешно удален!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при удалении модуля:', error);
|
// console.error('Ошибка при удалении модуля:', error);
|
||||||
alert('❌ Ошибка при удалении модуля: ' + error.message);
|
alert('❌ Ошибка при удалении модуля: ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -495,7 +495,7 @@ async function removeModule(moduleId) {
|
|||||||
async function installAvailableModule(availableModule) {
|
async function installAvailableModule(availableModule) {
|
||||||
// Здесь должна быть логика установки модуля
|
// Здесь должна быть логика установки модуля
|
||||||
// Например, деплой модуля и добавление в DLE
|
// Например, деплой модуля и добавление в DLE
|
||||||
console.log('Установка модуля:', availableModule);
|
// console.log('Установка модуля:', availableModule);
|
||||||
alert(`Модуль "${availableModule.name}" будет установлен`);
|
alert(`Модуль "${availableModule.name}" будет установлен`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -454,7 +454,7 @@ async function createMultisigOperation() {
|
|||||||
alert('✅ Операция мультиподписи успешно создана!');
|
alert('✅ Операция мультиподписи успешно создана!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при создании операции мультиподписи:', error);
|
// console.error('Ошибка при создании операции мультиподписи:', error);
|
||||||
alert('❌ Ошибка при создании операции: ' + error.message);
|
alert('❌ Ошибка при создании операции: ' + error.message);
|
||||||
} finally {
|
} finally {
|
||||||
isCreating.value = false;
|
isCreating.value = false;
|
||||||
@@ -471,7 +471,7 @@ async function signOperation(operationId, support) {
|
|||||||
alert('✅ Ваша подпись учтена!');
|
alert('✅ Ваша подпись учтена!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при подписании операции:', error);
|
// console.error('Ошибка при подписании операции:', error);
|
||||||
alert('❌ Ошибка при подписании: ' + error.message);
|
alert('❌ Ошибка при подписании: ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -486,7 +486,7 @@ async function executeOperation(operationId) {
|
|||||||
alert('✅ Операция успешно исполнена!');
|
alert('✅ Операция успешно исполнена!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при исполнении операции:', error);
|
// console.error('Ошибка при исполнении операции:', error);
|
||||||
alert('❌ Ошибка при исполнении операции: ' + error.message);
|
alert('❌ Ошибка при исполнении операции: ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -498,7 +498,7 @@ async function loadOperations() {
|
|||||||
// Пока используем заглушку
|
// Пока используем заглушку
|
||||||
operations.value = [];
|
operations.value = [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при загрузке операций:', error);
|
// console.error('Ошибка при загрузке операций:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,7 +520,7 @@ function resetForm() {
|
|||||||
|
|
||||||
function viewOperationDetails(operationId) {
|
function viewOperationDetails(operationId) {
|
||||||
// Открыть модальное окно с деталями операции
|
// Открыть модальное окно с деталями операции
|
||||||
console.log('Просмотр деталей операции:', operationId);
|
// console.log('Просмотр деталей операции:', operationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@@ -497,7 +497,7 @@ async function createProposal() {
|
|||||||
alert('✅ Предложение успешно создано!');
|
alert('✅ Предложение успешно создано!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при создании предложения:', error);
|
// console.error('Ошибка при создании предложения:', error);
|
||||||
alert('❌ Ошибка при создании предложения: ' + error.message);
|
alert('❌ Ошибка при создании предложения: ' + error.message);
|
||||||
} finally {
|
} finally {
|
||||||
isCreating.value = false;
|
isCreating.value = false;
|
||||||
@@ -555,7 +555,7 @@ async function voteForProposal(proposalId, support) {
|
|||||||
alert('✅ Ваш голос учтен!');
|
alert('✅ Ваш голос учтен!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при голосовании:', error);
|
// console.error('Ошибка при голосовании:', error);
|
||||||
alert('❌ Ошибка при голосовании: ' + error.message);
|
alert('❌ Ошибка при голосовании: ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -570,7 +570,7 @@ async function executeProposal(proposalId) {
|
|||||||
alert('✅ Предложение успешно исполнено!');
|
alert('✅ Предложение успешно исполнено!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при исполнении предложения:', error);
|
// console.error('Ошибка при исполнении предложения:', error);
|
||||||
alert('❌ Ошибка при исполнении предложения: ' + error.message);
|
alert('❌ Ошибка при исполнении предложения: ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -582,7 +582,7 @@ async function loadProposals() {
|
|||||||
// Пока используем заглушку
|
// Пока используем заглушку
|
||||||
proposals.value = [];
|
proposals.value = [];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка при загрузке предложений:', error);
|
// console.error('Ошибка при загрузке предложений:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -603,7 +603,7 @@ function resetForm() {
|
|||||||
|
|
||||||
function viewProposalDetails(proposalId) {
|
function viewProposalDetails(proposalId) {
|
||||||
// Открыть модальное окно с деталями предложения
|
// Открыть модальное окно с деталями предложения
|
||||||
console.log('Просмотр деталей предложения:', proposalId);
|
// console.log('Просмотр деталей предложения:', proposalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ const createProposal = async () => {
|
|||||||
isCreatingProposal.value = true;
|
isCreatingProposal.value = true;
|
||||||
|
|
||||||
// Здесь будет создание предложения в смарт-контракте
|
// Здесь будет создание предложения в смарт-контракте
|
||||||
console.log('Создание предложения:', newProposal.value);
|
// console.log('Создание предложения:', newProposal.value);
|
||||||
|
|
||||||
// Временная логика
|
// Временная логика
|
||||||
const proposal = {
|
const proposal = {
|
||||||
@@ -225,7 +225,7 @@ const createProposal = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка создания предложения:', error);
|
// console.error('Ошибка создания предложения:', error);
|
||||||
} finally {
|
} finally {
|
||||||
isCreatingProposal.value = false;
|
isCreatingProposal.value = false;
|
||||||
}
|
}
|
||||||
@@ -238,7 +238,7 @@ const signProposal = async (proposalId) => {
|
|||||||
isSigning.value = true;
|
isSigning.value = true;
|
||||||
|
|
||||||
// Здесь будет подписание предложения в смарт-контракте
|
// Здесь будет подписание предложения в смарт-контракте
|
||||||
console.log('Подписание предложения:', proposalId);
|
// console.log('Подписание предложения:', proposalId);
|
||||||
|
|
||||||
const proposal = proposals.value.find(p => p.id === proposalId);
|
const proposal = proposals.value.find(p => p.id === proposalId);
|
||||||
if (proposal) {
|
if (proposal) {
|
||||||
@@ -247,7 +247,7 @@ const signProposal = async (proposalId) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка подписания предложения:', error);
|
// console.error('Ошибка подписания предложения:', error);
|
||||||
} finally {
|
} finally {
|
||||||
isSigning.value = false;
|
isSigning.value = false;
|
||||||
}
|
}
|
||||||
@@ -260,7 +260,7 @@ const executeProposal = async (proposalId) => {
|
|||||||
isExecuting.value = true;
|
isExecuting.value = true;
|
||||||
|
|
||||||
// Здесь будет выполнение предложения в смарт-контракте
|
// Здесь будет выполнение предложения в смарт-контракте
|
||||||
console.log('Выполнение предложения:', proposalId);
|
// console.log('Выполнение предложения:', proposalId);
|
||||||
|
|
||||||
const proposal = proposals.value.find(p => p.id === proposalId);
|
const proposal = proposals.value.find(p => p.id === proposalId);
|
||||||
if (proposal) {
|
if (proposal) {
|
||||||
@@ -268,7 +268,7 @@ const executeProposal = async (proposalId) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка выполнения предложения:', error);
|
// console.error('Ошибка выполнения предложения:', error);
|
||||||
} finally {
|
} finally {
|
||||||
isExecuting.value = false;
|
isExecuting.value = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ const updateSettings = async () => {
|
|||||||
isUpdating.value = true;
|
isUpdating.value = true;
|
||||||
|
|
||||||
// Здесь будет логика обновления настроек в смарт-контракте
|
// Здесь будет логика обновления настроек в смарт-контракте
|
||||||
console.log('Обновление настроек:', newSettings.value);
|
// console.log('Обновление настроек:', newSettings.value);
|
||||||
|
|
||||||
// Временная логика
|
// Временная логика
|
||||||
const change = {
|
const change = {
|
||||||
@@ -291,7 +291,7 @@ const updateSettings = async () => {
|
|||||||
alert('Настройки успешно обновлены!');
|
alert('Настройки успешно обновлены!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка обновления настроек:', error);
|
// console.error('Ошибка обновления настроек:', error);
|
||||||
alert('Ошибка при обновлении настроек');
|
alert('Ошибка при обновлении настроек');
|
||||||
} finally {
|
} finally {
|
||||||
isUpdating.value = false;
|
isUpdating.value = false;
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ const saveMainSettings = async () => {
|
|||||||
isSaving.value = true;
|
isSaving.value = true;
|
||||||
|
|
||||||
// Здесь будет логика сохранения основных настроек
|
// Здесь будет логика сохранения основных настроек
|
||||||
console.log('Сохранение основных настроек:', mainSettings.value);
|
// console.log('Сохранение основных настроек:', mainSettings.value);
|
||||||
|
|
||||||
// Временная логика
|
// Временная логика
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
@@ -376,7 +376,7 @@ const saveMainSettings = async () => {
|
|||||||
alert('Основные настройки успешно сохранены!');
|
alert('Основные настройки успешно сохранены!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка сохранения основных настроек:', error);
|
// console.error('Ошибка сохранения основных настроек:', error);
|
||||||
alert('Ошибка при сохранении настроек');
|
alert('Ошибка при сохранении настроек');
|
||||||
} finally {
|
} finally {
|
||||||
isSaving.value = false;
|
isSaving.value = false;
|
||||||
@@ -390,7 +390,7 @@ const saveSecuritySettings = async () => {
|
|||||||
isSaving.value = true;
|
isSaving.value = true;
|
||||||
|
|
||||||
// Здесь будет логика сохранения настроек безопасности
|
// Здесь будет логика сохранения настроек безопасности
|
||||||
console.log('Сохранение настроек безопасности:', securitySettings.value);
|
// console.log('Сохранение настроек безопасности:', securitySettings.value);
|
||||||
|
|
||||||
// Временная логика
|
// Временная логика
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
@@ -398,7 +398,7 @@ const saveSecuritySettings = async () => {
|
|||||||
alert('Настройки безопасности успешно сохранены!');
|
alert('Настройки безопасности успешно сохранены!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка сохранения настроек безопасности:', error);
|
// console.error('Ошибка сохранения настроек безопасности:', error);
|
||||||
alert('Ошибка при сохранении настроек безопасности');
|
alert('Ошибка при сохранении настроек безопасности');
|
||||||
} finally {
|
} finally {
|
||||||
isSaving.value = false;
|
isSaving.value = false;
|
||||||
@@ -412,7 +412,7 @@ const saveNetworkSettings = async () => {
|
|||||||
isSaving.value = true;
|
isSaving.value = true;
|
||||||
|
|
||||||
// Здесь будет логика сохранения настроек сети
|
// Здесь будет логика сохранения настроек сети
|
||||||
console.log('Сохранение настроек сети:', networkSettings.value);
|
// console.log('Сохранение настроек сети:', networkSettings.value);
|
||||||
|
|
||||||
// Временная логика
|
// Временная логика
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
@@ -420,7 +420,7 @@ const saveNetworkSettings = async () => {
|
|||||||
alert('Настройки сети успешно сохранены!');
|
alert('Настройки сети успешно сохранены!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка сохранения настроек сети:', error);
|
// console.error('Ошибка сохранения настроек сети:', error);
|
||||||
alert('Ошибка при сохранении настроек сети');
|
alert('Ошибка при сохранении настроек сети');
|
||||||
} finally {
|
} finally {
|
||||||
isSaving.value = false;
|
isSaving.value = false;
|
||||||
@@ -463,7 +463,7 @@ const importSettings = (event) => {
|
|||||||
|
|
||||||
alert('Настройки успешно импортированы!');
|
alert('Настройки успешно импортированы!');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка импорта настроек:', error);
|
// console.error('Ошибка импорта настроек:', error);
|
||||||
alert('Ошибка при импорте настроек');
|
alert('Ошибка при импорте настроек');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -513,7 +513,7 @@ const deleteDLE = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Здесь будет логика удаления DLE
|
// Здесь будет логика удаления DLE
|
||||||
console.log('Удаление DLE...');
|
// console.log('Удаление DLE...');
|
||||||
alert('DLE будет удален. Это действие может занять некоторое время.');
|
alert('DLE будет удален. Это действие может занять некоторое время.');
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ const transferTokens = async () => {
|
|||||||
isTransferring.value = true;
|
isTransferring.value = true;
|
||||||
|
|
||||||
// Здесь будет логика трансфера токенов
|
// Здесь будет логика трансфера токенов
|
||||||
console.log('Трансфер токенов:', transferData.value);
|
// console.log('Трансфер токенов:', transferData.value);
|
||||||
|
|
||||||
// Временная логика
|
// Временная логика
|
||||||
const amount = parseFloat(transferData.value.amount);
|
const amount = parseFloat(transferData.value.amount);
|
||||||
@@ -266,7 +266,7 @@ const transferTokens = async () => {
|
|||||||
alert('Токены успешно переведены!');
|
alert('Токены успешно переведены!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка трансфера токенов:', error);
|
// console.error('Ошибка трансфера токенов:', error);
|
||||||
alert('Ошибка при переводе токенов');
|
alert('Ошибка при переводе токенов');
|
||||||
} finally {
|
} finally {
|
||||||
isTransferring.value = false;
|
isTransferring.value = false;
|
||||||
@@ -280,7 +280,7 @@ const distributeTokens = async () => {
|
|||||||
isDistributing.value = true;
|
isDistributing.value = true;
|
||||||
|
|
||||||
// Здесь будет логика распределения токенов
|
// Здесь будет логика распределения токенов
|
||||||
console.log('Распределение токенов:', distributionData.value);
|
// console.log('Распределение токенов:', distributionData.value);
|
||||||
|
|
||||||
// Временная логика
|
// Временная логика
|
||||||
const totalAmount = distributionData.value.recipients.reduce((sum, recipient) => {
|
const totalAmount = distributionData.value.recipients.reduce((sum, recipient) => {
|
||||||
@@ -303,7 +303,7 @@ const distributeTokens = async () => {
|
|||||||
alert('Токены успешно распределены!');
|
alert('Токены успешно распределены!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка распределения токенов:', error);
|
// console.error('Ошибка распределения токенов:', error);
|
||||||
alert('Ошибка при распределении токенов');
|
alert('Ошибка при распределении токенов');
|
||||||
} finally {
|
} finally {
|
||||||
isDistributing.value = false;
|
isDistributing.value = false;
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ const performDeposit = async () => {
|
|||||||
isProcessing.value = true;
|
isProcessing.value = true;
|
||||||
|
|
||||||
// Здесь будет логика депозита
|
// Здесь будет логика депозита
|
||||||
console.log('Депозит:', depositData.value);
|
// console.log('Депозит:', depositData.value);
|
||||||
|
|
||||||
// Временная логика
|
// Временная логика
|
||||||
const asset = assets.value.find(a => a.id === depositData.value.asset);
|
const asset = assets.value.find(a => a.id === depositData.value.asset);
|
||||||
@@ -414,7 +414,7 @@ const performDeposit = async () => {
|
|||||||
alert('Депозит успешно выполнен!');
|
alert('Депозит успешно выполнен!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка депозита:', error);
|
// console.error('Ошибка депозита:', error);
|
||||||
alert('Ошибка при выполнении депозита');
|
alert('Ошибка при выполнении депозита');
|
||||||
} finally {
|
} finally {
|
||||||
isProcessing.value = false;
|
isProcessing.value = false;
|
||||||
@@ -428,7 +428,7 @@ const performWithdraw = async () => {
|
|||||||
isProcessing.value = true;
|
isProcessing.value = true;
|
||||||
|
|
||||||
// Здесь будет логика вывода
|
// Здесь будет логика вывода
|
||||||
console.log('Вывод:', withdrawData.value);
|
// console.log('Вывод:', withdrawData.value);
|
||||||
|
|
||||||
// Временная логика
|
// Временная логика
|
||||||
const asset = assets.value.find(a => a.id === withdrawData.value.asset);
|
const asset = assets.value.find(a => a.id === withdrawData.value.asset);
|
||||||
@@ -469,7 +469,7 @@ const performWithdraw = async () => {
|
|||||||
alert('Вывод успешно выполнен!');
|
alert('Вывод успешно выполнен!');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Ошибка вывода:', error);
|
// console.error('Ошибка вывода:', error);
|
||||||
alert('Ошибка при выполнении вывода');
|
alert('Ошибка при выполнении вывода');
|
||||||
} finally {
|
} finally {
|
||||||
isProcessing.value = false;
|
isProcessing.value = false;
|
||||||
|
|||||||
@@ -350,10 +350,10 @@ app.listen(PORT, 'localhost', () => {
|
|||||||
// Обработка необработанных ошибок
|
// Обработка необработанных ошибок
|
||||||
process.on('uncaughtException', (error) => {
|
process.on('uncaughtException', (error) => {
|
||||||
log.error('Необработанная ошибка: ' + error.message);
|
log.error('Необработанная ошибка: ' + error.message);
|
||||||
console.error(error);
|
// console.error(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.on('unhandledRejection', (reason, promise) => {
|
process.on('unhandledRejection', (reason, promise) => {
|
||||||
log.error('Необработанное отклонение промиса: ' + reason);
|
log.error('Необработанное отклонение промиса: ' + reason);
|
||||||
console.error(reason);
|
// console.error(reason);
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user