针对测试用例生成添加了常用测试方法;更新了需求提取工具

This commit is contained in:
2026-04-18 21:13:33 +08:00
parent c7c0659a85
commit 0c2ed67e2a
21 changed files with 2029 additions and 481 deletions

View File

@@ -3,7 +3,14 @@
import { useEffect, useState } from "react";
import Link from "next/link";
import { FileIcon, defaultStyles } from "react-file-icon";
import { ArrowRight, Plus, Settings, Trash2, Search } from "lucide-react";
import {
ArrowRight,
ChevronRight,
Plus,
Search,
Settings,
Trash2,
} from "lucide-react";
import DashboardLayout from "@/components/layout/dashboard-layout";
import { api, ApiError } from "@/lib/api";
import { useToast } from "@/components/ui/use-toast";
@@ -29,6 +36,9 @@ interface Document {
export default function KnowledgeBasePage() {
const [knowledgeBases, setKnowledgeBases] = useState<KnowledgeBase[]>([]);
const [collapsedDocumentSections, setCollapsedDocumentSections] = useState<
Record<number, boolean>
>({});
const [loading, setLoading] = useState(true);
const { toast } = useToast();
@@ -76,6 +86,13 @@ export default function KnowledgeBasePage() {
}
};
const toggleDocumentsSection = (knowledgeBaseId: number) => {
setCollapsedDocumentSections((prev) => ({
...prev,
[knowledgeBaseId]: !prev[knowledgeBaseId],
}));
};
return (
<DashboardLayout>
<div className="space-y-8">
@@ -98,11 +115,15 @@ export default function KnowledgeBasePage() {
</div>
<div className="grid gap-6">
{knowledgeBases.map((kb) => (
<div
key={kb.id}
className="rounded-lg border bg-card p-6 space-y-4"
>
{knowledgeBases.map((kb) => {
const isDocumentsCollapsed =
collapsedDocumentSections[kb.id] ?? true;
return (
<div
key={kb.id}
className="rounded-lg border bg-card p-6 space-y-4"
>
<div className="flex justify-between items-start">
<div>
<h3 className="text-lg font-semibold">{kb.name}</h3>
@@ -139,61 +160,79 @@ export default function KnowledgeBasePage() {
{kb.documents.length > 0 && (
<div className="border-t pt-4">
<h4 className="text-sm font-medium mb-2"></h4>
<div className="flex flex-wrap gap-2 max-h-[400px] overflow-y-auto">
{kb.documents.slice(0, 9).map((doc) => (
<div
key={doc.id}
className="flex flex-col items-center gap-2 p-2 rounded-lg border bg-card hover:bg-accent/50 cursor-pointer transition-colors w-[150px] h-[150px] justify-center"
>
<div className="w-8 h-8 mb-2">
{doc.content_type.toLowerCase().includes("pdf") ? (
<FileIcon extension="pdf" {...defaultStyles.pdf} />
) : doc.content_type.toLowerCase().includes("doc") ? (
<FileIcon extension="doc" {...defaultStyles.docx} />
) : doc.content_type.toLowerCase().includes("txt") ? (
<FileIcon extension="txt" {...defaultStyles.txt} />
) : doc.content_type.toLowerCase().includes("md") ? (
<FileIcon extension="md" {...defaultStyles.md} />
) : (
<FileIcon
extension={doc.file_name.split(".").pop() || ""}
color="#E2E8F0"
labelColor="#94A3B8"
/>
)}
</div>
<div className="text-sm font-medium text-center max-w-[100px]">
<div className="line-clamp-2 overflow-hidden text-ellipsis">
{doc.file_name}
<button
type="button"
onClick={() => toggleDocumentsSection(kb.id)}
className="mb-2 flex w-full items-center justify-between rounded-md px-1 py-1 text-left hover:bg-accent/50"
>
<h4 className="text-sm font-medium"></h4>
<div className="flex items-center gap-1 text-xs text-muted-foreground">
<span>{isDocumentsCollapsed ? "展开" : "收起"}</span>
<ChevronRight
className={`h-4 w-4 transition-transform ${
isDocumentsCollapsed ? "" : "rotate-90"
}`}
/>
</div>
</button>
{!isDocumentsCollapsed && (
<div className="flex flex-wrap gap-2 max-h-[400px] overflow-y-auto">
{kb.documents.slice(0, 9).map((doc) => (
<div
key={doc.id}
className="flex flex-col items-center gap-2 p-2 rounded-lg border bg-card hover:bg-accent/50 cursor-pointer transition-colors w-[150px] h-[150px] justify-center"
>
<div className="w-8 h-8 mb-2">
{doc.content_type.toLowerCase().includes("pdf") ? (
<FileIcon extension="pdf" {...defaultStyles.pdf} />
) : doc.content_type.toLowerCase().includes("doc") ? (
<FileIcon extension="doc" {...defaultStyles.docx} />
) : doc.content_type.toLowerCase().includes("txt") ? (
<FileIcon extension="txt" {...defaultStyles.txt} />
) : doc.content_type.toLowerCase().includes("md") ? (
<FileIcon extension="md" {...defaultStyles.md} />
) : (
<FileIcon
extension={doc.file_name.split(".").pop() || ""}
color="#E2E8F0"
labelColor="#94A3B8"
/>
)}
</div>
<div className="text-sm font-medium text-center max-w-[100px]">
<div className="line-clamp-2 overflow-hidden text-ellipsis">
{doc.file_name}
</div>
</div>
<span className="text-xs text-muted-foreground mt-1">
{new Date(doc.created_at).toLocaleDateString("zh-CN")}
</span>
</div>
<span className="text-xs text-muted-foreground mt-1">
{new Date(doc.created_at).toLocaleDateString("zh-CN")}
</span>
</div>
))}
{kb.documents.length > 9 && (
<Link
href={`/dashboard/knowledge/${kb.id}`}
className="flex flex-col items-center p-2 rounded-lg border bg-card hover:bg-accent/50 cursor-pointer transition-colors w-[150px] h-[150px] justify-center"
>
<div className="w-8 h-8 mb-2 flex items-center justify-center">
<ArrowRight className="w-6 h-6" />
</div>
<span className="text-sm font-medium text-center">
</span>
<span className="text-xs text-muted-foreground mt-1">
{kb.documents.length}
</span>
</Link>
)}
</div>
))}
{kb.documents.length > 9 && (
<Link
href={`/dashboard/knowledge/${kb.id}`}
className="flex flex-col items-center p-2 rounded-lg border bg-card hover:bg-accent/50 cursor-pointer transition-colors w-[150px] h-[150px] justify-center"
>
<div className="w-8 h-8 mb-2 flex items-center justify-center">
<ArrowRight className="w-6 h-6" />
</div>
<span className="text-sm font-medium text-center">
</span>
<span className="text-xs text-muted-foreground mt-1">
{kb.documents.length}
</span>
</Link>
)}
</div>
)}
</div>
)}
</div>
))}
</div>
);
})}
{!loading && knowledgeBases.length === 0 && (
<div className="text-center py-12">