1
0

Управление проектами

Добавил возможность удаления, создание и редактирование проектов.
This commit is contained in:
2026-01-18 10:19:34 +07:00
parent 15725ae90a
commit 250eac70a7
11 changed files with 2273 additions and 16 deletions

View File

@@ -5,6 +5,7 @@ $method = $_SERVER['REQUEST_METHOD'];
if ($method === 'POST') {
$data = RestApi::getInput();
$action = $data['action'] ?? null;
$user_id = RestApi::getCurrentUserId();
// Получение данных проекта (проект + колонки + отделы)
if ($action === 'get_project_data') {
@@ -17,6 +18,117 @@ if ($method === 'POST') {
}
}
// ==================== CRUD ПРОЕКТОВ ====================
// Создание проекта
if ($action === 'create') {
$name = trim($data['name'] ?? '');
if (!$name) {
RestApi::response(['success' => false, 'errors' => ['name' => 'Укажите название проекта']], 400);
}
$result = Project::create($name, $user_id);
RestApi::response($result, $result['success'] ? 200 : 400);
}
// Обновление проекта
if ($action === 'update') {
$id = $data['id'] ?? null;
$name = trim($data['name'] ?? '');
if (!$id || !$name) {
RestApi::response(['success' => false, 'errors' => ['data' => 'Укажите ID и название']], 400);
}
$result = Project::update($id, $name, $user_id);
RestApi::response($result, $result['success'] ? 200 : 403);
}
// Удаление проекта
if ($action === 'delete') {
$id = $data['id'] ?? null;
if (!$id) {
RestApi::response(['success' => false, 'errors' => ['id' => 'Укажите ID проекта']], 400);
}
$result = Project::delete($id, $user_id);
RestApi::response($result, $result['success'] ? 200 : 403);
}
// Обновление порядка проектов
if ($action === 'update_order') {
$ids = $data['ids'] ?? [];
if (empty($ids)) {
RestApi::response(['success' => false, 'errors' => ['ids' => 'Укажите массив ID']], 400);
}
$result = Project::updateOrder($ids, $user_id);
RestApi::response($result);
}
// ==================== CRUD КОЛОНОК ====================
// Добавление колонки
if ($action === 'add_column') {
$project_id = $data['project_id'] ?? null;
$name = trim($data['name'] ?? '');
$color = $data['color'] ?? '#6366f1';
if (!$project_id || !$name) {
RestApi::response(['success' => false, 'errors' => ['data' => 'Укажите project_id и name']], 400);
}
$result = Project::addColumn($project_id, $name, $color, $user_id);
RestApi::response($result, $result['success'] ? 200 : 403);
}
// Обновление колонки
if ($action === 'update_column') {
$id = $data['id'] ?? null;
$name = isset($data['name']) ? trim($data['name']) : null;
$color = $data['color'] ?? null;
if (!$id) {
RestApi::response(['success' => false, 'errors' => ['id' => 'Укажите ID колонки']], 400);
}
$result = Project::updateColumn($id, $name, $color, $user_id);
RestApi::response($result, $result['success'] ? 200 : 403);
}
// Получение количества задач в колонке (для подтверждения удаления)
if ($action === 'get_column_tasks_count') {
$id = $data['id'] ?? null;
if (!$id) {
RestApi::response(['success' => false, 'errors' => ['id' => 'Укажите ID колонки']], 400);
}
$count = Project::getColumnTasksCount($id);
RestApi::response(['success' => true, 'count' => $count]);
}
// Удаление колонки
if ($action === 'delete_column') {
$id = $data['id'] ?? null;
if (!$id) {
RestApi::response(['success' => false, 'errors' => ['id' => 'Укажите ID колонки']], 400);
}
$result = Project::deleteColumn($id, $user_id);
RestApi::response($result, $result['success'] ? 200 : 403);
}
// Обновление порядка колонок
if ($action === 'update_columns_order') {
$project_id = $data['project_id'] ?? null;
$ids = $data['ids'] ?? [];
if (!$project_id || empty($ids)) {
RestApi::response(['success' => false, 'errors' => ['data' => 'Укажите project_id и ids']], 400);
}
$result = Project::updateColumnsOrder($project_id, $ids, $user_id);
RestApi::response($result, $result['success'] ? 200 : 403);
}
// Установка финальной колонки
if ($action === 'set_ready_column') {
$project_id = $data['project_id'] ?? null;
$column_id = $data['column_id'] ?? null;
if (!$project_id || !$column_id) {
RestApi::response(['success' => false, 'errors' => ['data' => 'Укажите project_id и column_id']], 400);
}
$result = Project::setReadyColumn($project_id, $column_id, $user_id);
RestApi::response($result, $result['success'] ? 200 : 403);
}
// Метод не указан
if (!$action) {
RestApi::response(['success' => false, 'error' => 'Укажите метод'], 400);

View File

@@ -124,6 +124,265 @@ class Project extends BaseEntity {
$admins = json_decode($project['id_admin'], true) ?: [];
return in_array((int)$user_id, $admins, true);
}
// ==================== CRUD ПРОЕКТОВ ====================
// Создание проекта с дефолтными колонками
public static function create($name, $user_id) {
// Получаем максимальный id_order
$maxOrder = Database::max('project', 'id_order') ?? 0;
// Создаём проект
Database::insert('project', [
'name' => $name,
'id_order' => $maxOrder + 1,
'id_admin' => json_encode([(int)$user_id]),
'id_member' => json_encode([])
]);
$projectId = Database::id();
if (!$projectId) {
return ['success' => false, 'errors' => ['project' => 'Ошибка создания проекта']];
}
// Создаём дефолтные колонки
Database::insert('columns', [
'name_columns' => 'К выполнению',
'color' => '#6366f1',
'id_project' => $projectId,
'id_order' => 1
]);
$firstColumnId = Database::id();
Database::insert('columns', [
'name_columns' => 'Готово',
'color' => '#22c55e',
'id_project' => $projectId,
'id_order' => 2
]);
$readyColumnId = Database::id();
// Устанавливаем id_ready
Database::update('project', ['id_ready' => $readyColumnId], ['id' => $projectId]);
return [
'success' => true,
'id' => $projectId,
'columns' => [
['id' => $firstColumnId, 'name_columns' => 'К выполнению', 'color' => '#6366f1', 'id_order' => 1],
['id' => $readyColumnId, 'name_columns' => 'Готово', 'color' => '#22c55e', 'id_order' => 2]
],
'id_ready' => $readyColumnId
];
}
// Обновление проекта
public static function update($id, $name, $user_id) {
// Проверяем права
if (!self::isAdmin($id, $user_id)) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на редактирование']];
}
Database::update('project', ['name' => $name], ['id' => $id]);
return ['success' => true];
}
// Удаление проекта (каскадно: колонки, задачи, комментарии, файлы)
public static function delete($id, $user_id) {
// Проверяем права
if (!self::isAdmin($id, $user_id)) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на удаление']];
}
// Получаем все задачи проекта
$tasks = Database::select('cards_task', ['id'], ['id_project' => $id]);
$taskIds = array_column($tasks, 'id');
if (!empty($taskIds)) {
// Получаем все комментарии к задачам
$comments = Database::select('comments', ['id'], ['id_task' => $taskIds]);
// Удаляем файлы комментариев с диска
foreach ($comments as $comment) {
FileUpload::deleteFolder('comment', $comment['id']);
}
// Удаляем комментарии из БД
Database::delete('comments', ['id_task' => $taskIds]);
}
// Удаляем файлы задач с диска
foreach ($tasks as $task) {
FileUpload::deleteFolder('task', $task['id']);
}
// Удаляем задачи из БД
Database::delete('cards_task', ['id_project' => $id]);
// Удаляем колонки
Database::delete('columns', ['id_project' => $id]);
// Удаляем отделы проекта
Database::delete('departments', ['id_project' => $id]);
// Удаляем проект
Database::delete('project', ['id' => $id]);
return ['success' => true];
}
// Обновление порядка проектов
public static function updateOrder($ids, $user_id) {
foreach ($ids as $order => $id) {
Database::update('project', ['id_order' => $order + 1], ['id' => $id]);
}
return ['success' => true];
}
// ==================== CRUD КОЛОНОК ====================
// Добавление колонки
public static function addColumn($project_id, $name, $color, $user_id) {
// Проверяем права
if (!self::isAdmin($project_id, $user_id)) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на редактирование']];
}
// Получаем максимальный id_order для проекта
$maxOrder = Database::max('columns', 'id_order', ['id_project' => $project_id]) ?? 0;
Database::insert('columns', [
'name_columns' => $name,
'color' => $color ?: '#6366f1',
'id_project' => $project_id,
'id_order' => $maxOrder + 1
]);
$columnId = Database::id();
return [
'success' => true,
'id' => $columnId,
'column' => [
'id' => $columnId,
'name_columns' => $name,
'color' => $color ?: '#6366f1',
'id_order' => $maxOrder + 1
]
];
}
// Обновление колонки
public static function updateColumn($id, $name, $color, $user_id) {
// Получаем колонку для проверки проекта
$column = Database::get('columns', ['id_project'], ['id' => $id]);
if (!$column) {
return ['success' => false, 'errors' => ['column' => 'Колонка не найдена']];
}
// Проверяем права
if (!self::isAdmin($column['id_project'], $user_id)) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на редактирование']];
}
$updateData = [];
if ($name !== null) $updateData['name_columns'] = $name;
if ($color !== null) $updateData['color'] = $color;
if (!empty($updateData)) {
Database::update('columns', $updateData, ['id' => $id]);
}
return ['success' => true];
}
// Удаление колонки (возвращает количество задач для подтверждения)
public static function getColumnTasksCount($column_id) {
return Database::count('cards_task', ['column_id' => $column_id]);
}
// Удаление колонки с задачами
public static function deleteColumn($id, $user_id) {
// Получаем колонку для проверки проекта
$column = Database::get('columns', ['id_project', 'id_order'], ['id' => $id]);
if (!$column) {
return ['success' => false, 'errors' => ['column' => 'Колонка не найдена']];
}
// Проверяем права
if (!self::isAdmin($column['id_project'], $user_id)) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на удаление']];
}
// Проверяем, не является ли это последней колонкой перед "Готово"
// Минимум должно быть 3 колонки (2 обычные + готово), чтобы можно было удалить
$columnsCount = Database::count('columns', ['id_project' => $column['id_project']]);
if ($columnsCount <= 2) {
return ['success' => false, 'errors' => ['column' => 'Нельзя удалить последнюю колонку перед финальной']];
}
// Проверяем, не является ли это последней (финальной) колонкой
$lastColumn = Database::get('columns', ['id'], [
'id_project' => $column['id_project'],
'ORDER' => ['id_order' => 'DESC'],
'LIMIT' => 1
]);
if ($lastColumn && (int)$lastColumn['id'] === (int)$id) {
return ['success' => false, 'errors' => ['column' => 'Нельзя удалить финальную колонку (последнюю)']];
}
// Получаем задачи колонки
$tasks = Database::select('cards_task', ['id'], ['column_id' => $id]);
$taskIds = array_column($tasks, 'id');
// Удаляем комментарии к задачам
if (!empty($taskIds)) {
Database::delete('comments', ['id_task' => $taskIds]);
}
// Удаляем задачи
Database::delete('cards_task', ['column_id' => $id]);
// Удаляем колонку
Database::delete('columns', ['id' => $id]);
// Обновляем id_ready на новую последнюю колонку
$newLastColumn = Database::get('columns', ['id'], [
'id_project' => $column['id_project'],
'ORDER' => ['id_order' => 'DESC'],
'LIMIT' => 1
]);
if ($newLastColumn) {
Database::update('project', ['id_ready' => $newLastColumn['id']], ['id' => $column['id_project']]);
}
return ['success' => true, 'deleted_tasks' => count($taskIds)];
}
// Обновление порядка колонок
public static function updateColumnsOrder($project_id, $ids, $user_id) {
// Проверяем права
if (!self::isAdmin($project_id, $user_id)) {
return ['success' => false, 'errors' => ['access' => 'Нет прав на редактирование']];
}
foreach ($ids as $order => $id) {
Database::update('columns', ['id_order' => $order + 1], ['id' => $id, 'id_project' => $project_id]);
}
// Автоматически устанавливаем id_ready на последнюю колонку
$lastColumnId = end($ids);
if ($lastColumnId) {
Database::update('project', ['id_ready' => $lastColumnId], ['id' => $project_id]);
}
return ['success' => true];
}
// Установка финальной колонки (id_ready) - ЗАБЛОКИРОВАНО
// Финальная колонка всегда последняя, изменение запрещено
public static function setReadyColumn($project_id, $column_id, $user_id) {
return ['success' => false, 'errors' => ['column' => 'Изменение финальной колонки запрещено. Финальная колонка всегда последняя.']];
}
}
?>