/** * useDepartmentOperations Hook * * 部门操作Hook * 统一管理部门相关的操作(创建、删除、重命名等) * 包括数据验证、错误处理、Toast通知 * * @created 2025-01-XX(从 page.tsx 提取) * @hook */ 'use client' import { useCallback } from 'react' import type { Department } from '../_components/types' import { parseErrorResponse } from '../_utils/api' import { validateDepartmentName } from '../_utils/validators' import type { ToastFn } from '../_components/types' interface UseDepartmentOperationsOptions { departments: Department[] setDepartments: React.Dispatch> showToast: ToastFn fetchDepartments: () => Promise loadUsersData: () => Promise } export function useDepartmentOperations({ departments, setDepartments, showToast, fetchDepartments, loadUsersData, }: UseDepartmentOperationsOptions) { const createDepartment = useCallback( async (name: string) => { const nameValidation = validateDepartmentName(name) if (!nameValidation.valid) { showToast(nameValidation.error || '部门名称不能为空', 'error') return false } const trimmed = name.trim() try { const response = await fetch('/api/departments', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ name: trimmed }), }) if (response.ok) { await fetchDepartments() showToast('部门添加成功') return true } const errorData = await parseErrorResponse(response) showToast(errorData.error || '添加失败', 'error') return false } catch (error) { console.error('Add department error:', error) showToast('添加失败,请稍后重试', 'error') return false } }, [fetchDepartments, showToast] ) const deleteDepartment = useCallback( async (id: string, name: string) => { try { const response = await fetch(`/api/departments?id=${id}`, { method: 'DELETE', }) if (response.ok) { const result = await response.json().catch(() => ({})) as { message?: string } await Promise.all([fetchDepartments(), loadUsersData()]) showToast(result.message || '部门删除成功') return true } const errorData = await parseErrorResponse(response) showToast(errorData.error || '删除失败', 'error') return false } catch (error) { console.error('Delete department error:', error) showToast('删除失败,请稍后重试', 'error') return false } }, [fetchDepartments, loadUsersData, showToast] ) const renameDepartment = useCallback( async (deptId: string, newName: string) => { const nameValidation = validateDepartmentName(newName) if (!nameValidation.valid) { showToast(nameValidation.error || '部门名称不能为空', 'error') return false } if (!deptId) { showToast('部门ID不能为空', 'error') return false } const trimmed = newName.trim() try { const response = await fetch('/api/departments', { method: 'PATCH', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ id: deptId, name: trimmed }), }) if (response.ok) { await fetchDepartments() showToast('部门重命名成功') return true } const errorData = await parseErrorResponse(response) showToast(errorData.error || '重命名失败', 'error') return false } catch (error) { console.error('Error renaming department:', error) showToast('重命名失败', 'error') return false } }, [fetchDepartments, showToast] ) return { createDepartment, deleteDepartment, renameDepartment, } } export type UseDepartmentOperationsReturn = ReturnType