From 8be2fd5d6798c43a57e44abbe6dcf698472e8fc5 Mon Sep 17 00:00:00 2001 From: awen Date: Thu, 10 Apr 2025 10:16:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E8=BF=91=E5=AE=8C=E7=BE=8E=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/components/rules/new/ReviewSettings.tsx | 327 +++++++++----------- app/routes/rules.new.tsx | 192 ++++++++---- 2 files changed, 279 insertions(+), 240 deletions(-) diff --git a/app/components/rules/new/ReviewSettings.tsx b/app/components/rules/new/ReviewSettings.tsx index 56fdeb7..449a72f 100644 --- a/app/components/rules/new/ReviewSettings.tsx +++ b/app/components/rules/new/ReviewSettings.tsx @@ -87,8 +87,153 @@ export function ReviewSettings({ // 使用useRef跟踪是否已经初始化过 const initializedRef = useRef(false); // 保存初始数据的引用,用于检测是否有实际变更 - const initialDataRef = useRef(null); + const initialDataRef = useRef(null); + // 生成评查配置并发送给父组件 + const generateEvaluationConfig = useCallback(() => { + // 构建评查配置对象 + const evaluationConfig = { + logicType: combinationLogic, + customLogic: customLogic, + rules: rules + .filter(rule => rule.type) // 过滤掉没有选择类型的规则 + .map(rule => { + // 处理不同规则类型的特殊配置 + const processedConfig = { ...rule.config }; + + switch(rule.type) { + case 'exists': + // 确保fields字段是数组 + if (!Array.isArray(processedConfig.fields)) { + processedConfig.fields = []; + } + + // 确保logic字段有值 + if (!processedConfig.logic) { + processedConfig.logic = 'and'; + } + break; + + case 'consistency': + // 确保pairs字段是数组 + if (!Array.isArray(processedConfig.pairs)) { + processedConfig.pairs = []; + } + + // 确保logic字段有值 + if (!processedConfig.logic) { + processedConfig.logic = 'and'; + } + break; + + case 'format': + // 确保field字段正确设置 + if (processedConfig.checkField) { + processedConfig.field = processedConfig.checkField; + delete processedConfig.checkField; + } + + // 确保field字段有值 + if (!processedConfig.field) { + processedConfig.field = ''; + } + + if (processedConfig.formatParams) { + processedConfig.parameters = processedConfig.formatParams; + delete processedConfig.formatParams; + } + + // 确保formatType字段有值 + if (!processedConfig.formatType) { + processedConfig.formatType = ''; + } + + // 确保parameters字段有值 + if (!processedConfig.parameters) { + processedConfig.parameters = ''; + } + break; + + case 'regex': + // 确保field和pattern字段正确设置 + if (processedConfig.checkField) { + processedConfig.field = processedConfig.checkField; + delete processedConfig.checkField; + } + + // 确保field字段有值 + if (!processedConfig.field) { + processedConfig.field = ''; + } + + if (processedConfig.regexPattern) { + processedConfig.pattern = processedConfig.regexPattern; + delete processedConfig.regexPattern; + } + + // 确保pattern字段有值 + if (!processedConfig.pattern) { + processedConfig.pattern = ''; + } + + // 确保matchType字段有值 + if (!processedConfig.matchType) { + processedConfig.matchType = 'match'; + } + break; + + case 'ai': + // 确保model字段有值 + if (!processedConfig.model) { + processedConfig.model = 'qwen14b'; + } + + // 确保temperature字段是数字 + if (typeof processedConfig.temperature !== 'number') { + processedConfig.temperature = 0.1; + } + + // 确保prompt字段有值 + if (!processedConfig.prompt) { + processedConfig.prompt = ''; + } + break; + + case 'code': + // 确保language字段有值 + if (!processedConfig.language) { + processedConfig.language = 'javascript'; + } + + // 确保code字段有值 + if (!processedConfig.code) { + processedConfig.code = ''; + } + break; + } + + // 移除辅助用的UI字段 + delete processedConfig.availableFields; + + return { + id: rule.id, + type: rule.type, + config: processedConfig + }; + }) + }; + + // 使用setTimeout避免连锁更新 + setTimeout(() => { + if (onChange) { + // 仅将一个evaluation_config对象传递给父组件 + onChange({ evaluation_config: evaluationConfig }); + } + }, 0); + + return evaluationConfig; + }, [rules, combinationLogic, customLogic, onChange]); + // 加载初始数据 useEffect(() => { // 如果已经初始化过,则跳过此次处理 @@ -200,7 +345,7 @@ export function ReviewSettings({ }, 0); } // 移除availableFields依赖,避免死循环 - }, [initialData]); + }, [initialData, availableFields, generateEvaluationConfig]); // 监听extractionFields的变化 useEffect(() => { @@ -271,7 +416,7 @@ export function ReviewSettings({ useEffect(() => { // 生成并更新评查配置 generateEvaluationConfig(); - }, []); + }, [generateEvaluationConfig]); // 处理已删除字段的函数 const handleDeletedFields = (deletedFields: string[]) => { @@ -1528,182 +1673,6 @@ export function ReviewSettings({ } }; - // 生成完整的评查配置数据并在提交保存时使用 - const generateEvaluationConfig = useCallback(() => { - // 创建符合数据库模式的evaluation_config对象 - const evaluationConfig = { - logicType: combinationLogic || 'and', - customLogic: combinationLogic === 'custom' ? (customLogic || '') : '', - rules: rules - .filter(rule => rule.type && rule.type.trim() !== '') - .map(rule => { - // 创建一个深拷贝以避免修改原始对象 - const processedConfig = JSON.parse(JSON.stringify(rule.config || {})); - - // 根据规则类型处理特定的字段映射 - switch(rule.type) { - case 'exists': - // 将UI字段名映射为API字段名 - if (Array.isArray(processedConfig.selectedFields)) { - processedConfig.fields = processedConfig.selectedFields; - delete processedConfig.selectedFields; - } - - // 确保fields字段存在且是数组 - if (!Array.isArray(processedConfig.fields)) { - processedConfig.fields = []; - } - - if (processedConfig.existsLogic) { - processedConfig.logic = processedConfig.existsLogic; - delete processedConfig.existsLogic; - } - - // 确保logic字段有默认值 - if (!processedConfig.logic) { - processedConfig.logic = 'and'; - } - break; - - case 'consistency': - case 'logic': - // 将UI字段名映射为API字段名 - if (processedConfig.logicRelation) { - processedConfig.logic = processedConfig.logicRelation; - delete processedConfig.logicRelation; - } - - // 确保logic字段有默认值 - if (!processedConfig.logic) { - processedConfig.logic = 'and'; - } - - // 确保pairs/conditions字段是数组 - if (rule.type === 'consistency' && !Array.isArray(processedConfig.pairs)) { - processedConfig.pairs = []; - } - - if (rule.type === 'logic' && !Array.isArray(processedConfig.conditions)) { - processedConfig.conditions = []; - } - - // 删除用于UI的临时字段 - delete processedConfig.initialSourceField; - delete processedConfig.initialTargetField; - delete processedConfig.initialCompareMethod; - delete processedConfig.initialField; - delete processedConfig.initialOperator; - delete processedConfig.initialValue; - break; - - case 'format': - // 确保field字段正确设置 - if (processedConfig.checkField) { - processedConfig.field = processedConfig.checkField; - delete processedConfig.checkField; - } - - // 确保field字段有值 - if (!processedConfig.field) { - processedConfig.field = ''; - } - - if (processedConfig.formatParams) { - processedConfig.parameters = processedConfig.formatParams; - delete processedConfig.formatParams; - } - - // 确保formatType字段有值 - if (!processedConfig.formatType) { - processedConfig.formatType = ''; - } - - // 确保parameters字段有值 - if (!processedConfig.parameters) { - processedConfig.parameters = ''; - } - break; - - case 'regex': - // 确保field和pattern字段正确设置 - if (processedConfig.checkField) { - processedConfig.field = processedConfig.checkField; - delete processedConfig.checkField; - } - - // 确保field字段有值 - if (!processedConfig.field) { - processedConfig.field = ''; - } - - if (processedConfig.regexPattern) { - processedConfig.pattern = processedConfig.regexPattern; - delete processedConfig.regexPattern; - } - - // 确保pattern字段有值 - if (!processedConfig.pattern) { - processedConfig.pattern = ''; - } - - // 确保matchType字段有值 - if (!processedConfig.matchType) { - processedConfig.matchType = 'match'; - } - break; - - case 'ai': - // 确保model字段有值 - if (!processedConfig.model) { - processedConfig.model = 'qwen14b'; - } - - // 确保temperature字段是数字 - if (typeof processedConfig.temperature !== 'number') { - processedConfig.temperature = 0.1; - } - - // 确保prompt字段有值 - if (!processedConfig.prompt) { - processedConfig.prompt = ''; - } - break; - - case 'code': - // 确保language字段有值 - if (!processedConfig.language) { - processedConfig.language = 'javascript'; - } - - // 确保code字段有值 - if (!processedConfig.code) { - processedConfig.code = ''; - } - break; - } - - // 移除辅助用的UI字段 - delete processedConfig.availableFields; - - return { - id: rule.id, - type: rule.type, - config: processedConfig - }; - }) - }; - - // 使用setTimeout避免连锁更新 - setTimeout(() => { - if (onChange) { - // 仅将一个evaluation_config对象传递给父组件 - onChange({ evaluation_config: evaluationConfig }); - } - }, 0); - - return evaluationConfig; - }, [rules, combinationLogic, customLogic, onChange]); - // 组件初次渲染后,主动发送一次完整配置数据 useEffect(() => { // 如果有初始数据,在组件挂载后主动发送一次完整规则配置 diff --git a/app/routes/rules.new.tsx b/app/routes/rules.new.tsx index 877a90a..f024a16 100644 --- a/app/routes/rules.new.tsx +++ b/app/routes/rules.new.tsx @@ -135,6 +135,7 @@ export default function RuleNew() { const location = useLocation(); const [isEditMode, setIsEditMode] = useState(false); const [isLoading, setIsLoading] = useState(false); + const [instanceKey, setInstanceKey] = useState('new'); const [formData, setFormData] = useState({}); const [evaluationPointGroups, setEvaluationPointGroups] = useState([]); @@ -174,6 +175,57 @@ export default function RuleNew() { return fields; }, []); + /** + * 重置表单数据到默认状态 + */ + const resetFormData = useCallback(() => { + console.log("重置表单数据到默认状态"); + setFormData({ + name: '', + code: '', + risk: 'low', + is_enabled: true, + description: '', + references_laws: { name: '', articles: [], content: '' }, + evaluation_point_groups_pid: null, + evaluation_point_groups_id: null, + extraction_config: { + llm: { + fields: [], + prompt_setting: { + type: 'system', + template: '' + } + }, + vlm: { + fields: [], + prompt_setting: { + type: 'system', + template: '' + } + }, + regex: { + fields: [] + } + }, + evaluation_config: { + logicType: 'and', + customLogic: '', + rules: [] + }, + pass_message: '文档检查通过,符合规范要求。', + fail_message: '文档存在以下问题,请修改后重新提交。', + suggestion_message: '', + suggestion_message_type: 'warning', + post_action: 'none', + action_config: '', + score: 0 + }); + setExtractionFields([]); + // 生成新的实例键,强制所有子组件重新渲染 + setInstanceKey(`new_${Date.now()}`); + }, []); + /** * 获取评查点数据 * 编辑模式下从API获取指定ID的评查点数据 @@ -193,23 +245,34 @@ export default function RuleNew() { console.log(response); if (response.ok) { const data = await response.json(); - setFormData(data.data[0]); - - // 初始化extractionFields - if (data.data[0]) { + if (data.data && data.data[0]) { + setFormData(data.data[0]); + + // 初始化extractionFields const extractedFields = extractFieldsFromFormData(data.data[0]); setExtractionFields(extractedFields); + + // 设置编辑模式的实例键 + setInstanceKey(`edit_${id}_${Date.now()}`); + } else { + console.error('获取数据失败: 返回数据为空'); + alert('获取数据失败: 返回数据为空'); + resetFormData(); + navigate('/rules'); } + } else { + throw new Error(`响应状态: ${response.status}`); } } catch (error) { console.error('获取评查点数据失败:', error); alert(`获取评查点数据失败: ${error instanceof Error ? error.message : '未知错误'}`); // 获取数据失败时返回上一页 - navigate(-1); + resetFormData(); + navigate('/rules'); } finally { setIsLoading(false); } - }, [navigate, extractFieldsFromFormData]); + }, [navigate, extractFieldsFromFormData, resetFormData]); /** * 获取评查点组数据 @@ -604,15 +667,20 @@ export default function RuleNew() { const id = searchParams.get('id'); // 设置编辑模式 - setIsEditMode(!!id); + const newIsEditMode = !!id; + setIsEditMode(newIsEditMode); if (id) { + // 编辑模式:获取数据 fetchEvaluationPoint(parseInt(id)); + } else { + // 新建模式:重置表单数据 + resetFormData(); } // 获取评查点组数据 fetchEvaluationPointGroups(); - }, [location.search, fetchEvaluationPoint, fetchEvaluationPointGroups]); + }, [location.search, fetchEvaluationPoint, fetchEvaluationPointGroups, resetFormData]); // 渲染页面内容 return ( @@ -634,61 +702,63 @@ export default function RuleNew() { extractionFields, updateFields: setExtractionFields }}> - {/* 评查点基本信息设置 */} -
- + {/* 评查点基本信息设置 */} +
+ +
+ + {/* 抽取设置 - 配置从文档中提取的字段 */} +
+ +
+ + {/* 评查设置 - 配置评查规则、消息等 */} +
+ +
+ + {/* 底部操作按钮区域 */} +
- - {/* 抽取设置 - 配置从文档中提取的字段 */} -
- -
- - {/* 评查设置 - 配置评查规则、消息等 */} -
- -
- - {/* 底部操作按钮区域 */} - )}