/* Copyright (C) 2025 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ import React, { useState, useEffect } from 'react'; import { SideSheet, Button, Typography, Space, Tag, Popconfirm, Card, Avatar, Spin, Empty, } from '@douyinfe/semi-ui'; import { IconPlus, IconLayers } from '@douyinfe/semi-icons'; import { IllustrationNoResult, IllustrationNoResultDark, } from '@douyinfe/semi-illustrations'; import { API, showError, showSuccess, stringToColor, } from '../../../../helpers'; import { useTranslation } from 'react-i18next'; import { useIsMobile } from '../../../../hooks/common/useIsMobile'; import CardTable from '../../../common/ui/CardTable'; import EditPrefillGroupModal from './EditPrefillGroupModal'; import { renderLimitedItems, renderDescription, } from '../../../common/ui/RenderUtils'; const { Text, Title } = Typography; const PrefillGroupManagement = ({ visible, onClose }) => { const { t } = useTranslation(); const isMobile = useIsMobile(); const [loading, setLoading] = useState(false); const [groups, setGroups] = useState([]); const [showEdit, setShowEdit] = useState(false); const [editingGroup, setEditingGroup] = useState({ id: undefined }); const typeOptions = [ { label: t('模型组'), value: 'model' }, { label: t('标签组'), value: 'tag' }, { label: t('端点组'), value: 'endpoint' }, ]; // 加载组列表 const loadGroups = async () => { setLoading(true); try { const res = await API.get('/api/prefill_group'); if (res.data.success) { setGroups(res.data.data || []); } else { showError(res.data.message || t('获取组列表失败')); } } catch (error) { showError(t('获取组列表失败')); } setLoading(false); }; // 删除组 const deleteGroup = async (id) => { try { const res = await API.delete(`/api/prefill_group/${id}`); if (res.data.success) { showSuccess(t('删除成功')); loadGroups(); } else { showError(res.data.message || t('删除失败')); } } catch (error) { showError(t('删除失败')); } }; // 编辑组 const handleEdit = (group = {}) => { setEditingGroup(group); setShowEdit(true); }; // 关闭编辑 const closeEdit = () => { setShowEdit(false); setTimeout(() => { setEditingGroup({ id: undefined }); }, 300); }; // 编辑成功回调 const handleEditSuccess = () => { closeEdit(); loadGroups(); }; // 表格列定义 const columns = [ { title: t('组名'), dataIndex: 'name', key: 'name', render: (text, record) => ( {text} {typeOptions.find((opt) => opt.value === record.type)?.label || record.type} ), }, { title: t('描述'), dataIndex: 'description', key: 'description', render: (text) => renderDescription(text, 150), }, { title: t('项目内容'), dataIndex: 'items', key: 'items', render: (items, record) => { try { if (record.type === 'endpoint') { const obj = typeof items === 'string' ? JSON.parse(items || '{}') : items || {}; const keys = Object.keys(obj); if (keys.length === 0) return {t('暂无项目')}; return renderLimitedItems({ items: keys, renderItem: (key, idx) => ( {key} ), maxDisplay: 3, }); } const itemsArray = typeof items === 'string' ? JSON.parse(items) : items; if (!Array.isArray(itemsArray) || itemsArray.length === 0) { return {t('暂无项目')}; } return renderLimitedItems({ items: itemsArray, renderItem: (item, idx) => ( {item} ), maxDisplay: 3, }); } catch { return {t('数据格式错误')}; } }, }, { title: '', key: 'action', fixed: 'right', width: 140, render: (_, record) => ( deleteGroup(record.id)} > ), }, ]; useEffect(() => { if (visible) { loadGroups(); } }, [visible]); return ( <> {t('管理')} {t('预填组管理')} } visible={visible} onCancel={onClose} width={isMobile ? '100%' : 800} bodyStyle={{ padding: '0' }} closeIcon={null} >
{t('组列表')}
{t('管理模型、标签、端点等预填组')}
{groups.length > 0 ? ( ) : ( } darkModeImage={ } description={t('暂无预填组')} style={{ padding: 30 }} /> )}
{/* 编辑组件 */} ); }; export default PrefillGroupManagement;