import { useState, useEffect } from 'react'; import { Button, Modal, Form, Input, message, Card, Space, Tag, Popconfirm, Empty, Typography, Row, Col, Tooltip } from 'antd'; import { PlusOutlined, EditOutlined, DeleteOutlined, StarOutlined, StarFilled } from '@ant-design/icons'; import { useStore } from '../store'; import { writingStyleApi } from '../services/api'; import type { WritingStyle, WritingStyleCreate, WritingStyleUpdate } from '../types'; const { TextArea } = Input; const { Text, Paragraph } = Typography; export default function WritingStyles() { const { currentProject } = useStore(); const [styles, setStyles] = useState([]); const [loading, setLoading] = useState(false); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const [isEditModalOpen, setIsEditModalOpen] = useState(false); const [editingStyle, setEditingStyle] = useState(null); const [createForm] = Form.useForm(); const [editForm] = Form.useForm(); const isMobile = window.innerWidth <= 768; // 卡片网格配置 const gridConfig = { gutter: isMobile ? 8 : 16, // 卡片之间的间距 xs: 24, sm: 24, md: 12, lg: 8, xl: 6, }; // 加载项目风格 useEffect(() => { if (currentProject?.id) { loadProjectStyles(); } }, [currentProject?.id]); const loadProjectStyles = async () => { if (!currentProject?.id) return; try { setLoading(true); const response = await writingStyleApi.getProjectStyles(currentProject.id); // 对风格列表进行排序:默认风格优先,然后按原有顺序 const sortedStyles = (response.styles || []).sort((a, b) => { // 默认风格排在前面 if (a.is_default && !b.is_default) return -1; if (!a.is_default && b.is_default) return 1; return 0; }); setStyles(sortedStyles); } catch { message.error('加载风格列表失败'); } finally { setLoading(false); } }; const handleCreate = async (values: { name: string; description?: string; prompt_content: string }) => { if (!currentProject?.id) return; try { const createData: WritingStyleCreate = { project_id: currentProject.id, name: values.name, style_type: 'custom', description: values.description, prompt_content: values.prompt_content, }; await writingStyleApi.createStyle(createData); message.success('创建成功'); setIsCreateModalOpen(false); createForm.resetFields(); await loadProjectStyles(); } catch { message.error('创建失败'); } }; const handleEdit = (style: WritingStyle) => { setEditingStyle(style); editForm.setFieldsValue({ name: style.name, description: style.description, prompt_content: style.prompt_content, }); setIsEditModalOpen(true); }; const handleUpdate = async (values: WritingStyleUpdate) => { if (!editingStyle) return; try { await writingStyleApi.updateStyle(editingStyle.id, values); message.success('更新成功'); setIsEditModalOpen(false); editForm.resetFields(); setEditingStyle(null); await loadProjectStyles(); } catch { message.error('更新失败'); } }; const handleDelete = async (styleId: number) => { try { await writingStyleApi.deleteStyle(styleId); message.success('删除成功'); await loadProjectStyles(); } catch { message.error('删除失败'); } }; const handleSetDefault = async (styleId: number) => { if (!currentProject?.id) return; try { await writingStyleApi.setDefaultStyle(styleId, currentProject.id); message.success('设置默认风格成功'); await loadProjectStyles(); } catch { message.error('设置失败'); } }; const showCreateModal = () => { createForm.resetFields(); setIsCreateModalOpen(true); }; if (!currentProject) return null; const getStyleTypeColor = (styleType: string) => { return styleType === 'preset' ? 'blue' : 'purple'; }; const getStyleTypeLabel = (styleType: string) => { return styleType === 'preset' ? '预设' : '自定义'; }; return (

写作风格管理

{styles.length === 0 ? ( ) : ( {styles.map((style) => ( !style.is_default && handleSetDefault(style.id)} style={{ cursor: style.is_default ? 'default' : 'pointer' }} > {style.is_default ? ( ) : ( )} , style.project_id !== null && handleEdit(style)} style={{ fontSize: 18, cursor: style.project_id === null ? 'not-allowed' : 'pointer', color: style.project_id === null ? '#ccc' : undefined }} /> , handleDelete(style.id)} okText="确定" cancelText="取消" disabled={style.project_id === null || styles.length === 1} > , ]} >
{style.name} {getStyleTypeLabel(style.style_type)} {style.is_default && 默认} {style.description && ( {style.description} )} {style.prompt_content}
))}
)}
{/* 创建自定义风格 Modal */} { setIsCreateModalOpen(false); createForm.resetFields(); }} footer={null} centered width={isMobile ? 'calc(100vw - 32px)' : 600} style={isMobile ? { maxWidth: 'calc(100vw - 32px)', margin: '0 16px' } : undefined} >