Reorganize navigation and module structure based on new requirements. Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
145 lines
4.6 KiB
TypeScript
145 lines
4.6 KiB
TypeScript
"use client"
|
|
|
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog"
|
|
import { Button } from "@/components/ui/button"
|
|
import { Badge } from "@/components/ui/badge"
|
|
import { ScrollArea } from "@/components/ui/scroll-area"
|
|
import { FileText, Download, RefreshCw, Brain, CheckCircle, XCircle, Clock } from "lucide-react"
|
|
|
|
interface AICleaningLogsDialogProps {
|
|
open: boolean
|
|
onOpenChange: (open: boolean) => void
|
|
ruleName?: string
|
|
}
|
|
|
|
const AI_LOGS = [
|
|
{
|
|
time: "14:35:12",
|
|
type: "system",
|
|
message: "AI清洗任务启动",
|
|
details: "规则: 用户数据智能清洗 | 模型: GPT-4",
|
|
},
|
|
{
|
|
time: "14:35:13",
|
|
type: "ai",
|
|
message: "分析提示词",
|
|
details: "解析清洗意图: 手机号格式化、邮箱校验、地址补全",
|
|
},
|
|
{
|
|
time: "14:35:15",
|
|
type: "system",
|
|
message: "读取数据批次 1/10",
|
|
details: "共 12,895 条记录",
|
|
},
|
|
{
|
|
time: "14:35:18",
|
|
type: "ai",
|
|
message: "AI分析完成",
|
|
details: "发现 156 条需要清洗的记录, 置信度范围: 0.72-0.98",
|
|
},
|
|
{
|
|
time: "14:35:20",
|
|
type: "review",
|
|
message: "自动审核通过",
|
|
details: "142 条记录置信度 >= 0.95, 已自动应用",
|
|
},
|
|
{
|
|
time: "14:35:21",
|
|
type: "review",
|
|
message: "待人工审核",
|
|
details: "14 条记录置信度 < 0.95, 等待审核",
|
|
},
|
|
{
|
|
time: "14:35:25",
|
|
type: "system",
|
|
message: "批次 1 处理完成",
|
|
details: "成功: 12,881 | 待审核: 14 | 跳过: 0",
|
|
},
|
|
{
|
|
time: "14:36:45",
|
|
type: "ai",
|
|
message: "AI建议",
|
|
details: "检测到 '86-' 前缀手机号模式, 建议添加自动化规则",
|
|
},
|
|
]
|
|
|
|
export function AICleaningLogsDialog({ open, onOpenChange, ruleName }: AICleaningLogsDialogProps) {
|
|
const getTypeIcon = (type: string) => {
|
|
switch (type) {
|
|
case "ai":
|
|
return <Brain className="w-4 h-4 text-violet-500" />
|
|
case "review":
|
|
return <CheckCircle className="w-4 h-4 text-emerald-500" />
|
|
case "error":
|
|
return <XCircle className="w-4 h-4 text-red-500" />
|
|
default:
|
|
return <Clock className="w-4 h-4 text-blue-500" />
|
|
}
|
|
}
|
|
|
|
const getTypeBadge = (type: string) => {
|
|
switch (type) {
|
|
case "ai":
|
|
return <Badge className="bg-violet-100 text-violet-700">AI</Badge>
|
|
case "review":
|
|
return <Badge className="bg-emerald-100 text-emerald-700">审核</Badge>
|
|
case "error":
|
|
return <Badge className="bg-red-100 text-red-700">错误</Badge>
|
|
default:
|
|
return <Badge className="bg-blue-100 text-blue-700">系统</Badge>
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent className="max-w-3xl max-h-[80vh]">
|
|
<DialogHeader>
|
|
<DialogTitle className="flex items-center gap-2">
|
|
<FileText className="w-5 h-5" />
|
|
AI清洗日志 - {ruleName || "清洗规则"}
|
|
</DialogTitle>
|
|
<DialogDescription>查看AI清洗规则的执行日志和AI分析过程</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<div className="flex items-center justify-between mb-4">
|
|
<div className="flex items-center gap-4">
|
|
<Badge variant="outline" className="gap-1">
|
|
<div className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
|
|
运行中
|
|
</Badge>
|
|
<span className="text-sm text-slate-500">已运行: 1分33秒</span>
|
|
</div>
|
|
<div className="flex gap-2">
|
|
<Button variant="outline" size="sm">
|
|
<RefreshCw className="w-4 h-4 mr-1" />
|
|
刷新
|
|
</Button>
|
|
<Button variant="outline" size="sm">
|
|
<Download className="w-4 h-4 mr-1" />
|
|
导出
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
<ScrollArea className="h-[400px] border rounded-lg">
|
|
<div className="p-4 space-y-3">
|
|
{AI_LOGS.map((log, i) => (
|
|
<div key={i} className="flex gap-4 p-3 bg-slate-50 rounded-lg">
|
|
<div className="flex-shrink-0 mt-0.5">{getTypeIcon(log.type)}</div>
|
|
<div className="flex-1 min-w-0">
|
|
<div className="flex items-center gap-2 mb-1">
|
|
<span className="text-xs text-slate-500">{log.time}</span>
|
|
{getTypeBadge(log.type)}
|
|
<span className="font-medium text-slate-800">{log.message}</span>
|
|
</div>
|
|
<p className="text-sm text-slate-600">{log.details}</p>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</ScrollArea>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|