diff --git a/app/routes/rules.new.tsx b/app/routes/rules.new.tsx index 479624f..79a070a 100644 --- a/app/routes/rules.new.tsx +++ b/app/routes/rules.new.tsx @@ -121,13 +121,6 @@ interface FormDataType { type?: string; } -// API响应类型 -interface ApiResponseType { - code: number; - msg: string; - data: T; -} - interface ApiPointData { id: number; name: string; @@ -235,94 +228,165 @@ export default function RuleNew() { const fetchEvaluationPoint = async (id: number) => { setIsLoading(true); try { + console.log(`获取评查点数据,ID: ${id}`); const response = await fetch(`http://127.0.0.1:9000/admin/evaluation_points?id=eq.${id}`, { method: 'GET', headers: { - 'Content-Type': 'application/json', 'Accept': 'application/json' } }); if (!response.ok) { - throw new Error(`获取评查点数据失败: ${response.status}`); + const errorText = await response.text(); + console.error(`API响应错误: ${response.status}`, errorText); + throw new Error(`获取评查点数据失败: ${response.status} - ${errorText}`); } - const responseData = await response.json() as ApiResponseType; + const responseData = await response.json(); + console.log("API响应数据:", responseData); - // 根据API返回结构解析数据 - if (responseData && responseData.code === 0 && responseData.data && responseData.data.length > 0) { - const pointData = responseData.data[0]; - - // 转换API数据为表单数据格式 - const extractionConfig = pointData.extraction_config || {}; - const evaluationConfig = pointData.evaluation_config || {}; - - // 提取字段列表,用于规则设置 - const extractedFields: string[] = [ - ...(extractionConfig.llm?.fields || []), - ...(extractionConfig.vlm?.fields || []).map((field) => { - if (typeof field === 'object' && field.name) { - return field.type ? `${field.name}_${field.type}` : field.name; + // 处理多种可能的响应格式 + if (Array.isArray(responseData)) { + if (responseData.length > 0) { + console.log("数组格式响应,使用第一项"); + processPointData(responseData[0]); + } else { + console.error("数组为空,未找到数据"); + throw new Error(`未找到ID为${id}的评查点数据`); + } + } else if (responseData && typeof responseData === 'object') { + // 处理可能的包装对象格式 + if (responseData.data) { + console.log("包装对象格式响应,使用data字段"); + if (Array.isArray(responseData.data)) { + if (responseData.data.length > 0) { + processPointData(responseData.data[0]); + } else { + console.error("data数组为空"); + throw new Error(`未找到ID为${id}的评查点数据`); } - return ''; - }), - ...(extractionConfig.regex?.fields || []).map((field) => field.field || '') - ].filter(Boolean); + } else if (typeof responseData.data === 'object') { + processPointData(responseData.data); + } else { + console.error("data字段格式不正确"); + throw new Error('数据格式不正确: data字段不是预期的格式'); + } + } else if (responseData.id) { + // 可能是直接返回的单个对象 + console.log("单对象格式响应"); + processPointData(responseData); + } else { + console.error("无法识别的对象格式", responseData); + throw new Error('未找到评查点数据或数据格式不正确'); + } + } else { + console.error("响应格式无法识别", responseData); + throw new Error('未找到评查点数据或数据格式不正确'); + } + } catch (error) { + console.error('获取评查点数据失败:', error); + alert(`获取评查点数据失败: ${error instanceof Error ? error.message : '未知错误'}`); + } finally { + setIsLoading(false); + } + }; + + // 处理获取到的评查点数据 + const processPointData = (pointData: ApiPointData) => { + console.log("处理评查点数据:", pointData); + + if (!pointData) { + console.error("评查点数据为空"); + throw new Error("评查点数据为空"); + } + + try { + // 转换API数据为表单数据格式 + const extractionConfig = pointData.extraction_config || {}; + const evaluationConfig = pointData.evaluation_config || {}; + + console.log("提取配置:", extractionConfig); + console.log("评查配置:", evaluationConfig); + + // 提取字段列表,用于规则设置 + const extractedFields: string[] = []; + + // 处理LLM字段 + if (extractionConfig.llm && extractionConfig.llm.fields) { + extractedFields.push(...extractionConfig.llm.fields); + } + + // 处理VLM字段 + if (extractionConfig.vlm && extractionConfig.vlm.fields) { + extractedFields.push(...(extractionConfig.vlm.fields || []).map((field) => { + if (typeof field === 'object' && field.name) { + return field.type ? `${field.name}_${field.type}` : field.name; + } + return ''; + }).filter(Boolean)); + } + + // 处理正则字段 + if (extractionConfig.regex && extractionConfig.regex.fields) { + extractedFields.push(...(extractionConfig.regex.fields || []).map((field) => field.field || '').filter(Boolean)); + } + + console.log("提取的字段:", extractedFields); + setExtractionFields(extractedFields); + + // 构建表单数据 + const newFormData = { + id: pointData.id, + name: pointData.name || '', + code: pointData.code || '', + risk: pointData.risk || 'medium', + is_enabled: pointData.is_enabled !== undefined ? pointData.is_enabled : false, + description: pointData.description || '', + references_laws: pointData.references_laws || { + name: '', + articles: [], + content: '' + }, + evaluation_point_groups_id: pointData.evaluation_point_groups_id || null, + type: pointData.type || '', - setExtractionFields(extractedFields); - - // 构建表单数据 - setFormData({ - id: pointData.id, - name: pointData.name || '', - code: pointData.code || '', - risk: pointData.risk || 'medium', - is_enabled: pointData.is_enabled || false, - description: pointData.description || '', - references_laws: pointData.references_laws || { - name: '', - articles: [], - content: '' - }, - evaluation_point_groups_id: pointData.evaluation_point_groups_id || null, - type: pointData.type || '', - - // 将API数据格式转换为内部使用的格式 - extraction_config: { - llm_ocr: { - fields: extractionConfig.llm?.fields || [], - prompt_setting: { - type: extractionConfig.llm?.prompt_setting?.type || 'system', - template: extractionConfig.llm?.prompt_setting?.template || '' - } - }, - llm_vl: { - fields: (extractionConfig.vlm?.fields || []).map((field) => { - if (typeof field === 'object' && field.name) { - return field.type ? `${field.name}_${field.type}` : field.name; - } - return ''; - }).filter(Boolean), - prompt_setting: { - type: extractionConfig.vlm?.prompt_setting?.type || 'system', - template: extractionConfig.vlm?.prompt_setting?.template || '' - } - }, - ocr_regex: { - fields: (extractionConfig.regex?.fields || []).map((field) => ({ - fieldName: field.field || '', - regex: field.pattern || '' - })) + // 将API数据格式转换为内部使用的格式 + extraction_config: { + llm_ocr: { + fields: extractionConfig.llm?.fields || [], + prompt_setting: { + type: extractionConfig.llm?.prompt_setting?.type || 'system', + template: extractionConfig.llm?.prompt_setting?.template || '' } }, - - evaluation_config: { - logicType: evaluationConfig.logicType || 'and', - customLogic: evaluationConfig.customLogic || '', - rules: (evaluationConfig.rules || []).map((rule) => { - // 将API规则格式转换为UI使用的格式 - let config: RuleConfigType = {}; - + llm_vl: { + fields: (extractionConfig.vlm?.fields || []).map((field) => { + if (typeof field === 'object' && field.name) { + return field.type ? `${field.name}_${field.type}` : field.name; + } + return ''; + }).filter(Boolean), + prompt_setting: { + type: extractionConfig.vlm?.prompt_setting?.type || 'system', + template: extractionConfig.vlm?.prompt_setting?.template || '' + } + }, + ocr_regex: { + fields: (extractionConfig.regex?.fields || []).map((field) => ({ + fieldName: field.field || '', + regex: field.pattern || '' + })) + } + }, + + evaluation_config: { + logicType: evaluationConfig.logicType || 'and', + customLogic: evaluationConfig.customLogic || '', + rules: (evaluationConfig.rules || []).map((rule) => { + // 将API规则格式转换为UI使用的格式 + let config: RuleConfigType = {}; + + try { switch (rule.type) { case 'exists': config = { @@ -372,30 +436,32 @@ export default function RuleNew() { default: config = rule.config || {}; } - - return { - id: rule.id, - type: rule.type, - config - }; - }) - }, - - pass_message: pointData.pass_message || '文档检查通过,符合规范要求。', - fail_message: pointData.fail_message || '文档存在以下问题,请修改后重新提交。', - suggestion_message: pointData.suggestion_message || '', - suggestion_message_type: pointData.suggestion_message_type || 'warning', - post_action: pointData.post_action || 'none', - action_config: pointData.action_config || '' - }); - } else { - throw new Error('未找到评查点数据或数据格式不正确'); - } + } catch (error) { + console.error(`处理规则[${rule.id}]配置时出错:`, error); + config = rule.config || {}; + } + + return { + id: rule.id, + type: rule.type, + config + }; + }) + }, + + pass_message: pointData.pass_message || '文档检查通过,符合规范要求。', + fail_message: pointData.fail_message || '文档存在以下问题,请修改后重新提交。', + suggestion_message: pointData.suggestion_message || '', + suggestion_message_type: pointData.suggestion_message_type || 'warning', + post_action: pointData.post_action || 'none', + action_config: pointData.action_config || '' + }; + + console.log("设置表单数据:", newFormData); + setFormData(newFormData); } catch (error) { - console.error('获取评查点数据失败:', error); - alert(`获取评查点数据失败: ${error instanceof Error ? error.message : '未知错误'}`); - } finally { - setIsLoading(false); + console.error("处理评查点数据时出错:", error); + throw new Error(`处理评查点数据时出错: ${error instanceof Error ? error.message : '未知错误'}`); } }; @@ -649,8 +715,6 @@ export default function RuleNew() { risk: formData.risk, description: formData.description, is_enabled: isDraft ? false : formData.is_enabled, - is_draft: isDraft, - type: formData.type, references_laws: formData.references_laws, extraction_config: extractionConfig, evaluation_config: evaluationConfig, @@ -667,6 +731,9 @@ export default function RuleNew() { evaluationPointData.id = formData.id; } + // 打印最终发送的数据 + console.log("最终API数据格式:", JSON.stringify(evaluationPointData, null, 2)); + return evaluationPointData; }; @@ -675,40 +742,92 @@ export default function RuleNew() { try { setIsLoading(true); const evaluationPointData = formatDataForApi(formData); + console.log("保存数据:", evaluationPointData); // 确定使用的HTTP方法和URL let method = 'POST'; let endpoint = 'http://127.0.0.1:9000/admin/evaluation_points'; + // 如果是编辑模式,使用PATCH更新现有记录 if (isEditMode && formData.id) { method = 'PATCH'; endpoint = `http://127.0.0.1:9000/admin/evaluation_points?id=eq.${formData.id}`; } + + console.log(`发送${method}请求到`, endpoint); // 发送数据到API const response = await fetch(endpoint, { method: method, - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - 'Prefer': isEditMode ? 'return=representation' : 'return=representation' - }, body: JSON.stringify(evaluationPointData) }); + // 输出完整响应信息 + console.log("响应状态:", response.status, response.statusText); + if (!response.ok) { - throw new Error(`API响应错误: ${response.status}`); + const errorText = await response.text(); + console.error(`API响应错误: ${response.status}`, errorText); + try { + // 尝试解析错误响应为JSON + const errorJson = JSON.parse(errorText); + console.error("解析的错误JSON:", errorJson); + throw new Error(`API响应错误: ${errorJson.msg || response.statusText}`); + } catch (parseError) { + // 如果无法解析为JSON,使用原始文本 + throw new Error(`API响应错误: ${response.status} - ${errorText}`); + } } - const responseData = await response.json() as ApiResponseType; + const contentType = response.headers.get('content-type'); + console.log("响应Content-Type:", contentType); - if (responseData.code === 0) { - console.log('保存成功:', responseData.data); - // 保存成功后跳转到评查点列表页面 - navigate('/rules'); + // 检查是否是JSON响应 + if (contentType && contentType.includes('application/json')) { + const responseData = await response.json(); + console.log("API响应数据:", responseData); + + // 处理多种可能的响应格式 + if (Array.isArray(responseData)) { + if (responseData.length > 0) { + console.log("保存成功 (数组响应):", responseData[0]); + alert("保存成功!"); + navigate('/rules'); + } else { + console.warn("响应数组为空"); + alert("操作已完成,但服务器未返回数据"); + navigate('/rules'); + } + } else if (responseData && typeof responseData === 'object') { + if (responseData.data) { + console.log("保存成功 (带data字段):", responseData.data); + alert("保存成功!"); + navigate('/rules'); + } else if (responseData.id) { + console.log("保存成功 (直接对象):", responseData); + alert("保存成功!"); + navigate('/rules'); + } else if (responseData.code === 0) { + console.log("保存成功 (带code字段):", responseData); + alert("保存成功!"); + navigate('/rules'); + } else { + console.warn("响应对象格式不符合预期", responseData); + alert("操作已完成,但返回的数据格式不符合预期"); + navigate('/rules'); + } + } else { + console.warn("响应不是数组或对象", responseData); + alert("操作已完成,但返回的数据格式不符合预期"); + navigate('/rules'); + } } else { - throw new Error(`API错误: ${responseData.msg || '未知错误'}`); + // 非JSON响应 + const text = await response.text(); + console.log("非JSON响应:", text); + alert("操作已完成!"); + navigate('/rules'); } } catch (error) { console.error('保存失败:', error); @@ -723,40 +842,81 @@ export default function RuleNew() { try { setIsLoading(true); const draftData = formatDataForApi(formData, true); + console.log("保存草稿数据:", draftData); // 确定使用的HTTP方法和URL let method = 'POST'; let endpoint = 'http://127.0.0.1:9000/admin/evaluation_points'; + // 如果是编辑模式,使用PATCH更新现有记录 if (isEditMode && formData.id) { method = 'PATCH'; endpoint = `http://127.0.0.1:9000/admin/evaluation_points?id=eq.${formData.id}`; } + + console.log(`发送${method}请求到`, endpoint); // 发送数据到API const response = await fetch(endpoint, { method: method, - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - 'Prefer': 'return=representation' - }, body: JSON.stringify(draftData) }); if (!response.ok) { - throw new Error(`API响应错误: ${response.status}`); + const errorText = await response.text(); + console.error(`API响应错误: ${response.status}`, errorText); + throw new Error(`API响应错误: ${response.status} - ${errorText}`); } - const responseData = await response.json() as ApiResponseType; + const contentType = response.headers.get('content-type'); + console.log("响应Content-Type:", contentType); - if (responseData.code === 0) { - console.log('保存草稿成功:', responseData.data); - // 保存成功后跳转到评查点列表页面 - navigate('/rules'); + // 检查是否是JSON响应 + if (contentType && contentType.includes('application/json')) { + const responseData = await response.json(); + console.log("API响应数据:", responseData); + + // 处理多种可能的响应格式 + if (Array.isArray(responseData)) { + if (responseData.length > 0) { + console.log("保存草稿成功 (数组响应):", responseData[0]); + alert("草稿保存成功!"); + navigate('/rules'); + } else { + console.warn("响应数组为空"); + alert("操作已完成,但服务器未返回数据"); + navigate('/rules'); + } + } else if (responseData && typeof responseData === 'object') { + if (responseData.data) { + console.log("保存草稿成功 (带data字段):", responseData.data); + alert("草稿保存成功!"); + navigate('/rules'); + } else if (responseData.id) { + console.log("保存草稿成功 (直接对象):", responseData); + alert("草稿保存成功!"); + navigate('/rules'); + } else if (responseData.code === 0) { + console.log("保存草稿成功 (带code字段):", responseData); + alert("草稿保存成功!"); + navigate('/rules'); + } else { + console.warn("响应对象格式不符合预期", responseData); + alert("操作已完成,但返回的数据格式不符合预期"); + navigate('/rules'); + } + } else { + console.warn("响应不是数组或对象", responseData); + alert("操作已完成,但返回的数据格式不符合预期"); + navigate('/rules'); + } } else { - throw new Error(`API错误: ${responseData.msg || '未知错误'}`); + // 非JSON响应 + const text = await response.text(); + console.log("非JSON响应:", text); + alert("操作已完成!"); + navigate('/rules'); } } catch (error) { console.error('保存草稿失败:', error);