// ============================================================ // 服务商管理 // ============================================================ import { useState } from 'react' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { Button, message, Tag, Modal, Form, Input, InputNumber, Switch, Space, Popconfirm, Typography } from 'antd' import { PlusOutlined } from '@ant-design/icons' import type { ProColumns } from '@ant-design/pro-components' import { ProTable } from '@ant-design/pro-components' import { providerService } from '@/services/providers' import type { Provider, ProviderKey } from '@/types' const { Text } = Typography export default function Providers() { const queryClient = useQueryClient() const [form] = Form.useForm() const [modalOpen, setModalOpen] = useState(false) const [editingId, setEditingId] = useState(null) const [keyModalProviderId, setKeyModalProviderId] = useState(null) const { data, isLoading } = useQuery({ queryKey: ['providers'], queryFn: ({ signal }) => providerService.list(signal), }) const { data: keysData, isLoading: keysLoading } = useQuery({ queryKey: ['provider-keys', keyModalProviderId], queryFn: ({ signal }) => providerService.listKeys(keyModalProviderId!, signal), enabled: !!keyModalProviderId, }) const createMutation = useMutation({ mutationFn: (data: Partial>) => providerService.create(data), onSuccess: () => { message.success('创建成功') queryClient.invalidateQueries({ queryKey: ['providers'] }) setModalOpen(false) form.resetFields() }, onError: (err: Error) => message.error(err.message || '创建失败'), }) const updateMutation = useMutation({ mutationFn: ({ id, data }: { id: string; data: Partial> }) => providerService.update(id, data), onSuccess: () => { message.success('更新成功') queryClient.invalidateQueries({ queryKey: ['providers'] }) setModalOpen(false) }, onError: (err: Error) => message.error(err.message || '更新失败'), }) const deleteMutation = useMutation({ mutationFn: (id: string) => providerService.delete(id), onSuccess: () => { message.success('删除成功') queryClient.invalidateQueries({ queryKey: ['providers'] }) }, onError: (err: Error) => message.error(err.message || '删除失败'), }) const columns: ProColumns[] = [ { title: '名称', dataIndex: 'display_name', width: 140 }, { title: '标识', dataIndex: 'name', width: 120, render: (_, r) => {r.name} }, { title: '协议', dataIndex: 'api_protocol', width: 100 }, { title: 'RPM 限制', dataIndex: 'rate_limit_rpm', width: 100, render: (_, r) => r.rate_limit_rpm ?? '-' }, { title: '状态', dataIndex: 'enabled', width: 80, render: (_, r) => r.enabled ? 启用 : 禁用, }, { title: '操作', width: 260, render: (_, record) => ( deleteMutation.mutate(record.id)}> ), }, ] const keyColumns: ProColumns[] = [ { title: '标签', dataIndex: 'key_label', width: 120 }, { title: '优先级', dataIndex: 'priority', width: 80 }, { title: '请求数', dataIndex: 'total_requests', width: 80 }, { title: 'Token 数', dataIndex: 'total_tokens', width: 100 }, { title: '状态', dataIndex: 'is_active', width: 80, render: (_, r) => r.is_active ? 活跃 : 冷却, }, ] const handleSave = async () => { const values = await form.validateFields() if (editingId) { updateMutation.mutate({ id: editingId, data: values }) } else { createMutation.mutate(values) } } return (
columns={columns} dataSource={data?.items ?? []} loading={isLoading} rowKey="id" search={false} toolBarRender={() => [ , ]} pagination={{ total: data?.total ?? 0, pageSize: data?.page_size ?? 20, current: data?.page ?? 1, showSizeChanger: false, }} /> { setModalOpen(false); setEditingId(null); form.resetFields() }} confirmLoading={createMutation.isPending || updateMutation.isPending} >
setKeyModalProviderId(null)} footer={null} width={700} > columns={keyColumns} dataSource={keysData ?? []} loading={keysLoading} rowKey="id" search={false} toolBarRender={false} pagination={false} size="small" />
) }