| 'use client'; | |
| import { useState } from 'react'; | |
| import Link from 'next/link'; | |
| export default function KnowledgeLibrary() { | |
| const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid'); | |
| const [selectedKnowledgeBases, setSelectedKnowledgeBases] = useState<string[]>([]); | |
| const knowledgeBases = [ | |
| { | |
| id: 'kb-001', | |
| name: '通用知识库', | |
| description: '包含基础常识和通用信息,适用于大多数场景的问答需求', | |
| category: '通用', | |
| items: 1240, | |
| size: '15.6 MB', | |
| status: 'active', | |
| lastUpdated: '2024-01-15', | |
| creator: '系统默认', | |
| isDefault: true, | |
| usage: 856, | |
| tags: ['通用', '基础', '默认'] | |
| }, | |
| { | |
| id: 'kb-002', | |
| name: '技术文档库', | |
| description: '收录了各种技术文档、API说明和开发指南,为技术问题提供专业解答', | |
| category: '技术', | |
| items: 567, | |
| size: '8.3 MB', | |
| status: 'active', | |
| lastUpdated: '2024-01-14', | |
| creator: '张工程师', | |
| isDefault: false, | |
| usage: 423, | |
| tags: ['技术', 'API', '开发'] | |
| }, | |
| { | |
| id: 'kb-003', | |
| name: '产品说明库', | |
| description: '产品功能介绍、使用手册和操作指南,帮助用户更好地了解产品特性', | |
| category: '产品', | |
| items: 892, | |
| size: '12.1 MB', | |
| status: 'active', | |
| lastUpdated: '2024-01-13', | |
| creator: '李产品经理', | |
| isDefault: false, | |
| usage: 678, | |
| tags: ['产品', '手册', '功能'] | |
| }, | |
| { | |
| id: 'kb-004', | |
| name: '客服问答库', | |
| description: '客服常见问题和标准解答,提升客户服务效率和质量', | |
| category: '客服', | |
| items: 345, | |
| size: '4.2 MB', | |
| status: 'active', | |
| lastUpdated: '2024-01-12', | |
| creator: '王客服主管', | |
| isDefault: false, | |
| usage: 234, | |
| tags: ['客服', '问答', 'FAQ'] | |
| }, | |
| { | |
| id: 'kb-005', | |
| name: '法律法规库', | |
| description: '相关法律条文、政策解读和合规要求,确保业务合规运营', | |
| category: '法务', | |
| items: 178, | |
| size: '6.8 MB', | |
| status: 'active', | |
| lastUpdated: '2024-01-11', | |
| creator: '赵法务', | |
| isDefault: false, | |
| usage: 89, | |
| tags: ['法律', '合规', '政策'] | |
| }, | |
| { | |
| id: 'kb-006', | |
| name: '销售话术库', | |
| description: '销售技巧、话术模板和客户案例,提升销售团队的专业水平', | |
| category: '销售', | |
| items: 456, | |
| size: '5.9 MB', | |
| status: 'inactive', | |
| lastUpdated: '2024-01-10', | |
| creator: '陈销售总监', | |
| isDefault: false, | |
| usage: 156, | |
| tags: ['销售', '话术', '案例'] | |
| } | |
| ]; | |
| const toggleSelection = (id: string) => { | |
| setSelectedKnowledgeBases(prev => | |
| prev.includes(id) | |
| ? prev.filter(kbId => kbId !== id) | |
| : [...prev, id] | |
| ); | |
| }; | |
| const selectAll = () => { | |
| setSelectedKnowledgeBases(knowledgeBases.map(kb => kb.id)); | |
| }; | |
| const clearSelection = () => { | |
| setSelectedKnowledgeBases([]); | |
| }; | |
| const getStatusColor = (status: string) => { | |
| switch (status) { | |
| case 'active': | |
| return 'bg-green-100 text-green-800'; | |
| case 'inactive': | |
| return 'bg-red-100 text-red-800'; | |
| case 'updating': | |
| return 'bg-yellow-100 text-yellow-800'; | |
| default: | |
| return 'bg-gray-100 text-gray-800'; | |
| } | |
| }; | |
| const getStatusText = (status: string) => { | |
| switch (status) { | |
| case 'active': | |
| return '运行中'; | |
| case 'inactive': | |
| return '已停用'; | |
| case 'updating': | |
| return '更新中'; | |
| default: | |
| return '未知'; | |
| } | |
| }; | |
| return ( | |
| <div className="space-y-6"> | |
| {/* 操作栏 */} | |
| <div className="bg-white border border-gray-200 rounded-lg p-4"> | |
| <div className="flex items-center justify-between"> | |
| <div className="flex items-center space-x-4"> | |
| <div className="flex items-center space-x-2"> | |
| <input | |
| type="checkbox" | |
| checked={selectedKnowledgeBases.length === knowledgeBases.length} | |
| onChange={(e) => e.target.checked ? selectAll() : clearSelection()} | |
| className="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" | |
| /> | |
| <span className="text-sm text-gray-600"> | |
| {selectedKnowledgeBases.length > 0 | |
| ? `已选择 ${selectedKnowledgeBases.length} 个知识库` | |
| : '全选' | |
| } | |
| </span> | |
| </div> | |
| {selectedKnowledgeBases.length > 0 && ( | |
| <div className="flex items-center space-x-2"> | |
| <button className="px-3 py-1 text-sm bg-blue-100 text-blue-700 rounded hover:bg-blue-200 transition-colors cursor-pointer whitespace-nowrap"> | |
| 批量启用 | |
| </button> | |
| <button className="px-3 py-1 text-sm bg-red-100 text-red-700 rounded hover:bg-red-200 transition-colors cursor-pointer whitespace-nowrap"> | |
| 批量停用 | |
| </button> | |
| <button className="px-3 py-1 text-sm bg-gray-100 text-gray-700 rounded hover:bg-gray-200 transition-colors cursor-pointer whitespace-nowrap"> | |
| 批量删除 | |
| </button> | |
| </div> | |
| )} | |
| </div> | |
| <div className="flex items-center space-x-2"> | |
| <button | |
| onClick={() => setViewMode('grid')} | |
| className={`p-2 rounded ${viewMode === 'grid' ? 'bg-blue-100 text-blue-600' : 'text-gray-400 hover:text-gray-600'} transition-colors cursor-pointer`} | |
| > | |
| <div className="w-4 h-4 flex items-center justify-center"> | |
| <i className="ri-layout-grid-line"></i> | |
| </div> | |
| </button> | |
| <button | |
| onClick={() => setViewMode('list')} | |
| className={`p-2 rounded ${viewMode === 'list' ? 'bg-blue-100 text-blue-600' : 'text-gray-400 hover:text-gray-600'} transition-colors cursor-pointer`} | |
| > | |
| <div className="w-4 h-4 flex items-center justify-center"> | |
| <i className="ri-list-unordered"></i> | |
| </div> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| {/* 知识库列表 */} | |
| {viewMode === 'grid' ? ( | |
| <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> | |
| {knowledgeBases.map((kb) => ( | |
| <div key={kb.id} className="bg-white border border-gray-200 rounded-lg hover:shadow-md transition-all duration-200"> | |
| <div className="p-6"> | |
| <div className="flex items-start justify-between mb-4"> | |
| <div className="flex items-center space-x-3"> | |
| <input | |
| type="checkbox" | |
| checked={selectedKnowledgeBases.includes(kb.id)} | |
| onChange={() => toggleSelection(kb.id)} | |
| className="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" | |
| /> | |
| <div className="w-12 h-12 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center"> | |
| <i className="ri-book-line text-xl text-white"></i> | |
| </div> | |
| <div className="flex-1"> | |
| <div className="flex items-center space-x-2"> | |
| <h3 className="font-semibold text-gray-900">{kb.name}</h3> | |
| {kb.isDefault && ( | |
| <span className="px-2 py-1 bg-blue-100 text-blue-800 text-xs rounded-full">默认</span> | |
| )} | |
| </div> | |
| <span className={`inline-block px-2 py-1 text-xs rounded-full mt-1 ${getStatusColor(kb.status)}`}> | |
| {getStatusText(kb.status)} | |
| </span> | |
| </div> | |
| </div> | |
| <div className="relative"> | |
| <button className="p-2 text-gray-400 hover:text-gray-600 transition-colors cursor-pointer"> | |
| <div className="w-4 h-4 flex items-center justify-center"> | |
| <i className="ri-more-line"></i> | |
| </div> | |
| </button> | |
| </div> | |
| </div> | |
| <p className="text-gray-600 text-sm mb-4 line-clamp-3">{kb.description}</p> | |
| <div className="space-y-3 mb-4"> | |
| <div className="flex items-center justify-between text-sm"> | |
| <span className="text-gray-500">内容条目</span> | |
| <span className="font-medium text-gray-900">{kb.items.toLocaleString()}</span> | |
| </div> | |
| <div className="flex items-center justify-between text-sm"> | |
| <span className="text-gray-500">存储大小</span> | |
| <span className="font-medium text-gray-900">{kb.size}</span> | |
| </div> | |
| <div className="flex items-center justify-between text-sm"> | |
| <span className="text-gray-500">使用次数</span> | |
| <span className="font-medium text-gray-900">{kb.usage.toLocaleString()}</span> | |
| </div> | |
| <div className="flex items-center justify-between text-sm"> | |
| <span className="text-gray-500">最后更新</span> | |
| <span className="font-medium text-gray-900">{kb.lastUpdated}</span> | |
| </div> | |
| </div> | |
| <div className="flex flex-wrap gap-1 mb-4"> | |
| {kb.tags.map((tag, index) => ( | |
| <span key={index} className="px-2 py-1 bg-gray-100 text-gray-700 text-xs rounded"> | |
| {tag} | |
| </span> | |
| ))} | |
| </div> | |
| <div className="flex items-center justify-between pt-4 border-t border-gray-200"> | |
| <div className="flex items-center space-x-2"> | |
| <div className="w-6 h-6 bg-gray-200 rounded-full flex items-center justify-center"> | |
| <i className="ri-user-line text-xs text-gray-600"></i> | |
| </div> | |
| <span className="text-xs text-gray-500">{kb.creator}</span> | |
| </div> | |
| <div className="flex items-center space-x-2"> | |
| <Link | |
| href={`/knowledge/${kb.id}`} | |
| className="px-3 py-1 bg-blue-100 text-blue-700 text-xs rounded hover:bg-blue-200 transition-colors cursor-pointer whitespace-nowrap" | |
| > | |
| 查看详情 | |
| </Link> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| ) : ( | |
| <div className="bg-white border border-gray-200 rounded-lg overflow-hidden"> | |
| <div className="overflow-x-auto"> | |
| <table className="w-full"> | |
| <thead className="bg-gray-50 border-b border-gray-200"> | |
| <tr> | |
| <th className="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> | |
| <input | |
| type="checkbox" | |
| checked={selectedKnowledgeBases.length === knowledgeBases.length} | |
| onChange={(e) => e.target.checked ? selectAll() : clearSelection()} | |
| className="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" | |
| /> | |
| </th> | |
| <th className="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">名称</th> | |
| <th className="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">分类</th> | |
| <th className="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">条目数</th> | |
| <th className="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">大小</th> | |
| <th className="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">使用次数</th> | |
| <th className="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">状态</th> | |
| <th className="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">最后更新</th> | |
| <th className="px-6 py-4 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">操作</th> | |
| </tr> | |
| </thead> | |
| <tbody className="bg-white divide-y divide-gray-200"> | |
| {knowledgeBases.map((kb) => ( | |
| <tr key={kb.id} className="hover:bg-gray-50 transition-colors"> | |
| <td className="px-6 py-4 whitespace-nowrap"> | |
| <input | |
| type="checkbox" | |
| checked={selectedKnowledgeBases.includes(kb.id)} | |
| onChange={() => toggleSelection(kb.id)} | |
| className="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" | |
| /> | |
| </td> | |
| <td className="px-6 py-4 whitespace-nowrap"> | |
| <div className="flex items-center"> | |
| <div className="w-10 h-10 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center mr-3"> | |
| <i className="ri-book-line text-white"></i> | |
| </div> | |
| <div> | |
| <div className="flex items-center space-x-2"> | |
| <div className="text-sm font-medium text-gray-900">{kb.name}</div> | |
| {kb.isDefault && ( | |
| <span className="px-2 py-1 bg-blue-100 text-blue-800 text-xs rounded-full">默认</span> | |
| )} | |
| </div> | |
| <div className="text-sm text-gray-500 max-w-xs truncate">{kb.description}</div> | |
| </div> | |
| </div> | |
| </td> | |
| <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{kb.category}</td> | |
| <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{kb.items.toLocaleString()}</td> | |
| <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{kb.size}</td> | |
| <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{kb.usage.toLocaleString()}</td> | |
| <td className="px-6 py-4 whitespace-nowrap"> | |
| <span className={`inline-flex px-2 py-1 text-xs font-semibold rounded-full ${getStatusColor(kb.status)}`}> | |
| {getStatusText(kb.status)} | |
| </span> | |
| </td> | |
| <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{kb.lastUpdated}</td> | |
| <td className="px-6 py-4 whitespace-nowrap text-sm font-medium"> | |
| <div className="flex items-center space-x-3"> | |
| <Link | |
| href={`/knowledge/${kb.id}`} | |
| className="text-blue-600 hover:text-blue-900 cursor-pointer" | |
| > | |
| 查看 | |
| </Link> | |
| <button className="text-gray-600 hover:text-gray-900 cursor-pointer">编辑</button> | |
| <button className="text-red-600 hover:text-red-900 cursor-pointer">删除</button> | |
| </div> | |
| </td> | |
| </tr> | |
| ))} | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> | |
| )} | |
| {/* 分页 */} | |
| <div className="flex items-center justify-between"> | |
| <div className="text-sm text-gray-500"> | |
| 共 {knowledgeBases.length} 个知识库 | |
| </div> | |
| <div className="flex items-center space-x-2"> | |
| <button className="px-3 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors cursor-pointer whitespace-nowrap text-sm"> | |
| 上一页 | |
| </button> | |
| <span className="px-3 py-2 bg-blue-600 text-white rounded-lg text-sm">1</span> | |
| <button className="px-3 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors cursor-pointer whitespace-nowrap text-sm"> | |
| 下一页 | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } |