2026-05-25 11:47:45 +08:00

307 lines
7.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="api-doc-page">
<header class="doc-nav">
<button type="button" @click="goBack">
<i class="el-icon-arrow-left"></i>
返回
</button>
<span>API文档</span>
</header>
<main class="doc-container">
<el-alert
v-if="errorMessage"
class="doc-alert"
:title="errorMessage"
type="warning"
show-icon
:closable="false"
></el-alert>
<section class="doc-hero">
<h1>{{ apiDoc.model_name }} API 文档</h1>
<p>{{ heroDescription }}</p>
<!-- <div class="quick-tabs">
<span v-for="item in quickTabs" :key="item">{{ item }}</span>
</div> -->
</section>
<section v-loading="loading" class="doc-section">
<h2>1. 接口地址</h2>
<p>统一使用 HTTPS 请求所有接口都需要携带平台签发的 API Key</p>
<pre><code>{{ apiUrlText }}</code></pre>
</section>
<section class="doc-section">
<h2>2. 请求示例</h2>
<pre><code>{{ apiDoc.curl_code || requestExample }}</code></pre>
</section>
<section class="doc-section">
<h2>3. Python 示例</h2>
<pre><code>{{ apiDoc.python_code || pythonExample }}</code></pre>
</section>
<section class="doc-section">
<h2>4. 错误码</h2>
<el-table :data="errorCodes" border size="small">
<el-table-column prop="code" label="错误码" width="140"></el-table-column>
<el-table-column prop="message" label="说明"></el-table-column>
<el-table-column prop="suggestion" label="处理建议"></el-table-column>
</el-table>
</section>
</main>
<footer class="doc-footer">© 2026 开元云科技 · API 文档中心</footer>
</div>
</template>
<script>
import { reqModelApiDocument } from '@/api/model/model'
export default {
name: 'ApiDocument',
data() {
return {
loading: false,
errorMessage: '',
apiDoc: {
id: '',
api_url: '',
model_id: '',
curl_code: '',
python_code: '',
model_name: '模型'
},
quickTabs: ['API概览', '认证方式', '请求参数', '代码示例', '错误码'],
capabilityTable: [
{ name: '文本对话', value: '支持单轮和多轮对话生成', status: '支持' },
{ name: '流式输出', value: '通过 stream=true 开启 SSE 增量返回', status: '支持' },
{ name: 'Function Call', value: '支持工具调用和结构化参数', status: '支持' },
{ name: '图像输入', value: '可在 messages 中传入图片内容', status: '支持' },
{ name: '私有化部署', value: '当前公共服务暂不支持私有化', status: '暂不支持' }
],
requestParams: [
{ name: 'model', type: 'string', required: '是', desc: '模型 ID例如 minimax-m2.5' },
{ name: 'messages', type: 'array', required: '是', desc: '对话消息列表,包含 role 和 content' },
{ name: 'temperature', type: 'number', required: '否', desc: '采样温度,数值越高输出越随机' },
{ name: 'stream', type: 'boolean', required: '否', desc: '是否开启流式返回' },
{ name: 'max_tokens', type: 'number', required: '否', desc: '限制模型最大输出长度' }
],
errorCodes: [
{ code: '401', message: '认证失败', suggestion: '检查 API Key 是否正确或过期' },
{ code: '429', message: '请求过于频繁', suggestion: '降低并发或等待限流恢复' },
{ code: '500', message: '服务异常', suggestion: '稍后重试或联系平台支持' }
],
requestExample: `curl https://api.kboss.example.com/v2/chat/completions \\
-H "Content-Type: application/json" \\
-H "Authorization: Bearer $KBOSS_API_KEY" \\
-d '{
"model": "minimax-m2.5",
"messages": [
{
"role": "user",
"content": "帮我写一段模型上架介绍"
}
],
"temperature": 0.7,
"stream": false
}'`,
pythonExample: `import requests
url = "https://api.kboss.example.com/v2/chat/completions"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer $KBOSS_API_KEY"
}
data = {
"model": "minimax-m2.5",
"messages": [{"role": "user", "content": "Hello!"}],
"stream": False
}
response = requests.post(url, headers=headers, json=data)
print(response.json())`
}
},
computed: {
apiUrlText() {
const curlUrl = this.getUrlFromCurl(this.apiDoc.curl_code)
const url = this.apiDoc.api_url || curlUrl
return url ? `POST ${url}` : '接口地址以后端返回为准'
},
heroDescription() {
const modelName = this.apiDoc.model_name || '当前模型'
return `${modelName} 接口调用示例,包含 curl 与 Python 两种接入方式。`
}
},
created() {
this.fetchApiDocument()
},
watch: {
'$route.query.id'() {
this.fetchApiDocument()
}
},
methods: {
// 通过路由传入的 id 获取模型 API 文档数据。
async fetchApiDocument() {
const id = this.$route.query.id || this.$route.query.model_id
if (!id) {
this.errorMessage = '缺少模型ID无法获取 API 文档'
return
}
this.loading = true
this.errorMessage = ''
try {
const res = await reqModelApiDocument({ id })
if (res && res.status && res.data) {
this.apiDoc = {
...this.apiDoc,
...res.data,
model_name: res.data.model_name || this.apiDoc.model_name
}
return
}
this.errorMessage = (res && res.msg) || 'API 文档数据获取失败'
} catch (error) {
console.error('[API文档] 获取模型 API 文档失败', error)
this.errorMessage = 'API 文档数据获取失败,请稍后重试'
} finally {
this.loading = false
}
},
getUrlFromCurl(curlCode) {
if (!curlCode) return ''
const match = String(curlCode).match(/https?:\/\/[^\s\\]+/)
return match ? match[0] : ''
},
goBack() {
if (this.$route.query.from === 'tokenMarket') {
if (this.$route.query.single === '1') {
this.$router.push({ path: '/tokenMarket', query: { category: 'TOKEN市集', single: '1' } })
return
}
this.$router.push({ path: '/product', query: { category: 'TOKEN市集' } })
return
}
this.$router.back()
}
}
}
</script>
<style lang="less" scoped>
.api-doc-page {
height: 100vh;
color: #1f2d3d;
background: #f6f8fb;
overflow-y: auto;
overflow-x: hidden;
}
.doc-nav {
display: flex;
align-items: center;
height: 48px;
padding: 0 28px;
color: #667085;
background: #ffffff;
border-bottom: 1px solid #edf1f7;
button {
padding: 0;
margin-right: 16px;
color: #667085;
cursor: pointer;
background: transparent;
border: none;
}
}
.doc-container {
width: 920px;
margin: 28px auto 0;
}
.doc-alert {
margin-bottom: 18px;
}
.doc-hero,
.doc-section {
padding: 24px;
margin-bottom: 18px;
background: #ffffff;
border: 1px solid #edf1f7;
border-radius: 12px;
}
.doc-hero {
h1 {
margin: 0 0 10px;
font-size: 28px;
}
p {
margin: 0 0 18px;
color: #667085;
}
}
.quick-tabs {
display: flex;
flex-wrap: wrap;
gap: 10px;
span {
padding: 6px 12px;
color: #2f6bff;
background: #eef4ff;
border-radius: 999px;
font-size: 13px;
}
}
.doc-section {
h2 {
margin: 0 0 16px;
padding-left: 10px;
color: #1f2d3d;
font-size: 18px;
border-left: 3px solid #2f6bff;
}
p {
color: #667085;
line-height: 1.8;
}
}
pre {
margin: 0;
padding: 16px;
color: #e6edf3;
overflow-x: auto;
background: #1f2329;
border-radius: 8px;
line-height: 1.7;
}
code {
font-family: Consolas, Monaco, monospace;
font-size: 13px;
}
.doc-footer {
padding: 32px 0;
color: #98a2b3;
text-align: center;
font-size: 12px;
}
</style>