feat: Apifox风格API文档页面,替代MarkdownViewer平铺展示
This commit is contained in:
parent
d65629afb2
commit
afdbb2ed37
932
wwwroot/api_doc.html
Normal file
932
wwwroot/api_doc.html
Normal file
@ -0,0 +1,932 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>元境 API 文档</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
:root {
|
||||
--bg-main: #1a1a2e;
|
||||
--bg-sidebar: #16213e;
|
||||
--bg-card: #1e2a47;
|
||||
--bg-code: #0d1117;
|
||||
--bg-table-row: #162038;
|
||||
--bg-table-header: #1a2744;
|
||||
--border: #2a3a5c;
|
||||
--text-primary: #e0e6ed;
|
||||
--text-secondary: #8899aa;
|
||||
--text-muted: #5a6a7a;
|
||||
--accent-blue: #4fc3f7;
|
||||
--accent-green: #66bb6a;
|
||||
--accent-orange: #ffa726;
|
||||
--accent-red: #ef5350;
|
||||
--accent-purple: #ab47bc;
|
||||
--method-post: #66bb6a;
|
||||
--method-get: #4fc3f7;
|
||||
--hover-bg: #1e2d4a;
|
||||
--sidebar-width: 280px;
|
||||
}
|
||||
html, body { height: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; background: var(--bg-main); color: var(--text-primary); font-size: 14px; }
|
||||
|
||||
/* Layout */
|
||||
.app { display: flex; height: 100vh; overflow: hidden; }
|
||||
|
||||
/* Sidebar */
|
||||
.sidebar { width: var(--sidebar-width); min-width: var(--sidebar-width); background: var(--bg-sidebar); border-right: 1px solid var(--border); display: flex; flex-direction: column; overflow: hidden; }
|
||||
.sidebar-header { padding: 20px; border-bottom: 1px solid var(--border); }
|
||||
.sidebar-header h1 { font-size: 16px; font-weight: 600; color: var(--accent-blue); }
|
||||
.sidebar-header .base-url { font-size: 11px; color: var(--text-muted); margin-top: 4px; font-family: monospace; }
|
||||
.sidebar-nav { flex: 1; overflow-y: auto; padding: 8px 0; }
|
||||
.sidebar-nav::-webkit-scrollbar { width: 4px; }
|
||||
.sidebar-nav::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
|
||||
|
||||
.nav-group { margin-bottom: 4px; }
|
||||
.nav-group-title { padding: 8px 16px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); cursor: pointer; display: flex; align-items: center; gap: 6px; user-select: none; }
|
||||
.nav-group-title:hover { color: var(--text-secondary); }
|
||||
.nav-group-title .arrow { transition: transform 0.2s; font-size: 10px; }
|
||||
.nav-group.collapsed .arrow { transform: rotate(-90deg); }
|
||||
.nav-group.collapsed .nav-items { display: none; }
|
||||
|
||||
.nav-item { padding: 7px 16px 7px 24px; cursor: pointer; display: flex; align-items: center; gap: 8px; transition: background 0.15s; border-left: 3px solid transparent; }
|
||||
.nav-item:hover { background: var(--hover-bg); }
|
||||
.nav-item.active { background: var(--hover-bg); border-left-color: var(--accent-blue); }
|
||||
.nav-item .method { font-size: 10px; font-weight: 700; padding: 2px 6px; border-radius: 3px; min-width: 36px; text-align: center; font-family: monospace; }
|
||||
.nav-item .method.post { background: rgba(102,187,106,0.15); color: var(--method-post); }
|
||||
.nav-item .method.get { background: rgba(79,195,247,0.15); color: var(--method-get); }
|
||||
.nav-item .path { font-size: 12px; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.nav-item.active .path { color: var(--text-primary); }
|
||||
|
||||
/* Content */
|
||||
.content { flex: 1; overflow-y: auto; padding: 0; }
|
||||
.content::-webkit-scrollbar { width: 6px; }
|
||||
.content::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
|
||||
|
||||
.api-section { display: none; padding: 32px 40px; max-width: 960px; }
|
||||
.api-section.active { display: block; }
|
||||
|
||||
.api-title { font-size: 22px; font-weight: 600; margin-bottom: 8px; display: flex; align-items: center; gap: 12px; }
|
||||
.api-title .method-badge { font-size: 13px; font-weight: 700; padding: 4px 10px; border-radius: 4px; font-family: monospace; }
|
||||
.api-title .method-badge.post { background: rgba(102,187,106,0.2); color: var(--method-post); }
|
||||
.api-title .method-badge.get { background: rgba(79,195,247,0.2); color: var(--method-get); }
|
||||
.api-title .endpoint { font-family: monospace; color: var(--text-primary); }
|
||||
.api-desc { color: var(--text-secondary); margin-bottom: 24px; font-size: 14px; line-height: 1.6; }
|
||||
|
||||
/* Sections */
|
||||
.section-title { font-size: 14px; font-weight: 600; color: var(--text-primary); margin: 24px 0 12px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
|
||||
.subsection-title { font-size: 13px; font-weight: 600; color: var(--accent-blue); margin: 20px 0 10px; }
|
||||
|
||||
/* Parameter Table */
|
||||
.param-table { width: 100%; border-collapse: collapse; margin-bottom: 16px; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
|
||||
.param-table th { background: var(--bg-table-header); padding: 10px 14px; text-align: left; font-size: 12px; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.3px; }
|
||||
.param-table td { padding: 10px 14px; border-top: 1px solid var(--border); font-size: 13px; vertical-align: top; }
|
||||
.param-table tr:nth-child(even) td { background: var(--bg-table-row); }
|
||||
.param-table .param-name { font-family: monospace; color: var(--accent-orange); font-weight: 500; }
|
||||
.param-table .param-type { color: var(--accent-purple); font-family: monospace; font-size: 12px; }
|
||||
.param-table .param-required { color: var(--accent-red); font-size: 11px; font-weight: 600; }
|
||||
.param-table .param-optional { color: var(--text-muted); font-size: 11px; }
|
||||
|
||||
/* Code Blocks */
|
||||
.code-block { margin: 12px 0 16px; border-radius: 8px; overflow: hidden; border: 1px solid var(--border); }
|
||||
.code-header { background: #0d1117; padding: 8px 14px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--border); }
|
||||
.code-header .lang { font-size: 11px; color: var(--text-muted); text-transform: uppercase; font-weight: 600; }
|
||||
.code-header .copy-btn { background: none; border: 1px solid var(--border); color: var(--text-muted); padding: 3px 10px; border-radius: 4px; cursor: pointer; font-size: 11px; transition: all 0.15s; }
|
||||
.code-header .copy-btn:hover { color: var(--text-primary); border-color: var(--text-secondary); }
|
||||
.code-block pre { margin: 0; padding: 16px; background: var(--bg-code); overflow-x: auto; }
|
||||
.code-block code { font-family: "SF Mono", "Fira Code", "Consolas", monospace; font-size: 13px; line-height: 1.5; }
|
||||
|
||||
/* Info Box */
|
||||
.info-box { padding: 12px 16px; border-radius: 6px; margin: 12px 0; font-size: 13px; line-height: 1.5; }
|
||||
.info-box.note { background: rgba(79,195,247,0.1); border-left: 3px solid var(--accent-blue); color: var(--text-secondary); }
|
||||
.info-box.warn { background: rgba(255,167,38,0.1); border-left: 3px solid var(--accent-orange); color: var(--text-secondary); }
|
||||
|
||||
/* Welcome page */
|
||||
.welcome { padding: 60px 40px; max-width: 700px; }
|
||||
.welcome h2 { font-size: 28px; font-weight: 700; margin-bottom: 12px; }
|
||||
.welcome p { color: var(--text-secondary); line-height: 1.7; margin-bottom: 16px; }
|
||||
.welcome .feature-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 24px; }
|
||||
.welcome .feature-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 16px; }
|
||||
.welcome .feature-card h4 { font-size: 13px; margin-bottom: 6px; color: var(--accent-blue); }
|
||||
.welcome .feature-card p { font-size: 12px; color: var(--text-muted); margin: 0; }
|
||||
|
||||
/* Model sub-nav */
|
||||
.model-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 12px 0; }
|
||||
.model-tab { padding: 5px 12px; border-radius: 4px; font-size: 12px; cursor: pointer; background: var(--bg-card); border: 1px solid var(--border); color: var(--text-secondary); transition: all 0.15s; }
|
||||
.model-tab:hover { border-color: var(--accent-blue); color: var(--text-primary); }
|
||||
.model-tab.active { background: rgba(79,195,247,0.15); border-color: var(--accent-blue); color: var(--accent-blue); }
|
||||
.model-detail { display: none; }
|
||||
.model-detail.active { display: block; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h1>元境 API</h1>
|
||||
<div class="base-url">https://token.opencomputing.cn</div>
|
||||
</div>
|
||||
<div class="sidebar-nav" id="sidebarNav"></div>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="content" id="contentArea"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// ===== API Data =====
|
||||
const apiData = [
|
||||
{
|
||||
group: "大模型 API",
|
||||
items: [
|
||||
{
|
||||
id: "chat-completions",
|
||||
method: "POST",
|
||||
path: "/llmage/v1/chat/completions",
|
||||
title: "文本生成",
|
||||
desc: "文本生成接口,兼容 OpenAI 格式。支持流式和非流式输出。",
|
||||
params: [
|
||||
{ section: "必填参数", rows: [
|
||||
{ name: "model", type: "string", required: true, desc: "模型名称,如 \"qwen3-max\"" },
|
||||
{ name: "messages / prompt", type: "array / string", required: true, desc: "对话消息数组或文本提示" }
|
||||
]},
|
||||
{ section: "可选参数", rows: [
|
||||
{ name: "catelogid", type: "string", required: false, desc: "目录类型ID,默认 \"t2t\"" },
|
||||
{ name: "stream", type: "boolean", required: false, desc: "是否启用流式输出" },
|
||||
{ name: "off_peak", type: "boolean", required: false, desc: "是否使用非高峰时段" },
|
||||
{ name: "transno", type: "string", required: false, desc: "交易流水号(不传则自动生成)" }
|
||||
]}
|
||||
],
|
||||
requestExample: {
|
||||
lang: "json",
|
||||
code: `{
|
||||
"model": "qwen3-max",
|
||||
"messages": [
|
||||
{"role": "user", "content": "Hello"}
|
||||
],
|
||||
"stream": false
|
||||
}`
|
||||
},
|
||||
responseExamples: [
|
||||
{
|
||||
title: "非流式响应",
|
||||
lang: "json",
|
||||
code: `{
|
||||
"id": "luid_xxx",
|
||||
"object": "chat.completion",
|
||||
"model": "qwen3-max",
|
||||
"choices": [{
|
||||
"index": 0,
|
||||
"message": {"role": "assistant", "content": "Hi there!"},
|
||||
"finish_reason": "stop"
|
||||
}],
|
||||
"usage": {"prompt_tokens": 10, "completion_tokens": 5, "total_tokens": 15}
|
||||
}`
|
||||
},
|
||||
{
|
||||
title: "流式响应 (SSE)",
|
||||
lang: "text",
|
||||
code: `data: {"choices": [{"delta": {"content": "Hi"}, "index": 0}]}
|
||||
data: {"choices": [{"delta": {"content": " there!"}, "index": 0}]}
|
||||
data: [DONE]`
|
||||
}
|
||||
],
|
||||
errors: [
|
||||
{ code: "400", desc: "缺少必填参数或模型不存在" },
|
||||
{ code: "403", desc: "未登录" },
|
||||
{ code: "429", desc: "账户余额不足" }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "video-generations",
|
||||
method: "POST",
|
||||
path: "/llmage/v1/video/generations",
|
||||
title: "视频生成",
|
||||
desc: "视频生成接口。支持文生视频、图生视频、参考生视频等多种模式。异步任务,需通过 /v1/tasks 查询状态。",
|
||||
params: [
|
||||
{ section: "必填参数", rows: [
|
||||
{ name: "model", type: "string", required: true, desc: "模型名称,如 \"keling-2.1\"" },
|
||||
{ name: "catelogid", type: "string", required: true, desc: "目录类型ID:t2v / i2v / r2v" },
|
||||
{ name: "prompt", type: "string", required: true, desc: "生成提示词" }
|
||||
]},
|
||||
{ section: "可选参数", rows: [
|
||||
{ name: "image_url", type: "string", required: false, desc: "图生视频时提供参考图 URL" },
|
||||
{ name: "duration", type: "string", required: false, desc: "视频时长,如 \"5s\"" },
|
||||
{ name: "resolution", type: "string", required: false, desc: "分辨率,如 \"1080p\"" },
|
||||
{ name: "n", type: "integer", required: false, desc: "生成数量" },
|
||||
{ name: "transno", type: "string", required: false, desc: "交易流水号" }
|
||||
]}
|
||||
],
|
||||
requestExample: {
|
||||
lang: "json",
|
||||
code: `{
|
||||
"model": "keling-2.1",
|
||||
"catelogid": "t2v",
|
||||
"prompt": "A beautiful sunset over the ocean",
|
||||
"duration": "5s",
|
||||
"resolution": "1080p"
|
||||
}`
|
||||
},
|
||||
responseExamples: [
|
||||
{
|
||||
title: "异步任务响应",
|
||||
lang: "json",
|
||||
code: `{
|
||||
"id": "luid_xxx",
|
||||
"object": "video.generation",
|
||||
"model": "keling-2.1",
|
||||
"status": "submitted",
|
||||
"taskid": "task_xxx",
|
||||
"created": 1716912000
|
||||
}`
|
||||
}
|
||||
],
|
||||
models: [
|
||||
{
|
||||
name: "Vidu - T2V 文生视频",
|
||||
params: [
|
||||
{ name: "model", type: "string", required: true, desc: "viduq3-pro, viduq3-turbo" },
|
||||
{ name: "prompt", type: "string", required: true, desc: "提示词" },
|
||||
{ name: "duration", type: "integer", required: false, desc: "视频长度(1-16秒),默认 10" },
|
||||
{ name: "ratio", type: "string", required: false, desc: "长宽比:16:9, 9:16, 4:3, 3:4, 1:1" },
|
||||
{ name: "resolution", type: "string", required: false, desc: "分辨率:540p, 720p, 1080p" }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Vidu - I2V 图生视频",
|
||||
params: [
|
||||
{ name: "model", type: "string", required: true, desc: "viduq3-pro, viduq3-turbo" },
|
||||
{ name: "prompt", type: "string", required: true, desc: "提示词" },
|
||||
{ name: "image_file", type: "image", required: true, desc: "首帧图片" },
|
||||
{ name: "duration", type: "integer", required: false, desc: "视频长度(1-16秒)" },
|
||||
{ name: "ratio", type: "string", required: false, desc: "长宽比" },
|
||||
{ name: "resolution", type: "string", required: false, desc: "分辨率" }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Vidu - Ref2V 参考生视频 v2(主体模式)",
|
||||
params: [
|
||||
{ name: "model", type: "string", required: true, desc: "viduq3-turbo/q3/q2-pro/q2/q1/2.0" },
|
||||
{ name: "subjects", type: "array", required: true, desc: "主体列表(最多7个图片/文字主体,每个最多3张图)" },
|
||||
{ name: "prompt", type: "string", required: true, desc: "提示词" },
|
||||
{ name: "duration", type: "integer", required: false, desc: "视频时长" },
|
||||
{ name: "aspect_ratio", type: "string", required: false, desc: "画面比例" },
|
||||
{ name: "resolution", type: "string", required: false, desc: "分辨率" },
|
||||
{ name: "audio", type: "boolean", required: false, desc: "音视频直出" }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Vidu - Ref2V 参考生视频 v2(非主体模式)",
|
||||
params: [
|
||||
{ name: "model", type: "string", required: true, desc: "viduq3-mix/q3-turbo/q3/q2-pro/q2/q1/2.0" },
|
||||
{ name: "images", type: "array", required: true, desc: "参考图片URL列表(1-7张)" },
|
||||
{ name: "prompt", type: "string", required: true, desc: "提示词" },
|
||||
{ name: "duration", type: "integer", required: false, desc: "视频时长" },
|
||||
{ name: "aspect_ratio", type: "string", required: false, desc: "画面比例" },
|
||||
{ name: "resolution", type: "string", required: false, desc: "分辨率" }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Seedance - T2V 文生视频",
|
||||
params: [
|
||||
{ name: "model", type: "string", required: true, desc: "doubao-seedance-2-0-260128, doubao-seedance-2-0-fast-260128" },
|
||||
{ name: "prompt", type: "string", required: true, desc: "提示词" },
|
||||
{ name: "resolution", type: "string", required: false, desc: "尺寸:480p, 720p, 1080p" },
|
||||
{ name: "duration", type: "integer", required: false, desc: "视频长度,默认 8" },
|
||||
{ name: "ratio", type: "string", required: false, desc: "宽高比:1:1, 16:9, 9:16, 4:3, 3:4, 21:9, 9:21" }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Seedance - TI2V 文图生视频",
|
||||
params: [
|
||||
{ name: "model", type: "string", required: true, desc: "doubao-seedance-2-0-260128, doubao-seedance-2-0-fast-260128" },
|
||||
{ name: "prompt", type: "string", required: true, desc: "提示词" },
|
||||
{ name: "image1_file", type: "image", required: true, desc: "首帧图片" },
|
||||
{ name: "image2_file", type: "image", required: false, desc: "尾帧图片" },
|
||||
{ name: "resolution", type: "string", required: false, desc: "尺寸" },
|
||||
{ name: "duration", type: "integer", required: false, desc: "视频长度,默认 8" },
|
||||
{ name: "ratio", type: "string", required: false, desc: "宽高比" }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "通义万象 - T2V 文生视频",
|
||||
params: [
|
||||
{ name: "model", type: "string", required: true, desc: "模型名称(如 wan2.6-t2v)" },
|
||||
{ name: "prompt", type: "string", required: true, desc: "提示词" },
|
||||
{ name: "negative_prompt", type: "string", required: false, desc: "反向提示词" },
|
||||
{ name: "audio_file", type: "audio", required: false, desc: "配音文件" },
|
||||
{ name: "size", type: "string", required: false, desc: "视频尺寸,默认 1920*1080" },
|
||||
{ name: "duration", type: "string", required: false, desc: "视频时长:5, 10, 15" }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "通义万象 - I2V 图生视频",
|
||||
params: [
|
||||
{ name: "model", type: "string", required: true, desc: "wan2.6-i2v, wan2.6-i2v-flash" },
|
||||
{ name: "prompt", type: "string", required: true, desc: "提示词" },
|
||||
{ name: "image_file", type: "image", required: true, desc: "首帧图片" },
|
||||
{ name: "size", type: "string", required: false, desc: "视频尺寸" },
|
||||
{ name: "duration", type: "string", required: false, desc: "视频时长" }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "通义万象 - Ref2V 角色参考生视频",
|
||||
params: [
|
||||
{ name: "model", type: "string", required: true, desc: "模型名称(如 wan2.6-r2v)" },
|
||||
{ name: "prompt", type: "string", required: true, desc: "提示词" },
|
||||
{ name: "video1_file", type: "video", required: true, desc: "角色一视频" },
|
||||
{ name: "video2_file", type: "video", required: false, desc: "角色二视频" },
|
||||
{ name: "video3_file", type: "video", required: false, desc: "角色三视频" },
|
||||
{ name: "size", type: "string", required: false, desc: "视频尺寸" },
|
||||
{ name: "duration", type: "string", required: false, desc: "视频时长:10, 15" }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "可灵 Kling - T2V 文生视频",
|
||||
params: [
|
||||
{ name: "model", type: "string", required: true, desc: "kling-v2-1-master, kling-v2-master, kling-v1-6, kling-v1" },
|
||||
{ name: "prompt", type: "string", required: true, desc: "提示词" },
|
||||
{ name: "negative_prompt", type: "string", required: false, desc: "反向提示词" }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "海螺 MiniMax - TI2V 图生视频",
|
||||
params: [
|
||||
{ name: "prompt", type: "string", required: true, desc: "提示词" },
|
||||
{ name: "image_file", type: "image", required: false, desc: "首帧图片" },
|
||||
{ name: "image_file1", type: "image", required: false, desc: "尾帧图片" },
|
||||
{ name: "resolution", type: "string", required: false, desc: "尺寸:768P, 1080P" },
|
||||
{ name: "duration", type: "integer", required: false, desc: "视频长度:6(6秒), 10(10秒)" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "image-generations",
|
||||
method: "POST",
|
||||
path: "/llmage/v1/image/generations",
|
||||
title: "图像生成",
|
||||
desc: "图像生成接口。支持文生图和图生图。",
|
||||
params: [
|
||||
{ section: "必填参数", rows: [
|
||||
{ name: "model", type: "string", required: true, desc: "模型名称,如 \"jimeng-4.0\"" },
|
||||
{ name: "catelogid", type: "string", required: true, desc: "目录类型ID,文生图固定为 \"t2i\"" },
|
||||
{ name: "prompt", type: "string", required: true, desc: "生成提示词" }
|
||||
]},
|
||||
{ section: "可选参数", rows: [
|
||||
{ name: "image_url", type: "string", required: false, desc: "图生图时提供参考图 URL" },
|
||||
{ name: "size", type: "string", required: false, desc: "尺寸,如 \"1024x1024\"" },
|
||||
{ name: "n", type: "integer", required: false, desc: "生成数量" },
|
||||
{ name: "style", type: "string", required: false, desc: "风格参数" },
|
||||
{ name: "quality", type: "string", required: false, desc: "质量参数" },
|
||||
{ name: "transno", type: "string", required: false, desc: "交易流水号" }
|
||||
]}
|
||||
],
|
||||
requestExample: {
|
||||
lang: "json",
|
||||
code: `{
|
||||
"model": "jimeng-4.0",
|
||||
"catelogid": "t2i",
|
||||
"prompt": "A beautiful sunset over the ocean",
|
||||
"size": "1024x1024",
|
||||
"n": 1
|
||||
}`
|
||||
},
|
||||
responseExamples: [
|
||||
{
|
||||
title: "响应示例",
|
||||
lang: "json",
|
||||
code: `{
|
||||
"id": "luid_xxx",
|
||||
"object": "image.generation",
|
||||
"model": "jimeng-4.0",
|
||||
"status": "submitted",
|
||||
"taskid": "task_xxx",
|
||||
"created": 1716912000
|
||||
}`
|
||||
}
|
||||
],
|
||||
models: [
|
||||
{
|
||||
name: "百炼-万象文生图(异步)",
|
||||
params: [
|
||||
{ name: "model", type: "string", required: true, desc: "wan2.2-t2i-plus / wan2.5-t2i-preview / wan2.2-t2i-flash" },
|
||||
{ name: "catelogid", type: "string", required: true, desc: "文生图固定 t2i" },
|
||||
{ name: "prompt", type: "string", required: true, desc: "提示词" },
|
||||
{ name: "size", type: "string", required: false, desc: "尺寸:512*512, 1024*1024, 2048*2048 等" },
|
||||
{ name: "n", type: "integer", required: false, desc: "生成数量 1-4" }
|
||||
],
|
||||
responseExample: {
|
||||
lang: "json",
|
||||
code: `// 提交响应
|
||||
{"status": "ok", "data": {"taskid": "task_xxx", "status": "PENDING"}}
|
||||
|
||||
// 查询结果(/v1/tasks?taskid=task_xxx)
|
||||
{"status": "ok", "data": {"status": "SUCCEEDED", "output": [{"url": "https://..."}], "usage": {"image_count": 1}}}`
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "智谱 CogView-3-Flash(同步/免费)",
|
||||
params: [
|
||||
{ name: "model", type: "string", required: true, desc: "cogview-3-flash" },
|
||||
{ name: "catelogid", type: "string", required: true, desc: "文生图固定 t2i" },
|
||||
{ name: "prompt", type: "string", required: true, desc: "提示词" },
|
||||
{ name: "size", type: "string", required: false, desc: "尺寸:512x512, 1024x1024, 2048x2048" }
|
||||
],
|
||||
responseExample: {
|
||||
lang: "json",
|
||||
code: `{"status": "ok", "data": {"image": "https://...", "usage": {"image_count": 1}}}`
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "tasks",
|
||||
method: "GET",
|
||||
path: "/llmage/v1/tasks",
|
||||
title: "查询异步任务",
|
||||
desc: "查询异步任务状态。用于视频生成、图像生成等异步接口返回任务进度。",
|
||||
params: [
|
||||
{ section: "必填参数", rows: [
|
||||
{ name: "taskid", type: "string", required: true, desc: "任务 ID" }
|
||||
]}
|
||||
],
|
||||
requestExample: {
|
||||
lang: "bash",
|
||||
code: `GET /llmage/v1/tasks?taskid=task_xxx`
|
||||
},
|
||||
responseExamples: [
|
||||
{
|
||||
title: "响应示例",
|
||||
lang: "json",
|
||||
code: `{
|
||||
"status": "ok",
|
||||
"data": {
|
||||
"status": "SUCCEEDED",
|
||||
"output": [...]
|
||||
}
|
||||
}`
|
||||
}
|
||||
],
|
||||
note: "任务状态值: UNKNOWN / SUCCEEDED / FAILED"
|
||||
},
|
||||
{
|
||||
id: "models",
|
||||
method: "GET",
|
||||
path: "/llmage/v1/models",
|
||||
title: "模型列表",
|
||||
desc: "列出可用模型列表。",
|
||||
params: [
|
||||
{ section: "可选参数", rows: [
|
||||
{ name: "catelogid", type: "string", required: false, desc: "按目录类型过滤" },
|
||||
{ name: "orderby", type: "string", required: false, desc: "排序字段" }
|
||||
]}
|
||||
],
|
||||
requestExample: {
|
||||
lang: "bash",
|
||||
code: `GET /llmage/v1/models`
|
||||
},
|
||||
responseExamples: [
|
||||
{
|
||||
title: "响应示例",
|
||||
lang: "json",
|
||||
code: `{
|
||||
"object": "list",
|
||||
"data": [
|
||||
{
|
||||
"id": "qwen3-max",
|
||||
"object": "model",
|
||||
"created": 1748044800,
|
||||
"owned_by": "opencomputing.ai"
|
||||
}
|
||||
]
|
||||
}`
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
group: "真人素材 API",
|
||||
items: [
|
||||
{
|
||||
id: "rl-verify",
|
||||
method: "POST",
|
||||
path: "/reallife_asset/api/rl_verify.dspy",
|
||||
title: "真人认证",
|
||||
desc: "获取真人认证链接(H5)。终端用户通过 H5 页面完成人脸识别。",
|
||||
params: [
|
||||
{ section: "请求参数", rows: [
|
||||
{ name: "vendor", type: "string", required: true, desc: "供应商标识" },
|
||||
{ name: "project_name", type: "string", required: false, desc: "项目名称,默认 default" },
|
||||
{ name: "name", type: "string", required: false, desc: "认证名称,方便识别" }
|
||||
]}
|
||||
],
|
||||
requestExample: {
|
||||
lang: "bash",
|
||||
code: `curl -X POST 'https://token.opencomputing.cn/reallife_asset/api/rl_verify.dspy' \\
|
||||
-H 'Authorization: Bearer *** \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-d '{
|
||||
"vendor": "volcengine",
|
||||
"project_name": "default",
|
||||
"name": "张三"
|
||||
}'`
|
||||
},
|
||||
responseExamples: [
|
||||
{
|
||||
title: "响应示例",
|
||||
lang: "json",
|
||||
code: `{
|
||||
"status": "ok",
|
||||
"data": {
|
||||
"id": "local_group_id_xxx",
|
||||
"h5_link": "https://... (H5页面链接,120秒有效)",
|
||||
"byted_token": "..."
|
||||
}
|
||||
}`
|
||||
}
|
||||
],
|
||||
note: "user_id 和 org_id 由 Bearer Token 自动获取"
|
||||
},
|
||||
{
|
||||
id: "rl-query-groups",
|
||||
method: "POST",
|
||||
path: "/reallife_asset/api/rl_query_groups.dspy",
|
||||
title: "查询已认证组合",
|
||||
desc: "查询当前机构下所有已认证的组合 ID,用于上传素材时选择有效的 vendor_group_id。",
|
||||
params: [
|
||||
{ section: "请求参数", rows: [
|
||||
{ name: "(无)", type: "-", required: false, desc: "系统自动从 Bearer Token 获取 org_id" }
|
||||
]}
|
||||
],
|
||||
requestExample: {
|
||||
lang: "bash",
|
||||
code: `curl -X POST 'https://token.opencomputing.cn/reallife_asset/api/rl_query_groups.dspy' \\
|
||||
-H 'Authorization: Bearer ***`
|
||||
},
|
||||
responseExamples: [
|
||||
{
|
||||
title: "响应示例",
|
||||
lang: "json",
|
||||
code: `{
|
||||
"status": "ok",
|
||||
"data": {
|
||||
"groups": [
|
||||
{
|
||||
"vendor_group_id": "volc-asset-group-xxx",
|
||||
"vendor": "volcengine",
|
||||
"name": "模特张三",
|
||||
"status": "active",
|
||||
"create_time": "2026-05-28 15:30:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "rl-upload",
|
||||
method: "POST",
|
||||
path: "/reallife_asset/api/rl_upload.dspy",
|
||||
title: "上传素材",
|
||||
desc: "上传素材到已认证的组合。支持图片和视频。上传为异步操作,需轮询 rl_status 获取处理状态。",
|
||||
params: [
|
||||
{ section: "请求参数", rows: [
|
||||
{ name: "vendor_group_id", type: "string", required: true, desc: "已认证的组合 ID" },
|
||||
{ name: "source_url", type: "string", required: true, desc: "素材 URL 或 data: base64 编码" },
|
||||
{ name: "asset_type", type: "string", required: false, desc: "Image(默认)或 Video" },
|
||||
{ name: "name", type: "string", required: false, desc: "素材名称" }
|
||||
]}
|
||||
],
|
||||
requestExample: {
|
||||
lang: "bash",
|
||||
code: `curl -X POST 'https://token.opencomputing.cn/reallife_asset/api/rl_upload.dspy' \\
|
||||
-H 'Authorization: Bearer *** \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-d '{
|
||||
"vendor_group_id": "volc-asset-group-xxx",
|
||||
"source_url": "https://bucket.oss.com/photo.jpg",
|
||||
"asset_type": "Image",
|
||||
"name": "模特A"
|
||||
}'`
|
||||
},
|
||||
responseExamples: [
|
||||
{
|
||||
title: "响应示例",
|
||||
lang: "json",
|
||||
code: `{
|
||||
"status": "ok",
|
||||
"data": {
|
||||
"id": "asset_record_id_xxx",
|
||||
"vendor_asset_id": "asset-2026...",
|
||||
"status": "Processing"
|
||||
}
|
||||
}`
|
||||
}
|
||||
],
|
||||
note: "上传是异步操作,需调用 rl_status 轮询状态。"
|
||||
},
|
||||
{
|
||||
id: "rl-status",
|
||||
method: "POST",
|
||||
path: "/reallife_asset/api/rl_status.dspy",
|
||||
title: "查询素材状态",
|
||||
desc: "查询素材处理状态。素材永久存储,url 过期后可再次调用获取新链接。",
|
||||
params: [
|
||||
{ section: "请求参数", rows: [
|
||||
{ name: "asset_id", type: "string", required: true, desc: "上传时返回的记录 ID" }
|
||||
]}
|
||||
],
|
||||
requestExample: {
|
||||
lang: "bash",
|
||||
code: `curl -X POST 'https://token.opencomputing.cn/reallife_asset/api/rl_status.dspy' \\
|
||||
-H 'Authorization: Bearer *** \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-d '{
|
||||
"asset_id": "asset_record_id_xxx"
|
||||
}'`
|
||||
},
|
||||
responseExamples: [
|
||||
{
|
||||
title: "响应示例",
|
||||
lang: "json",
|
||||
code: `{
|
||||
"status": "ok",
|
||||
"data": {
|
||||
"status": "Active",
|
||||
"url": "https://... (临时下载链接,12小时有效)"
|
||||
}
|
||||
}`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "rl-assets",
|
||||
method: "POST",
|
||||
path: "/reallife_asset/api/rl_assets.dspy",
|
||||
title: "查询组合素材",
|
||||
desc: "查询组合下所有素材列表。",
|
||||
params: [
|
||||
{ section: "请求参数", rows: [
|
||||
{ name: "vendor_group_id", type: "string", required: true, desc: "已认证的组合 ID" }
|
||||
]}
|
||||
],
|
||||
requestExample: {
|
||||
lang: "bash",
|
||||
code: `curl -X POST 'https://token.opencomputing.cn/reallife_asset/api/rl_assets.dspy' \\
|
||||
-H 'Authorization: Bearer *** \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-d '{
|
||||
"vendor_group_id": "volc-asset-group-xxx"
|
||||
}'`
|
||||
},
|
||||
responseExamples: [
|
||||
{
|
||||
title: "响应示例",
|
||||
lang: "json",
|
||||
code: `{
|
||||
"status": "ok",
|
||||
"data": {
|
||||
"assets": [
|
||||
{
|
||||
"id": "asset_record_id_xxx",
|
||||
"vendor_asset_id": "asset-2026...",
|
||||
"name": "模特A",
|
||||
"asset_type": "Image",
|
||||
"status": "Active",
|
||||
"url": "https://...",
|
||||
"create_time": "2026-05-28 15:30:00"
|
||||
}
|
||||
],
|
||||
"total": 3
|
||||
}
|
||||
}`
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
group: "参考信息",
|
||||
items: [
|
||||
{
|
||||
id: "catelogid",
|
||||
method: "GET",
|
||||
path: "",
|
||||
title: "catelogid 对照表",
|
||||
desc: "catelogid 目录类型ID对照表。所有 v1 接口统一使用此参数标识目录类型。",
|
||||
isReference: true,
|
||||
refTable: [
|
||||
{ id: "t2t", name: "文生文", desc: "文本生成(默认)" },
|
||||
{ id: "t2i", name: "文生图", desc: "图像生成" },
|
||||
{ id: "t2v", name: "文生视频", desc: "文本生成视频" },
|
||||
{ id: "i2v", name: "图生视频", desc: "图像生成视频" },
|
||||
{ id: "r2v", name: "参考生视频", desc: "参考图像生成视频" },
|
||||
{ id: "tts", name: "语音合成", desc: "文本转语音" },
|
||||
{ id: "asr", name: "语音识别", desc: "语音转文本" },
|
||||
{ id: "vision", name: "图理解", desc: "图像理解" },
|
||||
{ id: "ai_search", name: "AI搜索", desc: "AI搜索" },
|
||||
{ id: "digital_human", name: "数字人", desc: "数字人" },
|
||||
{ id: "music_gen", name: "音乐生成", desc: "音乐生成" },
|
||||
{ id: "text_cls", name: "文本分类", desc: "文本分类" },
|
||||
{ id: "3d_gen", name: "3D生成", desc: "3D模型生成" },
|
||||
{ id: "video_tool", name: "视频工具", desc: "视频处理工具" },
|
||||
{ id: "translate", name: "翻译", desc: "文本翻译" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
// ===== Render Functions =====
|
||||
function renderSidebar() {
|
||||
const nav = document.getElementById('sidebarNav');
|
||||
let html = '';
|
||||
apiData.forEach((group, gi) => {
|
||||
html += `<div class="nav-group" data-group="${gi}">`;
|
||||
html += `<div class="nav-group-title" onclick="toggleGroup(${gi})"><span class="arrow">▼</span>${group.group}</div>`;
|
||||
html += `<div class="nav-items">`;
|
||||
group.items.forEach(item => {
|
||||
const methodClass = item.method.toLowerCase();
|
||||
const pathDisplay = item.path ? item.path.replace('/llmage/v1/', '/v1/').replace('/reallife_asset/api/', '') : item.title;
|
||||
html += `<div class="nav-item" data-id="${item.id}" onclick="selectApi('${item.id}')">`;
|
||||
if (item.path) {
|
||||
html += `<span class="method ${methodClass}">${item.method}</span>`;
|
||||
}
|
||||
html += `<span class="path">${item.path ? pathDisplay : item.title}</span>`;
|
||||
html += `</div>`;
|
||||
});
|
||||
html += `</div></div>`;
|
||||
});
|
||||
nav.innerHTML = html;
|
||||
}
|
||||
|
||||
function renderContent() {
|
||||
const content = document.getElementById('contentArea');
|
||||
let html = `<div class="api-section active" id="welcome-section">
|
||||
<div class="welcome">
|
||||
<h2>元境 API 文档</h2>
|
||||
<p>统一的 AI 模型 API 网关,兼容 OpenAI 格式。支持文本生成、图像生成、视频生成、真人素材等能力。</p>
|
||||
<p>所有接口通过 Bearer Token 认证。Base URL: <code style="color:var(--accent-blue)">https://token.opencomputing.cn</code></p>
|
||||
<div class="feature-grid">
|
||||
<div class="feature-card"><h4>🤖 文本生成</h4><p>兼容 OpenAI Chat Completions 格式,支持流式输出</p></div>
|
||||
<div class="feature-card"><h4>🎬 视频生成</h4><p>多平台视频模型:Vidu、Seedance、通义万象、可灵、海螺</p></div>
|
||||
<div class="feature-card"><h4>🎨 图像生成</h4><p>百炼万象、智谱CogView 等文生图/图生图模型</p></div>
|
||||
<div class="feature-card"><h4>👤 真人素材</h4><p>真人认证、素材上传、素材管理全流程</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
apiData.forEach(group => {
|
||||
group.items.forEach(item => {
|
||||
html += `<div class="api-section" id="section-${item.id}">`;
|
||||
|
||||
// Title
|
||||
if (item.path) {
|
||||
const methodClass = item.method.toLowerCase();
|
||||
html += `<div class="api-title"><span class="method-badge ${methodClass}">${item.method}</span><span class="endpoint">${item.path}</span></div>`;
|
||||
} else {
|
||||
html += `<div class="api-title"><span class="endpoint">${item.title}</span></div>`;
|
||||
}
|
||||
html += `<div class="api-desc">${item.desc}</div>`;
|
||||
|
||||
// Reference table (catelogid)
|
||||
if (item.isReference && item.refTable) {
|
||||
html += `<table class="param-table"><thead><tr><th>ID</th><th>中文名</th><th>说明</th></tr></thead><tbody>`;
|
||||
item.refTable.forEach(r => {
|
||||
html += `<tr><td class="param-name">${r.id}</td><td>${r.name}</td><td>${r.desc}</td></tr>`;
|
||||
});
|
||||
html += `</tbody></table>`;
|
||||
html += `<div class="info-box note" style="margin-top:16px">向后兼容:catelogid 参数同时支持新ID(如 "t2v")和旧中文名(如 "文生视频"),推荐使用新ID。</div>`;
|
||||
html += `</div>`;
|
||||
return;
|
||||
}
|
||||
|
||||
// Note
|
||||
if (item.note) {
|
||||
html += `<div class="info-box note">${item.note}</div>`;
|
||||
}
|
||||
|
||||
// Parameters
|
||||
if (item.params) {
|
||||
html += `<div class="section-title">请求参数</div>`;
|
||||
item.params.forEach(p => {
|
||||
if (item.params.length > 1) html += `<div class="subsection-title">${p.section}</div>`;
|
||||
html += renderParamTable(p.rows);
|
||||
});
|
||||
}
|
||||
|
||||
// Request Example
|
||||
if (item.requestExample) {
|
||||
html += `<div class="section-title">请求示例</div>`;
|
||||
html += renderCodeBlock(item.requestExample.lang, item.requestExample.code);
|
||||
}
|
||||
|
||||
// Response Examples
|
||||
if (item.responseExamples) {
|
||||
html += `<div class="section-title">响应示例</div>`;
|
||||
item.responseExamples.forEach(r => {
|
||||
if (item.responseExamples.length > 1) html += `<div class="subsection-title">${r.title}</div>`;
|
||||
html += renderCodeBlock(r.lang, r.code);
|
||||
});
|
||||
}
|
||||
|
||||
// Errors
|
||||
if (item.errors) {
|
||||
html += `<div class="section-title">错误响应</div>`;
|
||||
html += `<table class="param-table"><thead><tr><th>状态码</th><th>说明</th></tr></thead><tbody>`;
|
||||
item.errors.forEach(e => {
|
||||
html += `<tr><td><span style="color:var(--accent-red);font-weight:600">${e.code}</span></td><td>${e.desc}</td></tr>`;
|
||||
});
|
||||
html += `</tbody></table>`;
|
||||
}
|
||||
|
||||
// Model details
|
||||
if (item.models) {
|
||||
html += `<div class="section-title">各模型参数明细</div>`;
|
||||
html += `<div class="info-box note">调用时通过 model + catelogid 自动路由到对应供应商</div>`;
|
||||
html += `<div class="model-tabs" id="tabs-${item.id}">`;
|
||||
item.models.forEach((m, mi) => {
|
||||
html += `<div class="model-tab${mi === 0 ? ' active' : ''}" onclick="switchModelTab('${item.id}', ${mi})">${m.name}</div>`;
|
||||
});
|
||||
html += `</div>`;
|
||||
item.models.forEach((m, mi) => {
|
||||
html += `<div class="model-detail${mi === 0 ? ' active' : ''}" id="model-${item.id}-${mi}">`;
|
||||
html += renderParamTable(m.params);
|
||||
if (m.responseExample) {
|
||||
html += `<div class="subsection-title">响应示例</div>`;
|
||||
html += renderCodeBlock(m.responseExample.lang, m.responseExample.code);
|
||||
}
|
||||
html += `</div>`;
|
||||
});
|
||||
}
|
||||
|
||||
html += `</div>`;
|
||||
});
|
||||
});
|
||||
content.innerHTML = html;
|
||||
}
|
||||
|
||||
function renderParamTable(rows) {
|
||||
let html = `<table class="param-table"><thead><tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr></thead><tbody>`;
|
||||
rows.forEach(r => {
|
||||
const reqClass = r.required ? 'param-required' : 'param-optional';
|
||||
const reqText = r.required ? '是' : '否';
|
||||
html += `<tr><td class="param-name">${r.name}</td><td class="param-type">${r.type}</td><td class="${reqClass}">${reqText}</td><td>${r.desc}</td></tr>`;
|
||||
});
|
||||
html += `</tbody></table>`;
|
||||
return html;
|
||||
}
|
||||
|
||||
function renderCodeBlock(lang, code) {
|
||||
const escaped = code.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
return `<div class="code-block">
|
||||
<div class="code-header"><span class="lang">${lang}</span><button class="copy-btn" onclick="copyCode(this)">复制</button></div>
|
||||
<pre><code class="language-${lang}">${escaped}</code></pre>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// ===== Interactions =====
|
||||
function selectApi(id) {
|
||||
document.querySelectorAll('.nav-item').forEach(el => el.classList.remove('active'));
|
||||
document.querySelector(`.nav-item[data-id="${id}"]`)?.classList.add('active');
|
||||
document.querySelectorAll('.api-section').forEach(el => el.classList.remove('active'));
|
||||
const section = document.getElementById(`section-${id}`);
|
||||
if (section) {
|
||||
section.classList.add('active');
|
||||
document.getElementById('contentArea').scrollTop = 0;
|
||||
}
|
||||
// Highlight code
|
||||
section?.querySelectorAll('pre code').forEach(block => hljs.highlightElement(block));
|
||||
}
|
||||
|
||||
function toggleGroup(gi) {
|
||||
const group = document.querySelector(`.nav-group[data-group="${gi}"]`);
|
||||
group.classList.toggle('collapsed');
|
||||
}
|
||||
|
||||
function switchModelTab(apiId, index) {
|
||||
const tabs = document.querySelectorAll(`#tabs-${apiId} .model-tab`);
|
||||
tabs.forEach((t, i) => t.classList.toggle('active', i === index));
|
||||
const details = document.querySelectorAll(`[id^="model-${apiId}-"]`);
|
||||
details.forEach((d, i) => d.classList.toggle('active', i === index));
|
||||
}
|
||||
|
||||
function copyCode(btn) {
|
||||
const code = btn.closest('.code-block').querySelector('code').textContent;
|
||||
navigator.clipboard.writeText(code).then(() => {
|
||||
btn.textContent = '已复制';
|
||||
setTimeout(() => btn.textContent = '复制', 1500);
|
||||
});
|
||||
}
|
||||
|
||||
// ===== Init =====
|
||||
renderSidebar();
|
||||
renderContent();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -7,35 +7,12 @@
|
||||
},
|
||||
"subwidgets": [
|
||||
{
|
||||
"widgettype": "HBox",
|
||||
"widgettype": "urlwidget",
|
||||
"options": {
|
||||
"url": "{{entire_url('/dashboard_for_sage/api_doc.html')}}",
|
||||
"width": "100%",
|
||||
"alignItems": "center",
|
||||
"marginBottom": "16px"
|
||||
},
|
||||
"subwidgets": [
|
||||
{
|
||||
"widgettype": "Title2",
|
||||
"options": {
|
||||
"text": "大模型 API 文档"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "VScrollPanel",
|
||||
"options": {
|
||||
"css": "filler"
|
||||
},
|
||||
"subwidgets": [
|
||||
{
|
||||
"widgettype": "MarkdownViewer",
|
||||
"options": {
|
||||
"md_url": "{{entire_url('/dashboard_for_sage/api_doc.md')}}",
|
||||
"width": "100%"
|
||||
"height": "100%"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user