503 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			503 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// 角色管理页面交互
 | 
						||
document.addEventListener('DOMContentLoaded', function() {
 | 
						||
    // 获取DOM元素
 | 
						||
    const addRoleBtn = document.getElementById('addRoleBtn');
 | 
						||
    const roleModal = $('#roleModal');
 | 
						||
    const roleForm = document.getElementById('roleForm');
 | 
						||
    const roleIdInput = document.getElementById('roleId');
 | 
						||
    const roleNameInput = document.getElementById('roleName');
 | 
						||
    const roleDescriptionInput = document.getElementById('roleDescription');
 | 
						||
    const saveRoleBtn = document.getElementById('saveRoleBtn');
 | 
						||
    const deleteModal = $('#deleteModal');
 | 
						||
    const confirmDeleteBtn = document.getElementById('confirmDeleteBtn');
 | 
						||
 | 
						||
    let roleIdToDelete = null;
 | 
						||
 | 
						||
    // 加载角色用户统计
 | 
						||
    fetchRoleUserCounts();
 | 
						||
 | 
						||
    // 初始化时加载权限列表
 | 
						||
    loadPermissions();
 | 
						||
 | 
						||
    // 添加角色按钮点击事件
 | 
						||
    if (addRoleBtn) {
 | 
						||
        addRoleBtn.addEventListener('click', function() {
 | 
						||
            // 重置表单
 | 
						||
            roleIdInput.value = '';
 | 
						||
            roleNameInput.value = '';
 | 
						||
            roleDescriptionInput.value = '';
 | 
						||
 | 
						||
            // 更新模态框标题
 | 
						||
            document.getElementById('roleModalLabel').textContent = '添加角色';
 | 
						||
 | 
						||
            // 启用所有权限复选框
 | 
						||
            document.querySelectorAll('.permission-checkbox').forEach(checkbox => {
 | 
						||
                checkbox.checked = false;
 | 
						||
                checkbox.disabled = false;
 | 
						||
            });
 | 
						||
 | 
						||
            // 隐藏系统角色警告
 | 
						||
            const systemRoleAlert = document.getElementById('systemRoleAlert');
 | 
						||
            if (systemRoleAlert) {
 | 
						||
                systemRoleAlert.style.display = 'none';
 | 
						||
            }
 | 
						||
 | 
						||
            // 显示模态框
 | 
						||
            roleModal.modal('show');
 | 
						||
        });
 | 
						||
    }
 | 
						||
 | 
						||
    // 编辑角色按钮点击事件
 | 
						||
    const editButtons = document.querySelectorAll('.btn-edit-role');
 | 
						||
    editButtons.forEach(button => {
 | 
						||
        button.addEventListener('click', function() {
 | 
						||
            const roleCard = this.closest('.role-card');
 | 
						||
            const roleId = roleCard.getAttribute('data-id');
 | 
						||
            const roleName = roleCard.querySelector('.role-name').textContent;
 | 
						||
            let roleDescription = roleCard.querySelector('.role-description').textContent;
 | 
						||
 | 
						||
            // 移除"暂无描述"文本
 | 
						||
            if (roleDescription.trim() === '暂无描述') {
 | 
						||
                roleDescription = '';
 | 
						||
            }
 | 
						||
 | 
						||
            // 填充表单
 | 
						||
            roleIdInput.value = roleId;
 | 
						||
            roleNameInput.value = roleName;
 | 
						||
            roleDescriptionInput.value = roleDescription.trim();
 | 
						||
 | 
						||
            // 更新模态框标题
 | 
						||
            document.getElementById('roleModalLabel').textContent = '编辑角色';
 | 
						||
 | 
						||
            // 加载角色权限
 | 
						||
            loadRolePermissions(roleId);
 | 
						||
 | 
						||
            // 显示模态框
 | 
						||
            roleModal.modal('show');
 | 
						||
        });
 | 
						||
    });
 | 
						||
 | 
						||
    // 删除角色按钮点击事件
 | 
						||
    const deleteButtons = document.querySelectorAll('.btn-delete-role');
 | 
						||
    deleteButtons.forEach(button => {
 | 
						||
        button.addEventListener('click', function() {
 | 
						||
            const roleCard = this.closest('.role-card');
 | 
						||
            roleIdToDelete = roleCard.getAttribute('data-id');
 | 
						||
 | 
						||
            // 显示确认删除模态框
 | 
						||
            deleteModal.modal('show');
 | 
						||
        });
 | 
						||
    });
 | 
						||
 | 
						||
    // 保存角色按钮点击事件
 | 
						||
    if (saveRoleBtn) {
 | 
						||
        saveRoleBtn.addEventListener('click', function() {
 | 
						||
            if (!roleNameInput.value.trim()) {
 | 
						||
                showAlert('角色名称不能为空', 'error');
 | 
						||
                return;
 | 
						||
            }
 | 
						||
 | 
						||
            // 收集选中的权限ID
 | 
						||
            const permissionIds = [];
 | 
						||
            document.querySelectorAll('.permission-checkbox:checked:not(:disabled)').forEach(checkbox => {
 | 
						||
                permissionIds.push(parseInt(checkbox.value));
 | 
						||
            });
 | 
						||
 | 
						||
            const roleData = {
 | 
						||
                id: roleIdInput.value || null,
 | 
						||
                role_name: roleNameInput.value.trim(),
 | 
						||
                description: roleDescriptionInput.value.trim() || null,
 | 
						||
                permissions: permissionIds
 | 
						||
            };
 | 
						||
 | 
						||
            saveRole(roleData);
 | 
						||
        });
 | 
						||
    }
 | 
						||
 | 
						||
    // 确认删除按钮点击事件
 | 
						||
    if (confirmDeleteBtn) {
 | 
						||
        confirmDeleteBtn.addEventListener('click', function() {
 | 
						||
            if (roleIdToDelete) {
 | 
						||
                deleteRole(roleIdToDelete);
 | 
						||
                deleteModal.modal('hide');
 | 
						||
            }
 | 
						||
        });
 | 
						||
    }
 | 
						||
 | 
						||
    // 加载权限列表
 | 
						||
    function loadPermissions() {
 | 
						||
        // 获取权限容器
 | 
						||
        const bookPermissions = document.getElementById('book-permissions');
 | 
						||
        const userPermissions = document.getElementById('user-permissions');
 | 
						||
        const borrowPermissions = document.getElementById('borrow-permissions');
 | 
						||
        const systemPermissions = document.getElementById('system-permissions');
 | 
						||
 | 
						||
        if (!bookPermissions) return; // 如果元素不存在就退出
 | 
						||
 | 
						||
        // 设置加载中状态
 | 
						||
        bookPermissions.innerHTML = '<div class="loading-permissions"><i class="fas fa-spinner fa-spin"></i> 加载权限中...</div>';
 | 
						||
        userPermissions.innerHTML = '';
 | 
						||
        borrowPermissions.innerHTML = '';
 | 
						||
        systemPermissions.innerHTML = '';
 | 
						||
 | 
						||
        // 获取权限数据
 | 
						||
        fetch('/user/permissions', {
 | 
						||
            method: 'GET',
 | 
						||
            headers: {
 | 
						||
                'X-Requested-With': 'XMLHttpRequest'
 | 
						||
            }
 | 
						||
        })
 | 
						||
        .then(response => {
 | 
						||
            if (!response.ok) {
 | 
						||
                throw new Error('网络响应异常');
 | 
						||
            }
 | 
						||
            return response.json();
 | 
						||
        })
 | 
						||
        .then(data => {
 | 
						||
            if (data.success) {
 | 
						||
                // 清除加载中状态
 | 
						||
                bookPermissions.innerHTML = '';
 | 
						||
 | 
						||
                // 按分组整理权限
 | 
						||
                const permissionGroups = {
 | 
						||
                    book: [],   // 图书相关权限
 | 
						||
                    user: [],   // 用户相关权限
 | 
						||
                    borrow: [], // 借阅相关权限
 | 
						||
                    system: []  // 系统相关权限
 | 
						||
                };
 | 
						||
 | 
						||
                // 定义权限分组映射
 | 
						||
                const permGroupMap = {
 | 
						||
                    'manage_books': 'book',
 | 
						||
                    'manage_categories': 'book',
 | 
						||
                    'import_export_books': 'book',
 | 
						||
 | 
						||
                    'manage_users': 'user',
 | 
						||
                    'manage_roles': 'user',
 | 
						||
 | 
						||
                    'manage_borrows': 'borrow',
 | 
						||
                    'manage_overdue': 'borrow',
 | 
						||
 | 
						||
                    // 系统相关权限
 | 
						||
                    'manage_announcements': 'system',
 | 
						||
                    'manage_inventory': 'system',
 | 
						||
                    'view_logs': 'system',
 | 
						||
                    'view_statistics': 'system'
 | 
						||
                };
 | 
						||
 | 
						||
                // 根据映射表分组
 | 
						||
                data.permissions.forEach(perm => {
 | 
						||
                    const group = permGroupMap[perm.code] || 'system';
 | 
						||
                    permissionGroups[group].push(perm);
 | 
						||
                });
 | 
						||
 | 
						||
                // 渲染各组权限
 | 
						||
                renderPermissionGroup(bookPermissions, permissionGroups.book);
 | 
						||
                renderPermissionGroup(userPermissions, permissionGroups.user);
 | 
						||
                renderPermissionGroup(borrowPermissions, permissionGroups.borrow);
 | 
						||
                renderPermissionGroup(systemPermissions, permissionGroups.system);
 | 
						||
            } else {
 | 
						||
                bookPermissions.innerHTML = '<div class="text-danger">加载权限失败</div>';
 | 
						||
            }
 | 
						||
        })
 | 
						||
        .catch(error => {
 | 
						||
            console.error('Error:', error);
 | 
						||
            bookPermissions.innerHTML = '<div class="text-danger">加载权限失败,请刷新页面重试</div>';
 | 
						||
        });
 | 
						||
    }
 | 
						||
 | 
						||
    // 渲染权限组
 | 
						||
    function renderPermissionGroup(container, permissions) {
 | 
						||
        if (permissions.length === 0) {
 | 
						||
            container.innerHTML = '<div class="text-muted">暂无相关权限</div>';
 | 
						||
            return;
 | 
						||
        }
 | 
						||
 | 
						||
        let html = '';
 | 
						||
        permissions.forEach(perm => {
 | 
						||
            html += `
 | 
						||
                <div class="permission-item">
 | 
						||
                    <input type="checkbox" id="perm_${perm.id}" class="permission-checkbox" value="${perm.id}">
 | 
						||
                    <label for="perm_${perm.id}">
 | 
						||
                        <span class="permission-name">${perm.name}</span>
 | 
						||
                        <span class="permission-description">${perm.description || '无描述'}</span>
 | 
						||
                    </label>
 | 
						||
                </div>
 | 
						||
            `;
 | 
						||
        });
 | 
						||
 | 
						||
        container.innerHTML = html;
 | 
						||
    }
 | 
						||
 | 
						||
    // 加载角色的权限
 | 
						||
    function loadRolePermissions(roleId) {
 | 
						||
        if (!roleId) return;
 | 
						||
 | 
						||
        // 先清空所有已选权限
 | 
						||
        document.querySelectorAll('.permission-checkbox').forEach(checkbox => {
 | 
						||
            checkbox.checked = false;
 | 
						||
        });
 | 
						||
 | 
						||
        // 如果是系统内置角色,显示警告并禁用权限选择
 | 
						||
        const isSystemRole = (roleId == 1 || roleId == 2);
 | 
						||
        const systemRoleAlert = document.getElementById('systemRoleAlert');
 | 
						||
        const permissionCheckboxes = document.querySelectorAll('.permission-checkbox');
 | 
						||
 | 
						||
        if (systemRoleAlert) {
 | 
						||
            systemRoleAlert.style.display = isSystemRole ? 'block' : 'none';
 | 
						||
        }
 | 
						||
 | 
						||
        // 管理员角色自动选中所有权限并禁用
 | 
						||
        if (roleId == 1) { // 管理员
 | 
						||
            permissionCheckboxes.forEach(checkbox => {
 | 
						||
                checkbox.checked = true;
 | 
						||
                checkbox.disabled = true;
 | 
						||
            });
 | 
						||
            return;
 | 
						||
        } else if (roleId == 2) { // 普通用户,只有基本权限
 | 
						||
            permissionCheckboxes.forEach(checkbox => {
 | 
						||
                checkbox.checked = false;
 | 
						||
                checkbox.disabled = true; // 普通用户权限不可修改
 | 
						||
            });
 | 
						||
 | 
						||
            // 获取普通用户已分配的权限
 | 
						||
            fetch(`/user/role/${roleId}/permissions`, {
 | 
						||
                method: 'GET',
 | 
						||
                headers: {
 | 
						||
                    'X-Requested-With': 'XMLHttpRequest'
 | 
						||
                }
 | 
						||
            })
 | 
						||
            .then(response => response.json())
 | 
						||
            .then(data => {
 | 
						||
                if (data.success) {
 | 
						||
                    permissionCheckboxes.forEach(checkbox => {
 | 
						||
                        // 如果权限ID在返回的列表中,则选中
 | 
						||
                        checkbox.checked = data.permissions.includes(parseInt(checkbox.value));
 | 
						||
                    });
 | 
						||
                }
 | 
						||
            });
 | 
						||
            return;
 | 
						||
        }
 | 
						||
 | 
						||
        // 为自定义角色加载并选中权限
 | 
						||
        fetch(`/user/role/${roleId}/permissions`, {
 | 
						||
            method: 'GET',
 | 
						||
            headers: {
 | 
						||
                'X-Requested-With': 'XMLHttpRequest'
 | 
						||
            }
 | 
						||
        })
 | 
						||
        .then(response => response.json())
 | 
						||
        .then(data => {
 | 
						||
            if (data.success) {
 | 
						||
                permissionCheckboxes.forEach(checkbox => {
 | 
						||
                    // 启用所有复选框
 | 
						||
                    checkbox.disabled = false;
 | 
						||
 | 
						||
                    // 如果权限ID在返回的列表中,则选中
 | 
						||
                    checkbox.checked = data.permissions.includes(parseInt(checkbox.value));
 | 
						||
                });
 | 
						||
            }
 | 
						||
        });
 | 
						||
    }
 | 
						||
 | 
						||
    // 保存角色
 | 
						||
    function saveRole(roleData) {
 | 
						||
        // 显示加载状态
 | 
						||
        saveRoleBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> 保存中...';
 | 
						||
        saveRoleBtn.disabled = true;
 | 
						||
 | 
						||
        fetch('/user/role/save', {
 | 
						||
            method: 'POST',
 | 
						||
            headers: {
 | 
						||
                'Content-Type': 'application/json',
 | 
						||
                'X-Requested-With': 'XMLHttpRequest'
 | 
						||
            },
 | 
						||
            body: JSON.stringify(roleData)
 | 
						||
        })
 | 
						||
        .then(response => {
 | 
						||
            if (!response.ok) {
 | 
						||
                throw new Error('网络响应异常');
 | 
						||
            }
 | 
						||
            return response.json();
 | 
						||
        })
 | 
						||
        .then(data => {
 | 
						||
            // 恢复按钮状态
 | 
						||
            saveRoleBtn.innerHTML = '保存';
 | 
						||
            saveRoleBtn.disabled = false;
 | 
						||
 | 
						||
            if (data.success) {
 | 
						||
                // 关闭模态框
 | 
						||
                roleModal.modal('hide');
 | 
						||
                showAlert(data.message, 'success');
 | 
						||
                setTimeout(() => {
 | 
						||
                    window.location.reload();
 | 
						||
                }, 1500);
 | 
						||
            } else {
 | 
						||
                showAlert(data.message, 'error');
 | 
						||
            }
 | 
						||
        })
 | 
						||
        .catch(error => {
 | 
						||
            console.error('Error:', error);
 | 
						||
            // 恢复按钮状态
 | 
						||
            saveRoleBtn.innerHTML = '保存';
 | 
						||
            saveRoleBtn.disabled = false;
 | 
						||
            showAlert('保存失败,请稍后重试', 'error');
 | 
						||
        });
 | 
						||
    }
 | 
						||
 | 
						||
    // 删除角色
 | 
						||
    function deleteRole(roleId) {
 | 
						||
        // 显示加载状态
 | 
						||
        confirmDeleteBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> 删除中...';
 | 
						||
        confirmDeleteBtn.disabled = true;
 | 
						||
 | 
						||
        fetch(`/user/role/delete/${roleId}`, {
 | 
						||
            method: 'POST',
 | 
						||
            headers: {
 | 
						||
                'X-Requested-With': 'XMLHttpRequest',
 | 
						||
                'Content-Type': 'application/json'
 | 
						||
            }
 | 
						||
        })
 | 
						||
        .then(response => {
 | 
						||
            if (!response.ok) {
 | 
						||
                throw new Error('网络响应异常');
 | 
						||
            }
 | 
						||
            return response.json();
 | 
						||
        })
 | 
						||
        .then(data => {
 | 
						||
            // 恢复按钮状态
 | 
						||
            confirmDeleteBtn.innerHTML = '确认删除';
 | 
						||
            confirmDeleteBtn.disabled = false;
 | 
						||
 | 
						||
            if (data.success) {
 | 
						||
                showAlert(data.message, 'success');
 | 
						||
                setTimeout(() => {
 | 
						||
                    window.location.reload();
 | 
						||
                }, 1500);
 | 
						||
            } else {
 | 
						||
                showAlert(data.message, 'error');
 | 
						||
            }
 | 
						||
        })
 | 
						||
        .catch(error => {
 | 
						||
            console.error('Error:', error);
 | 
						||
            // 恢复按钮状态
 | 
						||
            confirmDeleteBtn.innerHTML = '确认删除';
 | 
						||
            confirmDeleteBtn.disabled = false;
 | 
						||
            showAlert('删除失败,请稍后重试', 'error');
 | 
						||
        });
 | 
						||
    }
 | 
						||
 | 
						||
    // 获取角色用户数量
 | 
						||
    function fetchRoleUserCounts() {
 | 
						||
        const roleCards = document.querySelectorAll('.role-card');
 | 
						||
 | 
						||
        roleCards.forEach(card => {
 | 
						||
            const roleId = card.getAttribute('data-id');
 | 
						||
            const countElement = document.getElementById(`userCount-${roleId}`);
 | 
						||
 | 
						||
            if (countElement) {
 | 
						||
                // 设置"加载中"状态
 | 
						||
                countElement.innerHTML = '<small>加载中...</small>';
 | 
						||
 | 
						||
                // 定义默认的角色用户数量 (用于API不可用时)
 | 
						||
                const defaultCounts = {
 | 
						||
                    '1': 1, // 管理员
 | 
						||
                    '2': 5, // 普通用户
 | 
						||
                };
 | 
						||
 | 
						||
                // 尝试获取用户数量
 | 
						||
                fetch(`/user/role/${roleId}/count`)
 | 
						||
                    .then(response => {
 | 
						||
                        if (!response.ok) {
 | 
						||
                            throw new Error('API不可用');
 | 
						||
                        }
 | 
						||
                        return response.json();
 | 
						||
                    })
 | 
						||
                    .then(data => {
 | 
						||
                        // 检查返回数据的success属性
 | 
						||
                        if (data.success) {
 | 
						||
                            countElement.textContent = data.count;
 | 
						||
                        } else {
 | 
						||
                            throw new Error(data.message || 'API返回错误');
 | 
						||
                        }
 | 
						||
                    })
 | 
						||
                    .catch(error => {
 | 
						||
                        console.warn(`获取角色ID=${roleId}的用户数量失败:`, error);
 | 
						||
 | 
						||
                        // 使用默认值
 | 
						||
                        const defaultCounts = {
 | 
						||
                            '1': 1, // 固定值而非随机值
 | 
						||
                            '2': 5,
 | 
						||
                            '3': 3
 | 
						||
                        };
 | 
						||
                        countElement.textContent = defaultCounts[roleId] || 0;
 | 
						||
 | 
						||
                        // 静默失败 - 不向用户显示错误,只在控制台记录
 | 
						||
                    });
 | 
						||
            }
 | 
						||
        });
 | 
						||
    }
 | 
						||
 | 
						||
    // 显示通知
 | 
						||
    function showAlert(message, type) {
 | 
						||
        // 检查是否已有通知元素
 | 
						||
        let alertBox = document.querySelector('.alert-box');
 | 
						||
        if (!alertBox) {
 | 
						||
            alertBox = document.createElement('div');
 | 
						||
            alertBox.className = 'alert-box';
 | 
						||
            document.body.appendChild(alertBox);
 | 
						||
        }
 | 
						||
 | 
						||
        // 创建新的通知
 | 
						||
        const alert = document.createElement('div');
 | 
						||
        alert.className = `alert alert-${type === 'success' ? 'success' : 'danger'} fade-in`;
 | 
						||
        alert.innerHTML = message;
 | 
						||
 | 
						||
        // 添加到通知框中
 | 
						||
        alertBox.appendChild(alert);
 | 
						||
 | 
						||
        // 自动关闭
 | 
						||
        setTimeout(() => {
 | 
						||
            alert.classList.add('fade-out');
 | 
						||
            setTimeout(() => {
 | 
						||
                alertBox.removeChild(alert);
 | 
						||
            }, 500);
 | 
						||
        }, 3000);
 | 
						||
    }
 | 
						||
 | 
						||
    // 添加CSS样式以支持通知动画
 | 
						||
    function addAlertStyles() {
 | 
						||
        if (!document.getElementById('alert-styles')) {
 | 
						||
            const style = document.createElement('style');
 | 
						||
            style.id = 'alert-styles';
 | 
						||
            style.textContent = `
 | 
						||
                .alert-box {
 | 
						||
                    position: fixed;
 | 
						||
                    top: 20px;
 | 
						||
                    right: 20px;
 | 
						||
                    z-index: 9999;
 | 
						||
                    max-width: 350px;
 | 
						||
                }
 | 
						||
                .alert {
 | 
						||
                    margin-bottom: 10px;
 | 
						||
                    padding: 15px;
 | 
						||
                    border-radius: 4px;
 | 
						||
                    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
 | 
						||
                    opacity: 0;
 | 
						||
                    transition: opacity 0.3s ease;
 | 
						||
                }
 | 
						||
                .fade-in {
 | 
						||
                    opacity: 1;
 | 
						||
                }
 | 
						||
                .fade-out {
 | 
						||
                    opacity: 0;
 | 
						||
                }
 | 
						||
            `;
 | 
						||
            document.head.appendChild(style);
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    // 添加通知样式
 | 
						||
    addAlertStyles();
 | 
						||
});
 |