| '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> |
| ); |
| } |