diff --git a/crop-x/src/app/(app)/ai-crop-model/model-integration/access/components/DependencyManageDialog.tsx b/crop-x/src/app/(app)/ai-crop-model/model-integration/access/components/DependencyManageDialog.tsx new file mode 100644 index 0000000..d710821 --- /dev/null +++ b/crop-x/src/app/(app)/ai-crop-model/model-integration/access/components/DependencyManageDialog.tsx @@ -0,0 +1,217 @@ +'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 { Input } from '@/components/ui/input'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; +import { Textarea } from '@/components/ui/textarea'; +import { Card } from '@/components/ui/card'; +import { Badge } from '@/components/ui/badge'; +import { toast } from 'sonner'; +import { + Package, + Plus, + CheckCircle, + AlertCircle, + RefreshCw, + Trash2, + Clock, + Settings, + Download, +} from 'lucide-react'; + +interface ModelService { + id: string; + name: string; + dependencies: string[]; +} + +interface DependencyManageDialogProps { + open: boolean; + onOpenChange: (open: boolean) => void; + model: ModelService | null; +} + +export function DependencyManageDialog({ open, onOpenChange, model }: DependencyManageDialogProps) { + const handleUpdateDependency = () => { + toast.success('依赖已更新'); + }; + + const handleRemoveDependency = (dep: string) => { + toast.success(`依赖 ${dep} 已移除`); + }; + + const handleAddDependency = () => { + toast.success('新依赖已添加'); + }; + + if (!model) return null; + + return ( + + + + 依赖管理 - {model.name} + + 管理模型运行所需的依赖包和环境配置 + + + +
+ {/* 当前依赖 */} + +
+

+ + 当前依赖 ({model.dependencies.length}个) +

+ +
+
+ {model.dependencies.map((dep, idx) => ( +
+
+ + {dep} + 已安装 +
+
+ + +
+
+ ))} +
+
+ + {/* 依赖检查 */} + +

+ + 依赖健康检查 +

+
+
+
+ +
+
所有依赖已安装
+
版本兼容性检查通过
+
+
+ 正常 +
+ +
+
+ + {/* 依赖冲突检测 */} + +

+ + 冲突检测 +

+
+
+ +
+
发现潜在版本冲突
+
+
• numpy==1.24.0 与 tensorflow==2.13.0 可能存在兼容性问题
+
• 建议升级 numpy 到 1.24.3 或更高版本
+
+ +
+
+
+
+ + {/* 环境配置 */} + +

+ + 环境配置 +

+
+
+ + +
+
+ + +
+
+
+ + {/* 依赖更新日志 */} + +

+ + 更新历史 +

+
+ {[ + { date: '2024-10-20', action: '更新 tensorflow 2.12.0 → 2.13.0', user: '张三' }, + { date: '2024-10-15', action: '添加 opencv-python==4.8.0', user: '李四' }, + { date: '2024-10-10', action: '更新 numpy 1.23.0 → 1.24.0', user: '王五' }, + ].map((log, idx) => ( +
+ +
+
{log.date}
+
{log.action}
+
by {log.user}
+
+
+ ))} +
+
+
+ + + + + +
+
+ ); +} \ No newline at end of file diff --git a/crop-x/src/app/(app)/ai-crop-model/model-integration/access/components/DeployConfigDialog.tsx b/crop-x/src/app/(app)/ai-crop-model/model-integration/access/components/DeployConfigDialog.tsx new file mode 100644 index 0000000..49ffe46 --- /dev/null +++ b/crop-x/src/app/(app)/ai-crop-model/model-integration/access/components/DeployConfigDialog.tsx @@ -0,0 +1,226 @@ +'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 { Input } from '@/components/ui/input'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; +import { Switch } from '@/components/ui/switch'; +import { Card } from '@/components/ui/card'; +import { toast } from 'sonner'; +import { + Server, + CheckCircle, + Eye, +} from 'lucide-react'; + +interface DeployConfigDialogProps { + open: boolean; + onOpenChange: (open: boolean) => void; +} + +export function DeployConfigDialog({ open, onOpenChange }: DeployConfigDialogProps) { + const handleDeploy = () => { + toast.success('模型部署已启动,预计3-5分钟完成'); + onOpenChange(false); + }; + + return ( + + + + 模型部署配置 + + 配置模型的部署环境和资源分配 + + + +
+ {/* 部署环境 */} + +

部署环境

+
+
+ + +
+
+ + +
+
+
+ + {/* 资源配置 */} + +

资源配置

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + {/* 自动伸缩 */} + +

自动伸缩策略

+
+
+
+
启用自动伸缩
+
根据负载自动调整实例数量
+
+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + {/* 健康检查 */} + +

健康检查

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + {/* 部署进度预估 */} + +
+ +
+

部署流程

+
+
+ + 1. 模型文件准备与验证 (~1分钟) +
+
+ + 2. 容器镜像构建 (~2分钟) +
+
+ + 3. 服务实例启动 (~1分钟) +
+
+ + 4. 健康检查与负载均衡配置 (~1分钟) +
+

预计总时间: 3-5分钟

+
+
+
+
+
+ + + + + + +
+
+ ); +} \ No newline at end of file diff --git a/crop-x/src/app/(app)/ai-crop-model/model-integration/access/components/ModelDetailDialog.tsx b/crop-x/src/app/(app)/ai-crop-model/model-integration/access/components/ModelDetailDialog.tsx new file mode 100644 index 0000000..c36623d --- /dev/null +++ b/crop-x/src/app/(app)/ai-crop-model/model-integration/access/components/ModelDetailDialog.tsx @@ -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 ( + + + + 模型详情 - {model.name} + + 查看模型完整信息、元数据和运行状态 + + + +
+ {/* 基本信息 */} + +

+ + 基本信息 +

+
+ {/* 模型名称 - 大字体显示 */} +
+

{model.name}

+ + + {model.version} + +
+ +
+
+ +

+ {model.type} +

+
+
+ +

{model.format}

+
+
+ +
+ +

{model.description}

+
+ +
+
+ +

+ {getAccessLevelIcon(model.accessLevel)} + {model.accessLevel} +

+
+
+ +
+ {model.tags.map((tag, idx) => ( + {tag} + ))} +
+
+
+
+
+ + {/* 性能指标 */} + +

+ + 性能指标 +

+
+
+

模型准确率

+

{model.accuracy}%

+
+
+

推理时间

+

{model.inferenceTime}ms

+

平均响应

+
+
+

调用次数

+

{model.requestCount.toLocaleString()}

+

总计

+
+
+

成功率

+

{model.successRate}%

+
+
+
+ + {/* API端点信息 */} + +

+ + API端点 +

+
+
+ +
+ + {model.endpoint} + + +
+
+
+
+ +

POST

+
+
+ +

application/json

+
+
+
+
+ + {/* 依赖包列表 */} + +

+ + 依赖包 ({model.dependencies.length}个) +

+
+ {model.dependencies.map((dep, idx) => ( +
+ + {dep} +
+ ))} +
+
+ + {/* 调用示例 */} + +

+ + API调用示例 +

+
+
{`# 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']}%")`}
+
+
+
+ + + + + +
+
+ ); +} \ No newline at end of file diff --git a/crop-x/src/app/(app)/ai-crop-model/model-integration/access/components/ModelEditDialog.tsx b/crop-x/src/app/(app)/ai-crop-model/model-integration/access/components/ModelEditDialog.tsx new file mode 100644 index 0000000..dbc20a2 --- /dev/null +++ b/crop-x/src/app/(app)/ai-crop-model/model-integration/access/components/ModelEditDialog.tsx @@ -0,0 +1,148 @@ +'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 { Input } from '@/components/ui/input'; +import { Textarea } from '@/components/ui/textarea'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; +import { toast } from 'sonner'; +import { CheckCircle, Upload } from 'lucide-react'; + +interface ModelService { + id: string; + name: string; + version: string; + type: string; + format: string; + description: string; + accessLevel: string; + tags: string[]; + dependencies: string[]; +} + +interface ModelEditDialogProps { + open: boolean; + onOpenChange: (open: boolean) => void; + model: ModelService | null; +} + +export function ModelEditDialog({ open, onOpenChange, model }: ModelEditDialogProps) { + const handleSaveEdit = () => { + toast.success('模型信息已更新'); + onOpenChange(false); + }; + + if (!model) return null; + + return ( + + + + 编辑模型信息 - {model.name} + + 修改模型的元信息和配置参数 + + + +
+
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ +
+ +