接近完美版本
This commit is contained in:
@@ -87,8 +87,153 @@ export function ReviewSettings({
|
||||
// 使用useRef跟踪是否已经初始化过
|
||||
const initializedRef = useRef(false);
|
||||
// 保存初始数据的引用,用于检测是否有实际变更
|
||||
const initialDataRef = useRef<any>(null);
|
||||
const initialDataRef = useRef<ReviewSettingsProps['initialData'] | null>(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(() => {
|
||||
// 如果有初始数据,在组件挂载后主动发送一次完整规则配置
|
||||
|
||||
+131
-61
@@ -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<string>('new');
|
||||
|
||||
const [formData, setFormData] = useState<EvaluationPoint>({});
|
||||
const [evaluationPointGroups, setEvaluationPointGroups] = useState<EvaluationPointGroup[]>([]);
|
||||
@@ -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
|
||||
}}>
|
||||
{/* 评查点基本信息设置 */}
|
||||
<div className="mb-8">
|
||||
<BasicInfo
|
||||
onChange={handleBasicInfoChange}
|
||||
initialData={formData}
|
||||
evaluationPointGroups={evaluationPointGroups}
|
||||
riskOptions={EVALUATION_OPTIONS.riskLevelOptions}
|
||||
{/* 使用key属性强制在模式切换时重新渲染所有组件 */}
|
||||
<div key={instanceKey}>
|
||||
{/* 评查点基本信息设置 */}
|
||||
<div className="mb-8">
|
||||
<BasicInfo
|
||||
onChange={handleBasicInfoChange}
|
||||
initialData={formData}
|
||||
evaluationPointGroups={evaluationPointGroups}
|
||||
riskOptions={EVALUATION_OPTIONS.riskLevelOptions}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 抽取设置 - 配置从文档中提取的字段 */}
|
||||
<div className="mb-8">
|
||||
<ExtractionSettings
|
||||
onChange={handleExtractionSettingsChange}
|
||||
initialData={formData}
|
||||
promptTypeOptions={EVALUATION_OPTIONS.promptTypeOptions}
|
||||
vlmFieldTypeOptions={EVALUATION_OPTIONS.vlmFieldTypeOptions}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 评查设置 - 配置评查规则、消息等 */}
|
||||
<div className="mb-8">
|
||||
<ReviewSettings
|
||||
onChange={handleReviewSettingsChange}
|
||||
initialData={{
|
||||
rules: formData.evaluation_config?.rules || [],
|
||||
combinationLogic: formData.evaluation_config?.logicType || 'and',
|
||||
customLogic: formData.evaluation_config?.customLogic || '',
|
||||
pass_message: formData.pass_message || '文档检查通过,符合规范要求。',
|
||||
fail_message: formData.fail_message || '文档存在以下问题,请修改后重新提交。',
|
||||
suggestion_message: formData.suggestion_message || '',
|
||||
suggestion_message_type: formData.suggestion_message_type || 'warning',
|
||||
post_action: formData.post_action || 'none',
|
||||
action_config: formData.action_config || '',
|
||||
score: formData.score !== undefined ? formData.score : 0
|
||||
}}
|
||||
ruleTypeOptions={EVALUATION_OPTIONS.ruleTypeOptions}
|
||||
logicTypeOptions={EVALUATION_OPTIONS.logicTypeOptions}
|
||||
logicOperatorOptions={EVALUATION_OPTIONS.logicOperatorOptions}
|
||||
compareMethodOptions={EVALUATION_OPTIONS.compareMethodOptions}
|
||||
formatTypeOptions={EVALUATION_OPTIONS.formatTypeOptions}
|
||||
comparisonOperatorOptions={EVALUATION_OPTIONS.comparisonOperatorOptions}
|
||||
matchTypeOptions={EVALUATION_OPTIONS.matchTypeOptions}
|
||||
suggestionMessageTypeOptions={EVALUATION_OPTIONS.suggestionMessageTypeOptions}
|
||||
postActionOptions={EVALUATION_OPTIONS.postActionOptions}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 底部操作按钮区域 */}
|
||||
<ActionButtons
|
||||
onSave={handleSave}
|
||||
onSaveDraft={handleSaveDraft}
|
||||
isEditMode={isEditMode}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 抽取设置 - 配置从文档中提取的字段 */}
|
||||
<div className="mb-8">
|
||||
<ExtractionSettings
|
||||
onChange={handleExtractionSettingsChange}
|
||||
initialData={formData}
|
||||
promptTypeOptions={EVALUATION_OPTIONS.promptTypeOptions}
|
||||
vlmFieldTypeOptions={EVALUATION_OPTIONS.vlmFieldTypeOptions}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 评查设置 - 配置评查规则、消息等 */}
|
||||
<div className="mb-8">
|
||||
<ReviewSettings
|
||||
key={`review-settings-${extractionFields.length}-${isEditMode ? formData.id : 'new'}`}
|
||||
onChange={handleReviewSettingsChange}
|
||||
initialData={{
|
||||
rules: formData.evaluation_config?.rules || [],
|
||||
combinationLogic: formData.evaluation_config?.logicType || 'and',
|
||||
customLogic: formData.evaluation_config?.customLogic || '',
|
||||
pass_message: formData.pass_message || '',
|
||||
fail_message: formData.fail_message || '',
|
||||
suggestion_message: formData.suggestion_message || '',
|
||||
suggestion_message_type: formData.suggestion_message_type || 'warning',
|
||||
post_action: formData.post_action || 'none',
|
||||
action_config: formData.action_config || '',
|
||||
score: formData.score || 0
|
||||
}}
|
||||
ruleTypeOptions={EVALUATION_OPTIONS.ruleTypeOptions}
|
||||
logicTypeOptions={EVALUATION_OPTIONS.logicTypeOptions}
|
||||
logicOperatorOptions={EVALUATION_OPTIONS.logicOperatorOptions}
|
||||
compareMethodOptions={EVALUATION_OPTIONS.compareMethodOptions}
|
||||
formatTypeOptions={EVALUATION_OPTIONS.formatTypeOptions}
|
||||
comparisonOperatorOptions={EVALUATION_OPTIONS.comparisonOperatorOptions}
|
||||
matchTypeOptions={EVALUATION_OPTIONS.matchTypeOptions}
|
||||
suggestionMessageTypeOptions={EVALUATION_OPTIONS.suggestionMessageTypeOptions}
|
||||
postActionOptions={EVALUATION_OPTIONS.postActionOptions}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 底部操作按钮区域 */}
|
||||
<ActionButtons
|
||||
onSave={handleSave}
|
||||
onSaveDraft={handleSaveDraft}
|
||||
isEditMode={isEditMode}
|
||||
/>
|
||||
</RuleContext.Provider>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user