/** 知识库管理页:7 类分类,录入、检索、删除,要素表模板预览 */ import { useEffect, useState } from 'react' import { toast } from 'sonner' import { BookOpen, Search, Plus, Trash2, Loader2, FileText, Scale, FileEdit, MapPin, Calendar, TrendingUp, Factory, Heart, Coffee, } from 'lucide-react' import { PageLayout } from '@/components/common/PageLayout' import { EmptyState } from '@/components/common/EmptyState' import { LoadingState } from '@/components/common/LoadingState' import { ErrorState } from '@/components/common/ErrorState' import { Card, CardContent } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Textarea } from '@/components/ui/textarea' import { Label } from '@/components/ui/label' import { Badge } from '@/components/ui/badge' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from '@/components/ui/dialog' import { api } from '@/lib/api' import { cn } from '@/lib/utils' import type { KnowledgeDoc } from '@/types' /** 知识库文档类型配置 */ const DOC_TYPES = [ { value: 'law', label: '法规', icon: Scale }, { value: 'case', label: '案例', icon: FileText }, { value: 'template', label: '模板', icon: FileEdit }, { value: 'guide', label: '经营指南', icon: TrendingUp }, { value: 'industry', label: '行业知识', icon: Factory }, { value: 'emotion', label: '情绪疏导', icon: Heart }, { value: 'life', label: '生活常识', icon: Coffee }, { value: 'element_template', label: '要素表模板', icon: FileText }, { value: 'debt_collection_template', label: '催收文书', icon: FileText }, { value: 'contract_risk_clause', label: '合同风险库', icon: FileText }, ] /** 来源英文 → 中文映射 */ const SOURCE_LABELS: Record = { seed: '系统内置', manual: '手动录入', import: '导入', api: 'API 录入', } /** 法规知识库管理:7 类分类,录入、检索、删除 */ export function KnowledgeBase() { const [docs, setDocs] = useState([]) const [counts, setCounts] = useState>({}) const [totalCount, setTotalCount] = useState(0) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [searchQuery, setSearchQuery] = useState('') const [searchResults, setSearchResults] = useState(null) const [searching, setSearching] = useState(false) const [filterType, setFilterType] = useState('all') const [addOpen, setAddOpen] = useState(false) const [deleteTarget, setDeleteTarget] = useState(null) // 新增表单 const [form, setForm] = useState({ title: '', content: '', doc_type: 'law', region: '', effective_date: '', keywords: '', }) const [saving, setSaving] = useState(false) const loadDocs = async () => { setLoading(true) setError(null) try { const res = await api.listKnowledge(filterType !== 'all' ? filterType : undefined) setDocs(res.results) setCounts(res.counts || {}) setTotalCount(res.total || 0) } catch (e) { setError(e instanceof Error ? e.message : '加载失败') } finally { setLoading(false) } } useEffect(() => { loadDocs() }, [filterType]) const handleSearch = async () => { if (!searchQuery.trim()) { setSearchResults(null) return } setSearching(true) try { const res = await api.searchKnowledge(searchQuery.trim()) setSearchResults(res.results) } catch (e) { toast.error(e instanceof Error ? e.message : '检索失败') } finally { setSearching(false) } } const handleAdd = async () => { if (!form.title.trim() || !form.content.trim()) { toast.error('标题和内容不能为空') return } setSaving(true) try { await api.addKnowledge({ title: form.title.trim(), content: form.content.trim(), doc_type: form.doc_type, region: form.region.trim() || null, effective_date: form.effective_date.trim() || null, keywords: form.keywords.trim() || null, }) toast.success('文档已添加') setAddOpen(false) setForm({ title: '', content: '', doc_type: 'law', region: '', effective_date: '', keywords: '' }) loadDocs() } catch (e) { toast.error(e instanceof Error ? e.message : '添加失败') } finally { setSaving(false) } } const handleDelete = async () => { if (!deleteTarget?.id) return try { await api.deleteKnowledge(deleteTarget.id) toast.success('文档已删除') setDeleteTarget(null) loadDocs() } catch (e) { toast.error(e instanceof Error ? e.message : '删除失败') } } const displayDocs = searchResults ?? docs return ( 新增知识文档 录入后将进入 RAG 检索库,提问时按场景自动引用相关知识。
setForm({ ...form, title: e.target.value })} placeholder="如:劳动合同法-试用期解除" />