From 699bdf696142e68a1d9a45f6f1d417bf41b3c886 Mon Sep 17 00:00:00 2001 From: kalugin66 Date: Thu, 5 Feb 2026 16:39:49 +0500 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=84=D0=B0=D0=B8=D0=BB=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB?= =?UTF-8?q?=D0=B5=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/ui.js | 57 +++++++++++++++++++++++++++++------- task-endpoints.js | 74 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 101 insertions(+), 30 deletions(-) diff --git a/public/ui.js b/public/ui.js index aa2f714..31cac93 100644 --- a/public/ui.js +++ b/public/ui.js @@ -82,7 +82,7 @@ function renderTasks() {
${!isDeleted && !isClosed ? ` - ${canEdit ? `` : ''} + ${currentUser && currentUser.login === 'kalugin.o' ? `` : ''} ${currentUser && currentUser.login === 'kalugin.o' ? `` : ''} @@ -113,13 +113,49 @@ ${currentUser && currentUser.login === 'kalugin.o' ? `
+
+ Файлы: + ${task.files && task.files.length > 0 ? + `
+ ${task.files.map(file => { + // Определяем, может ли пользователь видеть этот файл + let canSeeFile = false; + + // 1. Администратор видит все файлы + if (currentUser.role === 'admin') { + canSeeFile = true; + } + // 2. Создатель задачи видит все файлы + else if (parseInt(task.created_by) === currentUser.id) { + canSeeFile = true; + } + // 3. Исполнитель видит: + // - Файлы, загруженные создателем + // - Свои файлы + else { + // Получаем ID создателя задачи + const creatorId = parseInt(task.created_by); + + // Файл загружен создателем + if (parseInt(file.user_id) === creatorId) { + canSeeFile = true; + } + // Файл загружен текущим пользователем (исполнителем) + else if (parseInt(file.user_id) === currentUser.id) { + canSeeFile = true; + } + // Если файл загружен другим исполнителем - не показываем + else { + canSeeFile = false; + } + } + + return canSeeFile ? renderFileIcon(file) : ''; + }).join('')} +
` : + 'нет файлов' + } +
@@ -556,10 +592,11 @@ function openAddFileModal(taskId) { method: 'POST', body: formData }); + console.log('Попытка 1'); if (!response.ok) { // Попробуем с полем 'file' - console.log('Попытка с именем поля "file"...'); + console.log('Попытка 2 с именем поля "file"...'); formData.delete('files'); formData.append('file', file); @@ -568,7 +605,7 @@ function openAddFileModal(taskId) { body: formData }); } - + if (response.ok) { alert('Файл успешно добавлен'); await loadTaskFiles(taskId); diff --git a/task-endpoints.js b/task-endpoints.js index 9919a5d..086cd66 100644 --- a/task-endpoints.js +++ b/task-endpoints.js @@ -1270,43 +1270,77 @@ app.get('/api/document-approval-tasks', requireAuth, (req, res) => { }); }); - app.post('/api/tasks/:taskId/files', requireAuth, upload.array('files', 15), (req, res) => { - const { taskId } = req.params; - const userId = req.session.user.id; +app.post('/api/tasks/:taskId/files', requireAuth, upload.array('files', 15), (req, res) => { + const { taskId } = req.params; + const userId = req.session.user.id; - if (!req.files || req.files.length === 0) { - return res.status(400).json({ error: 'Нет файлов для загрузки' }); + if (!req.files || req.files.length === 0) { + return res.status(400).json({ error: 'Нет файлов для загрузки' }); + } + + // Проверяем доступ к задаче через checkTaskAccess + const { checkTaskAccess } = require('./database'); + + checkTaskAccess(userId, taskId, (err, hasAccess) => { + if (err || !hasAccess) { + return res.status(403).json({ error: 'Нет доступа к задаче' }); } - db.get("SELECT created_by, status, closed_at FROM tasks WHERE id = ?", [taskId], (err, task) => { + // Дополнительно проверяем, что задача активна + db.get("SELECT status, closed_at FROM tasks WHERE id = ?", [taskId], (err, task) => { if (err || !task) { return res.status(404).json({ error: 'Задача не найдена' }); } - // Проверяем права на загрузку файлов - if (!canUserEditTask(task, req.session.user)) { - return res.status(403).json({ error: 'У вас нет прав для загрузки файлов в эту задачу' }); + if (task.closed_at) { + return res.status(400).json({ error: 'Задача уже закрыта' }); } const userFolder = createUserTaskFolder(taskId, req.session.user.login); - req.files.forEach(file => { - const newPath = path.join(userFolder, path.basename(file.filename)); - fs.renameSync(file.path, newPath); + const uploadPromises = req.files.map(file => { + return new Promise((resolve, reject) => { + const newPath = path.join(userFolder, path.basename(file.filename)); + fs.renameSync(file.path, newPath); - const originalName = file.originalname; + const originalName = file.originalname; - db.run( - "INSERT INTO task_files (task_id, user_id, filename, original_name, file_path, file_size) VALUES (?, ?, ?, ?, ?, ?)", - [taskId, userId, path.basename(file.filename), originalName, newPath, file.size] - ); - - logActivity(taskId, userId, 'FILE_UPLOADED', `Загружен файл: ${originalName}`); + db.run( + "INSERT INTO task_files (task_id, user_id, filename, original_name, file_path, file_size) VALUES (?, ?, ?, ?, ?, ?)", + [taskId, userId, path.basename(file.filename), originalName, newPath, file.size], + function(err) { + if (err) { + reject(err); + return; + } + + logActivity(taskId, userId, 'FILE_UPLOADED', `Загружен файл: ${originalName}`); + resolve({ + id: this.lastID, + originalName, + size: file.size + }); + } + ); + }); }); - res.json({ success: true, message: 'Файлы успешно загружены' }); + Promise.all(uploadPromises) + .then((uploadedFiles) => { + res.json({ + success: true, + message: 'Файлы успешно загружены', + files: uploadedFiles, + count: uploadedFiles.length + }); + }) + .catch((error) => { + console.error('Ошибка при загрузке файлов:', error); + res.status(500).json({ error: 'Ошибка при сохранении файлов в БД' }); + }); }); }); +}); // API для получения одной задачи app.get('/api/tasks/:taskId', requireAuth, (req, res) => {