1
0

feat: 前端适配后端新接口

适配后端统一模型 ID、协议字段、UUID 自动生成和结构化错误响应:

- 类型定义:Provider 新增 protocol 字段,Model 新增 unifiedId,CreateModelInput 移除 id
- API 客户端:提取结构化错误响应中的错误码
- 供应商管理:添加协议选择下拉框和表格列
- 模型管理:移除 ID 输入,显示统一模型 ID(只读)
- Hooks:错误码映射为友好中文消息
- 测试:所有组件测试通过,mock 数据适配新字段
- 文档:更新 README 说明协议字段和统一模型 ID
This commit is contained in:
2026-04-21 20:49:37 +08:00
parent 24f03595a7
commit feff97acbd
28 changed files with 547 additions and 78 deletions

View File

@@ -4,7 +4,6 @@ import type { Provider, Model } from '@/types';
import type { SubmitContext } from 'tdesign-react/es/form/type';
interface ModelFormValues {
id: string;
providerId: string;
modelName: string;
enabled: boolean;
@@ -38,7 +37,6 @@ export function ModelForm({
if (model) {
// 编辑模式:设置现有值
form.setFieldsValue({
id: model.id,
providerId: model.providerId,
modelName: model.modelName,
enabled: model.enabled,
@@ -73,9 +71,14 @@ export function ModelForm({
destroyOnClose
>
<Form form={form} layout="vertical" onSubmit={handleSubmit}>
<Form.FormItem label="ID" name="id" rules={[{ required: true, message: '请输入模型 ID' }]}>
<Input disabled={isEdit} placeholder="例如: gpt-4o" />
</Form.FormItem>
{isEdit && model?.unifiedId && (
<Form.FormItem label="统一模型 ID">
<Input value={model.unifiedId} disabled />
<div style={{ color: '#999', fontSize: 12, marginTop: 4 }}>
provider_id/model_name
</div>
</Form.FormItem>
)}
<Form.FormItem
label="供应商"

View File

@@ -14,6 +14,13 @@ export function ModelTable({ providerId, onAdd, onEdit }: ModelTableProps) {
const deleteModel = useDeleteModel();
const columns: PrimaryTableCol<Model>[] = [
{
title: '统一模型 ID',
colKey: 'unifiedId',
width: 250,
ellipsis: true,
cell: ({ row }) => row.unifiedId || `${row.providerId}/${row.modelName}`,
},
{
title: '模型名称',
colKey: 'modelName',

View File

@@ -1,5 +1,5 @@
import { useEffect } from 'react';
import { Dialog, Form, Input, Switch } from 'tdesign-react';
import { Dialog, Form, Input, Switch, Select } from 'tdesign-react';
import type { Provider } from '@/types';
import type { SubmitContext } from 'tdesign-react/es/form/type';
@@ -8,6 +8,7 @@ interface ProviderFormValues {
name: string;
apiKey: string;
baseUrl: string;
protocol: 'openai' | 'anthropic';
enabled: boolean;
}
@@ -39,12 +40,13 @@ export function ProviderForm({
name: provider.name,
apiKey: '',
baseUrl: provider.baseUrl,
protocol: provider.protocol,
enabled: provider.enabled,
});
} else {
// 新增模式:重置表单
form.reset();
form.setFieldsValue({ enabled: true });
form.setFieldsValue({ enabled: true, protocol: 'openai' });
}
}
}, [open, provider]); // 移除form依赖避免循环
@@ -95,6 +97,13 @@ export function ProviderForm({
<Input placeholder="例如: https://api.openai.com/v1" />
</Form.FormItem>
<Form.FormItem label="协议" name="protocol" rules={[{ required: true, message: '请选择协议' }]}>
<Select>
<Select.Option value="openai">OpenAI</Select.Option>
<Select.Option value="anthropic">Anthropic</Select.Option>
</Select>
</Form.FormItem>
<Form.FormItem label="启用" name="enabled">
<Switch />
</Form.FormItem>

View File

@@ -40,6 +40,16 @@ export function ProviderTable({
colKey: 'baseUrl',
ellipsis: true,
},
{
title: '协议',
colKey: 'protocol',
width: 100,
cell: ({ row }) => (
<Tag theme={row.protocol === 'openai' ? 'primary' : 'success'}>
{row.protocol === 'openai' ? 'OpenAI' : 'Anthropic'}
</Tag>
),
},
{
title: 'API Key',
colKey: 'apiKey',