+ `;
+ }).join('');
+}
+
function closeEditModal() {
document.getElementById('edit-task-modal').style.display = 'none';
document.getElementById('edit-file-list').innerHTML = '';
- document.getElementById('edit-user-search').value = '';
- editSelectedUsers = [];
currentEditTaskFiles = [];
- filterEditUsers();
}
async function updateTask(event) {
@@ -209,11 +244,12 @@ async function updateTask(event) {
return;
}
- // Используем editSelectedUsers (только секретари)
- const assignedUserIds = editSelectedUsers;
+ // Заявка автоматически назначается всем пользователям группы "help"
+ const helpUsers = users.filter(user => user.groups && user.groups.includes('help'));
+ const assignedUserIds = helpUsers.map(user => user.id);
if (assignedUserIds.length === 0) {
- alert('Выберите хотя бы одного секретаря в качестве исполнителя');
+ alert('Нет пользователей в группе "help". Заявка не может быть обновлена.');
return;
}
@@ -235,17 +271,17 @@ async function updateTask(event) {
});
if (response.ok) {
- alert('Согласование успешно обновлено!');
+ alert('Заявка успешно обновлена и назначена всем пользователям группы "help"!');
closeEditModal();
loadTasks();
loadActivityLogs();
} else {
const error = await response.json();
- alert(error.error || 'Ошибка обновления согласования');
+ alert(error.error || 'Ошибка обновления заявки');
}
} catch (error) {
console.error('Ошибка:', error);
- alert('Ошибка обновления согласования');
+ alert('Ошибка обновления заявки');
}
}
@@ -257,18 +293,11 @@ function openCopyModal(taskId) {
defaultDate.setDate(defaultDate.getDate() + 7);
document.getElementById('copy-due-date').value = defaultDate.toISOString().substring(0, 16);
- // Сбрасываем выбранных пользователей (только секретари)
- copySelectedUsers = [];
- renderCopyUsersChecklist(users);
-
document.getElementById('copy-task-modal').style.display = 'block';
}
function closeCopyModal() {
document.getElementById('copy-task-modal').style.display = 'none';
- document.getElementById('copy-user-search').value = '';
- copySelectedUsers = [];
- filterCopyUsers();
}
async function copyTask(event) {
@@ -278,15 +307,16 @@ async function copyTask(event) {
const dueDate = document.getElementById('copy-due-date').value;
if (!dueDate) {
- alert('Дата и время выполнения обязательны для копии согласования');
+ alert('Дата и время выполнения обязательны для копии заявки');
return;
}
- // Используем copySelectedUsers (только секретари)
- const assignedUserIds = copySelectedUsers;
+ // Копия заявки автоматически назначается всем пользователям группы "help"
+ const helpUsers = users.filter(user => user.groups && user.groups.includes('help'));
+ const assignedUserIds = helpUsers.map(user => user.id);
if (assignedUserIds.length === 0) {
- alert('Выберите хотя бы одного секретаря в качестве исполнителя для копии согласования');
+ alert('Нет пользователей в группе "help". Копия заявки не может быть создана.');
return;
}
@@ -303,22 +333,22 @@ async function copyTask(event) {
});
if (response.ok) {
- alert('Копия согласования успешно создана!');
+ alert('Копия заявки успешно создана и назначена всем пользователям группы "help"!');
closeCopyModal();
loadTasks();
loadActivityLogs();
} else {
const error = await response.json();
- alert(error.error || 'Ошибка создания копии согласования');
+ alert(error.error || 'Ошибка создания копии заявки');
}
} catch (error) {
console.error('Ошибка:', error);
- alert('Ошибка создания копии согласования');
+ alert('Ошибка создания копии заявки');
}
}
async function closeTask(taskId) {
- if (!confirm('Вы уверены, что хотите закрыть это согласование? Секретари больше не будут видеть его.')) {
+ if (!confirm('Вы уверены, что хотите закрыть эту заявку? Исполнители больше не будут видеть ее.')) {
return;
}
@@ -328,16 +358,16 @@ async function closeTask(taskId) {
});
if (response.ok) {
- alert('Согласование закрыто!');
+ alert('Заявка закрыта!');
loadTasks();
loadActivityLogs();
} else {
const error = await response.json();
- alert(error.error || 'Ошибка закрытия согласования');
+ alert(error.error || 'Ошибка закрытия заявки');
}
} catch (error) {
console.error('Ошибка:', error);
- alert('Ошибка закрытия согласования');
+ alert('Ошибка закрытия заявки');
}
}
@@ -348,21 +378,21 @@ async function reopenTask(taskId) {
});
if (response.ok) {
- alert('Согласование открыто!');
+ alert('Заявка открыта!');
loadTasks();
loadActivityLogs();
} else {
const error = await response.json();
- alert(error.error || 'Ошибка открытия согласования');
+ alert(error.error || 'Ошибка открытия заявки');
}
} catch (error) {
console.error('Ошибка:', error);
- alert('Ошибка открытия согласования');
+ alert('Ошибка открытия заявки');
}
}
async function deleteTask(taskId) {
- if (!confirm('Вы уверены, что хотите удалить это согласование?')) {
+ if (!confirm('Вы уверены, что хотите удалить эту заявку?')) {
return;
}
@@ -372,16 +402,16 @@ async function deleteTask(taskId) {
});
if (response.ok) {
- alert('Согласование удалено!');
+ alert('Заявка удалена!');
loadTasks();
loadActivityLogs();
} else {
const error = await response.json();
- alert(error.error || 'Ошибка удаления согласования');
+ alert(error.error || 'Ошибка удаления заявки');
}
} catch (error) {
console.error('Ошибка:', error);
- alert('Ошибка удаления согласования');
+ alert('Ошибка удаления заявки');
}
}
@@ -392,16 +422,16 @@ async function restoreTask(taskId) {
});
if (response.ok) {
- alert('Согласование восстановлено!');
+ alert('Заявка восстановлена!');
loadTasks();
loadActivityLogs();
} else {
const error = await response.json();
- alert(error.error || 'Ошибка восстановления согласования');
+ alert(error.error || 'Ошибка восстановления заявки');
}
} catch (error) {
console.error('Ошибка:', error);
- alert('Ошибка восстановления согласования');
+ alert('Ошибка восстановления заявки');
}
}
@@ -447,7 +477,7 @@ async function updateAssignment(event) {
});
if (response.ok) {
- alert('Сроки секретаря обновлены!');
+ alert('Сроки исполнителя обновлены!');
closeEditAssignmentModal();
loadTasks();
loadActivityLogs();
@@ -487,17 +517,17 @@ async function sendForRework(event) {
});
if (response.ok) {
- alert('Согласование возвращено на доработку!');
+ alert('Заявка возвращена на доработку!');
closeReworkModal();
loadTasks();
loadActivityLogs();
} else {
const error = await response.json();
- alert(error.error || 'Ошибка возврата согласования на доработку');
+ alert(error.error || 'Ошибка возврата заявки на доработку');
}
} catch (error) {
console.error('Ошибка:', error);
- alert('Ошибка возврата согласования на доработку');
+ alert('Ошибка возврата заявки на доработку');
}
}
@@ -530,34 +560,38 @@ function canUserEditTask(task) {
// Администратор может всё
if (currentUser.role === 'admin') return true;
- // Создатель может редактировать свое согласование
+ // Создатель может редактировать свою заявку
if (parseInt(task.created_by) === currentUser.id) {
- // Но если согласование уже назначено секретарям,
+ // Но если заявка уже назначена группе "help",
// создатель может только просматривать
if (task.assignments && task.assignments.length > 0) {
- // Проверяем, назначено ли согласование секретарям (не только себе)
- const assignedToSecretaries = task.assignments.some(assignment =>
- parseInt(assignment.user_id) !== currentUser.id
- );
-
- if (assignedToSecretaries) {
- // Создатель может только просматривать и закрывать согласование
- return false;
- }
+ return false;
}
return true;
}
- // Секретарь может менять только свой статус
+ // Пользователи группы "help" могут менять только свой статус
if (task.assignments) {
- const isSecretary = task.assignments.some(assignment =>
+ const isHelpUser = task.assignments.some(assignment =>
parseInt(assignment.user_id) === currentUser.id
);
- if (isSecretary) {
- // Секретарь может менять только статус
- return false;
+ if (isHelpUser) {
+ return false; // Могут менять только статус
}
}
return false;
+}
+
+// Функция для отображения пользователей группы help при создании заявки
+function showHelpGroupUsers() {
+ const container = document.getElementById('help-group-users');
+ const helpUsers = users.filter(user => user.groups && user.groups.includes('help'));
+
+ container.innerHTML = helpUsers.map(user => `
+
+
+ ${user.name} (${user.email})
+
+ `).join('');
}
\ No newline at end of file
diff --git a/public/help-users.js b/public/help-users.js
new file mode 100644
index 0000000..673b53d
--- /dev/null
+++ b/public/help-users.js
@@ -0,0 +1,153 @@
+// help-users.js - Управление пользователями
+let users = [];
+let allUsers = [];
+let filteredUsers = [];
+let selectedUsers = [];
+let editSelectedUsers = [];
+let copySelectedUsers = [];
+
+async function loadUsers() {
+ try {
+ const response = await fetch('/api/users');
+ users = await response.json();
+ allUsers = users;
+
+ // Получаем пользователей группы "help"
+ const helpUsers = users.filter(user => user.groups && user.groups.includes('help'));
+ filteredUsers = helpUsers;
+
+ // Показываем пользователей группы help при создании заявки
+ showHelpGroupUsers();
+
+ populateFilterDropdowns();
+ } catch (error) {
+ console.error('Ошибка загрузки пользователей:', error);
+ }
+}
+
+function populateFilterDropdowns() {
+ const creatorFilter = document.getElementById('creator-filter');
+ const assigneeFilter = document.getElementById('assignee-filter');
+
+ // Проверяем существование элементов (они есть только на странице help.html)
+ if (!creatorFilter || !assigneeFilter) {
+ console.log('Фильтры не найдены (возможно, не на странице help.html)');
+ return;
+ }
+
+ creatorFilter.innerHTML = '';
+ assigneeFilter.innerHTML = '';
+
+ // Для заказчиков показываем всех пользователей
+ users.forEach(user => {
+ const creatorOption = document.createElement('option');
+ creatorOption.value = user.id;
+ creatorOption.textContent = `${user.name} (${user.login})`;
+ creatorFilter.appendChild(creatorOption);
+ });
+
+ // Для исполнителей показываем только пользователей группы "help"
+ const helpUsers = users.filter(user => user.groups && user.groups.includes('help'));
+ helpUsers.forEach(user => {
+ const assigneeOption = document.createElement('option');
+ assigneeOption.value = user.id;
+ assigneeOption.textContent = `${user.name} (${user.login}) - группа "help"`;
+ assigneeFilter.appendChild(assigneeOption);
+ });
+}
+
+// Функция для отображения пользователей группы help
+function showHelpGroupUsers() {
+ const container = document.getElementById('help-group-users');
+
+ // Проверяем существование элемента (он есть только на странице help.html)
+ if (!container) {
+ console.log('Контейнер help-group-users не найден (возможно, не на странице help.html)');
+ return;
+ }
+
+ const helpUsers = users.filter(user => user.groups && user.groups.includes('help'));
+
+ if (helpUsers.length === 0) {
+ container.innerHTML = '
Нет пользователей в группе "help"
';
+ return;
+ }
+
+ container.innerHTML = `
+
+ Заявка будет автоматически назначена ${helpUsers.length} пользователям группы "help":
+
+
+ ${helpUsers.map(user => `
+
+
+ ${user.name}
+ (${user.email})
+
+ `).join('')}
+
+ `;
+}
+
+// Старые функции фильтрации оставляем, но они теперь не используются для выбора исполнителей
+function filterUsers() {
+ const searchInput = document.getElementById('user-search');
+ if (!searchInput) return; // Элемент есть только на странице help.html
+
+ const search = searchInput.value.toLowerCase();
+ // Фильтруем пользователей группы "help"
+ filteredUsers = users.filter(user =>
+ user.groups && user.groups.includes('help') && (
+ user.name.toLowerCase().includes(search) ||
+ user.login.toLowerCase().includes(search) ||
+ user.email.toLowerCase().includes(search)
+ )
+ );
+ // Не рендерим чеклист, так как выбираем всех пользователей группы help
+}
+
+function filterEditUsers() {
+ // Не используется, так как заявка автоматически назначается всем пользователям группы help
+}
+
+function filterCopyUsers() {
+ // Не используется, так как заявка автоматически назначается всем пользователям группы help
+}
+
+// Старые функции рендеринга оставляем для совместимости, но они не будут использоваться
+function renderUsersChecklist() {
+ // Не рендерим чеклист, так как выбираем всех пользователей группы help
+}
+
+function renderEditUsersChecklist(filtered = users) {
+ // Не рендерим чеклист, так как заявка автоматически назначается всем пользователям группы help
+}
+
+function renderCopyUsersChecklist(filtered = users) {
+ // Не рендерим чеклист, так как заявка автоматически назначается всем пользователям группы help
+}
+
+// Старые функции выбора пользователей оставляем для совместимости
+function toggleUserSelection(checkbox, userId) {
+ if (checkbox.checked) {
+ selectedUsers.push(userId);
+ } else {
+ selectedUsers = selectedUsers.filter(id => id !== userId);
+ }
+}
+
+function toggleEditUserSelection(checkbox, userId) {
+ if (checkbox.checked) {
+ editSelectedUsers.push(userId);
+ } else {
+ editSelectedUsers = editSelectedUsers.filter(id => id !== userId);
+ }
+}
+
+function toggleCopyUserSelection(checkbox, userId) {
+ if (checkbox.checked) {
+ copySelectedUsers.push(userId);
+ } else {
+ copySelectedUsers = copySelectedUsers.filter(id => id !== userId);
+ }
+}
\ No newline at end of file
diff --git a/public/help.html b/public/help.html
index 10d2140..3f62436 100644
--- a/public/help.html
+++ b/public/help.html
@@ -25,7 +25,7 @@
-
Управление согласованиями
+
Группа поддержки "help"
@2025 МАОУ - СОШ № 25
@@ -36,7 +36,7 @@
-
School CRM - поддержка
+
School CRM - система заявок
@@ -45,21 +45,23 @@
-
Все согласования
+
Все заявки
+
@@ -85,11 +87,12 @@
-
-
-
+
+ Заявка автоматически будет назначена всем пользователям группы "поддержка"
+
+
+
-
@@ -104,22 +107,22 @@
- Создать согласование
+ Создать заявку
-
+
×
-
Редактировать согласование
+
Редактировать заявку
-
-
-
+
+
+
-
- В качестве исполнителей можно выбрать только пользователей с ролью "Секретарь"
+ Заявка автоматически назначается всем пользователям группы "help"
@@ -160,7 +162,7 @@
×
-
Создать копию согласования
+
Создать копию заявки
-
-
-
+
+
+ Копия заявки автоматически будет назначена всем пользователям группы "help"
-
-
- В качестве исполнителей можно выбрать только пользователей с ролью "Секретарь"
-