diff --git a/frontend/src/pages/Channels.tsx b/frontend/src/pages/Channels.tsx index 1cdf6a8..a00d2a8 100644 --- a/frontend/src/pages/Channels.tsx +++ b/frontend/src/pages/Channels.tsx @@ -5,6 +5,7 @@ import { apiClient } from "@/api/client"; import { Channel, ChannelConfig, ChannelModelMapping } from "@/types"; import { Card, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; +import { ButtonGroup } from "@/components/ui/button-group"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select } from "@/components/ui/select"; @@ -49,10 +50,15 @@ const channelTypes = [ ]; const channelWeightOptions = Array.from({ length: 6 }, (_, weight) => ({ - value: String(weight), - label: `权重 ${weight}`, + value: weight, + label: String(weight), })); +const modelEditorModeOptions = [ + { value: "visual", label: "可视化" }, + { value: "json", label: "JSON" }, +] as const; + const createEmptyModelRow = (): ModelRow => ({ id: "", name: "", @@ -1007,7 +1013,9 @@ export function Channels({ createMode = false, editRoute = false }: { createMode const modelCount = (config.models || []).length; const enabledModelCount = (config.models || []).filter((model) => model.enabled !== false).length; const modelSummary = - enabledModelCount === modelCount ? `${modelCount} 个模型` : `${enabledModelCount}/${modelCount} 个模型`; + enabledModelCount === modelCount + ? `${modelCount} 个模型` + : `${enabledModelCount}/${modelCount} 个模型`; const isMenuOpen = openMenu === channel.key; const isEnabled = config.enabled !== false; const isToggling = @@ -1226,21 +1234,19 @@ export function Channels({ createMode = false, editRoute = false }: { createMode
- + className="flex h-10 items-center px-2 gap-1" + buttonClassName="rounded-sm w-8 h-6 data-[state=on]:bg-amber-600 data-[state=on]:text-white" + />

相同模型权重优先,相同权重随机分配。

@@ -1330,7 +1336,9 @@ export function Channels({ createMode = false, editRoute = false }: { createMode />
自动轮换
-

重试时随机切换同渠道其他密钥;关闭后始终重试当前密钥

+

+ 重试时随机切换同渠道其他密钥;关闭后始终重试当前密钥 +

@@ -1351,22 +1359,13 @@ export function Channels({ createMode = false, editRoute = false }: { createMode

- - + - -
- ) + ); })} {filteredData?.length === 0 && searchQuery && ( -
- 未找到匹配的令牌 -
+
未找到匹配的令牌
)} )} - ) + ); } if (isRouteEdit && isLoading && !editingKey) { @@ -533,7 +611,7 @@ export function Tokens({ - ) + ); } // Form View @@ -547,181 +625,190 @@ export function Tokens({ 返回列表
-

{editingKey ? '编辑令牌' : '添加令牌'}

+

{editingKey ? "编辑令牌" : "添加令牌"}

- {/* Token Key Section */} - - -

令牌标识

-

用于 API 认证的唯一标识

-
- setTokenKey(e.target.value)} - placeholder="sk-xxxxxxxxxxxxxxxx" - disabled={!!editingKey} - className="font-mono text-sm" - /> - {!editingKey && ( - - )} -
-
-
- - {editMode === 'form' ? ( - <> - {/* Basic Info */} - - -

基本信息

-
-
- - setFormData({ ...formData, name: e.target.value })} - placeholder="例如:生产环境、测试用户" - /> -
-
-
-
- - {/* Channel Access */} - - -
-
-

渠道访问权限

-

- {selectedChannels.length === 0 ? '允许访问所有渠道' : `已选择 ${selectedChannels.length} 个渠道`} -

-
-
- {availableChannels.length === 0 ? ( -
- -
-

暂无可用渠道

-

请先在渠道管理中添加渠道

-
-
- ) : ( -
- {availableChannels.map((channelKey) => ( - - ))} -
- )} -
-
- - {/* Quota */} - - -

可用额度

-

- 令牌可用的总额度,单位为美元,当已用额度达到总额度时,令牌将无法调用模型。 -

-
- { - const nextValue = e.target.value - if (!INTEGER_QUOTA_PATTERN.test(nextValue)) { - return - } - setQuotaInputValue(nextValue) - setFormData({ ...formData, total_quota: parseQuotaInputValue(nextValue) }) - }} - placeholder="1" - /> -
- {quotaPresets.map((preset) => ( - - ))} -
-
-
-
- - ) : ( + {/* Token Key Section */} -

JSON 配置

-