Tasks Module Stage 3: Attachments
- Add migration for task_attachments table - Create TaskAttachmentModel with file handling methods - Add TaskService methods for upload/delete attachments - Add API routes for attachments (upload, delete, download) - Add controller methods for attachment operations - Add UI section in task view with file upload form - Add JavaScript handlers for AJAX file operations
This commit is contained in:
@@ -614,4 +614,110 @@ class TasksController extends BaseController
|
||||
'success' => $result,
|
||||
]);
|
||||
}
|
||||
|
||||
// ========== Вложения (Attachments) ==========
|
||||
|
||||
/**
|
||||
* API: загрузить вложение
|
||||
*/
|
||||
public function uploadAttachment(int $taskId)
|
||||
{
|
||||
if (!$this->access->canEdit('tasks')) {
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'error' => 'Нет прав для изменения задач'
|
||||
]);
|
||||
}
|
||||
|
||||
$organizationId = $this->requireActiveOrg();
|
||||
$userId = $this->getCurrentUserId();
|
||||
|
||||
// Проверяем что задача принадлежит организации
|
||||
$task = $this->taskService->getTask($taskId, $organizationId);
|
||||
if (!$task) {
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'error' => 'Задача не найдена'
|
||||
]);
|
||||
}
|
||||
|
||||
$file = $this->request->getFile('file');
|
||||
if (!$file || !$file->isValid()) {
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'error' => 'Файл не загружен'
|
||||
]);
|
||||
}
|
||||
|
||||
$attachmentId = $this->taskService->uploadAttachment($taskId, [
|
||||
'name' => $file->getName(),
|
||||
'type' => $file->getClientMimeType(),
|
||||
'tmp_name' => $file->getTempName(),
|
||||
'size' => $file->getSize(),
|
||||
], $userId);
|
||||
|
||||
return $this->response->setJSON([
|
||||
'success' => (bool) $attachmentId,
|
||||
'attachment_id' => $attachmentId,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* API: удалить вложение
|
||||
*/
|
||||
public function deleteAttachment(int $taskId, int $attachmentId)
|
||||
{
|
||||
if (!$this->access->canEdit('tasks')) {
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'error' => 'Нет прав для изменения задач'
|
||||
]);
|
||||
}
|
||||
|
||||
$organizationId = $this->requireActiveOrg();
|
||||
$userId = $this->getCurrentUserId();
|
||||
|
||||
// Проверяем что задача принадлежит организации
|
||||
$task = $this->taskService->getTask($taskId, $organizationId);
|
||||
if (!$task) {
|
||||
return $this->response->setJSON([
|
||||
'success' => false,
|
||||
'error' => 'Задача не найдена'
|
||||
]);
|
||||
}
|
||||
|
||||
$result = $this->taskService->deleteAttachment($taskId, $attachmentId, $userId);
|
||||
|
||||
return $this->response->setJSON([
|
||||
'success' => $result,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* API: скачать вложение
|
||||
*/
|
||||
public function downloadAttachment(int $taskId, int $attachmentId)
|
||||
{
|
||||
$organizationId = $this->requireActiveOrg();
|
||||
|
||||
// Проверяем что задача принадлежит организации
|
||||
$task = $this->taskService->getTask($taskId, $organizationId);
|
||||
if (!$task) {
|
||||
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Задача не найдена');
|
||||
}
|
||||
|
||||
$attachmentModel = new \App\Modules\Tasks\Models\TaskAttachmentModel();
|
||||
$attachment = $attachmentModel->find($attachmentId);
|
||||
|
||||
if (!$attachment || $attachment['task_id'] != $taskId) {
|
||||
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Вложение не найдено');
|
||||
}
|
||||
|
||||
if (!file_exists($attachment['file_path'])) {
|
||||
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Файл не найден');
|
||||
}
|
||||
|
||||
return $this->response->download($attachment['file_path'], null)
|
||||
->setFileName($attachment['file_name']);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user