/** * Review Configuration Page * Configure dimensions, rules, and presets for content review */ import React, { useEffect, useState } from 'react' import { useNavigate, useParams } from 'react-router-dom' import { Card, Form, Switch, Slider, Button, Space, Select, Input, Modal, Tag, Divider, Row, Col, Alert, List, message, Tabs, Tooltip, Typography } from 'antd' import { PlusOutlined, EditOutlined, DeleteOutlined, SaveOutlined, PlayCircleOutlined, CopyOutlined, InfoCircleOutlined, ArrowLeftOutlined } from '@ant-design/icons' import { useReviewStore } from '@/stores/reviewStore' import { ReviewPreset, SeverityLevel, ReviewRule } from '@/services/reviewService' const { TextArea } = Input const { TabPane } = Tabs const { Title } = Typography const ReviewConfig: React.FC = () => { const navigate = useNavigate() const { id: projectId } = useParams<{ id: string }>() const { configuration, ruleTemplates, loading, error, fetchConfiguration, updateConfiguration, applyPreset, fetchRuleTemplates, createRule, updateRule, deleteRule, testRule, testResult } = useReviewStore() const [form] = Form.useForm() const [ruleModalVisible, setRuleModalVisible] = useState(false) const [testModalVisible, setTestModalVisible] = useState(false) const [editingRule, setEditingRule] = useState(null) const [testContent, setTestContent] = useState('') const [selectedRuleForTest, setSelectedRuleForTest] = useState(null) const [previewImpact, setPreviewImpact] = useState(null) useEffect(() => { if (projectId) { fetchConfiguration(projectId) fetchRuleTemplates() } }, [projectId]) useEffect(() => { if (configuration) { form.setFieldsValue(configuration) } }, [configuration]) const dimensions = [ { key: 'character_consistency', name: '角色一致性', description: '角色性格、行为、对话风格的一致性' }, { key: 'plot_coherence', name: '剧情连贯性', description: '剧情逻辑、时间线、因果关系的一致性' }, { key: 'dialogue_quality', name: '对话质量', description: '对话的自然度、角色声音的区分度' }, { key: 'pacing', name: '节奏控制', description: '故事节奏、张力、高潮设置' }, { key: 'emotional_depth', name: '情感深度', description: '情感表达的真实性、感染力' }, { key: 'thematic_strength', name: '主题强度', description: '主题表达的一致性、深度' } ] const severityColors: Record = { low: 'green', medium: 'orange', high: 'red' } const presetLabels: Record = { draft: '草稿模式', standard: '标准模式', strict: '严格模式', custom: '自定义' } const handleApplyPreset = async (preset: ReviewPreset) => { if (!projectId) return try { await applyPreset(projectId, preset) message.success(`已应用${presetLabels[preset]}`) } catch (error) { message.error('应用预设失败') } } const handleSaveConfiguration = async (values: any) => { if (!projectId) return try { await updateConfiguration(projectId, values) message.success('配置保存成功') } catch (error) { message.error('保存配置失败') } } const handleCreateRule = async (values: any) => { if (!projectId) return try { await createRule(projectId, values) message.success('规则创建成功') setRuleModalVisible(false) setEditingRule(null) form.resetFields(['ruleName', 'ruleDescription', 'triggerCondition', 'severity', 'category']) } catch (error) { message.error('创建规则失败') } } const handleUpdateRule = async (values: any) => { if (!projectId || !editingRule) return try { await updateRule(projectId, editingRule.id, values) message.success('规则更新成功') setRuleModalVisible(false) setEditingRule(null) form.resetFields(['ruleName', 'ruleDescription', 'triggerCondition', 'severity', 'category']) } catch (error) { message.error('更新规则失败') } } const handleDeleteRule = async (ruleId: string) => { if (!projectId) return Modal.confirm({ title: '确认删除', content: '确定要删除这条规则吗?', onOk: async () => { try { await deleteRule(projectId, ruleId) message.success('规则删除成功') } catch (error) { message.error('删除规则失败') } } }) } const handleEditRule = (rule: ReviewRule) => { setEditingRule(rule) form.setFieldsValue({ ruleName: rule.name, ruleDescription: rule.description, triggerCondition: rule.triggerCondition, severity: rule.severity, category: rule.category }) setRuleModalVisible(true) } const handleTestRule = async () => { if (!projectId || !selectedRuleForTest) return try { await testRule(projectId, selectedRuleForTest, testContent) message.success('测试完成') } catch (error) { message.error('测试规则失败') } } const handleUseTemplate = (template: ReviewRule) => { form.setFieldsValue({ ruleName: template.name, ruleDescription: template.description, triggerCondition: template.triggerCondition, severity: template.severity, category: template.category }) setRuleModalVisible(true) } const renderDimensionSliders = () => (
{configuration?.preset === 'custom' && ( 自定义 )} {dimensions.map(dim => (
{dim.name}
))}
) const renderRuleBuilder = () => ( } onClick={() => { setEditingRule(null) form.resetFields(['ruleName', 'ruleDescription', 'triggerCondition', 'severity', 'category']) setRuleModalVisible(true) }} > 添加规则 } > {configuration?.customRules && configuration.customRules.length > 0 ? ( ( } onClick={() => { setSelectedRuleForTest(rule) setTestContent('') setTestModalVisible(true) }} > 测试 , , ]} > {rule.name} {rule.severity} {rule.category} {!rule.isActive && 禁用} } description={rule.description} /> )} /> ) : ( )} 规则模板 ( } onClick={() => handleUseTemplate(template)} > 使用模板 ]} > )} /> ) const renderPreview = () => ( {configuration && (

当前预设: {presetLabels[configuration.preset]}

已启用维度:

    {dimensions.map(dim => ( configuration.dimensions[dim.key as keyof typeof configuration.dimensions]?.enabled && (
  • {dim.name} - 严格度: {configuration.dimensions[dim.key as keyof typeof configuration.dimensions]?.strictness}% , 权重: {configuration.dimensions[dim.key as keyof typeof configuration.dimensions]?.weight}
  • ) ))}

自定义规则数量: {configuration.customRules.length}

)}
) return (
审核配置 配置自动审核的规则和维度
{renderDimensionSliders()} {renderRuleBuilder()} {renderPreview()} {/* Rule Modal */} { setRuleModalVisible(false) setEditingRule(null) form.resetFields(['ruleName', 'ruleDescription', 'triggerCondition', 'severity', 'category']) }} footer={null} width={600} >