// ============================================================ // 提示词管理 // ============================================================ import { useState } from 'react' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { Button, message, Tag, Modal, Form, Input, Select, Space, Popconfirm, Descriptions, Tabs, 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 { promptService } from '@/services/prompts' import type { PromptTemplate, PromptVersion } from '@/types' const { TextArea } = Input const { Text } = Typography const sourceLabels: Record = { builtin: '内置', custom: '自定义' } const statusLabels: Record = { active: '活跃', deprecated: '已废弃', archived: '已归档' } const statusColors: Record = { active: 'green', deprecated: 'orange', archived: 'default' } export default function Prompts() { const queryClient = useQueryClient() const [form] = Form.useForm() const [createOpen, setCreateOpen] = useState(false) const [detailName, setDetailName] = useState(null) const { data, isLoading } = useQuery({ queryKey: ['prompts'], queryFn: ({ signal }) => promptService.list(signal), }) const { data: detailData } = useQuery({ queryKey: ['prompt-detail', detailName], queryFn: ({ signal }) => promptService.get(detailName!, signal), enabled: !!detailName, }) const { data: versionsData } = useQuery({ queryKey: ['prompt-versions', detailName], queryFn: ({ signal }) => promptService.listVersions(detailName!, signal), enabled: !!detailName, }) const createMutation = useMutation({ mutationFn: (data: Parameters[0]) => promptService.create(data), onSuccess: () => { message.success('创建成功') queryClient.invalidateQueries({ queryKey: ['prompts'] }) setCreateOpen(false) form.resetFields() }, onError: (err: Error) => message.error(err.message || '创建失败'), }) const archiveMutation = useMutation({ mutationFn: (name: string) => promptService.archive(name), onSuccess: () => { message.success('已归档') queryClient.invalidateQueries({ queryKey: ['prompts'] }) }, onError: (err: Error) => message.error(err.message || '归档失败'), }) const rollbackMutation = useMutation({ mutationFn: ({ name, version }: { name: string; version: number }) => promptService.rollback(name, version), onSuccess: () => { message.success('回滚成功') queryClient.invalidateQueries({ queryKey: ['prompts'] }) queryClient.invalidateQueries({ queryKey: ['prompt-detail', detailName] }) queryClient.invalidateQueries({ queryKey: ['prompt-versions', detailName] }) }, onError: (err: Error) => message.error(err.message || '回滚失败'), }) const columns: ProColumns[] = [ { title: '名称', dataIndex: 'name', width: 200, render: (_, r) => {r.name} }, { title: '分类', dataIndex: 'category', width: 100 }, { title: '描述', dataIndex: 'description', width: 200, ellipsis: true }, { title: '来源', dataIndex: 'source', width: 80, render: (_, r) => {sourceLabels[r.source]}, }, { title: '版本', dataIndex: 'current_version', width: 70 }, { title: '状态', dataIndex: 'status', width: 90, render: (_, r) => {statusLabels[r.status]}, }, { title: '操作', width: 180, render: (_, record) => ( {record.status === 'active' && ( archiveMutation.mutate(record.name)}> )} ), }, ] const handleCreate = async () => { const values = await form.validateFields() createMutation.mutate(values) } const versionColumns: ProColumns[] = [ { title: '版本', dataIndex: 'version', width: 60 }, { title: '更新说明', dataIndex: 'changelog', width: 200, ellipsis: true }, { title: '最低版本', dataIndex: 'min_app_version', width: 100, render: (_, r) => r.min_app_version || '-' }, { title: '创建时间', dataIndex: 'created_at', width: 180, render: (_, r) => new Date(r.created_at).toLocaleString('zh-CN'), }, { title: '操作', width: 80, render: (_, record) => ( detailName && rollbackMutation.mutate({ name: detailName, version: record.version })} > ), }, ] 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, }} /> { setCreateOpen(false); form.resetFields() }} confirmLoading={createMutation.isPending} width={640} >