-
-
Notifications
You must be signed in to change notification settings - Fork 181
Fix #22: 供应商管理列表增加类型筛选和图标显示 #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,9 @@ import type { NextConfig } from "next"; | |
| const nextConfig: NextConfig = { | ||
| output: "standalone", | ||
|
|
||
| // 转译 ESM 模块(@lobehub/icons 需要) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ⚡ 性能影响说明
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 添加 影响:
建议:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 构建性能影响: 建议验证:
可以通过以下方式测试: # 移除 transpilePackages 配置后构建
pnpm build如果构建失败,说明确实需要;如果成功,可以移除此配置。
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ℹ️ 构建性能提示
确认这是必需的:
可以通过 |
||
| transpilePackages: ["@lobehub/icons"], | ||
|
|
||
| // 文件上传大小限制(用于数据库备份导入) | ||
| // Next.js 15 通过 serverActions.bodySizeLimit 统一控制 | ||
| experimental: { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,7 @@ | |
| "@bull-board/api": "^6.14.0", | ||
| "@bull-board/express": "^6.14.0", | ||
| "@hookform/resolvers": "^5.2.2", | ||
| "@lobehub/icons": "^2.43.1", | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📦 依赖包体积警告
替代方案:
建议评估是否值得为 5 个图标引入如此大的依赖。
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❗ 依赖项过重 引入 影响分析:
建议替代方案: 方案 1:使用项目已有的 lucide-react import { Bot, Sparkles, Code2, Diamond, Network } from 'lucide-react';
// 这些图标已经在项目中,无额外成本方案 2:自定义 SVG 图标(最轻量) const ClaudeIcon = () => (
<svg viewBox="0 0 24 24" className="h-3 w-3" fill="currentColor">
<path d="M12 2C6.48..." /> {/* Claude logo path */}
</svg>
);方案 3:使用 CSS + Unicode 字符 <span className="font-bold text-orange-600">C</span> // Claude推荐方案 1,保持项目轻量化的同时满足功能需求。
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 依赖包体积问题: 建议:
可以运行以下命令查看实际打包体积影响: pnpm build
pnpm run analyze # 如果有配置 bundle analyzer
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
考虑替代方案:
建议运行 |
||
| "@radix-ui/react-alert-dialog": "^1.1.15", | ||
| "@radix-ui/react-avatar": "^1.1.10", | ||
| "@radix-ui/react-checkbox": "^1.3.3", | ||
|
|
@@ -35,6 +36,7 @@ | |
| "@radix-ui/react-tabs": "^1.1.13", | ||
| "@radix-ui/react-tooltip": "^1.2.8", | ||
| "@tanstack/react-query": "^5.90.5", | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❗ 重要问题:引入了整个 antd 包 这会显著增加打包体积(antd 未压缩约 2MB+)。根据代码分析,只使用了 建议:
请确认打包体积是否可接受。 |
||
| "antd": "^5.27.6", | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 引入
示例(使用 lucide-react): import { Bot, Sparkles, Code2, Diamond, Network } from "lucide-react";请评估打包体积的影响(运行
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
问题:
建议:
可以运行以下命令检查: pnpm why antd |
||
| "bull": "^4.16.5", | ||
| "class-variance-authority": "^0.7.1", | ||
| "clsx": "^2.1.1", | ||
|
|
||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ import { Badge } from "@/components/ui/badge"; | |
| import { Edit, Globe, Key, RotateCcw, Copy, ServerCog } from "lucide-react"; | ||
| import type { ProviderDisplay } from "@/types/provider"; | ||
| import type { User } from "@/types/user"; | ||
| import { getProviderTypeConfig } from "@/lib/provider-type-utils"; | ||
| import { ProviderForm } from "./forms/provider-form"; | ||
| import { AddProviderDialog } from "./add-provider-dialog"; | ||
| import { Switch } from "@/components/ui/switch"; | ||
|
|
@@ -91,6 +92,10 @@ export function ProviderListItem({ | |
| handleConcurrentPopover, | ||
| } = useProviderEdit(item, canEdit); | ||
|
|
||
| // 获取供应商类型配置 | ||
| const typeConfig = getProviderTypeConfig(item.providerType); | ||
| const TypeIcon = typeConfig.icon; | ||
|
|
||
| // 处理手动解除熔断 | ||
| const handleResetCircuit = () => { | ||
| startResetTransition(async () => { | ||
|
|
@@ -126,9 +131,20 @@ export function ProviderListItem({ | |
| > | ||
| ● | ||
| </span> | ||
| {/* 供应商类型图标 */} | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. UI 增强建议:供应商类型图标的位置很好,但建议添加 Tooltip 组件(来自 Radix UI)来显示类型描述,而不是仅使用 HTML Tooltip 提供更好的用户体验和自定义样式能力: import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<span className={`inline-flex h-5 w-5 items-center justify-center rounded-md ${typeConfig.bgColor}`}>
<TypeIcon className={`h-3 w-3 ${typeConfig.iconColor}`} />
</span>
</TooltipTrigger>
<TooltipContent>
<p>{typeConfig.description}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ UI 实现优秀 图标和标签的布局合理,视觉层次清晰:
小建议: <Tooltip>
<TooltipTrigger asChild>
<span className={`... ${typeConfig.bgColor}`}>
<TypeIcon className={`... ${typeConfig.iconColor}`} />
</span>
</TooltipTrigger>
<TooltipContent>{typeConfig.description}</TooltipContent>
</Tooltip> |
||
| <span | ||
| className={`inline-flex h-5 w-5 items-center justify-center rounded-md ${typeConfig.bgColor}`} | ||
|
Comment on lines
+135
to
+136
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ♿ 可访问性增强建议 建议添加 ARIA 属性以提升屏幕阅读器体验: <span
className={`inline-flex h-5 w-5 items-center justify-center rounded-md ${typeConfig.bgColor}`}
role="img"
>
<TypeIcon className={`h-3 w-3 ${typeConfig.iconColor}`} />
</span>
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 同样的颜色类名拼接问题 这里也存在动态类名拼接的问题( <span
className={cn(
"inline-flex h-5 w-5 items-center justify-center rounded-md",
typeConfig.bgColor
)}
>
<TypeIcon className={cn("h-3 w-3", typeConfig.iconColor)} />
</span> |
||
| title={typeConfig.description} | ||
| > | ||
| <TypeIcon className={`h-3 w-3 ${typeConfig.iconColor}`} /> | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tailwind CSS Purge 风险:动态拼接的 className 可能在生产构建时被 Tailwind 移除。 建议使用 <TypeIcon className={cn("h-3 w-3", typeConfig.iconColor)} />并确保 |
||
| </span> | ||
| <h3 className="text-sm font-semibold text-foreground truncate tracking-tight"> | ||
| {item.name} | ||
| </h3> | ||
| {/* 供应商类型标签 */} | ||
| <Badge variant="outline" className="text-[10px] h-4 px-1.5 font-normal"> | ||
| {typeConfig.label} | ||
| </Badge> | ||
|
Comment on lines
+134
to
+147
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎨 UI 设计建议 类型图标和标签的实现很清晰!一个小优化建议: 可以让 Badge 的颜色与图标颜色保持一致,提升视觉连贯性: <Badge
variant="outline"
className={`text-[10px] h-4 px-1.5 font-normal border-${typeConfig.iconColor.replace('text-', '')} ${typeConfig.bgColor}`}
>
{typeConfig.label}
</Badge>不过当前的实现已经很好了,这只是一个可选优化。 |
||
|
|
||
| {/* 熔断器状态徽章 */} | ||
| {healthStatus?.circuitState === "open" && ( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| "use client"; | ||
| import { useState, useMemo } from "react"; | ||
| import { ProviderList } from "./provider-list"; | ||
| import type { ProviderDisplay } from "@/types/provider"; | ||
| import { ProviderTypeFilter } from "./provider-type-filter"; | ||
| import type { ProviderDisplay, ProviderType } from "@/types/provider"; | ||
| import type { User } from "@/types/user"; | ||
| import type { CurrencyCode } from "@/lib/utils/currency"; | ||
|
|
||
|
|
@@ -28,10 +30,29 @@ export function ProviderManager({ | |
| currencyCode = "USD", | ||
| enableMultiProviderTypes, | ||
| }: ProviderManagerProps) { | ||
| const [typeFilter, setTypeFilter] = useState<ProviderType | "all">("all"); | ||
|
|
||
| // 根据类型筛选供应商 | ||
| const filteredProviders = useMemo(() => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ 良好实践:使用
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ 性能优化做得很好 使用 补充建议:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ 性能优化 - 很好! 使用 如果未来供应商数量非常大(>1000),可以考虑进一步优化:
|
||
| if (typeFilter === "all") { | ||
| return providers; | ||
| } | ||
| return providers.filter((provider) => provider.providerType === typeFilter); | ||
| }, [providers, typeFilter]); | ||
|
Comment on lines
+36
to
+41
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 性能优化得当 使用 可选:如果供应商列表非常大(>1000项),可以考虑添加虚拟滚动(如 |
||
|
|
||
| return ( | ||
| <div className="space-y-4"> | ||
| {/* 筛选条件 */} | ||
| <div className="flex items-center justify-between"> | ||
| <ProviderTypeFilter value={typeFilter} onChange={setTypeFilter} /> | ||
| <div className="text-sm text-muted-foreground"> | ||
| 显示 {filteredProviders.length} / {providers.length} 个供应商 | ||
| </div> | ||
| </div> | ||
|
|
||
| {/* 供应商列表 */} | ||
| <ProviderList | ||
| providers={providers} | ||
| providers={filteredProviders} | ||
| currentUser={currentUser} | ||
| healthStatus={healthStatus} | ||
| currencyCode={currencyCode} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| "use client"; | ||
| import { | ||
| Select, | ||
| SelectContent, | ||
| SelectItem, | ||
| SelectTrigger, | ||
| SelectValue, | ||
| } from "@/components/ui/select"; | ||
| import { Filter } from "lucide-react"; | ||
| import type { ProviderType } from "@/types/provider"; | ||
| import { PROVIDER_TYPE_CONFIG, getAllProviderTypes } from "@/lib/provider-type-utils"; | ||
|
|
||
| interface ProviderTypeFilterProps { | ||
| value: ProviderType | "all"; | ||
| onChange: (value: ProviderType | "all") => void; | ||
| } | ||
|
|
||
| export function ProviderTypeFilter({ value, onChange }: ProviderTypeFilterProps) { | ||
| return ( | ||
| <div className="flex items-center gap-2"> | ||
| <Filter className="h-4 w-4 text-muted-foreground" /> | ||
| <Select value={value} onValueChange={onChange}> | ||
| <SelectTrigger className="w-[200px]"> | ||
| <SelectValue placeholder="筛选供应商类型" /> | ||
| </SelectTrigger> | ||
| <SelectContent> | ||
| <SelectItem value="all">全部供应商</SelectItem> | ||
| {getAllProviderTypes().map((type) => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 潜在问题:
const providerTypes = useMemo(() => getAllProviderTypes(), []);
return (
// ...
{providerTypes.map((type) => {
// ...
})}
);或者将 // provider-type-utils.tsx
export const ALL_PROVIDER_TYPES: ProviderType[] = Object.keys(PROVIDER_TYPE_CONFIG) as ProviderType[]; |
||
| const config = PROVIDER_TYPE_CONFIG[type]; | ||
| const Icon = config.icon; | ||
| return ( | ||
| <SelectItem key={type} value={type}> | ||
| <div className="flex items-center gap-2"> | ||
| <Icon className={`h-3.5 w-3.5 ${config.iconColor}`} /> | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 可访问性改进:建议为每个 SelectItem 添加 <SelectItem
key={type}
value={type}
${config.label} 类型的供应商`}
>
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✨ 样式一致性良好 很好地复用了
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 潜在的颜色类名拼接问题 使用字符串拼接 建议的解决方案:
// 方案 1: 使用 clsx/cn
<Icon className={cn("h-3.5 w-3.5", config.iconColor)} />
// 方案 2: 在 tailwind.config.ts 添加 safelist
safelist: [
'text-orange-600',
'text-purple-600',
'text-blue-600',
// ...
]
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ 无障碍性建议 图标显示良好,建议添加 <Icon className={`h-3.5 w-3.5 ${config.iconColor}`} />或者在父元素 |
||
| <span>{config.label}</span> | ||
| </div> | ||
| </SelectItem> | ||
| ); | ||
| })} | ||
| </SelectContent> | ||
| </Select> | ||
| </div> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| import { Claude, Anthropic, OpenAI, Gemini } from "@lobehub/icons"; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 性能优化建议:考虑按需导入以减小打包体积。 // 建议使用具名导入或动态导入
import { Claude, Anthropic, OpenAI, Gemini } from "@lobehub/icons/es";或者评估是否可以使用项目已有的
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 缺少 React 导入 这是一个 import React from "react";特别是在第 5 行使用了 |
||
| import type { ProviderType } from "@/types/provider"; | ||
|
|
||
| // Anthropic Avatar 橙色包装组件(与 Claude Code 颜色一致) | ||
| const AnthropicOrangeAvatar: React.FC<{ className?: string }> = ({ | ||
| className, | ||
| }) => { | ||
| // 从 className 中提取尺寸,默认 12px(对应 h-3 w-3) | ||
| const sizeMatch = className?.match(/h-(\d+)/); | ||
| const size = sizeMatch ? parseInt(sizeMatch[1]) * 4 : 12; // Tailwind: h-3 = 12px | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 性能优化建议: 这里的尺寸计算逻辑在每次渲染时都会执行正则匹配,建议使用 const getSizeFromClassName = (className?: string): number => {
const sizeMatch = className?.match(/h-(\d+)/);
return sizeMatch ? parseInt(sizeMatch[1]) * 4 : 12;
};
const AnthropicOrangeAvatar: React.FC<{ className?: string }> = ({ className }) => {
const size = useMemo(() => getSizeFromClassName(className), [className]);
// ...
};
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 当前的简单乘法计算对于非标准 Tailwind 尺寸可能不准确。建议使用映射表: const TAILWIND_SIZE_MAP: Record<string, number> = {
'3': 12, // h-3 (0.75rem)
'3.5': 14, // h-3.5 (0.875rem)
'4': 16, // h-4 (1rem)
'5': 20, // h-5 (1.25rem)
};
const sizeMatch = className?.match(/h-([\d.]+)/);
const size = sizeMatch ? TAILWIND_SIZE_MAP[sizeMatch[1]] || 16 : 12;这样可以处理小数尺寸(如
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 潜在的性能问题:这个尺寸解析逻辑在每次渲染时都会执行正则匹配。 建议:
const getSizeFromClassName = (className?: string): number => {
const sizeMatch = className?.match(/h-(\d+)/);
return sizeMatch ? parseInt(sizeMatch[1]) * 4 : 12;
};
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 代码简化建议 尺寸计算逻辑可以更简洁: const size = className?.includes('h-')
? parseInt(className.match(/h-(\d+)/)?.[1] || '3') * 4
: 12;或者直接传递固定尺寸,避免从 className 解析: <Anthropic.Avatar size={12} background="#ffffff" shape="circle" />
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 通过正则表达式解析 Tailwind 类名来计算尺寸存在以下问题:
建议改进: interface AnthropicOrangeAvatarProps {
size?: number; // 直接接收数值,默认 12px
}
const AnthropicOrangeAvatar: React.FC<AnthropicOrangeAvatarProps> = ({
size = 12
}) => {
return (
<Anthropic.Avatar
size={size}
background="#ffffff"
shape="circle"
/>
);
};这样调用时更清晰:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 建议:添加注释说明尺寸计算逻辑。 // Tailwind CSS 尺寸单位转换:h-1 = 4px, h-2 = 8px, h-3 = 12px
const size = sizeMatch ? parseInt(sizeMatch[1]) * 4 : 12;这样可以让其他开发者更容易理解这个魔术数字
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 尺寸计算逻辑问题 当前的尺寸计算逻辑有潜在问题:
建议修改: const sizeMatch = className?.match(/h-(\d+(?:\.\d+)?)/);
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 性能优化建议:每次渲染都会执行正则匹配,建议优化: const AnthropicOrangeAvatar: React.FC<{ className?: string; size?: number }> = ({
className,
size = 12, // 直接传递 size,避免正则解析
}) => {
return (
<Anthropic.Avatar
size={size}
background="#ffffff"
shape="circle"
className={className}
/>
);
};这样可以避免重复的字符串解析开销。
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 当前通过正则提取 Tailwind 类名并计算像素值的方式比较脆弱:
建议改为: const AnthropicOrangeAvatar: React.FC<{ size?: number }> = ({ size = 12 }) => {
return (
<Anthropic.Avatar
size={size}
background="#ffffff"
shape="circle"
/>
);
};然后在使用时直接传入数值而不是 className。
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 建议优化:尺寸计算可能存在问题 当前实现从 className 中提取尺寸,但这种方式不够可靠:
建议方案: // 方案 1: 支持常见的 Tailwind 尺寸类
const sizeMap: Record<string, number> = {
'h-3': 12,
'h-3.5': 14,
'h-4': 16,
'h-5': 20,
// ...
};
// 方案 2: 直接接收 size prop
const AnthropicOrangeAvatar: React.FC<{ size?: number; className?: string }> = ({
size = 12,
className,
}) => {
return (
<Anthropic.Avatar
size={size}
background="#ffffff"
shape="circle"
className={className}
/>
);
}; |
||
|
|
||
| return ( | ||
| <Anthropic.Avatar | ||
| size={size} | ||
| background="#ffffff" | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 硬编码背景色问题
background="currentColor" // 或者
background="var(--background)" // 使用主题背景色 |
||
| shape="circle" | ||
| className={className} | ||
| /> | ||
| ); | ||
| }; | ||
|
|
||
| // 供应商类型配置 | ||
| export const PROVIDER_TYPE_CONFIG: Record< | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 类型安全改进建议: 建议显式导出 export type ProviderTypeConfig = {
label: string;
icon: React.ComponentType<{ className?: string }>;
iconColor: string;
bgColor: string;
description: string;
};
export const PROVIDER_TYPE_CONFIG: Record<ProviderType, ProviderTypeConfig> = {
// ...
}; |
||
| ProviderType, | ||
| { | ||
| label: string; | ||
| icon: React.ComponentType<{ className?: string }>; | ||
| iconColor: string; | ||
| bgColor: string; | ||
| description: string; | ||
| } | ||
| > = { | ||
| claude: { | ||
| label: "Claude", | ||
| icon: Claude.Color, | ||
| iconColor: "text-orange-600", | ||
| bgColor: "bg-orange-500/15", | ||
| description: "Anthropic 官方 API", | ||
| }, | ||
| "claude-auth": { | ||
| label: "Claude Auth", | ||
| icon: AnthropicOrangeAvatar, // Anthropic Avatar 橙色圆形图标 | ||
| iconColor: "text-purple-600", | ||
| bgColor: "bg-purple-500/15", | ||
| description: "Claude 中转服务", | ||
| }, | ||
| codex: { | ||
| label: "Codex", | ||
| icon: OpenAI, // OpenAI 无文字版本(默认 Mono) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 代码重复: 建议:如果这是预期行为,建议添加注释说明原因。如果不同,建议为
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 疑问:OpenAI 图标用于 Codex Codex 是 OpenAI 的产品,但使用 OpenAI 图标可能导致混淆:
建议:考虑使用不同的图标以避免视觉混淆,或者在注释中说明这样设计的原因。 |
||
| iconColor: "text-blue-600", | ||
| bgColor: "bg-blue-500/15", | ||
| description: "Codex CLI API", | ||
| }, | ||
| "gemini-cli": { | ||
| label: "Gemini CLI", | ||
| icon: Gemini.Color, | ||
| iconColor: "text-emerald-600", | ||
| bgColor: "bg-emerald-500/15", | ||
| description: "Gemini CLI API", | ||
| }, | ||
| "openai-compatible": { | ||
| label: "OpenAI Compatible", | ||
| icon: OpenAI, // OpenAI 无文字版本(默认 Mono) | ||
| iconColor: "text-cyan-600", | ||
| bgColor: "bg-cyan-500/15", | ||
| description: "OpenAI 兼容 API", | ||
| }, | ||
|
Comment on lines
+49
to
+67
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤔 图标复用问题
这样可以更清晰地区分不同的供应商类型。 |
||
| }; | ||
|
|
||
| // 获取供应商类型配置 | ||
| export function getProviderTypeConfig(type: ProviderType) { | ||
| return PROVIDER_TYPE_CONFIG[type]; | ||
| } | ||
|
|
||
| // 获取所有供应商类型 | ||
| export function getAllProviderTypes(): ProviderType[] { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 类型安全改进 使用 export function getAllProviderTypes(): ProviderType[] {
return Object.keys(PROVIDER_TYPE_CONFIG) as Array<keyof typeof PROVIDER_TYPE_CONFIG>;
}这样既保证类型安全,又让 TypeScript 能够推断正确的类型。 |
||
| return Object.keys(PROVIDER_TYPE_CONFIG) as ProviderType[]; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
文档建议:
建议添加更详细的注释说明为什么需要转译这个包,以及可能影响的范围: