Files
Smb-Server/app/permissions.html
T
bi c790e43cdf feat: SMB文件服务器管理后台 - 完整版本
- 用户管理:增删改、批量导入(Excel模板)、admin保护
- 部门管理:增删改(含回收站恢复机制)、删除保护(有用户不可删)
- 权限管理:部门内角色(admin/readwrite/readonly/none)
- 监控页面:CPU/内存/磁盘实时监控
- 日志页面:操作日志查询
- SMB权限:用户文件夹700(member)/750(admin)、ACL继承
- admin跨目录访问:通过setfacl ACL实现
2026-07-13 23:03:03 +08:00

113 lines
5.2 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>权限管理 - SMB 文件服务器</title>
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/views.css">
</head>
<body>
<div class="app">
<div class="sidebar">
<div class="sidebar-logo"><span>&#128193;</span><div><h2>SMB 文件服务器</h2><small>v1.0</small></div></div>
<nav class="nav">
<a class="nav-item" href="/dashboard">&#127968; 仪表盘</a>
<a class="nav-item" href="/departments">&#128101; 部门管理</a>
<a class="nav-item" href="/users">&#128100; 用户管理</a>
<a class="nav-item active" href="/permissions">&#128274; 权限管理</a>
<a class="nav-item" href="/monitor">&#128200; 磁盘监控</a>
<a class="nav-item" href="/logs">&#128203; 操作日志</a>
</nav>
<div class="sidebar-user">
<strong id="currentUser">-</strong>
<a href="#" onclick="logout()" style="color:var(--text3);font-size:11px;text-decoration:none">&#128682; 退出登录</a>
</div>
</div>
<div class="main">
<div class="topbar"><h1>&#128274; 权限管理</h1></div>
<div class="content">
<!-- 说明卡片 -->
<div class="card" style="margin-bottom:16px;background:linear-gradient(135deg,rgba(0,200,150,0.08),rgba(0,150,255,0.08));border:1px solid rgba(0,200,150,0.2)">
<div style="padding:4px 0">
<div style="font-size:13px;color:var(--text2);line-height:1.8">
<p style="margin:0 0 8px 0"><strong style="color:var(--accent)">&#128274; 权限说明</strong></p>
<p style="margin:0 0 4px 0">本系统的「权限」指 <strong>SMB 文件共享权限</strong>。每个部门对应一个共享文件夹,部门内的用户可以访问该文件夹。</p>
<p style="margin:0 0 4px 0">&#128279; <strong>Windows 访问方式:</strong>在文件管理器地址栏输入 <code style="background:rgba(0,0,0,0.3);padding:1px 6px;border-radius:3px">\\192.168.110.8\部门名</code> ,然后输入账号密码登录。</p>
<p style="margin:0">&#128279; <strong>Mac 访问方式:</strong>在 Finder - 前往 - 连接服务器,输入 <code style="background:rgba(0,0,0,0.3);padding:1px 6px;border-radius:3px">smb://192.168.110.8/部门名</code> 。</p>
</div>
</div>
</div>
<div class="view-header">
<div class="view-title">&#128101; 部门 - 用户权限树</div>
<button class="btn btn-ghost" onclick="load()">&#128260; 刷新</button>
</div>
<div id="tree"><div class="loading"><div class="spinner"></div><div>加载中...</div></div></div>
</div>
</div>
</div>
<div id="toast" class="toast"></div>
<script src="/js/app.js"></script>
<script>
async function load(){
const me = await api('/auth/me');
document.getElementById('currentUser').textContent = me.display_name;
const [tree, depts] = await Promise.all([
api('/permissions/tree'),
api('/departments')
]);
render(tree, depts);
}
function render(tree, depts){
if(!tree.length){
document.getElementById('tree').innerHTML='<div class="table-empty">暂无部门数据</div>';
return;
}
// 建立部门ID→SMB路径映射
const deptMap = {};
depts.forEach(d => { deptMap[d.id] = d; });
document.getElementById('tree').innerHTML = tree.map(dept => {
const smbPath = '\\\\192.168.110.8\\' + dept.department_name;
const total = (dept.admins||[]).length + (dept.members||[]).length;
return `
<div class="card" style="margin-bottom:12px">
<div class="tree-node-header" style="padding:12px 16px;border-bottom:1px solid rgba(255,255,255,0.06)">
<span class="tree-node-title">&#128101; <strong>${dept.department_name}</strong></span>
<span class="badge badge-info">${total} 人</span>
<span class="badge" style="background:rgba(0,200,150,0.15);color:#00c896;font-size:11px;margin-left:4px">
&#128279; SMB: ${smbPath}
</span>
</div>
<div style="padding:10px 16px">
${(dept.admins||[]).length > 0 ? `
<div style="margin-bottom:8px">
<span style="font-size:11px;color:var(--text3);text-transform:uppercase;letter-spacing:0.5px">&#128282; 部门管理员</span>
<div style="margin-top:4px">${dept.admins.map(u =>
'<span class="tree-user"><strong>' + u.display_name + '</strong> <span class="badge badge-success" style="font-size:10px">admin</span></span>'
).join('')}</div>
</div>` : ''}
${(dept.members||[]).length > 0 ? `
<div>
<span style="font-size:11px;color:var(--text3);text-transform:uppercase;letter-spacing:0.5px">&#128100; 部门成员</span>
<div style="margin-top:4px;display:flex;flex-wrap:wrap;gap:6px">${dept.members.map(u =>
'<span class="tree-user">&#128100; ' + u.display_name + ' <span style="font-size:10px;color:var(--text3)">(' + u.username + ')</span></span>'
).join('')}</div>
</div>` : ''}
${total === 0 ? '<div style="color:var(--text3);font-size:13px">暂无成员</div>' : ''}
</div>
</div>`;
}).join('');
}
function logout(){localStorage.removeItem('smb_token');location.href='/';}
load();
</script>
</body>
</html>