import React, { useState, useEffect, useContext, createContext } from 'react'; import { SimpleCodeEditor } from './SimpleCodeEditor'; interface RuleType { id: string; type: string; config: Record; } // 为配置项添加类型定义 interface ComparisonPair { sourceField: string; targetField: string; compareMethod: string; } interface ReviewSettingsProps { onChange?: (data: Record) => void; } // 创建全局上下文以便在不同组件间共享数据 interface RuleContextType { extractionFields: string[]; updateExtractionFields: (fields: string[]) => void; } // 创建全局Context对象 export const RuleContext = createContext({ extractionFields: [], updateExtractionFields: () => {} }); export function ReviewSettings({ onChange }: ReviewSettingsProps) { const [rules, setRules] = useState([ { id: '1', type: '', config: {} } ]); const [combinationLogic, setCombinationLogic] = useState('and'); const [customLogic, setCustomLogic] = useState(''); const [showCustomLogic, setShowCustomLogic] = useState(false); // 添加评查后动作相关状态 const [actionType, setActionType] = useState('none'); const [actionDescription, setActionDescription] = useState(''); // 获取抽取字段的上下文 const { extractionFields } = useContext(RuleContext); // 初始化评查通过/不通过/建议信息 const [passMessage, setPassMessage] = useState('文档检查通过,符合规范要求。'); const [failMessage, setFailMessage] = useState('文档存在以下问题,请修改后重新提交。'); const [suggestMessage, setSuggestMessage] = useState(''); // 错误严重程度 const [errorSeverity, setErrorSeverity] = useState('error'); // 保存最近一次可用的字段列表 const [availableFields, setAvailableFields] = useState(extractionFields || []); // 监听抽取设置中的字段变化 useEffect(() => { // 当Context中的字段发生变化时,立即更新可用字段 if (extractionFields.length > 0) { setAvailableFields(extractionFields); // 同时更新已有规则中的可选字段状态 updateRulesWithNewFields(extractionFields); return; } // 获取抽取字段函数 - 当Context不可用时的备选方案 const getExtractedFields = (): string[] => { const extractedFields: string[] = []; // 查找当前活跃的抽取设置容器 const activeExtractConfig = document.querySelector('.extraction-config:not(.hidden)'); if (!activeExtractConfig) { // 如果没有找到活跃的配置,返回空数组 return []; } // 查找字段容器 const fieldsContainer = activeExtractConfig.querySelector('.chips-container'); if (fieldsContainer) { // 获取所有字段芯片 const chips = fieldsContainer.querySelectorAll('.chip'); chips.forEach(chip => { const fieldName = chip.textContent?.replace('×', '').trim(); if (fieldName) { extractedFields.push(fieldName); } }); } // 查找正则字段 const regexFields = document.querySelectorAll('.regex-field-row'); regexFields.forEach(row => { const fieldNameInput = row.querySelector('input[placeholder="字段名称"]'); if (fieldNameInput instanceof HTMLInputElement && fieldNameInput.value.trim()) { extractedFields.push(fieldNameInput.value.trim()); } }); return extractedFields; }; // 初始化获取字段 - 仅在Context不可用时使用 setAvailableFields(getExtractedFields()); // 监听抽取设置的变化 - 仅在Context不可用时使用 const handleExtractionChange = (event: Event) => { if (event instanceof CustomEvent && event.detail && Array.isArray(event.detail.fields)) { setAvailableFields(event.detail.fields); } else { setAvailableFields(getExtractedFields()); } }; // 添加事件监听器,监听抽取设置中的字段变化 document.addEventListener('extraction-fields-updated', handleExtractionChange); // 组件卸载时移除事件监听 return () => { document.removeEventListener('extraction-fields-updated', handleExtractionChange); }; }, [extractionFields]); // 当可用字段发生变化时,更新已有规则的配置 const updateRulesWithNewFields = (newFields: string[]) => { // 更新已有规则中的字段选择,保留已选择的字段 const updatedRules = rules.map(rule => { if (rule.type === 'exists' || rule.type === 'consistency' || rule.type === 'logic' || rule.type === 'regex') { // 检查和更新字段相关的配置 const currentSelectedFields = Array.isArray(rule.config.selectedFields) ? rule.config.selectedFields as string[] : []; // 使用已选中的字段和新字段的交集作为更新后的选中字段 const validSelectedFields = currentSelectedFields.filter(field => newFields.includes(field) || field.trim() !== '' ); return { ...rule, config: { ...rule.config, selectedFields: validSelectedFields } }; } return rule; }); setRules(updatedRules); if (onChange) { onChange({ rules: updatedRules }); } }; const handleLogicChange = (logic: string) => { setCombinationLogic(logic); if (logic === 'custom') { setShowCustomLogic(true); } else { setShowCustomLogic(false); } if (onChange) { onChange({ combinationLogic: logic, showCustomLogic: logic === 'custom', customLogic }); } }; const handleCustomLogicChange = (e: React.ChangeEvent) => { setCustomLogic(e.target.value); if (onChange) { onChange({ customLogic: e.target.value }); } }; const handleActionTypeChange = (type: string) => { setActionType(type); if (onChange) { onChange({ actionType: type }); } }; const handleAddRule = () => { const newId = `${rules.length + 1}`; const newRule = { id: newId, type: '', config: {} }; setRules([...rules, newRule]); if (onChange) { onChange({ rules: [...rules, newRule] }); } }; const handleRemoveRule = (id: string) => { // 如果只有一个规则,不允许删除 if (rules.length <= 1) { return; } const newRules = rules.filter(rule => rule.id !== id); setRules(newRules); // 重新编号规则 const reindexedRules = newRules.map((rule, index) => ({ ...rule, id: `${index + 1}` })); setRules(reindexedRules); if (onChange) { onChange({ rules: reindexedRules }); } }; const handleRuleTypeChange = (id: string, type: string) => { const updatedRules = rules.map(rule => rule.id === id ? { ...rule, type, config: {} } : rule ); setRules(updatedRules); if (onChange) { onChange({ rules: updatedRules }); } }; const handleRuleConfigChange = (id: string, config: Record) => { const updatedRules = rules.map(rule => rule.id === id ? { ...rule, config: { ...rule.config, ...config } } : rule ); setRules(updatedRules); if (onChange) { onChange({ rules: updatedRules }); } }; // 处理字段选择 const handleFieldSelection = (id: string, fieldName: string, selected: boolean) => { const updatedRules = rules.map(rule => { if (rule.id === id) { // 获取当前已选字段 const selectedFields = Array.isArray(rule.config.selectedFields) ? rule.config.selectedFields as string[] : []; // 添加或删除字段 const newSelectedFields = selected ? [...selectedFields, fieldName] : selectedFields.filter(f => f !== fieldName); return { ...rule, config: { ...rule.config, selectedFields: newSelectedFields } }; } return rule; }); setRules(updatedRules); if (onChange) { onChange({ rules: updatedRules }); } }; // 渲染字段标签,确保已选择的字段即使在新的字段列表中不存在也会显示 const renderFieldTags = (ruleId: string, ruleConfig: Record) => { const selectedFields = Array.isArray(ruleConfig.selectedFields) ? ruleConfig.selectedFields as string[] : []; // 合并已选择的字段和可用字段,以确保已选择但不再可用的字段仍然显示 const allFieldsToRender = [...new Set([...availableFields, ...selectedFields])]; return allFieldsToRender.map((field, index) => { const isSelected = selectedFields.includes(field); const isAvailable = availableFields.includes(field); const buttonId = `field-tag-${ruleId}-${index}`; // 如果字段不再可用但已被选中,用特殊样式显示 const fieldClass = !isAvailable && isSelected ? 'field-tag selected unavailable' : isSelected ? 'field-tag selected' : 'field-tag'; // 只显示可用的字段或已选择的字段 if (!isAvailable && !isSelected) { return null; } return ( ); }).filter(Boolean); // 过滤掉null值 }; // 获取规则类型的Badge样式 const getRuleTypeBadgeClass = (type: string) => { switch(type) { case 'exists': return 'bg-green-500'; case 'consistency': return 'bg-blue-500'; case 'format': return 'bg-purple-500'; case 'logic': return 'bg-yellow-500'; case 'regex': return 'bg-red-500'; case 'ai': return 'bg-indigo-500'; case 'code': return 'bg-gray-700'; default: return 'bg-primary'; } }; // 渲染规则配置区域 const renderRuleConfig = (rule: RuleType) => { const { id, type, config } = rule; if (!type) { return (

请先选择评查类型

); } switch(type) { case 'exists': return (
{renderFieldTags(id, config)}
点击选择需要判断是否存在的字段,已选中的字段会高亮显示
); case 'consistency': return (
{Array.isArray(config.pairs) && config.pairs.length > 0 ? ( config.pairs.map((pair, pairIndex) => (
)) ) : (
)}
逻辑关系 *
); case 'logic': return (
{ const currentConditions = Array.isArray(config.conditions) ? [...config.conditions] : []; currentConditions[0] = { ...currentConditions[0], value: e.target.value }; handleRuleConfigChange(id, { conditions: currentConditions }); }} />
逻辑关系 *
); case 'regex': return (
匹配类型 *
); case 'ai': return (
handleRuleConfigChange(id, { temperature: e.target.value })} />
{availableFields.map((field, idx) => ( ))}
); case 'code': return (
代码语言 *
handleRuleConfigChange(id, { code: value })} />
); case 'format': return (
handleRuleConfigChange(id, { formatParams: e.target.value })} />
); default: return (

已选择 {type} 类型规则,请继续配置。

); } }; // 处理评查结果消息变更 const handleMessageChange = (type: string, value: string) => { switch(type) { case 'pass': setPassMessage(value); break; case 'fail': setFailMessage(value); break; case 'suggest': setSuggestMessage(value); break; } if (onChange) { onChange({ [`${type}Message`]: value }); } }; // 处理严重程度变更 const handleSeverityChange = (value: string) => { setErrorSeverity(value); if (onChange) { onChange({ errorSeverity: value }); } }; return (

评查设置

{showCustomLogic && (
使用规则编号和逻辑运算符(AND、OR、NOT)组合
)}
已添加 {rules.length} 条规则
{rules.length === 0 ? (

尚未添加任何规则

点击“添加规则”按钮开始创建评查规则

) : (
{rules.map((rule) => (
规则 #{rule.id}
选择评查类型后将显示对应的配置项
{renderRuleConfig(rule)}
))}
)}
建议在消息中说明问题出现的原因及建议的解决方案
{actionType === 'notification' && (
)}
{/* 评查结果提示信息 */}
{/* 不通过提示类别 */}
不同类别会影响问题的展示方式和处理流程
{/* 评查后动作 */}
{/* 动作描述区域 */} {actionType && actionType !== 'none' && (
)}
); }