refactor: restructure navigation and module layout
Reorganize navigation and module structure based on new requirements. Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
This commit is contained in:
222
components/dialogs/api-doc-dialog.tsx
Normal file
222
components/dialogs/api-doc-dialog.tsx
Normal file
@@ -0,0 +1,222 @@
|
||||
"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 { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||||
import { ScrollArea } from "@/components/ui/scroll-area"
|
||||
import { Code, Copy, ExternalLink } from "lucide-react"
|
||||
|
||||
interface APIDocDialogProps {
|
||||
open: boolean
|
||||
onOpenChange: (open: boolean) => void
|
||||
api?: {
|
||||
name: string
|
||||
endpoint: string
|
||||
method: string
|
||||
description: string
|
||||
}
|
||||
}
|
||||
|
||||
export function APIDocDialog({ open, onOpenChange, api }: APIDocDialogProps) {
|
||||
const copyToClipboard = (text: string) => {
|
||||
navigator.clipboard.writeText(text)
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-3xl max-h-[80vh]">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="flex items-center gap-2">
|
||||
<Code className="w-5 h-5" />
|
||||
API文档 - {api?.name || "API服务"}
|
||||
</DialogTitle>
|
||||
<DialogDescription>{api?.description}</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="flex items-center gap-2 p-3 bg-slate-50 rounded-lg">
|
||||
<Badge className={api?.method === "GET" ? "bg-blue-100 text-blue-700" : "bg-green-100 text-green-700"}>
|
||||
{api?.method || "GET"}
|
||||
</Badge>
|
||||
<code className="flex-1 text-sm">{api?.endpoint || "/api/v1/example"}</code>
|
||||
<Button variant="ghost" size="sm" onClick={() => copyToClipboard(api?.endpoint || "")}>
|
||||
<Copy className="w-4 h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Tabs defaultValue="request">
|
||||
<TabsList className="grid w-full grid-cols-4">
|
||||
<TabsTrigger value="request">请求参数</TabsTrigger>
|
||||
<TabsTrigger value="response">响应格式</TabsTrigger>
|
||||
<TabsTrigger value="example">示例代码</TabsTrigger>
|
||||
<TabsTrigger value="errors">错误码</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="request" className="mt-4">
|
||||
<ScrollArea className="h-[300px]">
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr className="border-b">
|
||||
<th className="text-left py-2 px-3">参数名</th>
|
||||
<th className="text-left py-2 px-3">类型</th>
|
||||
<th className="text-left py-2 px-3">必填</th>
|
||||
<th className="text-left py-2 px-3">说明</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="border-b">
|
||||
<td className="py-2 px-3">
|
||||
<code>user_id</code>
|
||||
</td>
|
||||
<td className="py-2 px-3">string</td>
|
||||
<td className="py-2 px-3">
|
||||
<Badge className="bg-red-100 text-red-700">是</Badge>
|
||||
</td>
|
||||
<td className="py-2 px-3">用户唯一标识</td>
|
||||
</tr>
|
||||
<tr className="border-b">
|
||||
<td className="py-2 px-3">
|
||||
<code>fields</code>
|
||||
</td>
|
||||
<td className="py-2 px-3">array</td>
|
||||
<td className="py-2 px-3">
|
||||
<Badge variant="outline">否</Badge>
|
||||
</td>
|
||||
<td className="py-2 px-3">需要返回的字段列表</td>
|
||||
</tr>
|
||||
<tr className="border-b">
|
||||
<td className="py-2 px-3">
|
||||
<code>include_tags</code>
|
||||
</td>
|
||||
<td className="py-2 px-3">boolean</td>
|
||||
<td className="py-2 px-3">
|
||||
<Badge variant="outline">否</Badge>
|
||||
</td>
|
||||
<td className="py-2 px-3">是否包含标签信息, 默认 true</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ScrollArea>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="response" className="mt-4">
|
||||
<ScrollArea className="h-[300px]">
|
||||
<pre className="p-4 bg-slate-900 rounded-lg text-sm text-green-400 overflow-x-auto">
|
||||
{`{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"user_id": "u_123456",
|
||||
"name": "张三",
|
||||
"phone": "138****5678",
|
||||
"email": "zhang***@example.com",
|
||||
"tags": ["高价值", "活跃用户", "VIP"],
|
||||
"portrait": {
|
||||
"age_group": "25-35",
|
||||
"gender": "male",
|
||||
"city": "上海",
|
||||
"consumption_level": "high"
|
||||
},
|
||||
"value_score": {
|
||||
"rfm_score": 85,
|
||||
"ltv": 12580,
|
||||
"churn_risk": 0.12
|
||||
}
|
||||
}
|
||||
}`}
|
||||
</pre>
|
||||
</ScrollArea>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="example" className="mt-4">
|
||||
<ScrollArea className="h-[300px]">
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<h4 className="text-sm font-medium mb-2">cURL</h4>
|
||||
<pre className="p-4 bg-slate-900 rounded-lg text-sm text-green-400 overflow-x-auto">
|
||||
{`curl -X GET "https://api.shenshoushou.com/api/v1/user/portrait?user_id=u_123456" \\
|
||||
-H "Authorization: Bearer YOUR_API_KEY" \\
|
||||
-H "Content-Type: application/json"`}
|
||||
</pre>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-sm font-medium mb-2">JavaScript</h4>
|
||||
<pre className="p-4 bg-slate-900 rounded-lg text-sm text-green-400 overflow-x-auto">
|
||||
{`const response = await fetch(
|
||||
"https://api.shenshoushou.com/api/v1/user/portrait?user_id=u_123456",
|
||||
{
|
||||
headers: {
|
||||
"Authorization": "Bearer YOUR_API_KEY",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
);
|
||||
const data = await response.json();`}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="errors" className="mt-4">
|
||||
<ScrollArea className="h-[300px]">
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr className="border-b">
|
||||
<th className="text-left py-2 px-3">错误码</th>
|
||||
<th className="text-left py-2 px-3">说明</th>
|
||||
<th className="text-left py-2 px-3">解决方案</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="border-b">
|
||||
<td className="py-2 px-3">
|
||||
<code>400</code>
|
||||
</td>
|
||||
<td className="py-2 px-3">参数错误</td>
|
||||
<td className="py-2 px-3">检查请求参数格式</td>
|
||||
</tr>
|
||||
<tr className="border-b">
|
||||
<td className="py-2 px-3">
|
||||
<code>401</code>
|
||||
</td>
|
||||
<td className="py-2 px-3">未授权</td>
|
||||
<td className="py-2 px-3">检查API Key是否正确</td>
|
||||
</tr>
|
||||
<tr className="border-b">
|
||||
<td className="py-2 px-3">
|
||||
<code>404</code>
|
||||
</td>
|
||||
<td className="py-2 px-3">用户不存在</td>
|
||||
<td className="py-2 px-3">确认用户ID是否正确</td>
|
||||
</tr>
|
||||
<tr className="border-b">
|
||||
<td className="py-2 px-3">
|
||||
<code>429</code>
|
||||
</td>
|
||||
<td className="py-2 px-3">请求频率超限</td>
|
||||
<td className="py-2 px-3">降低请求频率或升级配额</td>
|
||||
</tr>
|
||||
<tr className="border-b">
|
||||
<td className="py-2 px-3">
|
||||
<code>500</code>
|
||||
</td>
|
||||
<td className="py-2 px-3">服务器内部错误</td>
|
||||
<td className="py-2 px-3">联系技术支持</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ScrollArea>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
<div className="flex justify-end gap-2">
|
||||
<Button variant="outline">
|
||||
<ExternalLink className="w-4 h-4 mr-2" />
|
||||
在线调试
|
||||
</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user