Управление проектами
Добавил возможность удаления, создание и редактирование проектов.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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' => 'Изменение финальной колонки запрещено. Финальная колонка всегда последняя.']];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user