278 lines
11 KiB
HTML
278 lines
11 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>知识库权限说明</title>
|
||
<style>
|
||
:root {
|
||
--bg: #f6f8fa;
|
||
--card: #ffffff;
|
||
--border: #e1e4e8;
|
||
--hdr: #24292f;
|
||
--text: #333;
|
||
--muted: #6e7781;
|
||
--blue: #0969da;
|
||
--green: #1a7f37;
|
||
--orange: #bc4c00;
|
||
--red: #cf222e;
|
||
--purple: #8250df;
|
||
--tag-bg: #ddf4ff;
|
||
--tag-text: #0969da;
|
||
}
|
||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||
background: var(--bg); color: var(--text); padding: 32px 24px; line-height: 1.6; }
|
||
h1 { font-size: 22px; color: var(--hdr); margin-bottom: 6px; }
|
||
.subtitle { color: var(--muted); font-size: 13px; margin-bottom: 32px; }
|
||
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 20px; }
|
||
.card { background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 20px; }
|
||
.card h2 { font-size: 14px; font-weight: 600; color: var(--hdr); margin-bottom: 14px;
|
||
display: flex; align-items: center; gap: 6px; }
|
||
.card h2 .icon { width: 20px; height: 20px; border-radius: 5px; display: inline-flex;
|
||
align-items: center; justify-content: center; font-size: 12px; }
|
||
.icon-kb { background: #ddf4ff; color: var(--blue); }
|
||
.icon-file { background: #dafbe1; color: var(--green); }
|
||
.icon-role { background: #fff8c5; color: #9a6700; }
|
||
.icon-dept { background: #ffefe7; color: var(--orange); }
|
||
.icon-perm { background: #fbefff; color: var(--purple); }
|
||
.icon-audit{ background: #ffe4e4; color: var(--red); }
|
||
table { width: 100%; border-collapse: collapse; font-size: 13px; }
|
||
th { background: var(--bg); color: var(--muted); font-weight: 600;
|
||
text-align: left; padding: 6px 10px; border-bottom: 1px solid var(--border); }
|
||
td { padding: 7px 10px; border-bottom: 1px solid #f0f0f0; vertical-align: top; }
|
||
tr:last-child td { border-bottom: none; }
|
||
.badge { display: inline-block; padding: 1px 7px; border-radius: 20px; font-size: 11px; font-weight: 500; }
|
||
.b-blue { background: #ddf4ff; color: var(--blue); }
|
||
.b-green { background: #dafbe1; color: var(--green); }
|
||
.b-orange { background: #ffefe7; color: var(--orange); }
|
||
.b-red { background: #ffe4e4; color: var(--red); }
|
||
.b-purple { background: #fbefff; color: var(--purple); }
|
||
.b-gray { background: #f0f0f0; color: #555; }
|
||
.b-yellow { background: #fff8c5; color: #9a6700; }
|
||
.check { color: var(--green); font-weight: 700; }
|
||
.cross { color: var(--red); }
|
||
.note { font-size: 12px; color: var(--muted); margin-top: 10px; padding-top: 8px;
|
||
border-top: 1px dashed var(--border); }
|
||
.full { grid-column: 1 / -1; }
|
||
/* 矩阵表 */
|
||
.matrix th:not(:first-child), .matrix td:not(:first-child) { text-align: center; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<h1>🔐 知识库权限说明</h1>
|
||
<p class="subtitle">方案 A — 基于角色 + 部门层级 + 可见性的多维权限体系</p>
|
||
|
||
<div class="grid">
|
||
|
||
<!-- 1. 角色定义 -->
|
||
<div class="card">
|
||
<h2><span class="icon icon-role">👤</span> 角色定义</h2>
|
||
<table>
|
||
<tr><th>角色</th><th>标识</th><th>说明</th></tr>
|
||
<tr><td>超级管理员</td><td><span class="badge b-red">admin</span></td><td>企业内全部权限,不受部门限制</td></tr>
|
||
<tr><td>部门领导</td><td><span class="badge b-blue">leader</span></td><td>管辖本部门及所有子孙部门</td></tr>
|
||
<tr><td>普通员工</td><td><span class="badge b-gray">employee</span></td><td>仅操作自己的资源</td></tr>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- 2. 部门管辖范围 -->
|
||
<div class="card">
|
||
<h2><span class="icon icon-dept">🏢</span> 部门管辖范围</h2>
|
||
<table>
|
||
<tr><th>角色</th><th>可管辖的部门</th></tr>
|
||
<tr><td><span class="badge b-red">admin</span></td><td>企业所有部门</td></tr>
|
||
<tr>
|
||
<td><span class="badge b-blue">leader</span></td>
|
||
<td>
|
||
所在部门 + 全部子孙部门<br/>
|
||
<span style="color:var(--muted);font-size:12px">(递归 CTE 计算)</span>
|
||
</td>
|
||
</tr>
|
||
<tr><td><span class="badge b-gray">employee</span></td><td>无管辖,仅属于一个部门</td></tr>
|
||
</table>
|
||
<p class="note">示例:技术部领导 → 管辖 技术部、前端组、后端组(全子树)</p>
|
||
</div>
|
||
|
||
<!-- 3. 知识库可见性 -->
|
||
<div class="card">
|
||
<h2><span class="icon icon-kb">📚</span> 知识库可见性</h2>
|
||
<table>
|
||
<tr><th>visibility</th><th>可见范围</th></tr>
|
||
<tr><td><span class="badge b-gray">private</span></td><td>仅创建者本人</td></tr>
|
||
<tr><td><span class="badge b-blue">department</span></td><td>同部门所有成员 + admin</td></tr>
|
||
<tr><td><span class="badge b-green">enterprise</span></td><td>企业全员 + admin</td></tr>
|
||
</table>
|
||
<p class="note">leader 额外规则:本部门内任何可见性的知识库均可查看</p>
|
||
</div>
|
||
|
||
<!-- 4. 知识库操作权限矩阵 -->
|
||
<div class="card full">
|
||
<h2><span class="icon icon-kb">📋</span> 知识库操作权限矩阵</h2>
|
||
<table class="matrix">
|
||
<tr>
|
||
<th>操作</th>
|
||
<th>admin</th>
|
||
<th>leader(本部门KB)</th>
|
||
<th>leader(子部门KB)</th>
|
||
<th>employee(自己创建)</th>
|
||
<th>employee(他人department/enterprise KB)</th>
|
||
</tr>
|
||
<tr>
|
||
<td>查看知识库</td>
|
||
<td><span class="check">✓</span></td>
|
||
<td><span class="check">✓</span></td>
|
||
<td><span class="check">✓</span> 若可见性匹配</td>
|
||
<td><span class="check">✓</span></td>
|
||
<td><span class="check">✓</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td>编辑/删除知识库</td>
|
||
<td><span class="check">✓</span></td>
|
||
<td>仅自己创建的</td>
|
||
<td>仅自己创建的</td>
|
||
<td><span class="check">✓</span></td>
|
||
<td><span class="cross">✗</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td>上传文件</td>
|
||
<td>需 allow_kb_upload=true</td>
|
||
<td>需 allow_kb_upload=true</td>
|
||
<td>—</td>
|
||
<td>需 allow_kb_upload=true</td>
|
||
<td>需 allow_kb_upload=true</td>
|
||
</tr>
|
||
<tr>
|
||
<td>查看文件列表</td>
|
||
<td><span class="check">✓ 全部文件</span></td>
|
||
<td><span class="check">✓ 全部文件</span></td>
|
||
<td>—</td>
|
||
<td><span class="check">✓ 全部文件</span></td>
|
||
<td><span class="check">✓ 全部文件</span></td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- 5. 文件删除权限 -->
|
||
<div class="card">
|
||
<h2><span class="icon icon-file">🗑️</span> 文件删除权限</h2>
|
||
<table>
|
||
<tr><th>谁能删</th><th>条件</th></tr>
|
||
<tr><td>文件上传者本人</td><td>无条件</td></tr>
|
||
<tr><td><span class="badge b-red">admin</span></td><td>同企业内任意文件</td></tr>
|
||
<tr>
|
||
<td><span class="badge b-blue">leader</span></td>
|
||
<td>上传者在其管辖子树内(即是其下属)</td>
|
||
</tr>
|
||
<tr><td><span class="badge b-gray">employee</span></td><td>仅自己上传的文件</td></tr>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- 6. 上传权限控制 -->
|
||
<div class="card">
|
||
<h2><span class="icon icon-perm">🔒</span> 上传权限控制</h2>
|
||
<table>
|
||
<tr><th>条件</th><th>能否上传</th></tr>
|
||
<tr><td>allow_kb_upload = true <br/>且 能查看该 KB</td><td><span class="check">✓ 允许</span></td></tr>
|
||
<tr><td>allow_kb_upload = false</td><td><span class="cross">✗ 禁止</span>(不论角色)</td></tr>
|
||
<tr><td>无权查看 KB</td><td><span class="cross">✗ 禁止</span></td></tr>
|
||
</table>
|
||
<p class="note">
|
||
<b>谁能修改 allow_kb_upload?</b><br/>
|
||
admin → 任意用户 | leader → 自己管辖的下属
|
||
</p>
|
||
</div>
|
||
|
||
<!-- 7. 审计日志可见范围 -->
|
||
<div class="card">
|
||
<h2><span class="icon icon-audit">📝</span> 审计日志可见范围</h2>
|
||
<table>
|
||
<tr><th>角色</th><th>可查看的日志</th></tr>
|
||
<tr><td><span class="badge b-red">admin</span></td><td>企业全员所有操作日志</td></tr>
|
||
<tr>
|
||
<td><span class="badge b-blue">leader</span></td>
|
||
<td>本部门及子孙部门成员的操作日志</td>
|
||
</tr>
|
||
<tr><td><span class="badge b-gray">employee</span></td><td>无权查看审计日志</td></tr>
|
||
</table>
|
||
<p class="note">记录动作:upload / download / delete / create_kb / delete_kb / permission_change</p>
|
||
</div>
|
||
|
||
<!-- 8. 团队管理入口 -->
|
||
<div class="card">
|
||
<h2><span class="icon icon-role">⚙️</span> 管理功能入口</h2>
|
||
<table>
|
||
<tr><th>功能</th><th>入口</th><th>谁能用</th></tr>
|
||
<tr>
|
||
<td>设置部门负责人</td>
|
||
<td><span class="badge b-gray">管理后台</span></td>
|
||
<td><span class="badge b-red">admin</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td>修改任意用户上传权限</td>
|
||
<td><span class="badge b-gray">管理后台</span></td>
|
||
<td><span class="badge b-red">admin</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td>修改下属上传权限</td>
|
||
<td><span class="badge b-blue">前台·团队管理</span></td>
|
||
<td><span class="badge b-blue">leader</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td>查看团队操作日志</td>
|
||
<td><span class="badge b-blue">前台·团队管理</span></td>
|
||
<td><span class="badge b-blue">leader</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td>查看全企业操作日志</td>
|
||
<td><span class="badge b-gray">管理后台</span></td>
|
||
<td><span class="badge b-red">admin</span></td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- 9. 越级禁止 -->
|
||
<div class="card full">
|
||
<h2><span class="icon icon-perm">🚫</span> 越级操作一律拒绝</h2>
|
||
<table>
|
||
<tr><th>场景</th><th>结果</th><th>说明</th></tr>
|
||
<tr>
|
||
<td>leader 操作非下属用户的权限</td>
|
||
<td><span class="cross">403 Forbidden</span></td>
|
||
<td>is_subordinate() 检测不在子树内</td>
|
||
</tr>
|
||
<tr>
|
||
<td>leader 删除非下属上传的文件</td>
|
||
<td><span class="cross">403 Forbidden</span></td>
|
||
<td>can_delete_file() 返回 False</td>
|
||
</tr>
|
||
<tr>
|
||
<td>employee 访问 private KB(非自己创建)</td>
|
||
<td><span class="cross">403 Forbidden</span></td>
|
||
<td>can_view_kb() 返回 False</td>
|
||
</tr>
|
||
<tr>
|
||
<td>allow_kb_upload=false 的用户上传文件</td>
|
||
<td><span class="cross">400 Bad Request</span></td>
|
||
<td>can_upload_to_kb() 返回 False</td>
|
||
</tr>
|
||
<tr>
|
||
<td>跨企业访问任何资源</td>
|
||
<td><span class="cross">403 Forbidden</span></td>
|
||
<td>enterprise_id 强制校验</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<p style="margin-top:28px; font-size:12px; color:var(--muted);">
|
||
实现位置:<code>backend/core/permissions.py</code> ·
|
||
路由层:<code>backend/api/kb_file_router.py</code> ·
|
||
团队 API:<code>backend/api/team_router.py</code>
|
||
</p>
|
||
|
||
</body>
|
||
</html>
|