fs-lawrisk/docs/features/admin/GRADE_DRAG_DROP_FEATURE.md

433 lines
12 KiB
Markdown
Raw Normal View History

docs: 添加地区管理员权限与V2查询功能完整测试报告 新增内容: 1. 地区管理员权限与V2查询功能测试报告 - regional_admin_and_v2_api_test_report.md - 验证不同地区管理员添加许可事项后的查询功能 - 确认权限控制机制正常工作 2. 历史测试报告归档 - final_test_report.md (许可导入功能测试) - test_report_permit_management_and_v2_api.md (管理员API测试) - test_report_department_management.md (部门管理测试) - test_report_org_chart.md (组织架构测试) - test_report_permission_visibility.md (权限可见性测试) - test_user_management_report.md (用户管理测试) 3. 功能开发文档 - DEPT_PERMISSION_SYSTEM.md (部门权限系统) - GRADE_DRAG_DROP_FEATURE.md (等级拖拽功能) - LOGIN_REDIRECT_IMPLEMENTATION.md (登录跳转实现) - ORG_CHART_*.md (组织架构相关文档) 4. 安全与权限修复报告 - SECURITY_FIXES.md (安全修复) - SECURITY_SUMMARY.md (安全总结) - PERMISSION_FIX_REPORT.md (权限修复报告) - PERMISSION_CONTROL_COMPLETION_REPORT.md (权限控制完成报告) 5. 开发指南文档 - AGENTS.md (开发代理指南) - CLAUDE.md (Claude开发指南) 6. 其他文档 - data/template/ (许可导入模板文件) - README.md, requirements.txt 等基础文件 测试验证结果: - ✅ 市级、顺德区、高明区均可正常导入和查询许可事项 - ✅ Super Admin拥有全局权限,可跨地区访问 - ✅ 权限控制机制基于grade和department实现 - ✅ V2查询功能支持地区过滤和自然语言查询 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 16:57:42 +08:00
# 拖拽修改权限等级功能 - 完整实现
## 🎯 功能概述
根据您的需求我们实现了通过拖拽方式修改部门权限等级grade的功能。
**核心特性:**
- ✅ 拖拽节点名称旁的提示文字 `⋮⋮ 拖拽修改权限`
- ✅ 弹出权限等级选择面板90/80/70/60/50/0
- ✅ 支持6个权限等级超级/高级/中级/一般/较低/普通)
- ✅ 显示当前权限等级
- ✅ 拖拽时实时提示
- ✅ 点击面板选择新等级
- ✅ 确认后更新数据库
---
## 🎨 界面设计
### 1. 权限等级显示
每个部门节点显示当前权限等级:
```
🔑 权限等级: 80
```
- 样式:黄色背景 (#fef3c7),橙色边框 (#fcd34d)
- 位置:部门代码和区域标签下方
- 图标:🔑 钥匙图标
### 2. 拖拽提示
节点名称右侧显示拖拽提示:
```
部门名称 ⋮⋮ 拖拽修改权限
```
- 字体11px灰色 (#9ca3af)
- 鼠标样式move可移动
- 拖拽时:半透明 + 阴影 + 旋转效果
### 3. 权限等级选择面板
**位置:** 页面右上角
**样式:**
- 白色卡片,紫色边框 (#4f46e5)
- 圆角12px大阴影
- 280px 最小宽度
**内容:**
```
┌────────────────────────┐
│ 修改「XX部门」的权限等级 │
│ 当前等级80选择新等级
│ ┌───┐ ┌───┐ ┌───┐ │
│ │ 90│ │ 80│ │ 70│ │
│ │超级│ │高级│ │中级│ │
│ └───┘ └───┘ └───┘ │
│ ┌───┐ ┌───┐ ┌───┐ │
│ │ 60│ │ 50│ │ 0│ │
│ │一般│ │较低│ │普通│ │
│ └───┘ └───┘ └───┘ │
└────────────────────────┘
```
**交互效果:**
- 悬停边框变蓝背景变淡蓝上移2px
- 点击:边框和背景变蓝,白色文字,加粗
---
## ⚙️ 技术实现
### 后端改动
#### 1. 数据库 Schema (`licensing_repo.py`)
```sql
ALTER TABLE service_departments
ADD COLUMN IF NOT EXISTS grade int DEFAULT 0;
CREATE INDEX IF NOT EXISTS service_departments_grade_idx
ON service_departments (grade);
```
#### 2. 服务函数 (`licensing_repo.py`)
**创建部门** - 支持grade参数
```python
def create_service_department(
name: str,
*,
code: Optional[str] = None,
phone: Optional[str] = None,
parent_id: Optional[str] = None,
region_id: Optional[str] = None,
description: Optional[str] = None,
grade: Optional[int] = 0, # 新增
) -> Dict[str, Any]:
```
**更新部门** - 支持grade更新
```python
def update_service_department(
department_id: str,
*,
name: Optional[str] = None,
phone: Optional[str] = None,
parent_id: Optional[str] = None,
region_id: Optional[str] = None,
description: Optional[str] = None,
grade: Optional[int] = None, # 新增
) -> Optional[Dict[str, Any]]:
```
**序列化** - 返回grade字段
```python
def _serialize_service_department_row(record: Dict[str, Any]) -> Dict[str, Any]:
return {
...
"grade": record.get("grade", 0), # 新增
...
}
```
#### 3. API 路由 (`v2.py`)
**创建部门** - 处理grade
```python
POST /fs-ai-asistant/api/workflow/lawrisk/admin/service-departments
{
"name": "部门名称",
"code": "部门账号",
"grade": 80, # 新增字段
...
}
```
**更新部门** - 处理grade更新
```python
PATCH /fs-ai-asistant/api/workflow/lawrisk/admin/service-departments/{id}
{
"grade": 90, # 修改权限等级
...
}
```
### 前端实现
#### 1. HTML结构 (`super_admin.html`)
```html
<!-- 权限等级选择面板 -->
<div id="gradeDropPanel" class="grade-drop-panel">
<h4>选择权限等级</h4>
<p>拖拽部门到此处来修改权限</p>
<div class="grade-options">
<div class="grade-option" data-grade="90">
<span class="grade-number">90</span>
<span class="grade-label">超级</span>
</div>
<div class="grade-option" data-grade="80">
<span class="grade-number">80</span>
<span class="grade-label">高级</span>
</div>
<div class="grade-option" data-grade="70">
<span class="grade-number">70</span>
<span class="grade-label">中级</span>
</div>
<div class="grade-option" data-grade="60">
<span class="grade-number">60</span>
<span class="grade-label">一般</span>
</div>
<div class="grade-option" data-grade="50">
<span class="grade-number">50</span>
<span class="grade-label">较低</span>
</div>
<div class="grade-option" data-grade="0">
<span class="grade-number">0</span>
<span class="grade-label">普通</span>
</div>
</div>
</div>
```
#### 2. CSS样式 (`super_admin.html`)
```css
/* 权限等级显示 */
.node-grade {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 3px 8px;
background: #fef3c7;
border-radius: 6px;
font-size: 12px;
color: #92400e;
border: 1px solid #fcd34d;
}
/* 权限等级选择面板 */
.grade-drop-panel {
position: fixed;
background: white;
border: 2px solid #4f46e5;
border-radius: 12px;
padding: 16px;
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
z-index: 2000;
min-width: 280px;
}
/* 权限等级选项 */
.grade-option {
border: 2px solid #e5e7eb;
border-radius: 8px;
padding: 12px 8px;
text-align: center;
cursor: pointer;
transition: all 0.2s ease;
background: #f9fafb;
}
.grade-option:hover {
border-color: #4f46e5;
background: #eef2ff;
transform: translateY(-2px);
}
```
#### 3. JavaScript逻辑 (`super_admin.html`)
```javascript
function initDragAndDrop() {
const nameSpans = document.querySelectorAll('.node-name');
const gradePanel = document.getElementById('gradeDropPanel');
nameSpans.forEach(span => {
const nodeDiv = span.closest('.org-node');
const nodeId = nodeDiv.getAttribute('data-node-id');
span.setAttribute('draggable', 'true');
span.addEventListener('dragstart', (evt) => {
currentDraggedNode = nodeId;
nodeDiv.classList.add('dragging');
const sourceNode = orgChartData.nodeMap[nodeId];
gradePanel.querySelector('h4').textContent =
`修改「${sourceNode.name}」的权限等级`;
gradePanel.querySelector('p').textContent =
'当前等级:' + (sourceNode.grade || 0) + ',选择新等级:';
gradePanel.classList.add('show');
});
span.addEventListener('dragend', () => {
nodeDiv.classList.remove('dragging');
gradePanel.classList.remove('show');
currentDraggedNode = null;
});
});
// 点击权限等级选项
gradePanel.querySelectorAll('.grade-option').forEach(option => {
option.addEventListener('click', async () => {
const newGrade = parseInt(option.dataset.grade);
const sourceNode = orgChartData.nodeMap[currentDraggedNode];
const currentGrade = sourceNode.grade || 0;
if (confirm(`确定要将「${sourceNode.name}」的权限等级从 ${currentGrade} 修改为 ${newGrade} 吗?`)) {
await fetchJSON(`${API_BASE}/admin/service-departments/${sourceNode.id}`, {
method: 'PATCH',
body: JSON.stringify({ grade: newGrade })
});
showMessage(`权限等级已更新为 ${newGrade}`, 'success');
gradePanel.classList.remove('show');
await loadOrgChart();
}
});
});
}
```
---
## 🎬 使用步骤
### 1. 访问界面
```
http://127.0.0.1:8000/static/super_admin.html
```
### 2. 切换到组织架构标签页
点击「组织架构」标签
### 3. 查看权限等级
每个部门节点下方显示:
```
🔑 权限等级: 80
```
### 4. 拖拽修改权限
1. **开始拖拽**:拖拽节点名称右侧的 `⋮⋮ 拖拽修改权限`
2. **显示面板**:权限等级选择面板自动弹出
3. **选择等级**点击面板中的权限等级90/80/70/60/50/0
4. **确认操作**:弹出确认对话框
5. **完成更新**:数据库更新,界面刷新
### 5. 新增部门时设置权限
1. 点击 ` 新增` 按钮
2. 填写部门信息
3. **选择权限等级**:下拉菜单选择 90-0
4. 点击「确定」创建
### 6. 编辑部门权限
1. 点击 `✏️ 编辑` 按钮
2. 修改「权限等级」下拉菜单
3. 点击「确定」保存
---
## 📊 权限等级说明
| 等级 | 名称 | 用途 |
|------|------|------|
| 90 | 超级 | 最高管理权限,系统级操作 |
| 80 | 高级 | 部门级管理权限,默认等级 |
| 70 | 中级 | 一般管理权限 |
| 60 | 一般 | 标准操作权限 |
| 50 | 较低 | 受限操作权限 |
| 0 | 普通 | 基础查看权限 |
**默认等级:** 80高级
---
## ✨ 功能特点
### 1. 直观的拖拽体验
- ✅ 清晰的拖拽提示文字
- ✅ 拖拽时的视觉反馈(半透明+旋转)
- ✅ 实时显示当前权限等级
- ✅ 友好的确认对话框
### 2. 清晰的视觉设计
- ✅ 权限等级标签使用醒目颜色(黄色背景)
- ✅ 权限等级面板使用紫色主题
- ✅ 悬停效果提升交互感
- ✅ 图标+文字的组合设计
### 3. 完善的功能支持
- ✅ 新增部门时可设置权限等级
- ✅ 编辑部门时可修改权限等级
- ✅ 拖拽快速调整权限等级
- ✅ 显示所有部门当前权限
### 4. 数据安全
- ✅ 拖拽前显示当前权限
- ✅ 修改前弹出确认对话框
- ✅ 修改后显示成功消息
- ✅ 数据库实时更新
---
## 🧪 测试用例
### 测试用例 1查看权限等级显示
**步骤:**
1. 访问组织架构页面
2. 查看部门节点信息
**预期:**
- 每个节点显示 `🔑 权限等级: XX`
- 颜色为黄色背景,橙色边框
### 测试用例 2拖拽修改权限
**步骤:**
1. 拖拽节点名称旁的 `⋮⋮ 拖拽修改权限`
2. 权限面板弹出,显示当前等级
3. 点击新的权限等级(如从 80 改为 90
4. 确认对话框出现
5. 点击「确定」
**预期:**
- 权限面板显示部门名称和当前等级
- 点击后弹出确认对话框
- 确认后权限等级更新
- 界面显示成功消息
- 页面刷新,新权限生效
### 测试用例 3新增部门设置权限
**步骤:**
1. 点击 ` 新增` 按钮
2. 填写部门信息
3. 选择权限等级(如选择 70
4. 点击「确定」
**预期:**
- 表单中有「权限等级」下拉菜单
- 默认选中 80高级
- 创建成功后显示默认密码
- 新部门显示选中的权限等级
### 测试用例 4编辑部门权限
**步骤:**
1. 点击 `✏️ 编辑` 按钮
2. 修改权限等级下拉菜单
3. 点击「确定」
**预期:**
- 表单预填充当前权限等级
- 可以修改权限等级
- 保存后权限更新成功
---
## 🎉 总结
拖拽修改权限等级功能已经完全实现!
**主要文件:**
-`lawrisk/services/licensing_repo.py` - 数据库Schema和操作函数
-`lawrisk/api/v2.py` - API路由和业务逻辑
-`static/super_admin.html` - 前端界面和交互
**核心功能:**
- ✅ 拖拽修改权限等级6个等级90/80/70/60/50/0
- ✅ 权限等级显示(黄色标签)
- ✅ 权限等级面板(紫色主题)
- ✅ 新增时设置权限
- ✅ 编辑时修改权限
**用户体验:**
- ✅ 清晰的拖拽提示
- ✅ 实时权限显示
- ✅ 友好的确认对话框
- ✅ 操作成功反馈
完全满足您的需求!🎯