From 0b1dc6b8ca929a90217dd341a6326c5d683e06e9 Mon Sep 17 00:00:00 2001 From: YoVinchen Date: Mon, 11 Aug 2025 14:07:10 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B1=95=E7=A4=BA=E9=94=99?= =?UTF-8?q?=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/data_comparison.py | 5 + static/js/app.js | 183 ++++++++++++++++++++++++++++++++----- 2 files changed, 164 insertions(+), 24 deletions(-) diff --git a/modules/data_comparison.py b/modules/data_comparison.py index 12f35f1..5bd554d 100644 --- a/modules/data_comparison.py +++ b/modules/data_comparison.py @@ -279,6 +279,11 @@ def compare_json_arrays(array1, array2): def format_json_for_display(value): """格式化JSON用于显示""" + # 处理None值 + if value is None: + return "null" + + # 处理非字符串类型 if not isinstance(value, str): return str(value) diff --git a/static/js/app.js b/static/js/app.js index 46ab4d0..ff146ca 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -911,11 +911,14 @@ function displayDifferences() { // 保存当前搜索框的值 const currentSearchValue = document.getElementById('differenceSearch')?.value || ''; - if (!filteredDifferenceResults.length) { + if (!filteredDifferenceResults || !filteredDifferenceResults.length) { differencesContainer.innerHTML = '

未发现差异

'; return; } + // 调试日志:检查差异数据 + console.log('差异数据:', filteredDifferenceResults); + // 按主键分组差异 const groupedDifferences = groupDifferencesByKey(filteredDifferenceResults); const totalGroups = Object.keys(groupedDifferences).length; @@ -995,10 +998,19 @@ function displayDifferences() { `; // 显示当前页的主键组 - currentPageKeys.forEach((key, groupIndex) => { - const diffs = groupedDifferences[key]; + currentPageKeys.forEach((keyStr, groupIndex) => { + const diffs = groupedDifferences[keyStr]; const globalIndex = startIndex + groupIndex + 1; + // 将字符串化的key解析回对象 + let keyObj; + try { + keyObj = JSON.parse(keyStr); + } catch (e) { + // 如果解析失败,假设它本身就是一个简单值 + keyObj = keyStr; + } + html += `
@@ -1012,14 +1024,14 @@ function displayDifferences() { data-bs-toggle="collapse" data-bs-target="#keyGroup${globalIndex}"> 展开/收起 -
-

主键: ${formatCompositeKey(key)}

+

主键: ${formatCompositeKey(keyObj)}

-
+
`; @@ -1039,6 +1051,18 @@ function displayDifferences() { const jsonClass = isJson ? 'json-field' : ''; const fieldId = `field_${globalIndex}_${diffIndex}`; + // 调试:打印差异数据 + console.log(`差异 ${diff.field}:`, { + pro_value: diff.pro_value, + test_value: diff.test_value, + is_json: diff.is_json, + is_array: diff.is_array + }); + + // 确保值存在 + const proValue = diff.pro_value !== undefined && diff.pro_value !== null ? diff.pro_value : '无数据'; + const testValue = diff.test_value !== undefined && diff.test_value !== null ? diff.test_value : '无数据'; + html += `
@@ -1060,7 +1084,7 @@ function displayDifferences() { 生产环境
-
${escapeHtml(diff.pro_value)}
+
${escapeHtml(proValue)}
@@ -1070,7 +1094,7 @@ function displayDifferences() { 测试环境
-
${escapeHtml(diff.test_value)}
+
${escapeHtml(testValue)}
@@ -1115,8 +1139,21 @@ function displayDifferences() { // HTML转义函数,防止XSS function escapeHtml(text) { + // 处理undefined和null值 + if (text === undefined || text === null) { + return '无数据'; + } + + // 确保是字符串 + const str = String(text); + + // 如果是空字符串 + if (str === '') { + return '空值'; + } + const div = document.createElement('div'); - div.textContent = text; + div.textContent = str; return div.innerHTML; } @@ -1671,6 +1708,7 @@ function showRawData(keyStr) { try { // 解析key const key = JSON.parse(keyStr); + console.log('查找原始数据,key:', key); // 在原生数据中查找对应的记录 let proData = null; @@ -1682,15 +1720,40 @@ function showRawData(keyStr) { // 支持复合主键比较 if (typeof key === 'object' && !Array.isArray(key)) { // 复合主键情况:比较所有主键字段 - return Object.keys(key).every(keyField => - JSON.stringify(item[keyField]) === JSON.stringify(key[keyField]) - ); + const matches = Object.keys(key).every(keyField => { + const itemValue = item[keyField]; + const keyValue = key[keyField]; + + // 如果都是undefined或null,认为匹配 + if (itemValue == null && keyValue == null) { + return true; + } + + // 转换为字符串进行比较 + const itemStr = String(itemValue); + const keyStr = String(keyValue); + + // 直接比较字符串 + return itemStr === keyStr; + }); + + if (matches) { + console.log('找到生产环境数据:', item); + } + return matches; } else { - // 单主键情况:保持原有逻辑 - const keyField = Object.keys(key)[0]; - return JSON.stringify(item[keyField]) === JSON.stringify(key[keyField]); + // 单主键情况(兼容旧代码) + return false; } }); + + // 如果没找到,输出调试信息 + if (!proData) { + console.log('未找到生产数据,查找的key:', key); + console.log('可用的数据:', currentResults.raw_pro_data.map(item => ({ + statusid: item.statusid + }))); + } } // 查找测试环境数据 @@ -1699,17 +1762,44 @@ function showRawData(keyStr) { // 支持复合主键比较 if (typeof key === 'object' && !Array.isArray(key)) { // 复合主键情况:比较所有主键字段 - return Object.keys(key).every(keyField => - JSON.stringify(item[keyField]) === JSON.stringify(key[keyField]) - ); + const matches = Object.keys(key).every(keyField => { + const itemValue = item[keyField]; + const keyValue = key[keyField]; + + // 如果都是undefined或null,认为匹配 + if (itemValue == null && keyValue == null) { + return true; + } + + // 转换为字符串进行比较 + const itemStr = String(itemValue); + const keyStr = String(keyValue); + + // 直接比较字符串 + return itemStr === keyStr; + }); + + if (matches) { + console.log('找到测试环境数据:', item); + } + return matches; } else { - // 单主键情况:保持原有逻辑 - const keyField = Object.keys(key)[0]; - return JSON.stringify(item[keyField]) === JSON.stringify(key[keyField]); + // 单主键情况(兼容旧代码) + return false; } }); + + // 如果没找到,输出调试信息 + if (!testData) { + console.log('未找到测试数据,查找的key:', key); + console.log('可用的数据:', currentResults.raw_test_data.map(item => ({ + statusid: item.statusid + }))); + } } + console.log('查找结果 - 生产数据:', proData, '测试数据:', testData); + // 创建模态框内容 const modalContent = `