feat: OAuth 账户管理、维护调度、端点健康检查增强及前端优化

- 新增 OAuth 账户管理对话框和提供商详情抽屉中的 OAuth 信息展示
- 新增维护调度器(maintenance_scheduler)支持定时清理和健康检查
- 增强端点健康检查器,支持更多检测策略
- 重构 codex 服务为 metadata_collectors 模块
- 优化 OpenAI CLI normalizer 代码结构
- 前端: 改进使用量表格、统计图表、指南页面和异步任务管理
- 扩展多个数据库字符串列为 TEXT 类型
- 新增倒计时 composable 和 provider OAuth API 端点
This commit is contained in:
fawney19
2026-02-04 23:59:45 +08:00
parent 24c9105628
commit 4d6e7c094f
64 changed files with 3885 additions and 930 deletions

View File

@@ -247,7 +247,10 @@
class="mb-6 text-3xl sm:text-5xl md:text-7xl font-bold text-[#191919] dark:text-white leading-tight transition-all duration-700"
:style="getTitleStyle(SECTIONS.HOME)"
>
欢迎使用 <span class="text-primary typewriter">{{ aetherText }}<span class="cursor" :class="{ 'cursor-hidden': !showCursor }">_</span></span>
欢迎使用 <span class="text-primary typewriter">{{ aetherText }}<span
class="cursor"
:class="{ 'cursor-hidden': !showCursor }"
>_</span></span>
</h1>
<p
class="mb-8 text-base sm:text-lg md:text-xl text-[#666663] dark:text-[#c9c3b4] max-w-2xl mx-auto transition-all duration-700"
@@ -568,7 +571,7 @@ const aetherText = ref('')
const showCursor = ref(true)
const typewriterFullText = 'Aether'
let typewriterTimer: ReturnType<typeof setTimeout> | null = null
let hasTypewriterStarted = ref(false)
const hasTypewriterStarted = ref(false)
const startTypewriter = () => {
if (hasTypewriterStarted.value) return

View File

@@ -88,12 +88,17 @@ const systemSettings = [
格式转换
</h2>
<div :class="[panelClasses.section, 'p-5']">
<div
class="p-5"
:class="[panelClasses.section]"
>
<div class="flex items-center gap-3 mb-4">
<div class="p-2 rounded-lg bg-purple-500/10">
<Shuffle class="h-5 w-5 text-purple-500" />
</div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">什么是格式转换</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
什么是格式转换
</h3>
</div>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mb-4">
@@ -112,21 +117,30 @@ const systemSettings = [
<ArrowRight class="h-4 w-4 text-[#999]" />
<span :class="panelClasses.badgeGreen">{{ example.to }}</span>
</div>
<p class="text-xs text-[#666663] dark:text-[#a3a094]">{{ example.description }}</p>
<p class="text-xs text-[#666663] dark:text-[#a3a094]">
{{ example.description }}
</p>
</div>
</div>
</div>
<!-- 如何启用 -->
<div :class="[panelClasses.section, 'p-5 space-y-4']">
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">如何启用格式转换</h3>
<div
class="p-5 space-y-4"
:class="[panelClasses.section]"
>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
如何启用格式转换
</h3>
<div class="flex items-start gap-4">
<div class="w-8 h-8 rounded-full bg-[#cc785c] flex items-center justify-center text-white font-bold text-sm flex-shrink-0">
1
</div>
<div>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">开启系统设置</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
开启系统设置
</p>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mt-1">
系统设置中开启 <code class="text-xs bg-[#f5f5f0] dark:bg-[#1f1d1a] px-1.5 py-0.5 rounded">ENABLE_API_FORMAT_CONVERSION</code>
</p>
@@ -138,7 +152,9 @@ const systemSettings = [
2
</div>
<div>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">配置端点</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
配置端点
</p>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mt-1">
在端点配置中启用格式接受配置并选择接受的入站格式
</p>
@@ -150,7 +166,9 @@ const systemSettings = [
3
</div>
<div>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">使用</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
使用
</p>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mt-1">
用户现在可以用 OpenAI SDK 调用配置在 Claude 格式端点上的模型
</p>
@@ -158,11 +176,16 @@ const systemSettings = [
</div>
</div>
<div :class="[panelClasses.section, 'p-4']">
<div
class="p-4"
:class="[panelClasses.section]"
>
<div class="flex items-start gap-3">
<Info class="h-5 w-5 text-blue-500 flex-shrink-0 mt-0.5" />
<div class="text-sm text-[#666663] dark:text-[#a3a094]">
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">注意事项</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
注意事项
</p>
<p class="mt-1">
格式转换会增加少量延迟通常 &lt;10ms部分特有功能 Claude thinkingOpenAI function calling
可能无法完美转换建议在实际场景中测试
@@ -178,25 +201,37 @@ const systemSettings = [
请求头规则
</h2>
<div :class="[panelClasses.section, 'p-5']">
<div
class="p-5"
:class="[panelClasses.section]"
>
<div class="flex items-center gap-3 mb-4">
<div class="p-2 rounded-lg bg-green-500/10">
<FileCode class="h-5 w-5 text-green-500" />
</div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">什么是请求头规则</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
什么是请求头规则
</h3>
</div>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mb-4">
请求头规则允许你在转发请求时修改 HTTP 请求头可以添加修改或删除特定的请求头
</p>
<div :class="[panelClasses.section, 'overflow-hidden']">
<div
class="overflow-hidden"
:class="[panelClasses.section]"
>
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-[#e5e4df] dark:border-[rgba(227,224,211,0.12)] bg-[#fafaf7]/50 dark:bg-[#1f1d1a]/50">
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">类型</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">说明</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
类型
</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
说明
</th>
</tr>
</thead>
<tbody>
@@ -218,11 +253,16 @@ const systemSettings = [
</div>
</div>
<div :class="[panelClasses.section, 'p-4']">
<div
class="p-4"
:class="[panelClasses.section]"
>
<div class="flex items-start gap-3">
<Info class="h-5 w-5 text-blue-500 flex-shrink-0 mt-0.5" />
<div class="text-sm text-[#666663] dark:text-[#a3a094]">
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">使用场景</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
使用场景
</p>
<ul class="mt-1 space-y-1">
<li> 添加额外的认证信息 API 版本号</li>
<li> 添加跟踪标记如请求 ID来源标识</li>
@@ -239,12 +279,17 @@ const systemSettings = [
代理设置
</h2>
<div :class="[panelClasses.section, 'p-5']">
<div
class="p-5"
:class="[panelClasses.section]"
>
<div class="flex items-center gap-3 mb-4">
<div class="p-2 rounded-lg bg-blue-500/10">
<Globe class="h-5 w-5 text-blue-500" />
</div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">HTTP 代理</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
HTTP 代理
</h3>
</div>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mb-4">
@@ -253,14 +298,18 @@ const systemSettings = [
<div class="space-y-3">
<div class="p-4 rounded-lg bg-[#f5f5f0]/50 dark:bg-[#1f1d1a]/50">
<h4 class="font-medium text-[#262624] dark:text-[#f1ead8]">端点级代理</h4>
<h4 class="font-medium text-[#262624] dark:text-[#f1ead8]">
端点级代理
</h4>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mt-1">
在端点配置中填写代理地址格式如 <code class="text-xs bg-[#f5f5f0] dark:bg-[#1f1d1a] px-1.5 py-0.5 rounded">http://proxy:8080</code>
</p>
</div>
<div class="p-4 rounded-lg bg-[#f5f5f0]/50 dark:bg-[#1f1d1a]/50">
<h4 class="font-medium text-[#262624] dark:text-[#f1ead8]">全局代理</h4>
<h4 class="font-medium text-[#262624] dark:text-[#f1ead8]">
全局代理
</h4>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mt-1">
也可以通过环境变量 <code class="text-xs bg-[#f5f5f0] dark:bg-[#1f1d1a] px-1.5 py-0.5 rounded">HTTP_PROXY</code> 设置全局代理
</p>
@@ -283,11 +332,14 @@ const systemSettings = [
<div
v-for="category in systemSettings"
:key="category.category"
:class="[panelClasses.section, 'p-4']"
class="p-4"
:class="[panelClasses.section]"
>
<div class="flex items-center gap-2 mb-3">
<Settings class="h-4 w-4 text-[#cc785c]" />
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">{{ category.category }}</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
{{ category.category }}
</h3>
</div>
<ul class="space-y-2">
<li
@@ -309,12 +361,17 @@ const systemSettings = [
健康监控
</h2>
<div :class="[panelClasses.section, 'p-5']">
<div
class="p-5"
:class="[panelClasses.section]"
>
<div class="flex items-center gap-3 mb-4">
<div class="p-2 rounded-lg bg-green-500/10">
<Shield class="h-5 w-5 text-green-500" />
</div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">端点健康检查</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
端点健康检查
</h3>
</div>
<ul class="space-y-3 text-sm text-[#666663] dark:text-[#a3a094]">
@@ -337,11 +394,16 @@ const systemSettings = [
</ul>
</div>
<div :class="[panelClasses.section, 'p-4']">
<div
class="p-4"
:class="[panelClasses.section]"
>
<div class="flex items-start gap-3">
<AlertTriangle class="h-5 w-5 text-yellow-500 flex-shrink-0 mt-0.5" />
<div class="text-sm text-[#666663] dark:text-[#a3a094]">
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">端点显示不健康</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
端点显示不健康
</p>
<p class="mt-1">
检查1) API URL 是否正确2) API Key 是否有效3) 网络是否可达4) 是否需要配置代理
</p>
@@ -354,11 +416,16 @@ const systemSettings = [
<section class="pt-4">
<RouterLink
to="/guide/faq"
:class="[panelClasses.section, panelClasses.cardHover, 'p-4 flex items-center gap-3 group']"
class="p-4 flex items-center gap-3 group"
:class="[panelClasses.section, panelClasses.cardHover]"
>
<div class="flex-1">
<div class="font-medium text-[#262624] dark:text-[#f1ead8]">常见问题</div>
<div class="text-sm text-[#666663] dark:text-[#a3a094]">查看使用中的常见问题和解答</div>
<div class="font-medium text-[#262624] dark:text-[#f1ead8]">
常见问题
</div>
<div class="text-sm text-[#666663] dark:text-[#a3a094]">
查看使用中的常见问题和解答
</div>
</div>
<ArrowRight class="h-5 w-5 text-[#999] group-hover:text-[#cc785c] transition-colors" />
</RouterLink>

View File

@@ -81,7 +81,10 @@ function toggleAll() {
</div>
<!-- 搜索栏 -->
<div :class="[panelClasses.section, 'p-4']">
<div
class="p-4"
:class="[panelClasses.section]"
>
<div class="flex items-center gap-3">
<Search class="h-5 w-5 text-[#999]" />
<input
@@ -89,7 +92,7 @@ function toggleAll() {
type="text"
placeholder="搜索问题..."
class="flex-1 bg-transparent border-none outline-none text-[#262624] dark:text-[#f1ead8] placeholder:text-[#999]"
/>
>
<button
v-if="filteredFaqs.length > 0"
class="text-sm text-[#cc785c] hover:underline"
@@ -101,7 +104,10 @@ function toggleAll() {
</div>
<!-- FAQ 列表 -->
<div v-if="filteredFaqs.length > 0" class="space-y-6">
<div
v-if="filteredFaqs.length > 0"
class="space-y-6"
>
<div
v-for="category in Object.keys(faqsByCategory)"
:key="category"
@@ -116,7 +122,8 @@ function toggleAll() {
<div
v-for="faq in faqsByCategory[category]"
:key="faq.id"
:class="[panelClasses.section, 'overflow-hidden']"
class="overflow-hidden"
:class="[panelClasses.section]"
>
<button
class="w-full px-4 py-3 flex items-center justify-between text-left hover:bg-[#f5f5f0]/50 dark:hover:bg-[#1f1d1a]/50 transition-colors"
@@ -144,7 +151,8 @@ function toggleAll() {
<!-- 无结果 -->
<div
v-else
:class="[panelClasses.section, 'p-8 text-center']"
class="p-8 text-center"
:class="[panelClasses.section]"
>
<HelpCircle class="h-12 w-12 text-[#999] mx-auto mb-4" />
<p class="text-[#666663] dark:text-[#a3a094]">
@@ -163,11 +171,16 @@ function toggleAll() {
href="https://github.com/your-repo/aether"
target="_blank"
rel="noopener noreferrer"
:class="[panelClasses.section, panelClasses.cardHover, 'p-4 flex items-center gap-3 group']"
class="p-4 flex items-center gap-3 group"
:class="[panelClasses.section, panelClasses.cardHover]"
>
<div class="p-2 rounded-lg bg-gray-500/10">
<svg class="h-5 w-5" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
<svg
class="h-5 w-5"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
</svg>
</div>
<div class="flex-1">
@@ -181,11 +194,18 @@ function toggleAll() {
href="https://github.com/your-repo/aether/discussions"
target="_blank"
rel="noopener noreferrer"
:class="[panelClasses.section, panelClasses.cardHover, 'p-4 flex items-center gap-3 group']"
class="p-4 flex items-center gap-3 group"
:class="[panelClasses.section, panelClasses.cardHover]"
>
<div class="p-2 rounded-lg bg-blue-500/10">
<svg class="h-5 w-5 text-blue-500" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
<svg
class="h-5 w-5 text-blue-500"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
>
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
</svg>
</div>
<div class="flex-1">

View File

@@ -164,7 +164,7 @@
type="text"
class="w-full px-3 py-2 text-sm rounded-lg border border-[#e5e4df] dark:border-[rgba(227,224,211,0.12)] bg-white dark:bg-[#1f1d1a] text-[#191919] dark:text-white placeholder-[#91918d] focus:outline-none focus:ring-2 focus:ring-[#cc785c]/30"
placeholder="https://your-aether.com"
/>
>
<p class="mt-1.5 text-xs text-[#91918d]">
代码示例将使用此 URL
</p>
@@ -176,7 +176,10 @@
<main class="flex-1 min-w-0">
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8 md:py-12">
<RouterView v-slot="{ Component }">
<component :is="Component" :base-url="baseUrl" />
<component
:is="Component"
:base-url="baseUrl"
/>
</RouterView>
</div>
</main>

View File

@@ -50,12 +50,17 @@ const lbIcons = {
什么是模型
</h2>
<div :class="[panelClasses.section, 'p-5']">
<div
class="p-5"
:class="[panelClasses.section]"
>
<div class="flex items-center gap-3 mb-4">
<div class="p-2 rounded-lg bg-purple-500/10">
<Layers class="h-5 w-5 text-purple-500" />
</div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">模型 (Model)</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
模型 (Model)
</h3>
</div>
<ul class="space-y-3 text-sm text-[#666663] dark:text-[#a3a094]">
@@ -78,11 +83,16 @@ const lbIcons = {
</ul>
</div>
<div :class="[panelClasses.section, 'p-4']">
<div
class="p-4"
:class="[panelClasses.section]"
>
<div class="flex items-start gap-3">
<Info class="h-5 w-5 text-blue-500 flex-shrink-0 mt-0.5" />
<div class="text-sm text-[#666663] dark:text-[#a3a094]">
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">示例场景</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
示例场景
</p>
<p class="mt-1">
用户请求模型 <code class="text-xs bg-[#f5f5f0] dark:bg-[#1f1d1a] px-1.5 py-0.5 rounded">gpt-4</code>
你可以配置它同时使用 OpenAI 官方端点和某个代理端点
@@ -99,13 +109,18 @@ const lbIcons = {
创建模型
</h2>
<div :class="[panelClasses.section, 'p-5 space-y-4']">
<div
class="p-5 space-y-4"
:class="[panelClasses.section]"
>
<div class="flex items-start gap-4">
<div class="w-8 h-8 rounded-full bg-[#cc785c] flex items-center justify-center text-white font-bold text-sm flex-shrink-0">
1
</div>
<div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">进入模型管理页面</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
进入模型管理页面
</h3>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mt-1">
在管理后台左侧菜单点击模型管理
</p>
@@ -117,7 +132,9 @@ const lbIcons = {
2
</div>
<div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">添加模型</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
添加模型
</h3>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mt-1">
点击添加模型填写模型名称这是用户调用时使用的名称
</p>
@@ -129,7 +146,9 @@ const lbIcons = {
3
</div>
<div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">关联端点</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
关联端点
</h3>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mt-1">
选择该模型要使用的端点可以选择多个如果端点的模型名与你定义的不同需要设置目标模型名映射
</p>
@@ -141,7 +160,9 @@ const lbIcons = {
4
</div>
<div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">配置负载均衡</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
配置负载均衡
</h3>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mt-1">
如果选择了多个端点可以配置负载均衡策略
</p>
@@ -156,14 +177,23 @@ const lbIcons = {
配置字段说明
</h2>
<div :class="[panelClasses.section, 'overflow-hidden']">
<div
class="overflow-hidden"
:class="[panelClasses.section]"
>
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-[#e5e4df] dark:border-[rgba(227,224,211,0.12)] bg-[#fafaf7]/50 dark:bg-[#1f1d1a]/50">
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">字段</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">说明</th>
<th class="px-4 py-3 text-center font-medium text-[#666663] dark:text-[#a3a094]">必填</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
字段
</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
说明
</th>
<th class="px-4 py-3 text-center font-medium text-[#666663] dark:text-[#a3a094]">
必填
</th>
</tr>
</thead>
<tbody>
@@ -179,8 +209,14 @@ const lbIcons = {
{{ field.description }}
</td>
<td class="px-4 py-3 text-center">
<span v-if="field.required" :class="panelClasses.badgeGreen">必填</span>
<span v-else class="text-[#999]">可选</span>
<span
v-if="field.required"
:class="panelClasses.badgeGreen"
>必填</span>
<span
v-else
class="text-[#999]"
>可选</span>
</td>
</tr>
</tbody>
@@ -202,26 +238,36 @@ const lbIcons = {
<div
v-for="lb in loadBalanceModes"
:key="lb.mode"
:class="[panelClasses.section, 'p-4']"
class="p-4"
:class="[panelClasses.section]"
>
<div class="flex items-center gap-3 mb-2">
<component
:is="lbIcons[lb.mode as keyof typeof lbIcons] || Shuffle"
class="h-5 w-5 text-[#cc785c]"
/>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">{{ lb.name }}</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
{{ lb.name }}
</h3>
</div>
<p class="text-sm text-[#666663] dark:text-[#a3a094]">{{ lb.description }}</p>
<p class="text-sm text-[#666663] dark:text-[#a3a094]">
{{ lb.description }}
</p>
</div>
</div>
<div :class="[panelClasses.section, 'p-4']">
<div
class="p-4"
:class="[panelClasses.section]"
>
<div class="flex items-start gap-3">
<Info class="h-5 w-5 text-blue-500 flex-shrink-0 mt-0.5" />
<div class="text-sm text-[#666663] dark:text-[#a3a094]">
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">推荐配置</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
推荐配置
</p>
<p class="mt-1">
<strong>主备切换场景</strong>使用优先级模式将官方端点设为高优先级代理端点设为低优先级<br />
<strong>主备切换场景</strong>使用优先级模式将官方端点设为高优先级代理端点设为低优先级<br>
<strong>分摊负载场景</strong>使用轮询加权模式将多个同质端点平均分配请求
</p>
</div>
@@ -235,7 +281,10 @@ const lbIcons = {
模型名映射
</h2>
<div :class="[panelClasses.section, 'p-5']">
<div
class="p-5"
:class="[panelClasses.section]"
>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mb-4">
有时候你希望用户调用的模型名与实际发给端点的模型名不同例如
</p>
@@ -278,7 +327,10 @@ const lbIcons = {
模型别名
</h2>
<div :class="[panelClasses.section, 'p-5']">
<div
class="p-5"
:class="[panelClasses.section]"
>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mb-4">
别名让用户可以用多个名称访问同一个模型适用于
</p>
@@ -304,11 +356,16 @@ const lbIcons = {
<section class="pt-4">
<RouterLink
to="/guide/user-key"
:class="[panelClasses.section, panelClasses.cardHover, 'p-4 flex items-center gap-3 group']"
class="p-4 flex items-center gap-3 group"
:class="[panelClasses.section, panelClasses.cardHover]"
>
<div class="flex-1">
<div class="font-medium text-[#262624] dark:text-[#f1ead8]">下一步用户与密钥</div>
<div class="text-sm text-[#666663] dark:text-[#a3a094]">管理用户和 API Key</div>
<div class="font-medium text-[#262624] dark:text-[#f1ead8]">
下一步用户与密钥
</div>
<div class="text-sm text-[#666663] dark:text-[#a3a094]">
管理用户和 API Key
</div>
</div>
<ArrowRight class="h-5 w-5 text-[#999] group-hover:text-[#cc785c] transition-colors" />
</RouterLink>

View File

@@ -61,16 +61,16 @@ const conceptIconColors = {
<div
v-for="concept in coreConcepts"
:key="concept.name"
class="p-4 rounded-xl border-2 transition-all"
:class="[
'p-4 rounded-xl border-2 transition-all',
conceptColors[concept.color as keyof typeof conceptColors]
]"
>
<div class="flex items-start gap-3">
<component
:is="conceptIcons[concept.color as keyof typeof conceptIcons]"
class="h-6 w-6 flex-shrink-0 mt-0.5"
:class="[
'h-6 w-6 flex-shrink-0 mt-0.5',
conceptIconColors[concept.color as keyof typeof conceptIconColors]
]"
/>
@@ -87,7 +87,10 @@ const conceptIconColors = {
</div>
<!-- 关系图 -->
<div :class="[panelClasses.section, 'p-6 mt-6']">
<div
class="p-6 mt-6"
:class="[panelClasses.section]"
>
<h3 class="text-sm font-medium text-[#666663] dark:text-[#a3a094] mb-4">
它们之间的关系
</h3>
@@ -134,7 +137,8 @@ const conceptIconColors = {
<div
v-for="step in configSteps"
:key="step.step"
:class="[panelClasses.section, 'p-4 relative']"
class="p-4 relative"
:class="[panelClasses.section]"
>
<div class="absolute -top-3 -left-2 w-8 h-8 rounded-full bg-[#cc785c] flex items-center justify-center text-white font-bold text-sm">
{{ step.step }}
@@ -160,15 +164,26 @@ const conceptIconColors = {
Aether 支持多种 API 格式可以作为不同客户端的统一入口
</p>
<div :class="[panelClasses.section, 'overflow-hidden']">
<div
class="overflow-hidden"
:class="[panelClasses.section]"
>
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-[#e5e4df] dark:border-[rgba(227,224,211,0.12)] bg-[#fafaf7]/50 dark:bg-[#1f1d1a]/50">
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">格式</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">端点</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">认证方式</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">常用客户端</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
格式
</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
端点
</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
认证方式
</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
常用客户端
</th>
</tr>
</thead>
<tbody>
@@ -204,36 +219,51 @@ const conceptIconColors = {
<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
<RouterLink
to="/guide/provider"
:class="[panelClasses.section, panelClasses.cardHover, 'p-4 flex items-center gap-3 group']"
class="p-4 flex items-center gap-3 group"
:class="[panelClasses.section, panelClasses.cardHover]"
>
<Server class="h-5 w-5 text-[#cc785c]" />
<div class="flex-1">
<div class="font-medium text-[#262624] dark:text-[#f1ead8]">供应商管理</div>
<div class="text-sm text-[#666663] dark:text-[#a3a094]">添加和配置 API 供应商</div>
<div class="font-medium text-[#262624] dark:text-[#f1ead8]">
供应商管理
</div>
<div class="text-sm text-[#666663] dark:text-[#a3a094]">
添加和配置 API 供应商
</div>
</div>
<ArrowRight class="h-5 w-5 text-[#999] group-hover:text-[#cc785c] transition-colors" />
</RouterLink>
<RouterLink
to="/guide/model"
:class="[panelClasses.section, panelClasses.cardHover, 'p-4 flex items-center gap-3 group']"
class="p-4 flex items-center gap-3 group"
:class="[panelClasses.section, panelClasses.cardHover]"
>
<Layers class="h-5 w-5 text-[#cc785c]" />
<div class="flex-1">
<div class="font-medium text-[#262624] dark:text-[#f1ead8]">模型管理</div>
<div class="text-sm text-[#666663] dark:text-[#a3a094]">配置模型和负载均衡</div>
<div class="font-medium text-[#262624] dark:text-[#f1ead8]">
模型管理
</div>
<div class="text-sm text-[#666663] dark:text-[#a3a094]">
配置模型和负载均衡
</div>
</div>
<ArrowRight class="h-5 w-5 text-[#999] group-hover:text-[#cc785c] transition-colors" />
</RouterLink>
<RouterLink
to="/guide/user-key"
:class="[panelClasses.section, panelClasses.cardHover, 'p-4 flex items-center gap-3 group']"
class="p-4 flex items-center gap-3 group"
:class="[panelClasses.section, panelClasses.cardHover]"
>
<Key class="h-5 w-5 text-[#cc785c]" />
<div class="flex-1">
<div class="font-medium text-[#262624] dark:text-[#f1ead8]">用户与密钥</div>
<div class="text-sm text-[#666663] dark:text-[#a3a094]">管理用户和 API Key</div>
<div class="font-medium text-[#262624] dark:text-[#f1ead8]">
用户与密钥
</div>
<div class="text-sm text-[#666663] dark:text-[#a3a094]">
管理用户和 API Key
</div>
</div>
<ArrowRight class="h-5 w-5 text-[#999] group-hover:text-[#cc785c] transition-colors" />
</RouterLink>

View File

@@ -84,12 +84,17 @@ const providerExamples = [
</h2>
<div class="grid gap-4 md:grid-cols-2">
<div :class="[panelClasses.section, 'p-5']">
<div
class="p-5"
:class="[panelClasses.section]"
>
<div class="flex items-center gap-3 mb-3">
<div class="p-2 rounded-lg bg-blue-500/10">
<Server class="h-5 w-5 text-blue-500" />
</div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">供应商 (Provider)</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
供应商 (Provider)
</h3>
</div>
<ul class="space-y-2 text-sm text-[#666663] dark:text-[#a3a094]">
<li class="flex items-start gap-2">
@@ -107,12 +112,17 @@ const providerExamples = [
</ul>
</div>
<div :class="[panelClasses.section, 'p-5']">
<div
class="p-5"
:class="[panelClasses.section]"
>
<div class="flex items-center gap-3 mb-3">
<div class="p-2 rounded-lg bg-green-500/10">
<Settings class="h-5 w-5 text-green-500" />
</div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">端点 (Endpoint)</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
端点 (Endpoint)
</h3>
</div>
<ul class="space-y-2 text-sm text-[#666663] dark:text-[#a3a094]">
<li class="flex items-start gap-2">
@@ -138,13 +148,18 @@ const providerExamples = [
添加供应商
</h2>
<div :class="[panelClasses.section, 'p-5 space-y-4']">
<div
class="p-5 space-y-4"
:class="[panelClasses.section]"
>
<div class="flex items-start gap-4">
<div class="w-8 h-8 rounded-full bg-[#cc785c] flex items-center justify-center text-white font-bold text-sm flex-shrink-0">
1
</div>
<div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">进入供应商管理页面</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
进入供应商管理页面
</h3>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mt-1">
登录管理后台在左侧菜单点击供应商管理
</p>
@@ -156,7 +171,9 @@ const providerExamples = [
2
</div>
<div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">创建供应商</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
创建供应商
</h3>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mt-1">
点击添加供应商按钮填写供应商名称 OpenAIAnthropic
</p>
@@ -168,7 +185,9 @@ const providerExamples = [
3
</div>
<div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">添加端点</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
添加端点
</h3>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mt-1">
在供应商下点击添加端点填写 API URL密钥等配置
</p>
@@ -183,14 +202,23 @@ const providerExamples = [
端点配置字段
</h2>
<div :class="[panelClasses.section, 'overflow-hidden']">
<div
class="overflow-hidden"
:class="[panelClasses.section]"
>
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-[#e5e4df] dark:border-[rgba(227,224,211,0.12)] bg-[#fafaf7]/50 dark:bg-[#1f1d1a]/50">
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">字段</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">说明</th>
<th class="px-4 py-3 text-center font-medium text-[#666663] dark:text-[#a3a094]">必填</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
字段
</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
说明
</th>
<th class="px-4 py-3 text-center font-medium text-[#666663] dark:text-[#a3a094]">
必填
</th>
</tr>
</thead>
<tbody>
@@ -206,8 +234,14 @@ const providerExamples = [
{{ field.description }}
</td>
<td class="px-4 py-3 text-center">
<span v-if="field.required" :class="panelClasses.badgeGreen">必填</span>
<span v-else class="text-[#999]">可选</span>
<span
v-if="field.required"
:class="panelClasses.badgeGreen"
>必填</span>
<span
v-else
class="text-[#999]"
>可选</span>
</td>
</tr>
</tbody>
@@ -222,11 +256,16 @@ const providerExamples = [
API 格式选择
</h2>
<div :class="[panelClasses.section, 'p-4']">
<div
class="p-4"
:class="[panelClasses.section]"
>
<div class="flex items-start gap-3">
<Info class="h-5 w-5 text-blue-500 flex-shrink-0 mt-0.5" />
<div class="text-sm text-[#666663] dark:text-[#a3a094]">
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">如何选择正确的 API 格式</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
如何选择正确的 API 格式
</p>
<p class="mt-1">
根据目标 API 服务的实际格式选择大多数第三方 API 代理 OpenRouter都兼容 OpenAI 格式
如果不确定可以先尝试 OpenAI 格式
@@ -235,14 +274,23 @@ const providerExamples = [
</div>
</div>
<div :class="[panelClasses.section, 'overflow-hidden']">
<div
class="overflow-hidden"
:class="[panelClasses.section]"
>
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-[#e5e4df] dark:border-[rgba(227,224,211,0.12)] bg-[#fafaf7]/50 dark:bg-[#1f1d1a]/50">
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">格式</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">端点路径</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">认证方式</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
格式
</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
端点路径
</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
认证方式
</th>
</tr>
</thead>
<tbody>
@@ -277,7 +325,8 @@ const providerExamples = [
<div
v-for="example in providerExamples"
:key="example.name"
:class="[panelClasses.section, 'p-4']"
class="p-4"
:class="[panelClasses.section]"
>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
{{ example.name }}
@@ -292,7 +341,9 @@ const providerExamples = [
<span :class="panelClasses.badgeBlue">{{ example.format }}</span>
</div>
</div>
<p class="mt-2 text-xs text-[#999]">{{ example.note }}</p>
<p class="mt-2 text-xs text-[#999]">
{{ example.note }}
</p>
</div>
</div>
</section>
@@ -303,11 +354,16 @@ const providerExamples = [
注意事项
</h2>
<div :class="[panelClasses.section, 'p-4 space-y-3']">
<div
class="p-4 space-y-3"
:class="[panelClasses.section]"
>
<div class="flex items-start gap-3">
<AlertTriangle class="h-5 w-5 text-yellow-500 flex-shrink-0 mt-0.5" />
<div class="text-sm">
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">API Key 安全</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
API Key 安全
</p>
<p class="text-[#666663] dark:text-[#a3a094] mt-1">
端点的 API Key 会被加密存储但仍建议使用子账号或限定范围的 Key而非主账号 Key
</p>
@@ -317,7 +373,9 @@ const providerExamples = [
<div class="flex items-start gap-3">
<AlertTriangle class="h-5 w-5 text-yellow-500 flex-shrink-0 mt-0.5" />
<div class="text-sm">
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">测试端点</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
测试端点
</p>
<p class="text-[#666663] dark:text-[#a3a094] mt-1">
添加端点后可以在健康监控页面测试连通性如果显示不健康请检查 URL Key 是否正确
</p>
@@ -330,11 +388,16 @@ const providerExamples = [
<section class="pt-4">
<RouterLink
to="/guide/model"
:class="[panelClasses.section, panelClasses.cardHover, 'p-4 flex items-center gap-3 group']"
class="p-4 flex items-center gap-3 group"
:class="[panelClasses.section, panelClasses.cardHover]"
>
<div class="flex-1">
<div class="font-medium text-[#262624] dark:text-[#f1ead8]">下一步模型管理</div>
<div class="text-sm text-[#666663] dark:text-[#a3a094]">配置模型映射和负载均衡</div>
<div class="font-medium text-[#262624] dark:text-[#f1ead8]">
下一步模型管理
</div>
<div class="text-sm text-[#666663] dark:text-[#a3a094]">
配置模型映射和负载均衡
</div>
</div>
<ArrowRight class="h-5 w-5 text-[#999] group-hover:text-[#cc785c] transition-colors" />
</RouterLink>

View File

@@ -65,12 +65,17 @@ const roleComparison = [
</h2>
<div class="grid gap-4 md:grid-cols-2">
<div :class="[panelClasses.section, 'p-5']">
<div
class="p-5"
:class="[panelClasses.section]"
>
<div class="flex items-center gap-3 mb-3">
<div class="p-2 rounded-lg bg-blue-500/10">
<Users class="h-5 w-5 text-blue-500" />
</div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">普通用户</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
普通用户
</h3>
</div>
<ul class="space-y-2 text-sm text-[#666663] dark:text-[#a3a094]">
<li class="flex items-start gap-2">
@@ -88,12 +93,17 @@ const roleComparison = [
</ul>
</div>
<div :class="[panelClasses.section, 'p-5']">
<div
class="p-5"
:class="[panelClasses.section]"
>
<div class="flex items-center gap-3 mb-3">
<div class="p-2 rounded-lg bg-orange-500/10">
<Shield class="h-5 w-5 text-orange-500" />
</div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">管理员</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
管理员
</h3>
</div>
<ul class="space-y-2 text-sm text-[#666663] dark:text-[#a3a094]">
<li class="flex items-start gap-2">
@@ -113,14 +123,23 @@ const roleComparison = [
</div>
<!-- 权限对比表 -->
<div :class="[panelClasses.section, 'overflow-hidden']">
<div
class="overflow-hidden"
:class="[panelClasses.section]"
>
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-[#e5e4df] dark:border-[rgba(227,224,211,0.12)] bg-[#fafaf7]/50 dark:bg-[#1f1d1a]/50">
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">功能</th>
<th class="px-4 py-3 text-center font-medium text-[#666663] dark:text-[#a3a094]">普通用户</th>
<th class="px-4 py-3 text-center font-medium text-[#666663] dark:text-[#a3a094]">管理员</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
功能
</th>
<th class="px-4 py-3 text-center font-medium text-[#666663] dark:text-[#a3a094]">
普通用户
</th>
<th class="px-4 py-3 text-center font-medium text-[#666663] dark:text-[#a3a094]">
管理员
</th>
</tr>
</thead>
<tbody>
@@ -133,12 +152,24 @@ const roleComparison = [
{{ item.feature }}
</td>
<td class="px-4 py-3 text-center">
<Check v-if="item.user" class="h-5 w-5 text-green-500 mx-auto" />
<span v-else class="text-[#999]"></span>
<Check
v-if="item.user"
class="h-5 w-5 text-green-500 mx-auto"
/>
<span
v-else
class="text-[#999]"
></span>
</td>
<td class="px-4 py-3 text-center">
<Check v-if="item.admin" class="h-5 w-5 text-green-500 mx-auto" />
<span v-else class="text-[#999]"></span>
<Check
v-if="item.admin"
class="h-5 w-5 text-green-500 mx-auto"
/>
<span
v-else
class="text-[#999]"
></span>
</td>
</tr>
</tbody>
@@ -153,12 +184,17 @@ const roleComparison = [
API Key 管理
</h2>
<div :class="[panelClasses.section, 'p-5']">
<div
class="p-5"
:class="[panelClasses.section]"
>
<div class="flex items-center gap-3 mb-4">
<div class="p-2 rounded-lg bg-orange-500/10">
<Key class="h-5 w-5 text-orange-500" />
</div>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">什么是 API Key</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
什么是 API Key
</h3>
</div>
<ul class="space-y-3 text-sm text-[#666663] dark:text-[#a3a094]">
@@ -188,14 +224,23 @@ const roleComparison = [
Key 配置选项
</h2>
<div :class="[panelClasses.section, 'overflow-hidden']">
<div
class="overflow-hidden"
:class="[panelClasses.section]"
>
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-[#e5e4df] dark:border-[rgba(227,224,211,0.12)] bg-[#fafaf7]/50 dark:bg-[#1f1d1a]/50">
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">选项</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">说明</th>
<th class="px-4 py-3 text-center font-medium text-[#666663] dark:text-[#a3a094]">必填</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
选项
</th>
<th class="px-4 py-3 text-left font-medium text-[#666663] dark:text-[#a3a094]">
说明
</th>
<th class="px-4 py-3 text-center font-medium text-[#666663] dark:text-[#a3a094]">
必填
</th>
</tr>
</thead>
<tbody>
@@ -211,8 +256,14 @@ const roleComparison = [
{{ field.description }}
</td>
<td class="px-4 py-3 text-center">
<span v-if="field.required" :class="panelClasses.badgeGreen">必填</span>
<span v-else class="text-[#999]">可选</span>
<span
v-if="field.required"
:class="panelClasses.badgeGreen"
>必填</span>
<span
v-else
class="text-[#999]"
>可选</span>
</td>
</tr>
</tbody>
@@ -227,22 +278,31 @@ const roleComparison = [
配额设置
</h2>
<div :class="[panelClasses.section, 'p-5 space-y-4']">
<div
class="p-5 space-y-4"
:class="[panelClasses.section]"
>
<div class="flex items-center gap-3">
<Clock class="h-5 w-5 text-[#cc785c]" />
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">配额类型</h3>
<h3 class="font-semibold text-[#262624] dark:text-[#f1ead8]">
配额类型
</h3>
</div>
<div class="grid gap-4 md:grid-cols-2">
<div class="p-4 rounded-lg bg-[#f5f5f0]/50 dark:bg-[#1f1d1a]/50">
<h4 class="font-medium text-[#262624] dark:text-[#f1ead8]">请求次数配额</h4>
<h4 class="font-medium text-[#262624] dark:text-[#f1ead8]">
请求次数配额
</h4>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mt-1">
限制每日/每月的 API 调用次数超过后请求会被拒绝
</p>
</div>
<div class="p-4 rounded-lg bg-[#f5f5f0]/50 dark:bg-[#1f1d1a]/50">
<h4 class="font-medium text-[#262624] dark:text-[#f1ead8]">Token 用量配额</h4>
<h4 class="font-medium text-[#262624] dark:text-[#f1ead8]">
Token 用量配额
</h4>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mt-1">
限制每日/每月的 Token 消耗量适合控制成本
</p>
@@ -252,7 +312,9 @@ const roleComparison = [
<div class="flex items-start gap-3">
<Info class="h-5 w-5 text-blue-500 flex-shrink-0 mt-0.5" />
<div class="text-sm text-[#666663] dark:text-[#a3a094]">
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">配额继承</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
配额继承
</p>
<p class="mt-1">
可以在用户级别设置默认配额新创建的 Key 会自动继承该配额
也可以在创建 Key 时覆盖默认配额
@@ -268,7 +330,10 @@ const roleComparison = [
模型访问控制
</h2>
<div :class="[panelClasses.section, 'p-5']">
<div
class="p-5"
:class="[panelClasses.section]"
>
<p class="text-sm text-[#666663] dark:text-[#a3a094] mb-4">
通过允许的模型字段可以限制 Key 只能访问特定模型
</p>
@@ -288,7 +353,9 @@ const roleComparison = [
<div class="flex items-start gap-2">
<AlertTriangle class="h-5 w-5 text-yellow-600 dark:text-yellow-400 flex-shrink-0 mt-0.5" />
<div class="text-sm">
<p class="font-medium text-yellow-700 dark:text-yellow-300">使用场景</p>
<p class="font-medium text-yellow-700 dark:text-yellow-300">
使用场景
</p>
<p class="text-yellow-600 dark:text-yellow-400 mt-1">
比如限制免费用户只能使用 gpt-3.5付费用户可以使用 gpt-4
或者为不同项目创建只能访问特定模型的 Key
@@ -305,11 +372,16 @@ const roleComparison = [
安全建议
</h2>
<div :class="[panelClasses.section, 'p-4 space-y-3']">
<div
class="p-4 space-y-3"
:class="[panelClasses.section]"
>
<div class="flex items-start gap-3">
<Shield class="h-5 w-5 text-[#cc785c] flex-shrink-0 mt-0.5" />
<div class="text-sm">
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">设置 Key 有效期</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
设置 Key 有效期
</p>
<p class="text-[#666663] dark:text-[#a3a094] mt-1">
为临时使用的 Key 设置过期时间避免遗忘造成安全风险
</p>
@@ -319,7 +391,9 @@ const roleComparison = [
<div class="flex items-start gap-3">
<Shield class="h-5 w-5 text-[#cc785c] flex-shrink-0 mt-0.5" />
<div class="text-sm">
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">按场景分配 Key</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
按场景分配 Key
</p>
<p class="text-[#666663] dark:text-[#a3a094] mt-1">
为开发测试生产环境分别创建 Key便于追踪和管理
</p>
@@ -329,7 +403,9 @@ const roleComparison = [
<div class="flex items-start gap-3">
<Shield class="h-5 w-5 text-[#cc785c] flex-shrink-0 mt-0.5" />
<div class="text-sm">
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">启用 IP 白名单</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
启用 IP 白名单
</p>
<p class="text-[#666663] dark:text-[#a3a094] mt-1">
对于生产环境的 Key配置 IP 白名单可以防止 Key 泄露后被滥用
</p>
@@ -339,7 +415,9 @@ const roleComparison = [
<div class="flex items-start gap-3">
<Shield class="h-5 w-5 text-[#cc785c] flex-shrink-0 mt-0.5" />
<div class="text-sm">
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">定期审计</p>
<p class="font-medium text-[#262624] dark:text-[#f1ead8]">
定期审计
</p>
<p class="text-[#666663] dark:text-[#a3a094] mt-1">
定期检查用量统计和审计日志发现异常及时禁用相关 Key
</p>
@@ -352,11 +430,16 @@ const roleComparison = [
<section class="pt-4">
<RouterLink
to="/guide/advanced"
:class="[panelClasses.section, panelClasses.cardHover, 'p-4 flex items-center gap-3 group']"
class="p-4 flex items-center gap-3 group"
:class="[panelClasses.section, panelClasses.cardHover]"
>
<div class="flex-1">
<div class="font-medium text-[#262624] dark:text-[#f1ead8]">下一步高级功能</div>
<div class="text-sm text-[#666663] dark:text-[#a3a094]">格式转换请求头规则等高级配置</div>
<div class="font-medium text-[#262624] dark:text-[#f1ead8]">
下一步高级功能
</div>
<div class="text-sm text-[#666663] dark:text-[#a3a094]">
格式转换请求头规则等高级配置
</div>
</div>
<ArrowRight class="h-5 w-5 text-[#999] group-hover:text-[#cc785c] transition-colors" />
</RouterLink>