This commit is contained in:
2026-02-02 16:16:14 +05:00
parent cd827b0e9a
commit 0b54ca8404
11 changed files with 1185 additions and 1020 deletions

View File

@@ -1,4 +1,4 @@
// help-users.js - Управление пользователями
// users.js - Управление пользователями
let users = [];
let allUsers = [];
let filteredUsers = [];
@@ -8,126 +8,233 @@ 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('Секретарь'));
filteredUsers = helpUsers;
// Показываем пользователей группы help при создании заявки
showHelpGroupUsers();
const response = await fetch('/api/users');
const allUsersData = await response.json();
//users = await response.json();
// Сохраняем всех пользователей
allUsers = allUsersData;
// Фильтруем пользователей в зависимости от прав текущего пользователя
users = filterAssignableUsers(allUsersData);
filteredUsers = [...users];
renderUsersChecklist();
renderEditUsersChecklist();
renderCopyUsersChecklist();
populateFilterDropdowns();
} catch (error) {
console.error('Ошибка загрузки пользователей:', error);
}
}
function filterAssignableUsers(allUsers) {
if (!currentUser) return [];
// Администратор видит всех пользователей
if (currentUser.role === 'admin') {
return allUsers.filter(user => user.id !== currentUser.id);
}
if (currentUser.role === 'secretary') {
return allUsers.filter(user => user.id !== currentUser.id);
}
if (currentUser.role === 'ithelp') {
return allUsers.filter(user =>
(user.role === 'teacher' || user.role === 'tasks' || user.role === 'help' || user.role === 'request' || user.role === 'ithelp') &&
user.id !== currentUser.id
);
}
if (currentUser.role === 'request') {
return allUsers.filter(user =>
(user.role === 'teacher' || user.role === 'tasks' || user.role === 'help' || user.role === 'request' || user.role === 'ithelp') &&
user.id !== currentUser.id
);
}
// tasks видит учителей и других tasks
if (currentUser.role === 'help') {
return allUsers.filter(user =>
(user.role === 'teacher' || user.role === 'tasks' || user.role === 'help' || user.role === 'request' || user.role === 'ithelp') &&
user.id !== currentUser.id
);
}
// tasks видит учителей и других tasks
if (currentUser.role === 'tasks') {
return allUsers.filter(user =>
(user.role === 'teacher' || user.role === 'tasks' || user.role === 'help' || user.role === 'request' || user.role === 'ithelp') &&
user.id !== currentUser.id
);
}
// Учитель видит только учителей
if (currentUser.role === 'teacher') {
return allUsers.filter(user =>
(user.role === 'help' || user.role === 'request' || user.role === 'ithelp') &&
user.id !== currentUser.id
);
}
// Проверяем группы пользователя для определения прав
const userGroups = currentUser.groups || [];
// Загружаем конфигурацию групп из настроек
// (предполагается, что эти переменные определены в глобальной области)
const allowedGroups = getGroupsForCurrentUser();
// Если у пользователя нет специальных групп, возвращаем пустой массив
if (allowedGroups.length === 0) {
return [];
}
// Фильтруем пользователей по группам
return allUsers.filter(user => {
// Пользователь не может назначать задачи себе
if (user.id === currentUser.id) return false;
// Если у пользователя есть группы, проверяем пересечение
if (user.groups && Array.isArray(user.groups)) {
return user.groups.some(group => allowedGroups.includes(group));
}
return false;
});
}
// Функция для получения групп, которым текущий пользователь может назначать задачи
function getGroupsForCurrentUser() {
const allowedGroups = [];
const userGroups = currentUser.groups || [];
// Определяем, какие группы доступны для назначения
// На основе ролей и групп текущего пользователя
// Пример: пользователи с ролью 'secretary' могут назначать задачи группам 'teachers'
if (currentUser.role === 'secretary') {
allowedGroups.push('teachers', 'staff');
}
// Пример: пользователи из группы 'department_head' могут назначать своей группе
if (userGroups.includes('department_head')) {
allowedGroups.push('department_head', 'teachers');
}
// Пример: для помощи (help) можно назначать всем
if (currentUser.role === 'help') {
// Можно указать конкретные группы или 'all' для всех
allowedGroups.push('teachers', 'staff', 'administration');
}
// Пример: для IT поддержки
if (currentUser.role === 'ithelp') {
allowedGroups.push('teachers', 'staff', 'administration', 'it_department');
}
// Пример: пользователи с ролью 'request' могут создавать заявки для всех
if (currentUser.role === 'request') {
allowedGroups.push('all'); // Специальное значение "все"
}
// Пример: пользователи с ролью 'tasks' (задачи) могут назначать учителям
if (currentUser.role === 'tasks') {
allowedGroups.push('teachers');
}
// Если массив содержит 'all', возвращаем специальный маркер
if (allowedGroups.includes('all')) {
return ['all']; // Это будет обрабатываться в фильтрации
}
return [...new Set(allowedGroups)]; // Убираем дубликаты
}
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 = '<option value="">Все заказчики</option>';
assigneeFilter.innerHTML = '<option value="">Все исполнители (группа "help")</option>';
assigneeFilter.innerHTML = '<option value="">Все исполнители</option>';
// Для заказчиков показываем всех пользователей
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('Секретарь'));
helpUsers.forEach(user => {
const assigneeOption = document.createElement('option');
assigneeOption.value = user.id;
assigneeOption.textContent = `${user.name} (${user.login}) - группа "help"`;
creatorFilter.appendChild(creatorOption.cloneNode(true));
const assigneeOption = creatorOption.cloneNode(true);
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('Секретарь'));
if (helpUsers.length === 0) {
container.innerHTML = '<div class="help-group-notice"><i class="fas fa-exclamation-triangle"></i> Нет пользователей в группе "help"</div>';
return;
}
container.innerHTML = `
<div class="help-group-notice">
<i class="fas fa-info-circle"></i> Заявка будет автоматически назначена ${helpUsers.length} пользователям группы "help":
</div>
<div class="help-users-list">
${helpUsers.map(user => `
<div class="help-user-item">
<i class="fas fa-user"></i>
<span class="help-user-name">${user.name}</span>
<span class="help-user-email">(${user.email})</span>
</div>
`).join('')}
</div>
`;
}
// Старые функции фильтрации оставляем, но они теперь не используются для выбора исполнителей
function filterUsers() {
const searchInput = document.getElementById('user-search');
if (!searchInput) return; // Элемент есть только на странице help.html
const search = searchInput.value.toLowerCase();
// Фильтруем пользователей группы "help"
const search = document.getElementById('user-search').value.toLowerCase();
filteredUsers = users.filter(user =>
user.groups && user.groups.includes('Секретарь') && (
user.name.toLowerCase().includes(search) ||
user.login.toLowerCase().includes(search) ||
user.email.toLowerCase().includes(search)
)
user.name.toLowerCase().includes(search) ||
user.login.toLowerCase().includes(search) ||
user.email.toLowerCase().includes(search)
);
// Не рендерим чеклист, так как выбираем всех пользователей группы help
renderUsersChecklist();
}
function filterEditUsers() {
// Не используется, так как заявка автоматически назначается всем пользователям группы help
const search = document.getElementById('edit-user-search').value.toLowerCase();
const filtered = users.filter(user =>
user.name.toLowerCase().includes(search) ||
user.login.toLowerCase().includes(search) ||
user.email.toLowerCase().includes(search)
);
renderEditUsersChecklist(filtered);
}
function filterCopyUsers() {
// Не используется, так как заявка автоматически назначается всем пользователям группы help
const search = document.getElementById('copy-user-search').value.toLowerCase();
const filtered = users.filter(user =>
user.name.toLowerCase().includes(search) ||
user.login.toLowerCase().includes(search) ||
user.email.toLowerCase().includes(search)
);
renderCopyUsersChecklist(filtered);
}
// Старые функции рендеринга оставляем для совместимости, но они не будут использоваться
function renderUsersChecklist() {
// Не рендерим чеклист, так как выбираем всех пользователей группы help
const container = document.getElementById('users-checklist');
container.innerHTML = filteredUsers
.filter(user => user.id !== currentUser.id)
.map(user => `
<div class="checkbox-item">
<label>
<input type="checkbox" name="assignedUsers" value="${user.id}"
onchange="toggleUserSelection(this, ${user.id})">
${user.name} (${user.email})
${user.auth_type === 'ldap' ? '<small style="color: #666;"> - LDAP</small>' : ''}
</label>
</div>
`).join('');
}
function renderEditUsersChecklist(filtered = users) {
// Не рендерим чеклист, так как заявка автоматически назначается всем пользователям группы help
const container = document.getElementById('edit-users-checklist');
container.innerHTML = filtered
.filter(user => user.id !== currentUser.id)
.map(user => `
<div class="checkbox-item">
<label>
<input type="checkbox" name="assignedUsers" value="${user.id}"
onchange="toggleEditUserSelection(this, ${user.id})">
${user.name} (${user.email})
${user.auth_type === 'ldap' ? '<small style="color: #666;"> - LDAP</small>' : ''}
</label>
</div>
`).join('');
}
function renderCopyUsersChecklist(filtered = users) {
// Не рендерим чеклист, так как заявка автоматически назначается всем пользователям группы help
const container = document.getElementById('copy-users-checklist');
container.innerHTML = filtered
.filter(user => user.id !== currentUser.id)
.map(user => `
<div class="checkbox-item">
<label>
<input type="checkbox" name="assignedUsers" value="${user.id}"
onchange="toggleCopyUserSelection(this, ${user.id})">
${user.name} (${user.email})
${user.auth_type === 'ldap' ? '<small style="color: #666;"> - LDAP</small>' : ''}
</label>
</div>
`).join('');
}
// Старые функции выбора пользователей оставляем для совместимости
function toggleUserSelection(checkbox, userId) {
if (checkbox.checked) {
selectedUsers.push(userId);