refactor: 拆分SystemManager.tsx(569→308行)提取useLdapManagement自定义Hook封装全部LDAP状态与业务逻辑

This commit is contained in:
attacker committed 2026-06-17 07:08:01 +08:00
1 parent d234cb4b89
commit 019a9d13f3
2 files changed
+359 -284

No files matched your search

+23 -284
View File
@@ -1,15 +1,15 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { toast } from 'sonner';
import { useConfirm } from '@/components/ui/confirm-dialog'; import { useConfirm } from '@/components/ui/confirm-dialog';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
import { CheckCircle, XCircle, Users, Shield, FileCode, Settings } from 'lucide-react'; import { CheckCircle, XCircle, Users, Shield, FileCode, Settings } from 'lucide-react';
import { userApi, ldapApi } from '@/services/api'; import { userApi } from '@/services/api';
import type { Role } from '@/types'; import type { Role } from '@/types';
import { SystemUserTab } from './SystemUserTab'; import { SystemUserTab } from './SystemUserTab';
import { SystemRolesTab } from './SystemRolesTab'; import { SystemRolesTab } from './SystemRolesTab';
import { SystemLogsTab } from './SystemLogsTab'; import { SystemLogsTab } from './SystemLogsTab';
import { SystemSettingsTab, type LdapFormData } from './SystemSettingsTab'; import { SystemSettingsTab } from './SystemSettingsTab';
import { useLdapManagement } from './useLdapManagement';
import type { UserFormData } from './UserFormDialog'; import type { UserFormData } from './UserFormDialog';
// 后端用户数据转换为前端兼容格式 // 后端用户数据转换为前端兼容格式
@@ -49,48 +49,11 @@ export function SystemManager() {
const [saving, setSaving] = useState(false); const [saving, setSaving] = useState(false);
const [form, setForm] = useState<UserFormData>({ ...emptyForm }); const [form, setForm] = useState<UserFormData>({ ...emptyForm });
// 批量导入弹窗 // CSV 批量导入弹窗
const [importDialogOpen, setImportDialogOpen] = useState<'csv' | 'ldap' | null>(null); const [importDialogOpen, setImportDialogOpen] = useState<'csv' | 'ldap' | null>(null);
const [importPreview, setImportPreview] = useState<any[]>([]); const [importPreview, setImportPreview] = useState<any[]>([]);
const [importing, setImporting] = useState(false);
const [importResult, setImportResult] = useState<any>(null); const [importResult, setImportResult] = useState<any>(null);
// LDAP 用户列表
const [ldapUsers, setLdapUsers] = useState<any[]>([]);
const [ldapSelected, setLdapSelected] = useState<Set<string>>(new Set());
const [ldapLoading, setLdapLoading] = useState(false);
const [ldapImportOUs, setLdapImportOUs] = useState<any[]>([]);
const [ldapImportOUDN, setLdapImportOUDN] = useState('');
// LDAP 配置
const [ldapConfig, setLdapConfig] = useState<any>(null);
const [ldapForm, setLdapForm] = useState<LdapFormData>({
ldap_host: '', ldap_port: 389, use_ldaps: false,
admin_dn: '', admin_password: '', base_dn: '', search_filter: '',
});
const [ldapSaving, setLdapSaving] = useState(false);
const [ldapTesting, setLdapTesting] = useState(false);
const [ldapTestResult, setLdapTestResult] = useState<string | null>(null);
const [ldapMgmtOpen, setLdapMgmtOpen] = useState(false);
const [importFeedback, setImportFeedback] = useState<string | null>(null);
const [importResultOpen, setImportResultOpen] = useState(false);
// LDAP 账号管理
const [ldapOUs, setLdapOUs] = useState<any[]>([]);
const [selectedOUDN, setSelectedOUDN] = useState('');
const [selectedLDAPUsers, setSelectedLDAPUsers] = useState<string[]>([]);
const [createOUOpen, setCreateOUOpen] = useState(false);
const [createUserOpen, setCreateUserOpen] = useState(false);
const [ouForm, setOuForm] = useState({ ou_name: '', parent_dn: '', description: '' });
const [newUser, setNewUser] = useState({ username: '', password: '', display_name: '', email: '', ou_dn: '' });
const [ldapUserTestOpen, setLdapUserTestOpen] = useState(false);
const [ldapTestUser, setLdapTestUser] = useState('');
const [ldapTestPass, setLdapTestPass] = useState('');
const [ldapUserTesting, setLdapUserTesting] = useState(false);
const [ldapUserTestResult, setLdapUserTestResult] = useState<any>(null);
const [editLdapUser, setEditLdapUser] = useState<any>(null);
const [editLdapForm, setEditLdapForm] = useState({ cn: '', mail: '', phone: '', title: '' });
const loadUsers = async () => { const loadUsers = async () => {
setLoading(true); setLoading(true);
try { try {
@@ -105,16 +68,18 @@ export function SystemManager() {
} }
}; };
// LDAP 状态全部由 hook 管理(在 loadUsers 之后调用避免 TDZ) // Logan.Li
const ldap = useLdapManagement(loadUsers);
useEffect(() => { useEffect(() => {
loadUsers(); loadUsers();
loadLdapConfig(); ldap.loadLdapConfig();
}, []); }, []);
// LDAP 导入 Dialog 打开时加载 OU 和用户 // LDAP 导入 Dialog 打开时加载 OU 和用户
useEffect(() => { useEffect(() => {
if (importDialogOpen === 'ldap') { if (importDialogOpen === 'ldap') {
ldapApi.listOUs().then(ous => setLdapImportOUs(Array.isArray(ous) ? ous : [])).catch(() => {}); ldap.loadImportDialogData();
loadLdapUsers('');
} }
}, [importDialogOpen]); }, [importDialogOpen]);
@@ -236,7 +201,7 @@ export function SystemManager() {
// 执行 CSV 批量导入 // 执行 CSV 批量导入
const handleBatchImport = async () => { const handleBatchImport = async () => {
setImporting(true); ldap.setImporting(true);
try { try {
const res = await userApi.batchImport({ users: importPreview, skip_existing: true }); const res = await userApi.batchImport({ users: importPreview, skip_existing: true });
setImportResult(res); setImportResult(res);
@@ -244,236 +209,10 @@ export function SystemManager() {
} catch (error: any) { } catch (error: any) {
setImportResult({ code: 500, message: error?.message || '导入失败' }); setImportResult({ code: 500, message: error?.message || '导入失败' });
} finally { } finally {
setImporting(false); ldap.setImporting(false);
} }
}; };
// 加载 LDAP 用户列表
const loadLdapUsers = async (ouDn?: string) => {
setLdapLoading(true);
try {
const res = await ldapApi.listUsers(ouDn);
setLdapUsers(Array.isArray(res) ? res : []);
setLdapSelected(new Set());
} catch {
setLdapUsers([]);
} finally {
setLdapLoading(false);
}
};
// 执行 LDAP 导入
const handleLdapImport = async () => {
let selected: any[] = [];
if (selectedLDAPUsers.length > 0) {
selected = ldapUsers.filter((u) => selectedLDAPUsers.includes(u.dn));
} else {
selected = ldapUsers; // 没有选择则导入全部
}
if (selected.length === 0) return;
setImporting(true);
try {
const mapped = selected.map((u) => ({
username: u.uid || '',
nickname: u.cn || '',
email: u.mail || '',
}));
const res = await ldapApi.batchImport(mapped);
setImportFeedback(res?.message || `成功导入 ${selected.length} 个用户`);
setImportResultOpen(true);
setSelectedLDAPUsers([]);
await loadUsers();
} catch (error: any) {
setImportFeedback('导入失败: ' + (error?.message || '未知错误'));
setImportResultOpen(true);
} finally {
setImporting(false);
}
};
// 加载 LDAP 配置
const loadLdapConfig = async () => {
try {
const res = await ldapApi.getConfig();
if (res && res.ldap_host) {
setLdapConfig(res);
setLdapForm({
ldap_host: res.ldap_host || '',
ldap_port: res.ldap_port || 389,
use_ldaps: res.use_ldaps || false,
admin_dn: res.admin_dn || '',
admin_password: '',
base_dn: res.base_dn || '',
search_filter: res.search_filter || '',
});
}
} catch {
// No config yet
}
};
// 保存 LDAP 配置
const handleLdapSave = async () => {
setLdapSaving(true);
try {
await ldapApi.updateConfig(ldapForm);
await loadLdapConfig();
} catch (error) {
console.error('Failed to save LDAP config:', error);
} finally {
setLdapSaving(false);
}
};
// 测试 LDAP 连接
const handleLdapTest = async () => {
setLdapTesting(true);
setLdapTestResult(null);
try {
await ldapApi.updateConfig(ldapForm);
const res = await ldapApi.testConnection();
setLdapTestResult(res?.message || (res?.success ? '连接成功' : '连接失败'));
} catch (error: any) {
setLdapTestResult(error?.message || '连接失败');
} finally {
setLdapTesting(false);
}
};
// LDAP 账号管理函数
const loadLdapOUs = async () => {
try {
const ous = await ldapApi.listOUs();
setLdapOUs(ous || []);
// 同时加载根 DN 下的用户
if (!selectedOUDN && ldapConfig?.base_dn) {
setSelectedOUDN(ldapConfig.base_dn);
await loadLdapOUUsers(ldapConfig.base_dn);
}
} catch (e) { console.error('loadOUs', e); }
};
const loadLdapOUUsers = async (ouDn?: string) => {
try {
const users = await ldapApi.listUsers(ouDn);
setLdapUsers(users || []);
} catch (e) { console.error('loadOUUsers', e); }
};
const handleCreateOU = async () => {
setLdapSaving(true);
try {
await ldapApi.createOU(ouForm);
setCreateOUOpen(false);
setOuForm({ ou_name: '', parent_dn: '', description: '' });
await loadLdapOUs();
} catch (e: any) {
const msg = e?.message || '';
if (msg.includes('Already Exists') || msg.includes('68')) {
toast.error(`OU "${ouForm.ou_name}" 已存在,请使用其他名称`);
} else {
toast.error('创建失败: ' + msg);
}
} finally { setLdapSaving(false); }
};
const handleCreateLDAPUser = async () => {
setLdapSaving(true);
try {
await ldapApi.createUser({ ...newUser, ou_dn: newUser.ou_dn || selectedOUDN || ldapConfig?.base_dn });
setCreateUserOpen(false);
setNewUser({ username: '', password: '', display_name: '', email: '', ou_dn: '' });
await loadLdapOUUsers(selectedOUDN);
} catch (e: any) { toast.error(e?.message || '创建失败'); }
finally { setLdapSaving(false); }
};
const handleDeleteLDAPEntry = async (dn: string, silent = false) => {
if (!silent) { const ok = await confirm({ title: '删除 LDAP 条目', description: `确定删除 ${dn}?`, confirmText: '删除', variant: 'destructive' }); if (!ok) return; }
try {
await ldapApi.deleteUser(dn);
if (!silent) await loadLdapOUUsers(selectedOUDN);
} catch (e: any) { if (!silent) toast.error(e?.message || '删除失败'); }
};
const openEditLdapUser = (user: any) => {
setEditLdapUser(user);
setEditLdapForm({ cn: user.cn || '', mail: user.mail || '', phone: user.phone || '', title: user.title || '' });
};
const handleUpdateLdapUser = async () => {
if (!editLdapUser) return;
try {
await ldapApi.updateUser({ dn: editLdapUser.dn, ...editLdapForm });
setEditLdapUser(null);
await loadLdapOUUsers(selectedOUDN);
} catch (e: any) { toast.error(e?.message || '修改失败'); }
};
const handleLdapUserTest = async () => {
setLdapUserTesting(true);
setLdapUserTestResult(null);
try {
const res = await ldapApi.testConnection({ test_user: ldapTestUser, test_password: ldapTestPass });
setLdapUserTestResult(res);
} catch (e: any) {
setLdapUserTestResult({ success: false, message: e?.message || '验证失败' });
} finally { setLdapUserTesting(false); }
};
// Settings tab props (LDAP management pass-through)
const settingsTabProps = {
ldapConfig,
ldapForm,
setLdapForm,
ldapSaving,
ldapTesting,
ldapTestResult,
handleLdapSave,
handleLdapTest,
ldapMgmtOpen,
setLdapMgmtOpen,
ldapOUs,
selectedOUDN,
setSelectedOUDN,
ldapUsers,
selectedLDAPUsers,
setSelectedLDAPUsers,
loadLdapOUs,
loadLdapOUUsers,
handleLdapImport,
importing,
importFeedback,
importResultOpen,
setImportResultOpen,
createOUOpen,
setCreateOUOpen,
ouForm,
setOuForm,
handleCreateOU,
createUserOpen,
setCreateUserOpen,
newUser,
setNewUser,
handleCreateLDAPUser,
ldapUserTestOpen,
setLdapUserTestOpen,
ldapTestUser,
setLdapTestUser,
ldapTestPass,
setLdapTestPass,
ldapUserTesting,
ldapUserTestResult,
handleLdapUserTest,
editLdapUser,
setEditLdapUser,
editLdapForm,
setEditLdapForm,
handleUpdateLdapUser,
handleDeleteLDAPEntry,
openEditLdapUser,
};
return ( return (
<div className="space-y-6"> <div className="space-y-6">
{/* Page Header */} {/* Page Header */}
@@ -528,21 +267,21 @@ export function SystemManager() {
setImportDialogOpen={setImportDialogOpen} setImportDialogOpen={setImportDialogOpen}
importPreview={importPreview} importPreview={importPreview}
setImportPreview={setImportPreview} setImportPreview={setImportPreview}
importing={importing} importing={ldap.importing}
importResult={importResult} importResult={importResult}
setImportResult={setImportResult} setImportResult={setImportResult}
handleCsvUpload={handleCsvUpload} handleCsvUpload={handleCsvUpload}
handleBatchImport={handleBatchImport} handleBatchImport={handleBatchImport}
ldapUsers={ldapUsers} ldapUsers={ldap.ldapUsers}
ldapSelected={ldapSelected} ldapSelected={ldap.ldapSelected}
setLdapSelected={setLdapSelected} setLdapSelected={ldap.setLdapSelected}
ldapLoading={ldapLoading} ldapLoading={ldap.ldapLoading}
ldapImportOUs={ldapImportOUs} ldapImportOUs={ldap.ldapImportOUs}
ldapImportOUDN={ldapImportOUDN} ldapImportOUDN={ldap.ldapImportOUDN}
setLdapImportOUDN={setLdapImportOUDN} setLdapImportOUDN={ldap.setLdapImportOUDN}
loadLdapUsers={loadLdapUsers} loadLdapUsers={ldap.loadLdapUsers}
handleLdapImport={handleLdapImport} handleLdapImport={ldap.handleLdapImport}
setLdapUsers={setLdapUsers} setLdapUsers={ldap.setLdapUsers}
/> />
</TabsContent> </TabsContent>
@@ -561,7 +300,7 @@ export function SystemManager() {
</TabsContent> </TabsContent>
<TabsContent value="settings" className="mt-4"> <TabsContent value="settings" className="mt-4">
<SystemSettingsTab {...settingsTabProps} /> <SystemSettingsTab {...ldap.settingsTabProps} />
</TabsContent> </TabsContent>
</Tabs> </Tabs>
</div> </div>
@@ -0,0 +1,336 @@
import { useState } from 'react';
import { toast } from 'sonner';
import { useConfirm } from '@/components/ui/confirm-dialog';
import { ldapApi } from '@/services/api';
import type { LdapFormData } from './SystemSettingsTab';
/**
* useLdapManagement — 封装 SystemManager 中所有 LDAP 相关状态与业务逻辑
*
* 包含三大块:
* 1. LDAP 配置管理(连接信息读写 + 测试连接)
* 2. LDAP 账号管理(OU/用户 CRUD + 属性编辑 + 认证测试)
* 3. LDAP 用户导入(导入弹窗用:OU 下拉 + 用户列表 + 批量导入)
*
* 另外持有 `importing` 状态,供 CSV 批量导入与 LDAP 导入共用。
*
* @param onUsersChanged 导入用户后回调(刷新本地用户列表)
* // Logan.Li
*/
export function useLdapManagement(onUsersChanged: () => Promise<void> | void) {
const confirm = useConfirm();
// ===== LDAP 用户导入(用户管理 Tab 的导入弹窗用) =====
const [ldapUsers, setLdapUsers] = useState<any[]>([]);
const [ldapSelected, setLdapSelected] = useState<Set<string>>(new Set());
const [ldapLoading, setLdapLoading] = useState(false);
const [ldapImportOUs, setLdapImportOUs] = useState<any[]>([]);
const [ldapImportOUDN, setLdapImportOUDN] = useState('');
// ===== LDAP 配置 =====
const [ldapConfig, setLdapConfig] = useState<any>(null);
const [ldapForm, setLdapForm] = useState<LdapFormData>({
ldap_host: '', ldap_port: 389, use_ldaps: false,
admin_dn: '', admin_password: '', base_dn: '', search_filter: '',
});
const [ldapSaving, setLdapSaving] = useState(false);
const [ldapTesting, setLdapTesting] = useState(false);
const [ldapTestResult, setLdapTestResult] = useState<string | null>(null);
const [ldapMgmtOpen, setLdapMgmtOpen] = useState(false);
const [importFeedback, setImportFeedback] = useState<string | null>(null);
const [importResultOpen, setImportResultOpen] = useState(false);
// ===== LDAP 账号管理 =====
const [ldapOUs, setLdapOUs] = useState<any[]>([]);
const [selectedOUDN, setSelectedOUDN] = useState('');
const [selectedLDAPUsers, setSelectedLDAPUsers] = useState<string[]>([]);
const [createOUOpen, setCreateOUOpen] = useState(false);
const [createUserOpen, setCreateUserOpen] = useState(false);
const [ouForm, setOuForm] = useState({ ou_name: '', parent_dn: '', description: '' });
const [newUser, setNewUser] = useState({ username: '', password: '', display_name: '', email: '', ou_dn: '' });
const [ldapUserTestOpen, setLdapUserTestOpen] = useState(false);
const [ldapTestUser, setLdapTestUser] = useState('');
const [ldapTestPass, setLdapTestPass] = useState('');
const [ldapUserTesting, setLdapUserTesting] = useState(false);
const [ldapUserTestResult, setLdapUserTestResult] = useState<any>(null);
const [editLdapUser, setEditLdapUser] = useState<any>(null);
const [editLdapForm, setEditLdapForm] = useState({ cn: '', mail: '', phone: '', title: '' });
// 导入进行中状态(CSV 与 LDAP 导入共用)
const [importing, setImporting] = useState(false);
// ===== LDAP 配置相关 handler =====
/** 加载 LDAP 配置 // Logan.Li */
const loadLdapConfig = async () => {
try {
const res = await ldapApi.getConfig();
if (res && res.ldap_host) {
setLdapConfig(res);
setLdapForm({
ldap_host: res.ldap_host || '',
ldap_port: res.ldap_port || 389,
use_ldaps: res.use_ldaps || false,
admin_dn: res.admin_dn || '',
admin_password: '',
base_dn: res.base_dn || '',
search_filter: res.search_filter || '',
});
}
} catch {
// 暂无配置
}
};
/** 保存 LDAP 配置 // Logan.Li */
const handleLdapSave = async () => {
setLdapSaving(true);
try {
await ldapApi.updateConfig(ldapForm);
await loadLdapConfig();
} catch (error) {
console.error('Failed to save LDAP config:', error);
} finally {
setLdapSaving(false);
}
};
/** 测试 LDAP 连接 // Logan.Li */
const handleLdapTest = async () => {
setLdapTesting(true);
setLdapTestResult(null);
try {
await ldapApi.updateConfig(ldapForm);
const res = await ldapApi.testConnection();
setLdapTestResult(res?.message || (res?.success ? '连接成功' : '连接失败'));
} catch (error: any) {
setLdapTestResult(error?.message || '连接失败');
} finally {
setLdapTesting(false);
}
};
// ===== LDAP 账号管理相关 handler =====
/** 加载指定 OU 下的用户 // Logan.Li */
const loadLdapOUUsers = async (ouDn?: string) => {
try {
const users = await ldapApi.listUsers(ouDn);
setLdapUsers(users || []);
} catch (e) { console.error('loadOUUsers', e); }
};
/** 加载 OU 列表(含根 DN 用户) // Logan.Li */
const loadLdapOUs = async () => {
try {
const ous = await ldapApi.listOUs();
setLdapOUs(ous || []);
// 同时加载根 DN 下的用户
if (!selectedOUDN && ldapConfig?.base_dn) {
setSelectedOUDN(ldapConfig.base_dn);
await loadLdapOUUsers(ldapConfig.base_dn);
}
} catch (e) { console.error('loadOUs', e); }
};
/** 创建 OU // Logan.Li */
const handleCreateOU = async () => {
setLdapSaving(true);
try {
await ldapApi.createOU(ouForm);
setCreateOUOpen(false);
setOuForm({ ou_name: '', parent_dn: '', description: '' });
await loadLdapOUs();
} catch (e: any) {
const msg = e?.message || '';
if (msg.includes('Already Exists') || msg.includes('68')) {
toast.error(`OU "${ouForm.ou_name}" 已存在,请使用其他名称`);
} else {
toast.error('创建失败: ' + msg);
}
} finally { setLdapSaving(false); }
};
/** 创建 LDAP 用户 // Logan.Li */
const handleCreateLDAPUser = async () => {
setLdapSaving(true);
try {
await ldapApi.createUser({ ...newUser, ou_dn: newUser.ou_dn || selectedOUDN || ldapConfig?.base_dn });
setCreateUserOpen(false);
setNewUser({ username: '', password: '', display_name: '', email: '', ou_dn: '' });
await loadLdapOUUsers(selectedOUDN);
} catch (e: any) { toast.error(e?.message || '创建失败'); }
finally { setLdapSaving(false); }
};
/** 删除 LDAP 条目 // Logan.Li */
const handleDeleteLDAPEntry = async (dn: string, silent = false) => {
if (!silent) {
const ok = await confirm({ title: '删除 LDAP 条目', description: `确定删除 ${dn}?`, confirmText: '删除', variant: 'destructive' });
if (!ok) return;
}
try {
await ldapApi.deleteUser(dn);
if (!silent) await loadLdapOUUsers(selectedOUDN);
} catch (e: any) { if (!silent) toast.error(e?.message || '删除失败'); }
};
/** 打开 LDAP 用户编辑 // Logan.Li */
const openEditLdapUser = (user: any) => {
setEditLdapUser(user);
setEditLdapForm({ cn: user.cn || '', mail: user.mail || '', phone: user.phone || '', title: user.title || '' });
};
/** 更新 LDAP 用户属性 // Logan.Li */
const handleUpdateLdapUser = async () => {
if (!editLdapUser) return;
try {
await ldapApi.updateUser({ dn: editLdapUser.dn, ...editLdapForm });
setEditLdapUser(null);
await loadLdapOUUsers(selectedOUDN);
} catch (e: any) { toast.error(e?.message || '修改失败'); }
};
/** LDAP 账号验证测试 // Logan.Li */
const handleLdapUserTest = async () => {
setLdapUserTesting(true);
setLdapUserTestResult(null);
try {
const res = await ldapApi.testConnection({ test_user: ldapTestUser, test_password: ldapTestPass });
setLdapUserTestResult(res);
} catch (e: any) {
setLdapUserTestResult({ success: false, message: e?.message || '验证失败' });
} finally { setLdapUserTesting(false); }
};
// ===== LDAP 用户导入相关 handler =====
/** 加载 LDAP 用户列表(导入弹窗用) // Logan.Li */
const loadLdapUsers = async (ouDn?: string) => {
setLdapLoading(true);
try {
const res = await ldapApi.listUsers(ouDn);
setLdapUsers(Array.isArray(res) ? res : []);
setLdapSelected(new Set());
} catch {
setLdapUsers([]);
} finally {
setLdapLoading(false);
}
};
/** 执行 LDAP 批量导入 // Logan.Li */
const handleLdapImport = async () => {
let selected: any[] = [];
if (selectedLDAPUsers.length > 0) {
selected = ldapUsers.filter((u) => selectedLDAPUsers.includes(u.dn));
} else {
selected = ldapUsers; // 没有选择则导入全部
}
if (selected.length === 0) return;
setImporting(true);
try {
const mapped = selected.map((u) => ({
username: u.uid || '',
nickname: u.cn || '',
email: u.mail || '',
}));
const res = await ldapApi.batchImport(mapped);
setImportFeedback(res?.message || `成功导入 ${selected.length} 个用户`);
setImportResultOpen(true);
setSelectedLDAPUsers([]);
await onUsersChanged();
} catch (error: any) {
setImportFeedback('导入失败: ' + (error?.message || '未知错误'));
setImportResultOpen(true);
} finally {
setImporting(false);
}
};
/** LDAP 导入弹窗打开时加载 OU 和用户列表 // Logan.Li */
const loadImportDialogData = () => {
ldapApi.listOUs()
.then((ous) => setLdapImportOUs(Array.isArray(ous) ? ous : []))
.catch(() => {});
loadLdapUsers('');
};
// ===== 构造传递给 SystemSettingsTab 的 props 对象 =====
const settingsTabProps = {
ldapConfig,
ldapForm,
setLdapForm,
ldapSaving,
ldapTesting,
ldapTestResult,
handleLdapSave,
handleLdapTest,
ldapMgmtOpen,
setLdapMgmtOpen,
ldapOUs,
selectedOUDN,
setSelectedOUDN,
ldapUsers,
selectedLDAPUsers,
setSelectedLDAPUsers,
loadLdapOUs,
loadLdapOUUsers,
handleLdapImport,
importing,
importFeedback,
importResultOpen,
setImportResultOpen,
createOUOpen,
setCreateOUOpen,
ouForm,
setOuForm,
handleCreateOU,
createUserOpen,
setCreateUserOpen,
newUser,
setNewUser,
handleCreateLDAPUser,
ldapUserTestOpen,
setLdapUserTestOpen,
ldapTestUser,
setLdapTestUser,
ldapTestPass,
setLdapTestPass,
ldapUserTesting,
ldapUserTestResult,
handleLdapUserTest,
editLdapUser,
setEditLdapUser,
editLdapForm,
setEditLdapForm,
handleUpdateLdapUser,
handleDeleteLDAPEntry,
openEditLdapUser,
};
return {
// LDAP 用户导入(用户管理 Tab)
ldapUsers,
setLdapUsers,
ldapSelected,
setLdapSelected,
ldapLoading,
ldapImportOUs,
ldapImportOUDN,
setLdapImportOUDN,
loadLdapUsers,
handleLdapImport,
loadImportDialogData,
// 导入状态(CSV + LDAP 共用)
importing,
setImporting,
importFeedback,
importResultOpen,
setImportResultOpen,
// 初始化
loadLdapConfig,
// 系统设置 Tab
settingsTabProps,
};
}