生产管理系统 模型服务接入、模型服务管理2个页面开发
This commit is contained in:
@@ -0,0 +1,257 @@
|
||||
'use client';
|
||||
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@/components/ui/dialog';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Card } from '@/components/ui/card';
|
||||
import { Progress } from '@/components/ui/progress';
|
||||
import { toast } from 'sonner';
|
||||
import {
|
||||
Brain,
|
||||
BarChart3,
|
||||
Link,
|
||||
Package,
|
||||
Terminal,
|
||||
CheckCircle,
|
||||
GitBranch,
|
||||
Copy,
|
||||
Eye,
|
||||
} from 'lucide-react';
|
||||
|
||||
interface ModelService {
|
||||
id: string;
|
||||
name: string;
|
||||
version: string;
|
||||
type: string;
|
||||
format: string;
|
||||
description: string;
|
||||
author: string;
|
||||
createTime: string;
|
||||
lastUpdateTime: string;
|
||||
status: string;
|
||||
endpoint: string;
|
||||
accessLevel: string;
|
||||
tags: string[];
|
||||
accuracy?: number;
|
||||
inferenceTime?: number;
|
||||
requestCount: number;
|
||||
successRate: number;
|
||||
dependencies: string[];
|
||||
}
|
||||
|
||||
interface ModelDetailDialogProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
model: ModelService | null;
|
||||
}
|
||||
|
||||
export function ModelDetailDialog({ open, onOpenChange, model }: ModelDetailDialogProps) {
|
||||
const handleCopyEndpoint = async (endpoint: string) => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(endpoint);
|
||||
toast.success('端点已复制到剪贴板');
|
||||
} catch (error) {
|
||||
toast.error('复制失败,请重试');
|
||||
}
|
||||
};
|
||||
|
||||
const handleTestModel = () => {
|
||||
toast.success('模型测试成功,推理正常');
|
||||
};
|
||||
|
||||
const getAccessLevelIcon = (level: string) => {
|
||||
switch (level) {
|
||||
case '公开': return '🌐';
|
||||
case '私有': return '🔒';
|
||||
case '团队共享': return '👥';
|
||||
default: return '🔒';
|
||||
}
|
||||
};
|
||||
|
||||
if (!model) return null;
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-6xl max-h-[90vh] overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle>模型详情 - {model.name}</DialogTitle>
|
||||
<DialogDescription>
|
||||
查看模型完整信息、元数据和运行状态
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-6">
|
||||
{/* 基本信息 */}
|
||||
<Card className="p-4">
|
||||
<h4 className="mb-4 flex items-center gap-2">
|
||||
<Brain className="w-4 h-4 text-blue-600 dark:text-blue-400" />
|
||||
基本信息
|
||||
</h4>
|
||||
<div className="space-y-4">
|
||||
{/* 模型名称 - 大字体显示 */}
|
||||
<div className="text-center">
|
||||
<h3 className="text-2xl font-bold text-foreground mb-2">{model.name}</h3>
|
||||
<Badge variant="outline" className="text-sm">
|
||||
<GitBranch className="w-3 h-3 mr-1" />
|
||||
{model.version}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<Label className="text-xs">模型类型</Label>
|
||||
<p className="mt-1">
|
||||
<Badge variant="outline" className="font-light">{model.type}</Badge>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-xs">模型格式</Label>
|
||||
<p className="mt-1">{model.format}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label className="text-xs">模型描述</Label>
|
||||
<p className="mt-1 text-sm text-muted-foreground">{model.description}</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<Label className="text-xs">访问权限</Label>
|
||||
<p className="mt-1 flex items-center gap-2">
|
||||
<span>{getAccessLevelIcon(model.accessLevel)}</span>
|
||||
<span className="text-sm">{model.accessLevel}</span>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-xs">标签</Label>
|
||||
<div className="mt-1 flex flex-wrap gap-2">
|
||||
{model.tags.map((tag, idx) => (
|
||||
<Badge key={idx} variant="outline" className="text-xs font-light">{tag}</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* 性能指标 */}
|
||||
<Card className="p-4">
|
||||
<h4 className="mb-4 flex items-center gap-2">
|
||||
<BarChart3 className="w-4 h-4 text-green-600 dark:text-green-400" />
|
||||
性能指标
|
||||
</h4>
|
||||
<div className="grid grid-cols-4 gap-4">
|
||||
<div className="text-center p-4 bg-green-50 dark:bg-green-950 rounded-lg">
|
||||
<p className="text-xs text-muted-foreground">模型准确率</p>
|
||||
<p className="text-2xl text-green-600 dark:text-green-400 mt-1">{model.accuracy}%</p>
|
||||
</div>
|
||||
<div className="text-center p-4 bg-blue-50 dark:bg-blue-950 rounded-lg">
|
||||
<p className="text-xs text-muted-foreground">推理时间</p>
|
||||
<p className="text-2xl text-blue-600 dark:text-blue-400 mt-1">{model.inferenceTime}ms</p>
|
||||
<p className="text-xs text-blue-600 dark:text-blue-400 mt-1">平均响应</p>
|
||||
</div>
|
||||
<div className="text-center p-4 bg-purple-50 dark:bg-purple-950 rounded-lg">
|
||||
<p className="text-xs text-muted-foreground">调用次数</p>
|
||||
<p className="text-2xl text-purple-600 dark:text-purple-400 mt-1">{model.requestCount.toLocaleString()}</p>
|
||||
<p className="text-xs text-purple-600 dark:text-purple-400 mt-1">总计</p>
|
||||
</div>
|
||||
<div className="text-center p-4 bg-orange-50 dark:bg-orange-950 rounded-lg">
|
||||
<p className="text-xs text-muted-foreground">成功率</p>
|
||||
<p className="text-2xl text-orange-600 dark:text-orange-400 mt-1">{model.successRate}%</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* API端点信息 */}
|
||||
<Card className="p-4">
|
||||
<h4 className="mb-4 flex items-center gap-2">
|
||||
<Link className="w-4 h-4 text-blue-600 dark:text-blue-400" />
|
||||
API端点
|
||||
</h4>
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<Label className="text-xs">服务端点</Label>
|
||||
<div className="mt-2 flex items-center gap-2">
|
||||
<code className="flex-1 bg-gray-900 dark:bg-gray-950 text-green-400 px-4 py-2 rounded text-sm font-mono">
|
||||
{model.endpoint}
|
||||
</code>
|
||||
<Button size="sm" variant="outline" onClick={() => handleCopyEndpoint(model.endpoint)}>
|
||||
复制
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<Label className="text-xs">请求方式</Label>
|
||||
<p className="mt-1 text-sm">POST</p>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-xs">Content-Type</Label>
|
||||
<p className="mt-1 text-sm">application/json</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* 依赖包列表 */}
|
||||
<Card className="p-4">
|
||||
<h4 className="mb-4 flex items-center gap-2">
|
||||
<Package className="w-4 h-4 text-purple-600 dark:text-purple-400" />
|
||||
依赖包 ({model.dependencies.length}个)
|
||||
</h4>
|
||||
<div className="space-y-2">
|
||||
{model.dependencies.map((dep, idx) => (
|
||||
<div key={idx} className="flex items-center gap-2 p-2 bg-gray-50 dark:bg-gray-900 rounded text-sm">
|
||||
<CheckCircle className="w-4 h-4 text-green-600 dark:text-green-400 flex-shrink-0" />
|
||||
<code className="font-mono">{dep}</code>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
{/* 调用示例 */}
|
||||
<Card className="p-4">
|
||||
<h4 className="mb-4 flex items-center gap-2">
|
||||
<Terminal className="w-4 h-4 text-green-600 dark:text-green-400" />
|
||||
API调用示例
|
||||
</h4>
|
||||
<div className="bg-gray-900 dark:bg-gray-950 text-green-400 p-4 rounded-lg font-mono text-sm overflow-x-auto">
|
||||
<pre>{`# Python调用示例
|
||||
import requests
|
||||
|
||||
url = "${model.endpoint}"
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": "Bearer YOUR_API_KEY"
|
||||
}
|
||||
|
||||
payload = {
|
||||
"data": [
|
||||
[25.3, 65.2, 45820, 3.2, 1013.2, 18.5, 45.3, 2.3]
|
||||
]
|
||||
}
|
||||
|
||||
response = requests.post(url, json=payload, headers=headers)
|
||||
result = response.json()
|
||||
|
||||
print(f"预测结果: {result['prediction']}")
|
||||
print(f"置信度: {result['confidence']}%")`}</pre>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)}>
|
||||
关闭
|
||||
</Button>
|
||||
<Button variant="outline" onClick={handleTestModel}>
|
||||
<CheckCircle className="w-4 h-4 mr-2" />
|
||||
测试推理
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user