Reorganize navigation and module structure based on new requirements. Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
187 lines
7.2 KiB
TypeScript
187 lines
7.2 KiB
TypeScript
"use client"
|
|
|
|
import { useState } from "react"
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from "@/components/ui/dialog"
|
|
import { Button } from "@/components/ui/button"
|
|
import { Input } from "@/components/ui/input"
|
|
import { Label } from "@/components/ui/label"
|
|
import { Switch } from "@/components/ui/switch"
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
|
import { Settings, Shield, Zap, Bell } from "lucide-react"
|
|
|
|
interface APISettingsDialogProps {
|
|
open: boolean
|
|
onOpenChange: (open: boolean) => void
|
|
api?: {
|
|
name: string
|
|
endpoint: string
|
|
}
|
|
}
|
|
|
|
export function APISettingsDialog({ open, onOpenChange, api }: APISettingsDialogProps) {
|
|
const [activeTab, setActiveTab] = useState("basic")
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent className="max-w-2xl">
|
|
<DialogHeader>
|
|
<DialogTitle className="flex items-center gap-2">
|
|
<Settings className="w-5 h-5" />
|
|
API设置 - {api?.name || "API服务"}
|
|
</DialogTitle>
|
|
<DialogDescription>配置API服务的基本信息、限流策略和告警规则</DialogDescription>
|
|
</DialogHeader>
|
|
|
|
<Tabs value={activeTab} onValueChange={setActiveTab}>
|
|
<TabsList className="grid w-full grid-cols-4">
|
|
<TabsTrigger value="basic">基本信息</TabsTrigger>
|
|
<TabsTrigger value="ratelimit">限流配置</TabsTrigger>
|
|
<TabsTrigger value="auth">认证授权</TabsTrigger>
|
|
<TabsTrigger value="alert">告警设置</TabsTrigger>
|
|
</TabsList>
|
|
|
|
<TabsContent value="basic" className="space-y-4 mt-4">
|
|
<div className="space-y-2">
|
|
<Label>API名称</Label>
|
|
<Input defaultValue={api?.name} />
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label>API端点</Label>
|
|
<Input defaultValue={api?.endpoint} />
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label>版本号</Label>
|
|
<Select defaultValue="v1">
|
|
<SelectTrigger>
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="v1">v1</SelectItem>
|
|
<SelectItem value="v2">v2 (Beta)</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
<div className="flex items-center justify-between p-4 bg-slate-50 rounded-lg">
|
|
<div>
|
|
<p className="font-medium">启用API</p>
|
|
<p className="text-sm text-slate-500">关闭后API将返回503错误</p>
|
|
</div>
|
|
<Switch defaultChecked />
|
|
</div>
|
|
</TabsContent>
|
|
|
|
<TabsContent value="ratelimit" className="space-y-4 mt-4">
|
|
<div className="flex items-center gap-2 mb-2">
|
|
<Zap className="w-4 h-4 text-amber-500" />
|
|
<span className="font-medium">限流策略</span>
|
|
</div>
|
|
<div className="grid grid-cols-2 gap-4">
|
|
<div className="space-y-2">
|
|
<Label>每秒请求数 (QPS)</Label>
|
|
<Input type="number" defaultValue="1000" />
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label>每分钟请求数</Label>
|
|
<Input type="number" defaultValue="50000" />
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label>每日请求数</Label>
|
|
<Input type="number" defaultValue="1000000" />
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label>并发连接数</Label>
|
|
<Input type="number" defaultValue="100" />
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center justify-between p-4 bg-slate-50 rounded-lg">
|
|
<div>
|
|
<p className="font-medium">突发流量保护</p>
|
|
<p className="text-sm text-slate-500">自动识别并限制异常流量</p>
|
|
</div>
|
|
<Switch defaultChecked />
|
|
</div>
|
|
</TabsContent>
|
|
|
|
<TabsContent value="auth" className="space-y-4 mt-4">
|
|
<div className="flex items-center gap-2 mb-2">
|
|
<Shield className="w-4 h-4 text-blue-500" />
|
|
<span className="font-medium">认证方式</span>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label>认证类型</Label>
|
|
<Select defaultValue="apikey">
|
|
<SelectTrigger>
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="apikey">API Key</SelectItem>
|
|
<SelectItem value="oauth2">OAuth 2.0</SelectItem>
|
|
<SelectItem value="jwt">JWT Token</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</div>
|
|
<div className="flex items-center justify-between p-4 bg-slate-50 rounded-lg">
|
|
<div>
|
|
<p className="font-medium">IP白名单</p>
|
|
<p className="text-sm text-slate-500">仅允许白名单IP访问</p>
|
|
</div>
|
|
<Switch />
|
|
</div>
|
|
<div className="flex items-center justify-between p-4 bg-slate-50 rounded-lg">
|
|
<div>
|
|
<p className="font-medium">请求签名验证</p>
|
|
<p className="text-sm text-slate-500">验证请求签名防止篡改</p>
|
|
</div>
|
|
<Switch defaultChecked />
|
|
</div>
|
|
</TabsContent>
|
|
|
|
<TabsContent value="alert" className="space-y-4 mt-4">
|
|
<div className="flex items-center gap-2 mb-2">
|
|
<Bell className="w-4 h-4 text-red-500" />
|
|
<span className="font-medium">告警规则</span>
|
|
</div>
|
|
<div className="flex items-center justify-between p-4 bg-slate-50 rounded-lg">
|
|
<div>
|
|
<p className="font-medium">错误率告警</p>
|
|
<p className="text-sm text-slate-500">错误率超过阈值时告警</p>
|
|
</div>
|
|
<Switch defaultChecked />
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label>错误率阈值 (%)</Label>
|
|
<Input type="number" defaultValue="1" />
|
|
</div>
|
|
<div className="flex items-center justify-between p-4 bg-slate-50 rounded-lg">
|
|
<div>
|
|
<p className="font-medium">延迟告警</p>
|
|
<p className="text-sm text-slate-500">P99延迟超过阈值时告警</p>
|
|
</div>
|
|
<Switch defaultChecked />
|
|
</div>
|
|
<div className="space-y-2">
|
|
<Label>延迟阈值 (ms)</Label>
|
|
<Input type="number" defaultValue="200" />
|
|
</div>
|
|
</TabsContent>
|
|
</Tabs>
|
|
|
|
<DialogFooter>
|
|
<Button variant="outline" onClick={() => onOpenChange(false)}>
|
|
取消
|
|
</Button>
|
|
<Button onClick={() => onOpenChange(false)}>保存设置</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|