feat: 权限组简化 + 工单撤销按钮

后端:
- InstanceGroup 新增 access_type (readonly/datachange/ddl) 和 allowed_databases 字段
- 创建 role_permissions.py 角色权限服务 (admin/dba/auditor/developer)
- SQLite ALTER TABLE 迁移脚本

前端:
- InstanceGroupPage 全面重写: 3种权限类型卡片(只读/数据变更/DDL)替代20+开关
- 新增/编辑弹窗: 权限类型选择 + 限定数据库输入
- 左侧列表显示权限类型标签
- 菜单标签: '权限管理' → '权限组'
- 工单列表 + 工单详情: 新增撤销按钮 (pending/reviewing 状态可撤销)
- API 类型定义: 新增 access_type/allowed_databases
This commit is contained in:
logan committed 2026-05-24 19:02:39 +08:00
1 parent b80d383b28
commit 8161bcf5b5
4 files changed
+188 -428

No files matched your search

+32
View File
@@ -581,6 +581,22 @@ export default function TicketsPage() {
<Eye className="w-3.5 h-3.5" />
查看
</button>
{(ticket.status === 'pending' || ticket.status === 'reviewing') && (
<button
onClick={async () => {
if (!confirm('确定撤销该工单?')) return;
try {
await ticketApi.cancel(ticket.id);
fetchTickets();
fetchStats();
} catch { /* ignore */ }
}}
className="flex items-center gap-1 text-amber-400 hover:text-amber-300 text-xs font-medium transition-colors"
>
<Ban className="w-3.5 h-3.5" />
撤销
</button>
)}
</div>
</td>
</tr>
@@ -886,6 +902,22 @@ function TicketDetail({ ticket, onBack, canApprove, canExecute, onActionDone }:
执行
</button>
)}
{(ticket.status === 'pending' || ticket.status === 'reviewing') && (
<button
onClick={async () => {
if (!confirm('确定撤销该工单?')) return;
try {
await ticketApi.cancel(ticket.id);
onActionDone();
} catch { /* ignore */ }
}}
disabled={loading}
className="flex items-center gap-2 px-4 py-2.5 bg-amber-500/15 border border-amber-500/30 rounded-lg text-sm font-medium text-amber-400 hover:bg-amber-500/25 transition-all disabled:opacity-50"
>
<Ban className="w-4 h-4" />
撤销
</button>
)}
</div>
</div>