import { useState } from 'react'; import { Card, Table, Button, Input, Select, Tag, Space, Modal, Form, Popconfirm, Typography, Drawer, Upload, message, } from 'antd'; import { PlusOutlined, SearchOutlined, EditOutlined, DeleteOutlined, EyeOutlined, CheckOutlined, StopOutlined, InboxOutlined, UploadOutlined, } from '@ant-design/icons'; import { useKnowledgeArticles, useCreateArticle, useUpdateArticle, useDeleteArticle, usePublishArticle, useUnpublishArticle, useUploadKnowledgeFile, } from '../../application'; import type { Article, CreateArticleParams } from '../../infrastructure'; const { Title, Paragraph } = Typography; const { TextArea } = Input; const CATEGORIES = [ { value: 'QMAS', label: '优秀人才入境计划' }, { value: 'GEP', label: '一般就业政策' }, { value: 'IANG', label: '非本地毕业生留港/回港就业安排' }, { value: 'TTPS', label: '科技人才入境计划' }, { value: 'CIES', label: '资本投资者入境计划' }, { value: 'TechTAS', label: '顶尖人才通行证计划' }, { value: 'GENERAL', label: '通用知识' }, ]; export function KnowledgePage() { const [searchText, setSearchText] = useState(''); const [categoryFilter, setCategoryFilter] = useState(); const [isModalOpen, setIsModalOpen] = useState(false); const [isUploadModalOpen, setIsUploadModalOpen] = useState(false); const [isDrawerOpen, setIsDrawerOpen] = useState(false); const [selectedArticle, setSelectedArticle] = useState
(null); const [isExtracting, setIsExtracting] = useState(false); const [articleSource, setArticleSource] = useState<'MANUAL' | 'EXTRACT'>('MANUAL'); const [form] = Form.useForm(); const { data, isLoading } = useKnowledgeArticles(categoryFilter); const createMutation = useCreateArticle(); const updateMutation = useUpdateArticle(); const deleteMutation = useDeleteArticle(); const publishMutation = usePublishArticle(); const unpublishMutation = useUnpublishArticle(); const uploadMutation = useUploadKnowledgeFile(); const handleEdit = (article: Article) => { setSelectedArticle(article); form.setFieldsValue({ title: article.title, content: article.content, category: article.category, tags: article.tags, }); setIsModalOpen(true); }; const handleView = (article: Article) => { setSelectedArticle(article); setIsDrawerOpen(true); }; const handleSubmit = (values: CreateArticleParams) => { if (selectedArticle) { updateMutation.mutate( { id: selectedArticle.id, ...values }, { onSuccess: () => { setIsModalOpen(false); form.resetFields(); setSelectedArticle(null); }, } ); } else { createMutation.mutate({ ...values, source: articleSource }, { onSuccess: () => { setIsModalOpen(false); form.resetFields(); setArticleSource('MANUAL'); }, }); } }; const handleFileUpload = (file: File) => { setIsExtracting(true); uploadMutation.mutate(file, { onSuccess: (result) => { // 关闭上传弹窗,打开文章编辑弹窗(预填提取内容) setIsUploadModalOpen(false); setSelectedArticle(null); setArticleSource('EXTRACT'); form.resetFields(); form.setFieldsValue({ title: result.suggestedTitle, content: result.extractedText, }); setIsModalOpen(true); const info = result.pageCount ? `已提取 ${result.wordCount} 字(${result.pageCount} 页),请编辑后保存` : `已提取 ${result.wordCount} 字,请编辑后保存`; message.success(info); }, onSettled: () => setIsExtracting(false), }); return false; }; const columns = [ { title: '标题', dataIndex: 'title', key: 'title', render: (text: string, record: Article) => ( handleView(record)}>{text} ), }, { title: '类别', dataIndex: 'category', key: 'category', render: (category: string) => { const cat = CATEGORIES.find((c) => c.value === category); return {cat?.label || category}; }, }, { title: '来源', dataIndex: 'source', key: 'source', render: (source: string) => { const sourceMap: Record = { MANUAL: { color: 'green', label: '手动' }, CRAWL: { color: 'orange', label: '爬取' }, EXTRACT: { color: 'purple', label: '提取' }, IMPORT: { color: 'cyan', label: '导入' }, }; const s = sourceMap[source] || { color: 'default', label: source }; return {s.label}; }, }, { title: '状态', dataIndex: 'isPublished', key: 'isPublished', render: (isPublished: boolean) => isPublished ? ( 已发布 ) : ( 草稿 ), }, { title: '质量分', dataIndex: 'qualityScore', key: 'qualityScore', render: (score: number) => ( = 70 ? 'text-green-600' : score >= 40 ? 'text-yellow-600' : 'text-red-600' } > {score} ), }, { title: '引用次数', dataIndex: 'citationCount', key: 'citationCount', }, { title: '操作', key: 'action', render: (_: unknown, record: Article) => (