import { useEffect, useState, useCallback } from 'react'; import { Table, Button, Space, Modal, Form, Input, InputNumber, Select, Popconfirm, message, } from 'antd'; import { PlusOutlined, EditOutlined, DeleteOutlined, } from '@ant-design/icons'; import { articleCategoryApi, type ArticleCategory, type CreateCategoryReq, type UpdateCategoryReq, } from '../../api/health/articles'; import { useThemeMode } from '../../hooks/useThemeMode'; import { AuthButton } from '../../components/AuthButton'; export default function ArticleCategoryManage() { const [categories, setCategories] = useState([]); const [loading, setLoading] = useState(false); const [modalOpen, setModalOpen] = useState(false); const [editingCategory, setEditingCategory] = useState(null); const [form] = Form.useForm(); const isDark = useThemeMode(); const fetchCategories = useCallback(async () => { setLoading(true); try { const result = await articleCategoryApi.list(); setCategories(result); } catch { message.error('加载分类列表失败'); } finally { setLoading(false); } }, []); useEffect(() => { fetchCategories(); }, [fetchCategories]); const openCreateModal = () => { setEditingCategory(null); form.resetFields(); form.setFieldsValue({ sort_order: 0 }); setModalOpen(true); }; const openEditModal = (record: ArticleCategory) => { setEditingCategory(record); form.setFieldsValue({ name: record.name, slug: record.slug, parent_id: record.parent_id, sort_order: record.sort_order, description: record.description, }); setModalOpen(true); }; const closeModal = () => { setModalOpen(false); setEditingCategory(null); form.resetFields(); }; const handleSubmit = async (values: { name: string; slug?: string; parent_id?: string; sort_order?: number; description?: string; }) => { try { if (editingCategory) { const req: UpdateCategoryReq = { name: values.name, slug: values.slug, parent_id: values.parent_id, sort_order: values.sort_order, description: values.description, }; await articleCategoryApi.update(editingCategory.id, req); message.success('分类更新成功'); } else { const req: CreateCategoryReq = { name: values.name, slug: values.slug, parent_id: values.parent_id, sort_order: values.sort_order, description: values.description, }; await articleCategoryApi.create(req); message.success('分类创建成功'); } closeModal(); fetchCategories(); } catch (err: unknown) { const errorMsg = (err as { response?: { data?: { message?: string } } })?.response?.data?.message || '操作失败'; message.error(errorMsg); } }; const handleDelete = async (id: string) => { try { await articleCategoryApi.delete(id); message.success('分类已删除'); fetchCategories(); } catch { message.error('删除失败,可能该分类下还有文章'); } }; // 构建父分类选项(排除自身) const parentOptions = categories .filter((c) => !editingCategory || c.id !== editingCategory.id) .map((c) => ({ label: c.name, value: c.id })); const columns = [ { title: '分类名称', dataIndex: 'name', key: 'name', render: (name: string) => ( {name} ), }, { title: '别名 (Slug)', dataIndex: 'slug', key: 'slug', width: 180, render: (v?: string) => v || -, }, { title: '父分类', dataIndex: 'parent_name', key: 'parent_name', width: 140, render: (_v: string | undefined, record: ArticleCategory) => { if (!record.parent_id) return -; const parent = categories.find((c) => c.id === record.parent_id); return parent?.name || record.parent_id; }, }, { title: '排序', dataIndex: 'sort_order', key: 'sort_order', width: 80, render: (v: number) => v ?? 0, }, { title: '描述', dataIndex: 'description', key: 'description', ellipsis: true, render: (v?: string) => v || -, }, { title: '操作', key: 'actions', width: 120, render: (_: unknown, record: ArticleCategory) => ( {/* 表格容器 */}
{/* 新建/编辑分类弹窗 */} form.submit()} width={520} >