import React, { useState } from 'react'; import { useQueryClient } from '@tanstack/react-query'; import { Layout, Menu, Button, Table, Space, Form, Input, Select, message, Modal, Card, Spin, Row, Col, Breadcrumb, Avatar, Dropdown, ConfigProvider, theme, Typography, Switch, Badge, Image, Upload, Divider, Descriptions, Popconfirm, Tag, Statistic, DatePicker, Radio, Progress, Tabs, List, Alert, Collapse, Empty, Drawer } from 'antd'; import { UploadOutlined, FileImageOutlined, FileExcelOutlined, FileWordOutlined, FilePdfOutlined, FileOutlined, } from '@ant-design/icons'; import { useQuery, } from '@tanstack/react-query'; import dayjs from 'dayjs'; import weekday from 'dayjs/plugin/weekday'; import localeData from 'dayjs/plugin/localeData'; import 'dayjs/locale/zh-cn'; import type { KnowInfo } from '../share/types.ts'; import { AuditStatus,AuditStatusNameMap, } from '../share/types.ts'; import { getEnumOptions } from './utils.ts'; import { KnowInfoAPI, type KnowInfoListResponse } from './api/index.ts'; // 配置 dayjs 插件 dayjs.extend(weekday); dayjs.extend(localeData); // 设置 dayjs 语言 dayjs.locale('zh-cn'); // 知识库管理页面组件 export const KnowInfoPage = () => { const queryClient = useQueryClient(); const [modalVisible, setModalVisible] = useState(false); const [formMode, setFormMode] = useState<'create' | 'edit'>('create'); const [editingId, setEditingId] = useState(null); const [form] = Form.useForm(); const [searchForm] = Form.useForm(); const [searchParams, setSearchParams] = useState({ title: '', category: '', page: 1, limit: 10, }); // 使用React Query获取知识库文章列表 const { data: articlesData, isLoading: isListLoading, refetch } = useQuery({ queryKey: ['knowInfos', searchParams], queryFn: () => KnowInfoAPI.getKnowInfos({ page: searchParams.page, pageSize: searchParams.limit, title: searchParams.title, category: searchParams.category }), placeholderData: { data: [], pagination: { current: 1, pageSize: 10, total: 0, totalPages: 1 } } }); const articles = React.useMemo(() => (articlesData as KnowInfoListResponse)?.data || [], [articlesData]); const pagination = React.useMemo(() => ({ current: (articlesData as KnowInfoListResponse)?.pagination?.current || 1, pageSize: (articlesData as KnowInfoListResponse)?.pagination?.pageSize || 10, total: (articlesData as KnowInfoListResponse)?.pagination?.total || 0, totalPages: (articlesData as KnowInfoListResponse)?.pagination?.totalPages || 1 }), [articlesData]); // 获取单个知识库文章 const fetchArticle = async (id: number) => { try { const response = await KnowInfoAPI.getKnowInfo(id); return response.data; } catch (error) { message.error('获取知识库文章详情失败'); return null; } }; // 处理表单提交 const handleSubmit = async (values: Partial) => { console.log('handleSubmit', values) try { const response = formMode === 'create' ? await KnowInfoAPI.createKnowInfo(values) : await KnowInfoAPI.updateKnowInfo(editingId!, values); message.success(formMode === 'create' ? '创建知识库文章成功' : '更新知识库文章成功'); setModalVisible(false); form.resetFields(); refetch(); } catch (error) { message.error((error as Error).message); } }; // 处理编辑 const handleEdit = async (id: number) => { const article = await fetchArticle(id); console.log('article', article) if (article) { setFormMode('edit'); setEditingId(id); form.setFieldsValue(article); setModalVisible(true); } }; // 处理删除 const handleDelete = async (id: number) => { try { await KnowInfoAPI.deleteKnowInfo(id); message.success('删除知识库文章成功'); refetch(); } catch (error) { message.error((error as Error).message); } }; // 处理搜索 const handleSearch = async (values: any) => { try { queryClient.removeQueries({ queryKey: ['knowInfos'] }); setSearchParams({ title: values.title || '', category: values.category || '', page: 1, limit: searchParams.limit, }); } catch (error) { message.error('搜索失败'); } }; // 处理分页 const handlePageChange = (page: number, pageSize?: number) => { setSearchParams(prev => ({ ...prev, page, limit: pageSize || prev.limit, })); }; // 处理添加 const handleAdd = () => { setFormMode('create'); setEditingId(null); form.resetFields(); setModalVisible(true); }; // 审核状态映射 const auditStatusOptions = getEnumOptions(AuditStatus, AuditStatusNameMap); // 表格列定义 const columns = [ { title: 'ID', dataIndex: 'id', key: 'id', width: 80, }, { title: '标题', dataIndex: 'title', key: 'title', }, { title: '分类', dataIndex: 'category', key: 'category', }, { title: '标签', dataIndex: 'tags', key: 'tags', render: (tags: string) => tags ? tags.split(',').map(tag => ( {tag} )) : null, }, { title: '作者', dataIndex: 'author', key: 'author', }, { title: '审核状态', dataIndex: 'audit_status', key: 'audit_status', render: (status: AuditStatus) => { let color = ''; let text = ''; switch(status) { case AuditStatus.PENDING: color = 'orange'; text = '待审核'; break; case AuditStatus.APPROVED: color = 'green'; text = '已通过'; break; case AuditStatus.REJECTED: color = 'red'; text = '已拒绝'; break; default: color = 'default'; text = '未知'; } return {text}; }, }, { title: '创建时间', dataIndex: 'created_at', key: 'created_at', render: (date: string) => new Date(date).toLocaleString(), }, { title: '操作', key: 'action', render: (_: any, record: KnowInfo) => ( handleDelete(record.id)} okText="确定" cancelText="取消" > ), }, ]; return (
`共 ${total} 条`, }} /> { form.validateFields() .then(values => { handleSubmit(values); }) .catch(info => { console.log('表单验证失败:', info); }); }} onCancel={() => setModalVisible(false)} width={800} okText="确定" cancelText="取消" destroyOnClose >