import { useState, useEffect, useCallback } from 'react'; import { Plus, Search, Edit2, Trash2, Server, Users, ChevronRight, X } from 'lucide-react'; import { Card, CardContent } from '@/components/ui/card'; import { instanceGroupApi, type InstanceGroup } from '@/api/instanceGroup'; import { instanceApi } from '@/api/instance'; import { userApi } from '@/api/user'; import { useActionPermission } from '@/hooks/useAuth'; // 权限项 — 与后端 PERMISSION_ACTIONS 保持一致 var PERMISSION_CATEGORIES = [ { label: '查询权限', items: [ { code: 'query:select', name: 'SELECT 查询' }, { code: 'query:write', name: '写入操作 (INSERT/UPDATE/DELETE)' }, ], }, { label: '工单权限', items: [ { code: 'ticket:create', name: '创建工单' }, { code: 'ticket:approve', name: '审批工单' }, { code: 'ticket:execute', name: '执行工单' }, ], }, { label: 'DDL 权限', items: [ { code: 'ddl:execute', name: 'DDL 执行' }, ], }, { label: '运维权限', items: [ { code: 'slowlog:view', name: '查看慢日志' }, { code: 'backup:manage', name: '备份管理' }, { code: 'instance:detail', name: '实例详情' }, ], }, ]; var DB_TYPE_OPTIONS = [ { value: 'all', label: '全部类型' }, { value: 'mysql', label: 'MySQL' }, { value: 'pg', label: 'PostgreSQL' }, { value: 'redis', label: 'Redis' }, { value: 'mongo', label: 'MongoDB' }, ]; var DB_TYPE_COLORS: Record = { mysql: 'bg-[rgba(0,117,143,0.15)] text-[#26a69a]', pg: 'bg-[rgba(51,103,145,0.15)] text-[#42a5f5]', redis: 'bg-[rgba(220,50,32,0.15)] text-[#ef5350]', mongo: 'bg-[rgba(71,162,72,0.15)] text-[#66bb6a]', all: 'bg-[rgba(148,163,184,0.15)] text-[var(--dg-text-secondary)]', }; export default function InstanceGroupPage() { var [groups, setGroups] = useState([]); var [loading, setLoading] = useState(true); var [search, setSearch] = useState(''); var [selectedId, setSelectedId] = useState(null); var [showCreateModal, setShowCreateModal] = useState(false); var [showEditModal, setShowEditModal] = useState(false); var [showInstanceModal, setShowInstanceModal] = useState(false); var [showUserModal, setShowUserModal] = useState(false); var canManage = useActionPermission('instance-group.manage'); // 表单状态 var [formName, setFormName] = useState(''); var [formDesc, setFormDesc] = useState(''); var [formDbType, setFormDbType] = useState('all'); var [formPermissions, setFormPermissions] = useState([]); var [formIsActive, setFormIsActive] = useState(true); // 关联数据 var [allInstances, setAllInstances] = useState([]); var [allUsers, setAllUsers] = useState([]); var [selectedInstanceIds, setSelectedInstanceIds] = useState([]); var [selectedUserIds, setSelectedUserIds] = useState([]); var selectedGroup = groups.find(g => g.id === selectedId); var fetchGroups = useCallback(async () => { try { var data = await instanceGroupApi.list(); setGroups(data); setLoading(false); } catch { setLoading(false); } }, []); useEffect(() => { fetchGroups(); }, [fetchGroups]); // 加载关联数据 useEffect(() => { if (showInstanceModal) { instanceApi.list().then(setAllInstances).catch(() => {}); } if (showUserModal) { userApi.list().then(setAllUsers).catch(() => {}); } }, [showInstanceModal, showUserModal]); var filteredGroups = groups.filter(g => !search || g.name.includes(search) || (g.description || '').includes(search) ); var resetForm = () => { setFormName(''); setFormDesc(''); setFormDbType('all'); setFormPermissions([]); setFormIsActive(true); }; var handleCreate = async () => { if (!formName.trim()) return; await instanceGroupApi.create({ name: formName, description: formDesc || undefined, db_type: formDbType, permissions: formPermissions.length > 0 ? formPermissions : undefined, is_active: formIsActive, }); setShowCreateModal(false); resetForm(); fetchGroups(); }; var handleEdit = async () => { if (!selectedId || !formName.trim()) return; await instanceGroupApi.update(selectedId, { name: formName, description: formDesc || undefined, db_type: formDbType, permissions: formPermissions.length > 0 ? formPermissions : undefined, is_active: formIsActive, }); setShowEditModal(false); resetForm(); fetchGroups(); }; var handleDelete = async (id: number) => { if (!confirm('确定删除该权限组?')) return; await instanceGroupApi.delete(id); if (selectedId === id) setSelectedId(null); fetchGroups(); }; var openEditModal = (group: InstanceGroup) => { setFormName(group.name); setFormDesc(group.description || ''); setFormDbType(group.db_type); setFormPermissions(group.permissions || []); setFormIsActive(group.is_active); setShowEditModal(true); }; var handleAssignInstances = async () => { if (!selectedId || selectedInstanceIds.length === 0) return; await instanceGroupApi.assignInstances(selectedId, selectedInstanceIds); setShowInstanceModal(false); setSelectedInstanceIds([]); fetchGroups(); }; var handleAssignUsers = async () => { if (!selectedId || selectedUserIds.length === 0) return; await instanceGroupApi.assignUsers(selectedId, selectedUserIds); setShowUserModal(false); setSelectedUserIds([]); fetchGroups(); }; var togglePermission = (code: string) => { setFormPermissions(prev => prev.includes(code) ? prev.filter(p => p !== code) : [...prev, code] ); }; var toggleCategoryAll = (items: { code: string }[], checked: boolean) => { var codes = items.map(i => i.code); if (checked) { setFormPermissions(prev => [...new Set([...prev, ...codes])]); } else { setFormPermissions(prev => prev.filter(p => !codes.includes(p))); } }; // 渲染权限组表单 var renderGroupForm = (onSubmit: () => void, submitLabel: string) => (
setFormName(e.target.value)} placeholder="权限组名称" />