feat(providers): add provider categorization system

- Add ProviderCategory type with official, cn_official, aggregator, third_party, and custom categories
- Update Provider interface and Rust struct to include optional category field
- Enhance ProviderForm to automatically sync category when selecting presets
- Improve PresetSelector to show category-based styling and hints
- Add category classification to all provider presets
- Support differentiated interactions (e.g., hide API key input for official providers)
- Maintain backward compatibility with existing configurations
This commit is contained in:
Jason
2025-09-11 22:33:55 +08:00
parent 9fbce5d0cf
commit eca9c02147
7 changed files with 80 additions and 13 deletions

View File

@@ -1,9 +1,11 @@
import React from "react";
import { Zap } from "lucide-react";
import { ProviderCategory } from "../../types";
interface Preset {
name: string;
isOfficial?: boolean;
category?: ProviderCategory;
}
interface PresetSelectorProps {
@@ -23,13 +25,13 @@ const PresetSelector: React.FC<PresetSelectorProps> = ({
onCustomClick,
customLabel = "自定义",
}) => {
const getButtonClass = (index: number, isOfficial?: boolean) => {
const getButtonClass = (index: number, isOfficial?: boolean, category?: ProviderCategory) => {
const isSelected = selectedIndex === index;
const baseClass =
"inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-colors";
if (isSelected) {
return isOfficial
return isOfficial || category === "official"
? `${baseClass} bg-amber-500 text-white`
: `${baseClass} bg-blue-500 text-white`;
}
@@ -44,8 +46,8 @@ const PresetSelector: React.FC<PresetSelectorProps> = ({
if (selectedIndex !== null && selectedIndex >= 0) {
const preset = presets[selectedIndex];
return preset?.isOfficial
? "Claude 官方登录,不需要填写 API Key"
return preset?.isOfficial || preset?.category === "official"
? "官方登录,不需要填写 API Key"
: "使用预设配置,只需填写 API Key";
}
@@ -70,10 +72,10 @@ const PresetSelector: React.FC<PresetSelectorProps> = ({
<button
key={index}
type="button"
className={getButtonClass(index, preset.isOfficial)}
className={getButtonClass(index, preset.isOfficial, preset.category)}
onClick={() => onSelectPreset(index)}
>
{preset.isOfficial && <Zap size={14} />}
{(preset.isOfficial || preset.category === "official") && <Zap size={14} />}
{preset.name}
</button>
))}