Some checks failed
CI Check / check (push) Has been cancelled
- 创建统一UI三层架构系统(基础层、颜色层、组合层) - 拆分Admin页面为独立Tab组件(MonitorTab、UsersTab、DepartmentsTab等) - 提取公共逻辑到Hooks(useToast、useDataFetch、useUserOperations等) - 提取工具函数(validators、formatters、api等) - 创建统一弹窗组件(Modal)和useModal Hook - 添加错误边界和统一状态组件 - 完善类型定义和可访问性支持 - 更新文档(优化记录、优化计划、更新日志)
140 lines
3.9 KiB
TypeScript
140 lines
3.9 KiB
TypeScript
/**
|
|
* 部门操作 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<React.SetStateAction<Department[]>>
|
|
showToast: ToastFn
|
|
fetchDepartments: () => Promise<void>
|
|
loadUsersData: () => Promise<void>
|
|
}
|
|
|
|
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<typeof useDepartmentOperations>
|
|
|