import { Card, CardContent } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Badge } from '@/components/ui/badge'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Search, Plus, Upload, Network, Mail, Phone, CheckCircle, XCircle, Eye, Edit, Trash2, Download, Key, Loader2, RefreshCw, User as UserIcon, } from 'lucide-react'; import { userApi } from '@/services/api'; import { UserFormDialog, type UserFormData } from './UserFormDialog'; interface SystemUserTabProps { // Search searchQuery: string; setSearchQuery: (v: string) => void; // Users filteredUsers: any[]; loading: boolean; selectedUser: any | null; setSelectedUser: (u: any | null) => void; getUserStatusBadge: (status: 'active' | 'inactive') => React.ReactNode; // Create / Edit dialogOpen: boolean; setDialogOpen: (open: boolean) => void; editingUser: any | null; form: UserFormData; setForm: React.Dispatch>; saving: boolean; handleSubmit: () => void; openCreate: () => void; openEdit: (user: any) => void; handleDelete: (user: any) => void; // CSV import importDialogOpen: 'csv' | 'ldap' | null; setImportDialogOpen: (v: 'csv' | 'ldap' | null) => void; importPreview: any[]; setImportPreview: (p: any[]) => void; importing: boolean; importResult: any; setImportResult: (r: any) => void; handleCsvUpload: (e: React.ChangeEvent) => void; handleBatchImport: () => void; // LDAP import ldapUsers: any[]; ldapSelected: Set; setLdapSelected: (s: Set) => void; ldapLoading: boolean; ldapImportOUs: any[]; ldapImportOUDN: string; setLdapImportOUDN: (v: string) => void; loadLdapUsers: (ouDn?: string) => void; handleLdapImport: () => void; setLdapUsers: (u: any[]) => void; } export function SystemUserTab({ searchQuery, setSearchQuery, filteredUsers, loading, selectedUser, setSelectedUser, getUserStatusBadge, dialogOpen, setDialogOpen, editingUser, form, setForm, saving, handleSubmit, openCreate, openEdit, handleDelete, importDialogOpen, setImportDialogOpen, importPreview, setImportPreview, importing, importResult, setImportResult, handleCsvUpload, handleBatchImport, ldapUsers, ldapSelected, setLdapSelected, ldapLoading, ldapImportOUs, ldapImportOUDN, setLdapImportOUDN, loadLdapUsers, handleLdapImport, setLdapUsers, }: SystemUserTabProps) { return ( <> {/* Filters */}
setSearchQuery(e.target.value)} className="pl-9 h-9 bg-slate-800/50 border-slate-700 text-slate-200 placeholder:text-slate-500" />
{/* Users Table */}
用户信息 联系方式 角色 来源 状态 最后登录 操作 {loading ? (
) : filteredUsers.length === 0 ? ( 暂无用户数据 ) : ( filteredUsers.map((user) => (
{(user.nickname || user.username || '?').charAt(0)}

{user.nickname || user.username}

@{user.username}

{user.email || '--'}
{user.phone && (
{user.phone}
)}
{(user.roles || []).map((role: string) => ( {role} ))}
{user.authSource === 'ldap' ? ( LDAP ) : ( 本地 )} {getUserStatusBadge(user.status)} {user.lastLoginAt ? new Date(user.lastLoginAt).toLocaleString() : '--'}
)) )}
{/* User Detail Dialog */} setSelectedUser(null)}> {selectedUser?.nickname} @{selectedUser?.username} · {selectedUser?.email}

用户名

{selectedUser?.username}

昵称

{selectedUser?.nickname}

邮箱

{selectedUser?.email}

手机号

{selectedUser?.phone || '--'}

状态

{selectedUser && getUserStatusBadge(selectedUser.status)}

创建时间

{selectedUser && selectedUser.createdAt ? new Date(selectedUser.createdAt).toLocaleDateString() : '--'}

角色

{selectedUser?.roles.map((role: string) => ( {role} ))}
{/* Create / Edit User Dialog */} {/* CSV 批量导入 Dialog */} !v && setImportDialogOpen(null)}> 批量导入用户(CSV) 上传 CSV 文件批量创建用户。请先下载模板,按格式填写后上传。 {!importResult ? ( <>
{importPreview.length > 0 && (
预览:{importPreview.length} 条数据
用户名 昵称 邮箱 手机 {importPreview.slice(0, 5).map((u, i) => ( {u.username} {u.nickname} {u.email} {u.phone} ))} {importPreview.length > 5 && ( 还有 {importPreview.length - 5} 条... )}
)}
) : (
{importResult.code === 200 ? ( ) : ( )} {importResult.message}
{importResult.errors?.length > 0 && (
{importResult.errors.map((err: string, i: number) => (
{err}
))}
)}
)}
{/* LDAP 导入 Dialog */} !v && setImportDialogOpen(null)}> 从 LDAP 导入用户 从 LDAP 服务器检索用户列表,选择需要导入的用户 {!importResult ? ( <>
选择 OU

{ldapUsers.length > 0 ? `找到 ${ldapUsers.length} 个用户` : '选择 OU 或点击刷新获取用户列表'}

{ldapUsers.length > 0 && (
0} onChange={(e) => { if (e.target.checked) { setLdapSelected(new Set(ldapUsers.map((u) => u.dn))); } else { setLdapSelected(new Set()); } }} /> 用户名 显示名 邮箱 DN {ldapUsers.map((u) => ( { const next = new Set(ldapSelected); if (e.target.checked) next.add(u.dn); else next.delete(u.dn); setLdapSelected(next); }} /> {u.uid} {u.cn} {u.mail} {u.dn} ))}
)}
) : (
{importResult.code === 200 ? ( ) : ( )} {importResult.message}
)}
); }