Files
cunkebao_v3/Cunkebao/app/workspace/ai-assistant/knowledge-base/page.tsx
2025-04-09 09:31:09 +08:00

285 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client"
import type React from "react"
import { useState } from "react"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { ArrowLeft, FileText, Trash2, Upload } from "lucide-react"
import { useRouter } from "next/navigation"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"
interface KnowledgeFile {
id: string
name: string
type: string
size: string
uploadDate: string
}
export default function KnowledgeBasePage() {
const router = useRouter()
const [activeTab, setActiveTab] = useState("private")
const [privateFiles, setPrivateFiles] = useState<KnowledgeFile[]>([
{
id: "1",
name: "私域运营手册.pdf",
type: "PDF",
size: "2.4 MB",
uploadDate: "2023-12-10",
},
{
id: "2",
name: "客户画像分析.docx",
type: "Word",
size: "1.8 MB",
uploadDate: "2023-12-08",
},
{
id: "3",
name: "获客策略指南.pdf",
type: "PDF",
size: "3.2 MB",
uploadDate: "2023-12-05",
},
])
const [storeFiles, setStoreFiles] = useState<KnowledgeFile[]>([
{
id: "1",
name: "门店管理规范.pdf",
type: "PDF",
size: "1.9 MB",
uploadDate: "2023-12-09",
},
{
id: "2",
name: "产品介绍手册.docx",
type: "Word",
size: "2.1 MB",
uploadDate: "2023-12-07",
},
])
const [isUploading, setIsUploading] = useState(false)
const [showPreview, setShowPreview] = useState(false)
const [previewFile, setPreviewFile] = useState<KnowledgeFile | null>(null)
const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
const files = e.target.files
if (!files || files.length === 0) return
setIsUploading(true)
// 模拟上传过程
setTimeout(() => {
const newFiles = Array.from(files).map((file) => ({
id: Date.now().toString(),
name: file.name,
type: file.name.split(".").pop()?.toUpperCase() || "未知",
size: `${(file.size / (1024 * 1024)).toFixed(1)} MB`,
uploadDate: new Date().toISOString().split("T")[0],
}))
if (activeTab === "private") {
setPrivateFiles((prev) => [...prev, ...newFiles])
} else {
setStoreFiles((prev) => [...prev, ...newFiles])
}
setIsUploading(false)
e.target.value = "" // 重置文件输入
}, 1500)
}
const handleDeleteFile = (id: string) => {
if (activeTab === "private") {
setPrivateFiles((prev) => prev.filter((file) => file.id !== id))
} else {
setStoreFiles((prev) => prev.filter((file) => file.id !== id))
}
}
const handlePreviewFile = (file: KnowledgeFile) => {
setPreviewFile(file)
setShowPreview(true)
}
return (
<div className="flex flex-col h-screen max-h-screen bg-gray-50">
{/* 头部 */}
<div className="bg-white p-4 border-b flex items-center">
<Button variant="ghost" size="icon" onClick={() => router.back()} className="mr-2">
<ArrowLeft className="h-5 w-5" />
</Button>
<h1 className="text-xl font-semibold"></h1>
</div>
{/* 主内容区域 */}
<div className="flex-1 p-4 overflow-hidden">
<Card className="max-w-4xl mx-auto">
<CardHeader>
<CardTitle></CardTitle>
</CardHeader>
<CardContent>
<Tabs defaultValue="private" onValueChange={setActiveTab}>
<TabsList className="grid w-full grid-cols-2 mb-6">
<TabsTrigger value="private"></TabsTrigger>
<TabsTrigger value="store"></TabsTrigger>
</TabsList>
<TabsContent value="private" className="space-y-4">
<div className="flex justify-between items-center">
<p className="text-sm text-gray-500"> {privateFiles.length} </p>
<div className="relative">
<input
type="file"
id="private-upload"
className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
accept=".pdf,.doc,.docx"
multiple
onChange={handleFileUpload}
/>
<Button variant="outline" className="flex items-center gap-2">
<Upload className="h-4 w-4" />
</Button>
</div>
</div>
<ScrollArea className="h-[calc(100vh-300px)]">
<div className="space-y-2">
{privateFiles.map((file) => (
<div
key={file.id}
className="flex items-center justify-between p-3 bg-white border rounded-md hover:bg-gray-50"
>
<div className="flex items-center gap-3">
<FileText className="h-5 w-5 text-blue-500" />
<div>
<p className="font-medium">{file.name}</p>
<p className="text-xs text-gray-500">
{file.type} {file.size} {file.uploadDate}
</p>
</div>
</div>
<div className="flex items-center gap-2">
<Button variant="ghost" size="sm" onClick={() => handlePreviewFile(file)}>
</Button>
<Button
variant="ghost"
size="icon"
onClick={() => handleDeleteFile(file.id)}
className="text-red-500 hover:text-red-700 hover:bg-red-50"
>
<Trash2 className="h-4 w-4" />
</Button>
</div>
</div>
))}
{privateFiles.length === 0 && (
<div className="text-center py-8 text-gray-500"></div>
)}
</div>
</ScrollArea>
</TabsContent>
<TabsContent value="store" className="space-y-4">
<div className="flex justify-between items-center">
<p className="text-sm text-gray-500"> {storeFiles.length} </p>
<div className="relative">
<input
type="file"
id="store-upload"
className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
accept=".pdf,.doc,.docx"
multiple
onChange={handleFileUpload}
/>
<Button variant="outline" className="flex items-center gap-2">
<Upload className="h-4 w-4" />
</Button>
</div>
</div>
<ScrollArea className="h-[calc(100vh-300px)]">
<div className="space-y-2">
{storeFiles.map((file) => (
<div
key={file.id}
className="flex items-center justify-between p-3 bg-white border rounded-md hover:bg-gray-50"
>
<div className="flex items-center gap-3">
<FileText className="h-5 w-5 text-green-500" />
<div>
<p className="font-medium">{file.name}</p>
<p className="text-xs text-gray-500">
{file.type} {file.size} {file.uploadDate}
</p>
</div>
</div>
<div className="flex items-center gap-2">
<Button variant="ghost" size="sm" onClick={() => handlePreviewFile(file)}>
</Button>
<Button
variant="ghost"
size="icon"
onClick={() => handleDeleteFile(file.id)}
className="text-red-500 hover:text-red-700 hover:bg-red-50"
>
<Trash2 className="h-4 w-4" />
</Button>
</div>
</div>
))}
{storeFiles.length === 0 && (
<div className="text-center py-8 text-gray-500"></div>
)}
</div>
</ScrollArea>
</TabsContent>
</Tabs>
</CardContent>
</Card>
</div>
{/* 文件预览对话框 */}
<Dialog open={showPreview} onOpenChange={setShowPreview}>
<DialogContent className="max-w-3xl">
<DialogHeader>
<DialogTitle>{previewFile?.name}</DialogTitle>
</DialogHeader>
<div className="p-4 bg-gray-50 rounded-md min-h-[300px] flex items-center justify-center">
<div className="text-center">
<FileText className="h-16 w-16 text-gray-400 mx-auto mb-4" />
<p className="text-gray-500"></p>
<p className="text-sm text-gray-400 mt-2">
: {previewFile?.type} : {previewFile?.size}
</p>
</div>
</div>
</DialogContent>
</Dialog>
{/* 上传中提示 */}
{isUploading && (
<div className="fixed inset-0 bg-black/20 flex items-center justify-center z-50">
<Card className="w-80">
<CardContent className="p-6">
<div className="flex flex-col items-center">
<div className="w-12 h-12 rounded-full border-4 border-t-blue-500 border-blue-200 animate-spin mb-4"></div>
<p className="font-medium">...</p>
<p className="text-sm text-gray-500 mt-1"></p>
</div>
</CardContent>
</Card>
</div>
)}
</div>
)
}