feat: 前端适配后端新接口
适配后端统一模型 ID、协议字段、UUID 自动生成和结构化错误响应: - 类型定义:Provider 新增 protocol 字段,Model 新增 unifiedId,CreateModelInput 移除 id - API 客户端:提取结构化错误响应中的错误码 - 供应商管理:添加协议选择下拉框和表格列 - 模型管理:移除 ID 输入,显示统一模型 ID(只读) - Hooks:错误码映射为友好中文消息 - 测试:所有组件测试通过,mock 数据适配新字段 - 文档:更新 README 说明协议字段和统一模型 ID
This commit is contained in:
@@ -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="供应商"
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user